Let config client fail before bean creation (#1977)
If the config client fails and fail fast is enabled, the ConfigClientFailFastException will already be thrown when the bootstrap context is closed instead of during auto-configuration.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
* Copyright 2013-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,7 +21,6 @@ import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.RuntimeHintsRegistrar;
|
||||
import org.springframework.aot.hint.TypeReference;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
@@ -29,11 +28,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.config.ConfigDataLocation;
|
||||
import org.springframework.boot.context.event.ApplicationStartedEvent;
|
||||
import org.springframework.cloud.config.environment.PropertySource;
|
||||
import org.springframework.cloud.context.refresh.ContextRefresher;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
@@ -95,23 +92,6 @@ public class ConfigClientAutoConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
protected class ConfigClientFailFastListener implements ApplicationListener<ApplicationStartedEvent> {
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationStartedEvent event) {
|
||||
try {
|
||||
ConfigClientFailFastException exception = event.getApplicationContext()
|
||||
.getBean(ConfigClientFailFastException.class);
|
||||
throw exception;
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ConfigClientHints implements RuntimeHintsRegistrar {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2020 the original author or authors.
|
||||
* Copyright 2013-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -93,9 +93,9 @@ public class ConfigServerConfigDataLoader implements ConfigDataLoader<ConfigServ
|
||||
return interceptor.apply(new LoadContext(context, resource, binder, this::doLoad));
|
||||
}
|
||||
catch (ConfigClientFailFastException e) {
|
||||
context.getBootstrapContext()
|
||||
.addCloseListener(event -> event.getApplicationContext().getBeanFactory()
|
||||
.registerSingleton(ConfigClientFailFastException.class.getSimpleName(), e));
|
||||
context.getBootstrapContext().addCloseListener(event -> {
|
||||
throw e;
|
||||
});
|
||||
return new ConfigData(Collections.emptyList());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2018-2019 the original author or authors.
|
||||
* Copyright 2018-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,9 +19,11 @@ package sample;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.test.system.CapturedOutput;
|
||||
import org.springframework.boot.test.system.OutputCaptureExtension;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
@@ -39,16 +41,24 @@ public class ApplicationFailFastTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configDataContextFails(CapturedOutput output) {
|
||||
public void configDataContextFailsFast(CapturedOutput output) {
|
||||
assertThatThrownBy(() -> {
|
||||
new SpringApplicationBuilder().sources(Application.class).run("--server.port=0",
|
||||
"--spring.cloud.config.enabled=true", "--spring.cloud.config.fail-fast=true",
|
||||
new SpringApplicationBuilder().sources(Application.class, PropertyInjectionConfiguration.class).run(
|
||||
"--server.port=0", "--spring.cloud.config.enabled=true", "--spring.cloud.config.fail-fast=true",
|
||||
"--spring.config.import=optional:configserver:http://serverhostdoesnotexist:1234",
|
||||
"--spring.cloud.config.server.enabled=false", "--logging.level.org.springframework.retry=TRACE",
|
||||
"--logging.level.org.springframework.cloud.config=TRACE",
|
||||
"--logging.level.org.springframework.boot.context.config=TRACE");
|
||||
}).as("Exception not caused by fail fast").hasMessageContaining("fail fast");
|
||||
assertThat(output).contains("Retry: count=5");
|
||||
assertThat(output).contains("Retry: count=5").doesNotContain("Could not resolve placeholder");
|
||||
}
|
||||
|
||||
@Component
|
||||
private static class PropertyInjectionConfiguration {
|
||||
|
||||
@Value("${some.property}")
|
||||
private String someProperty;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user