Affects: since 4.1


Yaml file like bellow:

root:
  webservices:
    "[domain.test:8080]":
      - username: me
        password: mypassword

Yaml's map to json like

{
   "webservices": {
      "[domain.test:8080]": [
         {
            "username": "me",
            "password": "mypassword"
         }
      ]
   }
}

should equals properties file like:

root.webservices.[[domain.test\:8080]][0].username=me
root.webservices.[[domain.test\:8080]][0].password=mypassword

or:

root.webservices[[domain.test\:8080]][0].username=me
root.webservices[[domain.test\:8080]][0].password=mypassword

Both properties file is acceptable for Spring Boot Binding Maps

Reproduce Test Case is

    @Test
    void loadNestedEscapedProperties() throws Exception {

        String yaml = "root:\n" +
                "  webservices:\n" +
                "    \"[domain.test:8080]\":\n" +
                "      - username: me\n" +
                "        password: mypassword\n";
        String propsStr = "root.webservices[[domain.test\\:8080]][0].username=me\n" +
                "root.webservices[[domain.test\\:8080]][0].password=mypassword";
        final PropertiesFactoryBean factory = new PropertiesFactoryBean();
        factory.setLocations(new ByteArrayResource(propsStr.getBytes(StandardCharsets.UTF_8)));
        factory.setSingleton(false);
        final Properties properties = factory.getObject();

        final YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
        yamlFactory.setResources(new ByteArrayResource(yaml.getBytes(StandardCharsets.UTF_8)));
        assertThat(yamlFactory.getObject()).isEqualTo(properties);
    }

Current it is failed like bellow

expected: {"root.webservices[[domain.test:8080]][0].password"="mypassword", "root.webservices[[domain.test:8080]][0].username"="me"}
but was : {"root.webservices[domain.test:8080][0].password"="mypassword", "root.webservices[domain.test:8080][0].username"="me"}
org.opentest4j.AssertionFailedError: 
expected: {"root.webservices[[domain.test:8080]][0].password"="mypassword", "root.webservices[[domain.test:8080]][0].username"="me"}
but was : {"root.webservices[domain.test:8080][0].password"="mypassword", "root.webservices[domain.test:8080][0].username"="me"}
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at org.springframework.beans.factory.config.YamlPropertiesFactoryBeanTests.loadNestedEscapedProperties(YamlPropertiesFactoryBeanTests.java:270)

It seems there is a bug cause yaml's nested map is flatten incorrectly like

root.webservices[domain.test:8080][0].username=me
root.webservices[domain.test:8080][0].password=mypassword

Comment From: ian4hu

See https://github.com/spring-cloud/spring-cloud-config/issues/1595

Comment From: ian4hu

related #27022

Comment From: snicoll

@ian4hu you said you had some code to attempt to fix this issue. Would you mind sharing that?