Commit 66173f5e by Johannes Stelzer

Add tests for the client & server autoconfig and fix issue with cyclic dependency

parent d370971f
...@@ -39,7 +39,7 @@ One note: If you omit the Spring Boot Admin Client in you Client Applications yo ...@@ -39,7 +39,7 @@ One note: If you omit the Spring Boot Admin Client in you Client Applications yo
### Further configuration ### Further configuration
Since the DiscoveryClient doesn't tell the management.context-path you can suffix the url for all discovered clients by setting ``spring.boot.admin.discovery.management.context-path``. Since the DiscoveryClient doesn't tell the management.context-path you can suffix the url for all discovered clients by setting ``spring.boot.admin.discovery.management.context-path``.
Explictly disable DiscoveryClient support by setting ``spring.boot.admin.discover.enable=false``. Explictly disable DiscoveryClient support by setting ``spring.boot.admin.discover.enabled=false``.
## Hazelcast Support ## Hazelcast Support
Spring Boot Admin Server supports cluster replication with Hazelcast. Spring Boot Admin Server supports cluster replication with Hazelcast.
...@@ -93,6 +93,6 @@ Write xml-config hazelcast-config.xml: ...@@ -93,6 +93,6 @@ Write xml-config hazelcast-config.xml:
``` ```
### Further configuration ### Further configuration
Disable Hazelcast support by setting ``spring.boot.admin.hazelcast.enable=false``. Disable Hazelcast support by setting ``spring.boot.admin.hazelcast.enabled=false``.
To alter the name of the Hazelcast-Map set ``spring.boot.admin.hazelcast.map= my-own-map-name``. To alter the name of the Hazelcast-Map set ``spring.boot.admin.hazelcast.map= my-own-map-name``.
...@@ -46,6 +46,7 @@ import org.springframework.cloud.netflix.zuul.filters.pre.Servlet30WrapperFilter ...@@ -46,6 +46,7 @@ import org.springframework.cloud.netflix.zuul.filters.pre.Servlet30WrapperFilter
import org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter; import org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter;
import org.springframework.cloud.netflix.zuul.web.ZuulController; import org.springframework.cloud.netflix.zuul.web.ZuulController;
import org.springframework.cloud.netflix.zuul.web.ZuulHandlerMapping; import org.springframework.cloud.netflix.zuul.web.ZuulHandlerMapping;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener; import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
...@@ -65,6 +66,8 @@ import com.netflix.zuul.ZuulFilter; ...@@ -65,6 +66,8 @@ import com.netflix.zuul.ZuulFilter;
import de.codecentric.boot.admin.controller.RegistryController; import de.codecentric.boot.admin.controller.RegistryController;
import de.codecentric.boot.admin.discovery.ApplicationDiscoveryListener; import de.codecentric.boot.admin.discovery.ApplicationDiscoveryListener;
import de.codecentric.boot.admin.event.ClientApplicationRegisteredEvent;
import de.codecentric.boot.admin.event.ClientApplicationUnregisteredEvent;
import de.codecentric.boot.admin.model.Application; import de.codecentric.boot.admin.model.Application;
import de.codecentric.boot.admin.registry.ApplicationIdGenerator; import de.codecentric.boot.admin.registry.ApplicationIdGenerator;
import de.codecentric.boot.admin.registry.ApplicationRegistry; import de.codecentric.boot.admin.registry.ApplicationRegistry;
...@@ -76,7 +79,7 @@ import de.codecentric.boot.admin.zuul.ApplicationRouteLocator; ...@@ -76,7 +79,7 @@ import de.codecentric.boot.admin.zuul.ApplicationRouteLocator;
import de.codecentric.boot.admin.zuul.ApplicationRouteRefreshListener; import de.codecentric.boot.admin.zuul.ApplicationRouteRefreshListener;
@Configuration @Configuration
public class WebappConfig extends WebMvcConfigurerAdapter { public class AdminServerWebConfiguration extends WebMvcConfigurerAdapter {
/** /**
* Add JSON MessageConverter to send JSON objects to web clients. * Add JSON MessageConverter to send JSON objects to web clients.
...@@ -213,7 +216,7 @@ public class WebappConfig extends WebMvcConfigurerAdapter { ...@@ -213,7 +216,7 @@ public class WebappConfig extends WebMvcConfigurerAdapter {
} }
@Bean @Bean
ApplicationRouteRefreshListener applicationRouteRefreshListener() { public ApplicationRouteRefreshListener applicationRouteRefreshListener() {
return new ApplicationRouteRefreshListener(routeLocator(), zuulHandlerMapping(routeLocator())); return new ApplicationRouteRefreshListener(routeLocator(), zuulHandlerMapping(routeLocator()));
} }
...@@ -235,9 +238,9 @@ public class WebappConfig extends WebMvcConfigurerAdapter { ...@@ -235,9 +238,9 @@ public class WebappConfig extends WebMvcConfigurerAdapter {
@Configuration @Configuration
@ConditionalOnClass({ Hazelcast.class }) @ConditionalOnClass({ Hazelcast.class })
@ConditionalOnProperty(prefix = "spring.boot.admin.hazelcast", name = "enable", matchIfMissing = true) @ConditionalOnProperty(prefix = "spring.boot.admin.hazelcast", name = "enabled", matchIfMissing = true)
@AutoConfigureBefore(SimpleStoreConfig.class) @AutoConfigureBefore(SimpleStoreConfig.class)
public static class HazelcastStoreConfig { public static class HazelcastStoreConfiguration {
@Value("${spring.boot.admin.hazelcast.map:spring-boot-admin-application-store}") @Value("${spring.boot.admin.hazelcast.map:spring-boot-admin-application-store}")
private String hazelcastMapName; private String hazelcastMapName;
...@@ -270,44 +273,36 @@ public class WebappConfig extends WebMvcConfigurerAdapter { ...@@ -270,44 +273,36 @@ public class WebappConfig extends WebMvcConfigurerAdapter {
private static class ApplicationEntryListener implements EntryListener<String, Application> { private static class ApplicationEntryListener implements EntryListener<String, Application> {
@Autowired @Autowired
private ZuulHandlerMapping zuulHandlerMapping; ApplicationContext context;
@Autowired
private ApplicationRouteLocator routeLocator;
private void reset() {
routeLocator.resetRoutes();
zuulHandlerMapping.registerHandlers();
}
@Override @Override
public void entryAdded(EntryEvent<String, Application> event) { public void entryAdded(EntryEvent<String, Application> event) {
reset(); context.publishEvent(new ClientApplicationRegisteredEvent(this,event.getValue()));
} }
@Override @Override
public void entryRemoved(EntryEvent<String, Application> event) { public void entryRemoved(EntryEvent<String, Application> event) {
reset(); context.publishEvent(new ClientApplicationUnregisteredEvent(this,event.getValue()));
} }
@Override @Override
public void entryUpdated(EntryEvent<String, Application> event) { public void entryUpdated(EntryEvent<String, Application> event) {
reset(); context.publishEvent(new ClientApplicationRegisteredEvent(this,event.getValue()));
} }
@Override @Override
public void entryEvicted(EntryEvent<String, Application> event) { public void entryEvicted(EntryEvent<String, Application> event) {
reset(); context.publishEvent(new ClientApplicationRegisteredEvent(this,null));
} }
@Override @Override
public void mapEvicted(MapEvent event) { public void mapEvicted(MapEvent event) {
reset(); context.publishEvent(new ClientApplicationRegisteredEvent(this,null));
} }
@Override @Override
public void mapCleared(MapEvent event) { public void mapCleared(MapEvent event) {
reset(); context.publishEvent(new ClientApplicationRegisteredEvent(this,null));
} }
} }
} }
...@@ -316,7 +311,7 @@ public class WebappConfig extends WebMvcConfigurerAdapter { ...@@ -316,7 +311,7 @@ public class WebappConfig extends WebMvcConfigurerAdapter {
@ConditionalOnClass({ DiscoveryClient.class }) @ConditionalOnClass({ DiscoveryClient.class })
@ConditionalOnProperty(prefix = "spring.boot.admin.discovery", name = "enabled", matchIfMissing = true) @ConditionalOnProperty(prefix = "spring.boot.admin.discovery", name = "enabled", matchIfMissing = true)
@AutoConfigureAfter({ NoopDiscoveryClientAutoConfiguration.class }) @AutoConfigureAfter({ NoopDiscoveryClientAutoConfiguration.class })
public static class DiscoveryConfig { public static class DiscoveryClientConfiguration {
@Value("${spring.boot.admin.discovery.management.context-path:}") @Value("${spring.boot.admin.discovery.management.context-path:}")
private String managementPath; private String managementPath;
...@@ -329,12 +324,10 @@ public class WebappConfig extends WebMvcConfigurerAdapter { ...@@ -329,12 +324,10 @@ public class WebappConfig extends WebMvcConfigurerAdapter {
@Bean @Bean
ApplicationListener<ApplicationEvent> applicationDiscoveryListener() { ApplicationListener<ApplicationEvent> applicationDiscoveryListener() {
ApplicationDiscoveryListener listener = new ApplicationDiscoveryListener( ApplicationDiscoveryListener listener = new ApplicationDiscoveryListener(discoveryClient, registry);
discoveryClient,
registry);
listener.setManagementContextPath(managementPath); listener.setManagementContextPath(managementPath);
return listener; return listener;
} }
} }
} }
...@@ -30,7 +30,7 @@ import org.springframework.context.annotation.Import; ...@@ -30,7 +30,7 @@ import org.springframework.context.annotation.Import;
@Target(ElementType.TYPE) @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
@Import(WebappConfig.class) @Import(AdminServerWebConfiguration.class)
public @interface EnableAdminServer { public @interface EnableAdminServer {
} }
...@@ -63,9 +63,9 @@ public class AdminApplicationHazelcastTest { ...@@ -63,9 +63,9 @@ public class AdminApplicationHazelcastTest {
public void setup() throws InterruptedException { public void setup() throws InterruptedException {
System.setProperty("hazelcast.wait.seconds.before.join", "0"); System.setProperty("hazelcast.wait.seconds.before.join", "0");
instance1 = (EmbeddedWebApplicationContext) SpringApplication.run(TestAdminApplication.class, new String[] { instance1 = (EmbeddedWebApplicationContext) SpringApplication.run(TestAdminApplication.class, new String[] {
"--server.port=0", "--spring.jmx.enabled=false", "--spring.boot.admin.hazelcast.enable=true" }); "--server.port=0", "--spring.jmx.enabled=false", "--spring.boot.admin.hazelcast.enabled=true" });
instance2 = (EmbeddedWebApplicationContext) SpringApplication.run(TestAdminApplication.class, new String[] { instance2 = (EmbeddedWebApplicationContext) SpringApplication.run(TestAdminApplication.class, new String[] {
"--server.port=0", "--spring.jmx.enabled=false", "--spring.boot.admin.hazelcast.enable=true" }); "--server.port=0", "--spring.jmx.enabled=false", "--spring.boot.admin.hazelcast.enabled=true" });
} }
@After @After
......
package de.codecentric.boot.admin.config;
import static org.junit.Assert.assertTrue;
import org.junit.After;
import org.junit.Test;
import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration;
import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.cloud.client.discovery.noop.NoopDiscoveryClientAutoConfiguration;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import de.codecentric.boot.admin.discovery.ApplicationDiscoveryListener;
import de.codecentric.boot.admin.registry.store.ApplicationStore;
import de.codecentric.boot.admin.registry.store.HazelcastApplicationStore;
import de.codecentric.boot.admin.registry.store.SimpleApplicationStore;
public class AdminServerWebConfigurationTest {
private AnnotationConfigWebApplicationContext context;
@After
public void close() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void simpleConfig() {
load("spring.boot.admin.hazelcast.enabled:false", "spring.boot.admin.discovery.enabled:false");
assertTrue(context.getBean(ApplicationStore.class) instanceof SimpleApplicationStore);
assertTrue(context.getBeansOfType(ApplicationDiscoveryListener.class).isEmpty());
}
@Test
public void hazelcastConfig() {
load("spring.boot.admin.hazelcast.enabled:true", "spring.boot.admin.discovery.enabled:false");
assertTrue(context.getBean(ApplicationStore.class) instanceof HazelcastApplicationStore);
assertTrue(context.getBeansOfType(ApplicationDiscoveryListener.class).isEmpty());
}
@Test
public void discoveryConfig() {
load("spring.boot.admin.hazelcast.enabled:false", "spring.boot.admin.discovery.enabled:true");
assertTrue(context.getBean(ApplicationStore.class) instanceof SimpleApplicationStore);
context.getBean(ApplicationDiscoveryListener.class);
}
private void load(String... environment) {
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
applicationContext.register(ServerPropertiesAutoConfiguration.class);
applicationContext.register(NoopDiscoveryClientAutoConfiguration.class);
applicationContext.register(AdminServerWebConfiguration.class);
EnvironmentTestUtils.addEnvironment(applicationContext, environment);
applicationContext.refresh();
this.context = applicationContext;
}
}
...@@ -2,5 +2,5 @@ server.port=8080 ...@@ -2,5 +2,5 @@ server.port=8080
info.version=1.0.0 info.version=1.0.0
spring.application.name=spring-boot-admin-server-test spring.application.name=spring-boot-admin-server-test
spring.boot.admin.url=http://localhost:8080 spring.boot.admin.url=http://localhost:8080
spring.boot.admin.hazelcast.enable=false spring.boot.admin.hazelcast.enabled=false
spring.boot.admin.discovery.enable=false spring.boot.admin.discovery.enabled=false
\ No newline at end of file \ No newline at end of file
package de.codecentric.boot.admin.config;
import static org.junit.Assert.assertTrue;
import org.junit.After;
import org.junit.Test;
import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration;
import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import de.codecentric.boot.admin.actuate.LogfileMvcEndpoint;
import de.codecentric.boot.admin.services.SpringBootAdminRegistrator;
public class SpringBootAdminClientAutoConfigurationTest {
private AnnotationConfigWebApplicationContext context;
@After
public void close() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void not_active() {
load();
assertTrue(context.getBeansOfType(SpringBootAdminRegistrator.class).isEmpty());
}
@Test
public void active_nologfile() {
load("spring.boot.admin.url:http://localhost:8081");
context.getBean(SpringBootAdminRegistrator.class);
assertTrue(context.getBeansOfType(LogfileMvcEndpoint.class).isEmpty());
}
@Test
public void active_logfile() {
load("spring.boot.admin.url:http://localhost:8081", "logging.file:spring.log");
context.getBean(LogfileMvcEndpoint.class);
context.getBean(SpringBootAdminRegistrator.class);
}
@Test
public void active_logfile_supressed() {
load("spring.boot.admin.url:http://localhost:8081", "logging.file:spring.log",
"endpoints.logfile.enabled:false");
context.getBean(SpringBootAdminRegistrator.class);
assertTrue(context.getBeansOfType(LogfileMvcEndpoint.class).isEmpty());
}
private void load(String... environment) {
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
applicationContext.register(ServerPropertiesAutoConfiguration.class);
applicationContext.register(SpringBootAdminClientAutoConfiguration.class);
EnvironmentTestUtils.addEnvironment(applicationContext, environment);
applicationContext.refresh();
this.context = applicationContext;
}
}
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