falcon-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sowmya...@apache.org
Subject [1/3] falcon git commit: FALCON-1027 Falcon proxy user support. Contributed by Sowmya Ramesh.
Date Tue, 15 Sep 2015 01:46:38 GMT
Repository: falcon
Updated Branches:
  refs/heads/master cbd7c807e -> d8fbec9f9


http://git-wip-us.apache.org/repos/asf/falcon/blob/d8fbec9f/prism/src/main/java/org/apache/falcon/security/FalconAuthorizationFilter.java
----------------------------------------------------------------------
diff --git a/prism/src/main/java/org/apache/falcon/security/FalconAuthorizationFilter.java b/prism/src/main/java/org/apache/falcon/security/FalconAuthorizationFilter.java
index 15e94cd..542e956 100644
--- a/prism/src/main/java/org/apache/falcon/security/FalconAuthorizationFilter.java
+++ b/prism/src/main/java/org/apache/falcon/security/FalconAuthorizationFilter.java
@@ -49,6 +49,7 @@ import java.io.IOException;
 public class FalconAuthorizationFilter implements Filter {
 
     private static final Logger LOG = LoggerFactory.getLogger(FalconAuthorizationFilter.class);
+    private static final String DO_AS_PARAM = "doAs";
 
     private boolean isAuthorizationEnabled;
     private AuthorizationProvider authorizationProvider;
@@ -81,8 +82,9 @@ public class FalconAuthorizationFilter implements Filter {
                 authorizationProvider.authorizeResource(requestParts.getResource(),
                         requestParts.getAction(), requestParts.getEntityType(),
                         requestParts.getEntityName(), authenticatedUGI);
+                String doAsUser = request.getParameter(DO_AS_PARAM);
                 tryProxy(authenticatedUGI,
-                    requestParts.getEntityType(), requestParts.getEntityName());
+                    requestParts.getEntityType(), requestParts.getEntityName(), doAsUser);
                 LOG.info("Authorization succeeded for user={}, proxy={}",
                     authenticatedUGI.getShortUserName(), CurrentUser.getUser());
             } catch (AuthorizationException e) {
@@ -133,7 +135,8 @@ public class FalconAuthorizationFilter implements Filter {
     }
 
     private void tryProxy(UserGroupInformation authenticatedUGI,
-                          String entityType, String entityName) throws IOException {
+                          String entityType, String entityName,
+                          final String doAsUser) throws IOException {
         if (entityType == null || entityName == null) {
             return;
         }
@@ -141,7 +144,7 @@ public class FalconAuthorizationFilter implements Filter {
         try {
             EntityType type = EntityType.getEnum(entityType);
             Entity entity = EntityUtil.getEntity(type, entityName);
-            SecurityUtil.tryProxy(entity);
+            SecurityUtil.tryProxy(entity, doAsUser);
         } catch (FalconException ignore) {
             // do nothing
         }

http://git-wip-us.apache.org/repos/asf/falcon/blob/d8fbec9f/prism/src/main/java/org/apache/falcon/security/HostnameFilter.java
----------------------------------------------------------------------
diff --git a/prism/src/main/java/org/apache/falcon/security/HostnameFilter.java b/prism/src/main/java/org/apache/falcon/security/HostnameFilter.java
new file mode 100644
index 0000000..19e7bf4
--- /dev/null
+++ b/prism/src/main/java/org/apache/falcon/security/HostnameFilter.java
@@ -0,0 +1,105 @@
+/**
+ * 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.falcon.security;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Filter that resolves the requester hostname.
+ */
+public class HostnameFilter implements Filter {
+    private static final Logger LOG = LoggerFactory.getLogger(HostnameFilter.class);
+
+    static final ThreadLocal<String> HOSTNAME_TL = new ThreadLocal<>();
+
+    /**
+     * Initializes the filter.
+     *
+     * @param config filter configuration.
+     *
+     * @throws javax.servlet.ServletException thrown if the filter could not be initialized.
+     */
+    @Override
+    public void init(FilterConfig config) throws ServletException {
+    }
+
+    /**
+     * Resolves the requester hostname and delegates the request to the chain.
+     * <p>
+     * The requester hostname is available via the {@link #get} method.
+     *
+     * @param request servlet request.
+     * @param response servlet response.
+     * @param chain filter chain.
+     *
+     * @throws java.io.IOException thrown if an IO error occurs.
+     * @throws ServletException thrown if a servlet error occurs.
+     */
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+        throws IOException, ServletException {
+        try {
+            String hostname;
+            try {
+                String address = request.getRemoteAddr();
+                if (address != null) {
+                    hostname = InetAddress.getByName(address).getCanonicalHostName();
+                } else {
+                    LOG.warn("Request remote address is NULL");
+                    hostname = "???";
+                }
+            } catch (UnknownHostException ex) {
+                LOG.warn("Request remote address could not be resolved, {}", ex.toString(), ex);
+                hostname = "???";
+            }
+            HOSTNAME_TL.set(hostname);
+            chain.doFilter(request, response);
+        } finally {
+            HOSTNAME_TL.remove();
+        }
+    }
+
+    /**
+     * Returns the requester hostname.
+     *
+     * @return the requester hostname.
+     */
+    public static String get() {
+        return HOSTNAME_TL.get();
+    }
+
+    /**
+     * Destroys the filter.
+     * <p>
+     * This implementation is a NOP.
+     */
+    @Override
+    public void destroy() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/falcon/blob/d8fbec9f/prism/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/prism/src/main/webapp/WEB-INF/web.xml b/prism/src/main/webapp/WEB-INF/web.xml
index 551bf56..7c1a7ad 100644
--- a/prism/src/main/webapp/WEB-INF/web.xml
+++ b/prism/src/main/webapp/WEB-INF/web.xml
@@ -31,6 +31,11 @@
     </filter>
 
     <filter>
+        <filter-name>hostnameFilter</filter-name>
+        <filter-class>org.apache.falcon.security.HostnameFilter</filter-class>
+    </filter>
+
+    <filter>
         <filter-name>authentication</filter-name>
         <filter-class>org.apache.falcon.security.FalconAuthenticationFilter</filter-class>
     </filter>
@@ -46,6 +51,11 @@
     </filter-mapping>
 
     <filter-mapping>
+        <filter-name>hostnameFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+
+    <filter-mapping>
         <filter-name>authentication</filter-name>
         <servlet-name>FalconProxyAPI</servlet-name>
     </filter-mapping>

http://git-wip-us.apache.org/repos/asf/falcon/blob/d8fbec9f/prism/src/test/java/org/apache/falcon/resource/EntityManagerTest.java
----------------------------------------------------------------------
diff --git a/prism/src/test/java/org/apache/falcon/resource/EntityManagerTest.java b/prism/src/test/java/org/apache/falcon/resource/EntityManagerTest.java
index ea2c40f..5fabcf3 100644
--- a/prism/src/test/java/org/apache/falcon/resource/EntityManagerTest.java
+++ b/prism/src/test/java/org/apache/falcon/resource/EntityManagerTest.java
@@ -131,7 +131,7 @@ public class EntityManagerTest extends AbstractEntityManager {
          * Only one entity should be returned when the auth is enabled.
          */
         try {
-            getEntityList("", "", "", "process", "", "", "", "", 0, 10);
+            getEntityList("", "", "", "process", "", "", "", "", 0, 10, "");
             Assert.fail();
         } catch (Throwable ignore) {
             // do nothing
@@ -148,7 +148,7 @@ public class EntityManagerTest extends AbstractEntityManager {
         Entity process2 = buildProcess("processAuthUser", System.getProperty("user.name"), "", "");
         configStore.publish(EntityType.PROCESS, process2);
 
-        EntityList entityList = this.getEntityList("", "", "", "process", "", "", "", "asc", 0, 10);
+        EntityList entityList = this.getEntityList("", "", "", "process", "", "", "", "asc", 0, 10, "");
         Assert.assertNotNull(entityList.getElements());
         Assert.assertEquals(entityList.getElements().length, 1);
 
@@ -157,7 +157,7 @@ public class EntityManagerTest extends AbstractEntityManager {
          */
         StartupProperties.get().setProperty("falcon.security.authorization.enabled", "true");
         CurrentUser.authenticate(System.getProperty("user.name"));
-        entityList = this.getEntityList("", "", "", "process", "", "", "", "desc", 0, 10);
+        entityList = this.getEntityList("", "", "", "process", "", "", "", "desc", 0, 10, "");
         Assert.assertNotNull(entityList.getElements());
         Assert.assertEquals(entityList.getElements().length, 1);
 
@@ -172,7 +172,8 @@ public class EntityManagerTest extends AbstractEntityManager {
         Entity process2 = buildProcess("processAuthUserFilterBy", System.getProperty("user.name"), "", "USER-DATA");
         configStore.publish(EntityType.PROCESS, process2);
 
-        EntityList entityList = this.getEntityList("", "", "", "process", "", "PIPELINES:USER-DATA", "", "asc", 0, 10);
+        EntityList entityList = this.getEntityList("", "", "", "process", "",
+                "PIPELINES:USER-DATA", "", "asc", 0, 10, "");
         Assert.assertNotNull(entityList.getElements());
         Assert.assertEquals(entityList.getElements().length, 1);
         Assert.assertNotNull(entityList.getElements()[0].pipeline);
@@ -183,7 +184,7 @@ public class EntityManagerTest extends AbstractEntityManager {
          */
         StartupProperties.get().setProperty("falcon.security.authorization.enabled", "true");
         CurrentUser.authenticate(System.getProperty("user.name"));
-        entityList = this.getEntityList("", "", "", "process", "", "PIPELINES:USER-DATA", "", "desc", 0, 10);
+        entityList = this.getEntityList("", "", "", "process", "", "PIPELINES:USER-DATA", "", "desc", 0, 10, "");
         Assert.assertNotNull(entityList.getElements());
         Assert.assertEquals(entityList.getElements().length, 1);
         Assert.assertNotNull(entityList.getElements()[0].pipeline);
@@ -222,7 +223,7 @@ public class EntityManagerTest extends AbstractEntityManager {
         configStore.publish(EntityType.PROCESS, process4);
 
         EntityList entityList = this.getEntityList("tags", "", "", "process", "", "PIPELINES:dataReplicationPipeline",
-                "name", "desc", 1, 1);
+                "name", "desc", 1, 1, "");
         Assert.assertNotNull(entityList.getElements());
         Assert.assertEquals(entityList.getElements().length, 1);
         Assert.assertEquals(entityList.getElements()[0].name, "process1");
@@ -232,7 +233,7 @@ public class EntityManagerTest extends AbstractEntityManager {
 
 
         entityList = this.getEntityList("pipelines", "", "", "process",
-                "consumer=consumer@xyz.com, owner=producer@xyz.com", "", "name", "", 0, 2);
+                "consumer=consumer@xyz.com, owner=producer@xyz.com", "", "name", "", 0, 2, "");
         Assert.assertNotNull(entityList.getElements());
         Assert.assertEquals(entityList.getElements().length, 2);
         Assert.assertEquals(entityList.getElements()[1].name, "process2");
@@ -241,17 +242,17 @@ public class EntityManagerTest extends AbstractEntityManager {
         Assert.assertEquals(entityList.getElements()[0].tag, null);
 
         entityList = this.getEntityList("pipelines", "", "", "process",
-                "consumer=consumer@xyz.com, owner=producer@xyz.com", "", "name", "", 10, 2);
+                "consumer=consumer@xyz.com, owner=producer@xyz.com", "", "name", "", 10, 2, "");
         Assert.assertEquals(entityList.getElements().length, 0);
 
         entityList = this.getEntityList("pipelines", "", "", "process",
-                "owner=producer@xyz.com", "", "name", "", 1, 2);
+                "owner=producer@xyz.com", "", "name", "", 1, 2, "");
         Assert.assertEquals(entityList.getElements().length, 2);
 
         // Test negative value for numResults, should throw an exception.
         try {
             this.getEntityList("pipelines", "", "", "process",
-                    "consumer=consumer@xyz.com, owner=producer@xyz.com", "", "name", "", 10, -1);
+                    "consumer=consumer@xyz.com, owner=producer@xyz.com", "", "name", "", 10, -1, "");
             Assert.assertTrue(false);
         } catch (Throwable e) {
             Assert.assertTrue(true);
@@ -260,7 +261,7 @@ public class EntityManagerTest extends AbstractEntityManager {
         // Test invalid entry for sortOrder
         try {
             this.getEntityList("pipelines", "", "", "process",
-                    "consumer=consumer@xyz.com, owner=producer@xyz.com", "", "name", "invalid", 10, 2);
+                    "consumer=consumer@xyz.com, owner=producer@xyz.com", "", "name", "invalid", 10, 2, "");
             Assert.assertTrue(false);
         } catch (Throwable e) {
             Assert.assertTrue(true);
@@ -287,18 +288,18 @@ public class EntityManagerTest extends AbstractEntityManager {
         Entity process5 = buildProcess("Process5", user, "category=usHealthcarePlans,department=billingDepartment", "");
         configStore.publish(EntityType.PROCESS, process5);
 
-        EntityList entityList = this.getEntityList("", "sample", "health,billing", "", "", "", "name", "", 0, 10);
+        EntityList entityList = this.getEntityList("", "sample", "health,billing", "", "", "", "name", "", 0, 10, "");
         Assert.assertNotNull(entityList.getElements());
         Assert.assertEquals(entityList.getElements().length, 2);
         Assert.assertEquals(entityList.getElements()[0].name, "SampleProcess1");
         Assert.assertEquals(entityList.getElements()[1].name, "SampleProcess2");
 
-        entityList = this.getEntityList("", "sample4", "", "", "", "", "", "", 0, 10);
+        entityList = this.getEntityList("", "sample4", "", "", "", "", "", "", 0, 10, "");
         Assert.assertNotNull(entityList.getElements());
         Assert.assertEquals(entityList.getElements().length, 1);
         Assert.assertEquals(entityList.getElements()[0].name, "SampleProcess4");
 
-        entityList = this.getEntityList("", "", "health,us", "", "", "", "name", "", 0, 10);
+        entityList = this.getEntityList("", "", "health,us", "", "", "", "name", "", 0, 10, "");
         Assert.assertNotNull(entityList.getElements());
         Assert.assertEquals(entityList.getElements().length, 2);
         Assert.assertEquals(entityList.getElements()[0].name, "Process5");

http://git-wip-us.apache.org/repos/asf/falcon/blob/d8fbec9f/prism/src/test/java/org/apache/falcon/security/FalconAuthenticationFilterTest.java
----------------------------------------------------------------------
diff --git a/prism/src/test/java/org/apache/falcon/security/FalconAuthenticationFilterTest.java b/prism/src/test/java/org/apache/falcon/security/FalconAuthenticationFilterTest.java
index df85529..5627e68 100644
--- a/prism/src/test/java/org/apache/falcon/security/FalconAuthenticationFilterTest.java
+++ b/prism/src/test/java/org/apache/falcon/security/FalconAuthenticationFilterTest.java
@@ -18,8 +18,12 @@
 
 package org.apache.falcon.security;
 
+import org.apache.falcon.service.GroupsService;
+import org.apache.falcon.service.ProxyUserService;
+import org.apache.falcon.service.Services;
 import org.apache.falcon.util.FalconTestUtil;
 import org.apache.falcon.util.StartupProperties;
+import org.apache.falcon.util.RuntimeProperties;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler;
@@ -27,6 +31,7 @@ import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.testng.Assert;
+import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
@@ -37,6 +42,7 @@ import javax.servlet.FilterConfig;
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.security.AccessControlException;
 import java.util.Map;
 import java.util.Properties;
 import java.util.concurrent.ConcurrentHashMap;
@@ -46,6 +52,9 @@ import java.util.concurrent.ConcurrentHashMap;
  * Test for FalconAuthenticationFilter using mock objects.
  */
 public class FalconAuthenticationFilterTest {
+    private ProxyUserService proxyUserService;
+
+    private GroupsService groupsService;
 
     @Mock
     private HttpServletRequest mockRequest;
@@ -62,9 +71,28 @@ public class FalconAuthenticationFilterTest {
     @Mock
     private UserGroupInformation mockUgi;
 
+    @Mock
+    private HostnameFilter mockHostnameFilter;
+
     @BeforeClass
-    public void init() {
+    public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
+        Services.get().register(new ProxyUserService());
+        Services.get().register(new GroupsService());
+        groupsService = Services.get().getService(GroupsService.SERVICE_NAME);
+        proxyUserService = Services.get().getService(ProxyUserService.SERVICE_NAME);
+        groupsService.init();
+
+        RuntimeProperties.get().setProperty("falcon.service.ProxyUserService.proxyuser.foo.hosts", "*");
+        RuntimeProperties.get().setProperty("falcon.service.ProxyUserService.proxyuser.foo.groups", "*");
+        proxyUserService.init();
+    }
+
+    @AfterClass
+    public void tearDown() throws Exception {
+        proxyUserService.destroy();
+        groupsService.destroy();
+        Services.get().reset();
     }
 
     @BeforeMethod
@@ -215,4 +243,57 @@ public class FalconAuthenticationFilterTest {
         Properties properties = filter.getConfiguration(FalconAuthenticationFilter.FALCON_PREFIX, null);
         Assert.assertEquals(properties.get(KerberosAuthenticationHandler.PRINCIPAL), principal);
     }
+
+    @Test
+    public void testDoFilterWithEmptyDoAsUser() throws Exception {
+        Filter filter = new FalconAuthenticationFilter();
+        synchronized (StartupProperties.get()) {
+            filter.init(mockConfig);
+        }
+
+        CurrentUser.authenticate("testuser");
+        Mockito.when(mockRequest.getMethod()).thenReturn("POST");
+        Mockito.when(mockRequest.getQueryString()).thenReturn("user.name=testuser");
+        Mockito.when(mockRequest.getRemoteUser()).thenReturn("testuser");
+        Mockito.when(mockRequest.getParameter(FalconAuthenticationFilter.DO_AS_PARAM)).thenReturn("");
+        filter.doFilter(mockRequest, mockResponse, mockChain);
+        Assert.assertEquals(CurrentUser.getUser(), "testuser");
+    }
+
+    @Test
+    public void testDoFilterWithDoAsUser() throws Exception {
+        Filter filter = new FalconAuthenticationFilter();
+        HostnameFilter.HOSTNAME_TL.set("localhost");
+        synchronized (StartupProperties.get()) {
+            filter.init(mockConfig);
+        }
+
+        CurrentUser.authenticate("foo");
+        Mockito.when(mockRequest.getMethod()).thenReturn("POST");
+        Mockito.when(mockRequest.getQueryString()).thenReturn("user.name=foo");
+        Mockito.when(mockRequest.getRemoteUser()).thenReturn("foo");
+        Mockito.when(mockRequest.getParameter(FalconAuthenticationFilter.DO_AS_PARAM)).thenReturn("doAsProxyUser");
+        Mockito.when(mockRequest.getMethod()).thenReturn("POST");
+        filter.doFilter(mockRequest, mockResponse, mockChain);
+        Assert.assertEquals(CurrentUser.getUser(), "doAsProxyUser");
+    }
+
+    @Test (expectedExceptions = AccessControlException.class,
+           expectedExceptionsMessageRegExp = "User .* not defined as proxyuser.*")
+    public void testDoFilterWithInvalidProxyUser() throws Exception {
+        Filter filter = new FalconAuthenticationFilter();
+        HostnameFilter.HOSTNAME_TL.set("localhost");
+        synchronized (StartupProperties.get()) {
+            filter.init(mockConfig);
+        }
+
+        CurrentUser.authenticate("testuser");
+        Mockito.when(mockRequest.getMethod()).thenReturn("POST");
+        Mockito.when(mockRequest.getQueryString()).thenReturn("user.name=testuser");
+        Mockito.when(mockRequest.getRemoteUser()).thenReturn("testuser");
+        Mockito.when(mockRequest.getParameter(FalconAuthenticationFilter.DO_AS_PARAM)).thenReturn("doAsProxyUser");
+        Mockito.when(mockRequest.getMethod()).thenReturn("POST");
+        filter.doFilter(mockRequest, mockResponse, mockChain);
+        Assert.assertEquals(CurrentUser.getUser(), "doAsProxyUser");
+    }
 }

http://git-wip-us.apache.org/repos/asf/falcon/blob/d8fbec9f/prism/src/test/java/org/apache/falcon/security/HostnameFilterTest.java
----------------------------------------------------------------------
diff --git a/prism/src/test/java/org/apache/falcon/security/HostnameFilterTest.java b/prism/src/test/java/org/apache/falcon/security/HostnameFilterTest.java
new file mode 100644
index 0000000..2606ece
--- /dev/null
+++ b/prism/src/test/java/org/apache/falcon/security/HostnameFilterTest.java
@@ -0,0 +1,93 @@
+/**
+ * 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.falcon.security;
+
+import org.apache.hadoop.util.Shell;
+import org.mockito.Mockito;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * Unit tests for HostnameFilter.
+ */
+public class HostnameFilterTest {
+
+    @Test
+    public void testHostname() throws Exception {
+        ServletRequest request = Mockito.mock(ServletRequest.class);
+        Mockito.when(request.getRemoteAddr()).thenReturn("localhost");
+
+        ServletResponse response = Mockito.mock(ServletResponse.class);
+
+        final AtomicBoolean invoked = new AtomicBoolean();
+
+        FilterChain chain = new FilterChain() {
+            @Override
+            public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
+                throws IOException, ServletException {
+                Assert.assertTrue(HostnameFilter.get().
+                        contains(Shell.WINDOWS ? "127.0.0.1" : "localhost"));
+                invoked.set(true);
+            }
+        };
+
+        Filter filter = new HostnameFilter();
+        filter.init(null);
+        Assert.assertNull(HostnameFilter.get());
+        filter.doFilter(request, response, chain);
+        Assert.assertTrue(invoked.get());
+        Assert.assertNull(HostnameFilter.get());
+        filter.destroy();
+    }
+
+    @Test
+    public void testMissingHostname() throws Exception {
+        ServletRequest request = Mockito.mock(ServletRequest.class);
+        Mockito.when(request.getRemoteAddr()).thenReturn(null);
+
+        ServletResponse response = Mockito.mock(ServletResponse.class);
+
+        final AtomicBoolean invoked = new AtomicBoolean();
+
+        FilterChain chain = new FilterChain() {
+            @Override
+            public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
+                throws IOException, ServletException {
+                Assert.assertTrue(HostnameFilter.get().contains("???"));
+                invoked.set(true);
+            }
+        };
+
+        Filter filter = new HostnameFilter();
+        filter.init(null);
+        Assert.assertNull(HostnameFilter.get());
+        filter.doFilter(request, response, chain);
+        Assert.assertTrue(invoked.get());
+        Assert.assertNull(HostnameFilter.get());
+        filter.destroy();
+    }
+}

http://git-wip-us.apache.org/repos/asf/falcon/blob/d8fbec9f/src/conf/runtime.properties
----------------------------------------------------------------------
diff --git a/src/conf/runtime.properties b/src/conf/runtime.properties
index b31e6a3..1260f55 100644
--- a/src/conf/runtime.properties
+++ b/src/conf/runtime.properties
@@ -43,3 +43,19 @@ falcon.current.colo=local
 
 # If true, Falcon skips oozie dryrun while scheduling entities.
 *.falcon.skip.dryrun=false
+
+######### Proxyuser Configuration Start #########
+
+#List of hosts the '#USER#' user is allowed to perform 'doAs 'operations from. The '#USER#' must be replaced with the
+#username of the user who is allowed to perform 'doAs' operations. The value can be the '*' wildcard or a list of
+#comma separated hostnames
+
+*.falcon.service.ProxyUserService.proxyuser.#USER#.hosts=*
+
+#List of groups the '#USER#' user is allowed to 'doAs 'operations. The '#USER#' must be replaced with the
+#username of the user who is allowed to perform 'doAs' operations. The value can be the '*' wildcard or a list of
+#comma separated groups
+
+*.falcon.service.ProxyUserService.proxyuser.#USER#.groups=*
+
+######### Proxyuser Configuration End #########

http://git-wip-us.apache.org/repos/asf/falcon/blob/d8fbec9f/src/conf/startup.properties
----------------------------------------------------------------------
diff --git a/src/conf/startup.properties b/src/conf/startup.properties
index 9925373..ca55689 100644
--- a/src/conf/startup.properties
+++ b/src/conf/startup.properties
@@ -41,7 +41,9 @@
                         org.apache.falcon.rerun.service.RetryService,\
                         org.apache.falcon.rerun.service.LateRunService,\
                         org.apache.falcon.metadata.MetadataMappingService,\
-                        org.apache.falcon.service.LogCleanupService
+                        org.apache.falcon.service.LogCleanupService,\
+                        org.apache.falcon.service.GroupsService,\
+                        org.apache.falcon.service.ProxyUserService
 
 ##### Prism Services #####
 prism.application.services=org.apache.falcon.entity.store.ConfigurationStore

http://git-wip-us.apache.org/repos/asf/falcon/blob/d8fbec9f/unit/src/main/java/org/apache/falcon/unit/FalconUnitClient.java
----------------------------------------------------------------------
diff --git a/unit/src/main/java/org/apache/falcon/unit/FalconUnitClient.java b/unit/src/main/java/org/apache/falcon/unit/FalconUnitClient.java
index eb65cb3..d907683 100644
--- a/unit/src/main/java/org/apache/falcon/unit/FalconUnitClient.java
+++ b/unit/src/main/java/org/apache/falcon/unit/FalconUnitClient.java
@@ -78,7 +78,7 @@ public class FalconUnitClient extends AbstractFalconClient {
      * @return boolean
      */
     @Override
-    public APIResult submit(String type, String filePath) throws IOException, FalconCLIException {
+    public APIResult submit(String type, String filePath, String doAsUser) throws IOException, FalconCLIException {
         try {
             EntityType entityType = EntityType.getEnum(type);
             InputStream entityStream = FalconUnitHelper.getFileInputStream(filePath);
@@ -118,8 +118,8 @@ public class FalconUnitClient extends AbstractFalconClient {
      * @throws FalconException
      */
     @Override
-    public APIResult schedule(EntityType entityType, String entityName,
-                              String cluster, Boolean skipDryRun) throws FalconCLIException {
+    public APIResult schedule(EntityType entityType, String entityName, String cluster,
+                              Boolean skipDryRun, String doAsUser) throws FalconCLIException {
         return schedule(entityType, entityName, null, 0, cluster, skipDryRun);
     }
 

http://git-wip-us.apache.org/repos/asf/falcon/blob/d8fbec9f/unit/src/test/java/org/apache/falcon/unit/FalconUnitTestBase.java
----------------------------------------------------------------------
diff --git a/unit/src/test/java/org/apache/falcon/unit/FalconUnitTestBase.java b/unit/src/test/java/org/apache/falcon/unit/FalconUnitTestBase.java
index 997b301..df73628 100644
--- a/unit/src/test/java/org/apache/falcon/unit/FalconUnitTestBase.java
+++ b/unit/src/test/java/org/apache/falcon/unit/FalconUnitTestBase.java
@@ -125,7 +125,7 @@ public class FalconUnitTestBase {
         fs.mkdirs(new Path(STAGING_PATH), HadoopClientFactory.ALL_PERMISSION);
         fs.mkdirs(new Path(WORKING_PATH), HadoopClientFactory.READ_EXECUTE_PERMISSION);
         String clusterXmlPath = overlayParametersOverTemplate(CLUSTER_TEMPLATE, props);
-        APIResult result = falconUnitClient.submit(CLUSTER, clusterXmlPath);
+        APIResult result = falconUnitClient.submit(CLUSTER, clusterXmlPath, "");
         return true ? APIResult.Status.SUCCEEDED.equals(result.getStatus()) : false;
     }
 
@@ -138,7 +138,7 @@ public class FalconUnitTestBase {
     }
 
     public APIResult submit(String entityType, String filePath) throws FalconCLIException, IOException {
-        return falconUnitClient.submit(entityType, filePath);
+        return falconUnitClient.submit(entityType, filePath, "");
     }
 
     public APIResult submitProcess(String filePath, String appDirectory) throws IOException, FalconCLIException {

http://git-wip-us.apache.org/repos/asf/falcon/blob/d8fbec9f/webapp/pom.xml
----------------------------------------------------------------------
diff --git a/webapp/pom.xml b/webapp/pom.xml
index ce37634..828f7f5 100644
--- a/webapp/pom.xml
+++ b/webapp/pom.xml
@@ -401,6 +401,28 @@
             </plugin>
 
             <plugin>
+                <groupId>com.google.code.maven-replacer-plugin</groupId>
+                <artifactId>replacer</artifactId>
+                <version>1.5.3</version>
+                <executions>
+                    <execution>
+                        <phase>generate-test-resources</phase>
+                        <goals>
+                            <goal>replace</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <includes>
+                        <include>${project.build.directory}/test-classes/runtime.properties</include>
+                        <include>${project.build.directory}/webapps/oozie/conf/oozie-site.xml</include>
+                    </includes>
+                    <token>#USER#</token>
+                    <value>${user.name}</value>
+                </configuration>
+            </plugin>
+
+            <plugin>
                 <groupId>org.mortbay.jetty</groupId>
                 <artifactId>maven-jetty-plugin</artifactId>
                 <version>${jetty.version}</version>

http://git-wip-us.apache.org/repos/asf/falcon/blob/d8fbec9f/webapp/src/conf/oozie/conf/oozie-site.xml
----------------------------------------------------------------------
diff --git a/webapp/src/conf/oozie/conf/oozie-site.xml b/webapp/src/conf/oozie/conf/oozie-site.xml
index ded4873..8545ef9 100644
--- a/webapp/src/conf/oozie/conf/oozie-site.xml
+++ b/webapp/src/conf/oozie/conf/oozie-site.xml
@@ -338,8 +338,6 @@
 
     <!-- Proxyuser Configuration -->
 
-    <!--
-
     <property>
         <name>oozie.service.ProxyUserService.proxyuser.#USER#.hosts</name>
         <value>*</value>
@@ -374,7 +372,7 @@
         </description>
     </property>
 
-    -->
+
 
     <property>
         <name>oozie.base.url</name>

http://git-wip-us.apache.org/repos/asf/falcon/blob/d8fbec9f/webapp/src/main/java/org/apache/falcon/resource/SchedulableEntityManager.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/falcon/resource/SchedulableEntityManager.java b/webapp/src/main/java/org/apache/falcon/resource/SchedulableEntityManager.java
index 1f8cc1b..3bafb25 100644
--- a/webapp/src/main/java/org/apache/falcon/resource/SchedulableEntityManager.java
+++ b/webapp/src/main/java/org/apache/falcon/resource/SchedulableEntityManager.java
@@ -76,13 +76,14 @@ public class SchedulableEntityManager extends AbstractSchedulableEntityManager {
                                     @DefaultValue("") @QueryParam("orderBy") String orderBy,
                                     @DefaultValue("asc") @QueryParam("sortOrder") String sortOrder,
                                     @DefaultValue("0") @QueryParam("offset") Integer offset,
-                                    @QueryParam("numResults") Integer resultsPerPage) {
+                                    @QueryParam("numResults") Integer resultsPerPage,
+                                    @DefaultValue("") @QueryParam("doAs") String doAsUser) {
         if (StringUtils.isNotEmpty(type)) {
             type = type.substring(1);
         }
         resultsPerPage = resultsPerPage == null ? getDefaultResultsPerPage() : resultsPerPage;
         return super.getEntityList(fields, nameSubsequence, tagKeywords, type, tags, filterBy,
-                orderBy, sortOrder, offset, resultsPerPage);
+                orderBy, sortOrder, offset, resultsPerPage, doAsUser);
     }
 
     @GET
@@ -102,9 +103,10 @@ public class SchedulableEntityManager extends AbstractSchedulableEntityManager {
             @DefaultValue("asc") @QueryParam("sortOrder") String entitySortOrder,
             @DefaultValue("0") @QueryParam("offset") Integer entityOffset,
             @DefaultValue("10") @QueryParam("numResults") Integer numEntities,
-            @DefaultValue("7") @QueryParam("numInstances") Integer numInstanceResults) {
+            @DefaultValue("7") @QueryParam("numInstances") Integer numInstanceResults,
+            @DefaultValue("") @QueryParam("doAs") final String doAsUser) {
         return super.getEntitySummary(type, cluster, startStr, endStr, fields, entityFilter, entityTags,
-                entityOrderBy, entitySortOrder, entityOffset, numEntities, numInstanceResults);
+                entityOrderBy, entitySortOrder, entityOffset, numEntities, numInstanceResults, doAsUser);
     }
     //RESUME CHECKSTYLE CHECK ParameterNumberCheck
 

http://git-wip-us.apache.org/repos/asf/falcon/blob/d8fbec9f/webapp/src/main/webapp/WEB-INF/distributed/web.xml
----------------------------------------------------------------------
diff --git a/webapp/src/main/webapp/WEB-INF/distributed/web.xml b/webapp/src/main/webapp/WEB-INF/distributed/web.xml
index 31d78a2..4741897 100644
--- a/webapp/src/main/webapp/WEB-INF/distributed/web.xml
+++ b/webapp/src/main/webapp/WEB-INF/distributed/web.xml
@@ -31,6 +31,11 @@
     </filter>
 
     <filter>
+        <filter-name>hostnameFilter</filter-name>
+        <filter-class>org.apache.falcon.security.HostnameFilter</filter-class>
+    </filter>
+
+    <filter>
         <filter-name>authentication</filter-name>
         <filter-class>org.apache.falcon.security.FalconAuthenticationFilter</filter-class>
     </filter>
@@ -51,6 +56,11 @@
     </filter-mapping>
 
     <filter-mapping>
+        <filter-name>hostnameFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+
+    <filter-mapping>
         <filter-name>authentication</filter-name>
         <servlet-name>FalconRESTApi</servlet-name>
     </filter-mapping>

http://git-wip-us.apache.org/repos/asf/falcon/blob/d8fbec9f/webapp/src/main/webapp/WEB-INF/embedded/web.xml
----------------------------------------------------------------------
diff --git a/webapp/src/main/webapp/WEB-INF/embedded/web.xml b/webapp/src/main/webapp/WEB-INF/embedded/web.xml
index fa2db39..5ecfe77 100644
--- a/webapp/src/main/webapp/WEB-INF/embedded/web.xml
+++ b/webapp/src/main/webapp/WEB-INF/embedded/web.xml
@@ -31,6 +31,11 @@
     </filter>
 
     <filter>
+        <filter-name>hostnameFilter</filter-name>
+        <filter-class>org.apache.falcon.security.HostnameFilter</filter-class>
+    </filter>
+
+    <filter>
         <filter-name>authentication</filter-name>
         <filter-class>org.apache.falcon.security.FalconAuthenticationFilter</filter-class>
     </filter>
@@ -46,6 +51,11 @@
     </filter-mapping>
 
     <filter-mapping>
+        <filter-name>hostnameFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+
+    <filter-mapping>
         <filter-name>authentication</filter-name>
         <servlet-name>FalconRESTApi</servlet-name>
     </filter-mapping>

http://git-wip-us.apache.org/repos/asf/falcon/blob/d8fbec9f/webapp/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/webapp/src/main/webapp/WEB-INF/web.xml b/webapp/src/main/webapp/WEB-INF/web.xml
index 2cfd7de..acfa938 100644
--- a/webapp/src/main/webapp/WEB-INF/web.xml
+++ b/webapp/src/main/webapp/WEB-INF/web.xml
@@ -31,6 +31,11 @@
     </filter>
 
     <filter>
+        <filter-name>hostnameFilter</filter-name>
+        <filter-class>org.apache.falcon.security.HostnameFilter</filter-class>
+    </filter>
+
+    <filter>
         <filter-name>authentication</filter-name>
         <filter-class>org.apache.falcon.security.FalconAuthenticationFilter</filter-class>
     </filter>
@@ -46,6 +51,11 @@
     </filter-mapping>
 
     <filter-mapping>
+        <filter-name>hostnameFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+
+    <filter-mapping>
         <filter-name>authentication</filter-name>
         <servlet-name>FalconRESTApi</servlet-name>
     </filter-mapping>

http://git-wip-us.apache.org/repos/asf/falcon/blob/d8fbec9f/webapp/src/test/java/org/apache/falcon/cli/FalconCLIIT.java
----------------------------------------------------------------------
diff --git a/webapp/src/test/java/org/apache/falcon/cli/FalconCLIIT.java b/webapp/src/test/java/org/apache/falcon/cli/FalconCLIIT.java
index 0062070..b859256 100644
--- a/webapp/src/test/java/org/apache/falcon/cli/FalconCLIIT.java
+++ b/webapp/src/test/java/org/apache/falcon/cli/FalconCLIIT.java
@@ -80,14 +80,14 @@ public class FalconCLIIT {
                 + "/falcon/test/input/2014/11/23/23"), 0);
 
         filePath = TestContext.overlayParametersOverTemplate(TestContext.FEED_TEMPLATE2, overlay);
-        Assert.assertEquals(executeWithURL("entity -submit -type feed -file " + filePath), 0);
+        Assert.assertEquals(executeWithURL("entity -submit -type feed -doAs testUser -file " + filePath), 0);
         Assert.assertEquals(
                 stream.buffer.toString().trim(),
                 "falcon/default/Submit successful (feed) "
                         + overlay.get("outputFeedName"));
 
         filePath = TestContext.overlayParametersOverTemplate(TestContext.PROCESS_TEMPLATE, overlay);
-        Assert.assertEquals(executeWithURL("entity -submit -type process -file " + filePath), 0);
+        Assert.assertEquals(executeWithURL("entity -submit -type process -doAs testUser -file " + filePath), 0);
         Assert.assertEquals(
                 stream.buffer.toString().trim(),
                 "falcon/default/Submit successful (process) "
@@ -109,14 +109,14 @@ public class FalconCLIIT {
         context.setCluster(overlay.get("cluster"));
 
         filePath = TestContext.overlayParametersOverTemplate(TestContext.FEED_TEMPLATE1, overlay);
-        Assert.assertEquals(executeWithURL("entity -submitAndSchedule -type feed -file " + filePath), 0);
+        Assert.assertEquals(executeWithURL("entity -submitAndSchedule -type feed -doAs testUser -file " + filePath), 0);
         filePath = TestContext.overlayParametersOverTemplate(TestContext.FEED_TEMPLATE2, overlay);
         Assert.assertEquals(executeWithURL("entity -submitAndSchedule -type feed -file " + filePath), 0);
         filePath = TestContext.overlayParametersOverTemplate(TestContext.FEED_TEMPLATE1, overlay);
         Assert.assertEquals(executeWithURL("entity -submit -type feed -file " + filePath), 0);
 
         filePath = TestContext.overlayParametersOverTemplate(TestContext.FEED_TEMPLATE2, overlay);
-        Assert.assertEquals(executeWithURL("entity -submit -type feed -file " + filePath), 0);
+        Assert.assertEquals(executeWithURL("entity -submit -type feed -doAs testUser -file " + filePath), 0);
 
         filePath = TestContext.overlayParametersOverTemplate(TestContext.PROCESS_TEMPLATE, overlay);
         Assert.assertEquals(executeWithURL("entity -submitAndSchedule -type process -file " + filePath), 0);
@@ -147,7 +147,7 @@ public class FalconCLIIT {
 
         filePath = TestContext.overlayParametersOverTemplate(TestContext.FEED_TEMPLATE2, overlay);
         Assert.assertEquals(executeWithURL("entity -validate -type feed -file " + filePath), 0);
-        Assert.assertEquals(executeWithURL("entity -submit -type feed -file " + filePath), 0);
+        Assert.assertEquals(executeWithURL("entity -submit -type feed -doAs testUser -file " + filePath), 0);
 
         filePath = TestContext.overlayParametersOverTemplate(TestContext.PROCESS_TEMPLATE, overlay);
         Assert.assertEquals(executeWithURL("entity -validate -type process -file " + filePath), 0);
@@ -164,7 +164,8 @@ public class FalconCLIIT {
 
         Assert.assertEquals(executeWithURL("entity -definition -type feed -name " + overlay.get("inputFeedName")), 0);
 
-        Assert.assertEquals(executeWithURL("entity -definition -type feed -name " + overlay.get("outputFeedName")), 0);
+        Assert.assertEquals(executeWithURL("entity -definition -type feed  -doAs testUser -name " + overlay.get(
+            "outputFeedName")), 0);
 
         Assert.assertEquals(executeWithURL("entity -definition -type process -name " + overlay.get("processName")), 0);
 
@@ -178,6 +179,9 @@ public class FalconCLIIT {
 
         Assert.assertEquals(executeWithURL("entity -schedule -type cluster -name " + overlay.get("cluster")), -1);
 
+        Assert.assertEquals(executeWithURL("entity -schedule -type feed -doAs testUser -name " + overlay.get(
+            "inputFeedName")), 0);
+
         Assert.assertEquals(executeWithURL("entity -schedule -type feed -name " + overlay.get("outputFeedName")), 0);
 
         Assert.assertEquals(executeWithURL("entity -schedule -type process -name " + overlay.get("processName")), 0);
@@ -217,28 +221,46 @@ public class FalconCLIIT {
         Map<String, String> overlay = context.getUniqueOverlay();
         submitTestFiles(context, overlay);
 
+        Assert.assertEquals(executeWithURL("entity -status -type feed -doAs testUser -name "
+                + overlay.get("inputFeedName")), 0);
+
         Assert.assertEquals(executeWithURL("entity -status -type feed -name " + overlay.get("outputFeedName")), 0);
 
         Assert.assertEquals(executeWithURL("entity -status -type process -name " + overlay.get("processName")), 0);
 
+        Assert.assertEquals(executeWithURL("entity -schedule -type feed -doAs testUser  -name "
+                + overlay.get("inputFeedName")), 0);
+
         Assert.assertEquals(executeWithURL("entity -schedule -type feed -name " + overlay.get("outputFeedName")), 0);
 
         Assert.assertEquals(executeWithURL("entity -schedule -type process -name " + overlay.get("processName")), 0);
 
         OozieTestUtils.waitForProcessWFtoStart(context);
 
+        Assert.assertEquals(executeWithURL("entity -suspend -type feed -doAs testUser -name "
+                + overlay.get("inputFeedName")), 0);
+
         Assert.assertEquals(executeWithURL("entity -suspend -type feed -name " + overlay.get("outputFeedName")), 0);
 
         Assert.assertEquals(executeWithURL("entity -suspend -type process -name " + overlay.get("processName")), 0);
 
+        Assert.assertEquals(executeWithURL("entity -status -type feed -doAs testUser -name "
+                + overlay.get("inputFeedName")), 0);
+
         Assert.assertEquals(executeWithURL("entity -status -type feed -name " + overlay.get("outputFeedName")), 0);
 
         Assert.assertEquals(executeWithURL("entity -status -type process -name " + overlay.get("processName")), 0);
 
+        Assert.assertEquals(executeWithURL("entity -resume -type feed -doAs testUse -name "
+                + overlay.get("inputFeedName")), 0);
+
         Assert.assertEquals(executeWithURL("entity -resume -type feed -name " + overlay.get("outputFeedName")), 0);
 
         Assert.assertEquals(executeWithURL("entity -resume -type process -name " + overlay.get("processName")), 0);
 
+        Assert.assertEquals(executeWithURL("entity -status -type feed -doAs testUse -name "
+                + overlay.get("inputFeedName")), 0);
+
         Assert.assertEquals(executeWithURL("entity -status -type feed -name " + overlay.get("outputFeedName")), 0);
 
         Assert.assertEquals(executeWithURL("entity -status -type process -name " + overlay.get("processName")), 0);
@@ -262,8 +284,8 @@ public class FalconCLIIT {
                 + " -filterBy TYPE:PROCESS -orderBy name -sortOrder invalid "
                 + " -offset 0 -numResults 1 -numInstances 7"), -1);
 
-        // No start or end date
-        Assert.assertEquals(executeWithURL("entity -summary -type process -fields status,pipelines"
+        // No start or end date and with doAs option
+        Assert.assertEquals(executeWithURL("entity -summary -type process -doAs testUser -fields status,pipelines"
                 + " -cluster " + overlay.get("cluster")
                 + " -filterBy TYPE:PROCESS -orderBy name "
                 + " -offset 0 -numResults 1 -numInstances 7"), 0);
@@ -284,14 +306,15 @@ public class FalconCLIIT {
 
         Assert.assertEquals(executeWithURL("entity -delete -type feed -name " + overlay.get("inputFeedName")), -1);
 
-        Assert.assertEquals(executeWithURL("entity -delete -type feed -name " + overlay.get("outputFeedName")), -1);
+        Assert.assertEquals(executeWithURL("entity -delete -type feed -doAs testUser -name "
+                + overlay.get("outputFeedName")), -1);
 
-        Assert.assertEquals(executeWithURL("entity -delete -type process -name " + overlay.get("processName")), 0);
+        Assert.assertEquals(executeWithURL("entity -delete -type process -doAs testUser -name "
+                + overlay.get("processName")), 0);
 
         Assert.assertEquals(executeWithURL("entity -delete -type feed -name " + overlay.get("inputFeedName")), 0);
 
         Assert.assertEquals(executeWithURL("entity -delete -type feed -name " + overlay.get("outputFeedName")), 0);
-
     }
 
     public void testInvalidCLIEntitycommands() throws Exception {
@@ -318,41 +341,51 @@ public class FalconCLIIT {
         Assert.assertEquals(executeWithURL("instance -dependency -type feed -name " + overlay.get("inputFeedName")
                 + " -instanceTime 2010-01-01T00:00Z"), 0);
 
+        //Test the dependency command with doAs
+        Assert.assertEquals(executeWithURL("instance -dependency -type feed -doAs testUser -name "
+                + overlay.get("inputFeedName") + " -instanceTime 2010-01-01T00:00Z"), 0);
+
         Assert.assertEquals(executeWithURL("instance -status -type feed -name "
                 + overlay.get("outputFeedName")
                 + " -start " + START_INSTANCE), 0);
 
         Assert.assertEquals(executeWithURL("instance -running -type process -name " + overlay.get("processName")), 0);
+        // with doAs
+        Assert.assertEquals(executeWithURL("instance -running -type process -doAs testUser -name "
+                + overlay.get("processName")), 0);
 
         Assert.assertEquals(executeWithURL("instance -running -type feed -lifecycle eviction -name "
-                + overlay.get("outputFeedName")
-                + " -start " + SchemaHelper.getDateFormat().format(new Date())), 0);
+                + overlay.get("outputFeedName") + " -start " + SchemaHelper.getDateFormat().format(new Date())), 0);
 
         Assert.assertEquals(executeWithURL("instance -listing -type feed -name "
-                + overlay.get("outputFeedName")
-                + " -start " + SchemaHelper.getDateFormat().format(new Date())), 0);
+                + overlay.get("outputFeedName") + " -start " + SchemaHelper.getDateFormat().format(new Date())), 0);
 
         Assert.assertEquals(executeWithURL("instance -status -type process -name "
-                + overlay.get("processName")
-                + " -start " + START_INSTANCE), 0);
+                + overlay.get("processName") + " -start " + START_INSTANCE), 0);
+
+        //TEst instance status with doAs
+        Assert.assertEquals(executeWithURL("instance -status -type process -doAs testUser -name "
+                + overlay.get("processName") + " -start " + START_INSTANCE), 0);
+
 
         Assert.assertEquals(executeWithURL("instance -status -type feed -lifecycle eviction,replication -name "
                 + overlay.get("outputFeedName")
                 + " -start " + SchemaHelper.getDateFormat().format(new Date())), 0);
 
         Assert.assertEquals(executeWithURL("instance -status -type feed -lifecycle eviction -name "
-                + overlay.get("outputFeedName")
-                + " -start " + SchemaHelper.getDateFormat().format(new Date())), 0);
+                + overlay.get("outputFeedName") + " -start " + SchemaHelper.getDateFormat().format(new Date())), 0);
 
         Assert.assertEquals(executeWithURL("instance -params -type process -name "
-                + overlay.get("processName")
-                + " -start " + START_INSTANCE), 0);
+                + overlay.get("processName") + " -start " + START_INSTANCE), 0);
+
+        // doAs option
+        Assert.assertEquals(executeWithURL("instance -params -type process -doAs testUser -name "
+                + overlay.get("processName") + " -start " + START_INSTANCE), 0);
 
         // test filterBy, orderBy, offset, numResults
         String startTimeString = SchemaHelper.getDateFormat().format(new Date());
         Assert.assertEquals(executeWithURL("instance -running -type feed -lifecycle eviction -name "
-                + overlay.get("outputFeedName")
-                + " -start " + startTimeString
+                + overlay.get("outputFeedName") + " -start " + startTimeString
                 + " -orderBy startTime -sortOrder asc -offset 0 -numResults 1"), 0);
 
         Assert.assertEquals(executeWithURL("instance -running -type feed -lifecycle eviction -name "
@@ -361,18 +394,15 @@ public class FalconCLIIT {
                 + " -orderBy INVALID -offset 0 -numResults 1"), -1);
 
         Assert.assertEquals(executeWithURL("instance -running -type feed -lifecycle eviction -name "
-                + overlay.get("outputFeedName")
-                + " -start " + startTimeString
+                + overlay.get("outputFeedName") + " -start " + startTimeString
                 + " -orderBy startTime -sortOrder desc -offset 0 -numResults 1"), 0);
 
         Assert.assertEquals(executeWithURL("instance -running -type feed -lifecycle eviction -name "
-                + overlay.get("outputFeedName")
-                + " -start " + startTimeString
+                + overlay.get("outputFeedName") + " -start " + startTimeString
                 + " -orderBy startTime -sortOrder invalid -offset 0 -numResults 1"), -1);
 
         Assert.assertEquals(executeWithURL("instance -running -type feed -lifecycle eviction -name "
-                + overlay.get("outputFeedName")
-                + " -start " + SchemaHelper.getDateFormat().format(new Date())
+                + overlay.get("outputFeedName") + " -start " + SchemaHelper.getDateFormat().format(new Date())
                 + " -filterBy INVALID:FILTER -offset 0 -numResults 1"), -1);
 
         // testcase : start str is older than entity schedule time.
@@ -404,6 +434,10 @@ public class FalconCLIIT {
                 + " -filterBy SOURCECLUSTER:" + overlay.get("cluster")
                 + " -orderBy startTime -sortOrder desc -offset 0 -numResults 1"), 0);
 
+        //Test list with doAs
+        Assert.assertEquals(executeWithURL("instance -list -type feed -doAs testUser -name "
+                + overlay.get("outputFeedName") + " -start " + SchemaHelper.getDateFormat().format(new Date())), 0);
+
         Assert.assertEquals(executeWithURL("instance -list -type feed -lifecycle eviction -name "
                 + overlay.get("outputFeedName")
                 + " -start " + SchemaHelper.getDateFormat().format(new Date())
@@ -453,9 +487,17 @@ public class FalconCLIIT {
 
         Assert.assertEquals(executeWithURL("instance -running -type process -name " + overlay.get("processName")), 0);
 
+        //with doAs
+        Assert.assertEquals(executeWithURL("instance -running -type process -doAs testUser -name "
+                + overlay.get("processName")), 0);
+
         Assert.assertEquals(executeWithURL("instance -summary -type process -name "
                 + overlay.get("processName") + " -start " + START_INSTANCE), 0);
 
+        //with doAs
+        Assert.assertEquals(executeWithURL("instance -summary -type process -doAs testUser -name "
+                + overlay.get("processName") + " -start " + START_INSTANCE), 0);
+
         Assert.assertEquals(executeWithURL("instance -summary -type feed -lifecycle eviction -name "
                 + overlay.get("outputFeedName")
                 + " -start " + SchemaHelper.getDateFormat().format(new Date())), 0);
@@ -463,6 +505,10 @@ public class FalconCLIIT {
         Assert.assertEquals(executeWithURL("instance -params -type process -name "
                 + overlay.get("processName")
                 + " -start " + START_INSTANCE), 0);
+
+        //with doAs
+        Assert.assertEquals(executeWithURL("instance -params -type process -doAs testUser -name "
+                + overlay.get("processName") + " -start " + START_INSTANCE), 0);
     }
 
     public void testInstanceSuspendAndResume() throws Exception {
@@ -472,9 +518,15 @@ public class FalconCLIIT {
 
         Assert.assertEquals(executeWithURL("entity -schedule -type process -name " + overlay.get("processName")), 0);
 
+        Assert.assertEquals(executeWithURL("entity -schedule -type feed -name " + overlay.get("inputFeedName")), 0);
+
         Assert.assertEquals(executeWithURL("entity -schedule -type feed -name " + overlay.get("outputFeedName")), 0);
 
-        Assert.assertEquals(executeWithURL("instance -suspend -type process -name "
+        Assert.assertEquals(executeWithURL("instance -suspend -type feed -name "
+                + overlay.get("inputFeedName")
+                + " -start " + START_INSTANCE + " -end " + START_INSTANCE), 0);
+
+        Assert.assertEquals(executeWithURL("instance -suspend -type process -doAs testUser -name "
                 + overlay.get("processName")
                 + " -start " + START_INSTANCE + " -end " + START_INSTANCE), 0);
 
@@ -487,6 +539,10 @@ public class FalconCLIIT {
                 + overlay.get("processName")
                 + " -start " + START_INSTANCE + " -end " + START_INSTANCE), 0);
 
+        Assert.assertEquals(executeWithURL("instance -resume -type feed -doAs testUser -name "
+                + overlay.get("inputFeedName")
+                + " -start " + START_INSTANCE + " -end " + START_INSTANCE), 0);
+
         Assert.assertEquals(executeWithURL("instance -resume -type feed -lifecycle eviction -name "
                 + overlay.get("outputFeedName")
                 + " -start " + SchemaHelper.getDateFormat().format(new Date())
@@ -502,6 +558,9 @@ public class FalconCLIIT {
 
         Assert.assertEquals(executeWithURL("entity -schedule -type process -name " + overlay.get("processName")), 0);
 
+        Assert.assertEquals(executeWithURL("entity -schedule -type feed -doAs testUser -name "
+                + overlay.get("inputFeedName")), 0);
+
         Assert.assertEquals(executeWithURL("entity -schedule -type feed -name " + overlay.get("outputFeedName")), 0);
 
         OozieTestUtils.waitForProcessWFtoStart(context);
@@ -509,6 +568,10 @@ public class FalconCLIIT {
                 + overlay.get("processName")
                 + " -start " + START_INSTANCE + " -end " + START_INSTANCE), 0);
 
+        Assert.assertEquals(executeWithURL("instance -kill -type feed -doAs testUser -name "
+                + overlay.get("inputFeedName")
+                + " -start " + START_INSTANCE + " -end " + START_INSTANCE), 0);
+
         // Fail due to no end date
         Assert.assertEquals(executeWithURL("instance -kill -type feed -lifecycle eviction -name "
                 + overlay.get("outputFeedName")
@@ -519,6 +582,11 @@ public class FalconCLIIT {
                 + " -start " + START_INSTANCE + " -end " + START_INSTANCE
                 + " -file " + createTempJobPropertiesFile()), 0);
 
+        Assert.assertEquals(executeWithURL("instance -rerun -type feed -doAs testUser -name "
+                + overlay.get("inputFeedName")
+                + " -start " + START_INSTANCE + " -end " + START_INSTANCE
+                + " -file " + createTempJobPropertiesFile()), 0);
+
         Assert.assertEquals(executeWithURL("instance -rerun -type feed -lifecycle eviction -name "
                 + overlay.get("outputFeedName")
                 + " -start " + SchemaHelper.getDateFormat().format(new Date())
@@ -547,7 +615,7 @@ public class FalconCLIIT {
         Assert.assertEquals(executeWithURL("entity -submit -type process -file " + filePath), 0);
 
         Assert.assertEquals(executeWithURL("metadata -lineage -pipeline testPipeline"), 0);
-
+        Assert.assertEquals(executeWithURL("metadata -lineage -doAs testUser -pipeline testPipeline"), 0);
     }
 
     @Test
@@ -619,6 +687,11 @@ public class FalconCLIIT {
         Assert.assertEquals(executeWithURL("instance -status -type feed -name "
                 + overlay.get("outputFeedName") + " -start " + START_INSTANCE), 0);
         Assert.assertEquals(executeWithURL("instance -running -type process -name " + overlay.get("processName")), 0);
+
+        // with doAs
+        Assert.assertEquals(executeWithURL("entity -list -type process -doAs testUser -fields status "
+                + " -filterBy STATUS:SUBMITTED,TYPE:process -orderBy name "
+                + " -sortOrder asc -offset 1 -numResults 1"), 0);
     }
 
     @Test
@@ -642,6 +715,10 @@ public class FalconCLIIT {
 
         String metadataListCommand = FalconCLI.METADATA_CMD + " -" + FalconMetadataCLI.LIST_OPT + " -"
                 + FalconMetadataCLI.TYPE_OPT + " ";
+        String metadataListCommandWithDoAs = FalconCLI.METADATA_CMD + " -doAs testUser" + " -"
+                + FalconMetadataCLI.LIST_OPT + " -"
+                + FalconMetadataCLI.TYPE_OPT + " ";
+
         String clusterString = " -" + FalconMetadataCLI.CLUSTER_OPT + " " + clusterName;
 
         Assert.assertEquals(executeWithURL(metadataListCommand + RelationshipType.CLUSTER_ENTITY.name()), 0);
@@ -654,6 +731,9 @@ public class FalconCLIIT {
         Assert.assertEquals(executeWithURL(metadataListCommand + RelationshipType.CLUSTER_ENTITY.name()
                 + clusterString), 0);
 
+        //with doAs
+        Assert.assertEquals(executeWithURL(metadataListCommandWithDoAs + RelationshipType.FEED_ENTITY.name()), 0);
+
         Assert.assertEquals(executeWithURL(metadataListCommand + "feed"), -1);
         Assert.assertEquals(executeWithURL(metadataListCommand + "invalid"), -1);
     }
@@ -680,11 +760,19 @@ public class FalconCLIIT {
         String metadataRelationsCommand = FalconCLI.METADATA_CMD + " -" + FalconMetadataCLI.RELATIONS_OPT + " -"
                 + FalconMetadataCLI.TYPE_OPT + " ";
 
+        String metadataRelationsCommandWithDoAs = FalconCLI.METADATA_CMD + " -doAs testUser"
+                + " -" + FalconMetadataCLI.RELATIONS_OPT + " -"
+                + FalconMetadataCLI.TYPE_OPT + " ";
+
         Assert.assertEquals(executeWithURL(metadataRelationsCommand + RelationshipType.CLUSTER_ENTITY.name()
                 + " -" + FalconMetadataCLI.NAME_OPT + " " + clusterName), 0);
         Assert.assertEquals(executeWithURL(metadataRelationsCommand + RelationshipType.PROCESS_ENTITY.name()
                 + " -" + FalconMetadataCLI.NAME_OPT + " " + processName), 0);
 
+        // with doAs
+        Assert.assertEquals(executeWithURL(metadataRelationsCommandWithDoAs + RelationshipType.PROCESS_ENTITY.name()
+                + " -" + FalconMetadataCLI.NAME_OPT + " " + processName), 0);
+
         Assert.assertEquals(executeWithURL(metadataRelationsCommand + "feed -"
                 + FalconMetadataCLI.NAME_OPT + " " + clusterName), -1);
 
@@ -765,20 +853,26 @@ public class FalconCLIIT {
                 + TestContext.BASE_URL).split("\\s+")), 0);
 
         Assert.assertEquals(new FalconCLI().run(("entity -schedule -type process -name "
-                + overlay.get("processName")+ " -url "
+                + overlay.get("processName") + " -url "
                 + TestContext.BASE_URL).split("\\s+")), 0);
     }
 
     public void testGetVersion() throws Exception {
         Assert.assertEquals(new FalconCLI().run(("admin -version -url " + TestContext.BASE_URL).split("\\s")), 0);
+        Assert.assertEquals(new FalconCLI().run(("admin -doAs testUser -version -url "
+                + TestContext.BASE_URL).split("\\s")), 0);
     }
 
     public void testGetStatus() throws Exception {
         Assert.assertEquals(new FalconCLI().run(("admin -status -url " + TestContext.BASE_URL).split("\\s")), 0);
+        Assert.assertEquals(new FalconCLI().run(("admin -doAs testUser -status -url "
+                + TestContext.BASE_URL).split("\\s")), 0);
     }
 
     public void testGetThreadStackDump() throws Exception {
         Assert.assertEquals(new FalconCLI().run(("admin -stack -url " + TestContext.BASE_URL).split("\\s")), 0);
+        Assert.assertEquals(new FalconCLI().run(("admin -doAs testUser -stack -url "
+                + TestContext.BASE_URL).split("\\s")), 0);
     }
 
     public void testInstanceGetLogs() throws Exception {
@@ -800,6 +894,10 @@ public class FalconCLIIT {
                 + overlay.get("outputFeedName")
                 + " -start "+ SchemaHelper.getDateFormat().format(new Date())), 0);
 
+        // with doAs
+        Assert.assertEquals(executeWithURL("instance -logs -doAs testUser -type feed -lifecycle eviction -name "
+                + overlay.get("outputFeedName") + " -start "+ SchemaHelper.getDateFormat().format(new Date())), 0);
+
         // test filterBy, orderBy, offset, numResults
         Assert.assertEquals(executeWithURL("instance -logs -type process -name "
                 + overlay.get("processName")

http://git-wip-us.apache.org/repos/asf/falcon/blob/d8fbec9f/webapp/src/test/java/org/apache/falcon/resource/EntityManagerJerseyIT.java
----------------------------------------------------------------------
diff --git a/webapp/src/test/java/org/apache/falcon/resource/EntityManagerJerseyIT.java b/webapp/src/test/java/org/apache/falcon/resource/EntityManagerJerseyIT.java
index bcd3bd5..220e5a7 100644
--- a/webapp/src/test/java/org/apache/falcon/resource/EntityManagerJerseyIT.java
+++ b/webapp/src/test/java/org/apache/falcon/resource/EntityManagerJerseyIT.java
@@ -19,6 +19,7 @@ package org.apache.falcon.resource;
 
 import com.sun.jersey.api.client.ClientResponse;
 import com.sun.jersey.api.client.WebResource;
+import org.apache.falcon.cli.FalconCLI;
 import org.apache.falcon.entity.v0.Entity;
 import org.apache.falcon.entity.v0.EntityType;
 import org.apache.falcon.entity.v0.SchemaHelper;
@@ -243,7 +244,7 @@ public class EntityManagerJerseyIT {
         ClientResponse response = context.validate(tmpFile.getAbsolutePath(), overlay, EntityType.PROCESS);
         context.assertFailure(response);
 
-        context.scheduleProcess(tmpFile.getAbsolutePath(), overlay, false, null);
+        context.scheduleProcess(tmpFile.getAbsolutePath(), overlay, false);
 
         //Fix the process and then submitAndSchedule should succeed
         Iterator<Property> itr = process.getProperties().getProperties().iterator();
@@ -624,6 +625,14 @@ public class EntityManagerJerseyIT {
     }
 
     public void testProcesssScheduleAndDelete() throws Exception {
+        scheduleAndDeleteProcess(false);
+    }
+
+    public void testProcesssScheduleAndDeleteWithDoAs() throws Exception {
+        scheduleAndDeleteProcess(true);
+    }
+
+    private void scheduleAndDeleteProcess(boolean withDoAs) throws Exception {
         TestContext context = newContext();
         ClientResponse clientResponse;
         Map<String, String> overlay = context.getUniqueOverlay();
@@ -632,12 +641,21 @@ public class EntityManagerJerseyIT {
         updateEndtime(process);
         File tmpFile = TestContext.getTempFile();
         EntityType.PROCESS.getMarshaller().marshal(process, tmpFile);
-        context.scheduleProcess(tmpFile.getAbsolutePath(), overlay);
+        if (withDoAs) {
+            context.scheduleProcess(tmpFile.getAbsolutePath(), overlay, null, "testUser");
+        } else {
+            context.scheduleProcess(tmpFile.getAbsolutePath(), overlay);
+        }
         OozieTestUtils.waitForBundleStart(context, Status.RUNNING);
 
+        WebResource resource = context.service.path("api/entities/delete/process/" + context.processName);
+
+        if (withDoAs) {
+            resource = resource.queryParam(FalconCLI.DO_AS_OPT, "testUser");
+        }
+
         //Delete a scheduled process
-        clientResponse = context.service
-                .path("api/entities/delete/process/" + context.processName)
+        clientResponse = resource
                 .header("Cookie", context.getAuthenticationToken())
                 .accept(MediaType.TEXT_XML)
                 .delete(ClientResponse.class);

http://git-wip-us.apache.org/repos/asf/falcon/blob/d8fbec9f/webapp/src/test/java/org/apache/falcon/resource/MetadataResourceJerseyIT.java
----------------------------------------------------------------------
diff --git a/webapp/src/test/java/org/apache/falcon/resource/MetadataResourceJerseyIT.java b/webapp/src/test/java/org/apache/falcon/resource/MetadataResourceJerseyIT.java
index eb1dda8..8594603 100644
--- a/webapp/src/test/java/org/apache/falcon/resource/MetadataResourceJerseyIT.java
+++ b/webapp/src/test/java/org/apache/falcon/resource/MetadataResourceJerseyIT.java
@@ -87,6 +87,7 @@ public class MetadataResourceJerseyIT {
         response = context.service
                 .path("api/metadata/discovery/process_entity/list")
                 .queryParam("cluster", "random")
+                .queryParam("doAs", "testUser")
                 .header("Cookie", context.getAuthenticationToken())
                 .accept(MediaType.APPLICATION_JSON)
                 .get(ClientResponse.class);

http://git-wip-us.apache.org/repos/asf/falcon/blob/d8fbec9f/webapp/src/test/java/org/apache/falcon/resource/TestContext.java
----------------------------------------------------------------------
diff --git a/webapp/src/test/java/org/apache/falcon/resource/TestContext.java b/webapp/src/test/java/org/apache/falcon/resource/TestContext.java
index 54671fb..f031137 100644
--- a/webapp/src/test/java/org/apache/falcon/resource/TestContext.java
+++ b/webapp/src/test/java/org/apache/falcon/resource/TestContext.java
@@ -25,6 +25,7 @@ import com.sun.jersey.api.client.config.ClientConfig;
 import com.sun.jersey.api.client.config.DefaultClientConfig;
 import com.sun.jersey.client.urlconnection.HTTPSProperties;
 import org.apache.commons.lang.RandomStringUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.net.util.TrustManagerUtils;
 import org.apache.falcon.FalconException;
 import org.apache.falcon.FalconRuntimException;
@@ -230,11 +231,20 @@ public class TestContext {
     }
 
     public void scheduleProcess(String processTemplate, Map<String, String> overlay) throws Exception {
-        scheduleProcess(processTemplate, overlay, true, null);
+        scheduleProcess(processTemplate, overlay, true, null, "");
     }
 
     public void scheduleProcess(String processTemplate, Map<String, String> overlay,
-                                boolean succeed, Boolean skipDryRun) throws Exception {
+                                Boolean skipDryRun, final String doAsUSer) throws Exception {
+        scheduleProcess(processTemplate, overlay, true, skipDryRun, doAsUSer);
+    }
+
+    public void scheduleProcess(String processTemplate, Map<String, String> overlay, boolean succeed) throws Exception{
+        scheduleProcess(processTemplate, overlay, succeed, null, "");
+    }
+
+    public void scheduleProcess(String processTemplate, Map<String, String> overlay, boolean succeed,
+                                Boolean skipDryRun, final String doAsUser) throws Exception {
         ClientResponse response = submitToFalcon(CLUSTER_TEMPLATE, overlay, EntityType.CLUSTER);
         assertSuccessful(response);
 
@@ -244,7 +254,7 @@ public class TestContext {
         response = submitToFalcon(FEED_TEMPLATE2, overlay, EntityType.FEED);
         assertSuccessful(response);
 
-        response = submitAndSchedule(processTemplate, overlay, EntityType.PROCESS, skipDryRun);
+        response = submitAndSchedule(processTemplate, overlay, EntityType.PROCESS, skipDryRun, doAsUser);
         if (succeed) {
             assertSuccessful(response);
         } else {
@@ -279,21 +289,26 @@ public class TestContext {
 
     public ClientResponse submitAndSchedule(String template, Map<String, String> overlay, EntityType entityType)
         throws Exception {
-        return submitAndSchedule(template, overlay, entityType, null);
+        return submitAndSchedule(template, overlay, entityType, null, "");
     }
 
     public ClientResponse submitAndSchedule(String template, Map<String, String> overlay,
-                                            EntityType entityType, Boolean skipDryRun)
-        throws Exception {
+                                            EntityType entityType, Boolean skipDryRun,
+                                            final String doAsUser) throws Exception {
         String tmpFile = overlayParametersOverTemplate(template, overlay);
         ServletInputStream rawlogStream = getServletInputStream(tmpFile);
 
-        WebResource resource = service.path("api/entities/submitAndSchedule/" + entityType.name().toLowerCase());
+        WebResource resource = this.service.path("api/entities/submitAndSchedule/" + entityType.name().toLowerCase());
+
         if (null != skipDryRun) {
             resource = resource.queryParam("skipDryRun", String.valueOf(skipDryRun));
         }
-        return resource
-                .header("Cookie", getAuthenticationToken())
+
+        if (StringUtils.isNotEmpty(doAsUser)) {
+            resource = resource.queryParam(FalconCLI.DO_AS_OPT, doAsUser);
+        }
+
+        return resource.header("Cookie", getAuthenticationToken())
                 .accept(MediaType.TEXT_XML)
                 .type(MediaType.TEXT_XML)
                 .post(ClientResponse.class, rawlogStream);
@@ -323,6 +338,11 @@ public class TestContext {
 
     public ClientResponse submitToFalcon(String template, Map<String, String> overlay, EntityType entityType)
         throws IOException {
+        return submitToFalcon(template, overlay, entityType, "");
+    }
+
+    public ClientResponse submitToFalcon(String template, Map<String, String> overlay, EntityType entityType,
+                                         final String doAsUser) throws IOException {
         String tmpFile = overlayParametersOverTemplate(template, overlay);
         if (entityType == EntityType.CLUSTER) {
             try {
@@ -334,7 +354,7 @@ public class TestContext {
                 throw new IOException("Unable to setup cluster info", e);
             }
         }
-        return submitFileToFalcon(entityType, tmpFile);
+        return submitFileToFalcon(entityType, tmpFile, doAsUser);
     }
 
     public static void deleteClusterLocations(Cluster clusterEntity, FileSystem fs) throws IOException {
@@ -374,11 +394,21 @@ public class TestContext {
     }
 
     public ClientResponse submitFileToFalcon(EntityType entityType, String tmpFile) throws IOException {
+        return submitFileToFalcon(entityType, tmpFile, "");
+    }
+
+    public ClientResponse submitFileToFalcon(EntityType entityType, String tmpFile,
+                                             final String doAsUser) throws IOException {
 
         ServletInputStream rawlogStream = getServletInputStream(tmpFile);
 
-        return this.service.path("api/entities/submit/" + entityType.name().toLowerCase())
-                .header("Cookie", getAuthenticationToken())
+        WebResource resource = this.service.path("api/entities/submit/" + entityType.name().toLowerCase());
+
+        if (StringUtils.isNotEmpty(doAsUser)) {
+            resource = resource.queryParam(FalconCLI.DO_AS_OPT, doAsUser);
+        }
+
+        return resource.header("Cookie", getAuthenticationToken())
                 .accept(MediaType.TEXT_XML)
                 .type(MediaType.TEXT_XML)
                 .post(ClientResponse.class, rawlogStream);

http://git-wip-us.apache.org/repos/asf/falcon/blob/d8fbec9f/webapp/src/test/resources/runtime.properties
----------------------------------------------------------------------
diff --git a/webapp/src/test/resources/runtime.properties b/webapp/src/test/resources/runtime.properties
new file mode 100644
index 0000000..1da0ca7
--- /dev/null
+++ b/webapp/src/test/resources/runtime.properties
@@ -0,0 +1,50 @@
+#
+# 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.
+#
+
+*.domain=debug
+
+*.falcon.parentworkflow.retry.max=3
+*.falcon.parentworkflow.retry.interval.secs=1
+
+*.falcon.replication.workflow.maxmaps=5
+*.falcon.replication.workflow.mapbandwidth=100
+*.webservices.default.results.per.page=10
+
+# Default configs to handle replication for late arriving feeds.
+*.feed.late.allowed=true
+*.feed.late.frequency=hours(3)
+*.feed.late.policy=exp-backoff
+
+# If true, Falcon skips oozie dryrun while scheduling entities.
+*.falcon.skip.dryrun=false
+
+######### Proxyuser Configuration Start #########
+
+#List of hosts the '#USER#' user is allowed to perform 'doAs 'operations from. The '#USER#' must be replaced with the
+#username of the user who is allowed to perform 'doAs' operations. The value can be the '*' wildcard or a list of
+#comma separated hostnames
+
+*.falcon.service.ProxyUserService.proxyuser.#USER#.hosts=*
+
+#List of groups the '#USER#' user is allowed to 'doAs 'operations. The '#USER#' must be replaced with the
+#username of the user who is allowed to perform 'doAs' operations. The value can be the '*' wildcard or a list of
+#comma separated groups
+
+*.falcon.service.ProxyUserService.proxyuser.#USER#.groups=*
+
+######### Proxyuser Configuration End #########


Mime
View raw message