Prevent Spring Boot Invoking EC2MetadataUtils.getItems on startup - java

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.

Related

Spring Boot 2.6.12 compatibility with Spring Cloud (Config) 2021.0.4

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

Spring Cloud Consul Config not working with Spring Boot 2.6.6

I tried to follow the new changes with the latests versions of Spring, where the bootstrap.yaml has been removed, and use the "spring.config.import" property, but I am not able to make my application work (discovery is working fine, but not config server). I am doing so many tries and errors, so it does not make so much sense to copy my current properties, but I will give all the details, so maybe someone is able to identify what is going on:
In my POM, there is already the next dependencies: "spring-cloud-starter-config", "spring-cloud-starter-consul-all", "spring-cloud-starter-consul-discovery" and "spring-cloud-starter-consul-config". Spring Cloud version is "2021.0.1" and Consul "3.1.0".
Main class annotated with #EnableDiscoveryClient
Using "application.properties-development", not YAML, and SPRING_PROFILES_ACTIVE=development
Application name is "profiles"
In my Consul instance, in the "Key / Value" section, I have the next structure: Consul Structure (/config/development/profiles and JSON with the properties to load).
It would be nice that, as with the Cloud Config Server, if no property file is found, it would allow me to run the application.
Thank you in advance.
Cheers!

How to run the app with spring-cloud-starter-aws locally?

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.

How to load changed environment variable in spring boot application running in PCF without restarting application?

We have a spring boot application running in PCF and it reads the PCF environment variables(CF_INSTANCE_INDEX, CF_INSTANCE_ADDR,..) from an application. Based on those variables, we are trying to implement the logic for a scheduler. While running this scheduler, these variables' values could have changed. Is there a way to refresh/reload bean that have env values during runtime?
we used #RefreshScope annotation on config properties bean.
#Configuration
#RefreshScope
public class PcfEnvProperties{
#Value("${CF_INSTANCE_INDEX}")
private int intanceIndex;
#Value("${CF_INSTANCE_ADDR}")
private String intanceAddr;
...
}
and refresh using
context.getBean(RefreshScope.class).refresh("PcfEnvProperties");
PcfEnvProperties pcfEnv = context.getBean(PcfEnvProperties.class);
But It is not loading the recently changed env variable into running application. Any ideas on how to accomplish this?
You can use Spring Cloud Config Server in combination with Spring Actuator to expose an endpoint in your service that will refresh the application's properties on the fly. You could set up your scheduler to hit this endpoint on a timer or as needed.
Here is one tutorial I found that seems pretty straightforward: https://jeroenbellen.com/manage-and-reload-spring-application-properties-on-the-fly/
You may have to play with the setup depending on how your platform is configured, but I believe it should do what you're wanting. We have deployed many java web services on our PCF platform using this actuator/config server approach, and we can just make a call to the refresh endpoint and it successfully pulls in (and overwrites when necessary) the new properties and values from the config server. Also you can pull out a list of the property names and values that changed from the response.
I'm not familiar with the specific property values you mentioned, but as long as they are normally a part of Spring's ApplicationContext (where properties usually are found) then you should be able to pull in changed values using this approach with Spring's cloud config server and actuator libraries.
Hope this helps

Spring boot application shutting down on AWS

I have a Spring boot web application running on Production deployed on Amazon Web Servers. I have create two instances of my Web applications. But sometimes one/both instance(s) automatically stops. I can't understand how the process are killed automatically.
This issue is affecting many users experience. I am using Spring Boots default properties for tomcat.
Check your application.properties for endpoints.shutdown.enabled=true.
Perhaps the shutdown endpoint is getting called by someone.
Also, scan your code for any 'System.exit'
Also, the jvm may be crashing...
Is it stopping gracefully? Are there any logs?
Found the problem:
springBoot {
mainClass = ''
executable = true
buildInfo()
}
executable needs to be changed to false

Categories

Resources