Repository: tomee Updated Branches: refs/heads/master 5182e7262 -> 0b8ba1814
TOMEE-1981 propagating <name>.activated config to client default jaxrs provider, thanks Robert Panzer for the patch Project: http://git-wip-us.apache.org/repos/asf/tomee/repo Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/0b8ba181 Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/0b8ba181 Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/0b8ba181 Branch: refs/heads/master Commit: 0b8ba18148ac86ec22ed352def3e570fe887b377 Parents: 5182e72 Author: rmannibucau <[email protected]> Authored: Thu Dec 8 08:53:01 2016 +0100 Committer: rmannibucau <[email protected]> Committed: Thu Dec 8 08:53:01 2016 +0100 ---------------------------------------------------------------------- .../openejb/server/cxf/rs/CxfRSService.java | 82 +++++-------- .../server/cxf/rs/CxfRsHttpListener.java | 11 +- .../cxf/rs/johnzon/TomEEJohnzonProvider.java | 52 +++++++++ .../cxf/rs/johnzon/TomEEJsonpProvider.java | 45 +++++++ .../server/cxf/rs/DisableTomEEJohnzonTest.java | 117 +++++++++++++++++++ 5 files changed, 247 insertions(+), 60 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/0b8ba181/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRSService.java ---------------------------------------------------------------------- diff --git a/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRSService.java b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRSService.java index 020d7c1..31bd2e0 100644 --- a/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRSService.java +++ b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRSService.java @@ -21,9 +21,6 @@ import org.apache.cxf.binding.BindingFactoryManager; import org.apache.cxf.jaxrs.JAXRSBindingFactory; import org.apache.cxf.transport.DestinationFactory; import org.apache.cxf.transport.http.HTTPTransportFactory; -import org.apache.johnzon.jaxrs.JohnzonProvider; -import org.apache.johnzon.jaxrs.JsrProvider; -import org.apache.johnzon.mapper.MapperBuilder; import org.apache.openejb.cdi.WebBeansContextBeforeDeploy; import org.apache.openejb.loader.SystemInstance; import org.apache.openejb.observer.Observes; @@ -46,32 +43,24 @@ import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.InjectionPoint; import javax.enterprise.inject.spi.PassivationCapable; import javax.enterprise.util.AnnotationLiteral; -import javax.json.JsonStructure; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.Consumes; -import javax.ws.rs.Produces; import javax.ws.rs.container.ResourceContext; import javax.ws.rs.container.ResourceInfo; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Request; -import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; -import javax.ws.rs.core.StreamingOutput; import javax.ws.rs.core.UriInfo; import javax.ws.rs.ext.ContextResolver; -import javax.ws.rs.ext.Provider; import javax.ws.rs.ext.Providers; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Serializable; -import java.io.Writer; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; @@ -80,6 +69,7 @@ import java.lang.reflect.Proxy; import java.lang.reflect.Type; import java.net.Socket; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -93,6 +83,7 @@ public class CxfRSService extends RESTService { private static final String NAME = "cxf-rs"; private DestinationFactory destinationFactory; private boolean factoryByListener; + private Properties config; @Override public void service(final InputStream in, final OutputStream out) throws ServiceException, IOException { @@ -171,6 +162,7 @@ public class CxfRSService extends RESTService { @Override public void init(final Properties properties) throws Exception { super.init(properties); + config = properties; factoryByListener = "true".equalsIgnoreCase(properties.getProperty("openejb.cxf-rs.factoryByListener", "false")); System.setProperty("org.apache.johnzon.max-string-length", @@ -230,16 +222,27 @@ public class CxfRSService extends RESTService { if (bus.getProperty("org.apache.cxf.jaxrs.bus.providers") == null) { bus.setProperty("skip.default.json.provider.registration", "true"); // client jaxrs, we want johnzon not jettison + final Collection<Object> defaults = new ArrayList<>(); + for (final String provider : asList( + "org.apache.openejb.server.cxf.rs.johnzon.TomEEJohnzonProvider", + "org.apache.openejb.server.cxf.rs.johnzon.TomEEJsonpProvider")) { + if (!isActive(provider)) { + continue; + } + try { + defaults.add(Class.forName(provider, true, CxfRSService.class.getClassLoader()).newInstance()); + } catch (final Exception e) { + // no-op + } + } + try { final List<Object> all; final String userProviders = SystemInstance.get().getProperty("openejb.jaxrs.client.providers"); if (userProviders == null) { - (all = new ArrayList<>(2)).addAll(asList( - new TomEEJohnzonProvider<>(), - new TomEEJsonpProvider() - )); + (all = new ArrayList<>(defaults.size())).addAll(defaults); } else { - all = new ArrayList<>(4 /* blind guess */); + all = new ArrayList<>(defaults.size() + 2 /* blind guess */); for (String p : userProviders.split(" *, *")) { p = p.trim(); if (p.isEmpty()) { @@ -249,9 +252,8 @@ public class CxfRSService extends RESTService { all.add(Thread.currentThread().getContextClassLoader().loadClass(p).newInstance()); } - all.addAll(asList( // added after to be after in the list once sorted - new TomEEJohnzonProvider<>(), - new TomEEJsonpProvider())); + // added after to be after in the list once sorted + all.addAll(defaults); } bus.setProperty("org.apache.cxf.jaxrs.bus.providers", all); } catch (final Exception e) { @@ -291,7 +293,12 @@ public class CxfRSService extends RESTService { @Override protected RsHttpListener createHttpListener() { - return new CxfRsHttpListener(!factoryByListener ? destinationFactory : new HTTPTransportFactory(), getWildcard()); + return new CxfRsHttpListener(!factoryByListener ? destinationFactory : new HTTPTransportFactory(), getWildcard(), this); + } + + public boolean isActive(final String name) { + final String key = name + ".activated"; + return "true".equalsIgnoreCase(SystemInstance.get().getProperty(key, config.getProperty(key, "true"))); } private static class ContextLiteral extends EmptyAnnotationLiteral<Context> implements Context { @@ -393,39 +400,4 @@ public class CxfRSService extends RESTService { } } } - - @Provider - @Produces({"application/json", "application/*+json"}) - @Consumes({"application/json", "application/*+json"}) - public static class TomEEJohnzonProvider<T> extends JohnzonProvider<T> { - public TomEEJohnzonProvider() { - super(new MapperBuilder().setAccessModeName("both").build(), null); - } - - @Override - public boolean isWriteable(final Class<?> rawType, final Type genericType, - final Annotation[] annotations, final MediaType mediaType) { - return super.isWriteable(rawType, genericType, annotations, mediaType) - && !OutputStream.class.isAssignableFrom(rawType) - && !StreamingOutput.class.isAssignableFrom(rawType) - && !Writer.class.isAssignableFrom(rawType) - && !Response.class.isAssignableFrom(rawType) - && !JsonStructure.class.isAssignableFrom(rawType); - } - } - - @Provider - @Produces({"application/json", "application/*+json"}) - @Consumes({"application/json", "application/*+json"}) - public static class TomEEJsonpProvider extends JsrProvider { - @Override - public boolean isWriteable(final Class<?> rawType, final Type genericType, - final Annotation[] annotations, final MediaType mediaType) { - return super.isWriteable(rawType, genericType, annotations, mediaType) - && !OutputStream.class.isAssignableFrom(rawType) - && !StreamingOutput.class.isAssignableFrom(rawType) - && !Writer.class.isAssignableFrom(rawType) - && !Response.class.isAssignableFrom(rawType); - } - } } http://git-wip-us.apache.org/repos/asf/tomee/blob/0b8ba181/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java ---------------------------------------------------------------------- diff --git a/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java index 7bede36..e10172f 100644 --- a/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java +++ b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java @@ -164,6 +164,7 @@ public class CxfRsHttpListener implements RsHttpListener { private final DestinationFactory transportFactory; private final String wildcard; + private final CxfRSService service; private HttpDestination destination; private Server server; private String context = ""; @@ -191,9 +192,10 @@ public class CxfRsHttpListener implements RsHttpListener { private String pattern; - public CxfRsHttpListener(final DestinationFactory destinationFactory, final String star) { + public CxfRsHttpListener(final DestinationFactory destinationFactory, final String star, final CxfRSService cxfRSService) { transportFactory = destinationFactory; wildcard = star; + service = cxfRSService; } public void setUrlPattern(final String pattern) { @@ -491,12 +493,11 @@ public class CxfRsHttpListener implements RsHttpListener { return false; } - private static boolean shouldSkipProvider(final String name) { - return "false".equalsIgnoreCase(SystemInstance.get().getProperty(name + ".activated", "true")) - || name.startsWith("org.apache.wink.common.internal."); + private boolean shouldSkipProvider(final String name) { + return !service.isActive(name) || name.startsWith("org.apache.wink.common.internal."); } - private static void addMandatoryProviders(final Collection<Object> instances, final ServiceConfiguration serviceConfiguration) { + private void addMandatoryProviders(final Collection<Object> instances, final ServiceConfiguration serviceConfiguration) { if (!shouldSkipProvider(WadlDocumentMessageBodyWriter.class.getName())) { instances.add(new WadlDocumentMessageBodyWriter()); } http://git-wip-us.apache.org/repos/asf/tomee/blob/0b8ba181/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/johnzon/TomEEJohnzonProvider.java ---------------------------------------------------------------------- diff --git a/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/johnzon/TomEEJohnzonProvider.java b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/johnzon/TomEEJohnzonProvider.java new file mode 100644 index 0000000..4e16e80 --- /dev/null +++ b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/johnzon/TomEEJohnzonProvider.java @@ -0,0 +1,52 @@ +/* + * 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.openejb.server.cxf.rs.johnzon; + +import org.apache.johnzon.jaxrs.JohnzonProvider; +import org.apache.johnzon.mapper.MapperBuilder; + +import javax.json.JsonStructure; +import javax.ws.rs.Consumes; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; +import javax.ws.rs.ext.Provider; +import java.io.OutputStream; +import java.io.Writer; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +@Provider +@Produces({"application/json", "application/*+json"}) +@Consumes({"application/json", "application/*+json"}) +public class TomEEJohnzonProvider<T> extends JohnzonProvider<T> { + public TomEEJohnzonProvider() { + super(new MapperBuilder().setAccessModeName("both").build(), null); + } + + @Override + public boolean isWriteable(final Class<?> rawType, final Type genericType, + final Annotation[] annotations, final MediaType mediaType) { + return super.isWriteable(rawType, genericType, annotations, mediaType) + && !OutputStream.class.isAssignableFrom(rawType) + && !StreamingOutput.class.isAssignableFrom(rawType) + && !Writer.class.isAssignableFrom(rawType) + && !Response.class.isAssignableFrom(rawType) + && !JsonStructure.class.isAssignableFrom(rawType); + } +} http://git-wip-us.apache.org/repos/asf/tomee/blob/0b8ba181/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/johnzon/TomEEJsonpProvider.java ---------------------------------------------------------------------- diff --git a/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/johnzon/TomEEJsonpProvider.java b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/johnzon/TomEEJsonpProvider.java new file mode 100644 index 0000000..472fba8 --- /dev/null +++ b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/johnzon/TomEEJsonpProvider.java @@ -0,0 +1,45 @@ +/* + * 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.openejb.server.cxf.rs.johnzon; + +import org.apache.johnzon.jaxrs.JsrProvider; + +import javax.ws.rs.Consumes; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; +import javax.ws.rs.ext.Provider; +import java.io.OutputStream; +import java.io.Writer; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +@Provider +@Produces({"application/json", "application/*+json"}) +@Consumes({"application/json", "application/*+json"}) +public class TomEEJsonpProvider extends JsrProvider { + @Override + public boolean isWriteable(final Class<?> rawType, final Type genericType, + final Annotation[] annotations, final MediaType mediaType) { + return super.isWriteable(rawType, genericType, annotations, mediaType) + && !OutputStream.class.isAssignableFrom(rawType) + && !StreamingOutput.class.isAssignableFrom(rawType) + && !Writer.class.isAssignableFrom(rawType) + && !Response.class.isAssignableFrom(rawType); + } +} http://git-wip-us.apache.org/repos/asf/tomee/blob/0b8ba181/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/DisableTomEEJohnzonTest.java ---------------------------------------------------------------------- diff --git a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/DisableTomEEJohnzonTest.java b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/DisableTomEEJohnzonTest.java new file mode 100644 index 0000000..c6f0bc1 --- /dev/null +++ b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/DisableTomEEJohnzonTest.java @@ -0,0 +1,117 @@ +/* + * 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.openejb.server.cxf.rs; + +import org.apache.openejb.junit.ApplicationComposer; +import org.apache.openejb.loader.IO; +import org.apache.openejb.testing.Classes; +import org.apache.openejb.testing.ContainerProperties; +import org.apache.openejb.testing.EnableServices; +import org.apache.openejb.testing.JaxrsProviders; +import org.apache.openejb.testing.RandomPort; +import org.junit.Test; +import org.junit.runner.RunWith; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.ext.MessageBodyWriter; +import javax.ws.rs.ext.Provider; +import java.io.IOException; +import java.io.OutputStream; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.net.URL; + +import static javax.ws.rs.client.Entity.entity; +import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; +import static org.junit.Assert.assertEquals; + +@EnableServices("jax-rs") +@Classes(DisableTomEEJohnzonTest.Endpoint.class) +@JaxrsProviders(DisableTomEEJohnzonTest.TestWriter.class) +@ContainerProperties({ + @ContainerProperties.Property(name = "org.apache.openejb.server.cxf.rs.johnzon.TomEEJohnzonProvider.activated", value = "false") +}) +@RunWith(ApplicationComposer.class) +public class DisableTomEEJohnzonTest { + + private static final String PAYLOAD = "{\"not\": \"johnzon\"}"; + + @RandomPort("http") + private URL base; + + @Test + public void server() throws IOException { + assertEquals(PAYLOAD, IO.slurp(new URL(url()))); + } + + @Test + public void client() throws IOException { + assertEquals(PAYLOAD, ClientBuilder.newClient().register(new TestWriter()).target(url()).request().post(entity(new Payload(), APPLICATION_JSON_TYPE), String.class)); + } + + private String url() { + return base.toExternalForm() + "openejb/test"; + } + + @Path("test") + public static class Endpoint { + @GET + @Produces(MediaType.APPLICATION_JSON) + public Payload get() { + return new Payload(); + } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public String post(final String body) { + return body; + } + } + + public static class Payload { + } + + @Provider + @Produces(MediaType.WILDCARD) + public static class TestWriter implements MessageBodyWriter { + @Override + public boolean isWriteable(Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return aClass == Payload.class; + } + + @Override + public long getSize(Object o, Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return -1; + } + + @Override + public void writeTo(Object o, Class aClass, Type type, Annotation[] annotations, MediaType mediaType, + MultivaluedMap multivaluedMap, OutputStream outputStream) throws IOException, WebApplicationException { + outputStream.write(PAYLOAD.getBytes("UTF-8")); + + } + } +} \ No newline at end of file
