javaspringspring-bootspring-cloudspring-cloud-config

SpringBoot-2 application is not loading entries from bootstrap.yml file


Need your inputs as I am stuck on an issue for long time. I am implementing a scenario where in I am trying to read entires from bootstrap.yaml file in configuration class file.

/src/main/resources/META-INF/spring.factories ->

org.springframework.cloud.bootstrap.BootstrapConfiguration=\
com.xyz.config.BootStrapConfig

/src/main/resources/bootstrap.yml has below entries ->

spring.cloud.bootstrap.enabled: true
spring.application.name: ms-service
aws.service.name: lambda

dependencies in my gradle.build file ->

.........
def poiVersion = "3.14"
def joltVersion = "0.1.1"
def awsSdkVersion = "1.12.585"
def googleGuavaVersion = '24.1-jre'
def springBootVersion = "2.0.0.RELEASE"
def aspectVersion = "1.8.8"
def springCloudVersion = "1.2.2.RELEASE"

api("org.springframework.boot:spring-boot:${springBootVersion}")
api("org.springframework.boot:spring-boot-starter:${springBootVersion}")
api("org.springframework.boot:spring-boot-starter-web:${springBootVersion}")
api("org.springframework.boot:spring-boot-starter-aop:${springBootVersion}")
api("org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}")

api("org.aspectj:aspectjrt:${aspectVersion}")
api("org.aspectj:aspectjweaver:${aspectVersion}")
api('net.sf.json-lib:json-lib:2.4:jdk15')
api('org.apache.commons:commons-lang3:3.7')

api("com.google.guava:guava:$googleGuavaVersion")
api("com.amazonaws:aws-java-sdk-sqs:${awsSdkVersion}")
api("com.amazonaws:aws-java-sdk-sns:${awsSdkVersion}")
api("com.amazonaws:aws-java-sdk-core:${awsSdkVersion}")
api("com.amazonaws:aws-java-sdk-kms:${awsSdkVersion}")
api("com.amazonaws:aws-java-sdk-s3:${awsSdkVersion}")


api("com.amazonaws:elasticache-java-cluster-client:1.1.1")

api("org.springframework.cloud:spring-cloud-aws-messaging:${springCloudVersion}")
api("org.springframework.cloud:spring-cloud-aws-autoconfigure:${springCloudVersion}")

api('org.neo4j:neo4j-cypher-compiler-2.2:2.2.5')
api("com.bazaarvoice.jolt:json-utils:${joltVersion}")
api("com.bazaarvoice.jolt:jolt-core:${joltVersion}")
api('com.nimbusds:oauth2-oidc-sdk:5.63')

api('junit:junit:4.12')

api("org.springframework.boot:spring-boot-starter-test:${springBootVersion}") {
    exclude group: "com.vaadin.external.google", module:"android-json"
}
api('org.skyscreamer:jsonassert:1.2.3'){
    exclude group: "com.vaadin.external.google", module:"android-json"
}

api('com.google.code.gson:gson:2.8.2')

api('com.github.everit-org.json-schema:org.everit.json.schema:1.8.0')
api ('org.json:json:20180130')

api("org.springframework.cloud:spring-cloud-context:2.0.0.RELEASE")
api("org.springframework.cloud:spring-cloud-starter-bootstrap:3.1.8")
api('org.springframework.retry:spring-retry:1.3.1')

api 'org.springframework:spring-aspects:4.3.8.RELEASE'

testImplementation group: 'org.mockito', name: 'mockito-core', version: '2.22.0'
.....

I am trying to read entries in com.xyz.config.BootStrapConfig.java as below

@Configuration
public class BootStrapConfig {

    .....
    @Value("${aws.service.name}")
    private String serviceName;
    
    
    @Value("${spring.application.name}")
    private String appName;
    
    @Bean
        public PropertySourceLocator configSourceLocator() throws URISyntaxException {
            
            log.info("BootStrapConfig - configSourceLocator method: serviceName-{}, app name-{}", serviceName, appName);
            Map<String, Object> config = new HashMap<>();
    
            config.put("url", " code that will fetch value from aws");
            config.put("username", " code that will fetch value from aws");
            config.put("secret","code that will fetch value from aws");
            return environment -> {
                return new MapPropertySource("configparams", config);
            };
        }
    
     .....

Springboot application main class is as below -

package com.xyz;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.aws.messaging.config.annotation.EnableSns;
import org.springframework.cloud.aws.messaging.config.annotation.EnableSqs;
import org.springframework.context.annotation.PropertySource;
import org.springframework.retry.annotation.EnableRetry;

@SpringBootApplication(scanBasePackages = "com.xyz", exclude = {
        org.springframework.cloud.aws.autoconfigure.context.ContextInstanceDataAutoConfiguration.class,
        org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration.class,
        org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration.class
})

@EnableSqs
@EnableSns
@EnableRetry
@PropertySource({ "classpath:object-mapping.properties","classpath:config.properties"})
public class XYZIntegrationApplication {

    public static void main(String[] args) {

        new SpringApplicationBuilder(XYZIntegrationApplication.class)
                .properties("spring.config.location:classpath:application.yml")
                .build().run(args);
    }
}

Did a gradle build and its was successful, but when I run the application in intellij locally, application fails with below error

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.xyz.config.BootStrapConfig': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'aws.service.name' in value "${aws.service.name}"
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:405) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1420) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]

Solution

  • In yml files, the values should be properly indented under their respective keys.

    the bootstrap.yml should be like this:

    spring:
      cloud:
        bootstrap:
          enabled: true
      application:
        name: ms-service
    
    aws:
      service:
        name: lambda