I have a problem with the refreshing of a ConfigurationProperties object. The Properties includes a Map<String, MyObject> object. My problem is that when I remove from the configuration one entry of this map, the map in the Properties object still includes this entry. I guess my issue could be similar like #183.

I prepared a sample project for you. https://github.com/tommyziegler/spring-cloud-prototype.

You can clone the project and follow my sample and see my issue.

Sample

Clone the sample repo

 $ git clone https://github.com/tommyziegler/spring-cloud-prototype.git
 $ cd spring-cloud-prototype

Start the Server with 2 Rel's and see the Rel's in the interface

Following two Rels 'rel1' and 'rel2' are in the config file "config-server/config-server.yml" defined. - config-server/config-server.yml

com:
  tommyziegler:
    server01: http://localhost:8083

    cloud-server:
      links:
        rel1:
          href: ${com.tommyziegler.server01}/rel1
          method: GET
        rel2:
          href: ${com.tommyziegler.server01}/rel2
          method: GET
        # rel3:
        #   href: ${com.tommyziegler.server01}/rel3
        #   method: GET

Start the Server

$ mvn spring-boot:run

Curl the RootRestInterface

$ curl http://localhost:8080/rest
{
  "links" : [ {
    "rel" : "rel1",
    "href" : "http://localhost:8083/rel1",
    "method" : "GET"
  }, {
    "rel" : "rel2",
    "href" : "http://localhost:8083/rel2",
    "method" : "GET"
  } ]
}

Enable the 3rd Rel, refresh the Properties to see the Rel's in the interface

Extend one Rel 'rel3' in the config file "config-server/config-server.yml" defined. - config-server/config-server.yml

com:
  tommyziegler:
    server01: http://localhost:8083

    cloud-server:
      links:
        rel1:
          href: ${com.tommyziegler.server01}/rel1
          method: GET
        rel2:
          href: ${com.tommyziegler.server01}/rel2
          method: GET
        rel3:
          href: ${com.tommyziegler.server01}/rel3
          method: GET

Commit the 3rd Rel into the local Git repo for Spring-Cloud.

$ git commit config-server/config-server.yml -m "Activate 3rd rel"

Refresh the Scope to reload the changed configuration file.

$ curl -X POST http://localhost:8080/actuator-endpoint/refresh

Curl the RootRestInterface

$ curl http://localhost:8080/rest
{
  "links" : [ {
    "rel" : "rel1",
    "href" : "http://localhost:8083/rel1",
    "method" : "GET"
  }, {
    "rel" : "rel2",
    "href" : "http://localhost:8083/rel2",
    "method" : "GET"
  }, {
    "rel" : "rel3",
    "href" : "http://localhost:8083/rel3",
    "method" : "GET"
  } ]
}

Deactivate the 3rd Rel, refresh the Properties to see the Rel's in the interface

Deactivate the 3rd Rel 'rel3' in the config file "config-server/config-server.yml" which we defined in the previous step. - config-server/config-server.yml

com:
  tommyziegler:
    server01: http://localhost:8083

    cloud-server:
      links:
        rel1:
          href: ${com.tommyziegler.server01}/rel1
          method: GET
        rel2:
          href: ${com.tommyziegler.server01}/rel2
          method: GET
        #rel3:
          #href: ${com.tommyziegler.server01}/rel3
          #method: GET

Commit the deactivation of the 3rd Rel into the local Git repo for Spring-Cloud.

$ git commit config-server/config-server.yml -m "Deactivate 3rd rel"

Refresh the Scope to reload the changed configuration file.

$ curl -X POST http://localhost:8080/actuator-endpoint/refresh

Curl the RootRestInterface

$ curl http://localhost:8080/rest
{
  "links" : [ {
    "rel" : "rel1",
    "href" : "http://localhost:8083/rel1",
    "method" : "GET"
  }, {
    "rel" : "rel2",
    "href" : "http://localhost:8083/rel2",
    "method" : "GET"
  }, {
    "rel" : "rel3",
    "href" : "http://localhost:8083/rel3",
    "method" : "GET"
  } ]
}

Doesn't look for me like expected.

Conclusion / Question

After deactivating the 3rd Rel my interface still returns it. Is that like expected!? Do I still need maybe an annotation to build up the whole PropertiesObject? Is that even a Spring-Cloud problem, or more an ConfigurationProperties issue?

I would appreciate if you could give some hint how I could solve this issue, as we would like to take such an service online, where we can specify which Rel's on an RootRest Interface are included via a Git Repository.

Thx a lot

Tommy

Comment From: dsyer

Your problem is that your @ConfgurationProperties bean is not in @RefreshScope. You can put it in the right scope by explicitly marking it as a @Component instead of using @EnableConfigurationProperties to define the bean.

P.S. you don't need a config server to test it. Just the app and some local config files.

Comment From: abhisheksarkar30

I too faced this same issue. Here is the solution that worked for me:

  1. Keep the variable name as linksConfig(which is different than the java binding variable i.e. links) along with it's getter.
  2. Create just a setter of links(not linksConfig by the above variable name) with body :

public void setLinks(Map<String, HrefAndMethod> links) { this.linksConfig = links; }

Alternative simpler solution: 1. Considering your variable name is 'links', you need to keep the setter name as 'setLinks' ofcourse, but don't keep the getter name as 'getLinks'. Keep some other name for getter like 'getLinksConfig' which you'll use internally in your code.

Let me know if you still face an issue.