question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Config server yml or properties endpoints can produce unexpected results when merging collections and maps

See original GitHub issue

Please review the attached YAML file for sample properties. Note the default profile has an array of PromoCode objects defined. When a SpringBoot application is configured to talk to the Config Server with the appropriate profile, you get the correct response. However, when you request the properties or yaml view, you get a mixed array of the 2 profiles.

http://localhost:8888/promoCodes/default - produces correct json
http://localhost:8888/promoCodes/dev - produces correct json

Alternate views produce correct results for default profile

http://localhost:8888/promoCodes-default.properties

promos.promoCards[0].client: Google Nexus 6P     <----
promos.promoCards[0].description: Free stuff for Google users     <----
promos.promoCards[0].endDate: 2016-04-26T20:01:30.781Z     <----
promos.promoCards[0].image: http://google.com/images/coolpic.jpg     <----
promos.promoCards[0].name: P1     <----
promos.promoCards[0].platform: Android     <----
promos.promoCards[0].startDate: 2016-04-26T20:01:30.781Z     <----
promos.promoCards[0].thumbnail: http://google.com/images/coolpic.jpg     <----
promos.promoCards[1].client: Google Nexus 5X
promos.promoCards[1].description: Free stuff for Google users
promos.promoCards[1].endDate: 2016-04-26T20:01:30.781Z
promos.promoCards[1].image: http://google.com/images/coolpic.jpg
promos.promoCards[1].name: P2
promos.promoCards[1].platform: Android
promos.promoCards[1].startDate: 2016-04-26T20:01:30.781Z
promos.promoCards[1].thumbnail: http://google.com/images/coolpic.jpg
promos.promoCards[2].client: iPhone 6S
promos.promoCards[2].description: Expensive stuff from Steve
promos.promoCards[2].endDate: 2016-04-26T20:01:30.781Z
promos.promoCards[2].image: http://apple.com/images/coolpic.jpg
promos.promoCards[2].name: P3
promos.promoCards[2].platform: iOS 9
promos.promoCards[2].startDate: 2016-04-26T20:01:30.781Z
promos.promoCards[2].thumbnail: http://apple.com/images/coolpic.jpg
promos.promoCards[3].client: Nokia Lumia 8610
promos.promoCards[3].description: Bad stuff for windoze users
promos.promoCards[3].endDate: 2016-04-26T20:01:30.781Z
promos.promoCards[3].image: http://microsoft.com.com/images/coolpic.jpg
promos.promoCards[3].name: P4
promos.promoCards[3].platform: Windoze
promos.promoCards[3].startDate: 2016-04-26T20:01:30.781Z
promos.promoCards[3].thumbnail: http://microsoft.com.com/images/coolpic.jpg

Alternate views produce incorrect results for dev profile

http://localhost:8888/promoCodes-dev.properties

promos.promoCards[0].client: Nokia Lumia 8888     <----
promos.promoCards[0].description: Bad stuff for windoze users     <----
promos.promoCards[0].endDate: 2016-04-26T20:01:30.781Z     <----
promos.promoCards[0].image: http://microsoft.com.com/images/coolpic.jpg     <----
promos.promoCards[0].name: P4     <----
promos.promoCards[0].platform: Windoze     <----
promos.promoCards[0].startDate: 2016-04-26T20:01:30.781Z     <----
promos.promoCards[0].thumbnail: http://microsoft.com.com/images/coolpic.jpg     <----
promos.promoCards[1].client: Google Nexus 5X
promos.promoCards[1].description: Free stuff for Google users
promos.promoCards[1].endDate: 2016-04-26T20:01:30.781Z
promos.promoCards[1].image: http://google.com/images/coolpic.jpg
promos.promoCards[1].name: P2
promos.promoCards[1].platform: Android
promos.promoCards[1].startDate: 2016-04-26T20:01:30.781Z
promos.promoCards[1].thumbnail: http://google.com/images/coolpic.jpg
promos.promoCards[2].client: iPhone 6S
promos.promoCards[2].description: Expensive stuff from Steve
promos.promoCards[2].endDate: 2016-04-26T20:01:30.781Z
promos.promoCards[2].image: http://apple.com/images/coolpic.jpg
promos.promoCards[2].name: P3
promos.promoCards[2].platform: iOS 9
promos.promoCards[2].startDate: 2016-04-26T20:01:30.781Z
promos.promoCards[2].thumbnail: http://apple.com/images/coolpic.jpg
promos.promoCards[3].client: Nokia Lumia 8610
promos.promoCards[3].description: Bad stuff for windoze users
promos.promoCards[3].endDate: 2016-04-26T20:01:30.781Z
promos.promoCards[3].image: http://microsoft.com.com/images/coolpic.jpg
promos.promoCards[3].name: P4
promos.promoCards[3].platform: Windoze
promos.promoCards[3].startDate: 2016-04-26T20:01:30.781Z
promos.promoCards[3].thumbnail: http://microsoft.com.com/images/coolpic.jpg

Note the difference in promos.promoCards[0] between the 2 results indicated by <----.

The desired output should be for the dev profile:

http://localhost:8888/promoCodes-dev.properties

promos.promoCards[0].client: Nokia Lumia 8888
promos.promoCards[0].description: Bad stuff for windoze users
promos.promoCards[0].endDate: 2016-04-26T20:01:30.781Z
promos.promoCards[0].image: http://microsoft.com.com/images/coolpic.jpg
promos.promoCards[0].name: P4
promos.promoCards[0].platform: Windoze
promos.promoCards[0].startDate: 2016-04-26T20:01:30.781Z
promos.promoCards[0].thumbnail: http://microsoft.com.com/images/coolpic.jpg

The issue occurs in org.springframework.cloud.config.server.environment.EnvironmentController, specifically convertToProperties(Environment environment):

private Map<String, Object> convertToProperties(Environment profiles) {
    Map<String, Object> map = new TreeMap<>();
    List<PropertySource> sources = new ArrayList<>(
            profiles.getPropertySources());
    Collections.reverse(sources);
    for (PropertySource source : sources) {
        @SuppressWarnings("unchecked")
        Map<String, String> value = (Map<String, String>) source.getSource();
        map.putAll(value);                               <-- (No checking for existing array from earlier profile with same name)
    }
    postProcessProperties(map);
    return map;
}

The issue is the for loop over the PropertySources. The Map<String, String> value has a key that contains all the individual promos.promoCards[X] entries individually and puts them all on each iteration into a final map, replacing any duplicates. However, in the case of a YAML list, it should also be checking if any other ‘promos.promoCards[’ exists as keys and remove them before adding all of the current iteration to the resulting map.

promoCodes.yml.txt

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
dsyercommented, Nov 23, 2020

This issue was closed as “fixed” more than 4 years ago. If you are experiencing a problem with the latest version, it would be better to open a new issue as it’s unlikely to be related.

0reactions
velykovcommented, Nov 23, 2020

Yep, thank you

Read more comments on GitHub >

github_iconTop Results From Across the Web

Spring Cloud Config
An example would be properties from the Spring Cloud Config Server. ... This can lead to unexpected behaviour such as missing properties.
Read more >
Spring Boot - merging map of map property - Stack Overflow
This is working as designed. The application.yml can be seen as providing the default values for other profiles to override.
Read more >
Server-Side Apply - Kubernetes
Server -Side Apply helps users and controllers manage their resources through declarative configurations. Clients can create and modify their ...
Read more >
Configuring Infinispan caches
In a distributed cache, a key is allocated to a list of nodes with an opaque algorithm. There is no easy way to...
Read more >
Configuration properties | Bitbucket Data Center and Server 8.6
This page describes the configuration properties that can be used to control behavior in Bitbucket Data Center and Server. Create the bitbucket.properties ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found