I need to run Spring Boot based app locally. It uses spring-cloud-starter-aws dependency.
The problem is that it tries to connect to EC2 metadata service always. Setting "cloud.aws.*" properties doesn't help.
I expect that default AWS credentials chain will be used, credentials and region will be read from one of AWS preferred way (e.g. ~/.aws/config and ~/.aws/credentials files).
I tried to set cloud.aws.credentials.useDefaultAwsCredentialsChain property but spring-cloud-starter-aws doesn't care
I found examples that use CloudFormation stack for very strange reason to run the app locally.
When I use AWS SDK for Java default AWS chain is used without any issues - I don't need to do anything specific for local running of the application (locally it reads credentials from files and on EC2 it uses instance metadata service). But with Spring Boot it doesn't work out of the box and I need to enable local running somehow.
I use 2.2.2.RELEASE version of Spring Boot and 2.2.1.RELEASE version of Spring Cloud. I have a feeling they introduced regression, because in previous versions it worked without problems.
Any ideas how to run the app locally?
Adding the following lines to configuration helps:
cloud.aws.region.static=my region
cloud.aws.stack.auto=false
spring.autoconfigure.exclude=org.springframework.cloud.aws.autoconfigure.metrics.CloudWatchExportAutoConfiguration
So Spring uses AWS default chain but only for credentials. AWS SDK uses it for region and other configuration parameters too. So this is Spring bug for sure.
It still gives a warning about no connection to instance metadata service once during application start but more or less this solution can be used for local running.
If we don't have the last line with excluding CloudWatchExportAutoConfiguration, there will be many exceptions in stack trace while closing the app. I use CloudWatch metrics in my app.
I guess rationale behind excluding aws auto configuration is that it has conflicts with boot actuator but I'm not sure.
Related
I'm trying to update my project Spring Boot version from 2.4.13 to 2.6.12
We were using Spring Cloud 2020.0.0-M6 and I also wanted to bump the version to 2021.0.4
Now my application won't load its remote configuration even though I can see in the logs that it finds the service and the configuration!!
In the above picture you can see my app does find the config-service once deployed to our Development environment.
And after that, it throws me an error because it's trying to use its local configuration where I'm using Environment Variables set from my IDE, using the following syntax ${var}, to replace the value depending on the Run/Debug Configuration.
In the meantime, I'm trying to use Spring Boot 2.6.11 with Spring Cloud 2021.0.4. If I can't get it to work I will have to downgrade it to the last working version until I find the problem.
Any help is appreciated!
Thanks
I am using spring.data.elasticsearch with Elasticsearch 7.14.1 in my Spring Boot (2.5.4) application.
My application.properties is something like this
spring.elasticsearch.rest.uris=elasticsearch:9200
spring.data.elasticsearch.cluster=elasticsearch:9200
spring.data.elasticsearch.repositories.enabled=true
This works fine as long as the invocation is from localhost, no issues. However, when I try to bring up my Spring Boot container, I see a failure with NoReachableHostException
reactor.core.Exceptions$ErrorCallbackNotImplemented: org.springframework.data.elasticsearch.client.NoReachableHostException: Host 'localhost:9200' not reachable. Cluster state is offline.
blah-blah-service
Caused by: org.springframework.data.elasticsearch.client.NoReachableHostException: Host **'localhost:9200'** not reachable. Cluster state is offline.
blah-blah-service
at org.springframework.data.elasticsearch.client.reactive.SingleNodeHostProvider.lambda$lookupActiveHost$3(SingleNodeHostProvider.java:101)
Clearly, my suggestion to use "elasticsearch" host (defined network, that is tested and accessible from within and outside docker containers), hasn't gone well with Spring Data for whatever reason. I have even used
#PropertySource("classpath:mysearch.properties")
in my application to try and coax these properties into the app, but doesn't look like anything works. Is there something I am missing in my Elasticsearch configuration or otherwise?
PS: I have exercised curl http://elasticsearch:9200 from within the container and find no issues
These configurations are Spring Boot specific, Spring Data Elasticsearch does not use them. But as far as I can see, you are configuring the transport client (cluster entry, should not be used anyway) and the imperative REST client, but according to the error message you are using the reactive REST client.
According to the Spring Boot documentation you would need to set spring.data.elasticsearch.client.reactive.endpoints
In the .properties file, I used the below and solved the issue for me;
spring.elasticsearch.rest.uris=http://localhost:<port_number>
spring.data.elasticsearch.client.reactive.endpoints=localhost:<port_number>
I have a spring boot project in which spring scheduler is working fine as i have added logger in scheduler method in my local system using Cron expression.
Problem:
When same spring boot app is deployed over PCF(Pivotal Cloud Foundary) it does not enable the scheduler and no logs are printed neither any error is shown in pcf logs related to scheduler.
While if i hit any controller through postman, logs are printing for that but not of scheduler.
I also provided cron expression value like for every minute in pcf environment variables in app and restarted the app. But that didn't help.
Can anyone suggest me something in this issue?
Thank you in advance for your valuable time!!
When you deploy your application in PCF Cloud space, it takes your code, scan it against available buildpacks unless explicitly provided by user and then creates a container image also known as Droplet using code, build-pack and base container.
If you use cloud config to manage the configurations for spring boot scheduler, it uses auto configurations to load the properties at runtime. In some cases due to the difference in the OS configuration and loading of these configurations at runtime, there will be mismatch between what timezone your app expects and the one that the server understands.
Most of the time it can be resolved by explicitly defining the timezone configuration in PCF manifest file or command line when pushing the application.
E.g. set environment TZ variable.
cf set-env {app-name} TZ 'America/Chicago'
OR by adding following in manifest.yml file:
env:
TZ: America/Chicago
I've created a spring boot project and deployed it on a vm. I've added a command in local.rc that starts the spring boot application on reboot. I want to check whether the command got executed and the application is running. How do I do that?
There are two ways
On system level - you can run your project as a service, which is documented in the Official documentation - Deployments. Then you can query the application status service myapp status.
On application level - include Spring Boot Actuator in your app and use the Actuator endpoints such as /actuator/health as per Official documentation - Production Ready Endpoints. These endpoints can be exposed via HTTP or JMX.
Note: prior to spring boot 2.0 the actuator endpoint is /health
If it's a web project, it makes sense to include spring-boot-actuator (just add a dependency in maven and start the microservice).
In this case, it will automatically expose the following endpoint (for example, its actually can be flexibly set up):
http://<HOST>:<PORT>/health
Just issue an HTTP GET request, and if you get 200 - it's up and running.
If using an actuator is not an option (although it should be really addressed as a first bet), then you can merely telnet to http://<HOST>:<PORT>
The ratio behind this is that that PORT is exposed and ready to "listen" to external connections only after the application context is really started.
I am having an issue where EC2MetaDataUtils.getItems is being invoked on application start up ( Spring boot app), we do not use EC2 and so the calls made to AWS to get Metadata always fail, the application attempts to get this data 3 times and so this is adding around 15 seconds to the start time of the application.
I have been searching high and low for solutions I found a promising solution would suggested the following #EnableAutoConfiguration(exclude = { ContextResourceLoaderAutoConfiguration.class, ContextResourceLoaderConfiguration.class, ContextInstanceDataAutoConfiguration.class })
However when I try to start up the application it complains that ContextResourceLoaderConfiguration.class cannot be excluded as it is not auto configuration; if I just exclude the other 2 the application still invokes the MetaDataUtils.
Has anyone experienced this in the past and managed to resolve it?
Thank you for your time.
Resolved with the following:
#EnableAutoConfiguration(exclude = {ContextInstanceDataAutoConfiguration.class, ContextStackAutoConfiguration.class, ContextResourceLoaderAutoConfiguration.class})
when running spring-boot-application with AWS dependencies ,
It invokes stack auto-configuration , you need to disable it ,
add following to application.yml
cloud.aws.stack.auto: false
SpringBoot application should not do any call to EC2. This mean your are using some AWS specific library/component/what ever and this library on startup do this call.
Please check your dependencies and context configuration. There are nothing about SpringBoot. There is something with your custom dependencies/components.
If you're not using EC2, you can try removing the spring-cloud-aws* libraries from your dependencies.
You can use Spring profiles to differentiate between cloud and default profiles. For cloud profile, you can use spring-cloud-aws artifact to get metadata about EC2 instance which you need EC2 read permission access from an attached IAM role whereas for default profile, you don't need to worry about cloud environment and disable the cloud configuration properties which should not cause an issue for the application startup.