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/07/20 09:24:21 UTC
[incubator-servicecomb-java-chassis] 02/06: [SCB-708] generate
schema for Object query param
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 ed2c00a784e8027a13c568ab8b7e041706f77836
Author: yaohaishi <ya...@huawei.com>
AuthorDate: Fri Jul 6 18:49:15 2018 +0800
[SCB-708] generate schema for Object query param
---
.../swagger/generator/core/OperationGenerator.java | 25 +-
.../swagger/generator/core/TestClassUtils.java | 6 +-
.../generator/core/TestOperationGenerator.java | 33 ++
.../SpringmvcDefaultObjectParameterProcessor.java | 115 +++++++
.../SpringmvcDefaultParameterProcessor.java | 34 ++-
... SpringmvcDefaultSimpleParameterProcessor.java} | 2 +-
...ringmvcDefaultObjectParameterProcessorTest.java | 337 +++++++++++++++++++++
.../SpringmvcDefaultParameterProcessorTest.java | 162 ++++++++++
...ringmvcDefaultSimpleParameterProcessorTest.java | 53 ++++
9 files changed, 754 insertions(+), 13 deletions(-)
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGenerator.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGenerator.java
index 40edc67..ba0b900 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGenerator.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGenerator.java
@@ -32,6 +32,8 @@ import javax.ws.rs.DefaultValue;
import org.apache.servicecomb.swagger.SwaggerUtils;
import org.apache.servicecomb.swagger.extend.parameter.ContextParameter;
import org.apache.servicecomb.swagger.generator.core.utils.ParamUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import io.swagger.models.HttpMethod;
@@ -45,6 +47,8 @@ import io.swagger.models.properties.Property;
import io.swagger.util.ReflectionUtils;
public class OperationGenerator {
+ private static final Logger LOGGER = LoggerFactory.getLogger(OperationGenerator.class);
+
protected SwaggerGenerator swaggerGenerator;
protected Swagger swagger;
@@ -139,7 +143,27 @@ public class OperationGenerator {
methodAnnotationParameters.add(parameter);
}
+ /**
+ * Add a parameter into {@linkplain #providerParameters},
+ * duplicated name params will be ignored(excepting for {@linkplain ContextParameter}s)
+ */
public void addProviderParameter(Parameter parameter) {
+ if (ContextParameter.class.isInstance(parameter)) {
+ // ContextParameter has no name and is not written in schema,
+ // so just add it without checking
+ providerParameters.add(parameter);
+ return;
+ }
+ // check duplicated param according to param name
+ for (Parameter providerParameter : providerParameters) {
+ if (parameter.getName().equals(providerParameter.getName())) {
+ LOGGER.warn(
+ "Param name [{}] is duplicated which may cause ambiguous deserialization result. Please check you schema definition",
+ parameter.getName());
+ return;
+ }
+ }
+
providerParameters.add(parameter);
}
@@ -294,7 +318,6 @@ public class OperationGenerator {
if (parameter instanceof AbstractSerializableParameter && defaultValue != null) {
((AbstractSerializableParameter<?>) parameter).setDefaultValue(defaultValue);
}
-
}
protected void processByParameterType(Type parameterType, int paramIdx) {
diff --git a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestClassUtils.java b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestClassUtils.java
index 32d8253..d1b2d38 100644
--- a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestClassUtils.java
+++ b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestClassUtils.java
@@ -84,10 +84,10 @@ public class TestClassUtils {
@Test
public void testHasAnnotation() {
- Assert.assertEquals(true, ClassUtils.hasAnnotation(TestClassUtils.class, SwaggerDefinition.class));
- Assert.assertEquals(true, ClassUtils.hasAnnotation(TestClassUtils.class, Test.class));
+ Assert.assertTrue(ClassUtils.hasAnnotation(TestClassUtils.class, SwaggerDefinition.class));
+ Assert.assertTrue(ClassUtils.hasAnnotation(TestClassUtils.class, Test.class));
- Assert.assertEquals(false, ClassUtils.hasAnnotation(TestClassUtils.class, Path.class));
+ Assert.assertFalse(ClassUtils.hasAnnotation(TestClassUtils.class, Path.class));
}
@Test
diff --git a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestOperationGenerator.java b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestOperationGenerator.java
index 1ecb0e6..1b520bc 100644
--- a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestOperationGenerator.java
+++ b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestOperationGenerator.java
@@ -26,11 +26,16 @@ import java.util.Collections;
import java.util.List;
import org.apache.servicecomb.foundation.test.scaffolding.spring.SpringUtils;
+import org.apache.servicecomb.swagger.extend.parameter.HttpRequestParameter;
import org.apache.servicecomb.swagger.generator.pojo.PojoSwaggerGeneratorContext;
+import org.junit.Assert;
import org.junit.Test;
import org.springframework.util.StringValueResolver;
import io.swagger.annotations.ApiOperation;
+import io.swagger.models.parameters.BodyParameter;
+import io.swagger.models.parameters.Parameter;
+import io.swagger.models.parameters.QueryParameter;
public class TestOperationGenerator {
@Test
@@ -88,6 +93,34 @@ public class TestOperationGenerator {
assertThat(tagList, contains("default0", "default1"));
}
+ @Test
+ public void addProviderParameter() throws NoSuchMethodException {
+ Method function = TestClass.class.getMethod("functionWithNoAnnotation");
+ SwaggerGenerator swaggerGenerator = new SwaggerGenerator(new PojoSwaggerGeneratorContext(), TestClass.class);
+ OperationGenerator operationGenerator = new OperationGenerator(swaggerGenerator, function);
+
+ Parameter parameter = new BodyParameter();
+ parameter.setName("param0");
+ operationGenerator.addProviderParameter(parameter);
+ Assert.assertEquals(1, operationGenerator.getProviderParameters().size());
+ Assert.assertSame(parameter, operationGenerator.getProviderParameters().get(0));
+
+ parameter = new HttpRequestParameter();
+ operationGenerator.addProviderParameter(parameter);
+ Assert.assertSame(parameter, operationGenerator.getProviderParameters().get(1));
+
+ parameter = new QueryParameter();
+ parameter.setName("param1");
+ operationGenerator.addProviderParameter(parameter);
+ Assert.assertSame(parameter, operationGenerator.getProviderParameters().get(2));
+
+ parameter = new QueryParameter();
+ parameter.setName("param0");
+ operationGenerator.addProviderParameter(parameter);
+ Assert.assertEquals(3, operationGenerator.getProviderParameters().size());
+ Assert.assertNotSame(parameter, operationGenerator.getProviderParameters().get(2));
+ }
+
private static class TestClass {
@ApiOperation(value = "value1", tags = {"tag1", "tag2"})
public void function() {
diff --git a/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultObjectParameterProcessor.java b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultObjectParameterProcessor.java
new file mode 100644
index 0000000..e5fa320
--- /dev/null
+++ b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultObjectParameterProcessor.java
@@ -0,0 +1,115 @@
+/*
+ * 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.parameter;
+
+import java.lang.reflect.Type;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.servicecomb.swagger.generator.core.DefaultParameterProcessor;
+import org.apache.servicecomb.swagger.generator.core.OperationGenerator;
+import org.apache.servicecomb.swagger.generator.core.utils.ParamUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import io.swagger.converter.ModelConverters;
+import io.swagger.models.Model;
+import io.swagger.models.parameters.AbstractSerializableParameter;
+import io.swagger.models.parameters.QueryParameter;
+import io.swagger.models.properties.Property;
+import io.swagger.models.properties.RefProperty;
+
+/**
+ * Flatten a object parameter into a set of flatten simple parameters.
+ * <p/>
+ * <em>Nesting object params and generic Object params are NOT supported.</em>
+ * We support query object just for aggregating query params instead of transporting objects in query param.
+ * So we don't support a generic param whose generic type is complex, but a simple generic type param can be supported.
+ */
+public class SpringmvcDefaultObjectParameterProcessor implements DefaultParameterProcessor {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SpringmvcDefaultObjectParameterProcessor.class);
+
+ @Override
+ public void process(OperationGenerator operationGenerator, int paramIndex) {
+ Model paramModel = getParamModel(operationGenerator, paramIndex);
+
+ if (null == paramModel) {
+ LOGGER.warn("cannot find param, provider method is [{}], paramIndex = [{}]",
+ operationGenerator.getProviderMethod().getName(), paramIndex);
+ return;
+ }
+
+ LinkedHashMap<String, AbstractSerializableParameter<?>> resultParamMap = getFlattenParams(paramModel);
+
+ addProviderParams(operationGenerator, resultParamMap);
+ }
+
+ private void addProviderParams(OperationGenerator operationGenerator,
+ LinkedHashMap<String, AbstractSerializableParameter<?>> resultParamMap) {
+ resultParamMap.forEach((paramName, param) -> operationGenerator.addProviderParameter(param));
+ }
+
+ private Model getParamModel(OperationGenerator operationGenerator, int paramIndex) {
+ Type paramType = ParamUtils.getGenericParameterType(operationGenerator.getProviderMethod(), paramIndex);
+ Property property = ModelConverters.getInstance().readAsProperty(paramType);
+ // ensure type
+ if (!RefProperty.class.isInstance(property)) {
+ LOGGER.error("Unsupported property type: [{}], paramIndex is [{}]", property.getClass().getName(), paramIndex);
+ return null;
+ }
+
+ Map<String, Model> models = ModelConverters.getInstance().readAll(paramType);
+
+ // find param root
+ RefProperty refProperty = (RefProperty) property;
+ String refTypeName = refProperty.getSimpleRef();
+ Model paramRoot = null;
+ for (Entry<String, Model> entry : models.entrySet()) {
+ if (refTypeName.equals(entry.getKey())) {
+ paramRoot = entry.getValue();
+ break;
+ }
+ }
+ return paramRoot;
+ }
+
+ private LinkedHashMap<String, AbstractSerializableParameter<?>> getFlattenParams(Model paramModel) {
+ LinkedHashMap<String, AbstractSerializableParameter<?>> flattenParamMap = new LinkedHashMap<>();
+ // traversal the properties of current paramModel
+ // create simple parameters, nesting object param is ignored
+ for (Entry<String, Property> propertyEntry : paramModel.getProperties().entrySet()) {
+ if (ParamUtils.isComplexProperty(propertyEntry.getValue())) {
+ LOGGER.info("A nesting complex field is ignored, field name = [{}]", propertyEntry.getKey());
+ continue;
+ }
+ AbstractSerializableParameter<?> newParameter = createSimpleParam(propertyEntry);
+ flattenParamMap.put(propertyEntry.getKey(), newParameter);
+ }
+
+ return flattenParamMap;
+ }
+
+ private AbstractSerializableParameter<?> createSimpleParam(Entry<String, Property> propertyEntry) {
+ AbstractSerializableParameter<?> newParameter = new QueryParameter();
+ newParameter.setName(propertyEntry.getKey());
+ newParameter.setProperty(propertyEntry.getValue());
+ return newParameter;
+ }
+}
diff --git a/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultParameterProcessor.java b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultParameterProcessor.java
index a87ef87..d9b5a5d 100644
--- a/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultParameterProcessor.java
+++ b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultParameterProcessor.java
@@ -17,24 +17,42 @@
package org.apache.servicecomb.swagger.generator.springmvc.processor.parameter;
+import java.lang.reflect.Type;
+
import org.apache.servicecomb.swagger.generator.core.DefaultParameterProcessor;
import org.apache.servicecomb.swagger.generator.core.OperationGenerator;
import org.apache.servicecomb.swagger.generator.core.utils.ParamUtils;
-import io.swagger.models.parameters.QueryParameter;
+import io.swagger.converter.ModelConverters;
+import io.swagger.models.properties.Property;
+import io.swagger.models.properties.RefProperty;
public class SpringmvcDefaultParameterProcessor implements DefaultParameterProcessor {
+ private SpringmvcDefaultSimpleParameterProcessor simpleParameterProcessor = new SpringmvcDefaultSimpleParameterProcessor();
+
+ private SpringmvcDefaultObjectParameterProcessor objectParameterProcessor = new SpringmvcDefaultObjectParameterProcessor();
@Override
public void process(OperationGenerator operationGenerator, int paramIdx) {
- String paramName = ParamUtils.getParameterName(operationGenerator.getProviderMethod(), paramIdx);
+ Type paramType = ParamUtils.getGenericParameterType(operationGenerator.getProviderMethod(), paramIdx);
+ Property property = ModelConverters.getInstance().readAsProperty(paramType);
+
+ if (RefProperty.class.isInstance(property)) {
+ objectParameterProcessor.process(operationGenerator, paramIdx);
+ return;
+ }
+ if (!ParamUtils.isComplexProperty(property)) {
+ simpleParameterProcessor.process(operationGenerator, paramIdx);
+ return;
+ }
- QueryParameter queryParameter = new QueryParameter();
- queryParameter.setName(paramName);
- ParamUtils.setParameterType(operationGenerator.getSwagger(),
- operationGenerator.getProviderMethod(),
+ // unsupported param type
+ String msg = String.format("cannot process parameter [%s], method=%s:%s, paramIdx=%d, type=%s",
+ ParamUtils.getParameterName(operationGenerator.getProviderMethod(), paramIdx),
+ operationGenerator.getProviderMethod().getDeclaringClass().getName(),
+ operationGenerator.getProviderMethod().getName(),
paramIdx,
- queryParameter);
- operationGenerator.addProviderParameter(queryParameter);
+ paramType.getTypeName());
+ throw new Error(msg);
}
}
diff --git a/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultParameterProcessor.java b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultSimpleParameterProcessor.java
similarity index 94%
copy from swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultParameterProcessor.java
copy to swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultSimpleParameterProcessor.java
index a87ef87..3d9f5a1 100644
--- a/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultParameterProcessor.java
+++ b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultSimpleParameterProcessor.java
@@ -23,7 +23,7 @@ import org.apache.servicecomb.swagger.generator.core.utils.ParamUtils;
import io.swagger.models.parameters.QueryParameter;
-public class SpringmvcDefaultParameterProcessor implements DefaultParameterProcessor {
+public class SpringmvcDefaultSimpleParameterProcessor implements DefaultParameterProcessor {
@Override
public void process(OperationGenerator operationGenerator, int paramIdx) {
diff --git a/swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultObjectParameterProcessorTest.java b/swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultObjectParameterProcessorTest.java
new file mode 100644
index 0000000..128cbee
--- /dev/null
+++ b/swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultObjectParameterProcessorTest.java
@@ -0,0 +1,337 @@
+/*
+ * 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.parameter;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.apache.servicecomb.swagger.generator.core.OperationGenerator;
+import org.apache.servicecomb.swagger.generator.core.SwaggerGenerator;
+import org.apache.servicecomb.swagger.generator.core.SwaggerGeneratorContext;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.swagger.models.parameters.Parameter;
+import io.swagger.models.parameters.QueryParameter;
+import mockit.Deencapsulation;
+
+public class SpringmvcDefaultObjectParameterProcessorTest {
+
+ @Test
+ public void processOnObjectParam() throws NoSuchMethodException {
+ final OperationGenerator operationGenerator = mockOperationGenerator("testObjectParam", "/test", TestParam.class);
+
+ new SpringmvcDefaultObjectParameterProcessor().process(operationGenerator, 0);
+
+ final List<Parameter> providerParameters = operationGenerator.getProviderParameters();
+ Assert.assertEquals(2, providerParameters.size());
+ Parameter parameter = providerParameters.get(0);
+ Assert.assertEquals(QueryParameter.class, parameter.getClass());
+ Assert.assertEquals("name", parameter.getName());
+ Assert.assertEquals("query", parameter.getIn());
+ QueryParameter queryParameter = (QueryParameter) parameter;
+ Assert.assertEquals("string", queryParameter.getType());
+ parameter = providerParameters.get(1);
+ Assert.assertEquals(QueryParameter.class, parameter.getClass());
+ Assert.assertEquals("age", parameter.getName());
+ Assert.assertEquals("query", parameter.getIn());
+ queryParameter = (QueryParameter) parameter;
+ Assert.assertEquals("integer", queryParameter.getType());
+ Assert.assertEquals("int32", queryParameter.getFormat());
+ }
+
+ @Test
+ public void processOnMultiObjectParamsWithSameFieldName() throws NoSuchMethodException {
+ final OperationGenerator operationGenerator = mockOperationGenerator("testMultiObjParamsWithSameFiledName", "/test",
+ String.class, TestParam.class, TestParam.class, int.class);
+
+ final SpringmvcDefaultObjectParameterProcessor springmvcDefaultParameterProcessor = new SpringmvcDefaultObjectParameterProcessor();
+ springmvcDefaultParameterProcessor.process(operationGenerator, 0);
+ springmvcDefaultParameterProcessor.process(operationGenerator, 1);
+ springmvcDefaultParameterProcessor.process(operationGenerator, 2);
+ springmvcDefaultParameterProcessor.process(operationGenerator, 3);
+
+ final List<Parameter> providerParameters = operationGenerator.getProviderParameters();
+ Assert.assertEquals(2, providerParameters.size());
+ Parameter parameter = providerParameters.get(0);
+ Assert.assertEquals(QueryParameter.class, parameter.getClass());
+ Assert.assertEquals("name", parameter.getName());
+ Assert.assertEquals("query", parameter.getIn());
+ QueryParameter queryParameter = (QueryParameter) parameter;
+ Assert.assertEquals("string", queryParameter.getType());
+ parameter = providerParameters.get(1);
+ Assert.assertEquals(QueryParameter.class, parameter.getClass());
+ Assert.assertEquals("age", parameter.getName());
+ Assert.assertEquals("query", parameter.getIn());
+ queryParameter = (QueryParameter) parameter;
+ Assert.assertEquals("integer", queryParameter.getType());
+ Assert.assertEquals("int32", queryParameter.getFormat());
+ }
+
+ @Test
+ public void processOnRecursiveObjectParam() throws NoSuchMethodException {
+ final OperationGenerator operationGenerator = mockOperationGenerator("testRecursiveParam", "/test",
+ RecursiveParamA.class);
+
+ new SpringmvcDefaultObjectParameterProcessor().process(operationGenerator, 0);
+
+ final List<Parameter> providerParameters = operationGenerator.getProviderParameters();
+ Assert.assertEquals(1, providerParameters.size());
+ Parameter parameter = providerParameters.get(0);
+ Assert.assertEquals(QueryParameter.class, parameter.getClass());
+ Assert.assertEquals("name", parameter.getName());
+ Assert.assertEquals("query", parameter.getIn());
+ QueryParameter queryParameter = (QueryParameter) parameter;
+ Assert.assertEquals("string", queryParameter.getType());
+ }
+
+ @Test
+ public void processOnGenericObjectParam() throws NoSuchMethodException {
+ final OperationGenerator operationGenerator = mockOperationGenerator("testGenericObjectParam", "/test",
+ GenericParam.class);
+
+ new SpringmvcDefaultObjectParameterProcessor().process(operationGenerator, 0);
+
+ final List<Parameter> providerParameters = operationGenerator.getProviderParameters();
+ Assert.assertEquals(2, providerParameters.size());
+ Parameter parameter = providerParameters.get(0);
+ Assert.assertEquals(QueryParameter.class, parameter.getClass());
+ Assert.assertEquals("num", parameter.getName());
+ Assert.assertEquals("query", parameter.getIn());
+ QueryParameter queryParameter = (QueryParameter) parameter;
+ Assert.assertEquals("integer", queryParameter.getType());
+ Assert.assertEquals("int32", queryParameter.getFormat());
+ parameter = providerParameters.get(1);
+ Assert.assertEquals(QueryParameter.class, parameter.getClass());
+ Assert.assertEquals("str", parameter.getName());
+ Assert.assertEquals("query", parameter.getIn());
+ queryParameter = (QueryParameter) parameter;
+ Assert.assertEquals("string", queryParameter.getType());
+ }
+
+ @Test
+ public void processOnGenericSimpleParam() throws NoSuchMethodException {
+ final OperationGenerator operationGenerator = mockOperationGenerator("testGenericSimpleParam", "/test",
+ GenericParam.class);
+
+ new SpringmvcDefaultObjectParameterProcessor().process(operationGenerator, 0);
+
+ final List<Parameter> providerParameters = operationGenerator.getProviderParameters();
+ Assert.assertEquals(3, providerParameters.size());
+ Parameter parameter = providerParameters.get(0);
+ Assert.assertEquals(QueryParameter.class, parameter.getClass());
+ Assert.assertEquals("num", parameter.getName());
+ Assert.assertEquals("query", parameter.getIn());
+ QueryParameter queryParameter = (QueryParameter) parameter;
+ Assert.assertEquals("integer", queryParameter.getType());
+ Assert.assertEquals("int32", queryParameter.getFormat());
+ parameter = providerParameters.get(1);
+ Assert.assertEquals(QueryParameter.class, parameter.getClass());
+ Assert.assertEquals("str", parameter.getName());
+ Assert.assertEquals("query", parameter.getIn());
+ queryParameter = (QueryParameter) parameter;
+ Assert.assertEquals("string", queryParameter.getType());
+ parameter = providerParameters.get(2);
+ Assert.assertEquals(QueryParameter.class, parameter.getClass());
+ Assert.assertEquals("data", parameter.getName());
+ Assert.assertEquals("query", parameter.getIn());
+ queryParameter = (QueryParameter) parameter;
+ Assert.assertEquals("string", queryParameter.getType());
+ }
+
+ private OperationGenerator mockOperationGenerator(String providerParamName, String path, Class<?>... classes)
+ throws NoSuchMethodException {
+ final SwaggerGenerator swaggerGenerator = new SwaggerGenerator(Mockito.mock(SwaggerGeneratorContext.class),
+ TestProvider.class);
+ final Method providerMethod = TestProvider.class
+ .getDeclaredMethod(providerParamName, classes);
+ final OperationGenerator operationGenerator = new OperationGenerator(swaggerGenerator, providerMethod);
+ Deencapsulation.setField(operationGenerator, "path", path);
+ return operationGenerator;
+ }
+
+ static class TestProvider {
+ public String testObjectParam(TestParam objParam) {
+ return objParam.toString();
+ }
+
+ public String testMultiObjParamsWithSameFiledName(String name, TestParam objParam0, TestParam objParam1, int age) {
+ return objParam0 + "-" + objParam1;
+ }
+
+ public String testRecursiveParam(RecursiveParamA recursiveParamA) {
+ return null;
+ }
+
+ public String testGenericObjectParam(GenericParam<TestParam> genericParam) {
+ return genericParam.toString();
+ }
+
+ public String testGenericSimpleParam(GenericParam<String> genericParam) {
+ return genericParam.toString();
+ }
+ }
+
+ static class TestParam {
+ private String name;
+
+ private int age;
+
+ public String getName() {
+ return name;
+ }
+
+ public TestParam setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public TestParam setAge(int age) {
+ this.age = age;
+ return this;
+ }
+ }
+
+ static class GenericParam<T> {
+ private int num;
+
+ private String str;
+
+ T data;
+
+ public int getNum() {
+ return num;
+ }
+
+ public void setNum(int num) {
+ this.num = num;
+ }
+
+ public String getStr() {
+ return str;
+ }
+
+ public void setStr(String str) {
+ this.str = str;
+ }
+
+ public T getData() {
+ return data;
+ }
+
+ public void setData(T data) {
+ this.data = data;
+ }
+ }
+
+ static class RecursiveParamA {
+ private String name;
+
+ private RecursiveParamB recursiveParamB;
+
+ private RecursiveParamC recursiveParamC;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public RecursiveParamB getRecursiveParamB() {
+ return recursiveParamB;
+ }
+
+ public void setRecursiveParamB(
+ RecursiveParamB recursiveParamB) {
+ this.recursiveParamB = recursiveParamB;
+ }
+
+ public RecursiveParamC getRecursiveParamC() {
+ return recursiveParamC;
+ }
+
+ public void setRecursiveParamC(
+ RecursiveParamC recursiveParamC) {
+ this.recursiveParamC = recursiveParamC;
+ }
+ }
+
+ static class RecursiveParamB {
+ private int age;
+
+ private RecursiveParamA recursiveParamA;
+
+ private RecursiveParamC recursiveParamC;
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public RecursiveParamA getRecursiveParamA() {
+ return recursiveParamA;
+ }
+
+ public void setRecursiveParamA(
+ RecursiveParamA recursiveParamA) {
+ this.recursiveParamA = recursiveParamA;
+ }
+
+ public RecursiveParamC getRecursiveParamC() {
+ return recursiveParamC;
+ }
+
+ public void setRecursiveParamC(
+ RecursiveParamC recursiveParamC) {
+ this.recursiveParamC = recursiveParamC;
+ }
+ }
+
+ static class RecursiveParamC {
+ private String address;
+
+ private RecursiveParamB recursiveParamB;
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ public RecursiveParamB getRecursiveParamB() {
+ return recursiveParamB;
+ }
+
+ public void setRecursiveParamB(
+ RecursiveParamB recursiveParamB) {
+ this.recursiveParamB = recursiveParamB;
+ }
+ }
+}
\ No newline at end of file
diff --git a/swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultParameterProcessorTest.java b/swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultParameterProcessorTest.java
new file mode 100644
index 0000000..2edafbf
--- /dev/null
+++ b/swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultParameterProcessorTest.java
@@ -0,0 +1,162 @@
+/*
+ * 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.parameter;
+
+import static org.junit.Assert.fail;
+
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.servicecomb.swagger.generator.core.OperationGenerator;
+import org.apache.servicecomb.swagger.generator.core.SwaggerGenerator;
+import org.apache.servicecomb.swagger.generator.core.SwaggerGeneratorContext;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.swagger.models.parameters.Parameter;
+import io.swagger.models.parameters.QueryParameter;
+import mockit.Deencapsulation;
+
+public class SpringmvcDefaultParameterProcessorTest {
+ @Test
+ public void processOnSimpleParam() throws NoSuchMethodException {
+ final SwaggerGenerator swaggerGenerator = new SwaggerGenerator(Mockito.mock(SwaggerGeneratorContext.class),
+ TestProvider.class);
+ final Method providerMethod = TestProvider.class.getDeclaredMethod("testSimpleParam", String.class);
+ final OperationGenerator operationGenerator = new OperationGenerator(swaggerGenerator, providerMethod);
+
+ new SpringmvcDefaultParameterProcessor().process(operationGenerator, 0);
+
+ final List<Parameter> providerParameters = operationGenerator.getProviderParameters();
+ Assert.assertEquals(1, providerParameters.size());
+ Parameter parameter = providerParameters.get(0);
+ Assert.assertEquals(QueryParameter.class, parameter.getClass());
+ Assert.assertEquals("strParam", parameter.getName());
+ Assert.assertEquals("query", parameter.getIn());
+ QueryParameter queryParameter = (QueryParameter) parameter;
+ Assert.assertEquals("string", queryParameter.getType());
+ }
+
+ @Test
+ public void processOnObjectParam() throws NoSuchMethodException {
+ final OperationGenerator operationGenerator = mockOperationGenerator("testObjectParam", "/test", TestParam.class);
+
+ new SpringmvcDefaultParameterProcessor().process(operationGenerator, 0);
+
+ final List<Parameter> providerParameters = operationGenerator.getProviderParameters();
+ Assert.assertEquals(2, providerParameters.size());
+ Parameter parameter = providerParameters.get(0);
+ Assert.assertEquals(QueryParameter.class, parameter.getClass());
+ Assert.assertEquals("name", parameter.getName());
+ Assert.assertEquals("query", parameter.getIn());
+ QueryParameter queryParameter = (QueryParameter) parameter;
+ Assert.assertEquals("string", queryParameter.getType());
+ parameter = providerParameters.get(1);
+ Assert.assertEquals(QueryParameter.class, parameter.getClass());
+ Assert.assertEquals("age", parameter.getName());
+ Assert.assertEquals("query", parameter.getIn());
+ queryParameter = (QueryParameter) parameter;
+ Assert.assertEquals("integer", queryParameter.getType());
+ Assert.assertEquals("int32", queryParameter.getFormat());
+ }
+
+ /**
+ * Map and List param is not supported
+ */
+ @Test
+ public void processOnUnsupportedParam() throws NoSuchMethodException {
+ final SwaggerGenerator swaggerGenerator = new SwaggerGenerator(Mockito.mock(SwaggerGeneratorContext.class),
+ TestProvider.class);
+ final Method providerMethod = TestProvider.class.getDeclaredMethod("testUnsupportedParamType",
+ int.class, List.class, Map.class);
+ final OperationGenerator operationGenerator = new OperationGenerator(swaggerGenerator, providerMethod);
+
+ try {
+ new SpringmvcDefaultParameterProcessor().process(operationGenerator, 1);
+ fail("an error is expected!");
+ } catch (Error e) {
+ Assert.assertEquals(
+ "cannot process parameter [integerList], method=org.apache.servicecomb.swagger.generator.springmvc"
+ + ".processor.parameter.SpringmvcDefaultParameterProcessorTest$TestProvider:testUnsupportedParamType, "
+ + "paramIdx=1, type=java.util.List<org.apache.servicecomb.swagger.generator.springmvc.processor.parameter"
+ + ".SpringmvcDefaultParameterProcessorTest$TestParam>",
+ e.getMessage());
+ }
+ try {
+ new SpringmvcDefaultParameterProcessor().process(operationGenerator, 2);
+ fail("an error is expected!");
+ } catch (Error e) {
+ Assert.assertEquals(
+ "cannot process parameter [stringMap], method=org.apache.servicecomb.swagger.generator.springmvc"
+ + ".processor.parameter.SpringmvcDefaultParameterProcessorTest$TestProvider:testUnsupportedParamType, "
+ + "paramIdx=2, type=java.util.Map<java.lang.String, java.lang.String>",
+ e.getMessage());
+ }
+ }
+
+ private OperationGenerator mockOperationGenerator(String providerParamName, String path, Class<?>... classes)
+ throws NoSuchMethodException {
+ final SwaggerGenerator swaggerGenerator = new SwaggerGenerator(Mockito.mock(SwaggerGeneratorContext.class),
+ TestProvider.class);
+ final Method providerMethod = TestProvider.class
+ .getDeclaredMethod(providerParamName, classes);
+ final OperationGenerator operationGenerator = new OperationGenerator(swaggerGenerator, providerMethod);
+ Deencapsulation.setField(operationGenerator, "path", path);
+ return operationGenerator;
+ }
+
+ static class TestProvider {
+ public String testSimpleParam(String strParam) {
+ return strParam;
+ }
+
+ public String testObjectParam(TestParam objParam) {
+ return objParam.toString();
+ }
+
+ public String testUnsupportedParamType(int i, List<TestParam> integerList, Map<String, String> stringMap) {
+ return null;
+ }
+ }
+
+ static class TestParam {
+ private String name;
+
+ private int age;
+
+ public String getName() {
+ return name;
+ }
+
+ public TestParam setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public TestParam setAge(int age) {
+ this.age = age;
+ return this;
+ }
+ }
+}
\ No newline at end of file
diff --git a/swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultSimpleParameterProcessorTest.java b/swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultSimpleParameterProcessorTest.java
new file mode 100644
index 0000000..dd29928
--- /dev/null
+++ b/swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/processor/parameter/SpringmvcDefaultSimpleParameterProcessorTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.parameter;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.apache.servicecomb.swagger.generator.core.OperationGenerator;
+import org.apache.servicecomb.swagger.generator.core.SwaggerGenerator;
+import org.apache.servicecomb.swagger.generator.core.SwaggerGeneratorContext;
+import org.apache.servicecomb.swagger.generator.springmvc.processor.parameter.SpringmvcDefaultParameterProcessorTest.TestProvider;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.swagger.models.parameters.Parameter;
+import io.swagger.models.parameters.QueryParameter;
+
+public class SpringmvcDefaultSimpleParameterProcessorTest {
+ @Test
+ public void process() throws NoSuchMethodException {
+ final SwaggerGenerator swaggerGenerator = new SwaggerGenerator(Mockito.mock(SwaggerGeneratorContext.class),
+ TestProvider.class);
+ final Method providerMethod = TestProvider.class.getDeclaredMethod("testSimpleParam", String.class);
+ final OperationGenerator operationGenerator = new OperationGenerator(swaggerGenerator, providerMethod);
+
+ new SpringmvcDefaultSimpleParameterProcessor().process(operationGenerator, 0);
+
+ final List<Parameter> providerParameters = operationGenerator.getProviderParameters();
+ Assert.assertEquals(1, providerParameters.size());
+ Parameter parameter = providerParameters.get(0);
+ Assert.assertEquals(QueryParameter.class, parameter.getClass());
+ Assert.assertEquals("strParam", parameter.getName());
+ Assert.assertEquals("query", parameter.getIn());
+ QueryParameter queryParameter = (QueryParameter) parameter;
+ Assert.assertEquals("string", queryParameter.getType());
+ }
+}