Commit a93fa6ee by Johannes Edmeier

Use AutoConfiguration with marker bean for server

To avoid some strange config sorting errors using the DeferredImportSelector, switch to a real AutoConfiguration activated by a marker bean
parent 8b7c58c0
...@@ -38,21 +38,25 @@ import de.codecentric.boot.admin.server.web.client.HttpHeadersProvider; ...@@ -38,21 +38,25 @@ import de.codecentric.boot.admin.server.web.client.HttpHeadersProvider;
import io.netty.channel.ChannelOption; import io.netty.channel.ChannelOption;
import org.reactivestreams.Publisher; import org.reactivestreams.Publisher;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClient;
@Configuration @Configuration
@ConditionalOnBean(AdminServerMarkerConfiguration.Marker.class)
@EnableConfigurationProperties(AdminServerProperties.class) @EnableConfigurationProperties(AdminServerProperties.class)
public class AdminServerCoreConfiguration { @Import({AdminServerWebConfiguration.class, AdminServerNotifierConfiguration.class})
public class AdminServerAutoConfiguration {
private final AdminServerProperties adminServerProperties; private final AdminServerProperties adminServerProperties;
public AdminServerCoreConfiguration(AdminServerProperties adminServerProperties) { public AdminServerAutoConfiguration(AdminServerProperties adminServerProperties) {
this.adminServerProperties = adminServerProperties; this.adminServerProperties = adminServerProperties;
} }
...@@ -138,14 +142,14 @@ public class AdminServerCoreConfiguration { ...@@ -138,14 +142,14 @@ public class AdminServerCoreConfiguration {
} }
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean(ClientApplicationEventStore.class)
public ClientApplicationEventStore eventStore() { public InMemoryEventStore eventStore() {
return new InMemoryEventStore(); return new InMemoryEventStore();
} }
@Bean(initMethod = "start", destroyMethod = "stop") @Bean(initMethod = "start", destroyMethod = "stop")
@ConditionalOnMissingBean(ApplicationRepository.class) @ConditionalOnMissingBean(ApplicationRepository.class)
public EventSourcingApplicationRepository applicationRepository() { public EventSourcingApplicationRepository applicationRepository(ClientApplicationEventStore eventStore) {
return new EventSourcingApplicationRepository(eventStore()); return new EventSourcingApplicationRepository(eventStore);
} }
} }
...@@ -36,9 +36,10 @@ import com.netflix.discovery.EurekaClient; ...@@ -36,9 +36,10 @@ import com.netflix.discovery.EurekaClient;
@Configuration @Configuration
@ConditionalOnSingleCandidate(DiscoveryClient.class) @ConditionalOnSingleCandidate(DiscoveryClient.class)
@ConditionalOnBean(AdminServerMarkerConfiguration.Marker.class)
@ConditionalOnProperty(prefix = "spring.boot.admin.discovery", name = "enabled", matchIfMissing = true) @ConditionalOnProperty(prefix = "spring.boot.admin.discovery", name = "enabled", matchIfMissing = true)
@AutoConfigureAfter({SimpleDiscoveryClientAutoConfiguration.class}) @AutoConfigureAfter({AdminServerAutoConfiguration.class, SimpleDiscoveryClientAutoConfiguration.class})
public class DiscoveryClientConfiguration { public class AdminServerDiscoveryAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
...@@ -53,10 +54,10 @@ public class DiscoveryClientConfiguration { ...@@ -53,10 +54,10 @@ public class DiscoveryClientConfiguration {
} }
@Configuration @Configuration
@ConditionalOnMissingBean({ServiceInstanceConverter.class})
@ConditionalOnBean(EurekaClient.class) @ConditionalOnBean(EurekaClient.class)
public static class EurekaConverterConfiguration { public static class EurekaConverterConfiguration {
@Bean @Bean
@ConditionalOnMissingBean({ServiceInstanceConverter.class})
@ConfigurationProperties(prefix = "spring.boot.admin.discovery.converter") @ConfigurationProperties(prefix = "spring.boot.admin.discovery.converter")
public EurekaServiceInstanceConverter serviceInstanceConverter() { public EurekaServiceInstanceConverter serviceInstanceConverter() {
return new EurekaServiceInstanceConverter(); return new EurekaServiceInstanceConverter();
......
...@@ -24,6 +24,7 @@ import java.util.List; ...@@ -24,6 +24,7 @@ import java.util.List;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
...@@ -34,20 +35,20 @@ import com.hazelcast.core.HazelcastInstance; ...@@ -34,20 +35,20 @@ import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap; import com.hazelcast.core.IMap;
@Configuration @Configuration
@ConditionalOnBean(AdminServerMarkerConfiguration.Marker.class)
@ConditionalOnSingleCandidate(HazelcastInstance.class) @ConditionalOnSingleCandidate(HazelcastInstance.class)
@ConditionalOnProperty(prefix = "spring.boot.admin.hazelcast", name = "enabled", matchIfMissing = true) @ConditionalOnProperty(prefix = "spring.boot.admin.hazelcast", name = "enabled", matchIfMissing = true)
@AutoConfigureBefore(AdminServerWebConfiguration.class) @AutoConfigureBefore({AdminServerAutoConfiguration.class})
@AutoConfigureAfter(HazelcastAutoConfiguration.class) @AutoConfigureAfter(HazelcastAutoConfiguration.class)
public class HazelcastStoreConfiguration { public class AdminServerHazelcastAutoConfiguration {
@Value("${spring.boot.admin.hazelcast.event-store:spring-boot-admin-event-store}") @Value("${spring.boot.admin.hazelcast.event-store:spring-boot-admin-event-store}")
private String mapName; private String mapName;
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean(ClientApplicationEventStore.class)
public ClientApplicationEventStore eventStore(HazelcastInstance hazelcastInstance) { public HazelcastEventStore eventStore(HazelcastInstance hazelcastInstance) {
IMap<ApplicationId, List<ClientApplicationEvent>> map = hazelcastInstance.getMap(mapName); IMap<ApplicationId, List<ClientApplicationEvent>> map = hazelcastInstance.getMap(mapName);
return new HazelcastEventStore(map); return new HazelcastEventStore(map);
} }
} }
...@@ -13,35 +13,19 @@ ...@@ -13,35 +13,19 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package de.codecentric.boot.admin.server.config;
import java.util.Arrays;
import org.springframework.context.annotation.DeferredImportSelector;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.ClassUtils;
/** package de.codecentric.boot.admin.server.config;
* Defers the imports for our {@code @Configuration}-classes, because the need to be processed after
* normal @Configuration-classes.
*
* @author Johannes Edmeier
*/
public class AdminServerImportSelector implements DeferredImportSelector {
@Override import org.springframework.context.annotation.Bean;
public String[] selectImports(AnnotationMetadata importingClassMetadata) { import org.springframework.context.annotation.Configuration;
String[] configs = {NotifierConfiguration.class.getCanonicalName(),
HazelcastStoreConfiguration.class.getCanonicalName(),
AdminServerCoreConfiguration.class.getCanonicalName(),
AdminServerWebConfiguration.class.getCanonicalName(),
DiscoveryClientConfiguration.class.getCanonicalName()};
if (ClassUtils.isPresent("de.codecentric.boot.admin.ui.config.AdminServerWebUiConfiguration", @Configuration
this.getClass().getClassLoader())) { public class AdminServerMarkerConfiguration {
configs = Arrays.copyOf(configs, configs.length + 1); @Bean
configs[configs.length - 1] = "de.codecentric.boot.admin.ui.config.AdminServerWebUiConfiguration"; public Marker adminServerMarker() {
} return new Marker();
return configs;
} }
public static class Marker {
}
} }
...@@ -47,7 +47,7 @@ import org.springframework.context.annotation.Primary; ...@@ -47,7 +47,7 @@ import org.springframework.context.annotation.Primary;
import org.springframework.mail.MailSender; import org.springframework.mail.MailSender;
@Configuration @Configuration
public class NotifierConfiguration { public class AdminServerNotifierConfiguration {
@Configuration @Configuration
@ConditionalOnBean(Notifier.class) @ConditionalOnBean(Notifier.class)
......
/* /*
* Copyright 2013-2014 the original author or authors. * Copyright 2014-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
...@@ -28,7 +28,7 @@ import org.springframework.context.annotation.Import; ...@@ -28,7 +28,7 @@ import org.springframework.context.annotation.Import;
@Target(ElementType.TYPE) @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
@Import(AdminServerImportSelector.class) @Import(AdminServerMarkerConfiguration.class)
public @interface EnableAdminServer { public @interface EnableAdminServer {
} }
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
de.codecentric.boot.admin.server.config.AdminServerAutoConfiguration,\
de.codecentric.boot.admin.server.config.AdminServerDiscoveryAutoConfiguration,\
de.codecentric.boot.admin.server.config.AdminServerHazelcastAutoConfiguration
\ No newline at end of file
...@@ -36,7 +36,7 @@ import com.netflix.discovery.EurekaClient; ...@@ -36,7 +36,7 @@ import com.netflix.discovery.EurekaClient;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
public class DiscoveryClientConfigurationTest { public class AdminServerDiscoveryAutoConfigurationTest {
private AnnotationConfigWebApplicationContext context; private AnnotationConfigWebApplicationContext context;
@After @After
...@@ -99,10 +99,9 @@ public class DiscoveryClientConfigurationTest { ...@@ -99,10 +99,9 @@ public class DiscoveryClientConfigurationTest {
} }
applicationContext.register(UtilAutoConfiguration.class); applicationContext.register(UtilAutoConfiguration.class);
applicationContext.register(RestTemplateAutoConfiguration.class); applicationContext.register(RestTemplateAutoConfiguration.class);
applicationContext.register(AdminServerCoreConfiguration.class); applicationContext.register(AdminServerMarkerConfiguration.class);
applicationContext.register(AdminServerWebConfiguration.class); applicationContext.register(AdminServerAutoConfiguration.class);
applicationContext.register(UtilAutoConfiguration.class); applicationContext.register(AdminServerDiscoveryAutoConfiguration.class);
applicationContext.register(DiscoveryClientConfiguration.class);
applicationContext.refresh(); applicationContext.refresh();
this.context = applicationContext; this.context = applicationContext;
......
...@@ -48,7 +48,7 @@ import static org.assertj.core.api.Assertions.assertThat; ...@@ -48,7 +48,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.is;
public class NotifierConfigurationTest { public class AdminServerNotifierConfigurationTest {
private static final ClientApplicationEvent APP_DOWN = new ClientApplicationStatusChangedEvent( private static final ClientApplicationEvent APP_DOWN = new ClientApplicationStatusChangedEvent(
ApplicationId.of("id-2"), 1L, StatusInfo.ofDown()); ApplicationId.of("id-2"), 1L, StatusInfo.ofDown());
...@@ -126,9 +126,9 @@ public class NotifierConfigurationTest { ...@@ -126,9 +126,9 @@ public class NotifierConfigurationTest {
context.register(config); context.register(config);
} }
context.register(RestTemplateAutoConfiguration.class); context.register(RestTemplateAutoConfiguration.class);
context.register(AdminServerCoreConfiguration.class);
context.register(MailSenderAutoConfiguration.class); context.register(MailSenderAutoConfiguration.class);
context.register(NotifierConfiguration.class); context.register(AdminServerMarkerConfiguration.class);
context.register(AdminServerAutoConfiguration.class);
TestPropertyValues.of(environment).applyTo(context); TestPropertyValues.of(environment).applyTo(context);
context.refresh(); context.refresh();
......
...@@ -117,11 +117,11 @@ public class AdminServerWebConfigurationTest { ...@@ -117,11 +117,11 @@ public class AdminServerWebConfigurationTest {
} }
applicationContext.register(RestTemplateAutoConfiguration.class); applicationContext.register(RestTemplateAutoConfiguration.class);
applicationContext.register(HazelcastAutoConfiguration.class); applicationContext.register(HazelcastAutoConfiguration.class);
applicationContext.register(HazelcastStoreConfiguration.class);
applicationContext.register(UtilAutoConfiguration.class); applicationContext.register(UtilAutoConfiguration.class);
applicationContext.register(DiscoveryClientConfiguration.class); applicationContext.register(AdminServerMarkerConfiguration.class);
applicationContext.register(AdminServerCoreConfiguration.class); applicationContext.register(AdminServerHazelcastAutoConfiguration.class);
applicationContext.register(AdminServerWebConfiguration.class); applicationContext.register(AdminServerAutoConfiguration.class);
applicationContext.register(AdminServerDiscoveryAutoConfiguration.class);
TestPropertyValues.of(environment).applyTo(applicationContext); TestPropertyValues.of(environment).applyTo(applicationContext);
applicationContext.refresh(); applicationContext.refresh();
......
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