Repository: ambari
Updated Branches:
  refs/heads/trunk c775c6071 -> c8032c6d1


AMBARI-9551 - Views: ContextClassLoader can't load resources for JARs 
(tbeerbower)


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

Branch: refs/heads/trunk
Commit: c8032c6d13dd3cf3afb1d6cb76ec48dd19782031
Parents: c775c60
Author: tbeerbower <tbeerbo...@hortonworks.com>
Authored: Tue Feb 10 15:09:06 2015 -0500
Committer: tbeerbower <tbeerbo...@hortonworks.com>
Committed: Tue Feb 10 15:09:35 2015 -0500

----------------------------------------------------------------------
 .../server/controller/AmbariHandlerList.java    | 69 ++++++++++++++++++++
 .../server/controller/FailsafeHandlerList.java  | 25 +++++--
 .../controller/AmbariHandlerListTest.java       | 65 ++++++++++++++++++
 3 files changed, 154 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/c8032c6d/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariHandlerList.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariHandlerList.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariHandlerList.java
index da15a66..7c68311 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariHandlerList.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariHandlerList.java
@@ -17,11 +17,18 @@
  */
 package org.apache.ambari.server.controller;
 
+import java.io.IOException;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 
 import org.apache.ambari.server.orm.entities.ViewEntity;
 import org.apache.ambari.server.orm.entities.ViewInstanceEntity;
@@ -31,10 +38,13 @@ import org.apache.ambari.server.view.ViewRegistry;
 import org.apache.ambari.view.SystemException;
 import org.apache.ambari.view.ViewContext;
 import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.SessionManager;
 import org.eclipse.jetty.server.session.SessionHandler;
 import org.eclipse.jetty.servlet.FilterHolder;
 import org.eclipse.jetty.webapp.WebAppContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.web.context.WebApplicationContext;
 import org.springframework.web.context.support.GenericWebApplicationContext;
 import org.springframework.web.filter.DelegatingFilterProxy;
@@ -47,6 +57,12 @@ import org.springframework.web.filter.DelegatingFilterProxy;
 public class AmbariHandlerList extends FailsafeHandlerList implements 
ViewInstanceHandlerList {
 
   /**
+   * The target pattern for a view resource request.
+   */
+  private static final Pattern VIEW_RESOURCE_TARGET_PATTERN =
+      
Pattern.compile("/api/(\\S+)/views/(\\S+)/versions/(\\S+)/instances/(\\S+)/resources/(\\S+)");
+
+  /**
    * The view registry.
    */
   @Inject
@@ -76,6 +92,12 @@ public class AmbariHandlerList extends FailsafeHandlerList 
implements ViewInstan
    */
   private GenericWebApplicationContext springWebAppContext;
 
+  /**
+   * The logger.
+   */
+  protected final static Logger LOG = 
LoggerFactory.getLogger(AmbariHandlerList.class);
+
+
   // ----- Constructors ------------------------------------------------------
 
   /**
@@ -122,6 +144,39 @@ public class AmbariHandlerList extends FailsafeHandlerList 
implements ViewInstan
   }
 
 
+  // ----- FailsafeHandlerList -----------------------------------------------
+
+  @Override
+  protected void handleNonFailSafe(String target, Request baseRequest,
+                                   HttpServletRequest request, 
HttpServletResponse response,
+                                   List<Handler> handlers) throws IOException, 
ServletException {
+
+    ViewEntity viewEntity = getTargetView(target);
+
+    if (viewEntity == null) {
+      super.handleNonFailSafe(target, baseRequest, request, response, 
handlers);
+    } else {
+      // if there is a view target (as in a view resource request) then set 
the view class loader
+      ClassLoader contextClassLoader = 
Thread.currentThread().getContextClassLoader();
+      ClassLoader viewClassLoader    = null;
+
+      try {
+        viewClassLoader = viewEntity.getClassLoader();
+        if (viewClassLoader == null) {
+          LOG.warn("No class loader associated with view " + 
viewEntity.getName() + ".");
+        } else {
+          Thread.currentThread().setContextClassLoader(viewClassLoader);
+        }
+        super.handleNonFailSafe(target, baseRequest, request, response, 
handlers);
+      } finally {
+        if (viewClassLoader != null) {
+          Thread.currentThread().setContextClassLoader(contextClassLoader);
+        }
+      }
+    }
+  }
+
+
   // ----- ViewInstanceHandler -----------------------------------------------
 
   @Override
@@ -167,6 +222,20 @@ public class AmbariHandlerList extends FailsafeHandlerList 
implements ViewInstan
   }
 
 
+  /**
+   * Get the view that is the target of the request; null if not a view 
request.
+   *
+   * @param target  the target of the request
+   *
+   * @return the view target; null if none
+   */
+  private ViewEntity getTargetView(String target) {
+    Matcher matcher = VIEW_RESOURCE_TARGET_PATTERN.matcher(target);
+
+    return matcher.matches() ? viewRegistry.getDefinition(matcher.group(2), 
matcher.group(3)) : null;
+  }
+
+
   // ----- inner interface : HandlerFactory ----------------------------------
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/c8032c6d/ambari-server/src/main/java/org/apache/ambari/server/controller/FailsafeHandlerList.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/FailsafeHandlerList.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/FailsafeHandlerList.java
index fa1e6b1..26395cc 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/FailsafeHandlerList.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/FailsafeHandlerList.java
@@ -127,12 +127,27 @@ public class FailsafeHandlerList extends 
HandlerCollection {
           return;
         }
       }
+      handleNonFailSafe(target, baseRequest, request, response, 
nonFailsafeHandlers);
+    }
+  }
 
-      for (Handler handler : nonFailsafeHandlers) {
-        handler.handle(target, baseRequest, request, response);
-        if (baseRequest.isHandled()) {
-          return;
-        }
+  /**
+   * Attempt to handle the request with the non-failsafe handlers.
+   *
+   * @param target       the target of the request - either a URI or a name
+   * @param baseRequest  the original unwrapped request object.
+   * @param request      the request
+   * @param response     the response
+   * @param handlers     the non-failsafe handlers
+   */
+  protected void handleNonFailSafe(String target, Request baseRequest, 
HttpServletRequest request,
+                                   HttpServletResponse response, List<Handler> 
handlers)
+      throws IOException, ServletException {
+
+    for (Handler handler : handlers) {
+      handler.handle(target, baseRequest, request, response);
+      if (baseRequest.isHandled()) {
+        return;
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/c8032c6d/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariHandlerListTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariHandlerListTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariHandlerListTest.java
index 7171e88..04a4b15 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariHandlerListTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariHandlerListTest.java
@@ -18,15 +18,25 @@
 
 package org.apache.ambari.server.controller;
 
+import org.apache.ambari.server.orm.entities.ViewEntity;
 import org.apache.ambari.server.orm.entities.ViewInstanceEntity;
 import org.apache.ambari.server.orm.entities.ViewInstanceEntityTest;
+import org.apache.ambari.server.view.ViewRegistry;
 import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.AbstractHandler;
 import org.junit.Assert;
 import org.junit.Test;
 
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
 
 import static org.easymock.EasyMock.createNiceMock;
 import static org.easymock.EasyMock.expect;
@@ -104,4 +114,59 @@ public class AmbariHandlerListTest {
     verify(handler, server);
 
   }
+
+  @Test
+  public void testHandleNonFailSafe() throws Exception {
+    TestHandler handler = new TestHandler();
+    AmbariHandlerList.HandlerFactory handlerFactory = 
createNiceMock(AmbariHandlerList.HandlerFactory.class);
+    ViewRegistry viewRegistry = createNiceMock(ViewRegistry.class);
+    ViewEntity viewEntity = createNiceMock(ViewEntity.class);
+    ClassLoader classLoader = createNiceMock(ClassLoader.class);
+
+    Request baseRequest = createNiceMock(Request.class);
+
+    HttpServletRequest request = createNiceMock(HttpServletRequest.class);
+    HttpServletResponse response = createNiceMock(HttpServletResponse.class);
+
+    List <Handler> handlers = new LinkedList<Handler>();
+    handlers.add(handler);
+
+    expect(viewRegistry.getDefinition("TEST", 
"1.0.0")).andReturn(viewEntity).anyTimes();
+    expect(viewEntity.getClassLoader()).andReturn(classLoader).anyTimes();
+
+    replay(viewRegistry, viewEntity);
+
+    AmbariHandlerList handlerList = new AmbariHandlerList(handlerFactory);
+    handlerList.viewRegistry = viewRegistry;
+
+    
handlerList.handleNonFailSafe("/api/v1/views/TEST/versions/1.0.0/instances/INSTANCE_1/resources/test",
+        baseRequest, request, response, handlers);
+
+    
Assert.assertEquals("/api/v1/views/TEST/versions/1.0.0/instances/INSTANCE_1/resources/test",
 handler.getTarget());
+    Assert.assertEquals(classLoader, handler.getClassLoader());
+
+    verify(viewRegistry, viewEntity);
+  }
+
+  private static class TestHandler extends AbstractHandler {
+
+    private ClassLoader classLoader = null;
+    private String target = null;
+
+    @Override
+    public void handle(String target, Request request,
+                       HttpServletRequest httpServletRequest, 
HttpServletResponse httpServletResponse)
+        throws IOException, ServletException {
+      this.target = target;
+      classLoader = Thread.currentThread().getContextClassLoader();
+    }
+
+    public ClassLoader getClassLoader() {
+      return classLoader;
+    }
+
+    public String getTarget() {
+      return target;
+    }
+  }
 }

Reply via email to