Commit fef76a64 by Johannes Edmeier

Extract core- from web-config

parent d49f16a0
...@@ -12,6 +12,7 @@ import org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration.Res ...@@ -12,6 +12,7 @@ import org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration.Res
import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import de.codecentric.boot.admin.config.AdminServerCoreConfiguration;
import de.codecentric.boot.admin.config.AdminServerWebConfiguration; import de.codecentric.boot.admin.config.AdminServerWebConfiguration;
import de.codecentric.boot.admin.config.RevereseZuulProxyConfiguration; import de.codecentric.boot.admin.config.RevereseZuulProxyConfiguration;
import spring.boot.admin.turbine.web.TurbineController; import spring.boot.admin.turbine.web.TurbineController;
...@@ -51,6 +52,7 @@ public class TurbineAutoConfigurationTest { ...@@ -51,6 +52,7 @@ public class TurbineAutoConfigurationTest {
applicationContext.register(PropertyPlaceholderAutoConfiguration.class); applicationContext.register(PropertyPlaceholderAutoConfiguration.class);
applicationContext.register(RestTemplateConfiguration.class); applicationContext.register(RestTemplateConfiguration.class);
applicationContext.register(ServerPropertiesAutoConfiguration.class); applicationContext.register(ServerPropertiesAutoConfiguration.class);
applicationContext.register(AdminServerCoreConfiguration.class);
applicationContext.register(AdminServerWebConfiguration.class); applicationContext.register(AdminServerWebConfiguration.class);
applicationContext.register(RevereseZuulProxyConfiguration.class); applicationContext.register(RevereseZuulProxyConfiguration.class);
applicationContext.register(TurbineAutoConfiguration.class); applicationContext.register(TurbineAutoConfiguration.class);
......
/*
* Copyright 2014 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.codecentric.boot.admin.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.web.client.DefaultResponseErrorHandler;
import de.codecentric.boot.admin.journal.ApplicationEventJournal;
import de.codecentric.boot.admin.journal.store.JournaledEventStore;
import de.codecentric.boot.admin.journal.store.SimpleJournaledEventStore;
import de.codecentric.boot.admin.registry.ApplicationIdGenerator;
import de.codecentric.boot.admin.registry.ApplicationRegistry;
import de.codecentric.boot.admin.registry.HashingApplicationUrlIdGenerator;
import de.codecentric.boot.admin.registry.StatusUpdateApplicationListener;
import de.codecentric.boot.admin.registry.StatusUpdater;
import de.codecentric.boot.admin.registry.store.ApplicationStore;
import de.codecentric.boot.admin.registry.store.SimpleApplicationStore;
import de.codecentric.boot.admin.web.client.BasicAuthHttpHeaderProvider;
import de.codecentric.boot.admin.web.client.HttpHeadersProvider;
@Configuration
@EnableConfigurationProperties(AdminServerProperties.class)
public class AdminServerCoreConfiguration {
private final AdminServerProperties adminServerProperties;
public AdminServerCoreConfiguration(AdminServerProperties adminServerProperties) {
this.adminServerProperties = adminServerProperties;
}
@Bean
@ConditionalOnMissingBean
public ApplicationRegistry applicationRegistry(ApplicationStore applicationStore,
ApplicationIdGenerator applicationIdGenerator) {
return new ApplicationRegistry(applicationStore, applicationIdGenerator);
}
@Bean
@ConditionalOnMissingBean
public ApplicationIdGenerator applicationIdGenerator() {
return new HashingApplicationUrlIdGenerator();
}
@Bean
@ConditionalOnMissingBean
public HttpHeadersProvider httpHeadersProvider() {
return new BasicAuthHttpHeaderProvider();
}
@Bean
@ConditionalOnMissingBean
public StatusUpdater statusUpdater(RestTemplateBuilder restTemplBuilder,
ApplicationStore applicationStore) {
RestTemplateBuilder builder = restTemplBuilder
.messageConverters(new MappingJackson2HttpMessageConverter())
.errorHandler(new DefaultResponseErrorHandler() {
@Override
protected boolean hasError(HttpStatus statusCode) {
return false;
}
});
StatusUpdater statusUpdater = new StatusUpdater(builder.build(), applicationStore,
httpHeadersProvider());
statusUpdater.setStatusLifetime(adminServerProperties.getMonitor().getStatusLifetime());
return statusUpdater;
}
@Bean
@Qualifier("updateTaskScheduler")
public TaskScheduler updateTaskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(1);
taskScheduler.setRemoveOnCancelPolicy(true);
taskScheduler.setThreadNamePrefix("updateTask");
return taskScheduler;
}
@Bean
@ConditionalOnMissingBean
public StatusUpdateApplicationListener statusUpdateApplicationListener(
StatusUpdater statusUpdater,
@Qualifier("updateTaskScheduler") TaskScheduler taskScheduler) {
StatusUpdateApplicationListener listener = new StatusUpdateApplicationListener(
statusUpdater, taskScheduler);
listener.setUpdatePeriod(adminServerProperties.getMonitor().getPeriod());
return listener;
}
@Bean
@ConditionalOnMissingBean
public ApplicationEventJournal applicationEventJournal(
JournaledEventStore journaledEventStore) {
return new ApplicationEventJournal(journaledEventStore);
}
@Bean
@ConditionalOnMissingBean
public JournaledEventStore journaledEventStore() {
return new SimpleJournaledEventStore();
}
@Bean
@ConditionalOnMissingBean
public ApplicationStore applicationStore() {
return new SimpleApplicationStore();
}
}
...@@ -30,6 +30,7 @@ public class AdminServerImportSelector implements DeferredImportSelector { ...@@ -30,6 +30,7 @@ public class AdminServerImportSelector implements DeferredImportSelector {
public String[] selectImports(AnnotationMetadata importingClassMetadata) { public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[] { NotifierConfiguration.class.getCanonicalName(), return new String[] { NotifierConfiguration.class.getCanonicalName(),
HazelcastStoreConfiguration.class.getCanonicalName(), HazelcastStoreConfiguration.class.getCanonicalName(),
AdminServerCoreConfiguration.class.getCanonicalName(),
AdminServerWebConfiguration.class.getCanonicalName(), AdminServerWebConfiguration.class.getCanonicalName(),
DiscoveryClientConfiguration.class.getCanonicalName(), DiscoveryClientConfiguration.class.getCanonicalName(),
RevereseZuulProxyConfiguration.class.getCanonicalName() }; RevereseZuulProxyConfiguration.class.getCanonicalName() };
......
...@@ -18,12 +18,8 @@ package de.codecentric.boot.admin.config; ...@@ -18,12 +18,8 @@ package de.codecentric.boot.admin.config;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
...@@ -31,14 +27,10 @@ import org.springframework.context.annotation.Bean; ...@@ -31,14 +27,10 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener; import org.springframework.context.event.EventListener;
import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
...@@ -49,51 +41,31 @@ import de.codecentric.boot.admin.event.ClientApplicationDeregisteredEvent; ...@@ -49,51 +41,31 @@ import de.codecentric.boot.admin.event.ClientApplicationDeregisteredEvent;
import de.codecentric.boot.admin.event.ClientApplicationRegisteredEvent; import de.codecentric.boot.admin.event.ClientApplicationRegisteredEvent;
import de.codecentric.boot.admin.event.RoutesOutdatedEvent; import de.codecentric.boot.admin.event.RoutesOutdatedEvent;
import de.codecentric.boot.admin.journal.ApplicationEventJournal; import de.codecentric.boot.admin.journal.ApplicationEventJournal;
import de.codecentric.boot.admin.journal.store.JournaledEventStore;
import de.codecentric.boot.admin.journal.store.SimpleJournaledEventStore;
import de.codecentric.boot.admin.journal.web.JournalController; import de.codecentric.boot.admin.journal.web.JournalController;
import de.codecentric.boot.admin.registry.ApplicationIdGenerator;
import de.codecentric.boot.admin.registry.ApplicationRegistry; import de.codecentric.boot.admin.registry.ApplicationRegistry;
import de.codecentric.boot.admin.registry.HashingApplicationUrlIdGenerator;
import de.codecentric.boot.admin.registry.StatusUpdateApplicationListener;
import de.codecentric.boot.admin.registry.StatusUpdater;
import de.codecentric.boot.admin.registry.store.ApplicationStore;
import de.codecentric.boot.admin.registry.store.SimpleApplicationStore;
import de.codecentric.boot.admin.registry.web.RegistryController; import de.codecentric.boot.admin.registry.web.RegistryController;
import de.codecentric.boot.admin.web.AdminController; import de.codecentric.boot.admin.web.AdminController;
import de.codecentric.boot.admin.web.PrefixHandlerMapping; import de.codecentric.boot.admin.web.PrefixHandlerMapping;
import de.codecentric.boot.admin.web.client.BasicAuthHttpHeaderProvider;
import de.codecentric.boot.admin.web.client.HttpHeadersProvider;
import de.codecentric.boot.admin.web.servlet.resource.ConcatenatingResourceResolver; import de.codecentric.boot.admin.web.servlet.resource.ConcatenatingResourceResolver;
import de.codecentric.boot.admin.web.servlet.resource.PreferMinifiedFilteringResourceResolver; import de.codecentric.boot.admin.web.servlet.resource.PreferMinifiedFilteringResourceResolver;
import de.codecentric.boot.admin.web.servlet.resource.ResourcePatternResolvingResourceResolver; import de.codecentric.boot.admin.web.servlet.resource.ResourcePatternResolvingResourceResolver;
@Configuration @Configuration
@EnableConfigurationProperties
public class AdminServerWebConfiguration extends WebMvcConfigurerAdapter public class AdminServerWebConfiguration extends WebMvcConfigurerAdapter
implements ApplicationContextAware { implements ApplicationContextAware {
private final ApplicationEventPublisher publisher;
private final ServerProperties server;
private final ResourcePatternResolver resourcePatternResolver;
private final AdminServerProperties adminServerProperties;
private ApplicationContext applicationContext; private ApplicationContext applicationContext;
@Autowired public AdminServerWebConfiguration(ApplicationEventPublisher publisher, ServerProperties server,
private ApplicationEventPublisher publisher; ResourcePatternResolver resourcePatternResolver,
AdminServerProperties adminServerProperties) {
@Autowired this.publisher = publisher;
private ApplicationStore applicationStore; this.server = server;
this.resourcePatternResolver = resourcePatternResolver;
@Autowired this.adminServerProperties = adminServerProperties;
private ServerProperties server;
@Autowired
private ResourcePatternResolver resourcePatternResolver;
@Autowired
private RestTemplateBuilder restTemplBuilder;
@Bean
@ConditionalOnMissingBean
public AdminServerProperties adminServerProperties() {
return new AdminServerProperties();
} }
@Override @Override
...@@ -122,18 +94,18 @@ public class AdminServerWebConfiguration extends WebMvcConfigurerAdapter ...@@ -122,18 +94,18 @@ public class AdminServerWebConfiguration extends WebMvcConfigurerAdapter
@Override @Override
public void addResourceHandlers(ResourceHandlerRegistry registry) { public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(adminServerProperties().getContextPath() + "/**") registry.addResourceHandler(adminServerProperties.getContextPath() + "/**")
.addResourceLocations("classpath:/META-INF/spring-boot-admin-server-ui/") .addResourceLocations("classpath:/META-INF/spring-boot-admin-server-ui/")
.resourceChain(true) .resourceChain(true)
.addResolver(new PreferMinifiedFilteringResourceResolver(".min")); .addResolver(new PreferMinifiedFilteringResourceResolver(".min"));
registry.addResourceHandler(adminServerProperties().getContextPath() + "/all-modules.css") registry.addResourceHandler(adminServerProperties.getContextPath() + "/all-modules.css")
.resourceChain(true) .resourceChain(true)
.addResolver(new ResourcePatternResolvingResourceResolver(resourcePatternResolver, .addResolver(new ResourcePatternResolvingResourceResolver(resourcePatternResolver,
"classpath*:/META-INF/spring-boot-admin-server-ui/*/module.css")) "classpath*:/META-INF/spring-boot-admin-server-ui/*/module.css"))
.addResolver(new ConcatenatingResourceResolver("\n".getBytes())); .addResolver(new ConcatenatingResourceResolver("\n".getBytes()));
registry.addResourceHandler(adminServerProperties().getContextPath() + "/all-modules.js") registry.addResourceHandler(adminServerProperties.getContextPath() + "/all-modules.js")
.resourceChain(true) .resourceChain(true)
.addResolver(new ResourcePatternResolvingResourceResolver(resourcePatternResolver, .addResolver(new ResourcePatternResolvingResourceResolver(resourcePatternResolver,
"classpath*:/META-INF/spring-boot-admin-server-ui/*/module.js")) "classpath*:/META-INF/spring-boot-admin-server-ui/*/module.js"))
...@@ -143,12 +115,11 @@ public class AdminServerWebConfiguration extends WebMvcConfigurerAdapter ...@@ -143,12 +115,11 @@ public class AdminServerWebConfiguration extends WebMvcConfigurerAdapter
@Override @Override
public void addViewControllers(ViewControllerRegistry registry) { public void addViewControllers(ViewControllerRegistry registry) {
if (StringUtils.hasText(adminServerProperties().getContextPath())) { String contextPath = adminServerProperties.getContextPath();
registry.addRedirectViewController(adminServerProperties().getContextPath(), if (StringUtils.hasText(contextPath)) {
server.getPath(adminServerProperties().getContextPath()) + "/"); registry.addRedirectViewController(contextPath, server.getPath(contextPath) + "/");
} }
registry.addViewController(adminServerProperties().getContextPath() + "/") registry.addViewController(contextPath + "/").setViewName("forward:index.html");
.setViewName("forward:index.html");
} }
@Bean @Bean
...@@ -157,75 +128,20 @@ public class AdminServerWebConfiguration extends WebMvcConfigurerAdapter ...@@ -157,75 +128,20 @@ public class AdminServerWebConfiguration extends WebMvcConfigurerAdapter
.getBeansWithAnnotation(AdminController.class); .getBeansWithAnnotation(AdminController.class);
PrefixHandlerMapping prefixHandlerMapping = new PrefixHandlerMapping( PrefixHandlerMapping prefixHandlerMapping = new PrefixHandlerMapping(
beans.values().toArray(new Object[beans.size()])); beans.values().toArray(new Object[beans.size()]));
prefixHandlerMapping.setPrefix(adminServerProperties().getContextPath()); prefixHandlerMapping.setPrefix(adminServerProperties.getContextPath());
return prefixHandlerMapping; return prefixHandlerMapping;
} }
/**
* @return Controller with REST-API for spring-boot applications to register itself.
*/
@Bean
public RegistryController registryController() {
return new RegistryController(applicationRegistry());
}
/**
* @return Default registry for all registered application.
*/
@Bean
public ApplicationRegistry applicationRegistry() {
return new ApplicationRegistry(applicationStore, applicationIdGenerator());
}
/**
* @return Default applicationId Generator
*/
@Bean
@ConditionalOnMissingBean
public ApplicationIdGenerator applicationIdGenerator() {
return new HashingApplicationUrlIdGenerator();
}
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public HttpHeadersProvider httpHeadersProvider() { public RegistryController registryController(ApplicationRegistry applicationRegistry) {
return new BasicAuthHttpHeaderProvider(); return new RegistryController(applicationRegistry);
} }
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public StatusUpdater statusUpdater() { public JournalController journalController(ApplicationEventJournal applicationEventJournal) {
RestTemplateBuilder builder = restTemplBuilder return new JournalController(applicationEventJournal);
.messageConverters(new MappingJackson2HttpMessageConverter())
.errorHandler(new DefaultResponseErrorHandler() {
@Override
protected boolean hasError(HttpStatus statusCode) {
return false;
}
});
StatusUpdater statusUpdater = new StatusUpdater(builder.build(), applicationStore,
httpHeadersProvider());
statusUpdater.setStatusLifetime(adminServerProperties().getMonitor().getStatusLifetime());
return statusUpdater;
}
@Bean
@Qualifier("updateTaskScheduler")
public TaskScheduler updateTaskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(1);
taskScheduler.setRemoveOnCancelPolicy(true);
taskScheduler.setThreadNamePrefix("updateTask");
return taskScheduler;
}
@Bean
public StatusUpdateApplicationListener statusUpdateApplicationListener() {
StatusUpdateApplicationListener listener = new StatusUpdateApplicationListener(
statusUpdater(), updateTaskScheduler());
listener.setUpdatePeriod(adminServerProperties().getMonitor().getPeriod());
return listener;
} }
@EventListener @EventListener
...@@ -238,28 +154,4 @@ public class AdminServerWebConfiguration extends WebMvcConfigurerAdapter ...@@ -238,28 +154,4 @@ public class AdminServerWebConfiguration extends WebMvcConfigurerAdapter
publisher.publishEvent(new RoutesOutdatedEvent()); publisher.publishEvent(new RoutesOutdatedEvent());
} }
@Bean
@ConditionalOnMissingBean
public ApplicationEventJournal applicationEventJournal() {
return new ApplicationEventJournal(journaledEventStore());
}
@Bean
@ConditionalOnMissingBean
public JournaledEventStore journaledEventStore() {
return new SimpleJournaledEventStore();
}
@Bean
@ConditionalOnMissingBean
public JournalController journalController() {
return new JournalController(applicationEventJournal());
}
@Bean
@ConditionalOnMissingBean
public ApplicationStore applicationStore() {
return new SimpleApplicationStore();
}
} }
...@@ -63,7 +63,8 @@ public class AdminServerWebConfigurationTest { ...@@ -63,7 +63,8 @@ public class AdminServerWebConfigurationTest {
@Test @Test
public void jacksonMapperPresentFromDefault() { public void jacksonMapperPresentFromDefault() {
AdminServerWebConfiguration config = new AdminServerWebConfiguration(); AdminServerWebConfiguration config = new AdminServerWebConfiguration(null, null, null,
null);
List<HttpMessageConverter<?>> converters = new ArrayList<>(); List<HttpMessageConverter<?>> converters = new ArrayList<>();
converters.add(new MappingJackson2HttpMessageConverter()); converters.add(new MappingJackson2HttpMessageConverter());
...@@ -76,7 +77,8 @@ public class AdminServerWebConfigurationTest { ...@@ -76,7 +77,8 @@ public class AdminServerWebConfigurationTest {
@Test @Test
public void jacksonMapperPresentNeedExtend() { public void jacksonMapperPresentNeedExtend() {
AdminServerWebConfiguration config = new AdminServerWebConfiguration(); AdminServerWebConfiguration config = new AdminServerWebConfiguration(null, null, null,
null);
List<HttpMessageConverter<?>> converters = new ArrayList<>(); List<HttpMessageConverter<?>> converters = new ArrayList<>();
config.extendMessageConverters(converters); config.extendMessageConverters(converters);
...@@ -137,6 +139,7 @@ public class AdminServerWebConfigurationTest { ...@@ -137,6 +139,7 @@ public class AdminServerWebConfigurationTest {
applicationContext.register(HazelcastAutoConfiguration.class); applicationContext.register(HazelcastAutoConfiguration.class);
applicationContext.register(HazelcastStoreConfiguration.class); applicationContext.register(HazelcastStoreConfiguration.class);
applicationContext.register(DiscoveryClientConfiguration.class); applicationContext.register(DiscoveryClientConfiguration.class);
applicationContext.register(AdminServerCoreConfiguration.class);
applicationContext.register(AdminServerWebConfiguration.class); applicationContext.register(AdminServerWebConfiguration.class);
EnvironmentTestUtils.addEnvironment(applicationContext, environment); EnvironmentTestUtils.addEnvironment(applicationContext, environment);
......
...@@ -94,6 +94,7 @@ public class DiscoveryClientConfigurationTest { ...@@ -94,6 +94,7 @@ public class DiscoveryClientConfigurationTest {
applicationContext.register(PropertyPlaceholderAutoConfiguration.class); applicationContext.register(PropertyPlaceholderAutoConfiguration.class);
applicationContext.register(RestTemplateConfiguration.class); applicationContext.register(RestTemplateConfiguration.class);
applicationContext.register(ServerPropertiesAutoConfiguration.class); applicationContext.register(ServerPropertiesAutoConfiguration.class);
applicationContext.register(AdminServerCoreConfiguration.class);
applicationContext.register(AdminServerWebConfiguration.class); applicationContext.register(AdminServerWebConfiguration.class);
applicationContext.register(DiscoveryClientConfiguration.class); applicationContext.register(DiscoveryClientConfiguration.class);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment