This is an automated email from the ASF dual-hosted git repository. liubao pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
commit 56d8899c4039813045ff11c004c55114bc6ec12b Author: yaohaishi <[email protected]> AuthorDate: Tue Oct 16 22:48:22 2018 +0800 [SCB-964] fix MediaType setting problem --- .../org/apache/servicecomb/it/ConsumerMain.java | 2 + .../it/schema/ApiOperationJaxrsSchema.java | 50 +++++++++++++ .../it/schema/ApiOperationSpringMVCSchema.java | 46 ++++++++++++ .../servicecomb/it/schema/TestApiOperation.java | 74 +++++++++++++++++++ .../annotation/ApiOperationProcessor.java | 29 ++++---- .../annotation/SwaggerDefinitionProcessor.java | 16 ++-- .../annotation/ApiOperationProcessorTest.java | 57 ++++++++++++++ .../annotation/SwaggerDefinitionProcessorTest.java | 34 ++++++++- .../annotation/ConsumesAnnotationProcessor.java | 12 ++- .../annotation/ProducesAnnotationProcessor.java | 12 ++- .../ConsumesAnnotationProcessorTest.java | 86 ++++++++++++++++++++++ .../ProducesAnnotationProcessorTest.java | 59 +++++++++++++++ ...stractHttpMethodMappingAnnotationProcessor.java | 15 +++- ...equestMappingMethodAnnotationProcessorTest.java | 83 +++++++++++++++++++++ 14 files changed, 542 insertions(+), 33 deletions(-) diff --git a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/ConsumerMain.java b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/ConsumerMain.java index e7455da..1004eef 100644 --- a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/ConsumerMain.java +++ b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/ConsumerMain.java @@ -20,6 +20,7 @@ import org.apache.servicecomb.core.SCBEngine; import org.apache.servicecomb.foundation.common.utils.BeanUtils; import org.apache.servicecomb.it.deploy.Deploys; import org.apache.servicecomb.it.junit.ITJUnitUtils; +import org.apache.servicecomb.it.schema.TestApiOperation; import org.apache.servicecomb.it.testcase.TestAnnotatedAttribute; import org.apache.servicecomb.it.testcase.TestApiParam; import org.apache.servicecomb.it.testcase.TestChangeTransport; @@ -71,6 +72,7 @@ public class ConsumerMain { ITJUnitUtils.run(TestIgnoreStaticMethod.class); ITJUnitUtils.run(TestIgnoreMethod.class); ITJUnitUtils.run(TestApiParam.class); + ITJUnitUtils.run(TestApiOperation.class); // 1.base test case // include all extension point abnormal scenes test case diff --git a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/schema/ApiOperationJaxrsSchema.java b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/schema/ApiOperationJaxrsSchema.java new file mode 100644 index 0000000..42db9d4 --- /dev/null +++ b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/schema/ApiOperationJaxrsSchema.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.servicecomb.it.schema; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.apache.servicecomb.provider.rest.common.RestSchema; + +import io.swagger.annotations.ApiOperation; + +@RestSchema(schemaId = "apiOperationJaxrsSchema") +@Path("/apiOperationJaxrsSchema") +public class ApiOperationJaxrsSchema { + @POST + @Path("/testMediaType1") + @Consumes(MediaType.TEXT_PLAIN) + @Produces(MediaType.TEXT_HTML) + @ApiOperation(value = "testMediaType1", consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_XML) + public String testMediaType1(String input) { + return input; + } + + @POST + @Path("/testMediaType2") + @ApiOperation(value = "testMediaType2", consumes = MediaType.TEXT_PLAIN, produces = MediaType.TEXT_HTML) + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_XML) + public String testMediaType2(String input) { + return input; + } +} diff --git a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/schema/ApiOperationSpringMVCSchema.java b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/schema/ApiOperationSpringMVCSchema.java new file mode 100644 index 0000000..78781f6 --- /dev/null +++ b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/schema/ApiOperationSpringMVCSchema.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.servicecomb.it.schema; + +import javax.ws.rs.core.MediaType; + +import org.apache.servicecomb.provider.rest.common.RestSchema; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; + +@RestSchema(schemaId = "apiOperationSpringMVCSchema") +@RequestMapping(value = "/apiOperationSpringMVCSchema", consumes = MediaType.TEXT_PLAIN, produces = MediaType.TEXT_HTML) +@SwaggerDefinition(consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_XML) +public class ApiOperationSpringMVCSchema { + @RequestMapping(value = "/testMediaType1", method = RequestMethod.POST, consumes = MediaType.TEXT_PLAIN, produces = MediaType.TEXT_HTML) + @ApiOperation(value = "testMediaType1", consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_XML) + public String testMediaType1(@RequestBody String input) { + return input; + } + + @ApiOperation(value = "testMediaType2", consumes = MediaType.TEXT_PLAIN, produces = MediaType.TEXT_HTML) + @PutMapping(value = "/testMediaType2", consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_XML) + public String testMediaType2(@RequestBody String input) { + return input; + } +} diff --git a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/schema/TestApiOperation.java b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/schema/TestApiOperation.java new file mode 100644 index 0000000..dee2699 --- /dev/null +++ b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/schema/TestApiOperation.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.servicecomb.it.schema; + +import javax.ws.rs.core.MediaType; + +import org.apache.servicecomb.core.SCBEngine; +import org.apache.servicecomb.core.definition.MicroserviceMeta; +import org.apache.servicecomb.core.definition.SchemaMeta; +import org.hamcrest.Matchers; +import org.junit.Assert; +import org.junit.Test; + +import io.swagger.models.Operation; +import io.swagger.models.Swagger; + +public class TestApiOperation { + MicroserviceMeta microserviceMeta = SCBEngine.getInstance().getProducerMicroserviceMeta(); + + protected Operation getOperation(String schemaId, String opName) { + SchemaMeta schemaMeta = microserviceMeta.findSchemaMeta(schemaId); + return schemaMeta.findOperation(opName).getSwaggerOperation(); + } + + @Test + public void jaxrs_TestMediaType1() { + Operation operation = getOperation("apiOperationJaxrsSchema", "testMediaType1"); + Assert.assertThat(operation.getConsumes(), Matchers.contains(MediaType.APPLICATION_JSON)); + Assert.assertThat(operation.getProduces(), Matchers.contains(MediaType.APPLICATION_XML)); + } + + @Test + public void jaxrs_TestMediaType2() { + Operation operation = getOperation("apiOperationJaxrsSchema", "testMediaType2"); + Assert.assertThat(operation.getConsumes(), Matchers.contains(MediaType.APPLICATION_JSON)); + Assert.assertThat(operation.getProduces(), Matchers.contains(MediaType.APPLICATION_XML)); + } + + @Test + public void springMVC_TestMediaType1() { + Operation operation = getOperation("apiOperationSpringMVCSchema", "testMediaType1"); + Assert.assertThat(operation.getConsumes(), Matchers.contains(MediaType.APPLICATION_JSON)); + Assert.assertThat(operation.getProduces(), Matchers.contains(MediaType.APPLICATION_XML)); + } + + @Test + public void springMVC_TestMediaType2() { + Operation operation = getOperation("apiOperationSpringMVCSchema", "testMediaType2"); + Assert.assertThat(operation.getConsumes(), Matchers.contains(MediaType.APPLICATION_JSON)); + Assert.assertThat(operation.getProduces(), Matchers.contains(MediaType.APPLICATION_XML)); + } + + @Test + public void springMVC_TestSwaggerDefinitionMediaType() { + Swagger swagger = microserviceMeta.findSchemaMeta("apiOperationSpringMVCSchema").getSwagger(); + Assert.assertThat(swagger.getConsumes(), Matchers.contains(MediaType.APPLICATION_JSON)); + Assert.assertThat(swagger.getProduces(), Matchers.contains(MediaType.APPLICATION_XML)); + } +} diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiOperationProcessor.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiOperationProcessor.java index 344e3a3..0207727 100644 --- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiOperationProcessor.java +++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiOperationProcessor.java @@ -17,6 +17,10 @@ package org.apache.servicecomb.swagger.generator.core.processor.annotation; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + import org.apache.servicecomb.swagger.generator.core.MethodAnnotationProcessor; import org.apache.servicecomb.swagger.generator.core.OperationGenerator; import org.springframework.util.StringUtils; @@ -27,6 +31,9 @@ import io.swagger.models.Scheme; import io.swagger.util.BaseReaderUtils; public class ApiOperationProcessor implements MethodAnnotationProcessor { + + private static final String SEPARATOR = ","; + @Override public void process(Object annotation, OperationGenerator operationGenerator) { ApiOperation apiOperationAnnotation = (ApiOperation) annotation; @@ -64,7 +71,7 @@ public class ApiOperationProcessor implements MethodAnnotationProcessor { return; } - for (String protocol : protocols.split(",")) { + for (String protocol : protocols.split(SEPARATOR)) { if (StringUtils.isEmpty(protocol)) { continue; } @@ -79,12 +86,10 @@ public class ApiOperationProcessor implements MethodAnnotationProcessor { return; } - for (String consume : consumes.split(",")) { - if (StringUtils.isEmpty(consume)) { - continue; - } - - operation.addConsumes(consume); + List<String> consumeList = Arrays.stream(consumes.split(SEPARATOR)).filter(s -> !StringUtils.isEmpty(s)) + .collect(Collectors.toList()); + if (!consumeList.isEmpty()) { + operation.setConsumes(consumeList); } } @@ -94,12 +99,10 @@ public class ApiOperationProcessor implements MethodAnnotationProcessor { return; } - for (String produce : produces.split(",")) { - if (StringUtils.isEmpty(produce)) { - continue; - } - - operation.addProduces(produce); + List<String> produceList = Arrays.stream(produces.split(SEPARATOR)).filter(s -> !StringUtils.isEmpty(s)) + .collect(Collectors.toList()); + if (!produceList.isEmpty()) { + operation.setProduces(produceList); } } diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/SwaggerDefinitionProcessor.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/SwaggerDefinitionProcessor.java index 97cda46..3763b5e 100644 --- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/SwaggerDefinitionProcessor.java +++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/SwaggerDefinitionProcessor.java @@ -138,10 +138,10 @@ public class SwaggerDefinitionProcessor implements ClassAnnotationProcessor { if (produces == null) { return; } - for (String produce : produces) { - if (!StringUtils.isEmpty(produce)) { - swagger.addProduces(produce); - } + List<String> produceList = Arrays.stream(produces).filter(s -> !StringUtils.isEmpty(s)) + .collect(Collectors.toList()); + if (!produceList.isEmpty()) { + swagger.setProduces(produceList); } } @@ -150,10 +150,10 @@ public class SwaggerDefinitionProcessor implements ClassAnnotationProcessor { if (consumes == null) { return; } - for (String consume : consumes) { - if (!StringUtils.isEmpty(consume)) { - swagger.addConsumes(consume); - } + List<String> consumeList = Arrays.stream(consumes).filter(s -> !StringUtils.isEmpty(s)) + .collect(Collectors.toList()); + if (!consumeList.isEmpty()) { + swagger.setConsumes(consumeList); } } } diff --git a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiOperationProcessorTest.java b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiOperationProcessorTest.java index 0209fe3..27f285e 100644 --- a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiOperationProcessorTest.java +++ b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiOperationProcessorTest.java @@ -24,9 +24,12 @@ import static org.junit.Assert.assertThat; import java.lang.reflect.Method; import java.util.List; +import javax.ws.rs.core.MediaType; + import org.apache.servicecomb.swagger.generator.core.OperationGenerator; import org.apache.servicecomb.swagger.generator.core.SwaggerGenerator; import org.apache.servicecomb.swagger.generator.pojo.PojoSwaggerGeneratorContext; +import org.hamcrest.Matchers; import org.junit.Test; import io.swagger.annotations.ApiOperation; @@ -62,6 +65,43 @@ public class ApiOperationProcessorTest { assertNull(tagList); } + @Test + public void testMediaType() throws NoSuchMethodException { + ApiOperationProcessor apiOperationProcessor = new ApiOperationProcessor(); + + Method method = TestClass.class.getMethod("testSingleMediaType", String.class); + SwaggerGenerator swaggerGenerator = new SwaggerGenerator(new PojoSwaggerGeneratorContext(), TestClass.class); + OperationGenerator operationGenerator = new OperationGenerator(swaggerGenerator, method); + + apiOperationProcessor.process(method.getAnnotation(ApiOperation.class), operationGenerator); + + assertThat(operationGenerator.getOperation().getConsumes(), Matchers.contains(MediaType.TEXT_PLAIN)); + assertThat(operationGenerator.getOperation().getProduces(), Matchers.contains(MediaType.APPLICATION_XML)); + + method = TestClass.class.getMethod("testMultiMediaType", String.class); + apiOperationProcessor.process(method.getAnnotation(ApiOperation.class), operationGenerator); + + assertThat(operationGenerator.getOperation().getConsumes(), + Matchers.contains(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN)); + assertThat(operationGenerator.getOperation().getProduces(), + Matchers.contains(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML)); + + method = TestClass.class.getMethod("testBlankMediaType", String.class); + apiOperationProcessor.process(method.getAnnotation(ApiOperation.class), operationGenerator); + + assertThat(operationGenerator.getOperation().getConsumes(), + Matchers.contains(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN)); + assertThat(operationGenerator.getOperation().getProduces(), + Matchers.contains(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML)); + + operationGenerator.getOperation().addConsumes(MediaType.TEXT_HTML); + operationGenerator.getOperation().addProduces(MediaType.TEXT_HTML); + assertThat(operationGenerator.getOperation().getConsumes(), + Matchers.contains(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN, MediaType.TEXT_HTML)); + assertThat(operationGenerator.getOperation().getProduces(), + Matchers.contains(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_HTML)); + } + private static class TestClass { @ApiOperation(value = "value1", tags = {"tag1", "tag2"}) public void function() { @@ -70,5 +110,22 @@ public class ApiOperationProcessorTest { @ApiOperation(value = "value2") public void functionWithNoTag() { } + + @ApiOperation(value = "testSingleMediaType", consumes = MediaType.TEXT_PLAIN, produces = MediaType.APPLICATION_XML) + public String testSingleMediaType(String input) { + return input; + } + + @ApiOperation(value = "testMultiMediaType", + consumes = MediaType.APPLICATION_JSON + "," + MediaType.TEXT_PLAIN, + produces = MediaType.APPLICATION_JSON + "," + MediaType.APPLICATION_XML) + public String testMultiMediaType(String input) { + return input; + } + + @ApiOperation(value = "testBlankMediaType", consumes = "", produces = "") + public String testBlankMediaType(String input) { + return input; + } } } diff --git a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/SwaggerDefinitionProcessorTest.java b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/SwaggerDefinitionProcessorTest.java index adfae44..679b34e 100644 --- a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/SwaggerDefinitionProcessorTest.java +++ b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/SwaggerDefinitionProcessorTest.java @@ -21,8 +21,11 @@ import static org.hamcrest.Matchers.contains; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; +import javax.ws.rs.core.MediaType; + import org.apache.servicecomb.swagger.generator.core.SwaggerGenerator; import org.apache.servicecomb.swagger.generator.core.SwaggerGeneratorContext; +import org.hamcrest.Matchers; import org.junit.Test; import org.mockito.Mockito; @@ -43,10 +46,13 @@ public class SwaggerDefinitionProcessorTest { public void testProcess() { SwaggerGenerator swaggerGenerator = new SwaggerGenerator(Mockito.mock(SwaggerGeneratorContext.class), null); + Swagger swagger = swaggerGenerator.getSwagger(); + // to test MediaType overwrite + swagger.addConsumes(MediaType.APPLICATION_XML); + swagger.addProduces(MediaType.APPLICATION_XML); swaggerDefinitionProcessor.process(SwaggerTestTarget.class.getAnnotation(SwaggerDefinition.class), swaggerGenerator); - Swagger swagger = swaggerGenerator.getSwagger(); assertEquals(1, swagger.getTags().size()); io.swagger.models.Tag tag = swagger.getTags().get(0); assertEquals("testTag", tag.getName()); @@ -61,6 +67,24 @@ public class SwaggerDefinitionProcessorTest { assertEquals("desc", info.getDescription()); assertEquals("contactName", info.getContact().getName()); assertEquals("licenseName", info.getLicense().getName()); + assertThat(swagger.getConsumes(), Matchers.contains(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN)); + assertThat(swagger.getProduces(), Matchers.contains(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML)); + } + + @Test + public void testProcess_emptyMediaType() { + SwaggerGenerator swaggerGenerator = new SwaggerGenerator(Mockito.mock(SwaggerGeneratorContext.class), + null); + Swagger swagger = swaggerGenerator.getSwagger(); + // to test MediaType overwrite + swagger.addConsumes(MediaType.APPLICATION_XML); + swagger.addProduces(MediaType.TEXT_PLAIN); + swaggerDefinitionProcessor.process(SwaggerTestTarget_EmptyMediaType.class.getAnnotation(SwaggerDefinition.class), + swaggerGenerator); + + // empty media type should not be set, so keep consumes/produces not modified + assertThat(swagger.getConsumes(), Matchers.contains(MediaType.APPLICATION_XML)); + assertThat(swagger.getProduces(), Matchers.contains(MediaType.TEXT_PLAIN)); } @SwaggerDefinition(tags = { @@ -69,7 +93,13 @@ public class SwaggerDefinitionProcessorTest { host = "127.0.0.1", schemes = {Scheme.HTTP, Scheme.HTTPS}, info = @Info(title = "title", version = "version", description = "desc", contact = @Contact(name = "contactName"), - license = @License(name = "licenseName"))) + license = @License(name = "licenseName")), + consumes = {MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN}, + produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) private class SwaggerTestTarget { } + + @SwaggerDefinition(consumes = "", produces = "") + private class SwaggerTestTarget_EmptyMediaType { + } } diff --git a/swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/ConsumesAnnotationProcessor.java b/swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/ConsumesAnnotationProcessor.java index d92d977..ec2f87c 100644 --- a/swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/ConsumesAnnotationProcessor.java +++ b/swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/ConsumesAnnotationProcessor.java @@ -17,6 +17,10 @@ package org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + import javax.ws.rs.Consumes; import org.apache.servicecomb.swagger.generator.core.MethodAnnotationProcessor; @@ -28,10 +32,10 @@ public class ConsumesAnnotationProcessor implements MethodAnnotationProcessor { public void process(Object annotation, OperationGenerator operationGenerator) { Consumes consumes = (Consumes) annotation; - for (String consume : consumes.value()) { - if (!StringUtils.isEmpty(consume)) { - operationGenerator.getOperation().addConsumes(consume); - } + List<String> consumeList = Arrays.stream(consumes.value()).filter(s -> !StringUtils.isEmpty(s)) + .collect(Collectors.toList()); + if (!consumeList.isEmpty()) { + operationGenerator.getOperation().setConsumes(consumeList); } } } diff --git a/swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/ProducesAnnotationProcessor.java b/swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/ProducesAnnotationProcessor.java index 61f368b..5786c3d 100644 --- a/swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/ProducesAnnotationProcessor.java +++ b/swagger/swagger-generator/generator-jaxrs/src/main/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/ProducesAnnotationProcessor.java @@ -17,6 +17,10 @@ package org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + import javax.ws.rs.Produces; import org.apache.commons.lang3.StringUtils; @@ -28,10 +32,10 @@ public class ProducesAnnotationProcessor implements MethodAnnotationProcessor { public void process(Object annotation, OperationGenerator operationGenerator) { Produces produces = (Produces) annotation; - for (String produce : produces.value()) { - if (!StringUtils.isEmpty(produce)) { - operationGenerator.getOperation().addProduces(produce); - } + List<String> produceList = Arrays.stream(produces.value()).filter(s -> !StringUtils.isEmpty(s)) + .collect(Collectors.toList()); + if (!produceList.isEmpty()) { + operationGenerator.getOperation().setProduces(produceList); } } } diff --git a/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/ConsumesAnnotationProcessorTest.java b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/ConsumesAnnotationProcessorTest.java new file mode 100644 index 0000000..d0e3fa9 --- /dev/null +++ b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/ConsumesAnnotationProcessorTest.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.servicecomb.swagger.generator.jaxrs.processor.annotation; + +import java.lang.annotation.Annotation; + +import javax.ws.rs.Consumes; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.apache.servicecomb.swagger.generator.core.OperationGenerator; +import org.hamcrest.Matchers; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; + +import io.swagger.models.Operation; + +public class ConsumesAnnotationProcessorTest { + @Test + public void testProcess() throws NoSuchMethodException { + ConsumesAnnotationProcessor processor = new ConsumesAnnotationProcessor(); + Operation operation = new Operation(); + OperationGenerator operationGenerator = mockOperationGenerator(operation); + + Annotation consumesAnnotation = TestProducer.class.getMethod("testSingleMediaType", String.class) + .getAnnotation(Consumes.class); + processor.process(consumesAnnotation, operationGenerator); + Assert.assertThat(operation.getConsumes(), Matchers.contains(MediaType.APPLICATION_JSON)); + + consumesAnnotation = TestProducer.class.getMethod("testMultipleMediaType", String.class) + .getAnnotation(Consumes.class); + processor.process(consumesAnnotation, operationGenerator); + Assert.assertThat(operation.getConsumes(), Matchers.contains(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON)); + + consumesAnnotation = TestProducer.class.getMethod("testBlankMediaType", String.class) + .getAnnotation(Consumes.class); + processor.process(consumesAnnotation, operationGenerator); + Assert.assertThat(operation.getConsumes(), Matchers.contains(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON)); + + operation.addConsumes(MediaType.APPLICATION_XML); + Assert.assertThat(operation.getConsumes(), + Matchers.contains(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML)); + } + + static OperationGenerator mockOperationGenerator(Operation operation) { + OperationGenerator operationGenerator = Mockito.mock(OperationGenerator.class); + Mockito.when(operationGenerator.getOperation()).thenReturn(operation); + return operationGenerator; + } + + static class TestProducer { + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_XML) + public String testSingleMediaType(String input) { + return input; + } + + @Consumes({MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON}) + @Produces({MediaType.TEXT_PLAIN, MediaType.APPLICATION_XML}) + public String testMultipleMediaType(String input) { + return input; + } + + @Consumes("") + @Produces("") + public String testBlankMediaType(String input) { + return input; + } + } +} \ No newline at end of file diff --git a/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/ProducesAnnotationProcessorTest.java b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/ProducesAnnotationProcessorTest.java new file mode 100644 index 0000000..d4d3c0c --- /dev/null +++ b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/processor/annotation/ProducesAnnotationProcessorTest.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.servicecomb.swagger.generator.jaxrs.processor.annotation; + +import java.lang.annotation.Annotation; + +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.apache.servicecomb.swagger.generator.core.OperationGenerator; +import org.apache.servicecomb.swagger.generator.jaxrs.processor.annotation.ConsumesAnnotationProcessorTest.TestProducer; +import org.hamcrest.Matchers; +import org.junit.Assert; +import org.junit.Test; + +import io.swagger.models.Operation; + +public class ProducesAnnotationProcessorTest { + @Test + public void testProcess() throws NoSuchMethodException { + ProducesAnnotationProcessor processor = new ProducesAnnotationProcessor(); + Operation operation = new Operation(); + OperationGenerator operationGenerator = ConsumesAnnotationProcessorTest.mockOperationGenerator(operation); + + Annotation produceAnnotation = TestProducer.class.getMethod("testSingleMediaType", String.class) + .getAnnotation(Produces.class); + processor.process(produceAnnotation, operationGenerator); + Assert.assertThat(operation.getProduces(), Matchers.contains(MediaType.APPLICATION_XML)); + + produceAnnotation = TestProducer.class.getMethod("testMultipleMediaType", String.class) + .getAnnotation(Produces.class); + processor.process(produceAnnotation, operationGenerator); + Assert.assertThat(operation.getProduces(), Matchers.contains(MediaType.TEXT_PLAIN, MediaType.APPLICATION_XML)); + + produceAnnotation = TestProducer.class.getMethod("testBlankMediaType", String.class) + .getAnnotation(Produces.class); + processor.process(produceAnnotation, operationGenerator); + Assert.assertThat(operation.getProduces(), Matchers.contains(MediaType.TEXT_PLAIN, MediaType.APPLICATION_XML)); + + operation.addProduces(MediaType.APPLICATION_JSON); + Assert.assertThat(operation.getProduces(), + Matchers.contains(MediaType.TEXT_PLAIN, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON)); + } +} \ No newline at end of file diff --git a/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/AbstractHttpMethodMappingAnnotationProcessor.java b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/AbstractHttpMethodMappingAnnotationProcessor.java index ac82ef5..d481844 100644 --- a/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/AbstractHttpMethodMappingAnnotationProcessor.java +++ b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/AbstractHttpMethodMappingAnnotationProcessor.java @@ -18,9 +18,12 @@ package org.apache.servicecomb.swagger.generator.springmvc.processor.annotation; import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; import org.apache.servicecomb.swagger.generator.core.MethodAnnotationProcessor; import org.apache.servicecomb.swagger.generator.core.OperationGenerator; +import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMethod; import io.swagger.models.Operation; @@ -51,7 +54,11 @@ abstract class AbstractHttpMethodMappingAnnotationProcessor implements MethodAnn return; } - operation.setConsumes(Arrays.asList(consumes)); + List<String> consumeList = Arrays.stream(consumes).filter(s -> !StringUtils.isEmpty(s)) + .collect(Collectors.toList()); + if (!consumeList.isEmpty()) { + operation.setConsumes(consumeList); + } } protected void processProduces(String[] produces, Operation operation) { @@ -59,6 +66,10 @@ abstract class AbstractHttpMethodMappingAnnotationProcessor implements MethodAnn return; } - operation.setProduces(Arrays.asList(produces)); + List<String> produceList = Arrays.stream(produces).filter(s -> !StringUtils.isEmpty(s)) + .collect(Collectors.toList()); + if (!produceList.isEmpty()) { + operation.setProduces(produceList); + } } } diff --git a/swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestMappingMethodAnnotationProcessorTest.java b/swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestMappingMethodAnnotationProcessorTest.java new file mode 100644 index 0000000..04cfaf5 --- /dev/null +++ b/swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestMappingMethodAnnotationProcessorTest.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.servicecomb.swagger.generator.springmvc.processor.annotation; + +import javax.ws.rs.core.MediaType; + +import org.apache.servicecomb.swagger.generator.core.OperationGenerator; +import org.apache.servicecomb.swagger.generator.core.SwaggerGenerator; +import org.hamcrest.Matchers; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import io.swagger.models.Operation; + +public class RequestMappingMethodAnnotationProcessorTest { + @Test + public void testProcess() throws NoSuchMethodException { + RequestMappingMethodAnnotationProcessor processor = new RequestMappingMethodAnnotationProcessor(); + SwaggerGenerator swaggerGenerator = new SwaggerGenerator(null, null); + OperationGenerator operationGenerator = new OperationGenerator(swaggerGenerator, null); + Operation operation = operationGenerator.getOperation(); + + RequestMapping annotation = TestProducer.class.getMethod("testSingleMediaType", String.class) + .getAnnotation(RequestMapping.class); + processor.process(annotation, operationGenerator); + Assert.assertThat(operation.getConsumes(), Matchers.contains(MediaType.APPLICATION_XML)); + Assert.assertThat(operation.getProduces(), Matchers.contains(MediaType.APPLICATION_XML)); + + annotation = TestProducer.class.getMethod("testMultipleMediaType", String.class) + .getAnnotation(RequestMapping.class); + processor.process(annotation, operationGenerator); + Assert.assertThat(operation.getConsumes(), Matchers.contains(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON)); + Assert.assertThat(operation.getProduces(), Matchers.contains(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON)); + + annotation = TestProducer.class.getMethod("testBlankMediaType", String.class) + .getAnnotation(RequestMapping.class); + processor.process(annotation, operationGenerator); + Assert.assertThat(operation.getConsumes(), Matchers.contains(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON)); + Assert.assertThat(operation.getProduces(), Matchers.contains(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON)); + + operation.addConsumes(MediaType.APPLICATION_XML); + operation.addProduces(MediaType.APPLICATION_XML); + Assert.assertThat(operation.getConsumes(), + Matchers.contains(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML)); + Assert.assertThat(operation.getProduces(), + Matchers.contains(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML)); + } + + static class TestProducer { + @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_XML, produces = MediaType.APPLICATION_XML) + public String testSingleMediaType(String input) { + return input; + } + + @RequestMapping(method = RequestMethod.PUT, consumes = {MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON}, + produces = {MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON}) + public String testMultipleMediaType(String input) { + return input; + } + + @RequestMapping(method = RequestMethod.POST, consumes = "", produces = "") + public String testBlankMediaType(String input) { + return input; + } + } +} \ No newline at end of file
