You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2018/08/29 02:56:27 UTC
[incubator-servicecomb-java-chassis] 01/03: [SCB-206] Support
setting produces and consumes by @Api
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 0cd340c535ece1cb82252367651b3b23df7457db
Author: yaohaishi <ya...@huawei.com>
AuthorDate: Wed Aug 22 15:54:38 2018 +0800
[SCB-206] Support setting produces and consumes by @Api
---
.../core/processor/annotation/ApiProcessor.java | 51 +++++++++++
.../processor/annotation/ApiProcessorTest.java | 64 +++++++++++++-
...RequestMappingClassAnnotationProcessorTest.java | 98 ++++++++++++++++++++++
3 files changed, 209 insertions(+), 4 deletions(-)
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiProcessor.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiProcessor.java
index 57b4dbf..f882e34 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiProcessor.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiProcessor.java
@@ -17,11 +17,16 @@
package org.apache.servicecomb.swagger.generator.core.processor.annotation;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
import org.apache.servicecomb.swagger.generator.core.ClassAnnotationProcessor;
import org.apache.servicecomb.swagger.generator.core.SwaggerGenerator;
import org.springframework.util.StringUtils;
import io.swagger.annotations.Api;
+import io.swagger.models.Swagger;
public class ApiProcessor implements ClassAnnotationProcessor {
@Override
@@ -29,6 +34,52 @@ public class ApiProcessor implements ClassAnnotationProcessor {
Api api = (Api) annotation;
setTags(api, swaggerGenerator);
+ // except for @Api, @RequestMapping can also set consumes and produces
+ // @RequestMapping takes HIGHER priority than @Api for legacy reason
+ processConsumes(api, swaggerGenerator.getSwagger());
+ processProduces(api, swaggerGenerator.getSwagger());
+ }
+
+ private void processProduces(Api api, Swagger swagger) {
+ List<String> validProducesList = getValidStringList(api.produces());
+ if (isBlank(swagger.getProduces()) && !validProducesList.isEmpty()) {
+ swagger.setProduces(validProducesList);
+ }
+ }
+
+ private void processConsumes(Api api, Swagger swagger) {
+ List<String> validConsumesList = getValidStringList(api.consumes());
+ if (isBlank(swagger.getConsumes()) && !validConsumesList.isEmpty()) {
+ swagger.setConsumes(validConsumesList);
+ }
+ }
+
+ /**
+ * Split {@link Api#consumes} and {@link Api#produces}, and filter empty items.
+ */
+ private List<String> getValidStringList(String rawString) {
+ return Stream.of(rawString.split(","))
+ .filter(s -> !StringUtils.isEmpty(s))
+ .map(String::trim)
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * @return true if {@code stringList} is empty or each element of {@code stringList} is empty;
+ * otherwise false.
+ */
+ private boolean isBlank(List<String> stringList) {
+ boolean isEmpty = null == stringList || stringList.isEmpty();
+ if (isEmpty) {
+ return true;
+ }
+
+ for (String s : stringList) {
+ if (StringUtils.isEmpty(s)) {
+ return true;
+ }
+ }
+ return false;
}
private void setTags(Api api, SwaggerGenerator swaggerGenerator) {
diff --git a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiProcessorTest.java b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiProcessorTest.java
index 62f5a3e..047daac 100644
--- a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiProcessorTest.java
+++ b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiProcessorTest.java
@@ -19,12 +19,19 @@ package org.apache.servicecomb.swagger.generator.core.processor.annotation;
import static org.hamcrest.Matchers.contains;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
import java.util.Set;
+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;
@@ -35,22 +42,66 @@ public class ApiProcessorTest {
@Test
public void process() {
- SwaggerGenerator swaggerGenerator = new SwaggerGenerator(Mockito.mock(SwaggerGeneratorContext.class),
- null);
+ SwaggerGenerator swaggerGenerator = getSwaggerGenerator();
apiProcessor.process(SwaggerTestTarget.class.getAnnotation(Api.class),
swaggerGenerator);
assertThat(swaggerGenerator.getDefaultTags(), contains("tag1", "tag2"));
+ assertNull(swaggerGenerator.getSwagger().getConsumes());
+ assertNull(swaggerGenerator.getSwagger().getProduces());
}
@Test
public void processOnNoTag() {
- SwaggerGenerator swaggerGenerator = new SwaggerGenerator(Mockito.mock(SwaggerGeneratorContext.class),
- null);
+ SwaggerGenerator swaggerGenerator = getSwaggerGenerator();
apiProcessor.process(SwaggerTestTargetWithNoTag.class.getAnnotation(Api.class), swaggerGenerator);
Set<String> tags = swaggerGenerator.getDefaultTags();
assertEquals(0, tags.size());
+ assertNull(swaggerGenerator.getSwagger().getConsumes());
+ assertNull(swaggerGenerator.getSwagger().getProduces());
+ }
+
+ @Test
+ public void processOverWriteEmptyConsumesAndProduces() {
+ SwaggerGenerator swaggerGenerator = getSwaggerGenerator();
+ swaggerGenerator.getSwagger().setConsumes(Arrays.asList("", " "));
+ swaggerGenerator.getSwagger().setProduces(Arrays.asList("", " "));
+ apiProcessor.process(SwaggerTestTargetWithConsumesAndProduces.class.getAnnotation(Api.class), swaggerGenerator);
+
+ List<String> consumes = swaggerGenerator.getSwagger().getConsumes();
+ assertThat(consumes, Matchers.contains(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON));
+ List<String> produces = swaggerGenerator.getSwagger().getProduces();
+ assertThat(produces, Matchers.contains(MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON));
+ }
+
+ @Test
+ public void processNotOverWriteValidConsumesAndProduces() {
+ SwaggerGenerator swaggerGenerator = getSwaggerGenerator();
+ swaggerGenerator.getSwagger().setConsumes(Collections.singletonList(MediaType.MULTIPART_FORM_DATA));
+ swaggerGenerator.getSwagger().setProduces(Collections.singletonList(MediaType.MULTIPART_FORM_DATA));
+ apiProcessor.process(SwaggerTestTargetWithConsumesAndProduces.class.getAnnotation(Api.class), swaggerGenerator);
+
+ List<String> consumes = swaggerGenerator.getSwagger().getConsumes();
+ assertThat(consumes, Matchers.contains(MediaType.MULTIPART_FORM_DATA));
+ List<String> produces = swaggerGenerator.getSwagger().getProduces();
+ assertThat(produces, Matchers.contains(MediaType.MULTIPART_FORM_DATA));
+ }
+
+ @Test
+ public void processWithConsumesAndProduces() {
+ SwaggerGenerator swaggerGenerator = getSwaggerGenerator();
+ apiProcessor.process(SwaggerTestTargetWithConsumesAndProduces.class.getAnnotation(Api.class), swaggerGenerator);
+
+ List<String> consumes = swaggerGenerator.getSwagger().getConsumes();
+ assertThat(consumes, Matchers.contains(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON));
+ List<String> produces = swaggerGenerator.getSwagger().getProduces();
+ assertThat(produces, Matchers.contains(MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON));
+ }
+
+ private SwaggerGenerator getSwaggerGenerator() {
+ return new SwaggerGenerator(Mockito.mock(SwaggerGeneratorContext.class),
+ null);
}
@Api(tags = {"tag1", "tag2", "", "tag1"})
@@ -60,4 +111,9 @@ public class ApiProcessorTest {
@Api
private class SwaggerTestTargetWithNoTag {
}
+
+ @Api(consumes = MediaType.TEXT_PLAIN + " , " + MediaType.APPLICATION_JSON,
+ produces = MediaType.APPLICATION_XML + "," + MediaType.APPLICATION_JSON)
+ private class SwaggerTestTargetWithConsumesAndProduces {
+ }
}
diff --git a/swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestMappingClassAnnotationProcessorTest.java b/swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestMappingClassAnnotationProcessorTest.java
new file mode 100644
index 0000000..35d829a
--- /dev/null
+++ b/swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestMappingClassAnnotationProcessorTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.SwaggerGenerator;
+import org.apache.servicecomb.swagger.generator.core.SwaggerGeneratorContext;
+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.annotations.Api;
+import mockit.Mock;
+import mockit.MockUp;
+
+public class RequestMappingClassAnnotationProcessorTest {
+
+ private RequestMappingClassAnnotationProcessor processor = new RequestMappingClassAnnotationProcessor();
+
+ @Test
+ public void process() {
+ SwaggerGenerator swaggerGenerator = getSwaggerGenerator();
+ processor.process(SwaggerTestTarget.class.getAnnotation(RequestMapping.class), swaggerGenerator);
+
+ Assert.assertEquals("/test", swaggerGenerator.getSwagger().getBasePath());
+ Assert.assertEquals("post", swaggerGenerator.getHttpMethod());
+ Assert.assertThat(swaggerGenerator.getSwagger().getConsumes(),
+ Matchers.contains(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON));
+ Assert.assertThat(swaggerGenerator.getSwagger().getProduces(),
+ Matchers.contains(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN));
+ }
+
+ /**
+ * {@link RequestMapping#value()} takes higher priority than {@link RequestMapping#path()}
+ */
+ @Test
+ public void process_ValueOverWritePath() {
+ SwaggerGenerator swaggerGenerator = getSwaggerGenerator();
+ processor.process(SwaggerTestTarget_ValueOverWritePath.class.getAnnotation(RequestMapping.class), swaggerGenerator);
+
+ Assert.assertEquals("/testValue", swaggerGenerator.getSwagger().getBasePath());
+ }
+
+ /**
+ * {@link RequestMapping} takes higher priority than {@link Api} on setting {@code consumes} and {@code produces}
+ */
+ @Test
+ public void process_OverWriteConsumesAndProduces() {
+ SwaggerGenerator swaggerGenerator = getSwaggerGenerator();
+ swaggerGenerator.getSwagger().addConsumes(MediaType.APPLICATION_XML);
+ swaggerGenerator.getSwagger().addProduces(MediaType.APPLICATION_XML);
+ processor.process(SwaggerTestTarget.class.getAnnotation(RequestMapping.class), swaggerGenerator);
+
+ Assert.assertThat(swaggerGenerator.getSwagger().getConsumes(),
+ Matchers.contains(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON));
+ Assert.assertThat(swaggerGenerator.getSwagger().getProduces(),
+ Matchers.contains(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN));
+ }
+
+ private SwaggerGenerator getSwaggerGenerator() {
+ SwaggerGeneratorContext swaggerGeneratorContext = new MockUp<SwaggerGeneratorContext>() {
+ @Mock
+ String resolveStringValue(String strVal) {
+ return strVal;
+ }
+ }.getMockInstance();
+
+ return new SwaggerGenerator(swaggerGeneratorContext, null);
+ }
+
+ @RequestMapping(path = "/test", method = RequestMethod.POST,
+ consumes = {MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON},
+ produces = {MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})
+ private class SwaggerTestTarget {
+ }
+
+ @RequestMapping(value = "/testValue", path = "/testPath")
+ private class SwaggerTestTarget_ValueOverWritePath {
+ }
+}