From 749665b1ec790e24ae564662c4297e97a4259821 Mon Sep 17 00:00:00 2001 From: Rakesh Pawar Date: Thu, 20 Jul 2017 17:01:26 +0530 Subject: [PATCH 1/2] issue-2319 parse Example from APiResponse annotations --- .../io/swagger/annotations/ApiResponse.java | 2 + .../swagger/annotations/ExampleProperty.java | 2 +- .../main/java/io/swagger/jaxrs/Reader.java | 37 +++++++++++-------- .../main/java/io/swagger/models/Response.java | 3 +- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/modules/swagger-annotations/src/main/java/io/swagger/annotations/ApiResponse.java b/modules/swagger-annotations/src/main/java/io/swagger/annotations/ApiResponse.java index f9b2bccd43..51382b5dd5 100644 --- a/modules/swagger-annotations/src/main/java/io/swagger/annotations/ApiResponse.java +++ b/modules/swagger-annotations/src/main/java/io/swagger/annotations/ApiResponse.java @@ -85,4 +85,6 @@ * Valid values are "List", "Set" or "Map". Any other value will be ignored. */ String responseContainer() default ""; + + Example examples() default @Example(value = @ExampleProperty(value = "", mediaType = "")); } diff --git a/modules/swagger-annotations/src/main/java/io/swagger/annotations/ExampleProperty.java b/modules/swagger-annotations/src/main/java/io/swagger/annotations/ExampleProperty.java index 4bd5d6e8e3..0f90c728f7 100644 --- a/modules/swagger-annotations/src/main/java/io/swagger/annotations/ExampleProperty.java +++ b/modules/swagger-annotations/src/main/java/io/swagger/annotations/ExampleProperty.java @@ -36,7 +36,7 @@ * * @return the name of the property */ - String mediaType() default "default"; + String mediaType() default ""; /** * The value of the example. diff --git a/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java b/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java index 27a6e72a1c..1f78aad6ed 100644 --- a/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java +++ b/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java @@ -23,21 +23,7 @@ import com.fasterxml.jackson.databind.introspect.AnnotatedMethod; import com.fasterxml.jackson.databind.introspect.AnnotatedParameter; import com.fasterxml.jackson.databind.type.TypeFactory; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; -import io.swagger.annotations.ApiKeyAuthDefinition; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import io.swagger.annotations.Authorization; -import io.swagger.annotations.AuthorizationScope; -import io.swagger.annotations.BasicAuthDefinition; -import io.swagger.annotations.Info; -import io.swagger.annotations.OAuth2Definition; -import io.swagger.annotations.ResponseHeader; -import io.swagger.annotations.Scope; -import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.*; import io.swagger.converter.ModelConverters; import io.swagger.jaxrs.config.DefaultReaderConfig; import io.swagger.jaxrs.config.ReaderConfig; @@ -1007,9 +993,10 @@ private void processOperationDecorator(Operation operation, Method method) { private void addResponse(Operation operation, ApiResponse apiResponse, JsonView jsonView) { Map responseHeaders = parseResponseHeaders(apiResponse.responseHeaders(), jsonView); + Map examples = parseExamples(apiResponse.examples()); Response response = new Response() - .description(apiResponse.message()).headers(responseHeaders); + .description(apiResponse.message()).headers(responseHeaders).setExamples(examples); if (apiResponse.code() == 0) { operation.defaultResponse(response); @@ -1029,6 +1016,24 @@ private void addResponse(Operation operation, ApiResponse apiResponse, JsonView } } + private Map parseExamples(Example examples) { + if(examples == null){ + return null; + } + + Map map = null; + for(ExampleProperty prop : examples.value()){ + + if(prop.mediaType().equals("") && prop.value().equals("")){ + continue; + } + + map = map == null ? new HashMap() : map; + map.put(prop.mediaType(), prop.value()); + } + return map; + } + private List getParameters(Type type, List annotations) { final Iterator chain = SwaggerExtensions.chain(); if (!chain.hasNext()) { diff --git a/modules/swagger-models/src/main/java/io/swagger/models/Response.java b/modules/swagger-models/src/main/java/io/swagger/models/Response.java index 545d7c1957..d4ce91f8f8 100644 --- a/modules/swagger-models/src/main/java/io/swagger/models/Response.java +++ b/modules/swagger-models/src/main/java/io/swagger/models/Response.java @@ -91,8 +91,9 @@ public Map getExamples() { return this.examples; } - public void setExamples(Map examples) { + public Response setExamples(Map examples) { this.examples = examples; + return this; } public Map getHeaders() { From e0934811d38d1b43fe67a528bb939fa15d719667 Mon Sep 17 00:00:00 2001 From: frantuma Date: Tue, 8 May 2018 17:14:55 +0200 Subject: [PATCH 2/2] refs #2319 - response example support: tests and fixes --- .../io/swagger/annotations/ApiResponse.java | 7 ++++ .../main/java/io/swagger/jaxrs/Reader.java | 24 +++++++++++-- .../java/io/swagger/SimpleReaderTest.java | 25 +++++++++++++ .../ResourceWithResponseExamples.java | 35 +++++++++++++++++++ .../main/java/io/swagger/models/Response.java | 3 +- 5 files changed, 89 insertions(+), 5 deletions(-) create mode 100644 modules/swagger-jaxrs/src/test/java/io/swagger/resources/ResourceWithResponseExamples.java diff --git a/modules/swagger-annotations/src/main/java/io/swagger/annotations/ApiResponse.java b/modules/swagger-annotations/src/main/java/io/swagger/annotations/ApiResponse.java index 51382b5dd5..7fbc43f8c3 100644 --- a/modules/swagger-annotations/src/main/java/io/swagger/annotations/ApiResponse.java +++ b/modules/swagger-annotations/src/main/java/io/swagger/annotations/ApiResponse.java @@ -86,5 +86,12 @@ */ String responseContainer() default ""; + /** + * Examples for the response. + * + * @since 1.5.20 + * + * @return + */ Example examples() default @Example(value = @ExampleProperty(value = "", mediaType = "")); } diff --git a/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java b/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java index 1f78aad6ed..ec079ffa0a 100644 --- a/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java +++ b/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java @@ -23,7 +23,23 @@ import com.fasterxml.jackson.databind.introspect.AnnotatedMethod; import com.fasterxml.jackson.databind.introspect.AnnotatedParameter; import com.fasterxml.jackson.databind.type.TypeFactory; -import io.swagger.annotations.*; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiKeyAuthDefinition; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.Authorization; +import io.swagger.annotations.AuthorizationScope; +import io.swagger.annotations.BasicAuthDefinition; +import io.swagger.annotations.Example; +import io.swagger.annotations.ExampleProperty; +import io.swagger.annotations.Info; +import io.swagger.annotations.OAuth2Definition; +import io.swagger.annotations.ResponseHeader; +import io.swagger.annotations.Scope; +import io.swagger.annotations.SwaggerDefinition; import io.swagger.converter.ModelConverters; import io.swagger.jaxrs.config.DefaultReaderConfig; import io.swagger.jaxrs.config.ReaderConfig; @@ -996,7 +1012,9 @@ private void addResponse(Operation operation, ApiResponse apiResponse, JsonView Map examples = parseExamples(apiResponse.examples()); Response response = new Response() - .description(apiResponse.message()).headers(responseHeaders).setExamples(examples); + .description(apiResponse.message()) + .headers(responseHeaders); + response.setExamples(examples); if (apiResponse.code() == 0) { operation.defaultResponse(response); @@ -1028,7 +1046,7 @@ private Map parseExamples(Example examples) { continue; } - map = map == null ? new HashMap() : map; + map = map == null ? new LinkedHashMap() : map; map.put(prop.mediaType(), prop.value()); } return map; diff --git a/modules/swagger-jaxrs/src/test/java/io/swagger/SimpleReaderTest.java b/modules/swagger-jaxrs/src/test/java/io/swagger/SimpleReaderTest.java index fd43bf3876..a04cd597e0 100644 --- a/modules/swagger-jaxrs/src/test/java/io/swagger/SimpleReaderTest.java +++ b/modules/swagger-jaxrs/src/test/java/io/swagger/SimpleReaderTest.java @@ -50,6 +50,7 @@ import io.swagger.resources.ResourceWithMapReturnValue; import io.swagger.resources.ResourceWithRanges; import io.swagger.resources.ResourceWithResponse; +import io.swagger.resources.ResourceWithResponseExamples; import io.swagger.resources.ResourceWithResponseHeaders; import io.swagger.resources.ResourceWithTypedResponses; import io.swagger.resources.ResourceWithVoidReturns; @@ -585,6 +586,30 @@ public void checkResponseModelsProcessing() { } } + @Test(description = "test response examples") + public void testResponseExamples() { + Swagger swagger = getSwagger(ResourceWithResponseExamples.class); + for (Map.Entry entry : swagger.getPaths().entrySet()) { + String name = entry.getKey().substring(entry.getKey().lastIndexOf("/") + 1); + if ("testPrimitiveResponses".equals(name)) { + Map expected = ImmutableMap.of("404", new String[]{"string", null}); + assertEquals(entry.getValue().getGet().getResponses().size(), expected.size()); + for (Map.Entry responseEntry : entry.getValue().getGet().getResponses().entrySet()) { + String[] expectedProp = expected.get(responseEntry.getKey()); + Model model = responseEntry.getValue().getResponseSchema(); + ModelImpl modelImpl = (ModelImpl) model; + assertEquals(modelImpl.getType(), expectedProp[0]); + assertEquals(modelImpl.getFormat(), expectedProp[1]); + Response response = responseEntry.getValue(); + assertEquals(response.getExamples().size(), 2); + assertEquals(response.getExamples().get("*/*").toString(), "message example 1"); + assertEquals(response.getExamples().get("application/json").toString(), "message example 2"); + } + } + } + } + + @Test(description = "scan a resource with custom operation nickname") public void scanResourceWithApiOperationNickname() { Swagger swagger = getSwagger(NicknamedOperation.class); diff --git a/modules/swagger-jaxrs/src/test/java/io/swagger/resources/ResourceWithResponseExamples.java b/modules/swagger-jaxrs/src/test/java/io/swagger/resources/ResourceWithResponseExamples.java new file mode 100644 index 0000000000..0fccafd509 --- /dev/null +++ b/modules/swagger-jaxrs/src/test/java/io/swagger/resources/ResourceWithResponseExamples.java @@ -0,0 +1,35 @@ +package io.swagger.resources; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.Example; +import io.swagger.annotations.ExampleProperty; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; + +@Api(value = "/root") +@Path("/") +public class ResourceWithResponseExamples { + + @GET + @Path("testPrimitiveResponses") + @ApiResponses({ + @ApiResponse( + code = 404, + message = "Message for String", + response = String.class, + examples = @Example(value = + { + @ExampleProperty(mediaType = "*/*", value = "message example 1"), + @ExampleProperty(mediaType = "application/json", value = "message example 2") + } + )) + }) + public Response testPrimitiveResponses() { + return null; + } + +} diff --git a/modules/swagger-models/src/main/java/io/swagger/models/Response.java b/modules/swagger-models/src/main/java/io/swagger/models/Response.java index d4ce91f8f8..545d7c1957 100644 --- a/modules/swagger-models/src/main/java/io/swagger/models/Response.java +++ b/modules/swagger-models/src/main/java/io/swagger/models/Response.java @@ -91,9 +91,8 @@ public Map getExamples() { return this.examples; } - public Response setExamples(Map examples) { + public void setExamples(Map examples) { this.examples = examples; - return this; } public Map getHeaders() {