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 a1d0804132cc949061440d7de6fd971a1cfeb246 Author: yaohaishi <yaohai...@huawei.com> AuthorDate: Wed Jul 18 13:11:55 2018 +0800 [SCB-752] throw error to interrupt the boot up process when meeting unsupported query object type --- .../demo/compute/GenericParamWithJsonIgnore.java | 66 ++++++++++++ .../demo/springmvc/client/TestResponse.java | 2 +- .../demo/springmvc/client/TestRestTemplate.java | 2 +- .../demo/springmvc/server/CodeFirstSpringmvc.java | 3 +- .../SpringmvcDefaultObjectParameterProcessor.java | 11 +- ...ringmvcDefaultObjectParameterProcessorTest.java | 114 +++++++++++++++------ .../SpringmvcDefaultParameterProcessorTest.java | 35 ++++++- 7 files changed, 190 insertions(+), 43 deletions(-) diff --git a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/compute/GenericParamWithJsonIgnore.java b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/compute/GenericParamWithJsonIgnore.java new file mode 100644 index 0000000..0a295a8 --- /dev/null +++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/compute/GenericParamWithJsonIgnore.java @@ -0,0 +1,66 @@ +/* + * 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.demo.compute; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +public class GenericParamWithJsonIgnore<T> { + private String str; + + private long num; + + @JsonIgnore + private T data; + + public String getStr() { + return str; + } + + public GenericParamWithJsonIgnore<T> setStr(String str) { + this.str = str; + return this; + } + + public long getNum() { + return num; + } + + public GenericParamWithJsonIgnore<T> setNum(long num) { + this.num = num; + return this; + } + + public T getData() { + return data; + } + + public GenericParamWithJsonIgnore<T> setData(T data) { + this.data = data; + return this; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("GenericParamWithJsonIgnore{"); + sb.append("str='").append(str).append('\''); + sb.append(", num=").append(num); + sb.append(", data=").append(data); + sb.append('}'); + return sb.toString(); + } +} diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestResponse.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestResponse.java index 2dda35c..e417e20 100644 --- a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestResponse.java +++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestResponse.java @@ -89,7 +89,7 @@ public class TestResponse { requestBody.setNum(1).setStr("str1").setData(new Person("bodyPerson")); String result = intf.checkQueryGenericObject(requestBody, "str2", 2); TestMgr.check( - "str=str2,generic=GenericParam{str='str2', num=2, data=null},requestBody=GenericParam{str='str1', num=1, data=bodyPerson}", + "str=str2,generic=GenericParamWithJsonIgnore{str='str2', num=2, data=null},requestBody=GenericParam{str='str1', num=1, data=bodyPerson}", result); } diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestRestTemplate.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestRestTemplate.java index c29c0e9..06c302a 100644 --- a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestRestTemplate.java +++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestRestTemplate.java @@ -76,7 +76,7 @@ public class TestRestTemplate { .exchange("cse://springmvc/codeFirstSpringmvc/checkQueryGenericObject?str={1}&num={2}", HttpMethod.PUT, requestEntity, String.class, "str2", 2); TestMgr.check( - "str=str2,generic=GenericParam{str='str2', num=2, data=null},requestBody=GenericParam{str='str1', num=1, data=bodyPerson}", + "str=str2,generic=GenericParamWithJsonIgnore{str='str2', num=2, data=null},requestBody=GenericParam{str='str1', num=1, data=bodyPerson}", responseEntity.getBody()); } diff --git a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java index 0f407f6..6b97de5 100644 --- a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java +++ b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java @@ -36,6 +36,7 @@ import org.apache.servicecomb.demo.EmptyObject; import org.apache.servicecomb.demo.Generic; import org.apache.servicecomb.demo.compute.GenericParam; import org.apache.servicecomb.demo.compute.GenericParamExtended; +import org.apache.servicecomb.demo.compute.GenericParamWithJsonIgnore; import org.apache.servicecomb.demo.compute.Person; import org.apache.servicecomb.demo.ignore.InputModelForTestIgnore; import org.apache.servicecomb.demo.ignore.OutputModelForTestIgnore; @@ -484,7 +485,7 @@ public class CodeFirstSpringmvc { */ @PutMapping(path = "/checkQueryGenericObject") public String checkQueryGenericObject(@RequestBody GenericParam<Person> requestBody, - GenericParam<Person> generic, String str) { + GenericParamWithJsonIgnore<Person> generic, String str) { LOGGER.info("checkQueryGenericObject() is called!"); return "str=" + str + ",generic=" + generic + ",requestBody=" + requestBody; } 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 index e5fa320..d1b44a0 100644 --- 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 @@ -51,9 +51,9 @@ public class SpringmvcDefaultObjectParameterProcessor implements DefaultParamete Model paramModel = getParamModel(operationGenerator, paramIndex); if (null == paramModel) { - LOGGER.warn("cannot find param, provider method is [{}], paramIndex = [{}]", - operationGenerator.getProviderMethod().getName(), paramIndex); - return; + throw new Error(String.format("cannot find param, provider method is [%s], paramIndex = [%d]. " + + "Please check your parameter definition.", + operationGenerator.getProviderMethod().getName(), paramIndex)); } LinkedHashMap<String, AbstractSerializableParameter<?>> resultParamMap = getFlattenParams(paramModel); @@ -96,8 +96,9 @@ public class SpringmvcDefaultObjectParameterProcessor implements DefaultParamete // 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; + throw new Error( + "A nesting complex field is found in the query object and this is not supported, field name = [" + + propertyEntry.getKey() + "]. Please remove this field or tag @JsonIgnore on it."); } AbstractSerializableParameter<?> newParameter = createSimpleParam(propertyEntry); flattenParamMap.put(propertyEntry.getKey(), newParameter); 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 index 128cbee..7d948d7 100644 --- 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 @@ -17,6 +17,8 @@ package org.apache.servicecomb.swagger.generator.springmvc.processor.parameter; +import static org.junit.Assert.fail; + import java.lang.reflect.Method; import java.util.List; @@ -27,6 +29,8 @@ import org.junit.Assert; import org.junit.Test; import org.mockito.Mockito; +import com.fasterxml.jackson.annotation.JsonIgnore; + import io.swagger.models.parameters.Parameter; import io.swagger.models.parameters.QueryParameter; import mockit.Deencapsulation; @@ -57,34 +61,6 @@ public class SpringmvcDefaultObjectParameterProcessorTest { } @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); @@ -102,9 +78,43 @@ public class SpringmvcDefaultObjectParameterProcessorTest { } @Test + public void processOnRecursiveObjectParamWithNoJsonIgnore() throws NoSuchMethodException { + final OperationGenerator operationGenerator = mockOperationGenerator("testRecursiveParamWithNoJsonIgnore", "/test", + RecursiveParamB.class); + + try { + new SpringmvcDefaultObjectParameterProcessor().process(operationGenerator, 0); + fail("an error is expected"); + } catch (Throwable e) { + Assert.assertEquals(Error.class, e.getClass()); + Assert.assertEquals( + "A nesting complex field is found in the query object and this is not supported," + + " field name = [recursiveParamA]. Please remove this field or tag @JsonIgnore on it.", + e.getMessage()); + } + } + + @Test public void processOnGenericObjectParam() throws NoSuchMethodException { final OperationGenerator operationGenerator = mockOperationGenerator("testGenericObjectParam", "/test", GenericParam.class); + try { + new SpringmvcDefaultObjectParameterProcessor().process(operationGenerator, 0); + fail("an error is expected"); + } catch (Throwable e) { + Assert.assertEquals(Error.class, e.getClass()); + Assert.assertEquals( + "A nesting complex field is found in the query object and this is not supported," + + " field name = [data]. Please remove this field or tag @JsonIgnore on it.", + e.getMessage()); + } + } + + @Test + public void processOnGenericObjectParamWithJsonIgnore() throws NoSuchMethodException { + final OperationGenerator operationGenerator = mockOperationGenerator("testGenericObjectParamWithJsonIgnore", + "/test", + GenericParamWithJsonIgnore.class); new SpringmvcDefaultObjectParameterProcessor().process(operationGenerator, 0); @@ -159,8 +169,7 @@ public class SpringmvcDefaultObjectParameterProcessorTest { throws NoSuchMethodException { final SwaggerGenerator swaggerGenerator = new SwaggerGenerator(Mockito.mock(SwaggerGeneratorContext.class), TestProvider.class); - final Method providerMethod = TestProvider.class - .getDeclaredMethod(providerParamName, classes); + final Method providerMethod = TestProvider.class.getDeclaredMethod(providerParamName, classes); final OperationGenerator operationGenerator = new OperationGenerator(swaggerGenerator, providerMethod); Deencapsulation.setField(operationGenerator, "path", path); return operationGenerator; @@ -171,11 +180,11 @@ public class SpringmvcDefaultObjectParameterProcessorTest { 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 testRecursiveParam(RecursiveParamA recursiveParamA) { + public String testRecursiveParamWithNoJsonIgnore(RecursiveParamB recursiveParamB) { return null; } @@ -183,6 +192,10 @@ public class SpringmvcDefaultObjectParameterProcessorTest { return genericParam.toString(); } + public String testGenericObjectParamWithJsonIgnore(GenericParamWithJsonIgnore<TestParam> genericParam) { + return genericParam.toString(); + } + public String testGenericSimpleParam(GenericParam<String> genericParam) { return genericParam.toString(); } @@ -244,11 +257,46 @@ public class SpringmvcDefaultObjectParameterProcessorTest { } } + static class GenericParamWithJsonIgnore<T> { + private int num; + + private String str; + + @JsonIgnore + 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; + @JsonIgnore private RecursiveParamB recursiveParamB; + @JsonIgnore private RecursiveParamC recursiveParamC; public String getName() { 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 index 2edafbf..4d194a1 100644 --- 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 @@ -111,12 +111,39 @@ public class SpringmvcDefaultParameterProcessorTest { } } + @Test + public void processOnMultiObjectParamsWithSameFieldName() throws NoSuchMethodException { + final OperationGenerator operationGenerator = mockOperationGenerator("testMultiObjParamsWithSameFiledName", "/test", + String.class, TestParam.class, TestParam.class, int.class); + + final SpringmvcDefaultParameterProcessor springmvcDefaultParameterProcessor = new SpringmvcDefaultParameterProcessor(); + 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()); + } + 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 Method providerMethod = TestProvider.class.getDeclaredMethod(providerParamName, classes); final OperationGenerator operationGenerator = new OperationGenerator(swaggerGenerator, providerMethod); Deencapsulation.setField(operationGenerator, "path", path); return operationGenerator; @@ -134,6 +161,10 @@ public class SpringmvcDefaultParameterProcessorTest { public String testUnsupportedParamType(int i, List<TestParam> integerList, Map<String, String> stringMap) { return null; } + + public String testMultiObjParamsWithSameFiledName(String name, TestParam objParam0, TestParam objParam1, int age) { + return objParam0 + "-" + objParam1; + } } static class TestParam {