ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tbeerbo...@apache.org
Subject git commit: AMBARI-7938 - Views: ability to use current ambari authorization + session
Date Fri, 24 Oct 2014 17:21:42 GMT
Repository: ambari
Updated Branches:
  refs/heads/trunk 52422ca16 -> 439a0a40d


AMBARI-7938 - Views: ability to use current ambari authorization + session


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

Branch: refs/heads/trunk
Commit: 439a0a40d5bffdfa38059deb212d3658ea79adf1
Parents: 52422ca
Author: tbeerbower <tbeerbower@hortonworks.com>
Authored: Thu Oct 23 19:45:27 2014 -0400
Committer: tbeerbower <tbeerbower@hortonworks.com>
Committed: Fri Oct 24 13:21:18 2014 -0400

----------------------------------------------------------------------
 .../controller/AmbariManagementController.java  |  10 ++
 .../ambari/server/controller/AmbariServer.java  |   4 +
 .../server/controller/AmbariSessionManager.java |  73 +++++++++++++
 .../controller/internal/URLStreamProvider.java  | 108 ++++++++++++++-----
 .../server/view/ViewAmbariStreamProvider.java   | 108 +++++++++++++++++++
 .../ambari/server/view/ViewContextImpl.java     | 100 +++++------------
 .../apache/ambari/server/view/ViewRegistry.java |  45 ++++++++
 .../server/view/ViewURLStreamProvider.java      |  78 ++++++++++++++
 .../internal/URLStreamProviderTest.java         |  83 ++++++++++++++
 .../view/ViewAmbariStreamProviderTest.java      |  73 +++++++++++++
 .../ambari/server/view/ViewContextImplTest.java |  45 ++++----
 .../server/view/ViewURLStreamProviderTest.java  |  80 ++++++++++++++
 .../ambari/view/AmbariStreamProvider.java       |  45 ++++++++
 .../org/apache/ambari/view/ViewContext.java     |   8 +-
 14 files changed, 737 insertions(+), 123 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/439a0a40/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
index c37ee79..5af88a8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
@@ -49,6 +49,16 @@ import java.util.Set;
  */
 public interface AmbariManagementController {
 
+  /**
+   * Get an Ambari endpoint URI for the given path.
+   *
+   * @param path  the path (e.g. /api/v1/users)
+   *
+   * @return the Ambari endpoint URI
+   */
+  public String getAmbariServerURI(String path);
+
+
   // ----- Create -----------------------------------------------------------
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/439a0a40/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index 4a064a2..cfb73bc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -114,6 +114,7 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.request.RequestContextListener;
 import org.springframework.web.context.support.GenericWebApplicationContext;
 import org.springframework.web.filter.DelegatingFilterProxy;
 
@@ -276,6 +277,9 @@ public class AmbariServer {
       root.addFilter(new FilterHolder(new MethodOverrideFilter()), "/api/*", 1);
       root.addFilter(new FilterHolder(new MethodOverrideFilter()), "/proxy/*", 1);
 
+      // register listener to capture request context
+      root.addEventListener(new RequestContextListener());
+
       agentroot.addFilter(new FilterHolder(injector.getInstance(AmbariPersistFilter.class)), "/agent/*", 1);
       agentroot.addFilter(SecurityFilter.class, "/*", 1);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/439a0a40/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariSessionManager.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariSessionManager.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariSessionManager.java
new file mode 100644
index 0000000..e6dd07f
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariSessionManager.java
@@ -0,0 +1,73 @@
+/**
+ * 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.ambari.server.controller;
+
+import org.eclipse.jetty.server.SessionManager;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+/**
+ * Class to expose current session information.
+ */
+public class AmbariSessionManager {
+
+  /**
+   * Session manager.
+   */
+  @Inject
+  SessionManager sessionManager;
+
+
+  // ----- AmbariSessionManager ----------------------------------------------
+
+  /**
+   * Get the session id associated with the current thread-bound request.
+   *
+   * @return the current session id; null if no request is associated with the current thread
+   */
+  public String getCurrentSessionId() {
+    RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
+
+    if (requestAttributes instanceof ServletRequestAttributes) {
+      ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
+
+      HttpServletRequest request = servletRequestAttributes.getRequest();
+      if (request != null) {
+        HttpSession session = request.getSession(true);
+
+        return session.getId();
+      }
+    }
+    return null;
+  }
+
+  /**
+   * The session cookie id (i.e. AMBARISESSIONID).
+   *
+   * @return the session cookie
+   */
+  public String getSessionCookie() {
+    return sessionManager.getSessionCookie();
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/439a0a40/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/URLStreamProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/URLStreamProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/URLStreamProvider.java
index 1b57c84..156c736 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/URLStreamProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/URLStreamProvider.java
@@ -24,8 +24,9 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.net.HttpURLConnection;
 import java.net.URL;
-import java.net.URLConnection;
 import java.security.KeyStore;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -46,7 +47,7 @@ import org.apache.http.HttpStatus;
  */
 public class URLStreamProvider implements StreamProvider {
 
-  private static final String COOKIE = "Cookie";
+  public static final String COOKIE = "Cookie";
   private static final String WWW_AUTHENTICATE = "WWW-Authenticate";
   private static final String NEGOTIATE = "Negotiate";
   private static Log LOG = LogFactory.getLog(URLStreamProvider.class);
@@ -57,7 +58,10 @@ public class URLStreamProvider implements StreamProvider {
   private final String password;
   private final String type;
   private volatile SSLSocketFactory sslSocketFactory = null;
-  private AppCookieManager appCookieManager;
+  private AppCookieManager appCookieManager = null;
+
+
+  // ----- Constructors ------------------------------------------------------
 
   /**
    * Provide the connection timeout for the underlying connection.
@@ -88,18 +92,39 @@ public class URLStreamProvider implements StreamProvider {
 
     this.connTimeout = connectionTimeout;
     this.readTimeout = readTimeout;
-    this.path = path;          // truststroe path
-    this.password = password;  // truststore password
-    this.type = type;          // truststroe type
-    appCookieManager = new AppCookieManager();
+    this.path        = path;      // truststroe path
+    this.password    = password;  // truststore password
+    this.type        = type;      // truststroe type
   }
 
-  
+
+  // ----- StreamProvider ----------------------------------------------------
+
   @Override
   public InputStream readFrom(String spec, String requestMethod, String params) throws IOException {
     return processURL(spec, requestMethod, params, null).getInputStream();
   }
 
+  @Override
+  public InputStream readFrom(String spec) throws IOException {
+    return readFrom(spec, "GET", null);
+  }
+
+
+  // ----- URLStreamProvider -------------------------------------------------
+
+  /**
+   * Get a URL connection from the given spec.
+   *
+   * @param spec           the String to parse as a URL
+   * @param requestMethod  the HTTP method (GET,POST,PUT,etc.).
+   * @param params         the body of the request; may be null
+   * @param headers        the headers of the request; may be null
+   *
+   * @return a URL connection
+   *
+   * @throws IOException if the URL connection can not be established
+   */
   public HttpURLConnection processURL(String spec, String requestMethod, Object params, Map<String, List<String>> headers)
           throws IOException {
     if (LOG.isDebugEnabled()) {
@@ -107,13 +132,25 @@ public class URLStreamProvider implements StreamProvider {
     }
 
     HttpURLConnection connection = spec.startsWith("https") ?
-            (HttpURLConnection)getSSLConnection(spec)
-            : (HttpURLConnection)getConnection(spec);
+            getSSLConnection(spec) : getConnection(spec);
+
+    AppCookieManager appCookieManager = getAppCookieManager();
 
     String appCookie = appCookieManager.getCachedAppCookie(spec);
     if (appCookie != null) {
       LOG.debug("Using cached app cookie for URL:" + spec);
-      connection.setRequestProperty(COOKIE, appCookie);
+
+      // allow for additional passed in cookies
+      if (headers == null || headers.isEmpty()) {
+        headers = Collections.singletonMap(COOKIE, Collections.singletonList(appCookie));
+      } else {
+        headers = new HashMap<String, List<String>>(headers);
+
+        List<String> cookieList = headers.get(COOKIE);
+        String       cookies    = cookieList.isEmpty() ? null : cookieList.get(0);
+
+        headers.put(COOKIE, Collections.singletonList(appendCookie(cookies, appCookie)));
+      }
     }
     connection.setConnectTimeout(connTimeout);
     connection.setReadTimeout(readTimeout);
@@ -145,10 +182,8 @@ public class URLStreamProvider implements StreamProvider {
       }
       if (wwwAuthHeader != null &&
         wwwAuthHeader.trim().startsWith(NEGOTIATE)) {
-        //connection.getInputStream().close();
         connection = spec.startsWith("https") ?
-           (HttpURLConnection)getSSLConnection(spec)
-           : (HttpURLConnection)getConnection(spec);
+           getSSLConnection(spec) : getConnection(spec);
         appCookie = appCookieManager.getAppCookie(spec, true);
         connection.setRequestProperty(COOKIE, appCookie);
         connection.setConnectTimeout(connTimeout);
@@ -168,23 +203,44 @@ public class URLStreamProvider implements StreamProvider {
         return connection;
     }
   }
-  
-  @Override
-  public InputStream readFrom(String spec) throws IOException {
-    
-    return readFrom(spec, "GET", null);
-    
+
+  /**
+   * Get the associated app cookie manager.
+   *
+   * @return the app cookie manager
+   */
+  public synchronized AppCookieManager getAppCookieManager() {
+    if (appCookieManager == null) {
+      appCookieManager = new AppCookieManager();
+    }
+    return appCookieManager;
+  }
+
+  /**
+   * Utility method to append a new cookie value to an existing list of cookies.
+   *
+   * @param cookies    the semicolon separated list of cookie values
+   * @param newCookie  a new cookie value to be appended.
+   *
+   * @return the new list of cookie values
+   */
+  public static String appendCookie(String cookies, String newCookie) {
+    if (cookies == null || cookies.length() == 0) {
+      return newCookie;
+    }
+    return cookies + "; " + newCookie;
   }
-  
+
+
   // ----- helper methods ----------------------------------------------------
 
   // Get a connection
-  private URLConnection getConnection(String spec) throws IOException {
-    return new URL(spec).openConnection();
+  protected HttpURLConnection getConnection(String spec) throws IOException {
+    return (HttpURLConnection) new URL(spec).openConnection();
   }
 
   // Get an ssl connection
-  private HttpsURLConnection getSSLConnection(String spec) throws IOException {
+  protected HttpsURLConnection getSSLConnection(String spec) throws IOException {
 
     if (sslSocketFactory == null) {
       synchronized (this) {
@@ -218,8 +274,4 @@ public class URLStreamProvider implements StreamProvider {
  
     return connection;
   }
-
-  public AppCookieManager getAppCookieManager() {
-    return appCookieManager;
-  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/439a0a40/ambari-server/src/main/java/org/apache/ambari/server/view/ViewAmbariStreamProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewAmbariStreamProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewAmbariStreamProvider.java
new file mode 100644
index 0000000..d8448b8
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewAmbariStreamProvider.java
@@ -0,0 +1,108 @@
+/**
+ * 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.ambari.server.view;
+
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.AmbariSessionManager;
+import org.apache.ambari.server.controller.internal.URLStreamProvider;
+import org.apache.ambari.view.AmbariStreamProvider;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Provider of an input stream for a request to the Ambari server.
+ */
+public class ViewAmbariStreamProvider implements AmbariStreamProvider {
+  /**
+   * Internal stream provider.
+   */
+  private final URLStreamProvider streamProvider;
+
+  /**
+   * The Ambari session manager.
+   */
+  private final AmbariSessionManager ambariSessionManager;
+
+  /**
+   * The Ambari management controller.
+   */
+  private final AmbariManagementController controller;
+
+
+  // ----- Constructor -----------------------------------------------------
+
+  /**
+   * Construct a view Ambari stream provider.
+   *
+   * @param streamProvider        the underlying stream provider
+   * @param ambariSessionManager  the Ambari session manager
+   * @param controller         the Ambari configuration
+   *
+   * @throws IllegalStateException if the Ambari stream provider can not be created
+   */
+  protected ViewAmbariStreamProvider(URLStreamProvider streamProvider, AmbariSessionManager ambariSessionManager,
+                                     AmbariManagementController controller) {
+    this.streamProvider       = streamProvider;
+    this.ambariSessionManager = ambariSessionManager;
+    this.controller           = controller;
+  }
+
+
+  // ----- AmbariStreamProvider -----------------------------------------------
+
+  @Override
+  public InputStream readFrom(String path, String requestMethod, String params, Map<String, String> headers,
+                              boolean useAmbariSession)
+      throws IOException {
+
+    // add the Ambari session cookie to the given headers
+    if (useAmbariSession) {
+      String sessionId = ambariSessionManager.getCurrentSessionId();
+      if (sessionId != null) {
+
+        String ambariSessionCookie = ambariSessionManager.getSessionCookie() + "=" + sessionId;
+
+        if (headers == null || headers.isEmpty()) {
+          headers = Collections.singletonMap(URLStreamProvider.COOKIE, ambariSessionCookie);
+        } else {
+          headers = new HashMap<String, String>(headers);
+
+          String cookies = headers.get(URLStreamProvider.COOKIE);
+
+          headers.put(URLStreamProvider.COOKIE, URLStreamProvider.appendCookie(cookies, ambariSessionCookie));
+        }
+      }
+    }
+
+    // adapt the headers for the internal URLStreamProvider signature
+    Map<String, List<String>> headerMap = new HashMap<String, List<String>>();
+    for (Map.Entry<String, String> entry : headers.entrySet()) {
+      headerMap.put(entry.getKey(), Collections.singletonList(entry.getValue()));
+    }
+
+    return streamProvider.processURL(controller.getAmbariServerURI(path.startsWith("/") ? path : "/" + path),
+        requestMethod, params, headerMap).getInputStream();
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/439a0a40/ambari-server/src/main/java/org/apache/ambari/server/view/ViewContextImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewContextImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewContextImpl.java
index 7fea0d5..dd7417a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewContextImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewContextImpl.java
@@ -20,7 +20,6 @@ package org.apache.ambari.server.view;
 
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-import org.apache.ambari.server.configuration.ComponentSSLConfiguration;
 import org.apache.ambari.server.orm.entities.PermissionEntity;
 import org.apache.ambari.server.orm.entities.ViewEntity;
 import org.apache.ambari.server.orm.entities.ViewInstanceEntity;
@@ -29,15 +28,14 @@ import org.apache.ambari.server.view.configuration.ViewConfig;
 import org.apache.ambari.server.view.events.EventImpl;
 import org.apache.ambari.server.view.persistence.DataStoreImpl;
 import org.apache.ambari.server.view.persistence.DataStoreModule;
+import org.apache.ambari.view.AmbariStreamProvider;
 import org.apache.ambari.view.DataStore;
+import org.apache.ambari.view.ImpersonatorSetting;
 import org.apache.ambari.view.MaskException;
 import org.apache.ambari.view.Masker;
 import org.apache.ambari.view.ResourceProvider;
 import org.apache.ambari.view.SecurityException;
 import org.apache.ambari.view.SystemException;
-import org.apache.ambari.view.URLStreamProvider;
-import org.apache.ambari.server.controller.internal.AppCookieManager;
-import org.apache.ambari.view.ImpersonatorSetting;
 import org.apache.ambari.view.ViewContext;
 import org.apache.ambari.view.ViewController;
 import org.apache.ambari.view.ViewDefinition;
@@ -51,15 +49,11 @@ import org.apache.velocity.VelocityContext;
 import org.apache.velocity.app.Velocity;
 import org.apache.velocity.exception.ParseErrorException;
 
-import java.io.IOException;
-import java.io.InputStream;
 import java.io.StringWriter;
 import java.io.Writer;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 
@@ -89,9 +83,14 @@ public class ViewContextImpl implements ViewContext, ViewController {
   private final ViewRegistry viewRegistry;
 
   /**
-   * The available stream provider.
+   * The URL stream provider.
+   */
+  private ViewURLStreamProvider streamProvider;
+
+  /**
+   * The Ambari stream provider.
    */
-  private final ViewURLStreamProvider streamProvider;
+  private ViewAmbariStreamProvider ambariStreamProvider;
 
   /**
    * The data store.
@@ -131,7 +130,6 @@ public class ViewContextImpl implements ViewContext, ViewController {
     this.viewEntity         = viewEntity;
     this.viewInstanceEntity = viewInstanceEntity;
     this.viewRegistry       = viewRegistry;
-    this.streamProvider     = ViewURLStreamProvider.getProvider();
     this.masker             = getMasker(viewEntity.getClassLoader(), viewEntity.getConfiguration());
     this.velocityContext    = initVelocityContext();
   }
@@ -275,11 +273,20 @@ public class ViewContextImpl implements ViewContext, ViewController {
   }
 
   @Override
-  public URLStreamProvider getURLStreamProvider() {
+  public org.apache.ambari.view.URLStreamProvider getURLStreamProvider() {
+    ensureURLStreamProvider();
     return streamProvider;
   }
 
   @Override
+  public synchronized AmbariStreamProvider getAmbariStreamProvider() {
+    if (ambariStreamProvider == null) {
+      ambariStreamProvider = viewRegistry.createAmbariStreamProvider();
+    }
+    return ambariStreamProvider;
+  }
+
+  @Override
   public synchronized DataStore getDataStore() {
     if (viewInstanceEntity != null) {
       if (dataStore == null) {
@@ -311,7 +318,8 @@ public class ViewContextImpl implements ViewContext, ViewController {
 
   @Override
   public HttpImpersonatorImpl getHttpImpersonator() {
-    return new HttpImpersonatorImpl(this, this.streamProvider.getAppCookieManager());
+    ensureURLStreamProvider();
+    return new HttpImpersonatorImpl(this, streamProvider.getAppCookieManager());
   }
 
   @Override
@@ -319,6 +327,7 @@ public class ViewContextImpl implements ViewContext, ViewController {
     return new ImpersonatorSettingImpl(this);
   }
 
+
   // ----- ViewController ----------------------------------------------------
 
   @Override
@@ -352,6 +361,13 @@ public class ViewContextImpl implements ViewContext, ViewController {
 
   // ----- helper methods ----------------------------------------------------
 
+  // ensure that the URL stream provider has been created
+  private synchronized void ensureURLStreamProvider() {
+    if (streamProvider == null) {
+      streamProvider = viewRegistry.createURLStreamProvider();
+    }
+  }
+
   // check for an associated instance
   private void checkInstance() {
     if (viewInstanceEntity == null) {
@@ -413,64 +429,6 @@ public class ViewContextImpl implements ViewContext, ViewController {
     return context;
   }
 
-  // ----- Inner class : ViewURLStreamProvider -------------------------------
-
-  /**
-   * Wrapper around internal URL stream provider.
-   */
-  protected static class ViewURLStreamProvider implements URLStreamProvider {
-    private static final int DEFAULT_REQUEST_CONNECT_TIMEOUT = 5000;
-    private static final int DEFAULT_REQUEST_READ_TIMEOUT    = 10000;
-
-    /**
-     * Internal stream provider.
-     */
-    private final org.apache.ambari.server.controller.internal.URLStreamProvider streamProvider;
-
-    // ----- Constructor -----------------------------------------------------
-
-    protected ViewURLStreamProvider(org.apache.ambari.server.controller.internal.URLStreamProvider streamProvider) {
-      this.streamProvider = streamProvider;
-    }
-
-
-    // ----- URLStreamProvider -----------------------------------------------
-
-    @Override
-    public InputStream readFrom(String spec, String requestMethod, String params, Map<String, String> headers)
-        throws IOException {
-      // adapt to org.apache.ambari.server.controller.internal.URLStreamProvider processURL signature
-      Map<String, List<String>> headerMap = new HashMap<String, List<String>>();
-      for (Map.Entry<String, String> entry : headers.entrySet()) {
-        headerMap.put(entry.getKey(), Collections.singletonList(entry.getValue()));
-      }
-      return streamProvider.processURL(spec, requestMethod, params, headerMap).getInputStream();
-    }
-
-
-    // ----- helper methods --------------------------------------------------
-
-    /**
-     * Factory method.
-     *
-     * @return a new URL stream provider.
-     */
-    protected static ViewURLStreamProvider getProvider() {
-      ComponentSSLConfiguration configuration = ComponentSSLConfiguration.instance();
-      org.apache.ambari.server.controller.internal.URLStreamProvider streamProvider =
-          new org.apache.ambari.server.controller.internal.URLStreamProvider(
-              DEFAULT_REQUEST_CONNECT_TIMEOUT, DEFAULT_REQUEST_READ_TIMEOUT,
-              configuration.getTruststorePath(),
-              configuration.getTruststorePassword(),
-              configuration.getTruststoreType());
-      return new ViewURLStreamProvider(streamProvider);
-    }
-
-    protected AppCookieManager getAppCookieManager() {
-      return streamProvider.getAppCookieManager();
-    }
-  }
-
   // ----- Inner class : ParameterResolver -------------------------------
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/439a0a40/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
index 1f5db9a..c4da8b4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
@@ -27,7 +27,10 @@ import org.apache.ambari.server.api.resources.SubResourceDefinition;
 import org.apache.ambari.server.api.resources.ViewExternalSubResourceDefinition;
 import org.apache.ambari.server.api.services.ViewExternalSubResourceService;
 import org.apache.ambari.server.api.services.ViewSubResourceService;
+import org.apache.ambari.server.configuration.ComponentSSLConfiguration;
 import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.controller.AmbariServer;
+import org.apache.ambari.server.controller.AmbariSessionManager;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.spi.ResourceProvider;
 import org.apache.ambari.server.orm.dao.MemberDAO;
@@ -102,6 +105,8 @@ public class ViewRegistry {
   private static final String EXTRACTED_ARCHIVES_DIR = "work";
   private static final String EXTRACT_COMMAND = "extract";
   private static final String ALL_VIEWS_REG_EXP = ".*";
+  protected static final int DEFAULT_REQUEST_CONNECT_TIMEOUT = 5000;
+  protected static final int DEFAULT_REQUEST_READ_TIMEOUT    = 10000;
 
   /**
    * Thread pool
@@ -219,6 +224,12 @@ public class ViewRegistry {
   @Inject
   ViewArchiveUtility archiveUtility;
 
+  /**
+   * The Ambari session manager.
+   */
+  @Inject
+  AmbariSessionManager ambariSessionManager;
+
 
   // ----- ViewRegistry ------------------------------------------------------
 
@@ -1370,4 +1381,38 @@ public class ViewRegistry {
     }
     return executorService;
   }
+
+  /**
+   * Factory method to create a view URL stream provider.
+   *
+   * @return a new view URL stream provider
+   */
+  protected ViewURLStreamProvider createURLStreamProvider() {
+    ComponentSSLConfiguration configuration1 = ComponentSSLConfiguration.instance();
+    org.apache.ambari.server.controller.internal.URLStreamProvider streamProvider =
+        new org.apache.ambari.server.controller.internal.URLStreamProvider(
+            DEFAULT_REQUEST_CONNECT_TIMEOUT,
+            DEFAULT_REQUEST_READ_TIMEOUT,
+            configuration1.getTruststorePath(),
+            configuration1.getTruststorePassword(),
+            configuration1.getTruststoreType());
+    return new ViewURLStreamProvider(streamProvider);
+  }
+
+  /**
+   * Factory method to create a view Ambari stream provider.
+   *
+   * @return a new view Ambari stream provider
+   */
+  protected ViewAmbariStreamProvider createAmbariStreamProvider() {
+    ComponentSSLConfiguration configuration1 = ComponentSSLConfiguration.instance();
+    org.apache.ambari.server.controller.internal.URLStreamProvider streamProvider =
+        new org.apache.ambari.server.controller.internal.URLStreamProvider(
+            DEFAULT_REQUEST_CONNECT_TIMEOUT,
+            DEFAULT_REQUEST_READ_TIMEOUT,
+            configuration1.getTruststorePath(),
+            configuration1.getTruststorePassword(),
+            configuration1.getTruststoreType());
+    return new ViewAmbariStreamProvider(streamProvider, ambariSessionManager, AmbariServer.getController());
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/439a0a40/ambari-server/src/main/java/org/apache/ambari/server/view/ViewURLStreamProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewURLStreamProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewURLStreamProvider.java
new file mode 100644
index 0000000..87e2753
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewURLStreamProvider.java
@@ -0,0 +1,78 @@
+/**
+ * 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.ambari.server.view;
+
+import org.apache.ambari.server.controller.internal.AppCookieManager;
+import org.apache.ambari.server.controller.internal.URLStreamProvider;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Wrapper around an internal URL stream provider.
+ */
+public class ViewURLStreamProvider implements org.apache.ambari.view.URLStreamProvider {
+  /**
+   * Internal stream provider.
+   */
+  private final URLStreamProvider streamProvider;
+
+
+  // ----- Constructor -----------------------------------------------------
+
+  /**
+   * Construct a view URL stream provider.
+   *
+   * @param streamProvider  the underlying stream provider
+   */
+  protected ViewURLStreamProvider(URLStreamProvider streamProvider) {
+    this.streamProvider = streamProvider;
+  }
+
+
+  // ----- URLStreamProvider -----------------------------------------------
+
+  @Override
+  public InputStream readFrom(String spec, String requestMethod, String params, Map<String, String> headers)
+      throws IOException {
+    // adapt the headers to the internal URLStreamProvider processURL signature
+    Map<String, List<String>> headerMap = new HashMap<String, List<String>>();
+    for (Map.Entry<String, String> entry : headers.entrySet()) {
+      headerMap.put(entry.getKey(), Collections.singletonList(entry.getValue()));
+    }
+    return streamProvider.processURL(spec, requestMethod, params, headerMap).getInputStream();
+  }
+
+
+  // ----- helper methods --------------------------------------------------
+
+  /**
+   * Get the associated app cookie manager
+   *
+   * @return get the app cookie manager
+   */
+  protected AppCookieManager getAppCookieManager() {
+    return streamProvider.getAppCookieManager();
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/439a0a40/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/URLStreamProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/URLStreamProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/URLStreamProviderTest.java
new file mode 100644
index 0000000..ebed4db
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/URLStreamProviderTest.java
@@ -0,0 +1,83 @@
+/**
+ * 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.ambari.server.controller.internal;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.net.HttpURLConnection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.createMockBuilder;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * URLStreamProvider tests.
+ */
+public class URLStreamProviderTest {
+
+  @Test
+  public void testProcessURL() throws Exception {
+    HttpURLConnection connection = createNiceMock(HttpURLConnection.class);
+    AppCookieManager appCookieManager = createNiceMock(AppCookieManager.class);
+
+    URLStreamProvider urlStreamProvider = createMockBuilder(URLStreamProvider.class).
+        withConstructor(Integer.TYPE, Integer.TYPE, String.class, String.class, String.class).
+        withArgs(1000, 1000, "path", "password", "type").
+        addMockedMethod("getAppCookieManager").
+        addMockedMethod("getConnection", String.class).
+        createMock();
+
+    expect(urlStreamProvider.getAppCookieManager()).andReturn(appCookieManager).anyTimes();
+    expect(urlStreamProvider.getConnection("spec")).andReturn(connection);
+
+    Map<String, List<String>> headerMap = new HashMap<String, List<String>>();
+    headerMap.put("Header1", Collections.singletonList("value"));
+    headerMap.put("Cookie", Collections.singletonList("FOO=bar"));
+
+    expect(appCookieManager.getCachedAppCookie("spec")).andReturn("APPCOOKIE=abcdef");
+
+    connection.setConnectTimeout(1000);
+    connection.setReadTimeout(1000);
+    connection.setRequestMethod("GET");
+
+    connection.setRequestProperty("Header1", "value");
+    connection.setRequestProperty("Cookie", "FOO=bar; APPCOOKIE=abcdef");
+
+    replay(urlStreamProvider, connection, appCookieManager);
+
+    Assert.assertEquals(connection, urlStreamProvider.processURL("spec", "GET", null, headerMap));
+
+    verify(urlStreamProvider, connection, appCookieManager);
+  }
+
+  @Test
+  public void testAppendCookie() throws Exception {
+    Assert.assertEquals("newCookie", URLStreamProvider.appendCookie(null, "newCookie"));
+    Assert.assertEquals("newCookie", URLStreamProvider.appendCookie("", "newCookie"));
+    Assert.assertEquals("oldCookie; newCookie", URLStreamProvider.appendCookie("oldCookie", "newCookie"));
+    Assert.assertEquals("oldCookie1; oldCookie2; newCookie", URLStreamProvider.appendCookie("oldCookie1; oldCookie2", "newCookie"));
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/439a0a40/ambari-server/src/test/java/org/apache/ambari/server/view/ViewAmbariStreamProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewAmbariStreamProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewAmbariStreamProviderTest.java
new file mode 100644
index 0000000..94f5e86
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewAmbariStreamProviderTest.java
@@ -0,0 +1,73 @@
+/**
+ * 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.ambari.server.view;
+
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.AmbariSessionManager;
+import org.apache.ambari.server.controller.internal.URLStreamProvider;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+public class ViewAmbariStreamProviderTest {
+
+  @Test
+  public void testReadFrom() throws Exception {
+    URLStreamProvider streamProvider = createNiceMock(URLStreamProvider.class);
+    AmbariSessionManager sessionManager = createNiceMock(AmbariSessionManager.class);
+    AmbariManagementController controller = createNiceMock(AmbariManagementController.class);
+
+    HttpURLConnection urlConnection = createNiceMock(HttpURLConnection.class);
+    InputStream inputStream = createNiceMock(InputStream.class);
+
+    Map<String, String> headers = new HashMap<String, String>();
+    headers.put("header", "headerValue");
+    headers.put("Cookie", "FOO=bar");
+
+    Map<String, List<String>> headerMap = new HashMap<String, List<String>>();
+    headerMap.put("header", Collections.singletonList("headerValue"));
+    headerMap.put("Cookie", Collections.singletonList("FOO=bar; AMBARISESSIONID=abcdefg"));
+
+    expect(sessionManager.getCurrentSessionId()).andReturn("abcdefg");
+    expect(sessionManager.getSessionCookie()).andReturn("AMBARISESSIONID");
+
+    expect(controller.getAmbariServerURI("/spec")).andReturn("http://c6401.ambari.apache.org:8080/spec");
+    expect(streamProvider.processURL("http://c6401.ambari.apache.org:8080/spec", "requestMethod", "params", headerMap)).andReturn(urlConnection);
+    expect(urlConnection.getInputStream()).andReturn(inputStream);
+
+    replay(streamProvider, sessionManager, controller, urlConnection, inputStream);
+
+    ViewAmbariStreamProvider viewAmbariStreamProvider = new ViewAmbariStreamProvider(streamProvider, sessionManager, controller);
+
+    Assert.assertEquals(inputStream, viewAmbariStreamProvider.readFrom("spec", "requestMethod", "params", headers, true));
+
+    verify(streamProvider, sessionManager, urlConnection, inputStream);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/439a0a40/ambari-server/src/test/java/org/apache/ambari/server/view/ViewContextImplTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewContextImplTest.java b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewContextImplTest.java
index 6bddf08..519d010 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewContextImplTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewContextImplTest.java
@@ -18,7 +18,6 @@
 
 package org.apache.ambari.server.view;
 
-import org.apache.ambari.server.controller.internal.URLStreamProvider;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.orm.entities.ViewEntity;
 import org.apache.ambari.server.orm.entities.ViewEntityTest;
@@ -30,11 +29,6 @@ import org.apache.ambari.view.ResourceProvider;
 import org.junit.Assert;
 import org.junit.Test;
 
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 
 import static org.easymock.EasyMock.createMockBuilder;
@@ -165,40 +159,45 @@ public class ViewContextImplTest {
     ViewEntity viewDefinition = ViewEntityTest.getViewEntity();
     ViewInstanceEntity viewInstanceDefinition = new ViewInstanceEntity(viewDefinition, instanceConfig);
     ViewRegistry viewRegistry = createNiceMock(ViewRegistry.class);
+    ViewURLStreamProvider urlStreamProvider = createNiceMock(ViewURLStreamProvider.class);
 
     ResourceProvider provider = createNiceMock(ResourceProvider.class);
     Resource.Type type = new Resource.Type("MY_VIEW/myType");
 
     viewInstanceDefinition.addResourceProvider(type, provider);
 
+    expect(viewRegistry.createURLStreamProvider()).andReturn(urlStreamProvider);
+
+    replay(viewRegistry);
+
     ViewContextImpl viewContext = new ViewContextImpl(viewInstanceDefinition, viewRegistry);
 
-    Assert.assertNotNull(viewContext.getURLStreamProvider());
+    Assert.assertEquals(urlStreamProvider, viewContext.getURLStreamProvider());
+
+    verify(viewRegistry);
   }
 
   @Test
-  public void testViewURLStreamProvider() throws Exception {
-
-    URLStreamProvider streamProvider = createNiceMock(URLStreamProvider.class);
-    HttpURLConnection urlConnection = createNiceMock(HttpURLConnection.class);
-    InputStream inputStream = createNiceMock(InputStream.class);
+  public void testGetAmbariStreamProvider() throws Exception {
+    InstanceConfig instanceConfig = InstanceConfigTest.getInstanceConfigs().get(0);
+    ViewEntity viewDefinition = ViewEntityTest.getViewEntity();
+    ViewInstanceEntity viewInstanceDefinition = new ViewInstanceEntity(viewDefinition, instanceConfig);
+    ViewRegistry viewRegistry = createNiceMock(ViewRegistry.class);
+    ViewAmbariStreamProvider ambariStreamProvider = createNiceMock(ViewAmbariStreamProvider.class);
 
-    Map<String, String> headers = new HashMap<String, String>();
-    headers.put("header", "headerValue");
+    ResourceProvider provider = createNiceMock(ResourceProvider.class);
+    Resource.Type type = new Resource.Type("MY_VIEW/myType");
 
-    Map<String, List<String>> headerMap = new HashMap<String, List<String>>();
-    headerMap.put("header", Collections.singletonList("headerValue"));
+    viewInstanceDefinition.addResourceProvider(type, provider);
 
-    expect(streamProvider.processURL("spec", "requestMethod", "params", headerMap)).andReturn(urlConnection);
-    expect(urlConnection.getInputStream()).andReturn(inputStream);
+    expect(viewRegistry.createAmbariStreamProvider()).andReturn(ambariStreamProvider);
 
-    replay(streamProvider, urlConnection, inputStream);
+    replay(viewRegistry);
 
-    ViewContextImpl.ViewURLStreamProvider viewURLStreamProvider =
-        new ViewContextImpl.ViewURLStreamProvider(streamProvider);
+    ViewContextImpl viewContext = new ViewContextImpl(viewInstanceDefinition, viewRegistry);
 
-    Assert.assertEquals(inputStream, viewURLStreamProvider.readFrom("spec", "requestMethod", "params", headers));
+    Assert.assertEquals(ambariStreamProvider, viewContext.getAmbariStreamProvider());
 
-    verify(streamProvider, urlConnection, inputStream);
+    verify(viewRegistry);
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/439a0a40/ambari-server/src/test/java/org/apache/ambari/server/view/ViewURLStreamProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewURLStreamProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewURLStreamProviderTest.java
new file mode 100644
index 0000000..3241e46
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewURLStreamProviderTest.java
@@ -0,0 +1,80 @@
+/**
+ * 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.ambari.server.view;
+
+import org.apache.ambari.server.controller.internal.AppCookieManager;
+import org.apache.ambari.server.controller.internal.URLStreamProvider;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+public class ViewURLStreamProviderTest {
+
+  @Test
+  public void testReadFrom() throws Exception {
+
+    URLStreamProvider streamProvider = createNiceMock(URLStreamProvider.class);
+    HttpURLConnection urlConnection = createNiceMock(HttpURLConnection.class);
+    InputStream inputStream = createNiceMock(InputStream.class);
+
+    Map<String, String> headers = new HashMap<String, String>();
+    headers.put("header", "headerValue");
+
+    Map<String, List<String>> headerMap = new HashMap<String, List<String>>();
+    headerMap.put("header", Collections.singletonList("headerValue"));
+
+    expect(streamProvider.processURL("spec", "requestMethod", "params", headerMap)).andReturn(urlConnection);
+    expect(urlConnection.getInputStream()).andReturn(inputStream);
+
+    replay(streamProvider, urlConnection, inputStream);
+
+    ViewURLStreamProvider viewURLStreamProvider = new ViewURLStreamProvider(streamProvider);
+
+    Assert.assertEquals(inputStream, viewURLStreamProvider.readFrom("spec", "requestMethod", "params", headers));
+
+    verify(streamProvider, urlConnection, inputStream);
+  }
+
+  @Test
+  public void testGetAppCookieManager() throws Exception {
+    URLStreamProvider streamProvider = createNiceMock(URLStreamProvider.class);
+    AppCookieManager appCookieManager = createNiceMock(AppCookieManager.class);
+
+    expect(streamProvider.getAppCookieManager()).andReturn(appCookieManager);
+
+    replay(streamProvider, appCookieManager);
+
+    ViewURLStreamProvider viewURLStreamProvider = new ViewURLStreamProvider(streamProvider);
+
+    Assert.assertEquals(appCookieManager, viewURLStreamProvider.getAppCookieManager());
+
+    verify(streamProvider, appCookieManager);
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/439a0a40/ambari-views/src/main/java/org/apache/ambari/view/AmbariStreamProvider.java
----------------------------------------------------------------------
diff --git a/ambari-views/src/main/java/org/apache/ambari/view/AmbariStreamProvider.java b/ambari-views/src/main/java/org/apache/ambari/view/AmbariStreamProvider.java
new file mode 100644
index 0000000..0f8367a
--- /dev/null
+++ b/ambari-views/src/main/java/org/apache/ambari/view/AmbariStreamProvider.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.ambari.view;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+
+/**
+ * Provider of an input stream for a request to the Ambari server.
+ */
+public interface AmbariStreamProvider {
+  /**
+   * Read from the input stream specified by the given path on the Ambari server.
+   *
+   * @param path              the String to parse as an Ambari endpoint (e.g. /api/v1/users)
+   * @param requestMethod     the HTTP method (GET,POST,PUT,etc.).
+   * @param params            the body of the request; may be null
+   * @param headers           the headers of the request; may be null
+   * @param useAmbariSession  indicates that the current Ambari session cookie should be set for the request
+   *
+   * @return the input stream
+   *
+   * @throws java.io.IOException if an error occurred connecting to the server
+   */
+  public InputStream readFrom(String path, String requestMethod, String params,
+                              Map<String, String> headers, boolean useAmbariSession)
+      throws IOException;
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/439a0a40/ambari-views/src/main/java/org/apache/ambari/view/ViewContext.java
----------------------------------------------------------------------
diff --git a/ambari-views/src/main/java/org/apache/ambari/view/ViewContext.java b/ambari-views/src/main/java/org/apache/ambari/view/ViewContext.java
index 97385d3..1897a0c 100644
--- a/ambari-views/src/main/java/org/apache/ambari/view/ViewContext.java
+++ b/ambari-views/src/main/java/org/apache/ambari/view/ViewContext.java
@@ -20,7 +20,6 @@ package org.apache.ambari.view;
 
 import java.util.Collection;
 import java.util.Map;
-import org.apache.ambari.view.HttpImpersonator;
 
 /**
  * Context object available to the view components to provide access to
@@ -149,6 +148,13 @@ public interface ViewContext {
   public URLStreamProvider getURLStreamProvider();
 
   /**
+   * Get an Ambari stream provider.
+   *
+   * @return an Ambari stream provider
+   */
+  public AmbariStreamProvider getAmbariStreamProvider();
+
+  /**
    * Get a data store for view persistence entities.
    *
    * @return a data store; null if no instance is associated


Mime
View raw message