From 3a7af2c8fea8ad4e3cb3136409c0a5637ea9b4f4 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 20 Jun 2017 13:31:35 +0100 Subject: [PATCH] Generate some stubs, yay! --- pom.xml | 15 +++ spring-cloud-netflix-eureka-server/pom.xml | 62 +++++++++- .../doc/AbstractDocumentationTests.java | 111 ++++++++++++++++++ .../eureka/server/doc/EmptyAppsTests.java | 59 ++++++++++ .../eureka/server/doc/EurekaObjectMapper.java | 56 +++++++++ .../server/doc/RegisteredAppsTests.java | 80 +++++++++++++ .../src/test/resources/application.properties | 6 +- spring-cloud-netflix-hystrix-contract/pom.xml | 1 - spring-cloud-netflix-hystrix-stream/pom.xml | 7 +- 9 files changed, 391 insertions(+), 6 deletions(-) create mode 100644 spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/doc/AbstractDocumentationTests.java create mode 100644 spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/doc/EmptyAppsTests.java create mode 100644 spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/doc/EurekaObjectMapper.java create mode 100644 spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/doc/RegisteredAppsTests.java diff --git a/pom.xml b/pom.xml index 1eeb4108..16b684e2 100644 --- a/pom.xml +++ b/pom.xml @@ -27,6 +27,8 @@ 1.3.0.BUILD-SNAPSHOT 1.4.0.BUILD-SNAPSHOT Ditmars.BUILD-SNAPSHOT + + 1.1.2.BUILD-SNAPSHOT 3.6.1 @@ -70,6 +72,12 @@ + + org.springframework.cloud + spring-cloud-netflix-hystrix-contract + ${project.version} + test + org.springframework.cloud spring-cloud-netflix-dependencies @@ -105,6 +113,13 @@ pom import + + org.springframework.cloud + spring-cloud-contract-dependencies + ${spring-cloud-contract.version} + pom + import + io.netty netty-codec-http diff --git a/spring-cloud-netflix-eureka-server/pom.xml b/spring-cloud-netflix-eureka-server/pom.xml index 94533bd7..7a3ab77d 100644 --- a/spring-cloud-netflix-eureka-server/pom.xml +++ b/spring-cloud-netflix-eureka-server/pom.xml @@ -96,11 +96,28 @@ com.thoughtworks.xstream xstream + + org.projectlombok + lombok + + compile + true + + + org.springframework.restdocs + spring-restdocs-restassured + test + org.springframework.boot spring-boot-starter-test test + + org.springframework.cloud + spring-cloud-contract-wiremock + test + @@ -116,7 +133,7 @@ maven-resources-plugin - copy-resources validate @@ -133,6 +150,25 @@ + + copy-resources + prepare-package + + copy-resources + + + + ${project.build.outputDirectory}/static/docs + + + + + ${project.build.directory}/generated-docs + + + + + @@ -168,6 +204,30 @@ + + org.asciidoctor + asciidoctor-maven-plugin + + + generate-docs + prepare-package + + process-asciidoc + + + html + book + + + + + + org.springframework.restdocs + spring-restdocs-asciidoctor + 1.1.3.RELEASE + + + diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/doc/AbstractDocumentationTests.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/doc/AbstractDocumentationTests.java new file mode 100644 index 00000000..597c093d --- /dev/null +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/doc/AbstractDocumentationTests.java @@ -0,0 +1,111 @@ +/* + * Copyright 2013-2015 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 org.springframework.cloud.netflix.eureka.server.doc; + +import com.jayway.restassured.RestAssured; +import com.jayway.restassured.builder.RequestSpecBuilder; +import com.jayway.restassured.filter.Filter; +import com.jayway.restassured.specification.RequestSpecification; + +import org.junit.Rule; +import org.junit.runner.RunWith; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.context.embedded.LocalServerPort; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.cloud.contract.wiremock.restdocs.WireMockSnippet; +import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; +import org.springframework.cloud.netflix.eureka.server.doc.AbstractDocumentationTests.Application; +import org.springframework.context.annotation.Configuration; +import org.springframework.restdocs.JUnitRestDocumentation; +import org.springframework.restdocs.restassured.RestAssuredRestDocumentation; +import org.springframework.restdocs.restassured.RestDocumentationFilter; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; +import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.documentationConfiguration; +import static org.springframework.restdocs.restassured.operation.preprocess.RestAssuredPreprocessors.modifyUris; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.DEFINED_PORT, value = { + "spring.jmx.enabled=true", "management.security.enabled=false" }) +@DirtiesContext +public abstract class AbstractDocumentationTests { + + @LocalServerPort + private int port = 0; + + @Rule + public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation( + "target/generated-snippets"); + + private RestDocumentationFilter filter(String name) { + return RestAssuredRestDocumentation.document(name, + preprocessRequest(modifyUris().host("eureka.example.com").removePort(), + prettyPrint()), + preprocessResponse(prettyPrint())); + } + + private RequestSpecification document(Filter... filters) { + return document(null, filters); + } + + private RequestSpecification document(Object body, Filter... filters) { + RequestSpecBuilder builder = new RequestSpecBuilder() + .addFilter(documentationConfiguration(this.restDocumentation).snippets() + .withAdditionalDefaults(new WireMockSnippet())); + for (Filter filter : filters) { + builder = builder.addFilter(filter); + } + RequestSpecification spec = builder.setPort(this.port).build(); + if (body != null) { + spec.contentType("application/json").body(body, new EurekaObjectMapper()); + } + return spec; + } + + protected RequestSpecification assure(String name, Object body) { + RestDocumentationFilter filter = filter(name); + return RestAssured.given(document(body, filter)).filter(filter); + } + + protected RequestSpecification assure(String name) { + RestDocumentationFilter filter = filter(name); + return RestAssured.given(document(filter)).filter(filter); + } + + protected RequestSpecification assure() { + return assure("{method-name}"); + } + + @Configuration + @EnableAutoConfiguration + @EnableEurekaServer + protected static class Application { + public static void main(String[] args) { + new SpringApplicationBuilder(Application.class).properties( + "spring.application.name=eureka", "management.security.enabled=false", + "eureka.client.registerWithEureka=true").run(args); + } + } + +} diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/doc/EmptyAppsTests.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/doc/EmptyAppsTests.java new file mode 100644 index 00000000..2813a041 --- /dev/null +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/doc/EmptyAppsTests.java @@ -0,0 +1,59 @@ +/* + * Copyright 2013-2015 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 org.springframework.cloud.netflix.eureka.server.doc; + +import com.netflix.appinfo.ApplicationInfoManager; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.emptyIterable; + +@RunWith(SpringJUnit4ClassRunner.class) +public class EmptyAppsTests extends AbstractDocumentationTests { + + @Autowired + private EurekaInstanceConfigBean instanceConfig; + @Autowired + private ApplicationInfoManager applicationInfoManager; + + @Test + public void addApp() throws Exception { + instanceConfig.setAppname("foo"); + instanceConfig.setInstanceId("unique-id"); + instanceConfig.setHostname("foo.example.com"); + applicationInfoManager.initComponent(instanceConfig); + assure("add-app", applicationInfoManager.getInfo()).when() + .post("/eureka/apps/FOO").then().assertThat().statusCode(is(204)); + assure("delete-app").when() + .delete("/eureka/apps/FOO/{id}", + applicationInfoManager.getInfo().getInstanceId()) + .then().assertThat().statusCode(is(200)); + } + + @Test + public void emptyApps() { + assure().when().accept("application/json").get("/eureka/apps").then().assertThat() + .body("applications.application", emptyIterable()).statusCode(is(200)); + } + +} diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/doc/EurekaObjectMapper.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/doc/EurekaObjectMapper.java new file mode 100644 index 00000000..c5b28ef0 --- /dev/null +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/doc/EurekaObjectMapper.java @@ -0,0 +1,56 @@ +/* + * Copyright 2016-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 org.springframework.cloud.netflix.eureka.server.doc; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import javax.ws.rs.core.MediaType; + +import com.jayway.restassured.mapper.ObjectMapperDeserializationContext; +import com.jayway.restassured.mapper.ObjectMapperSerializationContext; +import com.netflix.discovery.converters.EntityBodyConverter; + +final class EurekaObjectMapper + implements com.jayway.restassured.mapper.ObjectMapper { + private EntityBodyConverter converter = new EntityBodyConverter(); + + @Override + public Object serialize(ObjectMapperSerializationContext context) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + converter.write(context.getObjectToSerialize(), out, + MediaType.APPLICATION_JSON_TYPE); + } + catch (IOException e) { + throw new IllegalStateException("Cannot serialize", e); + } + return out.toByteArray(); + } + + @Override + public Object deserialize( + ObjectMapperDeserializationContext context) { + try { + return converter.read( + context.getDataToDeserialize().asInputStream(), + context.getType(), MediaType.APPLICATION_JSON_TYPE); + } + catch (IOException e) { + throw new IllegalStateException("Cannot deserialize", e); + } + } +} \ No newline at end of file diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/doc/RegisteredAppsTests.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/doc/RegisteredAppsTests.java new file mode 100644 index 00000000..fd28e6ec --- /dev/null +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/doc/RegisteredAppsTests.java @@ -0,0 +1,80 @@ +/* + * Copyright 2013-2015 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 org.springframework.cloud.netflix.eureka.server.doc; + +import com.netflix.appinfo.ApplicationInfoManager; + +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.netflix.eureka.CloudEurekaClient; +import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean; +import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.hasSize; + +@RunWith(SpringJUnit4ClassRunner.class) +public class RegisteredAppsTests extends AbstractDocumentationTests { + + @Autowired + private EurekaInstanceConfigBean instanceConfig; + @Autowired + private EurekaClientConfigBean clientConfig; + @Autowired + private ApplicationInfoManager applicationInfoManager; + @Autowired + private ApplicationEventPublisher publisher; + + private static CloudEurekaClient client; + + @Before + public void setUp() throws Exception { + if (client == null) { + instanceConfig.setAppname("foo"); + instanceConfig.setLeaseRenewalIntervalInSeconds(1); + applicationInfoManager.initComponent(instanceConfig); + clientConfig.setInitialInstanceInfoReplicationIntervalSeconds(0); + clientConfig.setRegisterWithEureka(true); + client = new CloudEurekaClient(applicationInfoManager, clientConfig, + publisher); + // Give registration a chance to work + while (client.getLastSuccessfulHeartbeatTimePeriod() < 0) { + Thread.sleep(100L); + } + } + } + + @AfterClass + public static void cleanUp() { + if (client != null) { + client.shutdown(); + } + } + + @Test + public void registeredApps() throws Exception { + assure().accept("application/json").when().get("/eureka/apps").then().assertThat() + .body("applications.application", hasSize(1)).statusCode(is(200)); + } + +} diff --git a/spring-cloud-netflix-eureka-server/src/test/resources/application.properties b/spring-cloud-netflix-eureka-server/src/test/resources/application.properties index 6897a296..1d7b7452 100644 --- a/spring-cloud-netflix-eureka-server/src/test/resources/application.properties +++ b/spring-cloud-netflix-eureka-server/src/test/resources/application.properties @@ -1,4 +1,6 @@ -server.port=8761 +server.port=${local.server.port:8761} spring.application.name=eureka eureka.client.registerWithEureka=false -eureka.client.fetchRegistry=false \ No newline at end of file +eureka.client.fetchRegistry=false +logging.level.org.springframework.web.client=DEBUG +logging.level.com.netflix.discovery=DEBUG \ No newline at end of file diff --git a/spring-cloud-netflix-hystrix-contract/pom.xml b/spring-cloud-netflix-hystrix-contract/pom.xml index 4f9a3421..7b1b8359 100644 --- a/spring-cloud-netflix-hystrix-contract/pom.xml +++ b/spring-cloud-netflix-hystrix-contract/pom.xml @@ -29,7 +29,6 @@ org.springframework.cloud spring-cloud-contract-verifier - ${spring-cloud-contract.version} diff --git a/spring-cloud-netflix-hystrix-stream/pom.xml b/spring-cloud-netflix-hystrix-stream/pom.xml index 951356e6..8fb84f8d 100644 --- a/spring-cloud-netflix-hystrix-stream/pom.xml +++ b/spring-cloud-netflix-hystrix-stream/pom.xml @@ -14,7 +14,6 @@ Spring Cloud Netflix Hystrix Stream ${basedir}/.. - 1.0.5.RELEASE @@ -79,7 +78,11 @@ org.springframework.cloud spring-cloud-netflix-hystrix-contract - ${project.version} + test + + + org.springframework.cloud + spring-cloud-contract-verifier test