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 2021/09/07 08:12:45 UTC
[servicecomb-java-chassis] branch master updated: [SCB-2331]
swagger generator support NotBlank and NotEmpty annotations (#2554)
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/servicecomb-java-chassis.git
The following commit(s) were added to refs/heads/master by this push:
new 68e5228 [SCB-2331] swagger generator support NotBlank and NotEmpty annotations (#2554)
68e5228 is described below
commit 68e52289206aaf1c36981b60335df05fa64df302
Author: Alne <84...@users.noreply.github.com>
AuthorDate: Tue Sep 7 16:12:13 2021 +0800
[SCB-2331] swagger generator support NotBlank and NotEmpty annotations (#2554)
---
.../client/validation/ValidationServiceClient.java | 2 +-
.../generator/core/AbstractOperationGenerator.java | 47 +++++++++++++----
.../annotation/ApiOperationProcessorTest.java | 61 ++++++++++++++++++++++
3 files changed, 98 insertions(+), 12 deletions(-)
diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/validation/ValidationServiceClient.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/validation/ValidationServiceClient.java
index 84fa8d0..9616b48 100644
--- a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/validation/ValidationServiceClient.java
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/validation/ValidationServiceClient.java
@@ -79,7 +79,7 @@ public class ValidationServiceClient {
} catch (InvocationException e) {
TestMgr.check(400, e.getStatus().getStatusCode());
TestMgr.check(Status.BAD_REQUEST, e.getReasonPhrase());
- TestMgr.check(e.getErrorData().toString().contains("propertyPath=queryValidate.name"), true);
+ TestMgr.check(e.getErrorData().toString().contains("Parameter is not valid for operation"), 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 3eabb68..56734d0 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
@@ -26,14 +26,8 @@ import static org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.pos
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
+import java.util.*;
import java.util.Map.Entry;
-import java.util.Set;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.MediaType;
@@ -101,6 +95,8 @@ public abstract class AbstractOperationGenerator implements OperationGenerator {
// 如果Response中不存在对应的header,则会将这些header补充进去
protected Map<String, Property> methodResponseHeaders = new LinkedHashMap<>();
+ private static List<String> NOT_NULL_ANNOTATIONS = Arrays.asList("NotBlank", "NotEmpty");
+
public AbstractOperationGenerator(AbstractSwaggerGenerator swaggerGenerator, Method method) {
this.swaggerGenerator = swaggerGenerator;
this.swagger = swaggerGenerator.getSwagger();
@@ -250,12 +246,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()) {
@@ -298,7 +294,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(),
@@ -364,7 +360,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) {
@@ -383,6 +379,11 @@ 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())){
+ parameter.setRequired(true);
+ }
+ });
return;
}
@@ -405,9 +406,33 @@ public abstract class AbstractOperationGenerator implements OperationGenerator {
}
}
+ // swagger 2.0 do not support NotBlank and NotEmpty annotations, fix it
+ if (((JavaType)type).getBindings().getTypeParameters().isEmpty()){
+ convertAnnotationProperty(((JavaType)type).getRawClass());
+ } else {
+ ((JavaType)type).getBindings().getTypeParameters().stream().
+ forEach(javaType -> convertAnnotationProperty(javaType.getRawClass()));
+ }
+
mergeBodyParameter((BodyParameter) parameter, newBodyParameter);
}
+ private void convertAnnotationProperty(Class<?> beanClass) {
+ Map<String, Model> definitions = swagger.getDefinitions();
+ if (definitions == null) {
+ return;
+ }
+ Model model = definitions.get(beanClass.getSimpleName());
+ Arrays.stream(beanClass.getDeclaredFields()).forEach(field -> {
+ boolean requireItem = Arrays.stream(field.getAnnotations()).anyMatch(annotation ->
+ NOT_NULL_ANNOTATIONS.contains(annotation.annotationType().getSimpleName()));
+ if (requireItem) {
+ model.getProperties().get(field.getName()).setRequired(true);
+ }
+ });
+ }
+
+
private void mergeBodyParameter(BodyParameter bodyParameter, BodyParameter fromBodyParameter) {
if (fromBodyParameter.getExamples() != null) {
bodyParameter.setExamples(fromBodyParameter.getExamples());
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 0aa1491..ae7bc19 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
@@ -20,9 +20,14 @@ package org.apache.servicecomb.swagger.generator.core.processor.annotation;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
import javax.ws.rs.core.MediaType;
+import io.swagger.models.properties.Property;
import org.apache.servicecomb.swagger.generator.core.model.SwaggerOperation;
import org.apache.servicecomb.swagger.generator.core.model.SwaggerOperations;
import org.hamcrest.Matchers;
@@ -30,6 +35,9 @@ import org.junit.AfterClass;
import org.junit.Test;
import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.Map;
public class ApiOperationProcessorTest {
static SwaggerOperations swaggerOperations = SwaggerOperations.generate(TestClass.class);
@@ -64,6 +72,48 @@ public class ApiOperationProcessorTest {
public String testBlankMediaType(String input) {
return input;
}
+
+ @ApiOperation(value = "testBodyParam")
+ public String testBodyParam(@RequestBody TestBodyBean user) {
+ return user.toString();
+ }
+ }
+
+
+ private static class TestBodyBean {
+
+ @NotBlank
+ private String age;
+
+ @NotNull
+ private String name;
+
+ @NotEmpty
+ private String sexes;
+
+ public String getAge() {
+ return age;
+ }
+
+ public void setAge(String age) {
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getSexes() {
+ return sexes;
+ }
+
+ public void setSexes(String sexes) {
+ this.sexes = sexes;
+ }
}
@Test
@@ -99,4 +149,15 @@ public class ApiOperationProcessorTest {
assertThat(swaggerOperation.getOperation().getConsumes(), Matchers.contains(MediaType.TEXT_HTML));
assertThat(swaggerOperation.getOperation().getProduces(), Matchers.contains(MediaType.TEXT_HTML));
}
+
+
+ @Test
+ public void testBodyParam() {
+ SwaggerOperation swaggerOperation = swaggerOperations.findOperation("testBodyParam");
+ Map<String, Property> properties = swaggerOperation.getSwagger().getDefinitions().get("TestBodyBean").getProperties();
+ assertTrue("Support NotBlank annotation", properties.get("age").getRequired());
+ assertTrue("Support NotEmpty annotation", properties.get("sexes").getRequired());
+ assertTrue("Original support NotNull annotation", properties.get("name").getRequired());
+ }
+
}