Commit 071e36c7 by Johannes Edmeier

Add tests for using spring cloud discovery

parent 41e80a2d
/* /*
* 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.
...@@ -30,7 +30,11 @@ public class AdminServerImportSelector implements DeferredImportSelector { ...@@ -30,7 +30,11 @@ public class AdminServerImportSelector implements DeferredImportSelector {
@Override @Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) { public String[] selectImports(AnnotationMetadata importingClassMetadata) {
String[] configs = {NotifierConfiguration.class.getCanonicalName(), HazelcastStoreConfiguration.class.getCanonicalName(), AdminServerCoreConfiguration.class.getCanonicalName(), AdminServerWebConfiguration.class.getCanonicalName()}; 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", if (ClassUtils.isPresent("de.codecentric.boot.admin.ui.config.AdminServerWebUiConfiguration",
this.getClass().getClassLoader())) { this.getClass().getClassLoader())) {
......
...@@ -100,7 +100,7 @@ public class ApplicationDiscoveryListener { ...@@ -100,7 +100,7 @@ public class ApplicationDiscoveryListener {
.flatMap(this::registerInstance) .flatMap(this::registerInstance)
.collect(Collectors.toSet()) .collect(Collectors.toSet())
.flatMap(this::removeStaleInstances) .flatMap(this::removeStaleInstances)
.subscribe(); .subscribe(v -> {}, ex -> log.error("Unexpected error.", ex));
} }
protected Mono<Void> removeStaleInstances(Set<ApplicationId> registeredApplicationIds) { protected Mono<Void> removeStaleInstances(Set<ApplicationId> registeredApplicationIds) {
......
...@@ -25,7 +25,12 @@ import java.util.concurrent.atomic.AtomicReference; ...@@ -25,7 +25,12 @@ import java.util.concurrent.atomic.AtomicReference;
import org.json.JSONObject; import org.json.JSONObject;
import org.junit.Test; import org.junit.Test;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.codec.json.Jackson2JsonDecoder;
import org.springframework.http.codec.json.Jackson2JsonEncoder;
import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
...@@ -34,16 +39,14 @@ public abstract class AbstractAdminApplicationTest { ...@@ -34,16 +39,14 @@ public abstract class AbstractAdminApplicationTest {
private WebTestClient webClient; private WebTestClient webClient;
private int port; private int port;
public void setWebClient(WebTestClient webClient) {
this.webClient = webClient;
}
public void setPort(int port) { public void setUp(int port) throws Exception {
this.port = port; this.port = port;
this.webClient = createWebClient(port);
} }
@Test @Test
public void lifecycle() throws InterruptedException { public void lifecycle() {
Flux<JSONObject> events = getEventStream(); Flux<JSONObject> events = getEventStream();
AtomicReference<URI> location = new AtomicReference<>(); AtomicReference<URI> location = new AtomicReference<>();
...@@ -67,7 +70,7 @@ public abstract class AbstractAdminApplicationTest { ...@@ -67,7 +70,7 @@ public abstract class AbstractAdminApplicationTest {
.verify(Duration.ofSeconds(30)); .verify(Duration.ofSeconds(30));
} }
private Flux<JSONObject> getEventStream() { protected Flux<JSONObject> getEventStream() {
//@formatter:off //@formatter:off
return webClient.get().uri("/api/applications/events").accept(MediaType.APPLICATION_STREAM_JSON) return webClient.get().uri("/api/applications/events").accept(MediaType.APPLICATION_STREAM_JSON)
.exchange() .exchange()
...@@ -77,7 +80,7 @@ public abstract class AbstractAdminApplicationTest { ...@@ -77,7 +80,7 @@ public abstract class AbstractAdminApplicationTest {
//@formatter:on //@formatter:on
} }
private URI registerApplication() { protected URI registerApplication() {
//@formatter:off //@formatter:off
return webClient.post().uri("/api/applications").contentType(MediaType.APPLICATION_JSON).syncBody(createRegistration()) return webClient.post().uri("/api/applications").contentType(MediaType.APPLICATION_JSON).syncBody(createRegistration())
.exchange() .exchange()
...@@ -87,7 +90,7 @@ public abstract class AbstractAdminApplicationTest { ...@@ -87,7 +90,7 @@ public abstract class AbstractAdminApplicationTest {
//@formatter:on //@formatter:on
} }
private void getApplication(URI uri) { protected void getApplication(URI uri) {
//@formatter:off //@formatter:off
webClient.get().uri(uri).accept(MediaType.APPLICATION_JSON_UTF8) webClient.get().uri(uri).accept(MediaType.APPLICATION_JSON_UTF8)
.exchange() .exchange()
...@@ -99,7 +102,7 @@ public abstract class AbstractAdminApplicationTest { ...@@ -99,7 +102,7 @@ public abstract class AbstractAdminApplicationTest {
//@formatter:on //@formatter:on
} }
private void listApplications() { protected void listApplications() {
//@formatter:off //@formatter:off
webClient.get().uri("/api/applications").accept(MediaType.APPLICATION_JSON_UTF8) webClient.get().uri("/api/applications").accept(MediaType.APPLICATION_JSON_UTF8)
.exchange() .exchange()
...@@ -111,7 +114,7 @@ public abstract class AbstractAdminApplicationTest { ...@@ -111,7 +114,7 @@ public abstract class AbstractAdminApplicationTest {
//@formatter:on //@formatter:on
} }
private void listEmptyApplications() { protected void listEmptyApplications() {
//@formatter:off //@formatter:off
webClient.get().uri("/api/applications").accept(MediaType.APPLICATION_JSON_UTF8) webClient.get().uri("/api/applications").accept(MediaType.APPLICATION_JSON_UTF8)
.exchange() .exchange()
...@@ -120,7 +123,7 @@ public abstract class AbstractAdminApplicationTest { ...@@ -120,7 +123,7 @@ public abstract class AbstractAdminApplicationTest {
//@formatter:on //@formatter:on
} }
private void deregisterApplication(URI uri) { protected void deregisterApplication(URI uri) {
webClient.delete().uri(uri).exchange().expectStatus().isNoContent(); webClient.delete().uri(uri).exchange().expectStatus().isNoContent();
} }
...@@ -133,4 +136,23 @@ public abstract class AbstractAdminApplicationTest { ...@@ -133,4 +136,23 @@ public abstract class AbstractAdminApplicationTest {
.serviceUrl("http://localhost:" + port) .serviceUrl("http://localhost:" + port)
.build(); .build();
} }
protected WebTestClient createWebClient(int port) {
ObjectMapper mapper = new ObjectMapper().registerModule(new JsonOrgModule());
return WebTestClient.bindToServer()
.baseUrl("http://localhost:" + port)
.exchangeStrategies(ExchangeStrategies.builder().codecs((configurer) -> {
configurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(mapper));
configurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(mapper));
}).build())
.build();
}
public int getPort() {
return port;
}
public WebTestClient getWebClient() {
return webClient;
}
} }
/*
* Copyright 2014-2017 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.server;
import de.codecentric.boot.admin.server.config.EnableAdminServer;
import java.net.URI;
import java.util.List;
import org.json.JSONObject;
import org.junit.After;
import org.junit.Before;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent;
import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryProperties;
import org.springframework.http.MediaType;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
public class AdminApplicationDiscoveryTest extends AbstractAdminApplicationTest {
private ServletWebServerApplicationContext instance;
private SimpleDiscoveryProperties simpleDiscovery;
@Before
public void setUp() throws Exception {
instance = (ServletWebServerApplicationContext) SpringApplication.run(TestAdminApplication.class,
"--server.port=0", "--management.context-path=/mgmt", "--info.test=foobar",
"--management.security.enabled=false");
simpleDiscovery = instance.getBean(SimpleDiscoveryProperties.class);
super.setUp(instance.getWebServer().getPort());
}
@Override
protected URI registerApplication() {
//We register the application by setting static values for the SimpleDiscoveryClient and issuing a
//InstanceRegisteredEvent that makes sure the application gets registered.
SimpleDiscoveryProperties.SimpleServiceInstance serviceInstance = new SimpleDiscoveryProperties.SimpleServiceInstance();
serviceInstance.setServiceId("Test-Application");
serviceInstance.setUri(URI.create("http://localhost:" + getPort()));
serviceInstance.getMetadata().put("management.context-path", "/mgmt");
simpleDiscovery.getInstances().put("Test-Application", singletonList(serviceInstance));
instance.publishEvent(new InstanceRegisteredEvent<>(new Object(), null));
//To get the location of the registered applications we fetch the application with the name.
List<JSONObject> applications = getWebClient().get()
.uri("/api/applications?name=Test-Application")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus()
.isOk()
.returnResult(JSONObject.class)
.getResponseBody()
.collectList()
.block();
assertThat(applications).hasSize(1);
return URI.create("http://localhost:" + getPort() + "/api/applications/" + applications.get(0).optString("id"));
}
@Override
protected void deregisterApplication(URI uri) {
simpleDiscovery.getInstances().clear();
instance.publishEvent(new InstanceRegisteredEvent<>(new Object(), null));
}
@After
public void shutdown() {
instance.close();
}
@EnableAdminServer
@EnableAutoConfiguration
@SpringBootConfiguration
public static class TestAdminApplication {
}
}
...@@ -24,12 +24,6 @@ import org.springframework.boot.SpringBootConfiguration; ...@@ -24,12 +24,6 @@ import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.http.codec.json.Jackson2JsonDecoder;
import org.springframework.http.codec.json.Jackson2JsonEncoder;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule;
import com.hazelcast.config.Config; import com.hazelcast.config.Config;
import com.hazelcast.config.EvictionPolicy; import com.hazelcast.config.EvictionPolicy;
import com.hazelcast.config.InMemoryFormat; import com.hazelcast.config.InMemoryFormat;
...@@ -48,7 +42,7 @@ public class AdminApplicationHazelcastTest extends AbstractAdminApplicationTest ...@@ -48,7 +42,7 @@ public class AdminApplicationHazelcastTest extends AbstractAdminApplicationTest
private ServletWebServerApplicationContext instance2; private ServletWebServerApplicationContext instance2;
@Before @Before
public void setup() throws InterruptedException { public void setUp() throws Exception {
System.setProperty("hazelcast.wait.seconds.before.join", "0"); System.setProperty("hazelcast.wait.seconds.before.join", "0");
instance1 = (ServletWebServerApplicationContext) SpringApplication.run(TestAdminApplication.class, instance1 = (ServletWebServerApplicationContext) SpringApplication.run(TestAdminApplication.class,
"--server.port=0", "--spring.jmx.enabled=false", "--management.context-path=/mgmt", "--server.port=0", "--spring.jmx.enabled=false", "--management.context-path=/mgmt",
...@@ -57,23 +51,7 @@ public class AdminApplicationHazelcastTest extends AbstractAdminApplicationTest ...@@ -57,23 +51,7 @@ public class AdminApplicationHazelcastTest extends AbstractAdminApplicationTest
"--server.port=0", "--spring.jmx.enabled=false", "--management.context-path=/mgmt", "--server.port=0", "--spring.jmx.enabled=false", "--management.context-path=/mgmt",
"--info.test=foobar"); "--info.test=foobar");
int port = instance1.getWebServer().getPort(); super.setUp(instance1.getWebServer().getPort());
super.setPort(port);
WebTestClient webClient = createWebClient(port);
super.setWebClient(webClient);
}
private WebTestClient createWebClient(int port) {
ObjectMapper mapper = new ObjectMapper().registerModule(new JsonOrgModule());
return WebTestClient.bindToServer()
.baseUrl("http://localhost:" + port)
.exchangeStrategies(ExchangeStrategies.builder().codecs((configurer) -> {
configurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(mapper));
configurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(mapper));
}).build())
.build();
} }
@After @After
......
...@@ -28,41 +28,16 @@ import org.springframework.boot.SpringApplication; ...@@ -28,41 +28,16 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
import org.springframework.http.MediaType;
import org.springframework.http.codec.json.Jackson2JsonDecoder;
import org.springframework.http.codec.json.Jackson2JsonEncoder;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule;
public class AdminApplicationTest extends AbstractAdminApplicationTest { public class AdminApplicationTest extends AbstractAdminApplicationTest {
private ServletWebServerApplicationContext instance; private ServletWebServerApplicationContext instance;
@Before @Before
public void setup() throws InterruptedException { public void setUp() throws Exception {
System.setProperty("hazelcast.wait.seconds.before.join", "0");
instance = (ServletWebServerApplicationContext) SpringApplication.run(TestAdminApplication.class, instance = (ServletWebServerApplicationContext) SpringApplication.run(TestAdminApplication.class,
"--server.port=0", "--spring.jmx.enabled=false", "--management.context-path=/mgmt", "--server.port=0", "--management.context-path=/mgmt", "--info.test=foobar");
"--info.test=foobar");
int port = instance.getWebServer().getPort(); super.setUp(instance.getWebServer().getPort());
super.setPort(port);
WebTestClient webClient = createWebClient(port);
super.setWebClient(webClient);
}
private WebTestClient createWebClient(int port) {
ObjectMapper mapper = new ObjectMapper().registerModule(new JsonOrgModule());
return WebTestClient.bindToServer()
.baseUrl("http://localhost:" + port)
.exchangeStrategies(ExchangeStrategies.builder().codecs((configurer) -> {
configurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(mapper));
configurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(mapper));
}).build())
.build();
} }
@After @After
...@@ -70,7 +45,6 @@ public class AdminApplicationTest extends AbstractAdminApplicationTest { ...@@ -70,7 +45,6 @@ public class AdminApplicationTest extends AbstractAdminApplicationTest {
instance.close(); instance.close();
} }
@EnableAdminServer @EnableAdminServer
@EnableAutoConfiguration @EnableAutoConfiguration
@SpringBootConfiguration @SpringBootConfiguration
......
...@@ -3,33 +3,5 @@ server: ...@@ -3,33 +3,5 @@ server:
spring: spring:
application: application:
name: spring-boot-admin-server-test name: spring-boot-admin-server-test
info:
version: 1.0.0
---
spring:
profiles: default
boot:
admin:
url: http://localhost:8080
---
server:
port: 8761
spring:
profiles: eurekaServer
jmx: jmx:
enabled: false enabled: false
boot:
admin:
contextPath: /admin
eureka:
client:
registerWithEureka: true
fetchRegistry: true
registry-fetch-interval-seconds: 5
serviceUrl:
defaultZone: http://localhost:8761/eureka/
instance:
nonSecurePort: 8761
home-page-url: http://${spring.cloud.client.hostname}:3333
health-check-url: http://${spring.cloud.client.hostname}:4444/customHealth
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