Repository: tomee
Updated Branches:
  refs/heads/master 1c961beea -> 7f1ee68c3


TOMEE-1727 caching getSingletons and getClasses calls for jaxrs


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/84ede0f2
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/84ede0f2
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/84ede0f2

Branch: refs/heads/master
Commit: 84ede0f229433d9f8f74a10dcaba7a69afdf12b5
Parents: 1c961be
Author: Romain manni-Bucau <rmannibu...@gmail.com>
Authored: Tue Mar 8 21:40:40 2016 +0100
Committer: Romain manni-Bucau <rmannibu...@gmail.com>
Committed: Tue Mar 8 21:40:40 2016 +0100

----------------------------------------------------------------------
 .../server/cxf/rs/CxfRsHttpListener.java        | 68 ++++++++---------
 .../server/cxf/rs/SingletonProviderTest.java    | 79 ++++++++++++++++++++
 .../server/rest/InternalApplication.java        |  4 +
 .../apache/openejb/server/rest/RESTService.java | 15 ++--
 4 files changed, 126 insertions(+), 40 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/84ede0f2/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 77a6dd2..1a8d95e 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
@@ -41,8 +41,6 @@ import org.apache.cxf.message.Message;
 import org.apache.cxf.service.invoker.Invoker;
 import org.apache.cxf.transport.DestinationFactory;
 import org.apache.cxf.transport.servlet.BaseUrlHelper;
-import org.apache.johnzon.jaxrs.ConfigurableJohnzonProvider;
-import org.apache.johnzon.jaxrs.JohnzonProvider;
 import org.apache.johnzon.jaxrs.WadlDocumentMessageBodyWriter;
 import org.apache.openejb.AppContext;
 import org.apache.openejb.BeanContext;
@@ -83,6 +81,24 @@ import org.apache.webbeans.config.WebBeansContext;
 import org.apache.webbeans.container.BeanManagerImpl;
 import org.apache.webbeans.context.creational.CreationalContextImpl;
 
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.management.ObjectName;
+import javax.management.openmbean.TabularData;
+import javax.naming.Context;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.ConstrainedTo;
+import javax.ws.rs.RuntimeType;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Configuration;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.MessageBodyWriter;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
@@ -107,24 +123,6 @@ import java.util.Set;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.logging.Level;
 import java.util.regex.Pattern;
-import javax.enterprise.context.spi.CreationalContext;
-import javax.enterprise.inject.spi.Bean;
-import javax.management.ObjectName;
-import javax.management.openmbean.TabularData;
-import javax.naming.Context;
-import javax.servlet.ServletException;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.ServletRequest;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
-import javax.servlet.http.HttpServletResponse;
-import javax.ws.rs.ConstrainedTo;
-import javax.ws.rs.RuntimeType;
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.Configuration;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.ext.MessageBodyReader;
-import javax.ws.rs.ext.MessageBodyWriter;
 
 import static java.util.Arrays.asList;
 import static org.apache.openejb.loader.JarLocation.jarLocation;
@@ -146,7 +144,7 @@ public class CxfRsHttpListener implements RsHttpListener {
     private static final boolean FAIL_ON_CONSTRAINED_TO = 
"true".equalsIgnoreCase(SystemInstance.get().getProperty("openejb.jaxrs.fail-on-constrainedto",
 "true"));
 
     private static final Map<String, String> STATIC_CONTENT_TYPES;
-    private static final String[] DEFAULT_WELCOME_FILES = new String[]{ 
"/index.html", "/index.htm" };
+    private static final String[] DEFAULT_WELCOME_FILES = new 
String[]{"/index.html", "/index.htm"};
 
     private final DestinationFactory transportFactory;
     private final String wildcard;
@@ -159,7 +157,7 @@ public class CxfRsHttpListener implements RsHttpListener {
     private final Collection<CreationalContext<?>> toRelease = new 
LinkedHashSet<>();
     private final Collection<CdiSingletonResourceProvider> singletons = new 
LinkedHashSet<>();
 
-    private static final char[] URL_SEP = new char[] { '?', '#', ';' };
+    private static final char[] URL_SEP = new char[]{'?', '#', ';'};
 
     static {
         STATIC_CONTENT_TYPES = new HashMap<>();
@@ -473,7 +471,7 @@ public class CxfRsHttpListener implements RsHttpListener {
 
     private static boolean shouldSkipProvider(final String name) {
         return "false".equalsIgnoreCase(SystemInstance.get().getProperty(name 
+ ".activated", "true"))
-                || name.startsWith("org.apache.wink.common.internal.");
+            || name.startsWith("org.apache.wink.common.internal.");
     }
 
     private static void addMandatoryProviders(final Collection<Object> 
instances) {
@@ -556,7 +554,7 @@ public class CxfRsHttpListener implements RsHttpListener {
                         factory.setResourceProvider(clazz, new 
NoopResourceProvider(restServiceInfo.context.getBeanClass(), proxy));
                     } else {
                         factory.setResourceProvider(clazz, new 
OpenEJBPerRequestPojoResourceProvider(
-                                classLoader, clazz, injections, context, 
owbCtx));
+                            classLoader, clazz, injections, context, owbCtx));
                     }
                 }
             }
@@ -572,7 +570,7 @@ public class CxfRsHttpListener implements RsHttpListener {
                         final Object proxy = 
ProxyEJB.subclassProxy(restServiceInfo.context);
                         factory.setResourceProvider(clazz, new 
NoopResourceProvider(restServiceInfo.context.getBeanClass(), proxy));
                     } else {
-                        if (owbCtx.getBeanManagerImpl().isInUse()) {
+                        if (owbCtx != null && 
owbCtx.getBeanManagerImpl().isInUse()) {
                             final CdiSingletonResourceProvider provider = new 
CdiSingletonResourceProvider(classLoader, clazz, o, injections, context, 
owbCtx);
                             singletons.add(provider);
                             factory.setResourceProvider(clazz, provider);
@@ -778,7 +776,9 @@ public class CxfRsHttpListener implements RsHttpListener {
 
         // effective logging
 
-        LOGGER.info("REST Application: " + Logs.forceLength(prefix, 
addressSize, true) + " -> " + application.getClass().getName());
+        LOGGER.info("REST Application: " + Logs.forceLength(prefix, 
addressSize, true) + " -> " +
+            (InternalApplication.class.isInstance(application) && 
InternalApplication.class.cast(application).getOriginal() != null ?
+            InternalApplication.class.cast(application).getOriginal() : 
application));
 
         Collections.sort(resourcesToLog);
 
@@ -924,7 +924,7 @@ public class CxfRsHttpListener implements RsHttpListener {
         }
 
         SystemInstance.get().fireEvent(new ExtensionProviderRegistration(
-                
AppFinder.findAppContextOrWeb(Thread.currentThread().getContextClassLoader(), 
AppFinder.AppContextTransformer.INSTANCE), providers));
+            
AppFinder.findAppContextOrWeb(Thread.currentThread().getContextClassLoader(), 
AppFinder.AppContextTransformer.INSTANCE), providers));
 
         if (!providers.isEmpty()) {
             factory.setProviders(providers);
@@ -934,7 +934,7 @@ public class CxfRsHttpListener implements RsHttpListener {
     private Comparator<?> findProviderComparator(final ServiceConfiguration 
serviceConfiguration, final WebBeansContext ctx) {
         final String comparatorKey = CXF_JAXRS_PREFIX + "provider-comparator";
         final String comparatorClass = serviceConfiguration.getProperties()
-                                           .getProperty(comparatorKey, 
SystemInstance.get().getProperty(comparatorKey));
+            .getProperty(comparatorKey, 
SystemInstance.get().getProperty(comparatorKey));
 
         Comparator<Object> comparator = null;
         if (comparatorClass == null) {
@@ -1026,8 +1026,8 @@ public class CxfRsHttpListener implements RsHttpListener {
             final boolean loadersNotNull = classLoader1 != null && 
classLoader2 != null;
 
             if (classLoader1 != classLoader2
-                    && loadersNotNull
-                    && !classLoader1.equals(classLoader2) && 
!classLoader2.equals(classLoader1)) {
+                && loadersNotNull
+                && !classLoader1.equals(classLoader2) && 
!classLoader2.equals(classLoader1)) {
                 if (isParent(classLoader1, classLoader2)) {
                     return 1;
                 }
@@ -1042,9 +1042,9 @@ public class CxfRsHttpListener implements RsHttpListener {
 
                 if (MessageBodyWriter.class.isInstance(o1.getProvider())) {
                     final List<MediaType> types1 =
-                            
JAXRSUtils.sortMediaTypes(JAXRSUtils.getProviderProduceTypes(MessageBodyWriter.class.cast(o1.getProvider())),
 JAXRSUtils.MEDIA_TYPE_QS_PARAM);
+                        
JAXRSUtils.sortMediaTypes(JAXRSUtils.getProviderProduceTypes(MessageBodyWriter.class.cast(o1.getProvider())),
 JAXRSUtils.MEDIA_TYPE_QS_PARAM);
                     final List<MediaType> types2 =
-                            
JAXRSUtils.sortMediaTypes(JAXRSUtils.getProviderProduceTypes(MessageBodyWriter.class.cast(o2.getProvider())),
 JAXRSUtils.MEDIA_TYPE_QS_PARAM);
+                        
JAXRSUtils.sortMediaTypes(JAXRSUtils.getProviderProduceTypes(MessageBodyWriter.class.cast(o2.getProvider())),
 JAXRSUtils.MEDIA_TYPE_QS_PARAM);
 
                     if (types1.contains(MediaType.WILDCARD_TYPE) && 
!types2.contains(MediaType.WILDCARD_TYPE)) {
                         return 1;
@@ -1059,9 +1059,9 @@ public class CxfRsHttpListener implements RsHttpListener {
                     }
                 } else if 
(MessageBodyReader.class.isInstance(o1.getProvider())) { // else is not super 
good but using both is not sa well so let it be for now
                     final List<MediaType> types1 =
-                            
JAXRSUtils.sortMediaTypes(JAXRSUtils.getProviderConsumeTypes(MessageBodyReader.class.cast(o1.getProvider())),
 null);
+                        
JAXRSUtils.sortMediaTypes(JAXRSUtils.getProviderConsumeTypes(MessageBodyReader.class.cast(o1.getProvider())),
 null);
                     final List<MediaType> types2 =
-                            
JAXRSUtils.sortMediaTypes(JAXRSUtils.getProviderConsumeTypes(MessageBodyReader.class.cast(o2.getProvider())),
 null);
+                        
JAXRSUtils.sortMediaTypes(JAXRSUtils.getProviderConsumeTypes(MessageBodyReader.class.cast(o2.getProvider())),
 null);
 
                     if (types1.contains(MediaType.WILDCARD_TYPE) && 
!types2.contains(MediaType.WILDCARD_TYPE)) {
                         return 1;

http://git-wip-us.apache.org/repos/asf/tomee/blob/84ede0f2/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SingletonProviderTest.java
----------------------------------------------------------------------
diff --git 
a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SingletonProviderTest.java
 
b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SingletonProviderTest.java
new file mode 100644
index 0000000..0f7ad6e
--- /dev/null
+++ 
b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SingletonProviderTest.java
@@ -0,0 +1,79 @@
+/*
+ *     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.EnableServices;
+import org.apache.openejb.testing.RandomPort;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+
+@EnableServices("jax-rs")
+@Classes(value = SingletonProviderTest.ApplicationSample.class, context = 
"app")
+@RunWith(ApplicationComposer.class)
+public class SingletonProviderTest {
+    @RandomPort("http")
+    private URL base;
+
+    @Test
+    public void check() throws Exception {
+        final HttpURLConnection conn = HttpURLConnection.class.cast(new 
URL(base.toExternalForm() + "app/need-provider").openConnection());
+        assertEquals("ok", IO.slurp(conn.getInputStream()));
+        conn.getInputStream().close();
+    }
+
+    @Path("need-provider")
+    public static class NeedAProvider {
+        @GET
+        public String providers() {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    @Provider
+    public static class DontLetResourcesFail implements 
ExceptionMapper<IllegalArgumentException> {
+        @Override
+        public Response toResponse(final IllegalArgumentException throwable) {
+            return Response.ok("ok").build();
+        }
+    }
+
+    public static class ApplicationSample extends Application {
+        @Override
+        public Set<Object> getSingletons() {
+            return new HashSet<Object>() {{
+                add(new NeedAProvider());
+                add(new DontLetResourcesFail());
+            }};
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/84ede0f2/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/InternalApplication.java
----------------------------------------------------------------------
diff --git 
a/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/InternalApplication.java
 
b/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/InternalApplication.java
index cb36fda..04a8cbd 100644
--- 
a/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/InternalApplication.java
+++ 
b/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/InternalApplication.java
@@ -27,6 +27,10 @@ public class InternalApplication extends Application {
 
     public InternalApplication(final Application original) {
         this.original = original;
+        if (original != null) {
+            singletons.addAll(original.getSingletons());
+            classes.addAll(original.getClasses());
+        }
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/tomee/blob/84ede0f2/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/RESTService.java
----------------------------------------------------------------------
diff --git 
a/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/RESTService.java
 
b/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/RESTService.java
index fc28001..d7ac5e5 100644
--- 
a/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/RESTService.java
+++ 
b/server/openejb-rest/src/main/java/org/apache/openejb/server/rest/RESTService.java
@@ -51,6 +51,12 @@ import org.apache.openejb.util.Logger;
 import org.apache.webbeans.config.WebBeansContext;
 import org.apache.xbean.finder.MetaAnnotatedClass;
 
+import javax.naming.Context;
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.ext.Provider;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -67,12 +73,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
-import javax.naming.Context;
-import javax.ws.rs.ApplicationPath;
-import javax.ws.rs.Path;
-import javax.ws.rs.core.Application;
-import javax.ws.rs.core.UriBuilder;
-import javax.ws.rs.ext.Provider;
 
 @SuppressWarnings("UnusedDeclaration")
 public abstract class RESTService implements ServerService, SelfManaging {
@@ -155,6 +155,9 @@ public abstract class RESTService implements ServerService, 
SelfManaging {
                         throw new OpenEJBRestRuntimeException("can't create 
class " + app, e);
                     }
 
+                    application = 
"true".equalsIgnoreCase(appInfo.properties.getProperty("openejb.cxf-rs.cache-application",
 "true"))
+                        ? new InternalApplication(application) /* caches 
singletons and classes */ : application;
+
                     final Set<Class<?>> classes = new 
HashSet<>(application.getClasses());
                     final Set<Object> singletons = application.getSingletons();
 

Reply via email to