This is an automated email from the ASF dual-hosted git repository. chanjarster pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/servicecomb-toolkit.git
commit 7ad21eedcbd22c028be3704e63a05b905a49b8cc Author: kakulisen <[email protected]> AuthorDate: Thu Dec 19 16:26:10 2019 +0800 [SCB-1673] parse the remaining information of RequestMapping Signed-off-by: kakulisen <[email protected]> --- .../toolkit/generator/context/OasContext.java | 40 +++++++++++ .../generator/context/OperationContext.java | 81 +++++++++++++++++++++- ...stractHttpMethodMappingAnnotationProcessor.java | 36 +++------- .../RequestMappingClassAnnotationProcessor.java | 41 +++++++++++ .../RequestMappingMethodAnnotationProcessor.java | 25 ++++--- .../generator/SpringAnnotationProcessorTest.java | 25 ++++++- 6 files changed, 207 insertions(+), 41 deletions(-) diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/context/OasContext.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/context/OasContext.java index d1a80ff..90e1c47 100644 --- a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/context/OasContext.java +++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/context/OasContext.java @@ -47,6 +47,14 @@ public class OasContext implements IExtensionsContext { private List<ISchemaContext> schemaCtxList = new ArrayList<>(); + private String httpMethod; + + private String[] consumers; + + private String[] produces; + + private String[] headers; + public OasContext(OpenApiAnnotationParser parser) { this(new OpenAPI(), parser); } @@ -162,4 +170,36 @@ public class OasContext implements IExtensionsContext { public Map<String, Object> getExtensions() { return openAPI.getExtensions(); } + + public String getHttpMethod() { + return httpMethod; + } + + public void setHttpMethod(String httpMethod) { + this.httpMethod = httpMethod; + } + + public String[] getConsumers() { + return consumers; + } + + public void setConsumers(String[] consumers) { + this.consumers = consumers; + } + + public String[] getProduces() { + return produces; + } + + public void setProduces(String[] produces) { + this.produces = produces; + } + + public String[] getHeaders() { + return headers; + } + + public void setHeaders(String[] headers) { + this.headers = headers; + } } diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/context/OperationContext.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/context/OperationContext.java index 6d36ccb..7941e54 100644 --- a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/context/OperationContext.java +++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/context/OperationContext.java @@ -19,8 +19,10 @@ package org.apache.servicecomb.toolkit.generator.context; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; @@ -37,6 +39,8 @@ import io.swagger.v3.oas.models.media.Content; import io.swagger.v3.oas.models.media.MediaType; import io.swagger.v3.oas.models.media.ObjectSchema; import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.media.StringSchema; +import io.swagger.v3.oas.models.parameters.HeaderParameter; import io.swagger.v3.oas.models.parameters.Parameter; import io.swagger.v3.oas.models.parameters.RequestBody; import io.swagger.v3.oas.models.responses.ApiResponse; @@ -74,6 +78,10 @@ public class OperationContext implements IExtensionsContext { private String[] consumers; + private String[] produces; + + private String[] headers; + public OperationContext(Method method, OasContext parentContext) { this.parentContext = parentContext; this.method = method; @@ -87,7 +95,7 @@ public class OperationContext implements IExtensionsContext { } public boolean hasOperation() { - return httpMethod != null && method != null; + return getHttpMethod() != null && method != null; } public Operation toOperation() { @@ -101,6 +109,8 @@ public class OperationContext implements IExtensionsContext { } operation.operationId(operationId); + processHeaders(); + processProduces(); correctResponse(apiResponses); operation.setResponses(apiResponses); @@ -156,6 +166,57 @@ public class OperationContext implements IExtensionsContext { return operation; } + private void processHeaders() { + + if (headers == null) { + headers = parentContext.getHeaders(); + } + + if (headers == null) { + return; + } + + Arrays.stream(headers).forEach(header -> { + String[] headMap = header.split("="); + if (headMap.length == 2) { + HeaderParameter headerParameter = new HeaderParameter(); + headerParameter.setName(headMap[0]); + StringSchema value = new StringSchema(); + value.setDefault(headMap[1]); + headerParameter.setSchema(value); + operation.addParametersItem(headerParameter); + } + }); + } + + private void processProduces() { + + if (produces == null) { + produces = parentContext.getProduces(); + } + + if (produces == null) { + return; + } + + List<String> produceList = Arrays.stream(produces).filter(s -> !StringUtils.isEmpty(s)) + .collect(Collectors.toList()); + + if (!produceList.isEmpty()) { + ApiResponse apiResponse = new ApiResponse(); + Content content = new Content(); + MediaType mediaType = new MediaType(); + Schema schema = ModelConverter + .getSchema(getMethod().getReturnType(), getComponents(), RequestResponse.RESPONSE); + mediaType.schema(schema); + for (String produce : produceList) { + content.addMediaType(produce, mediaType); + } + apiResponse.setContent(content); + addResponse(HttpStatuses.OK, apiResponse); + } + } + public void setRequestBody(RequestBody requestBody) { operation.requestBody(requestBody); } @@ -238,7 +299,7 @@ public class OperationContext implements IExtensionsContext { } public String getHttpMethod() { - return httpMethod; + return Optional.ofNullable(httpMethod).orElse(parentContext.getHttpMethod()); } public void setHttpMethod(String httpMethod) { @@ -308,4 +369,20 @@ public class OperationContext implements IExtensionsContext { public void addParamCtx(ParameterContext ctx) { this.parameterContexts.add(ctx); } + + public String[] getProduces() { + return produces; + } + + public void setProduces(String[] produces) { + this.produces = produces; + } + + public String[] getHeaders() { + return headers; + } + + public void setHeaders(String[] headers) { + this.headers = headers; + } } diff --git a/oas-generator/oas-generator-spring/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/AbstractHttpMethodMappingAnnotationProcessor.java b/oas-generator/oas-generator-spring/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/AbstractHttpMethodMappingAnnotationProcessor.java index 526b3c6..4205b70 100644 --- a/oas-generator/oas-generator-spring/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/AbstractHttpMethodMappingAnnotationProcessor.java +++ b/oas-generator/oas-generator-spring/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/AbstractHttpMethodMappingAnnotationProcessor.java @@ -17,22 +17,9 @@ package org.apache.servicecomb.toolkit.generator.annotation; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import org.apache.servicecomb.toolkit.generator.HttpStatuses; import org.apache.servicecomb.toolkit.generator.context.OperationContext; -import org.apache.servicecomb.toolkit.generator.util.ModelConverter; -import org.apache.servicecomb.toolkit.generator.util.RequestResponse; -import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMethod; -import io.swagger.v3.oas.models.media.Content; -import io.swagger.v3.oas.models.media.MediaType; -import io.swagger.v3.oas.models.media.Schema; -import io.swagger.v3.oas.models.responses.ApiResponse; - public abstract class AbstractHttpMethodMappingAnnotationProcessor<Annotation, Context> implements MethodAnnotationProcessor<Annotation, Context> { @@ -58,6 +45,8 @@ public abstract class AbstractHttpMethodMappingAnnotationProcessor<Annotation, C if (null == consumes || consumes.length == 0) { return; } + + operationContext.setConsumers(consumes); } protected void processProduces(String[] produces, OperationContext operationContext) { @@ -65,22 +54,13 @@ public abstract class AbstractHttpMethodMappingAnnotationProcessor<Annotation, C return; } - List<String> produceList = Arrays.stream(produces).filter(s -> !StringUtils.isEmpty(s)) - .collect(Collectors.toList()); + operationContext.setProduces(produces); + } - if (!produceList.isEmpty()) { - ApiResponse apiResponse = new ApiResponse(); - Content content = new Content(); - MediaType mediaType = new MediaType(); - Schema schema = ModelConverter - .getSchema(operationContext.getMethod().getReturnType(), operationContext.getComponents(), - RequestResponse.RESPONSE); - mediaType.schema(schema); - for (String produce : produceList) { - content.addMediaType(produce, mediaType); - } - apiResponse.setContent(content); - operationContext.addResponse(HttpStatuses.OK, apiResponse); + protected void processHeaders(String[] headers, OperationContext operationContext) { + if (null == headers || headers.length == 0) { + return; } + operationContext.setHeaders(headers); } } diff --git a/oas-generator/oas-generator-spring/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/RequestMappingClassAnnotationProcessor.java b/oas-generator/oas-generator-spring/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/RequestMappingClassAnnotationProcessor.java index ad01f16..860a11b 100644 --- a/oas-generator/oas-generator-spring/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/RequestMappingClassAnnotationProcessor.java +++ b/oas-generator/oas-generator-spring/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/RequestMappingClassAnnotationProcessor.java @@ -19,6 +19,7 @@ package org.apache.servicecomb.toolkit.generator.annotation; import org.apache.servicecomb.toolkit.generator.context.OasContext; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; public class RequestMappingClassAnnotationProcessor implements ClassAnnotationProcessor<RequestMapping, OasContext> { @@ -37,5 +38,45 @@ public class RequestMappingClassAnnotationProcessor implements } oasContext.setBasePath(paths[0]); + + processMethod(requestMapping.method(), oasContext); + processConsumes(requestMapping.consumes(), oasContext); + processProduces(requestMapping.produces(), oasContext); + processHeaders(requestMapping.headers(), oasContext); + } + + protected void processMethod(RequestMethod[] requestMethods, OasContext oasContext) { + if (null == requestMethods || requestMethods.length == 0) { + return; + } + + if (requestMethods.length > 1) { + throw new Error( + "not allowed multi http method for " + oasContext.getCls().getName()); + } + + oasContext.setHttpMethod(requestMethods[0].name()); + } + + protected void processConsumes(String[] consumes, OasContext oasContext) { + if (null == consumes || consumes.length == 0) { + return; + } + oasContext.setConsumers(consumes); + } + + protected void processProduces(String[] produces, OasContext oasContext) { + if (null == produces || produces.length == 0) { + return; + } + oasContext.setProduces(produces); + } + + protected void processHeaders(String[] headers, OasContext oasContext) { + if (null == headers || headers.length == 0) { + return; + } + oasContext.setHeaders(headers); } } + diff --git a/oas-generator/oas-generator-spring/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/RequestMappingMethodAnnotationProcessor.java b/oas-generator/oas-generator-spring/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/RequestMappingMethodAnnotationProcessor.java index 040f559..06b6e65 100644 --- a/oas-generator/oas-generator-spring/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/RequestMappingMethodAnnotationProcessor.java +++ b/oas-generator/oas-generator-spring/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/RequestMappingMethodAnnotationProcessor.java @@ -19,23 +19,32 @@ package org.apache.servicecomb.toolkit.generator.annotation; import org.apache.servicecomb.toolkit.generator.context.OperationContext; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; -public class RequestMappingMethodAnnotationProcessor implements - MethodAnnotationProcessor<RequestMapping, OperationContext> { +public class RequestMappingMethodAnnotationProcessor extends + AbstractHttpMethodMappingAnnotationProcessor<RequestMapping, OperationContext> { @Override public void process(RequestMapping requestMapping, OperationContext operationContext) { - String[] paths = requestMapping.value(); - if (null == paths || paths.length == 0) { + this.processPath(requestMapping.path(), operationContext); + this.processPath(requestMapping.value(), operationContext); + this.processMethod(requestMapping.method(), operationContext); + this.processConsumes(requestMapping.consumes(), operationContext); + this.processProduces(requestMapping.produces(), operationContext); + this.processHeaders(requestMapping.headers(), operationContext); + } + + protected void processMethod(RequestMethod[] requestMethods, OperationContext operationContext) { + if (null == requestMethods || requestMethods.length == 0) { return; } - // swagger only support one basePath - if (paths.length > 1) { - throw new Error("not support multi path for " + operationContext.getMethod().getName()); + if (requestMethods.length > 1) { + throw new Error( + "not allowed multi http method for " + operationContext.getMethod().getName()); } - operationContext.setPath(paths[0]); + this.processMethod(requestMethods[0], operationContext); } } diff --git a/oas-generator/oas-generator-spring/src/test/java/org/apache/servicecomb/toolkit/generator/SpringAnnotationProcessorTest.java b/oas-generator/oas-generator-spring/src/test/java/org/apache/servicecomb/toolkit/generator/SpringAnnotationProcessorTest.java index adfd48a..3cad49b 100644 --- a/oas-generator/oas-generator-spring/src/test/java/org/apache/servicecomb/toolkit/generator/SpringAnnotationProcessorTest.java +++ b/oas-generator/oas-generator-spring/src/test/java/org/apache/servicecomb/toolkit/generator/SpringAnnotationProcessorTest.java @@ -34,6 +34,7 @@ import org.apache.servicecomb.toolkit.generator.annotation.RequestPartAnnotation import org.apache.servicecomb.toolkit.generator.context.OasContext; import org.apache.servicecomb.toolkit.generator.context.OperationContext; import org.apache.servicecomb.toolkit.generator.context.ParameterContext; +import org.apache.servicecomb.toolkit.generator.parser.SpringmvcAnnotationParser; import org.junit.Assert; import org.junit.Test; import org.springframework.web.bind.annotation.DeleteMapping; @@ -44,6 +45,7 @@ import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; @@ -55,13 +57,15 @@ public class SpringAnnotationProcessorTest { @Test public void getHttpMethod() throws NoSuchMethodException { + SpringmvcAnnotationParser parser = new SpringmvcAnnotationParser(); - OasContext oasContext = new OasContext(null); + OasContext oasContext = new OasContext(parser); Class<HttpMethodResource> httpMethodResourceClass = HttpMethodResource.class; RequestMapping requestMappingClassAnnotation = httpMethodResourceClass.getAnnotation(RequestMapping.class); RequestMappingClassAnnotationProcessor requestMappingClassAnnotationProcessor = new RequestMappingClassAnnotationProcessor(); requestMappingClassAnnotationProcessor.process(requestMappingClassAnnotation, oasContext); Assert.assertEquals(requestMappingClassAnnotation.value()[0], oasContext.getBasePath()); + Assert.assertEquals(RequestMethod.GET.name(), oasContext.getHttpMethod()); RequestMappingMethodAnnotationProcessor requestMappingMethodAnnotationProcessor = new RequestMappingMethodAnnotationProcessor(); Method requestMethod = httpMethodResourceClass.getMethod("request"); @@ -71,6 +75,16 @@ public class SpringAnnotationProcessorTest { Assert .assertEquals(requestMappingMethodAnnotation.value()[0], requestOperationContext.getPath()); + Assert.assertEquals(RequestMethod.POST.name(), requestOperationContext.getHttpMethod()); + + Method getRequestMethod = httpMethodResourceClass.getMethod("getRequest"); + RequestMapping getRequestMappingMethodAnnotation = getRequestMethod.getAnnotation(RequestMapping.class); + OperationContext getRequestOperationContext = new OperationContext(getRequestMethod, oasContext); + requestMappingMethodAnnotationProcessor.process(getRequestMappingMethodAnnotation, getRequestOperationContext); + Assert + .assertEquals(getRequestMappingMethodAnnotation.value()[0], + getRequestOperationContext.getPath()); + Assert.assertEquals(RequestMethod.GET.name(), getRequestOperationContext.getHttpMethod()); GetMappingMethodAnnotationProcessor getMappingMethodAnnotationProcessor = new GetMappingMethodAnnotationProcessor(); Method getMethod = httpMethodResourceClass.getMethod("get"); @@ -178,14 +192,19 @@ public class SpringAnnotationProcessorTest { } @RestController - @RequestMapping("/path") + @RequestMapping(value = "/path", method = RequestMethod.GET) class HttpMethodResource { - @RequestMapping("/request") + @RequestMapping(value = "/request", method = RequestMethod.POST, headers = "cookie=1") public String request() { return "request"; } + @RequestMapping(value = "/getRequest") + public String getRequest() { + return "getRequest"; + } + @GetMapping(value = "/get", consumes = {"application/json"}, produces = {"application/json"}) public String get() { return "get";
