Describe the bug

Summary

With

  <properties>
    <java.version>11</java.version>
    <spring-cloud.version>Hoxton.SR8</spring-cloud.version>
  </properties>
  • when put the application.properties in config server, it's able fetch and luanch the app.
  • when add logging.config=${spring.cloud.config.uri}/${spring.application.name}/default/master/logback.xml in application.properties, and also put logback.xml file in Config Server, but when fetch the logback.xml, it would meet 401 error.

Details

  • Create an azure spring cloud service with the config server which need certificates and authentication.
  • Then put the application.properties, logback.xml file in the Config server.
  • add a settings in application.properties such as: logging.config=${spring.cloud.config.uri}/${spring.application.name}/default/master/logback.xml refer to the logback.xml.

As I know, the Hoxton.SR8 can fetch the application.properties correctly, while fetch logback.xml would meet issue as below:

"message"":""Error opening logging config file https://myapp.svc.azuremicroservices.io/config/application/default/master/logback.xml"",""logger_name"":""org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration"",""thread_name"":""main"",""level"":""WARN"",""level_value"":30000,""stack_trace"":""java.io.IOException:
Server returned HTTP response code: 401 for URL:
https://myapp.svc.azuremicroservices.io/config/application/default/master/logback.xml
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1900)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1498)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:268)
at java.net.URL.openStream(URL.java:1068)
at org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration.reinitializeLoggingSystem(PropertySourceBotstrapConfiguration.java:143)
at org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration.initialize(PropertySourceBootstrapConfiguration.java:126)\n\tat org.springframework.boot.SpringApplication.applyInitializers(SpringApplication.java:626)
at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:370)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
at com.ethoca.eliminatorissuerapi.EliminatorIssuerApiApplication.main(EliminatorIssuerApiApplication.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:107)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88)\n"",""projName"":""[MYAPP]""}

I've checked the Hoxton.SR8's code, when it load logback.xml file, it goes through:

public void initialize(ConfigurableApplicationContext applicationContext) {

    while(true) {
        Collection source;
        do {
            do {
                if (!var5.hasNext()) {
                    if (!empty) {
                        // ....
                        this.reinitializeLoggingSystem(environment, logConfig, logFile);   <----Here
                        // ....
                    }
                    return;
                }
            } while(source == null);
        } while(source.size() == 0);
}

Then

private void reinitializeLoggingSystem(ConfigurableEnvironment environment, String oldLogConfig, LogFile oldLogFile) {
     // ....
            ResourceUtils.getURL(logConfig).openStream().close();   <--- Here!!
     // ....
    }
}

While by URL, it would try to use net.URL to access this resource without auth.

public static URL getURL(String resourceLocation) throws FileNotFoundException {
    Assert.notNull(resourceLocation, "Resource location must not be null");
    if (resourceLocation.startsWith("classpath:")) {

    } else {
        try {
            return new URL(resourceLocation);  // <-- Access here by a normal net call.
        } ... 
    }
}

Here is no auth with a normal URL() call, so it would meet a 401 error.

It makes a little confused that:

  • application.properties
  • logback.xml

both are located on Config Server with authenticate required, but application.properities loaded success, while logback.xml load with failure.

When load the logback.xml, it may also need to go-through the correct path to fetch the certificates and authentication to avoid 401 error.

Sample

  • https://github.com/krish-gh/azure-spring-cloud-test

Comment From: spencergibb

ResourceUtils is a framework class. I suggest writing a BootstrapConfiguration that gets the logging configuration ahead of time as we have no plans to implement that.

Comment From: spring-projects-issues

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

Comment From: spring-projects-issues

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.

Comment From: JiYou

@spencergibb thanks for your feed back. I want double check is BootStrapConfiguration. Is BootStrapConfiguration usage as below?

@Configuration
public class MyBootstrapConfiguration implements PropertySourceLocator {

    private static final Logger log = LoggerFactory.getLogger(BootstrapConfigurer .class);
    /**
     * @param environment the current Environment
     * @return a PropertySource or null if there is none
     * @throws IllegalStateException if there is a fail fast condition
     */
    @Override
    public PropertySource<?> locate(Environment environment) {
        // fetch and set the config XXXX.
    }
}

Then add line in META-INF/spring.factories:

org.springframework.cloud.bootstrap.BootstrapConfiguration=\
com.xxx.MyBootstrapConfiguration