From dev-return-3678-archive-asf-public=cust-asf.ponee.io@servicecomb.apache.org Mon Apr 16 11:36:50 2018 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id B3E61180608 for ; Mon, 16 Apr 2018 11:36:48 +0200 (CEST) Received: (qmail 61440 invoked by uid 500); 16 Apr 2018 09:36:47 -0000 Mailing-List: contact dev-help@servicecomb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@servicecomb.apache.org Delivered-To: mailing list dev@servicecomb.apache.org Received: (qmail 61429 invoked by uid 99); 16 Apr 2018 09:36:47 -0000 Received: from ec2-52-202-80-70.compute-1.amazonaws.com (HELO gitbox.apache.org) (52.202.80.70) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 16 Apr 2018 09:36:47 +0000 From: GitBox To: dev@servicecomb.apache.org Subject: [GitHub] liubao68 closed pull request #627: [SCB-292] chassis support standard parameter validation Message-ID: <152387140677.25987.11999080749593302797.gitbox@gitbox.apache.org> Date: Mon, 16 Apr 2018 09:36:46 -0000 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit liubao68 closed pull request #627: [SCB-292] chassis support standard parameter validation URL: https://github.com/apache/incubator-servicecomb-java-chassis/pull/627 This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CustomLoadbalanceExtensionsFactory.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CustomLoadbalanceExtensionsFactory.java index 819249d49..77ce21b88 100644 --- a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CustomLoadbalanceExtensionsFactory.java +++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CustomLoadbalanceExtensionsFactory.java @@ -22,6 +22,7 @@ import com.netflix.client.DefaultLoadBalancerRetryHandler; import com.netflix.client.RetryHandler; +import com.netflix.client.Utils; import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.RoundRobinRule; @@ -33,6 +34,14 @@ } class MyCustomHandler extends DefaultLoadBalancerRetryHandler { + @Override + public boolean isRetriableException(Throwable e, boolean sameServer) { + if (retryEnabled) { + return Utils.isPresentAsCause(e, getRetriableExceptions()); + } + return false; + } + public MyCustomHandler(int retrySameServer, int retryNextServer, boolean retryEnabled) { super(retrySameServer, retryNextServer, retryEnabled); } diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java index 5047a878b..5e63c2ddc 100644 --- a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java +++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java @@ -21,6 +21,7 @@ import java.util.Map; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response.Status; import org.apache.servicecomb.common.rest.codec.RestObjectMapper; import org.apache.servicecomb.core.CseContext; @@ -28,9 +29,11 @@ import org.apache.servicecomb.demo.DemoConst; import org.apache.servicecomb.demo.TestMgr; import org.apache.servicecomb.demo.compute.Person; +import org.apache.servicecomb.demo.validator.Student; import org.apache.servicecomb.foundation.common.utils.BeanUtils; import org.apache.servicecomb.foundation.common.utils.Log4jUtils; import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder; +import org.apache.servicecomb.swagger.invocation.exception.InvocationException; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -57,6 +60,7 @@ public static void run() throws Exception { CodeFirstRestTemplate codeFirstClient = new CodeFirstRestTemplateJaxrs(); codeFirstClient.testCodeFirst(templateNew, "jaxrs", "/codeFirstJaxrs/"); testCompute(templateNew); + testValidator(templateNew); } private static void testCompute(RestTemplate template) throws Exception { @@ -76,6 +80,24 @@ private static void testCompute(RestTemplate template) throws Exception { } } + private static void testValidator(RestTemplate template) throws Exception { + String microserviceName = "jaxrs"; + for (String transport : DemoConst.transports) { + CseContext.getInstance().getConsumerProviderManager().setTransport(microserviceName, transport); + TestMgr.setMsg(microserviceName, transport); + + String cseUrlPrefix = "cse://" + microserviceName + "/validator/"; + + testValidatorAddSuccess(template, cseUrlPrefix); + testValidatorAddFail(template, cseUrlPrefix); + testValidatorSayHiSuccess(template, cseUrlPrefix); + testValidatorSayHiFail(template, cseUrlPrefix); + testValidatorExchangeSuccess(template, cseUrlPrefix); + testValidatorExchangeFail(template, cseUrlPrefix); + } + } + + private static void testGet(RestTemplate template, String cseUrlPrefix) { Map params = new HashMap<>(); params.put("a", "5"); @@ -147,4 +169,85 @@ private static void testRawJsonParam(RestTemplate template, String cseUrlPrefix) TestMgr.check("hello Tom", template.postForObject(cseUrlPrefix + "/compute/testrawjson", jsonPerson, String.class)); } + + private static void testValidatorAddFail(RestTemplate template, String cseUrlPrefix) { + Map params = new HashMap<>(); + params.put("a", "5"); + params.put("b", "3"); + boolean isExcep = false; + try { + template.postForObject(cseUrlPrefix + "add", params, Integer.class); + } catch (InvocationException e) { + isExcep = true; + TestMgr.check(400, e.getStatus().getStatusCode()); + TestMgr.check(Status.BAD_REQUEST, e.getReasonPhrase()); + TestMgr.check( + "CommonExceptionData [message=[ConstraintViolationImpl{interpolatedMessage='must be greater than or equal to 20', propertyPath=add.arg1, rootBeanClass=class org.apache.servicecomb.demo.jaxrs.server.Validator, messageTemplate='{javax.validation.constraints.Min.message}'}]]", + e.getErrorData()); + } + + TestMgr.check(true, isExcep); + } + + private static void testValidatorAddSuccess(RestTemplate template, String cseUrlPrefix) { + Map params = new HashMap<>(); + params.put("a", "5"); + params.put("b", "20"); + int result = template.postForObject(cseUrlPrefix + "add", params, Integer.class); + TestMgr.check(25, result); + } + + private static void testValidatorSayHiFail(RestTemplate template, String cseUrlPrefix) { + boolean isExcep = false; + try { + template.exchange(cseUrlPrefix + "sayhi/{name}", HttpMethod.PUT, null, String.class, "te"); + } catch (InvocationException e) { + isExcep = true; + TestMgr.check(400, e.getStatus().getStatusCode()); + TestMgr.check(Status.BAD_REQUEST, e.getReasonPhrase()); + TestMgr.check( + "CommonExceptionData [message=[ConstraintViolationImpl{interpolatedMessage='length must be between 3 and 2147483647', propertyPath=sayHi.arg0, rootBeanClass=class org.apache.servicecomb.demo.jaxrs.server.Validator, messageTemplate='{org.hibernate.validator.constraints.Length.message}'}]]", + e.getErrorData()); + } + TestMgr.check(true, isExcep); + } + + private static void testValidatorSayHiSuccess(RestTemplate template, String cseUrlPrefix) { + ResponseEntity responseEntity = + template.exchange(cseUrlPrefix + "sayhi/{name}", HttpMethod.PUT, null, String.class, "world"); + TestMgr.check(202, responseEntity.getStatusCode()); + TestMgr.check("world sayhi", responseEntity.getBody()); + } + + private static void testValidatorExchangeFail(RestTemplate template, String cseUrlPrefix) { + HttpHeaders headers = new HttpHeaders(); + headers.add("Accept", MediaType.APPLICATION_JSON); + Student student = new Student(); + student.setName(""); + student.setAge(25); + boolean isExcep = false; + try { + HttpEntity requestEntity = new HttpEntity<>(student, headers); + template.exchange(cseUrlPrefix + "/sayhello", + HttpMethod.POST, + requestEntity, + Student.class); + } catch (InvocationException e) { + isExcep = true; + TestMgr.check(400, e.getStatus().getStatusCode()); + TestMgr.check(Status.BAD_REQUEST, e.getReasonPhrase()); + TestMgr.check( + "CommonExceptionData [message=[ConstraintViolationImpl{interpolatedMessage='must be less than or equal to 20', propertyPath=sayHello.arg0.age, rootBeanClass=class org.apache.servicecomb.demo.jaxrs.server.Validator, messageTemplate='{javax.validation.constraints.Max.message}'}]]", + e.getErrorData()); + } + TestMgr.check(true, isExcep); + } + + private static void testValidatorExchangeSuccess(RestTemplate template, String cseUrlPrefix) { + Student student = new Student(); + student.setName("test"); + student.setAge(15); + Student result = template.postForObject(cseUrlPrefix + "sayhello", student, Student.class); + TestMgr.check("hello test 15", result); + } } diff --git a/demo/demo-jaxrs/jaxrs-server/pom.xml b/demo/demo-jaxrs/jaxrs-server/pom.xml index af8de5619..0abb64f41 100644 --- a/demo/demo-jaxrs/jaxrs-server/pom.xml +++ b/demo/demo-jaxrs/jaxrs-server/pom.xml @@ -17,68 +17,69 @@ --> - 4.0.0 - - org.apache.servicecomb.demo - demo-jaxrs - 1.0.0-m2-SNAPSHOT - - jaxrs-server - Java Chassis::Demo::JAXRS::Server - - - - org.apache.servicecomb.demo - demo-schema - - - org.apache.servicecomb - provider-jaxrs - - - - - org.apache.servicecomb.demo.jaxrs.server.JaxrsServer - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - com.github.odavid.maven.plugins - mixin-maven-plugin - - - - org.apache.servicecomb.demo - docker-build-config - 1.0.0-m2-SNAPSHOT - - - - - - - - - - docker - - - - io.fabric8 - docker-maven-plugin - - - org.commonjava.maven.plugins - directory-maven-plugin - - - - - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" + xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + 4.0.0 + + org.apache.servicecomb.demo + demo-jaxrs + 1.0.0-m2-SNAPSHOT + + jaxrs-server + Java Chassis::Demo::JAXRS::Server + + + org.apache.servicecomb.demo + demo-schema + + + org.apache.servicecomb + provider-jaxrs + + + org.apache.servicecomb + swagger-invocation-validator + + + + org.apache.servicecomb.demo.jaxrs.server.JaxrsServer + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + com.github.odavid.maven.plugins + mixin-maven-plugin + + + + org.apache.servicecomb.demo + docker-build-config + 1.0.0-m2-SNAPSHOT + + + + + + + + + docker + + + + io.fabric8 + docker-maven-plugin + + + org.commonjava.maven.plugins + directory-maven-plugin + + + + + diff --git a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/Validator.java b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/Validator.java new file mode 100644 index 000000000..986f6a348 --- /dev/null +++ b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/Validator.java @@ -0,0 +1,61 @@ +/* + * 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.jaxrs.server; + +import javax.validation.Valid; +import javax.validation.constraints.Min; +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.apache.servicecomb.demo.validator.Student; +import org.apache.servicecomb.provider.rest.common.RestSchema; +import org.apache.servicecomb.swagger.invocation.context.ContextUtils; +import org.hibernate.validator.constraints.Length; + +@RestSchema(schemaId = "validator") +@Path("/validator") +@Produces(MediaType.APPLICATION_JSON) +public class Validator { + + @Path("/add") + @POST + public int add(@FormParam("a") int a, @Min(20) @FormParam("b") int b) { + return a + b; + } + + @Path("/sayhi/{name}") + @PUT + public String sayHi(@Length(min = 3) @PathParam("name") String name) { + ContextUtils.getInvocationContext().setStatus(202); + return name + " sayhi"; + } + + @Path("/sayhello") + @POST + public Student sayHello(@Valid Student student) { + student.setName("hello " + student.getName()); + student.setAge(student.getAge()); + return student; + } + +} diff --git a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/validator/Student.java b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/validator/Student.java new file mode 100644 index 000000000..65feea2ec --- /dev/null +++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/validator/Student.java @@ -0,0 +1,58 @@ +/* + * 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.validator; + +import javax.validation.constraints.Max; +import javax.validation.constraints.NotNull; + +public class Student { + @NotNull + private String name; + + @Max(20) + private int age; + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + public Student() { + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public Student(String name, int age) { + this.name = name; + this.age = age; + } + + @Override + public String toString() { + return name + " " + age; + } +} diff --git a/demo/pom.xml b/demo/pom.xml index 2cf4603c2..55505d2ad 100644 --- a/demo/pom.xml +++ b/demo/pom.xml @@ -47,7 +47,6 @@ demo-multiple demo-signature demo-edge - perf diff --git a/java-chassis-dependencies/pom.xml b/java-chassis-dependencies/pom.xml index b7b622785..c0adb91c3 100644 --- a/java-chassis-dependencies/pom.xml +++ b/java-chassis-dependencies/pom.xml @@ -899,6 +899,11 @@ swagger-invocation-springmvc 1.0.0-m2-SNAPSHOT + + org.apache.servicecomb + swagger-invocation-validator + 1.0.0-m2-SNAPSHOT + org.apache.servicecomb service-registry diff --git a/java-chassis-distribution/pom.xml b/java-chassis-distribution/pom.xml index 95b30e1a0..ebaa6677a 100644 --- a/java-chassis-distribution/pom.xml +++ b/java-chassis-distribution/pom.xml @@ -88,6 +88,10 @@ org.apache.servicecomb swagger-invocation-springmvc + + org.apache.servicecomb + swagger-invocation-validator + org.apache.servicecomb foundation-common diff --git a/swagger/swagger-invocation/invocation-core/pom.xml b/swagger/swagger-invocation/invocation-core/pom.xml index d60e95489..b7a367e99 100644 --- a/swagger/swagger-invocation/invocation-core/pom.xml +++ b/swagger/swagger-invocation/invocation-core/pom.xml @@ -48,4 +48,4 @@ test - + \ No newline at end of file diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducerOperation.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducerOperation.java index 4827a7641..5c3caf091 100644 --- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducerOperation.java +++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducerOperation.java @@ -18,14 +18,17 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.List; import java.util.concurrent.CompletableFuture; +import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils; import org.apache.servicecomb.swagger.invocation.AsyncResponse; import org.apache.servicecomb.swagger.invocation.Response; import org.apache.servicecomb.swagger.invocation.SwaggerInvocation; import org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerArgumentsMapper; import org.apache.servicecomb.swagger.invocation.context.ContextUtils; import org.apache.servicecomb.swagger.invocation.exception.ExceptionFactory; +import org.apache.servicecomb.swagger.invocation.extension.ProducerInvokeExtension; import org.apache.servicecomb.swagger.invocation.response.producer.ProducerResponseMapper; public class SwaggerProducerOperation { @@ -44,6 +47,9 @@ private ProducerResponseMapper responseMapper; + private List producerInvokeExtenstionList = + SPIServiceUtils.getSortedService(ProducerInvokeExtension.class); + public String getName() { return name; } @@ -119,6 +125,9 @@ public void completableFutureInvoke(SwaggerInvocation invocation, AsyncResponse public void doCompletableFutureInvoke(SwaggerInvocation invocation, AsyncResponse asyncResp) { try { Object[] args = argumentsMapper.toProducerArgs(invocation); + for (ProducerInvokeExtension producerInvokeExtension : producerInvokeExtenstionList) { + producerInvokeExtension.beforeMethodInvoke(invocation, this, args); + } Object result = producerMethod.invoke(producerInstance, args); ((CompletableFuture) result).whenComplete((realResult, ex) -> { @@ -145,6 +154,9 @@ public Response doInvoke(SwaggerInvocation invocation) { Response response = null; try { Object[] args = argumentsMapper.toProducerArgs(invocation); + for (ProducerInvokeExtension producerInvokeExtension : producerInvokeExtenstionList) { + producerInvokeExtension.beforeMethodInvoke(invocation, this, args); + } Object result = producerMethod.invoke(producerInstance, args); response = responseMapper.mapResponse(invocation.getStatus(), result); } catch (Throwable e) { diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/ExceptionToResponseConverter.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/ExceptionToResponseConverter.java index 3b36f5ab1..4c14ad87f 100644 --- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/ExceptionToResponseConverter.java +++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/ExceptionToResponseConverter.java @@ -22,5 +22,9 @@ public interface ExceptionToResponseConverter { Class getExceptionClass(); + default int getOrder() { + return 0; + } + Response convert(SwaggerInvocation swaggerInvocation, T e); } diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/ExceptionToResponseConverters.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/ExceptionToResponseConverters.java index bc2ea3121..60706a900 100644 --- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/ExceptionToResponseConverters.java +++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/exception/ExceptionToResponseConverters.java @@ -31,7 +31,7 @@ @SuppressWarnings("unchecked") public ExceptionToResponseConverters() { - SPIServiceUtils.getAllService(ExceptionToResponseConverter.class).forEach(converter -> { + SPIServiceUtils.getSortedService(ExceptionToResponseConverter.class).forEach(converter -> { if (converter.getExceptionClass() == null) { defaultConverter = converter; return; diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/extension/ProducerInvokeExtension.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/extension/ProducerInvokeExtension.java new file mode 100644 index 000000000..370b3d192 --- /dev/null +++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/extension/ProducerInvokeExtension.java @@ -0,0 +1,32 @@ +/* + * 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.swagger.invocation.extension; + +import org.apache.servicecomb.swagger.engine.SwaggerProducerOperation; +import org.apache.servicecomb.swagger.invocation.SwaggerInvocation; + +/** + * Producer method invocation extension to handle the required validations/checks before invoking the actual method. + */ +public interface ProducerInvokeExtension { + + public int getOrder(); + + ///Invoked before the method execution to handle the required checks before method invocation. + void beforeMethodInvoke(SwaggerInvocation invocation, SwaggerProducerOperation producerOperation, + Object[] args) throws Exception; +} diff --git a/swagger/swagger-invocation/invocation-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToResponseConverter b/swagger/swagger-invocation/invocation-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToResponseConverter index 2fc781e17..b717491e6 100644 --- a/swagger/swagger-invocation/invocation-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToResponseConverter +++ b/swagger/swagger-invocation/invocation-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToResponseConverter @@ -16,4 +16,4 @@ # org.apache.servicecomb.swagger.invocation.exception.InvocationExceptionToResponseConverter -org.apache.servicecomb.swagger.invocation.exception.DefaultExceptionToResponseConverter \ No newline at end of file +org.apache.servicecomb.swagger.invocation.exception.DefaultExceptionToResponseConverter diff --git a/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/exception/TestExceptionToResponseConverters.java b/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/exception/TestExceptionToResponseConverters.java index 221ae9eb7..022ff8ced 100644 --- a/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/exception/TestExceptionToResponseConverters.java +++ b/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/exception/TestExceptionToResponseConverters.java @@ -38,7 +38,7 @@ public void convertExceptionToResponse(@Mocked ExceptionToResponseConverter c1, @Mocked Response rDef) { new Expectations(SPIServiceUtils.class) { { - SPIServiceUtils.getAllService(ExceptionToResponseConverter.class); + SPIServiceUtils.getSortedService(ExceptionToResponseConverter.class); result = Arrays.asList(c1, c2, cDef); c1.getExceptionClass(); diff --git a/swagger/swagger-invocation/invocation-validator/pom.xml b/swagger/swagger-invocation/invocation-validator/pom.xml new file mode 100644 index 000000000..08b2c0c83 --- /dev/null +++ b/swagger/swagger-invocation/invocation-validator/pom.xml @@ -0,0 +1,52 @@ + + + + 4.0.0 + + org.apache.servicecomb + swagger-invocation + 1.0.0-m2-SNAPSHOT + + swagger-invocation-validator + Java Chassis::Swagger::Invocation::Validator + + + org.apache.servicecomb + swagger-invocation-core + + + org.hibernate + hibernate-validator + + + org.glassfish + javax.el + + + org.slf4j + slf4j-log4j12 + test + + + log4j + log4j + test + + + \ No newline at end of file diff --git a/swagger/swagger-invocation/invocation-validator/src/main/java/org/apache/servicecomb/swagger/invocation/validator/ConstraintViolationExceptionToResponseConverter.java b/swagger/swagger-invocation/invocation-validator/src/main/java/org/apache/servicecomb/swagger/invocation/validator/ConstraintViolationExceptionToResponseConverter.java new file mode 100644 index 000000000..5ade95199 --- /dev/null +++ b/swagger/swagger-invocation/invocation-validator/src/main/java/org/apache/servicecomb/swagger/invocation/validator/ConstraintViolationExceptionToResponseConverter.java @@ -0,0 +1,43 @@ +/* + * 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.swagger.invocation.validator; + +import javax.validation.ConstraintViolationException; +import javax.ws.rs.core.Response.Status; + +import org.apache.servicecomb.swagger.invocation.Response; +import org.apache.servicecomb.swagger.invocation.SwaggerInvocation; +import org.apache.servicecomb.swagger.invocation.exception.ExceptionToResponseConverter; +import org.apache.servicecomb.swagger.invocation.exception.InvocationException; + +public class ConstraintViolationExceptionToResponseConverter + implements ExceptionToResponseConverter { + @Override + public Class getExceptionClass() { + return ConstraintViolationException.class; + } + + @Override + public Response convert(SwaggerInvocation swaggerInvocation, ConstraintViolationException e) { + return Response.createFail(new InvocationException(Status.BAD_REQUEST, e.getConstraintViolations().toString())); + } + + @Override + public int getOrder() { + return -100; + } +} diff --git a/swagger/swagger-invocation/invocation-validator/src/main/java/org/apache/servicecomb/swagger/invocation/validator/ParameterValidator.java b/swagger/swagger-invocation/invocation-validator/src/main/java/org/apache/servicecomb/swagger/invocation/validator/ParameterValidator.java new file mode 100644 index 000000000..0cb42ed58 --- /dev/null +++ b/swagger/swagger-invocation/invocation-validator/src/main/java/org/apache/servicecomb/swagger/invocation/validator/ParameterValidator.java @@ -0,0 +1,65 @@ +/* + * 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.swagger.invocation.validator; + +import java.util.Set; + +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import javax.validation.Validation; +import javax.validation.ValidatorFactory; +import javax.validation.executable.ExecutableValidator; +import javax.validation.groups.Default; + +import org.apache.servicecomb.swagger.engine.SwaggerProducerOperation; +import org.apache.servicecomb.swagger.invocation.SwaggerInvocation; +import org.apache.servicecomb.swagger.invocation.extension.ProducerInvokeExtension; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ParameterValidator implements ProducerInvokeExtension { + + private static final Logger LOGGER = LoggerFactory.getLogger(ParameterValidator.class); + + private static ExecutableValidator executableValidator; + + @Override + public void beforeMethodInvoke(SwaggerInvocation invocation, SwaggerProducerOperation producerOperation, + Object[] args) + throws ConstraintViolationException { + + if (null == executableValidator) { + ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + executableValidator = factory.getValidator().forExecutables(); + } + Set> violations = + executableValidator.validateParameters(producerOperation.getProducerInstance(), + producerOperation.getProducerMethod(), + args, + Default.class); + if (violations.size() > 0) { + LOGGER.warn("Parameter validation failed : " + violations.toString()); + throw new ConstraintViolationException(violations); + } + } + + @Override + public int getOrder() { + return 100; + } + +} diff --git a/swagger/swagger-invocation/invocation-validator/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToResponseConverter b/swagger/swagger-invocation/invocation-validator/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToResponseConverter new file mode 100644 index 000000000..9667b7a6b --- /dev/null +++ b/swagger/swagger-invocation/invocation-validator/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToResponseConverter @@ -0,0 +1,18 @@ +# +# 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. +# + +org.apache.servicecomb.swagger.invocation.validator.ConstraintViolationExceptionToResponseConverter \ No newline at end of file diff --git a/swagger/swagger-invocation/invocation-validator/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.extension.ProducerInvokeExtension b/swagger/swagger-invocation/invocation-validator/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.extension.ProducerInvokeExtension new file mode 100644 index 000000000..215fc5692 --- /dev/null +++ b/swagger/swagger-invocation/invocation-validator/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.extension.ProducerInvokeExtension @@ -0,0 +1,18 @@ +# +# 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. +# + +org.apache.servicecomb.swagger.invocation.validator.ParameterValidator diff --git a/swagger/swagger-invocation/pom.xml b/swagger/swagger-invocation/pom.xml index b22339c29..515db2c5a 100644 --- a/swagger/swagger-invocation/pom.xml +++ b/swagger/swagger-invocation/pom.xml @@ -30,5 +30,6 @@ invocation-core invocation-jaxrs invocation-springmvc + invocation-validator ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: users@infra.apache.org With regards, Apache Git Services