Spring boot microservices doesn't work with Intelij IDEA - spring-boot

I am creating a spring boot microservice project with intelij IDEA.
Currently I have developed three seperate spring boot rest services as customer service, vehicle service and spring cloud config server. Spring cloud config server is pointing to a github repository.
The issue is sometimes above projects take more than 10 minutes to run and sometimes does't run and give an error message as "failed to check application readystate intellij attached provider for the vm is not found". I have no idea why this happens ?

There are two possible causes:
1. IntelliJ IDEA and the Spring application are running in different JVMs.
There is a bug for IntelliJ IDEA regarding that:
https://youtrack.jetbrains.com/issue/IDEA-210665
Here is short summary:
IntelliJ IDEA uses local JMX connector for retrieving Spring Boot actuator endpoint's data by default. However, it could be impossible to get local JMX connector address via attach api if Spring Boot application and IntelliJ IDEA are run by different JVMs. In this case, add the following lines to VM options of your Spring Boot run configuration:
-Dcom.sun.management.jmxremote.port={some_port}
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
As mentioned in the official Oracle documentation, this configuration is insecure. Any remote user who knows (or guesses) your port number and host name will be able to monitor and control your Java applications and platform.
2. Prolonged time to retrieve local hostname
You can check that time using inetTester. Normally it should take only several milliseconds to complete. If it takes a long time then you can add the hostname returned by inetTester to /etc/hosts file like this:
127.0.0.1 localhost winsky
::1 localhost winsky

Related

Elasticsearch 7.10.2 doesn't bind application.properties variables on Mac M1

I'm facing a weird issue. I have 2 laptops, one running under Windows where everything works fine and on the other side, a Mac Mini M1.
Assuming, I'm developing a basic Spring Boot application with Elasticsearch as Repository.
In the application.yml, as usual I have the following properties :
spring:
elasticsearch:
rest:
uris: https://dummy-cloud-provider.cloud.com:12833
username: myusername
password: mypassword
But everytime I want to start the application on my Mac, I have the following error :
2021-06-23 15:55:51.972 ERROR [reactor-http-nio-3] r.c.p.Operators - Operator called default onErrorDropped
reactor.core.Exceptions$ErrorCallbackNotImplemented: org.springframework.data.elasticsearch.client.NoReachableHostException: Host 'localhost:9200' not reachable. Cluster state is offline.
Caused by: org.springframework.data.elasticsearch.client.NoReachableHostException: Host 'localhost:9200' not reachable. Cluster state is offline.
at org.springframework.data.elasticsearch.client.reactive.SingleNodeHostProvider.lambda$lookupActiveHost$3(SingleNodeHostProvider.java:101)
at reactor.core.publisher.FluxHandle$HandleSubscriber.onNext(FluxHandle.java:102)
at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onNext(FluxMap.java:220)
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2397)
...
I don't understand why it always skip my application.yml variables and try to reach localhost:9200.
I hope someone can help me :)
Best regards
This is not a Spring Data Elasticsearch problem, but a Spring Boot problem. Spring Data Elasticsearch does not use application properties to set anything up.
Looking at the configuration it seems that you want to set up a imperative (non-reactive) client connection to Elasticsearch?
The stacktrace shows that the failing call is done by the reactive client.
I suspect that you have the reactive Spring libraries (webflux) in the classpath and Spring boot actuator. And Spring Boot then configures a reactive client for the actuator using the default of localhost:9200.
I can't tell for sure without seeing your maven/gradle setup, but this for me is most possible explanation for this error.

How PCF works internally when deploying Spring boot project

Will PCF run the Tomcat embedded in Spring boot jar or it runs its own tomcat. In PCF we never mention the port number. In the classic approach, we start 3 Tomcat instances in different port number and have apache server before that. Does PCF work the same way.
This is a pretty broad question, so I'm going to answer with a pretty broad response but link you to where you can find more details, if you are inclined to dig in more.
How PCF works internally when deploying Spring boot project
Will PCF run the Tomcat embedded in Spring boot jar or it runs its own tomcat.
When you run cf push -p my/cool/file.jar (or even file.war), the cf cli extracts everything from that archive and pushes it up to CF. CF stores your app files & then your app is staged.
During staging, the Java build pack runs. It looks at all the files that were pushed & tries to determine what to do with them. It knows how to handle several different types of apps [1], including both standard WAR files & Spring Boot apps. The build pack will check your app to see if its one of the supported types in order [2] and will select the first match.
After selecting the type of app, it runs through and installs what is necessary to run your app. For a Spring Boot app, that's basically just the JVM. For a WAR file, it installs Tomcat & a JVM. In addition, it writes out the configuration & start up commands necessary for CF to launch your app.
At this point staging is complete and you have what is called a "droplet". If you have any additional questions on the staging workflow, read here for more details [3].
At this point, the app would be started. The platform takes the droplet that was created and executes the command specified by the build pack to start the app [4]. If all goes well, your app will then be up and running on CF.
In PCF we never mention the port number.
Correct. The platform will tell you the port on which your application should listen. For Java apps, you don't have to do anything. The Java buildpack will handle configuring Spring Boot or Tomcat to start and listen on the correct port.
For Spring Boot apps, you can look at the start up command to see how it's doing this. For Tomcat, it happens in the server.xml that's generated by the Java buildpack [5].
In the classic approach, we start 3 Tomcat instances in different port number and have apache server before that. Does PCF work the same way.
Yes and no. Each application you run can have multiple instances. If you scaled your app to have three instances, that would be roughly like having 3 Tomcat instances in your classic approach.
The main difference is that there would be no Apache Web Server in front. On Cloud Foundry, this is not necessary because it has it's own load balancer called Gorouter [6] which handles proxying traffic to your app and load balancing across available app instances.
This is a classic mistake that people new to CF make. They try to replicate classic architectures and shoehorn a reverse proxy into their app when it's not necessary. This is one of the benefits of CF. It handles routing traffic to your app in a scalable way, freeing you up to focus more on your app.
[1] See "Standard Containers -> https://github.com/cloudfoundry/java-buildpack#additional-documentation
[2] https://github.com/cloudfoundry/java-buildpack/blob/master/config/components.yml#L18
[3] https://docs.cloudfoundry.org/concepts/how-applications-are-staged.html
[4] https://docs.cloudfoundry.org/concepts/overview.html#apps-anywhere
[5] https://github.com/cloudfoundry/java-buildpack/blob/master/resources/tomcat/conf/server.xml#L21
[6] https://docs.cloudfoundry.org/concepts/architecture/#routing
No. The simple answer is each instance of ur application jar is running in its own container within PCF. So there is no clash of using the same port numbers.

spring boot startup failure if mongo host not reachable

I have Spring boot mongo db app, when i start running this application if mongo host is alive, am able to see the my app is up and running successfully,
if my mongo host is down when i start my application my app failed to start.
is there any way even thought if mongo host is down my application should be up and running.
could someone please help me on this?
am using spring boot mongo properties in my application
spring.data.mongodb.repositories.enabled=true
spring.data.mongodb.port=27017
spring.data.mongodb.database=db
spring.data.mongodb.uri=mongodb://mongo-node-1.ballu/db
have same problem with spring boot kafka also.
Sorry for the previous comment. It was for excluding auto config beans, anyway
Is there any way even though if mongo host is down my application
should be up and running.
Yes,
spring.datasource.continue-on-error=true #Whether to stop if an error occurs while initializing the database.
as per spring doc
By default, Spring Boot enables the fail-fast feature of the Spring
JDBC initializer. This means that, if the scripts cause exceptions,
the application fails to start. You can tune that behavior by setting
spring.datasource.continue-on-error.
and as of spring kafka try this(i'm not sure if this meets your requirement)
spring.kafka.admin.fail-fast=true # Whether to fail fast if the broker is not available on startup.

What are concrete steps to simultaneously 2 apps on tomcat in IntelliJ?

I have a Spring Boot app which writes to an ActiveMQ topic. Another application is a Spring Boot listener that reads from this topic. I am using IntelliJ IDEA 2018.1 (Ultimate Edition).
What are concrete steps to allow me to run both apps simultaneously on Tomcat 8.0.24?
I have tried changing Tomcat port from 8080 to 8081 and JMX port from 1099 to 1098 and setting a different debugger port for each application. I have also tried using an IntelliJ IDEA compound configuration and making a copy of the Tomcat install with all different ports in server.xml. I keep getting various errors like address is in use - bindException and cannot use debugger port. socket closed.
Under Intellij run configurations - create two different tomcat settings (i usually name it with the port number so its easy to identity tomcat-8080 and tomcat-8005), change ports on one of them.
http
jmx
shutdown

Spring Cloud Bus not working /bus/refresh call goes to controller and searching mapping in controller and failing

I have configured my application with config server and github supported external config files. It works fine when I am having single instance of my application in cloud foundry.
But for multiple instance it is said to implement spring cloud bus to apply external config changes to all the instances. For this I have bind my config server with rabbit MQ instance available on Pivotal Cloud foundry. have added spring.cloud.starter.bus.amqp jar in my build.gradle file.
Problem: But when I am hitting POST request to client app at:
http://server:port/bus/refresh the call goes to controller rather than refreshing all the instances and failing as no mapping for same.
Please let me know if I am missing any configuration to make spring-cloud-bus work.
Thanks in advance!
application.properties(Client application):
spring.profiles=cloud
spring.rabbitmq.host= 10.17.128.102
spring.rabbitmq.port= 5672
spring.rabbitmq.virtual-host= *****
spring.rabbitmq.username= ******
spring.rabbitmq.password= *****
rabbit.exchangeName= demoPartyServiceexc
rabbit.routingKey= demoPartyService
rabbit.queueName= demoPartyServicequeue
logging.level.ROOT= ERROR
bootstrap.properties(Client application):
spring.application.name=demo-api
spring.cloud.bus.enabled=true
spring.cloud.config.bus.enabled=true
spring.cloud.bus.amqp.enabled=true
spring.cloud.bus.refresh.enabled=true
spring.cloud.bus.env.enabled=true
spring.cloud.config.uri=https://config-a5e99419-8179-47f7-8c23-62ed5b38db0b.cf.com
spring.cloud.config.server.bootstrap=true
spring.cloud.config.server.git.uri= My Github repository URI
spring.cloud.config.server.git.username= ********
spring.cloud.config.server.git.password= ********
application.properties file in GIT repo:
logging.level.ROOT=WARN
What are server.servlet-path and management.context-path in client app set to?
I think you might need to send the request to http://host/<management.context-path>/bus/refresh.
Or better yet, to http://config-server-host/monitor so that it publishes a message to a topic in RabbitMQ and all client apps get notified.
Configuration snippets, source code and more details could be found at my blog post: Refreshable Configuration using Spring Cloud Config Server, Spring Cloud Bus, RabbitMQ and Git

Resources