Repository: cxf Updated Branches: refs/heads/3.1.x-fixes 1770c6f6c -> 1dea643ba
[CXF-6706] Make use of the support code in the ServiceMix hibernate bundle, plus add some tccl management to the BeanValidationProvider, to get BeanValidation to work with OSGi. Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/1dea643b Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/1dea643b Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/1dea643b Branch: refs/heads/3.1.x-fixes Commit: 1dea643baf6193e9a94abe8b1900c139bf273121 Parents: 1770c6f Author: Benson Margulies <[email protected]> Authored: Mon Dec 14 12:58:47 2015 -0500 Committer: Benson Margulies <[email protected]> Committed: Mon Dec 14 12:58:47 2015 -0500 ---------------------------------------------------------------------- .../cxf/validation/BeanValidationProvider.java | 24 ++++++++++-- osgi/itests/pom.xml | 12 ++++++ .../cxf/osgi/itests/CXFOSGiTestSupport.java | 7 ++-- .../org/apache/cxf/osgi/itests/jaxrs/Book.java | 4 ++ .../apache/cxf/osgi/itests/jaxrs/BookStore.java | 40 ++++++++++++++++++++ .../cxf/osgi/itests/jaxrs/JaxRsServiceTest.java | 22 ++++++++++- .../features/src/main/resources/features.xml | 4 ++ parent/pom.xml | 2 +- 8 files changed, 107 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/1dea643b/core/src/main/java/org/apache/cxf/validation/BeanValidationProvider.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/cxf/validation/BeanValidationProvider.java b/core/src/main/java/org/apache/cxf/validation/BeanValidationProvider.java index 2efc7a1..31e12e1 100644 --- a/core/src/main/java/org/apache/cxf/validation/BeanValidationProvider.java +++ b/core/src/main/java/org/apache/cxf/validation/BeanValidationProvider.java @@ -39,6 +39,7 @@ public class BeanValidationProvider { private static final Logger LOG = LogUtils.getL7dLogger(BeanValidationProvider.class); private final ValidatorFactory factory; + private ClassLoader validateContextClassloader; public BeanValidationProvider() { try { @@ -80,7 +81,7 @@ public class BeanValidationProvider { Class<javax.validation.spi.ValidationProvider<T>> providerType) { this(resolver, providerType, null); } - + public <T extends Configuration<T>> BeanValidationProvider( ValidationProviderResolver resolver, Class<javax.validation.spi.ValidationProvider<T>> providerType, @@ -96,7 +97,15 @@ public class BeanValidationProvider { throw ex; } } - + + public ClassLoader getValidateContextClassloader() { + return validateContextClassloader; + } + + public void setValidateContextClassloader(ClassLoader validateContextClassloader) { + this.validateContextClassloader = validateContextClassloader; + } + private static void initFactoryConfig(Configuration<?> factoryCfg, ValidationConfiguration cfg) { if (cfg != null) { factoryCfg.parameterNameProvider(cfg.getParameterNameProvider()); @@ -145,7 +154,16 @@ public class BeanValidationProvider { } private< T > Set<ConstraintViolation< T > > doValidateBean(final T bean) { - return factory.getValidator().validate(bean); + ClassLoader oldTccl = Thread.currentThread().getContextClassLoader(); + try { + // In OSGi, hibernate's hunt for an EL provided can fail without this. + if (validateContextClassloader != null) { + Thread.currentThread().setContextClassLoader(validateContextClassloader); + } + return factory.getValidator().validate(bean); + } finally { + Thread.currentThread().setContextClassLoader(oldTccl); + } } private ExecutableValidator getExecutableValidator() { http://git-wip-us.apache.org/repos/asf/cxf/blob/1dea643b/osgi/itests/pom.xml ---------------------------------------------------------------------- diff --git a/osgi/itests/pom.xml b/osgi/itests/pom.xml index 9ddf1fd..9d62eff 100644 --- a/osgi/itests/pom.xml +++ b/osgi/itests/pom.xml @@ -91,6 +91,18 @@ <version>${cxf.karaf.version}</version> </dependency> <dependency> + <groupId>org.apache.servicemix.specs</groupId> + <artifactId>org.apache.servicemix.specs.jsr303-api-1.1.0</artifactId> + <version>${cxf.servicemix.specs.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.servicemix.bundles</groupId> + <artifactId>org.apache.servicemix.bundles.hibernate-validator</artifactId> + <version>5.0.2.Final_1</version> + <scope>provided</scope> + </dependency> + <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.core</artifactId> </dependency> http://git-wip-us.apache.org/repos/asf/cxf/blob/1dea643b/osgi/itests/src/test/java/org/apache/cxf/osgi/itests/CXFOSGiTestSupport.java ---------------------------------------------------------------------- diff --git a/osgi/itests/src/test/java/org/apache/cxf/osgi/itests/CXFOSGiTestSupport.java b/osgi/itests/src/test/java/org/apache/cxf/osgi/itests/CXFOSGiTestSupport.java index 138b996..812eb18 100644 --- a/osgi/itests/src/test/java/org/apache/cxf/osgi/itests/CXFOSGiTestSupport.java +++ b/osgi/itests/src/test/java/org/apache/cxf/osgi/itests/CXFOSGiTestSupport.java @@ -138,9 +138,10 @@ public class CXFOSGiTestSupport { .name("Apache Karaf") .useDeployFolder(false) .unpackDirectory(new File("target/paxexam/")), - //DO NOT COMMIT WITH THIS LINE ENABLED!!! - //KarafDistributionOption.keepRuntimeFolder(), - systemProperty("java.awt.headless").value("true"), + //DO NOT COMMIT WITH THIS LINE ENABLED!!! + //KarafDistributionOption.keepRuntimeFolder(), + //debugConfiguration(), // nor this + systemProperty("java.awt.headless").value("true"), when(localRepo != null) .useOptions(editConfigurationFilePut("etc/org.ops4j.pax.url.mvn.cfg", "org.ops4j.pax.url.mvn.localRepository", http://git-wip-us.apache.org/repos/asf/cxf/blob/1dea643b/osgi/itests/src/test/java/org/apache/cxf/osgi/itests/jaxrs/Book.java ---------------------------------------------------------------------- diff --git a/osgi/itests/src/test/java/org/apache/cxf/osgi/itests/jaxrs/Book.java b/osgi/itests/src/test/java/org/apache/cxf/osgi/itests/jaxrs/Book.java index a244633..10bab48 100644 --- a/osgi/itests/src/test/java/org/apache/cxf/osgi/itests/jaxrs/Book.java +++ b/osgi/itests/src/test/java/org/apache/cxf/osgi/itests/jaxrs/Book.java @@ -19,11 +19,15 @@ package org.apache.cxf.osgi.itests.jaxrs; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "Book") public class Book { + @NotNull private String name; + @Min(0) private long id; public Book() { http://git-wip-us.apache.org/repos/asf/cxf/blob/1dea643b/osgi/itests/src/test/java/org/apache/cxf/osgi/itests/jaxrs/BookStore.java ---------------------------------------------------------------------- diff --git a/osgi/itests/src/test/java/org/apache/cxf/osgi/itests/jaxrs/BookStore.java b/osgi/itests/src/test/java/org/apache/cxf/osgi/itests/jaxrs/BookStore.java index 416c341..ebe3a02 100644 --- a/osgi/itests/src/test/java/org/apache/cxf/osgi/itests/jaxrs/BookStore.java +++ b/osgi/itests/src/test/java/org/apache/cxf/osgi/itests/jaxrs/BookStore.java @@ -24,6 +24,10 @@ import java.net.URI; import java.util.HashMap; import java.util.Map; +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import javax.validation.Validation; +import javax.validation.ValidatorFactory; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; @@ -40,6 +44,10 @@ import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriInfo; +import org.apache.cxf.validation.BeanValidationProvider; +import org.hibernate.validator.HibernateValidator; +import org.hibernate.validator.HibernateValidatorConfiguration; + @Path("/bookstore") @Produces("application/xml") public class BookStore { @@ -84,6 +92,38 @@ public class BookStore { return Response.ok().build(); } } + + @POST + @Path("/books-validate") + public Response createBookValidate(Book book) { + assertInjections(); + BeanValidationProvider prov; + ClassLoader oldtccl = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(HibernateValidator.class.getClassLoader()); + HibernateValidatorConfiguration configuration = + Validation.byProvider(HibernateValidator.class) + .configure(); + ValidatorFactory factory = configuration.buildValidatorFactory(); + prov = new BeanValidationProvider(factory); + } finally { + Thread.currentThread().setContextClassLoader(oldtccl); + } + prov.setValidateContextClassloader(getClass().getClassLoader()); + try { + prov.validateBean(book); + } catch (ConstraintViolationException cve) { + StringBuilder violationMessages = new StringBuilder(); + for (ConstraintViolation<?> constraintViolation : cve.getConstraintViolations()) { + violationMessages.append(constraintViolation.getPropertyPath()) + .append(": ").append(constraintViolation.getMessage()).append("\n"); + } + return Response.status(Response.Status.BAD_REQUEST).type("text/plain") + .entity(violationMessages.toString()).build(); + } + return createBook(book); + } + @POST @Path("/books") http://git-wip-us.apache.org/repos/asf/cxf/blob/1dea643b/osgi/itests/src/test/java/org/apache/cxf/osgi/itests/jaxrs/JaxRsServiceTest.java ---------------------------------------------------------------------- diff --git a/osgi/itests/src/test/java/org/apache/cxf/osgi/itests/jaxrs/JaxRsServiceTest.java b/osgi/itests/src/test/java/org/apache/cxf/osgi/itests/jaxrs/JaxRsServiceTest.java index 9be4b45..dab117b 100644 --- a/osgi/itests/src/test/java/org/apache/cxf/osgi/itests/jaxrs/JaxRsServiceTest.java +++ b/osgi/itests/src/test/java/org/apache/cxf/osgi/itests/jaxrs/JaxRsServiceTest.java @@ -73,6 +73,23 @@ public class JaxRsServiceTest extends CXFOSGiTestSupport { Assert.assertNotNull(response.getLocation()); } + //@Ignore("this passes with Karaf 4, but not with the test rig here.") + @Test + public void postWithValidation() throws Exception { + Book book = new Book(); + book.setId(-1); + book.setName(null); + Response response = wt.path("/books-validate/").request("application/xml").post(Entity.xml(book)); + Assert.assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus()); + + book = new Book(); + book.setId(3212); + book.setName("A Book"); + response = wt.path("/books-validate/").request("application/xml").post(Entity.xml(book)); + Assert.assertEquals(Status.CREATED.getStatusCode(), response.getStatus()); + Assert.assertNotNull(response.getLocation()); + } + @Test public void testJaxRsDelete() throws Exception { Response response = wt.path("/books/123").request("application/xml").delete(); @@ -93,7 +110,9 @@ public class JaxRsServiceTest extends CXFOSGiTestSupport { public Option[] config() { return new Option[] { cxfBaseConfig(), - features(cxfUrl, "cxf-core", "cxf-wsdl", "cxf-jaxrs", "http"), + features(cxfUrl, "cxf-core", "cxf-wsdl", "cxf-jaxrs", "http", + "cxf-bean-validation-core", + "cxf-bean-validation"), testUtils(), logLevel(LogLevel.INFO), provision(serviceBundle()) @@ -102,6 +121,7 @@ public class JaxRsServiceTest extends CXFOSGiTestSupport { private InputStream serviceBundle() { return TinyBundles.bundle() + .set(Constants.DYNAMICIMPORT_PACKAGE, "*") .add(JaxRsTestActivator.class) .add(Book.class) .add(BookStore.class) http://git-wip-us.apache.org/repos/asf/cxf/blob/1dea643b/osgi/karaf/features/src/main/resources/features.xml ---------------------------------------------------------------------- diff --git a/osgi/karaf/features/src/main/resources/features.xml b/osgi/karaf/features/src/main/resources/features.xml index ebd32d1..2312881 100644 --- a/osgi/karaf/features/src/main/resources/features.xml +++ b/osgi/karaf/features/src/main/resources/features.xml @@ -441,6 +441,8 @@ </feature> <feature name="cxf-bean-validation-core" version="${project.version}" resolver="(obr)"> + <!-- This feature has the wrong name; it's hibernate-only. Fix up in 3.2.0? Move all this to the + hibernate-bean-validation-helper feature --> <bundle start-level="10" dependency="true">mvn:org.apache.servicemix.specs/org.apache.servicemix.specs.jsr303-api-${cxf.osgi.validation.api.version}/${cxf.servicemix.specs.version}</bundle> <bundle start-level="30" dependency="true">mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.hibernate-validator/${cxf.hibernate-validator.bundle.version}</bundle> <!-- The hibernate bundle demands 1.1.0 of javax.validator, but servicemix only provides 1.0.0. So @@ -461,6 +463,8 @@ <bundle start-level="30" dependency="true">mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.cglib/${cxf.servicemix.cglib.version}</bundle> <bundle start-level="30" dependency="true">mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.aspectj/${cxf.servicemix.aspectj.version}</bundle> </feature> + + <feature name="cxf-bean-validation" version="${project.version}" resolver="(obr)"> <feature version="${project.version}">cxf-bean-validation-core</feature> http://git-wip-us.apache.org/repos/asf/cxf/blob/1dea643b/parent/pom.xml ---------------------------------------------------------------------- diff --git a/parent/pom.xml b/parent/pom.xml index f417940..52c225b 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -177,7 +177,7 @@ <cxf.osgi.version>4.2.0</cxf.osgi.version> <cxf.karaf.version>3.0.2</cxf.karaf.version> <cxf.pax.logging.version>1.6.0</cxf.pax.logging.version> - <cxf.pax.exam.version>4.5.0</cxf.pax.exam.version> + <cxf.pax.exam.version>4.7.0</cxf.pax.exam.version> <cxf.felix.framework.version>2.0.5</cxf.felix.framework.version> <cxf.felix.configadmin.version>1.2.4</cxf.felix.configadmin.version> <cxf.xmlbeans.bundle.version>2.6.0_2</cxf.xmlbeans.bundle.version>
