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
commit 6ad909d9189291a163c9df1fc9e5f3b135831482 Author: liubao <[email protected]> AuthorDate: Tue Aug 22 20:04:49 2023 +0800 [SCB-2803]add test case for response proto-buffer codec --- .../servicecomb/common/rest/codec/RestCodec.java | 3 ++- .../rest/codec/param/BodyProcessorCreator.java | 23 ++++++++-------------- .../codec/produce/ProduceProcessorManager.java | 2 +- .../common/rest/codec/TestRestCodec.java | 3 ++- .../common/rest/codec/param/TestBodyProcessor.java | 2 +- .../demo/springmvc/client/TestContentType.java | 16 ++++++--------- .../demo/springmvc/server/CodeFirstSpringmvc.java | 6 ------ .../springmvc/server/ContentTypeSpringmvc.java | 2 +- .../schemas/CodeFirstSpringmvcForSchema.yaml | 8 +------- ...stractHttpMethodMappingAnnotationProcessor.java | 13 +++++++----- .../RequestMappingClassAnnotationProcessor.java | 8 ++++++++ 11 files changed, 38 insertions(+), 48 deletions(-) diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestCodec.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestCodec.java index 161288b8f..260ac0d4c 100644 --- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestCodec.java +++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestCodec.java @@ -23,6 +23,7 @@ import java.util.Map; import org.apache.servicecomb.common.rest.definition.RestOperationMeta; import org.apache.servicecomb.common.rest.definition.RestParam; +import org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData; import org.apache.servicecomb.swagger.invocation.exception.InvocationException; import jakarta.servlet.http.HttpServletRequest; @@ -60,7 +61,7 @@ public final class RestCodec { param.getParamName(), param.getParamProcessor().getProcessorType(), e.getMessage()); - throw new InvocationException(Status.BAD_REQUEST, message, e); + throw new InvocationException(Status.BAD_REQUEST, new CommonExceptionData(message), e); } } diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java index b231f854c..83e46002a 100644 --- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java +++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java @@ -160,7 +160,7 @@ public class BodyProcessorCreator implements ParamValueProcessorCreator<RequestB } // edge support convert from form-data or x-www-form-urlencoded to json automatically - String contentType = parseContentType(request); + String contentType = validContentType(request.getContentType()); if (contentType.equals(MediaType.MULTIPART_FORM_DATA) || contentType.equals(MediaType.APPLICATION_FORM_URLENCODED)) { return convertValue(request.getParameterMap(), targetType); @@ -216,8 +216,7 @@ public class BodyProcessorCreator implements ParamValueProcessorCreator<RequestB } } - private String parseContentType(HttpServletRequest request) { - String type = request.getContentType(); + private String validContentType(String type) { if (StringUtils.isEmpty(type)) { if (supportedContentTypes.size() == 0) { throw new IllegalArgumentException("operation do not have any content type support."); @@ -233,9 +232,13 @@ public class BodyProcessorCreator implements ParamValueProcessorCreator<RequestB @Override public void setValue(RestClientRequest clientRequest, Object arg) throws Exception { - ensureContentType(clientRequest); + String userContentType = clientRequest.getHeaders().get(HttpHeaders.CONTENT_TYPE); + String contentType = validContentType(userContentType); + if (StringUtils.isEmpty(userContentType)) { + clientRequest.putHeader(HttpHeaders.CONTENT_TYPE, contentType); + } if (arg != null) { - Buffer buffer = createBodyBuffer(clientRequest.getHeaders().get(HttpHeaders.CONTENT_TYPE), arg); + Buffer buffer = createBodyBuffer(contentType, arg); clientRequest.write(buffer); } } @@ -270,16 +273,6 @@ public class BodyProcessorCreator implements ParamValueProcessorCreator<RequestB } } - /** - * If the Content-Type has not been set yet, set application/json as default value. - */ - private void ensureContentType(RestClientRequest clientRequest) { - if (null == clientRequest.getHeaders() - || StringUtils.isEmpty(clientRequest.getHeaders().get(HttpHeaders.CONTENT_TYPE))) { - clientRequest.putHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON); - } - } - @Override public String getParameterPath() { return ""; diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessorManager.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessorManager.java index 81302d576..36b9a8c3e 100644 --- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessorManager.java +++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessorManager.java @@ -137,7 +137,7 @@ public final class ProduceProcessorManager extends RegisterManager<String, Map<S } if (SwaggerConst.PROTOBUF_TYPE.equals(actualAccept)) { return new ProduceProtoBufferProcessor(operationMeta, - operationMeta.getSchemaMeta().getSwagger(), response.getContent().get(accept).getSchema()); + operationMeta.getSchemaMeta().getSwagger(), response.getContent().get(actualAccept).getSchema()); } if (MediaType.TEXT_PLAIN.equals(actualAccept)) { return findPlainProcessorByViewClass(serialViewClass); diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/TestRestCodec.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/TestRestCodec.java index 5e7270a6e..ebbe2975a 100644 --- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/TestRestCodec.java +++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/TestRestCodec.java @@ -27,6 +27,7 @@ import org.apache.servicecomb.common.rest.codec.param.RestClientRequestImpl; import org.apache.servicecomb.common.rest.definition.RestOperationMeta; import org.apache.servicecomb.common.rest.definition.RestParam; import org.apache.servicecomb.core.definition.OperationMeta; +import org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData; import org.apache.servicecomb.swagger.invocation.exception.InvocationException; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; @@ -159,7 +160,7 @@ public class TestRestCodec { success = true; } catch (InvocationException e) { Assertions.assertEquals(e.getStatusCode(), Status.BAD_REQUEST.getStatusCode()); - Assertions.assertTrue(((String) e.getErrorData()) + Assertions.assertTrue(((CommonExceptionData) e.getErrorData()).getMessage() .contains("Parameter is not valid for operation")); } Assertions.assertFalse(success); diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestBodyProcessor.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestBodyProcessor.java index 5ad90a83a..340b7f15c 100644 --- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestBodyProcessor.java +++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestBodyProcessor.java @@ -136,7 +136,7 @@ public class TestBodyProcessor { @Test public void testGetValueTextPlain() throws Exception { setupGetValue(String.class); - inputBodyByteBuf.writeCharSequence("\"abc\"", StandardCharsets.UTF_8); + inputBodyByteBuf.writeCharSequence("abc", StandardCharsets.UTF_8); Mockito.when(request.getContentType()).thenReturn(MediaType.TEXT_PLAIN); diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestContentType.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestContentType.java index 662f153b0..4fa466af3 100644 --- a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestContentType.java +++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestContentType.java @@ -51,22 +51,20 @@ public class TestContentType { TestMgr.check( "testGlobalSetting: name=[from testGlobalSetting], request content-type=[" + MediaType.TEXT_PLAIN + "]", responseEntity.getBody()); - // TODO: ContentTypeSpringmvc should generate consumes and produces TEXT_PLAIN, but now is JSON - // will fix later. -// TestMgr.check(MediaType.TEXT_PLAIN, extractContentType(responseEntity.getHeaders().getContentType())); + TestMgr.check(MediaType.TEXT_PLAIN, extractContentType(responseEntity.getHeaders().getContentType())); } private void testApiOperation() { HttpHeaders requestHeaders = new HttpHeaders(); - requestHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON); + requestHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN); CseHttpEntity<String> requestEntity = new CseHttpEntity<>("from testApiOperation", requestHeaders); ResponseEntity<String> responseEntity = restTemplate .exchange("cse://springmvc/contentTypeSpringmvc/testApiOperation", HttpMethod.POST, requestEntity, String.class); TestMgr.check( - "testApiOperation: name=[from testApiOperation], request content-type=[" + MediaType.APPLICATION_JSON + "]", + "testApiOperation: name=[from testApiOperation], request content-type=[" + MediaType.TEXT_PLAIN + "]", responseEntity.getBody()); - TestMgr.check(MediaType.APPLICATION_JSON, extractContentType(responseEntity.getHeaders().getContentType())); + TestMgr.check(MediaType.TEXT_PLAIN, extractContentType(responseEntity.getHeaders().getContentType())); } private void testRequestMapping() { @@ -97,16 +95,14 @@ public class TestContentType { TestMgr.check( "testRequestMapping: name=[hello:100:[a1, a2]], request content-type=[application/protobuf]", responseEntity.getBody()); - TestMgr.check(MediaType.APPLICATION_JSON, extractContentType(responseEntity.getHeaders().getContentType())); + TestMgr.check(SwaggerConst.PROTOBUF_TYPE, extractContentType(responseEntity.getHeaders().getContentType())); } private void testResponseTypeOverwrite() { ResponseEntity<String> responseEntity = restTemplate .getForEntity("cse://springmvc/contentTypeSpringmvcOverwrite/testResponseTypeOverwrite", String.class); TestMgr.check("testResponseTypeOverwrite: OK", responseEntity.getBody()); - // TODO: ContentTypeSpringmvc should generate consumes and produces TEXT_PLAIN, but now is JSON - // will fix later. -// TestMgr.check(MediaType.TEXT_PLAIN, extractContentType(responseEntity.getHeaders().getContentType())); + TestMgr.check(MediaType.TEXT_PLAIN, extractContentType(responseEntity.getHeaders().getContentType())); } private String extractContentType(org.springframework.http.MediaType mediaType) { 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 821fed840..71eacd4dc 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,7 +36,6 @@ 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; -import org.apache.servicecomb.demo.jaxbbean.JAXBPerson; import org.apache.servicecomb.demo.server.User; import org.apache.servicecomb.demo.springmvc.decoderesponse.DecodeTestResponse; import org.apache.servicecomb.foundation.common.Holder; @@ -202,11 +201,6 @@ public class CodeFirstSpringmvc { return body; } - @RequestMapping(path = "/appXml", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_XML_VALUE) - public JAXBPerson appXml(@RequestBody JAXBPerson person) { - return person; - } - @RequestMapping(path = "/bytes", method = RequestMethod.POST) public byte[] bytes(@RequestBody byte[] input) { input[0] = (byte) (input[0] + 1); diff --git a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ContentTypeSpringmvc.java b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ContentTypeSpringmvc.java index 6626f553c..cd290cb75 100644 --- a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ContentTypeSpringmvc.java +++ b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ContentTypeSpringmvc.java @@ -50,7 +50,7 @@ public class ContentTypeSpringmvc { // TODO: 注册中心不会覆盖契约 @RequestMapping(path = "/testProtoBuffer", method = RequestMethod.POST, - consumes = SwaggerConst.PROTOBUF_TYPE, produces = MediaType.APPLICATION_JSON) + consumes = SwaggerConst.PROTOBUF_TYPE, produces = SwaggerConst.PROTOBUF_TYPE) public String testProtoBuffer(@RequestBody User user, HttpServletRequest request) { return String.format("testRequestMapping: name=[%s], request content-type=[%s]", user.getName() + ":" + user.getIndex() + ":" + diff --git a/demo/demo-springmvc/springmvc-server/src/main/resources/schemas/CodeFirstSpringmvcForSchema.yaml b/demo/demo-springmvc/springmvc-server/src/main/resources/schemas/CodeFirstSpringmvcForSchema.yaml index 9ac86e2f7..59f893152 100644 --- a/demo/demo-springmvc/springmvc-server/src/main/resources/schemas/CodeFirstSpringmvcForSchema.yaml +++ b/demo/demo-springmvc/springmvc-server/src/main/resources/schemas/CodeFirstSpringmvcForSchema.yaml @@ -53,10 +53,4 @@ paths: application/json: schema: type: boolean - application/protobuf: - schema: - type: boolean - text/plain: - schema: - type: boolean -components: {} +components: {} \ No newline at end of file diff --git a/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/AbstractHttpMethodMappingAnnotationProcessor.java b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/AbstractHttpMethodMappingAnnotationProcessor.java index ed094f1c4..8fe797bbb 100644 --- a/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/AbstractHttpMethodMappingAnnotationProcessor.java +++ b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/AbstractHttpMethodMappingAnnotationProcessor.java @@ -17,6 +17,8 @@ package org.apache.servicecomb.swagger.generator.springmvc.processor.annotation; +import java.util.Arrays; + import org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor; import org.apache.servicecomb.swagger.generator.OperationGenerator; import org.springframework.web.bind.annotation.RequestMethod; @@ -33,11 +35,12 @@ abstract class AbstractHttpMethodMappingAnnotationProcessor<ANNOTATION> implemen if (requestMethod != null) { operationGenerator.setHttpMethod(requestMethod.name()); } - // TODO: actually is no use to update consumes and produces - // Because they are system capabilities. -// Operation operation = operationGenerator.getOperation(); -// SwaggerUtils.updateConsumes(operation, consumes); -// SwaggerUtils.updateProduces(operation, produces); + if (consumes.length > 0) { + operationGenerator.getOperationGeneratorContext().updateConsumes(Arrays.asList(consumes)); + } + if (produces.length > 0) { + operationGenerator.getOperationGeneratorContext().updateProduces(Arrays.asList(produces)); + } } protected void processPath(OperationGenerator operationGenerator, String[] paths) { diff --git a/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestMappingClassAnnotationProcessor.java b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestMappingClassAnnotationProcessor.java index 459ada5bd..df18070f9 100644 --- a/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestMappingClassAnnotationProcessor.java +++ b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestMappingClassAnnotationProcessor.java @@ -18,6 +18,7 @@ package org.apache.servicecomb.swagger.generator.springmvc.processor.annotation; import java.lang.reflect.Type; +import java.util.Arrays; import org.apache.servicecomb.swagger.generator.ClassAnnotationProcessor; import org.apache.servicecomb.swagger.generator.SwaggerGenerator; @@ -37,6 +38,13 @@ public class RequestMappingClassAnnotationProcessor implements ClassAnnotationPr // path/value是等同的 this.processPath(requestMapping.path(), swaggerGenerator); this.processPath(requestMapping.value(), swaggerGenerator); + + if (requestMapping.consumes().length > 0) { + swaggerGenerator.getSwaggerGeneratorContext().updateConsumes(Arrays.asList(requestMapping.consumes())); + } + if (requestMapping.produces().length > 0) { + swaggerGenerator.getSwaggerGeneratorContext().updateProduces(Arrays.asList(requestMapping.produces())); + } } protected void processPath(String[] paths, SwaggerGenerator swaggerGenerator) {
