diff --git a/modules/swagger-jaxrs2-servlet-initializer/pom.xml b/modules/swagger-jaxrs2-servlet-initializer/pom.xml index d8650b3f84..5decdc30be 100644 --- a/modules/swagger-jaxrs2-servlet-initializer/pom.xml +++ b/modules/swagger-jaxrs2-servlet-initializer/pom.xml @@ -38,6 +38,26 @@ + + org.codehaus.mojo + build-helper-maven-plugin + 3.0.0 + + + jetty.port + jetty.port.stop + + + + + reserve-port + pre-integration-test + + reserve-network-port + + + + org.apache.maven.plugins maven-failsafe-plugin @@ -48,6 +68,11 @@ integration-test verify + + + ${jetty.port} + + @@ -56,8 +81,9 @@ jetty-maven-plugin 10 + ${jetty.port} a - 9999 + ${jetty.port.stop} true ${project.basedir}/src/test/webapp diff --git a/modules/swagger-jaxrs2/pom.xml b/modules/swagger-jaxrs2/pom.xml index 09bb93f77f..4b9e607b35 100644 --- a/modules/swagger-jaxrs2/pom.xml +++ b/modules/swagger-jaxrs2/pom.xml @@ -43,6 +43,26 @@ + + org.codehaus.mojo + build-helper-maven-plugin + 3.0.0 + + + jetty.port + jetty.port.stop + + + + + reserve-port + pre-integration-test + + reserve-network-port + + + + org.apache.maven.plugins maven-failsafe-plugin @@ -53,6 +73,11 @@ integration-test verify + + + ${jetty.port} + + @@ -61,8 +86,9 @@ jetty-maven-plugin 10 + ${jetty.port} a - 9999 + ${jetty.port.stop} true ${project.basedir}/src/test/webapp @@ -158,18 +184,6 @@ mockito-all test - - org.glassfish.jersey.core - jersey-server - ${jersey2-version} - test - - - org.javassist - javassist - - - 2.0.0-SNAPSHOT diff --git a/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/annotations/AbstractAnnotationTest.java b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/annotations/AbstractAnnotationTest.java index 27d63b32b9..c0f8db58e9 100644 --- a/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/annotations/AbstractAnnotationTest.java +++ b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/annotations/AbstractAnnotationTest.java @@ -30,4 +30,12 @@ public void compareAsYaml(Class cls, String yaml) throws IOException { OpenAPI openAPI = reader.read(cls); SerializationMatchers.assertEqualsToYaml(openAPI, yaml); } + + public void compareAsYaml(String actualYaml, String expectedYaml) throws IOException { + SerializationMatchers.assertEqualsToYaml(Yaml.mapper().readValue(actualYaml, OpenAPI.class), expectedYaml); + } + public void compareAsJson(String actualJson, String expectedJson) throws IOException { + SerializationMatchers.assertEqualsToJson(Yaml.mapper().readValue(actualJson, OpenAPI.class), expectedJson); + } + } diff --git a/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/it/OpenApiResourceIT.java b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/it/OpenApiResourceIT.java new file mode 100644 index 0000000000..e54d4eb7c0 --- /dev/null +++ b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/it/OpenApiResourceIT.java @@ -0,0 +1,189 @@ +package io.swagger.v3.jaxrs2.it; + +import com.jayway.restassured.http.ContentType; + +import io.swagger.v3.jaxrs2.annotations.AbstractAnnotationTest; +import org.testng.SkipException; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import static com.jayway.restassured.RestAssured.given; + +/** + *

+ * An functional integration test that runs during maven's integration-test phase, + * uses RestAssured to define REST API tests, and Jetty's Maven plugin to serve a simple + * sample app just prior to the integration-test phase starting. + */ +public class OpenApiResourceIT extends AbstractAnnotationTest { + private static final String EXPECTED_JSON = "{\n" + + " \"openapi\": \"3.0.0\",\n" + + " \"paths\": {\n" + + " \"/widgets/{widgetId}\": {\n" + + " \"get\": {\n" + + " \"tags\": [\n" + + " \"widgets\"\n" + + " ],\n" + + " \"summary\": \"Find pet by ID\",\n" + + " \"description\": \"Returns a pet when ID <= 10. ID > 10 or nonintegers will simulate API error conditions\",\n" + + " \"operationId\": \"getWidget\",\n" + + " \"parameters\": [\n" + + " {\n" + + " \"name\": \"widgetId\",\n" + + " \"in\": \"path\",\n" + + " \"required\": true,\n" + + " \"schema\": {\n" + + " \"type\": \"string\"\n" + + " }\n" + + " }\n" + + " ],\n" + + " \"responses\": {\n" + + " \"200\": {\n" + + " \"description\": \"Returns widget with matching id\",\n" + + " \"content\": {\n" + + " \"application/json\": {\n" + + " \"schema\": {\n" + + " \"$ref\": \"#/components/schemas/Widget\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " },\n" + + " \"components\": {\n" + + " \"schemas\": {\n" + + " \"Widget\": {\n" + + " \"type\": \"object\",\n" + + " \"properties\": {\n" + + " \"a\": {\n" + + " \"type\": \"string\"\n" + + " },\n" + + " \"b\": {\n" + + " \"type\": \"string\"\n" + + " },\n" + + " \"id\": {\n" + + " \"type\": \"string\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + "}"; + private static final String EXPECTED_YAML = "openapi: 3.0.0\n" + + "paths:\n" + + " /widgets/{widgetId}:\n" + + " get:\n" + + " tags:\n" + + " - widgets\n" + + " summary: Find pet by ID\n" + + " description: Returns a pet when ID <= 10. ID > 10 or nonintegers will simulate\n" + + " API error conditions\n" + + " operationId: getWidget\n" + + " parameters:\n" + + " - name: widgetId\n" + + " in: path\n" + + " required: true\n" + + " schema:\n" + + " type: string\n" + + " responses:\n" + + " 200:\n" + + " description: Returns widget with matching id\n" + + " content:\n" + + " application/json:\n" + + " schema:\n" + + " $ref: '#/components/schemas/Widget'\n" + + "components:\n" + + " schemas:\n" + + " Widget:\n" + + " type: object\n" + + " properties:\n" + + " a:\n" + + " type: string\n" + + " b:\n" + + " type: string\n" + + " id:\n" + + " type: string\n"; + + private static final int jettyPort = System.getProperties().containsKey("jetty.port") ? Integer.parseInt(System.getProperty("jetty.port")): -1; + + @BeforeMethod + public void checkJetty() { + if (jettyPort == -1) { + throw new SkipException("Jetty not configured"); + } + } + + @Test + public void testSwaggerJson() throws Exception { + + String actualBody = given() + .port(jettyPort) + .log().all() + .when() + .get("/openapi.json") + .then() + .log().all() + .assertThat() + .statusCode(200) + .contentType(ContentType.JSON) + .extract() + .response().body().asString(); + + compareAsJson(actualBody, EXPECTED_JSON); + } + + @Test + public void testSwaggerJsonUsingAcceptHeader() throws Exception { + String actualBody = given() + .port(jettyPort) + .log().all() + .accept(ContentType.JSON) + .when() + .get("/openapi") + .then() + .log().all() + .assertThat() + .statusCode(200) + .contentType(ContentType.JSON) + .extract().response().body().asString(); + + compareAsJson(actualBody, EXPECTED_JSON); + } + + @Test + public void testSwaggerYaml() throws Exception { + String actualBody = given() + .port(jettyPort) + .log().all() + .when() + .get("/openapi.yaml") + .then() + .log().all() + .assertThat() + .statusCode(200) + .contentType("application/yaml") + .extract().response().body().asString(); + + compareAsYaml(actualBody, EXPECTED_YAML); + } + + @Test + public void testSwaggerYamlUsingAcceptHeader() throws Exception { + String actualBody = given() + .port(jettyPort) + .log().all() + .accept("application/yaml") + .when() + .get("/openapi") + .then() + .log().all() + .assertThat() + .statusCode(200) + .contentType("application/yaml") + .extract().response().body().asString(); + + compareAsYaml(actualBody, EXPECTED_YAML); + } +} diff --git a/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/it/model/Widget.java b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/it/model/Widget.java new file mode 100644 index 0000000000..31c2290688 --- /dev/null +++ b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/it/model/Widget.java @@ -0,0 +1,35 @@ +package io.swagger.v3.jaxrs2.it.model; + +public class Widget { + + private String a; + private String b; + private String id; + + public String getA() { + return a; + } + + public Widget setA(String a) { + this.a = a; + return this; + } + + public String getB() { + return b; + } + + public Widget setB(String b) { + this.b = b; + return this; + } + + public String getId() { + return id; + } + + public Widget setId(String id) { + this.id = id; + return this; + } +} diff --git a/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/it/resources/WidgetResource.java b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/it/resources/WidgetResource.java new file mode 100644 index 0000000000..ce2e84069e --- /dev/null +++ b/modules/swagger-jaxrs2/src/test/java/io/swagger/v3/jaxrs2/it/resources/WidgetResource.java @@ -0,0 +1,37 @@ +package io.swagger.v3.jaxrs2.it.resources; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; + +import io.swagger.v3.jaxrs2.it.model.Widget; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; + +import javax.ws.rs.core.Response; + +@Path("/widgets") +@Tag(name="widgets") +@Produces("application/json") +@Consumes("application/json") +public class WidgetResource { + + @Path("/{widgetId}") + @GET + @Operation(summary = "Find pet by ID", + description = "Returns a pet when ID <= 10. ID > 10 or nonintegers will simulate API error conditions", + responses = @ApiResponse( + content = @Content(schema = @Schema(implementation = Widget.class)), + description = "Returns widget with matching id", + responseCode = "200" + ) + ) + public Response getWidget(@PathParam("widgetId") String widgetId) { + return Response.ok(new Widget().setA("foo").setB("bar")).build(); + } +} diff --git a/modules/swagger-jaxrs2/src/test/webapp/WEB-INF/web.xml b/modules/swagger-jaxrs2/src/test/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..c370bda00e --- /dev/null +++ b/modules/swagger-jaxrs2/src/test/webapp/WEB-INF/web.xml @@ -0,0 +1,31 @@ + + + + + jersey + org.glassfish.jersey.servlet.ServletContainer + + jersey.config.server.wadl.disableWadl + true + + + jersey.config.server.provider.packages + + io.swagger.v3.jaxrs2.integration.resources,io.swagger.v3.jaxrs2.it.resources + + + + openApi.configuration.prettyPrint + true + + 1 + + + + jersey + /* + + + diff --git a/pom.xml b/pom.xml index 611a0e978e..2bc09106c5 100644 --- a/pom.xml +++ b/pom.xml @@ -204,6 +204,52 @@ org.eclipse.jetty jetty-maven-plugin ${jetty-version} + + + org.glassfish.jersey.core + jersey-server + ${jersey2-version} + + + org.javassist + javassist + + + + + org.glassfish.jersey.containers + jersey-container-servlet + ${jersey2-version} + + + org.javassist + javassist + + + + + org.glassfish.jersey.media + jersey-media-multipart + ${jersey2-version} + + + org.javassist + javassist + + + + + org.glassfish.jersey.inject + jersey-hk2 + ${jersey2-version} + + + org.javassist + javassist + + + + org.apache.maven.plugins