You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2018/09/14 09:08:47 UTC

[isis] 02/02: ISIS-1895: fix ResourceServlet not picked up on skinny war deployment

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch ISIS-1976-rethink-object-adapters
in repository https://gitbox.apache.org/repos/asf/isis.git

commit d2ed9af15165e54590658df783a44227ee81abf4
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Sep 14 11:07:37 2018 +0200

    ISIS-1895: fix ResourceServlet not picked up on skinny war deployment
---
 .../core/webapp/content/ResourceCachingFilter.java | 64 +++++-------------
 .../isis/core/webapp/content/ResourceServlet.java  | 11 +--
 .../apache/isis/core/webapp/modules/WebModule.java |  1 +
 .../core/webapp/modules/WebModule_RestEasy.java    | 11 ++-
 .../webapp/modules/WebModule_StaticResources.java  | 79 ++++++++++++++++++++++
 .../IsisTransactionFilterForRestfulObjects.java    |  7 +-
 6 files changed, 116 insertions(+), 57 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/webapp/content/ResourceCachingFilter.java b/core/metamodel/src/main/java/org/apache/isis/core/webapp/content/ResourceCachingFilter.java
index ceb7758..d3f18ef 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/webapp/content/ResourceCachingFilter.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/webapp/content/ResourceCachingFilter.java
@@ -33,18 +33,16 @@ import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
-import javax.servlet.annotation.WebFilter;
-import javax.servlet.annotation.WebInitParam;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.isis.commons.internal.exceptions._Exceptions.FluentException;
-
-@WebFilter(
-        initParams = { @WebInitParam(name = "CacheTime", value = "86400") }, 
-        urlPatterns = { 
-                "*.css", "*.png", "*.jpg", "*.jpeg", "*.gif", "*.svg", "*.js", "*.html", "*.swf" }
-)
+//@WebFilter(
+//        initParams = { @WebInitParam(name = "CacheTime", value = "86400") }, 
+//        urlPatterns = { 
+//                "*.css", "*.png", "*.jpg", "*.jpeg", "*.gif", "*.svg", "*.js", "*.html", "*.swf" }
+//)
+//[ahuber] to support Servlet 3.0 annotations @WebFilter, @WebListener or others 
+//with skinny war deployment requires additional configuration, so for now we disable this annotation
 public class ResourceCachingFilter implements Filter {
 
     /**
@@ -113,7 +111,9 @@ public class ResourceCachingFilter implements Filter {
     private String[][] mReplyHeaders = { {} };
 
     /** The cache time in seconds. */
-    private Long cacheTime = 0L;
+    private long cacheTime = 0L;
+    
+    private final static DateFormat httpDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
 
     /**
      * Initializes the Servlet filter with the cache time and sets up the
@@ -130,9 +130,9 @@ public class ResourceCachingFilter implements Filter {
         final String cacheTime = pConfig.getInitParameter(CACHE_TIME_PARAM_NAME);
         this.cacheTime = Long.parseLong(cacheTime != null ? cacheTime : CACHE_TIME_PARAM_NAME_DEFAULT);
         if (this.cacheTime > 0L) {
-            newReplyHeaders.add(new String[] { CACHE_CONTROL_HEADER, MAX_AGE_VALUE + this.cacheTime.longValue() });
-            newReplyHeaders.add(new String[] { CACHE_CONTROL_HEADER, PRE_CHECK_VALUE + this.cacheTime.longValue() });
-            newReplyHeaders.add(new String[] { CACHE_CONTROL_HEADER, POST_CHECK_VALUE + this.cacheTime.longValue() });
+            newReplyHeaders.add(new String[] { CACHE_CONTROL_HEADER, MAX_AGE_VALUE + this.cacheTime });
+            newReplyHeaders.add(new String[] { CACHE_CONTROL_HEADER, PRE_CHECK_VALUE + this.cacheTime });
+            newReplyHeaders.add(new String[] { CACHE_CONTROL_HEADER, POST_CHECK_VALUE + this.cacheTime });
         } else {
             newReplyHeaders.add(new String[] { PRAGMA_HEADER, NO_CACHE_VALUE });
             newReplyHeaders.add(new String[] { EXPIRES_HEADER, ZERO_STRING_VALUE });
@@ -141,6 +141,7 @@ public class ResourceCachingFilter implements Filter {
         }
         this.mReplyHeaders = new String[newReplyHeaders.size()][2];
         newReplyHeaders.toArray(this.mReplyHeaders);
+        httpDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
     }
 
     /**
@@ -173,48 +174,17 @@ public class ResourceCachingFilter implements Filter {
         }
         if (this.cacheTime > 0L) {
             final long now = System.currentTimeMillis();
-            final DateFormat httpDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
-            httpDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
             httpResponse.addHeader(LAST_MODIFIED_HEADER, httpDateFormat.format(new Date(now)));
-            httpResponse.addHeader(EXPIRES_HEADER, httpDateFormat.format(new Date(now + (this.cacheTime.longValue() * MILLISECONDS_IN_SECOND))));
+            httpResponse.addHeader(EXPIRES_HEADER, httpDateFormat.format(new Date(now + (this.cacheTime * MILLISECONDS_IN_SECOND))));
         }
         httpRequest.setAttribute(REQUEST_ATTRIBUTE, true);
 
-        // try to suppress java.io.IOException of kind 'client connection abort'
-        // 1) the TCP protocol (by design) does not provide a means to check, whether a
-        //    connection has been closed by the client
-        // 2) the exception thrown and the exception message text are specific to the
-        //    servlet-engine implementation, so we can only guess here
-        try {
-            chain.doFilter(servletRequest, servletResponse);
-        } catch (IOException e) {
-            FluentException.of(e)
-            .suppressIf(this::isConnectionAbortException);
-        }
+        chain.doFilter(servletRequest, servletResponse);
     }
 
-    /**
-     * Destroy all humans!
-     *
-     * @see javax.servlet.Filter#destroy()
-     */
     @Override
     public void destroy() {
-    }
-
-    // -- HELPER
-
-    private boolean isConnectionAbortException(IOException e) {
-        // tomcat 9
-        if(e.getMessage().contains("An established connection was aborted by the software in your host machine")) {
-            return true;
-        }
-        // payara 4
-        if(e.getMessage().contains("Connection is closed")) {
-            return true;
-        }
-
-        return false;
+        // nothing to do
     }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/webapp/content/ResourceServlet.java b/core/metamodel/src/main/java/org/apache/isis/core/webapp/content/ResourceServlet.java
index 7220aa8..497394e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/webapp/content/ResourceServlet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/webapp/content/ResourceServlet.java
@@ -30,7 +30,6 @@ import java.nio.charset.StandardCharsets;
 
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletException;
-import javax.servlet.annotation.WebServlet;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -49,10 +48,12 @@ import org.apache.isis.core.commons.lang.StringExtensions;
  * Serves static web-resources by class-path or file-system lookup.
  * Also handles HTML-templates, where template's placeholders get replaced by their values.
  */
-@WebServlet(
-        urlPatterns = { 
-                "*.css", "*.png", "*.jpg", "*.jpeg", "*.gif", "*.svg", "*.js", "*.html", "*.swf" }
-        )
+//@WebServlet(
+//        urlPatterns = { 
+//                "*.css", "*.png", "*.jpg", "*.jpeg", "*.gif", "*.svg", "*.js", "*.html", "*.swf" }
+//        )
+//[ahuber] to support Servlet 3.0 annotations @WebFilter, @WebListener or others 
+//with skinny war deployment requires additional configuration, so for now we disable this annotation
 public class ResourceServlet extends HttpServlet {
 
     private static final Logger LOG = LoggerFactory.getLogger(ResourceServlet.class);
diff --git a/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule.java b/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule.java
index eab3bbd..04233c1 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule.java
@@ -88,6 +88,7 @@ public interface WebModule {
         
         return Stream.of(
                 new WebModule_Shiro(), // filters before all others
+                new WebModule_StaticResources(),
                 new WebModule_Wicket(),
                 new WebModule_FallbackBootstrapper(), // not required if the Wicket module is in use
                 new WebModule_RestEasy(), // default REST provider
diff --git a/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule_RestEasy.java b/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule_RestEasy.java
index de06abd..2dbd428 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule_RestEasy.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule_RestEasy.java
@@ -80,7 +80,8 @@ final class WebModule_RestEasy implements WebModule  {
     @Override
     public ServletContextListener init(ServletContext ctx) throws ServletException {
 
-        // add IsisSessionFilter
+        // add IsisSessionFilters
+        
         {
             final Dynamic filter = ctx.addFilter("IsisSessionFilterForRestfulObjects", IsisSessionFilter.class);
 
@@ -101,6 +102,14 @@ final class WebModule_RestEasy implements WebModule  {
                     getRestfulPath()+"swagger"); 
             
         }
+        
+        {
+            final Dynamic filter = ctx.addFilter("RestfulObjectsRestEasyDispatcher", 
+                    "org.apache.isis.viewer.restfulobjects.server.webapp.IsisTransactionFilterForRestfulObjects");
+            filter.addMappingForServletNames(null, true, RESTEASY_DISPATCHER); 
+        }
+        
+        
 
         // add RestEasy
         
diff --git a/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule_StaticResources.java b/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule_StaticResources.java
new file mode 100644
index 0000000..e280cf2
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/webapp/modules/WebModule_StaticResources.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.isis.core.webapp.modules;
+
+import javax.servlet.FilterRegistration.Dynamic;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextListener;
+import javax.servlet.ServletException;
+
+import org.apache.isis.core.webapp.content.ResourceCachingFilter;
+import org.apache.isis.core.webapp.content.ResourceServlet;
+
+/**
+ * Package private mixin for WebModule implementing WebModule.
+ * 
+ * @since 2.0.0
+ */
+final class WebModule_StaticResources implements WebModule  {
+    
+    private final static String[] urlPatterns = { 
+          "*.css", "*.png", "*.jpg", "*.jpeg", "*.gif", "*.svg", "*.js", "*.html", "*.swf" };
+    
+    private final static int cacheTimeSeconds = 86400;
+    
+    private final static String RESOURCE_SERVLET_NAME = "ResourceServlet";
+    
+    @Override
+    public String getName() {
+        return "StaticResources";
+    }
+    
+    @Override
+    public void prepare(ServletContext ctx) {
+        // nothing special required
+    }
+
+    @Override
+    public ServletContextListener init(ServletContext ctx) throws ServletException {
+
+        final Dynamic filter = ctx.addFilter("ResourceCachingFilter", ResourceCachingFilter.class);
+        if(filter==null) {
+            return null; // filter was already registered somewhere else (eg web.xml)
+        }
+
+        filter.setInitParameter(
+                "CacheTime", 
+                ""+cacheTimeSeconds);
+        filter.addMappingForUrlPatterns(null, true, urlPatterns);
+        
+        ctx.addServlet(RESOURCE_SERVLET_NAME, ResourceServlet.class);
+        ctx.getServletRegistration(RESOURCE_SERVLET_NAME)
+        .addMapping(urlPatterns);
+        
+        return null; // does not provide a listener
+    }
+
+    @Override
+    public boolean isApplicable(ServletContext ctx) {
+        return true;
+    }
+
+    
+}
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/webapp/IsisTransactionFilterForRestfulObjects.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/webapp/IsisTransactionFilterForRestfulObjects.java
index 4978144..8d9c099 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/webapp/IsisTransactionFilterForRestfulObjects.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/webapp/IsisTransactionFilterForRestfulObjects.java
@@ -24,13 +24,14 @@ import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
-import javax.servlet.annotation.WebFilter;
 
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.core.runtime.system.session.IsisSessionFactory;
 import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
 
-@WebFilter(servletNames= {"RestfulObjectsRestEasyDispatcher"})
+//@WebFilter(servletNames= {"RestfulObjectsRestEasyDispatcher"}) //[ahuber] to support 
+//Servlet 3.0 annotations @WebFilter, @WebListener or others 
+//with skinny war deployment requires additional configuration, so for now we disable this annotation
 public class IsisTransactionFilterForRestfulObjects implements Filter {
 
     @Override
@@ -67,8 +68,6 @@ public class IsisTransactionFilterForRestfulObjects implements Filter {
     public void destroy() {
     }
 
-
-    // REVIEW: ought to be able to obtain from thread or as a request attribute
     protected IsisSessionFactory isisSessionFactoryFrom(final ServletRequest request) {
         return IsisContext.getSessionFactory();
     }