skip to Main Content

I have been dealing with an issue for a while. I have a spring boot application which I need to integrate with azure application configuration store to dynamically change the properties without restarting the application. Before I explain the issue, here is my setup,

I have following dependencies added in the pom.xml along with
azure-spring-cloud-appconfiguration-config-web:2.11.0,

Spring Cloud dependencies

Spring Boot dependencies

Here is my java class annotated with @Configuration and @RefreshScope,

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;

@Configuration
@RefreshScope
public class CustomConfiguration {

  // property assigned a value  in the application.properties as "version=0.0"
  // property has also been assigned a valuein azure app config store as "version=1.0"
  @Value("${version}")
  private String version;

  // property only assigned value in the azure appconfig store as "test=1.0"

  @Value("${test}")
  private String test;
   
  public String getTest() {
       return test;
  }
    
  public String getVersion() {
       return version;
   }
}

Here is my bootstrap.properties,

spring.cloud.azure.appconfiguration.name=appName
spring.cloud.azure.appconfiguration.stores[0].enabled = true
spring.cloud.azure.appconfiguration.stores[0].connection-string=<Connection String>
spring.cloud.azure.appconfiguration.stores[0].selects[0].key-filter=/appName/
spring.cloud.azure.appconfiguration.stores[0].selects[0].label-filter=
spring.cloud.azure.appconfiguration.stores[0].monitoring.enabled=true
spring.cloud.azure.appconfiguration.stores[0].monitoring.triggers[0].key=/appName/sentinel
spring.cloud.azure.appconfiguration.stores[0].monitoring.refresh-interval= 5s

The issue that I have been experiencing is with a property("version") when it is assigned a value in the application.properties. When a property assigned a value in the application.properties, it does not read value from the azure app configuration. I have another property ("test") which is only assigned value in azure app config store.

When the application is started with this setup, "version" property takes the value from the applicaiton.properties and "test" property takes the value from azure app config store. Also, as I change the sentinel key after modifying other properties ("version", "test") in the azure app configuration, it generates refresh event and recognizes that "version" and "test" properties have been changed. However, it only updates "test" property value and "version" property remain the same as assigned in applciation.properties when it refreshes the spring-boot context.

Can someone help me understand this behavior?

For troubleshooting this issue, I have tried following,

I have compared the maven dependency tree with another application which works as expected (property that has been assigned value in Azure app configuration store overrides the value that is assigned in application.properties) to check if there are any version/artifact discrepancies.

Tried debugging both the application and compared debug logs to identify any difference.

Above troubleshooting steps did not help as the maven dependency tree was showing the same dependencies and the versions. Also, the debug logs were almost similar.

Here is the output of "env" endpoint from spring actuator. This shows that the default value in application.properties is overriding the property in the azure app configuration,

{
    "activeProfiles": [
        "dev"
    ],
    "propertySources": [
        {
            "name": "server.ports",
            "properties": {
                "local.server.port": {
                    "value": 8080
                }
            }
        },
        {
        "name":"bootstrapProperties-/myapp/<azure-app-store-link>{
            "properties": {
                "appconfig.version": {
                    "value": "1.0"
                },
                "sentinel": {
                    "value": "11"
                },
                "test": {
                    "value": "1.0"
                },
                "feature-management.featureManagement": {}
            }
        },
        {
            "name": "Config resource 'file [path\to\application.properties]' via location 'path/to'",
            "properties": {
                "appconfig.version": {
                    "value": "0.0",
                    "origin": "URL [file:path/to/application.properties] - 313:19"
                },
                "test": {
                    "value": "0.0",
                    "origin": "URL [file:path/to/application.properties] - 314:6"
                }
            }
        },
        {
            "name": "class path resource [application.properties]:class path resource [application.properties]",
            "properties": {}
        }
    }
}

2

Answers


  1. Chosen as BEST ANSWER

    I was able to find the root cause of this issue. It turned out to be customPrtopertySource.java class in the codebase. This class was adding application.properties as ReloadablePropertySource to the spring environment property sources. This was making application to give higher precedence to applicaiton.properties than any other sources.


  2. I have added the same dependencies which you used.
    in pom.xml.

        <groupId>com.configuration</groupId>
        <artifactId>sampleapp1</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>sampleapp1</name>
        <description>Demo project for Spring Boot</description>
        <properties>
            <java.version>17</java.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
            <dependency>
                <groupId>com.azure.spring</groupId>
                <artifactId>azure-spring-cloud-appconfiguration-config-web</artifactId>
                <version>2.11.0</version>
            </dependency>
    
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

    Please check my sample CustomConfiguration.

    package com.configuration.sampleapp1;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    @RefreshScope
    
    public class CustomConfiguration {
    
        @Value("${myapp.version}")
        private String version;
    
        @Value("${myapp.apiKey}")
        private String apiKey;
    
        public String getVersion() {
            return version;
        }
    
        public String getApiKey() {
            return apiKey;
        }
    }
    

    Please check the below snippet for more understanding.

    enter image description here

    Then I configured the Application.properties with below for test.

    # Custom Application Properties  
    myapp.version=2.11.0  
    myapp.apiKey=abc123
    
    • Then I created Azure app configuration in portal. I am able to get the Key-value from the app configuration successfully.
      enter image description here

    Result :
    enter image description here

    • I took the connection string into bootstrap.properties to connect with my spring boot application.

    • I am able to get the assigned value’s from the application.properties

    Result :
    enter image description here

    Monitored:

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search