Spring Boot Feature Manager not working

CareyBoldenow 96 Reputation points
2021-09-08T20:48:10.853+00:00

Hello,

I have a simple Spring Boot app that is currently using App Configuration and I am trying to extend that app to also use the "Feature Flag" capability in Azure App configuration. However, while everything seems to be wired up properly, the FeatureManager instance never seems to be able to find any of the feature flags I have enabled, so not sure what I am missing.

To start here is a screenshot of 2 feature flags I created in our app configuration resource:

130352-image.png

Netx, here are some of the key files in my app.

pom.xml

<?xml version="1.0" encoding="UTF-8"?>  
  
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">    
  <modelVersion>4.0.0</modelVersion>    
  <parent>   
    <groupId>org.springframework.boot</groupId>    
    <artifactId>spring-boot-starter-parent</artifactId>    
    <version>2.4.5</version>    
    <relativePath/>    
    <!-- lookup parent from repository -->   
  </parent>    
  <groupId>com.example</groupId>    
  <artifactId>config</artifactId>    
  <version>0.0.1-SNAPSHOT</version>    
  <name>config</name>    
  <description>Demo project for Spring Boot</description>    
  <properties>   
    <java.version>11</java.version>   
  </properties>    
  <dependencies>   
    <dependency>   
      <groupId>org.springframework.boot</groupId>    
      <artifactId>spring-boot-starter-web</artifactId>   
    </dependency>  
    <dependency>  
      <groupId>com.azure.spring</groupId>  
      <artifactId>azure-spring-cloud-appconfiguration-config-web</artifactId>  
      <version>2.0.0</version>  
    </dependency>  
    <dependency>  
      <groupId>com.azure.spring</groupId>  
      <artifactId>azure-spring-cloud-feature-management-web</artifactId>  
      <version>2.0.0</version>  
    </dependency>  
  
    <dependency>  
      <groupId>org.projectlombok</groupId>  
      <artifactId>lombok</artifactId>  
      <version>1.18.16</version>  
      <scope>provided</scope>  
    </dependency>  
  
    <dependency>  
      <groupId>org.springframework.boot</groupId>    
      <artifactId>spring-boot-starter-test</artifactId>    
      <scope>test</scope>   
    </dependency>  
    <dependency>  
      <groupId>com.azure</groupId>  
      <artifactId>azure-identity</artifactId>  
      <version>1.3.4</version>  
      <scope>compile</scope>  
    </dependency>  
  </dependencies>    
  <build>   
    <plugins>   
      <plugin>   
        <groupId>org.springframework.boot</groupId>    
        <artifactId>spring-boot-maven-plugin</artifactId>   
      </plugin>  
    </plugins>   
  </build>   
</project>  

bootstrap.properties

spring.cloud.azure.appconfiguration.stores[0].endpoint=${app.configuration.endpoint}  
spring.cloud.azure.appconfiguration.stores[0].label=${spring.profiles.active}  
  
spring.cloud.azure.appconfiguration.stores[0].monitoring.enabled=true  
spring.cloud.azure.appconfiguration.stores[0].monitoring.triggers[0].key=refreshkey-myapp  
spring.cloud.azure.appconfiguration.stores[0].monitoring.triggers[0].label=${spring.profiles.active}  
spring.cloud.azure.appconfiguration.stores[0].monitoring.refresh-interval=${app.configuration.cache.expiry}  
  
spring.application.name=myapp  

Controller

@RestController  
public class HelloController {  
  
    private static final Logger logger = LoggerFactory.getLogger(HelloController.class);  
  
  
    @Autowired  
    MessageProperties messageProperties;  
  
    @Autowired  
    FeatureManager featureManager;  
  
    @GetMapping  
    public Response getMessage() {  
        logger.info("FEATURES: " + featureManager.getAllFeatureNames().size());  
        if (featureManager.isEnabledAsync("EnabledForStore").block()) {  
           logger.info("TRUE!");  
        } else {  
            logger.info("FALSE!");  
        }  
        Response response = new Response();  
        response.setMessage(messageProperties.getAppConfigTest() + " " + messageProperties.getResponseSuffix() + messageProperties.getResponseEnd());  
        return response;  
    }  
  
}  

When I run the app and hit the controller, I always see that getAllFeatureNames returns an empty Set. Furthermore, I have never been able to return true for any of the features I have enabled. As I mentioned above, this same app is able to fetch key/value pairs from App Configuration so I know the connectivity is there, but no luck with the feature flags.

The other thing I would like to know is if we are able to namespace our feature flags by application. I know that we are forced to prefix all feature flags with .appconfig.featureflag/... but as you can see above, I have set the spring.application.name=myapp in the bootstrap.properties which then allows me to namespace/segment key/value pairs in app configuration by creating keys like /myapp/key1 and /myapp/key2. Can we do the same with feature flags? I created a feature flag with key of .appconfig.featureflag/myapp.foobar but I don't know if that will work given that I am unable to access any feature flags at this point. I guess in other words, if we want to use the same "named" feature flag in multiple apps, but enabled in some and not in others, how can we do that?

Any help with the above is greatly appreciated!

Azure App Configuration
Azure App Configuration
An Azure service that provides hosted, universal storage for Azure app configurations.
209 questions
{count} votes

Accepted answer
  1. kobulloc-MSFT 23,496 Reputation points Microsoft Employee
    2021-09-15T18:22:40.317+00:00

    Thank you @CareyBoldenow for bringing this to our attention (and to Andy for working on the investigation)!

    Going through the tutorial Quickstart: Add feature flags to a Spring Boot app, flags were defaulting to false as a result of not being read successfully.

    In the bootstrap.properties file there were 2 lines that needed to be added:

    spring.cloud.azure.appconfiguration.stores[0].feature-flags.enabled=true  
    spring.cloud.azure.appconfiguration.stores[0].feature-flags.label-filter=*  
    

    For the first line (feature-flags.enabled=true), the Azure SDK documentation lists the default value as false so this makes sense. The second line (feature-flags.label-filter=*) may not be a true requirement but it appears to be needed so a wildcard is used here.

    With these additions to the configuration, the "Beta" tab from the example application becomes visible:

    132514-image.png

    The feature name specified in code was the exact name of the App Configuration feature:

    132523-image.png

    132492-image.png

    References:


0 additional answers

Sort by: Most helpful