vanvasquez
vanvasquez

Reputation: 979

Unable to disable ContextCredentialsAutoConfiguration in Spring boot application

I am working on a Spring Batch application that should use aws cloud only for specific profiles. Currently I have a profile that uses aws and another that shouldn't as it runs the application locally with a local database, local files, etc. (Meanwhile the AWS profile will use RDS, S3 ,etc)

For my configuration using the AWS profile I have the following:

@Configuration
@Profile("!localDev")

public class FileReaderConfigAWS {

@Value("${cloud.aws.s3.bucket}")
private String amazonS3Bucket;

@Autowired
private ResourceLoader resourceLoader;

private static final Logger logger = LoggerFactory.getLogger(FileReaderConfigAWS.class);


@Bean
@StepScope
public FlatFileItemReader<Object> flatFileReader(@Value("#{jobParameters['inputFile']}") String inputFile,  LineMapper
    lineMapper) {
    FlatFileItemReader<Object> flatFileItemReader = new FlatFileItemReader<>();

    flatFileItemReader.setResource(resourceLoader.getResource("s3://" + this.amazonS3Bucket + "/" + inputFile));

    flatFileItemReader.setLineMapper(lineMapper);

    return flatFileItemReader;
}


@Bean
public AbstractFileValidator inputFileValidator() {
    InputS3Validator inputS3Validator = new InputS3Validator();
    inputS3Validator.setRequiredKeys(new String[]{InputFileSystemValidator.INPUT_FILE});
    return inputS3Validator;
}

}

For my localDev Profile I have the following:

@Profile("localDev")
@Configuration
public class FileReaderConfigLocalDev {


@Bean
@StepScope
public FlatFileItemReader<Object> flatFileReader(@Value("#{jobParameters['inputFile']}") String inputFile, LineMapper lineMapper) {
    FlatFileItemReader<Object> flatFileItemReader = new FlatFileItemReader<>();
    flatFileItemReader.setResource(new FileSystemResource(inputFile));

    flatFileItemReader.setLineMapper(lineMapper);

    return flatFileItemReader;
}

@Bean
public AbstractFileValidator inputFileValidator() {
    InputFileSystemValidator inputFileValidator = new InputFileSystemValidator();
    inputFileValidator.setRequiredKeys(new String[]{InputFileSystemValidator.INPUT_FILE});
    return inputFileValidator;
}

}

When I try to run the Spring Boot Main class using the localDev profile (-Dspring.profiles.active=localDev) I get the following error:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'amazonS3': Invocation of init method failed; nested exception is java.lang.IllegalStateException: There is not EC2 meta data available, because the application is not running in the EC2 environment. Region detection is only possible if the application is running on a EC2 instance
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    ... 18 common frames omitted
Caused by: java.lang.IllegalStateException: There is not EC2 meta data available, because the application is not running in the EC2 environment. Region detection is only possible if the application is running on a EC2 instance
    at org.springframework.util.Assert.state(Assert.java:70) ~[spring-core-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.cloud.aws.core.region.Ec2MetadataRegionProvider.getRegion(Ec2MetadataRegionProvider.java:39) ~[spring-cloud-aws-core-1.2.1.RELEASE.jar:1.2.1.RELEASE]
    at org.springframework.cloud.aws.core.config.AmazonWebserviceClientFactoryBean.createInstance(AmazonWebserviceClientFactoryBean.java:98) ~[spring-cloud-aws-core-1.2.1.RELEASE.jar:1.2.1.RELEASE]
    at org.springframework.cloud.aws.core.config.AmazonWebserviceClientFactoryBean.createInstance(AmazonWebserviceClientFactoryBean.java:44) ~[spring-cloud-aws-core-1.2.1.RELEASE.jar:1.2.1.RELEASE]
    at org.springframework.beans.factory.config.AbstractFactoryBean.afterPropertiesSet(AbstractFactoryBean.java:134) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    ... 25 common frames omitted

As I started debugging I found that once you add spring-cloud-aws-autoconfigure to your pom.xml then there seems to be no way to disable aws autoconfigure for non-aws environments at runtime.
I tried the following:

@EnableAutoConfiguration(exclude = {ContextCredentialsAutoConfiguration.class, ContextStackAutoConfiguration.class})

but still won't work, any ideas anyone?

Thanks in advance!

Upvotes: 2

Views: 6799

Answers (3)

Sunil Valmiki
Sunil Valmiki

Reputation: 616

You need to set 2 Properties in the application.properties file of resources

cloud.aws.region.static=us-east-2
cloud.aws.stack.auto=false

Please specify the correct region in the properties file.

This will configure the region for your application with 1st property and 2nd property will stop the auto-configuration of the application.

Upvotes: 6

vanvasquez
vanvasquez

Reputation: 979

In the end I decided to remove the spring-cloud-aws-autoconfigure dependency altogether from my pom.xml.
I created an aws-config.xml file under resources with the following information:

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:aws-context="http://www.springframework.org/schema/cloud/aws/context"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
                       http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
                       http://www.springframework.org/schema/cloud/aws/context
                       http://www.springframework.org/schema/cloud/aws/context/spring-cloud-aws-context-1.0.xsd">

    <aws-context:context-credentials>
        <aws-context:instance-profile-credentials/>
        <aws-context:simple-credentials access-key="${cloud.aws.credentials.accessKey:}" secret-key="${cloud.aws.credentials.secretKey:}"/>
    </aws-context:context-credentials>

    <aws-context:context-region region="${cloud.aws.region.static:}"/>
    <aws-context:context-resource-loader/>
</beans>

and I am referencing the above file in the java configuration file that uses the aws environment as follows:

@Configuration
@Profile("!localDev")

@ImportResource("classpath:/aws-config.xml")
public class FileReaderConfigAWS {

    @Value("${cloud.aws.s3.bucket}")
    private String amazonS3Bucket;

    @Autowired
    private ResourceLoader resourceLoader;
...

Upvotes: 2

le0diaz
le0diaz

Reputation: 2508

As for version of spring cloud Brixton.SR7, to configure manually the region you would set in your application.properties (or .xml, .yml whatever you're using). This parameter should be ONLY for your dev env, unless you truly need to specify it.

cloud.aws.region.static=us-east-1

I also had to set next property for dev, but maybe you dont need it.

cloud.aws.stack.auto=false

more reference information in http://cloud.spring.io/spring-cloud-static/spring-cloud-aws/1.1.4.RELEASE/#_region_configuration

Upvotes: 10

Related Questions