This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch 2.8.x
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git
The following commit(s) were added to refs/heads/2.8.x by this push:
new 34cda7ab8 [SCB-2856]ApiImplicitParams works in class annotation (#4208)
34cda7ab8 is described below
commit 34cda7ab8fdbee9e505acc3195ed7388d09a20bd
Author: liubao68 <[email protected]>
AuthorDate: Mon Jan 29 14:27:38 2024 +0800
[SCB-2856]ApiImplicitParams works in class annotation (#4208)
---
.../client/TestApiImplicitParamsSchema.java | 63 +++++++++++++
.../springmvc/server/ApiImplicitParamsSchema.java | 42 +++++++++
.../springmvc/server/ProducerTestsAfterBootup.java | 6 +-
.../generator/core/AbstractOperationGenerator.java | 105 ++++++++++++---------
4 files changed, 167 insertions(+), 49 deletions(-)
diff --git
a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestApiImplicitParamsSchema.java
b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestApiImplicitParamsSchema.java
new file mode 100644
index 000000000..a1ad60265
--- /dev/null
+++
b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestApiImplicitParamsSchema.java
@@ -0,0 +1,63 @@
+/*
+ * 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.springmvc.client;
+
+import java.net.URI;
+
+import org.apache.servicecomb.demo.CategorizedTestCase;
+import org.apache.servicecomb.demo.TestMgr;
+import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.RequestEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestOperations;
+
+@Component
+public class TestApiImplicitParamsSchema implements CategorizedTestCase {
+ private RestOperations restOperations = RestTemplateBuilder.create();
+
+ @Override
+ public void testRestTransport() throws Exception {
+ // test all parameters case
+ MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
+ headers.add("x-test-a", "a");
+ headers.add("x-test-b", "30");
+ RequestEntity<?> entity = new RequestEntity<>(headers, HttpMethod.GET,
+ new URI("servicecomb://springmvc/implicit/add?a=1&b=2"));
+ String result = restOperations.exchange(entity, String.class).getBody();
+ TestMgr.check("a,30,3", result);
+
+ // test default value
+ headers = new LinkedMultiValueMap<>();
+ headers.add("x-test-b", "10");
+ entity = new RequestEntity<>(headers, HttpMethod.GET,
+ new URI("servicecomb://springmvc/implicit/add?a=1&b=2"));
+ result = restOperations.exchange(entity, String.class).getBody();
+ TestMgr.check("test,10,3", result);
+
+ // test default required check
+ try {
+
restOperations.getForObject("servicecomb://springmvc/implicit/add?a=1&b=2",
String.class);
+ TestMgr.fail("do not have required check");
+ } catch (InvocationException e) {
+ TestMgr.check(e.getStatusCode(), 400);
+ }
+ }
+}
diff --git
a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ApiImplicitParamsSchema.java
b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ApiImplicitParamsSchema.java
new file mode 100644
index 000000000..9e7a63e40
--- /dev/null
+++
b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ApiImplicitParamsSchema.java
@@ -0,0 +1,42 @@
+/*
+ * 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.springmvc.server;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+
+@RestSchema(schemaId = "ApiImplicitParamsSchema")
+@RequestMapping(path = "/implicit", produces =
MediaType.APPLICATION_JSON_VALUE)
+@ApiImplicitParams({
+ @ApiImplicitParam(name = "x-test-a", paramType = "header", dataType =
"string", defaultValue = "test"),
+ @ApiImplicitParam(name = "x-test-b", paramType = "header", dataType =
"integer", defaultValue = "20", required = true)
+})
+public class ApiImplicitParamsSchema {
+ @GetMapping(path = "/add")
+ public String add(HttpServletRequest request, @RequestParam("a") int a,
@RequestParam("b") int b) {
+ return request.getHeader("x-test-a") + "," + request.getHeader("x-test-b")
+ "," +
+ (a + b);
+ }
+}
diff --git
a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ProducerTestsAfterBootup.java
b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ProducerTestsAfterBootup.java
index 172817164..a23cad0ff 100644
---
a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ProducerTestsAfterBootup.java
+++
b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ProducerTestsAfterBootup.java
@@ -26,9 +26,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
-import com.netflix.config.DynamicPropertyFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectWriter;
+import com.netflix.config.DynamicPropertyFactory;
import io.swagger.models.Swagger;
import io.swagger.util.Yaml;
@@ -91,9 +91,9 @@ public class ProducerTestsAfterBootup implements BootListener
{
public void testRegisteredBasePath() {
if
(DynamicPropertyFactory.getInstance().getBooleanProperty("servicecomb.test.vert.transport",
true).get()) {
- TestMgr.check(23,
RegistrationManager.INSTANCE.getMicroservice().getPaths().size());
+
TestMgr.check(RegistrationManager.INSTANCE.getMicroservice().getPaths().size()
>= 23, true);
} else {
- TestMgr.check(25,
RegistrationManager.INSTANCE.getMicroservice().getPaths().size());
+
TestMgr.check(RegistrationManager.INSTANCE.getMicroservice().getPaths().size()
>= 25, true);
}
}
diff --git
a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/AbstractOperationGenerator.java
b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/AbstractOperationGenerator.java
index 302482b30..b31c91154 100644
---
a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/AbstractOperationGenerator.java
+++
b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/AbstractOperationGenerator.java
@@ -16,11 +16,50 @@
*/
package org.apache.servicecomb.swagger.generator.core;
+import static
org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.collectAnnotations;
+import static
org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.findMethodAnnotationProcessor;
+import static
org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.findParameterProcessors;
+import static
org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.findResponseTypeProcessor;
+import static
org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.isContextParameter;
+import static
org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.postProcessOperation;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.servicecomb.config.inject.PlaceholderResolver;
+import org.apache.servicecomb.swagger.SwaggerUtils;
+import org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor;
+import org.apache.servicecomb.swagger.generator.OperationGenerator;
+import org.apache.servicecomb.swagger.generator.ParameterGenerator;
+import org.apache.servicecomb.swagger.generator.ParameterProcessor;
+import org.apache.servicecomb.swagger.generator.ResponseTypeProcessor;
+import org.apache.servicecomb.swagger.generator.SwaggerConst;
+import org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;
+import org.apache.servicecomb.swagger.generator.core.utils.MethodUtils;
+
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.google.common.reflect.TypeToken;
+
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiParam;
@@ -44,42 +83,6 @@ import io.swagger.models.properties.Property;
import io.swagger.models.properties.StringProperty;
import io.swagger.util.Json;
import io.swagger.util.ReflectionUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.servicecomb.config.inject.PlaceholderResolver;
-import org.apache.servicecomb.swagger.SwaggerUtils;
-import org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor;
-import org.apache.servicecomb.swagger.generator.OperationGenerator;
-import org.apache.servicecomb.swagger.generator.ParameterGenerator;
-import org.apache.servicecomb.swagger.generator.ParameterProcessor;
-import org.apache.servicecomb.swagger.generator.ResponseTypeProcessor;
-import org.apache.servicecomb.swagger.generator.SwaggerConst;
-import org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;
-import org.apache.servicecomb.swagger.generator.core.utils.MethodUtils;
-
-import javax.servlet.http.HttpServletResponse;
-import javax.ws.rs.core.MediaType;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.Comparator;
-import java.util.stream.Collectors;
-
-import static
org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.collectAnnotations;
-import static
org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.findMethodAnnotationProcessor;
-import static
org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.findParameterProcessors;
-import static
org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.findResponseTypeProcessor;
-import static
org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.isContextParameter;
-import static
org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.postProcessOperation;
public abstract class AbstractOperationGenerator implements OperationGenerator
{
protected AbstractSwaggerGenerator swaggerGenerator;
@@ -169,8 +172,8 @@ public abstract class AbstractOperationGenerator implements
OperationGenerator {
protected void scanMethodAnnotation() {
for (Annotation annotation : Arrays.stream(method.getAnnotations())
- .sorted(Comparator.comparing(a -> a.annotationType().getName()))
- .collect(Collectors.toList())
+ .sorted(Comparator.comparing(a -> a.annotationType().getName()))
+ .collect(Collectors.toList())
) {
MethodAnnotationProcessor<Annotation> processor =
findMethodAnnotationProcessor(annotation.annotationType());
if (processor == null) {
@@ -261,12 +264,12 @@ public abstract class AbstractOperationGenerator
implements OperationGenerator {
}
protected boolean isAggregatedParameter(ParameterGenerator
parameterGenerator,
- java.lang.reflect.Parameter
methodParameter) {
+ java.lang.reflect.Parameter methodParameter) {
return false;
}
protected void extractAggregatedParameterGenerators(Map<String,
List<Annotation>> methodAnnotationMap,
-
java.lang.reflect.Parameter methodParameter) {
+ java.lang.reflect.Parameter methodParameter) {
JavaType javaType =
TypeFactory.defaultInstance().constructType(methodParameter.getParameterizedType());
BeanDescription beanDescription =
Json.mapper().getSerializationConfig().introspect(javaType);
for (BeanPropertyDefinition propertyDefinition :
beanDescription.findProperties()) {
@@ -293,6 +296,16 @@ public abstract class AbstractOperationGenerator
implements OperationGenerator {
private Map<String, List<Annotation>> initMethodAnnotationByParameterName() {
Map<String, List<Annotation>> methodAnnotations = new LinkedHashMap<>();
+
+ for (Annotation annotation : clazz.getAnnotations()) {
+ if (annotation instanceof ApiImplicitParams) {
+ for (ApiImplicitParam apiImplicitParam : ((ApiImplicitParams)
annotation).value()) {
+ addMethodAnnotationByParameterName(methodAnnotations,
apiImplicitParam.name(), apiImplicitParam);
+ }
+ continue;
+ }
+ }
+
for (Annotation annotation : method.getAnnotations()) {
if (annotation instanceof ApiImplicitParams) {
for (ApiImplicitParam apiImplicitParam : ((ApiImplicitParams)
annotation).value()) {
@@ -309,7 +322,7 @@ public abstract class AbstractOperationGenerator implements
OperationGenerator {
}
private void addMethodAnnotationByParameterName(Map<String,
List<Annotation>> methodAnnotations, String name,
- Annotation annotation) {
+ Annotation annotation) {
if (StringUtils.isEmpty(name)) {
throw new IllegalStateException(String.format("%s.name should not be
empty. method=%s:%s",
annotation.annotationType().getSimpleName(),
@@ -375,7 +388,7 @@ public abstract class AbstractOperationGenerator implements
OperationGenerator {
}
protected void fillParameter(Swagger swagger, Parameter parameter, String
parameterName, JavaType type,
- List<Annotation> annotations) {
+ List<Annotation> annotations) {
for (Annotation annotation : annotations) {
ParameterProcessor<Parameter, Annotation> processor =
findParameterProcessors(annotation.annotationType());
if (processor != null) {
@@ -395,7 +408,7 @@ public abstract class AbstractOperationGenerator implements
OperationGenerator {
if (parameter instanceof AbstractSerializableParameter) {
io.swagger.util.ParameterProcessor.applyAnnotations(swagger, parameter,
type, annotations);
annotations.stream().forEach(annotation -> {
- if
(NOT_NULL_ANNOTATIONS.contains(annotation.annotationType().getSimpleName())){
+ if
(NOT_NULL_ANNOTATIONS.contains(annotation.annotationType().getSimpleName())) {
parameter.setRequired(true);
}
});
@@ -426,7 +439,7 @@ public abstract class AbstractOperationGenerator implements
OperationGenerator {
convertAnnotationProperty(((JavaType) type).getRawClass());
} else {
((JavaType) type).getBindings().getTypeParameters().
- forEach(javaType ->
convertAnnotationProperty(javaType.getRawClass()));
+ forEach(javaType ->
convertAnnotationProperty(javaType.getRawClass()));
}
mergeBodyParameter((BodyParameter) parameter, newBodyParameter);
@@ -434,7 +447,7 @@ public abstract class AbstractOperationGenerator implements
OperationGenerator {
private void convertAnnotationProperty(Class<?> beanClass) {
Map<String, Model> definitions = swagger.getDefinitions();
- if (definitions == null){
+ if (definitions == null) {
return;
}
Field[] fields = beanClass.getDeclaredFields();
@@ -446,7 +459,7 @@ public abstract class AbstractOperationGenerator implements
OperationGenerator {
if (properties != null) {
Arrays.stream(fields).forEach(field -> {
boolean requireItem = Arrays.stream(field.getAnnotations()).
- anyMatch(annotation ->
NOT_NULL_ANNOTATIONS.contains(annotation.annotationType().getSimpleName()));
+ anyMatch(annotation ->
NOT_NULL_ANNOTATIONS.contains(annotation.annotationType().getSimpleName()));
if (requireItem) {
Property property = properties.get(field.getName());
if (property != null) {