You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hawq.apache.org by ad...@apache.org on 2017/01/18 18:58:44 UTC

[1/4] incubator-hawq git commit: HAWQ-1203. Ranger Plugin Service Implementation. (with contributions by Lav Jain and Leslie Chang) (close #1092)

Repository: incubator-hawq
Updated Branches:
  refs/heads/master e46f06cc9 -> 7f36b35bd


http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/RangerHawqAuthorizerTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/RangerHawqAuthorizerTest.java b/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/RangerHawqAuthorizerTest.java
new file mode 100644
index 0000000..0a439db
--- /dev/null
+++ b/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/RangerHawqAuthorizerTest.java
@@ -0,0 +1,325 @@
+/*
+ * 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.hawq.ranger.authorization;
+
+import org.apache.hawq.ranger.authorization.model.AuthorizationRequest;
+import org.apache.hawq.ranger.authorization.model.AuthorizationResponse;
+import org.apache.hawq.ranger.authorization.model.HawqPrivilege;
+import org.apache.hawq.ranger.authorization.model.HawqResource;
+import org.apache.hawq.ranger.authorization.model.ResourceAccess;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.apache.ranger.plugin.policyengine.RangerAccessResult;
+import org.apache.ranger.plugin.service.RangerBasePlugin;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatcher;
+import org.mockito.Mock;
+import org.mockito.internal.util.collections.Sets;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertNotNull;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+
+@RunWith(MockitoJUnitRunner.class)
+public class RangerHawqAuthorizerTest {
+
+    private static final Integer TEST_REQUEST_ID = 1;
+    private static final String TEST_USER = "alex";
+    private static final String TEST_CLIENT = "1.2.3.4";
+    private static final String TEST_CONTEXT = "SELECT * FROM sales";
+    private static final Set<HawqPrivilege> TEST_PRIVILEGES = Sets.newSet(HawqPrivilege.select, HawqPrivilege.update);
+
+    private static final String TEST_RESOURCE_REQUEST =
+            "finance:us:sales>select,update#finance:emea:sales>create";
+    private static final String TEST_RESOURCE_RESPONSE_ALL_FALSE =
+            "finance:us:sales>select,update>false#finance:emea:sales>create>false";
+    private static final String TEST_RESOURCE_RESPONSE_ALL_TRUE =
+            "finance:us:sales>select,update>true#finance:emea:sales>create>true";
+    private static final String TEST_RESOURCE_RESPONSE_US_ALLOWED_EMEA_DENIED =
+            "finance:us:sales>select,update>true#finance:emea:sales>create>false";
+    private static final String TEST_RESOURCE_RESPONSE_UPDATE_DENIED =
+            "finance:us:sales>select,update>false#finance:emea:sales>create>true";
+
+    private static final String TEST_RESOURCE_REQUEST_CREATE_SCHEMA  = "finance>create";
+    private static final String TEST_RESOURCE_RESPONSE_CREATE_SCHEMA = "finance>create>true";
+    private static final String TEST_RESOURCE_REQUEST_USAGE_SCHEMA  = "finance:us>usage";
+    private static final String TEST_RESOURCE_RESPONSE_USAGE_SCHEMA = "finance:us>usage>true";
+
+    private RangerHawqAuthorizer authorizer;
+
+    @Mock
+    private RangerBasePlugin mockRangerPlugin;
+    @Mock
+    private RangerAccessResult mockRangerAccessResult;
+
+    @Before
+    public void setup() throws Exception {
+        authorizer = RangerHawqAuthorizer.getInstance();
+        authorizer.setRangerPlugin(mockRangerPlugin);
+    }
+
+    @Test
+    public void testAuthorize_allAllowed() throws Exception {
+        when(mockRangerPlugin.isAccessAllowed(any(RangerAccessRequest.class))).thenReturn(mockRangerAccessResult);
+        when(mockRangerAccessResult.getIsAllowed()).thenReturn(true);
+        testRequest(TEST_RESOURCE_REQUEST, TEST_RESOURCE_RESPONSE_ALL_TRUE);
+    }
+
+    @Test
+    public void testAuthorize_allDenied() throws Exception {
+        when(mockRangerPlugin.isAccessAllowed(any(RangerAccessRequest.class))).thenReturn(mockRangerAccessResult);
+        when(mockRangerAccessResult.getIsAllowed()).thenReturn(false);
+        testRequest(TEST_RESOURCE_REQUEST, TEST_RESOURCE_RESPONSE_ALL_FALSE);
+    }
+
+    @Test
+    public void testAuthorize_usAllowedEmeaDenied() throws Exception {
+        RangerAccessResult mockRangerAccessResultUS = mock(RangerAccessResult.class);
+        RangerAccessResult mockRangerAccessResultEMEA = mock(RangerAccessResult.class);
+
+        when(mockRangerPlugin.isAccessAllowed(argThat(new SchemaMatcher("us")))).thenReturn(mockRangerAccessResultUS);
+        when(mockRangerPlugin.isAccessAllowed(argThat(new SchemaMatcher("emea")))).thenReturn(mockRangerAccessResultEMEA);
+        when(mockRangerAccessResultUS.getIsAllowed()).thenReturn(true);
+        when(mockRangerAccessResultEMEA.getIsAllowed()).thenReturn(false);
+        testRequest(TEST_RESOURCE_REQUEST, TEST_RESOURCE_RESPONSE_US_ALLOWED_EMEA_DENIED);
+    }
+
+    @Test
+    public void testAuthorize_partialPrivilegeUpdateDenied() throws Exception {
+        RangerAccessResult mockRangerAccessResultCreateSelect = mock(RangerAccessResult.class);
+        RangerAccessResult mockRangerAccessResultUpdate = mock(RangerAccessResult.class);
+
+        when(mockRangerPlugin.isAccessAllowed(argThat(new PrivilegeMatcher("create", "select")))).thenReturn(mockRangerAccessResultCreateSelect);
+        when(mockRangerPlugin.isAccessAllowed(argThat(new PrivilegeMatcher("update")))).thenReturn(mockRangerAccessResultUpdate);
+        when(mockRangerAccessResultCreateSelect.getIsAllowed()).thenReturn(true);
+        when(mockRangerAccessResultUpdate.getIsAllowed()).thenReturn(false);
+        testRequest(TEST_RESOURCE_REQUEST, TEST_RESOURCE_RESPONSE_UPDATE_DENIED);
+    }
+
+    @Test
+    public void testAuthorize_createSchemaAllowed() throws Exception {
+        RangerAccessResult mockRangerAccessResultCreate = mock(RangerAccessResult.class);
+
+        when(mockRangerPlugin.isAccessAllowed(argThat(new PrivilegeMatcher("create-schema")))).thenReturn(mockRangerAccessResultCreate);
+        when(mockRangerAccessResultCreate.getIsAllowed()).thenReturn(true);
+        testRequest(TEST_RESOURCE_REQUEST_CREATE_SCHEMA, TEST_RESOURCE_RESPONSE_CREATE_SCHEMA);
+    }
+
+    @Test
+    public void testAuthorize_usageSchemaAllowed() throws Exception {
+        RangerAccessResult mockRangerAccessResultUsage = mock(RangerAccessResult.class);
+
+        when(mockRangerPlugin.isAccessAllowed(argThat(new PrivilegeMatcher("usage-schema")))).thenReturn(mockRangerAccessResultUsage);
+        when(mockRangerAccessResultUsage.getIsAllowed()).thenReturn(true);
+        testRequest(TEST_RESOURCE_REQUEST_USAGE_SCHEMA, TEST_RESOURCE_RESPONSE_USAGE_SCHEMA);
+    }
+
+    /* ----- VALIDATION TESTS ----- */
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testAuthorize_validationFailure_requestId() {
+        AuthorizationRequest request = prepareRequest(null, TEST_USER, TEST_CLIENT, TEST_CONTEXT, TEST_RESOURCE_REQUEST);
+        authorizer.isAccessAllowed(request);
+    }
+    @Test(expected=IllegalArgumentException.class)
+    public void testAuthorize_validationFailure_user() {
+        AuthorizationRequest request = prepareRequest(TEST_REQUEST_ID, "", TEST_CLIENT, TEST_CONTEXT, TEST_RESOURCE_REQUEST);
+        authorizer.isAccessAllowed(request);
+    }
+    @Test(expected=IllegalArgumentException.class)
+    public void testAuthorize_validationFailure_client() {
+        AuthorizationRequest request = prepareRequest(TEST_REQUEST_ID, TEST_USER, "", TEST_CONTEXT, TEST_RESOURCE_REQUEST);
+        authorizer.isAccessAllowed(request);
+    }
+    @Test(expected=IllegalArgumentException.class)
+    public void testAuthorize_validationFailure_context() {
+        AuthorizationRequest request = prepareRequest(TEST_REQUEST_ID, TEST_USER, TEST_CLIENT, "", TEST_RESOURCE_REQUEST);
+        authorizer.isAccessAllowed(request);
+    }
+    @Test(expected=IllegalArgumentException.class)
+    public void testAuthorize_validationFailure_emptyAccessSet() {
+        AuthorizationRequest request = prepareRequest(TEST_REQUEST_ID, TEST_USER, TEST_CLIENT, TEST_CONTEXT, new HashSet<ResourceAccess>());
+        authorizer.isAccessAllowed(request);
+    }
+    @Test(expected=IllegalArgumentException.class)
+    public void testAuthorize_validationFailure_emptyResource() {
+        ResourceAccess resourceAccess = new ResourceAccess();
+        resourceAccess.setResource(new HashMap<HawqResource, String>());
+        resourceAccess.setPrivileges(TEST_PRIVILEGES);
+        AuthorizationRequest request = prepareRequest(TEST_REQUEST_ID, TEST_USER, TEST_CLIENT, TEST_CONTEXT, resourceAccess);
+        authorizer.isAccessAllowed(request);
+    }
+    @Test(expected=IllegalArgumentException.class)
+    public void testAuthorize_validationFailure_emptyResourceValue() {
+        ResourceAccess resourceAccess = new ResourceAccess();
+        HashMap<HawqResource, String> resource = new HashMap<>();
+        resource.put(HawqResource.database, "");
+        resourceAccess.setResource(resource);
+        resourceAccess.setPrivileges(TEST_PRIVILEGES);
+        AuthorizationRequest request = prepareRequest(TEST_REQUEST_ID, TEST_USER, TEST_CLIENT, TEST_CONTEXT, resourceAccess);
+        authorizer.isAccessAllowed(request);
+    }
+    @Test(expected=IllegalArgumentException.class)
+    public void testAuthorize_validationFailure_emptyPrivileges() {
+        ResourceAccess resourceAccess = new ResourceAccess();
+        HashMap<HawqResource, String> resource = new HashMap<>();
+        resource.put(HawqResource.database, "abc");
+        resourceAccess.setResource(resource);
+        resourceAccess.setPrivileges(new HashSet<HawqPrivilege>());
+        AuthorizationRequest request = prepareRequest(TEST_REQUEST_ID, TEST_USER, TEST_CLIENT, TEST_CONTEXT, resourceAccess);
+        authorizer.isAccessAllowed(request);
+    }
+
+    /* ----- HELPER METHODS ----- */
+
+    private void testRequest(String request, String expectedResponse) {
+        AuthorizationRequest authRequest = prepareRequest(TEST_REQUEST_ID, TEST_USER, TEST_CLIENT, TEST_CONTEXT, request);
+        AuthorizationResponse authResponse = authorizer.isAccessAllowed(authRequest);
+        validateResponse(authResponse, expectedResponse);
+    }
+
+    private AuthorizationRequest prepareRequest(
+            Integer requestId, String user, String clientIp, String context, Set<ResourceAccess> access) {
+
+        AuthorizationRequest request = new AuthorizationRequest();
+        request.setRequestId(requestId);
+        request.setUser(user);
+        request.setClientIp(clientIp);
+        request.setContext(context);
+        request.setAccess(access);
+
+        return request;
+    }
+
+    private AuthorizationRequest prepareRequest(
+            Integer requestId, String user, String clientIp, String context, ResourceAccess resourceAccess) {
+
+        Set<ResourceAccess> access = new HashSet<>();
+        access.add(resourceAccess);
+        return prepareRequest(requestId, user, clientIp, context, access);
+    }
+
+    private AuthorizationRequest prepareRequest(
+            Integer requestId, String user, String clientIp, String context, String resources) {
+
+        Set<ResourceAccess> access = new HashSet<>();
+        // resource string is like "db:schema:table>select,update#db:schema:table>create"
+        for (String resourceStr : resources.split("#")) {
+            String[] parts = resourceStr.split(">");
+            String[] resource = parts[0].split(":");
+            String[] privs = parts[1].split(",");
+
+            Map<HawqResource, String> tableResource = new HashMap<>();
+            tableResource.put(HawqResource.database, resource[0]);
+            if (resource.length > 1) {
+                tableResource.put(HawqResource.schema, resource[1]);
+            }
+            if (resource.length > 2) {
+                tableResource.put(HawqResource.table, resource[2]);
+            }
+            ResourceAccess tableAccess = new ResourceAccess();
+            tableAccess.setResource(tableResource);
+
+            Set<HawqPrivilege> privSet = new HashSet<>();
+            for (String priv : privs) {
+                privSet.add(HawqPrivilege.valueOf(priv));
+            }
+            tableAccess.setPrivileges(privSet);
+            access.add(tableAccess);
+        }
+
+        return prepareRequest(requestId, user, clientIp, context, access);
+    }
+
+    private void validateResponse(AuthorizationResponse response, String resources) {
+
+        assertNotNull(response);
+
+        Set<ResourceAccess> actual = response.getAccess();
+        Set<ResourceAccess> expected = new HashSet<>();
+
+        // resources string is like "db:schema:table>select,update>true#db:schema:table>create>false"
+        for (String resourceStr : resources.split("#")) {
+            String[] parts = resourceStr.split(">");
+            String[] resource = parts[0].split(":");
+            String[] privs = parts[1].split(",");
+            Boolean allowed = Boolean.valueOf(parts[2]);
+
+            Map<HawqResource, String> tableResource = new HashMap<>();
+            tableResource.put(HawqResource.database, resource[0]);
+            if (resource.length > 1) {
+                tableResource.put(HawqResource.schema, resource[1]);
+            }
+            if (resource.length > 2) {
+                tableResource.put(HawqResource.table, resource[2]);
+            }
+            ResourceAccess tableAccess = new ResourceAccess();
+            tableAccess.setResource(tableResource);
+
+            Set<HawqPrivilege> privSet = new HashSet<>();
+            for (String priv : privs) {
+                privSet.add(HawqPrivilege.fromString(priv));
+            }
+            tableAccess.setPrivileges(privSet);
+            tableAccess.setAllowed(allowed);
+
+            expected.add(tableAccess);
+        }
+
+        assertEquals(expected.size(), actual.size());
+        assertEquals(expected, actual);
+    }
+
+    /* ----- Argument Matchers ----- */
+
+    private class SchemaMatcher extends ArgumentMatcher<RangerAccessRequest> {
+        private String schema;
+        public SchemaMatcher(String schema) {
+            this.schema = schema;
+        }
+        @Override
+        public boolean matches(Object request) {
+            return request == null ? false :
+                    schema.equals(((RangerAccessRequest) request).getResource().getAsMap().get("schema"));
+        }
+    };
+
+    private class PrivilegeMatcher extends ArgumentMatcher<RangerAccessRequest> {
+        private Set<String> privileges;
+        public PrivilegeMatcher(String... privileges) {
+            this.privileges = Sets.newSet(privileges);
+        }
+        @Override
+        public boolean matches(Object request) {
+            return request == null ? false :
+                    privileges.contains(((RangerAccessRequest) request).getAccessType());
+        }
+    };
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/RangerHawqPluginResourceTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/RangerHawqPluginResourceTest.java b/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/RangerHawqPluginResourceTest.java
new file mode 100644
index 0000000..40c2217
--- /dev/null
+++ b/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/RangerHawqPluginResourceTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hawq.ranger.authorization;
+
+import org.apache.hawq.ranger.authorization.model.AuthorizationRequest;
+import org.apache.hawq.ranger.authorization.model.AuthorizationResponse;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import static junit.framework.TestCase.*;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.when;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(RangerHawqAuthorizer.class)
+public class RangerHawqPluginResourceTest {
+
+    private RangerHawqPluginResource resource;
+
+    @Mock
+    private RangerHawqAuthorizer mockAuthorizer;
+    @Mock
+    private AuthorizationResponse mockResponse;
+    @Mock
+    private RuntimeException mockException;
+
+    @Before
+    public void setup() throws Exception {
+        PowerMockito.mockStatic(RangerHawqAuthorizer.class);
+        when(RangerHawqAuthorizer.getInstance()).thenReturn(mockAuthorizer);
+        resource = new RangerHawqPluginResource();
+    }
+
+    @Test
+    public void testGetVersion() {
+        String version = (String) resource.version().getEntity();
+        assertEquals("{\"version\":\"version-test\"}", version);
+    }
+
+    @Test
+    public void testAuthorizeSuccess() {
+        when(mockAuthorizer.isAccessAllowed(any(AuthorizationRequest.class))).thenReturn(mockResponse);
+        AuthorizationResponse response = resource.authorize(new AuthorizationRequest());
+        assertNotNull(response);
+        assertEquals(mockResponse, response);
+    }
+
+    @Test
+    public void testAuthorizeException() {
+        when(mockAuthorizer.isAccessAllowed(any(AuthorizationRequest.class))).thenThrow(mockException);
+        try {
+            resource.authorize(new AuthorizationRequest());
+            fail("should've thrown exception");
+        } catch (Exception e) {
+            assertSame(mockException, e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/ServiceExceptionMapperTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/ServiceExceptionMapperTest.java b/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/ServiceExceptionMapperTest.java
new file mode 100644
index 0000000..e81b76c
--- /dev/null
+++ b/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/ServiceExceptionMapperTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.hawq.ranger.authorization;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import javax.ws.rs.core.Response;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ServiceExceptionMapperTest {
+
+    private ServiceExceptionMapper mapper;
+
+    @Before
+    public void setup() {
+        mapper = new ServiceExceptionMapper();
+    }
+
+    @Test
+    public void testIllegalArgumentException() {
+
+        Response response = mapper.toResponse(new IllegalArgumentException("reason"));
+        ServiceExceptionMapper.ErrorPayload entity = (ServiceExceptionMapper.ErrorPayload) response.getEntity();
+
+        assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+        assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), entity.getStatus());
+        assertEquals("reason", entity.getMessage());
+    }
+
+    @Test
+    public void testOtherException() {
+
+        Response response = mapper.toResponse(new Exception("reason"));
+        ServiceExceptionMapper.ErrorPayload entity = (ServiceExceptionMapper.ErrorPayload) response.getEntity();
+
+        assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
+        assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), entity.getStatus());
+        assertEquals("reason", entity.getMessage());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/UtilsTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/UtilsTest.java b/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/UtilsTest.java
new file mode 100644
index 0000000..bf62785
--- /dev/null
+++ b/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/UtilsTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.hawq.ranger.authorization;
+
+import org.junit.Test;
+
+import static org.apache.hawq.ranger.authorization.Utils.APP_ID_PROPERTY;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * This test class uses values from rps.properties file in test/resources directory.
+ */
+public class UtilsTest {
+
+    @Test
+    public void testCustomAppId_SystemEnv() throws Exception {
+        System.setProperty(APP_ID_PROPERTY, "app-id");
+        assertEquals("app-id", Utils.getAppId());
+        System.clearProperty(APP_ID_PROPERTY);
+    }
+
+    @Test
+    public void testCustomAppId_PropertyFile() throws Exception {
+        assertEquals("instance-test", Utils.getAppId());
+    }
+
+    @Test
+    public void testGetVersion() throws Exception {
+        assertEquals("version-test", Utils.getVersion());
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/model/HawqPrivilegeTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/model/HawqPrivilegeTest.java b/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/model/HawqPrivilegeTest.java
new file mode 100644
index 0000000..39dd3cc
--- /dev/null
+++ b/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/model/HawqPrivilegeTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.hawq.ranger.authorization.model;
+
+import org.codehaus.jackson.map.ObjectMapper;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+
+public class HawqPrivilegeTest {
+
+    @Test
+    public void testSerialization() throws IOException {
+        assertEquals("create", HawqPrivilege.create.toValue());
+        assertEquals("create-schema", HawqPrivilege.create_schema.toValue());
+        assertEquals("usage-schema", HawqPrivilege.usage_schema.toValue());
+
+        ObjectMapper mapper = new ObjectMapper();
+        assertEquals("{\"value\":\"create\"}", mapper.writeValueAsString(new PrivilegeHolder(HawqPrivilege.create)));
+        assertEquals("{\"value\":\"create-schema\"}", mapper.writeValueAsString(new PrivilegeHolder(HawqPrivilege.create_schema)));
+        assertEquals("{\"value\":\"usage-schema\"}", mapper.writeValueAsString(new PrivilegeHolder(HawqPrivilege.usage_schema)));
+    }
+
+    @Test
+    public void testDeserialization() throws IOException {
+        assertNull(HawqPrivilege.fromString(null));
+        assertSame(HawqPrivilege.create, HawqPrivilege.fromString("create"));
+        assertSame(HawqPrivilege.create, HawqPrivilege.fromString("CREATE"));
+        assertSame(HawqPrivilege.create, HawqPrivilege.fromString("CreATe"));
+        assertSame(HawqPrivilege.create_schema, HawqPrivilege.fromString("CreATe-schema"));
+        assertSame(HawqPrivilege.usage_schema, HawqPrivilege.fromString("USage-schema"));
+
+
+        ObjectMapper mapper = new ObjectMapper();
+        assertSame(HawqPrivilege.create, mapper.readValue("{\"value\": \"create\"}", PrivilegeHolder.class).value);
+        assertSame(HawqPrivilege.create, mapper.readValue("{\"value\": \"CREATE\"}", PrivilegeHolder.class).value);
+        assertSame(HawqPrivilege.create, mapper.readValue("{\"value\": \"creATe\"}", PrivilegeHolder.class).value);
+        assertSame(HawqPrivilege.create_schema, mapper.readValue("{\"value\": \"CreATe-schema\"}", PrivilegeHolder.class).value);
+        assertSame(HawqPrivilege.usage_schema, mapper.readValue("{\"value\": \"USage-schema\"}", PrivilegeHolder.class).value);
+    }
+
+    public static class PrivilegeHolder {
+        public HawqPrivilege value;
+        PrivilegeHolder () {
+        }
+        PrivilegeHolder(HawqPrivilege value) {
+            this.value = value;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/model/HawqResourceTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/model/HawqResourceTest.java b/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/model/HawqResourceTest.java
new file mode 100644
index 0000000..f59a600
--- /dev/null
+++ b/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/model/HawqResourceTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.hawq.ranger.authorization.model;
+
+import org.codehaus.jackson.map.ObjectMapper;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+
+public class HawqResourceTest {
+
+    @Test
+    public void testCaseInsensitiveDeserialization() throws IOException {
+        assertNull(HawqResource.fromString(null));
+        assertSame(HawqResource.database, HawqResource.fromString("database"));
+        assertSame(HawqResource.database, HawqResource.fromString("DATABASE"));
+        assertSame(HawqResource.database, HawqResource.fromString("datABAse"));
+
+        ObjectMapper mapper = new ObjectMapper();
+        assertSame(HawqResource.database, mapper.readValue("{\"value\": \"database\"}", ResourceHolder.class).value);
+        assertSame(HawqResource.database, mapper.readValue("{\"value\": \"DATABASE\"}", ResourceHolder.class).value);
+        assertSame(HawqResource.database, mapper.readValue("{\"value\": \"datABAse\"}", ResourceHolder.class).value);
+    }
+
+    public static class ResourceHolder {
+        public HawqResource value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/test/resources/log4j.properties b/ranger-plugin/service/src/test/resources/log4j.properties
new file mode 100644
index 0000000..b9888df
--- /dev/null
+++ b/ranger-plugin/service/src/test/resources/log4j.properties
@@ -0,0 +1,42 @@
+# 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.
+
+# see debug messages during unit tests
+#project.root.logger=DEBUG,console
+
+# suppress all logging output during unit tests
+project.root.logger=FATAL,devnull
+
+#
+# Loggers
+#
+log4j.rootLogger=${project.root.logger}
+
+# ignore most errors from the Apache Ranger and Hadoop for unit tests
+log4j.logger.org.apache.ranger=FATAL
+log4j.logger.org.apache.hadoop=FATAL
+
+#
+# Appenders
+#
+
+# nothing
+log4j.appender.devnull=org.apache.log4j.varia.NullAppender
+
+# console
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.target=System.err
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2}: %m%n
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/test/resources/rps.properties
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/test/resources/rps.properties b/ranger-plugin/service/src/test/resources/rps.properties
new file mode 100644
index 0000000..1fd50e5
--- /dev/null
+++ b/ranger-plugin/service/src/test/resources/rps.properties
@@ -0,0 +1,17 @@
+# 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.
+
+ranger.hawq.instance=instance-test
+version=version-test
\ No newline at end of file


[3/4] incubator-hawq git commit: HAWQ-1203. Ranger Plugin Service Implementation. (with contributions by Lav Jain and Leslie Chang) (close #1092)

Posted by ad...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListSchemasTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListSchemasTest.java b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListSchemasTest.java
new file mode 100644
index 0000000..94372aa
--- /dev/null
+++ b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListSchemasTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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 schema governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.hawq.ranger.integration.admin;
+
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Set;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Arrays;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ListSchemasTest extends LookupTestBase {
+
+    private static final Set<String> DEFAULT_SCHEMAS = Sets.newHashSet("public");
+    private static final Set<String> EAST_SCHEMAS = Sets.newHashSet("common", "japan", "public");
+    private static final Set<String> WEST_SCHEMAS = Sets.newHashSet("common", "france", "jamaica", "public");
+    private static final Set<String> ALL_SCHEMAS = Sets.newHashSet("common", "japan", "france", "jamaica", "public");
+
+    private Map<String, List<String>> resources;
+
+    @Before
+    public void setUp() {
+        resources = new HashMap<>();
+    }
+
+    @Test
+    public void testListSchema_NoResources() throws Exception {
+        resources.put("database", Arrays.asList("noschema_db"));
+        List<String> result = service.lookupResource(getContext("schema", "*", resources));
+        assertEquals(DEFAULT_SCHEMAS.size(), result.size());
+        assertEquals(DEFAULT_SCHEMAS, Sets.newHashSet(result));
+    }
+
+    @Test
+    public void testListSchemas_SingleDb_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        List<String> result = service.lookupResource(getContext("schema", "*", resources));
+        assertEquals(EAST_SCHEMAS.size(), result.size());
+        assertEquals(EAST_SCHEMAS, Sets.newHashSet(result));
+    }
+
+    @Test
+    public void testListSchemas_TwoDb_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        List<String> result = service.lookupResource(getContext("schema", "*", resources));
+        assertEquals(ALL_SCHEMAS.size(), result.size());
+        assertEquals(ALL_SCHEMAS, Sets.newHashSet(result));
+    }
+
+    @Test
+    public void testListSchemas_AllDb_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("schema", "*", resources));
+        assertEquals(ALL_SCHEMAS.size(), result.size());
+        assertEquals(ALL_SCHEMAS, Sets.newHashSet(result));
+    }
+
+    @Test
+    public void testListSchemas_SingleDb_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        List<String> result = service.lookupResource(getContext("schema", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListSchemas_TwoDb_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        List<String> result = service.lookupResource(getContext("schema", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListSchemas_AllDb_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("schema", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListSchemas_SingleDb_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        List<String> result = service.lookupResource(getContext("schema", "ja", resources));
+        assertEquals(1, result.size());
+        assertEquals("japan", result.get(0));
+    }
+
+    @Test
+    public void testListSchemas_TwoDb_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        List<String> result = service.lookupResource(getContext("schema", "ja", resources));
+        assertEquals(2, result.size());
+        assertEquals(Sets.newHashSet("japan", "jamaica"), Sets.newHashSet(result));
+    }
+
+    @Test
+    public void testListSchemas_AllDb_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("schema", "ja", resources));
+        assertEquals(2, result.size());
+        assertEquals(Sets.newHashSet("japan", "jamaica"), Sets.newHashSet(result));
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListSequencesTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListSequencesTest.java b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListSequencesTest.java
new file mode 100644
index 0000000..0c601c2
--- /dev/null
+++ b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListSequencesTest.java
@@ -0,0 +1,250 @@
+/*
+ * 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 schema governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.hawq.ranger.integration.admin;
+
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Arrays;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ListSequencesTest extends LookupTestBase {
+
+    private Map<String, List<String>> resources;
+
+    @Before
+    public void setUp() {
+        resources = new HashMap<>();
+    }
+
+    @Test
+    public void testListSequences_NoSchemaDb_AllSchemas_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("noschema_db"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("sequence", "*", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListSequences_SingleDb_SingleSchema_AllFilter_NoSequences() throws Exception {
+        resources.put("database", Arrays.asList("west"));
+        resources.put("schema", Arrays.asList("jamaica"));
+        List<String> result = service.lookupResource(getContext("sequence", "*", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListSequences_SingleDb_SingleSchema_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("japan"));
+        List<String> result = service.lookupResource(getContext("sequence", "*", resources));
+        assertEquals(2, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("water", "sake")));
+    }
+
+    @Test
+    public void testListSequences_SingleDb_TwoSchemas_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("common", "japan"));
+        List<String> result = service.lookupResource(getContext("sequence", "*", resources));
+        assertEquals(3, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("water", "sprite", "sake")));
+    }
+
+    @Test
+    public void testListSequences_SingleDb_AllSchemas_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("sequence", "*", resources));
+        assertEquals(3, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("water", "sprite", "sake")));
+    }
+
+    @Test
+    public void testListSequences_TwoDb_CommonSchema_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("common"));
+        List<String> result = service.lookupResource(getContext("sequence", "*", resources));
+        assertEquals(2, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("water", "sprite")));
+    }
+
+    @Test
+    public void testListSequences_TwoDb_SingleSchema_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("japan"));
+        List<String> result = service.lookupResource(getContext("sequence", "*", resources));
+        assertEquals(2, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("water", "sake")));
+    }
+
+    @Test
+    public void testListSequences_TwoDb_AllSchemas_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("sequence", "*", resources));
+        assertEquals(4, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("water", "sprite", "sake", "scotch")));
+    }
+
+    @Test
+    public void testListSequences_AllDb_AllSchemas_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("*"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("sequence", "*", resources));
+        assertEquals(4, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("water", "sprite", "sake", "scotch")));
+    }
+
+    @Test
+    public void testListSequences_SingleDb_SingleSchema_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("japan"));
+        List<String> result = service.lookupResource(getContext("sequence", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListSequences_SingleDb_TwoSchemas_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("common", "japan"));
+        List<String> result = service.lookupResource(getContext("sequence", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListSequences_SingleDb_AllSchemas_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("sequence", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListSequences_TwoDbs_CommonSchema_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("common"));
+        List<String> result = service.lookupResource(getContext("sequence", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListSequences_TwoDbs_SingleSchema_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("japan"));
+        List<String> result = service.lookupResource(getContext("sequence", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListSequences_TwoDbs_AllSchemas_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("sequence", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListSequences_AllDbs_AllSchemas_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("*"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("sequence", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListSequences_SingleDb_SingleSchema_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("japan"));
+        List<String> result = service.lookupResource(getContext("sequence", "s", resources));
+        assertEquals(1, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("sake")));
+    }
+
+    @Test
+    public void testListSequences_SingleDb_TwoSchemas_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("common", "japan"));
+        List<String> result = service.lookupResource(getContext("sequence", "s", resources));
+        assertEquals(2, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("sprite", "sake")));
+    }
+
+    @Test
+    public void testListSequences_SingleDb_AllSchemas_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("sequence", "s", resources));
+        assertEquals(2, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("sprite", "sake")));
+    }
+
+    @Test
+    public void testListSequences_SingleDb_AllSchemas_FilteredPresent2() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("sequence", "w", resources));
+        assertEquals(1, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("water")));
+    }
+
+    @Test
+    public void testListSequences_TwoDbs_CommonSchema_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("common"));
+        List<String> result = service.lookupResource(getContext("sequence", "w", resources));
+        assertEquals(1, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("water")));
+    }
+
+    @Test
+    public void testListSequences_TwoDbs_SingleSchema_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("japan"));
+        List<String> result = service.lookupResource(getContext("sequence", "s", resources));
+        assertEquals(1, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("sake")));
+    }
+
+    @Test
+    public void testListSequences_TwoDbs_AllSchemas_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("sequence", "s", resources));
+        assertEquals(3, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("sprite", "sake", "scotch")));
+    }
+
+    @Test
+    public void testListSequences_AllDbs_AllSchemas_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("*"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("sequence", "s", resources));
+        assertEquals(3, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("sprite", "sake", "scotch")));
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListTablesTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListTablesTest.java b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListTablesTest.java
new file mode 100644
index 0000000..1360cac
--- /dev/null
+++ b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListTablesTest.java
@@ -0,0 +1,250 @@
+/*
+ * 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 schema governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.hawq.ranger.integration.admin;
+
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Arrays;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ListTablesTest extends LookupTestBase {
+
+    private Map<String, List<String>> resources;
+
+    @Before
+    public void setUp() {
+        resources = new HashMap<>();
+    }
+
+    @Test
+    public void testListTables_NoSchemaDb_AllSchemas_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("noschema_db"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("table", "*", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListTables_SingleDb_SingleSchema_AllFilter_NoTables() throws Exception {
+        resources.put("database", Arrays.asList("west"));
+        resources.put("schema", Arrays.asList("jamaica"));
+        List<String> result = service.lookupResource(getContext("table", "*", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListTables_SingleDb_SingleSchema_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("japan"));
+        List<String> result = service.lookupResource(getContext("table", "*", resources));
+        assertEquals(2, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("rice", "sushi")));
+    }
+
+    @Test
+    public void testListTables_SingleDb_TwoSchemas_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("common", "japan"));
+        List<String> result = service.lookupResource(getContext("table", "*", resources));
+        assertEquals(3, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("rice", "soup", "sushi")));
+    }
+
+    @Test
+    public void testListTables_SingleDb_AllSchemas_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("table", "*", resources));
+        assertEquals(3, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("rice", "soup", "sushi")));
+    }
+
+    @Test
+    public void testListTables_TwoDb_CommonSchema_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("common"));
+        List<String> result = service.lookupResource(getContext("table", "*", resources));
+        assertEquals(2, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("rice", "soup")));
+    }
+
+    @Test
+    public void testListTables_TwoDb_SingleSchema_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("japan"));
+        List<String> result = service.lookupResource(getContext("table", "*", resources));
+        assertEquals(2, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("rice", "sushi")));
+    }
+
+    @Test
+    public void testListTables_TwoDb_AllSchemas_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("table", "*", resources));
+        assertEquals(4, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("rice", "soup", "sushi", "stew")));
+    }
+
+    @Test
+    public void testListTables_AllDb_AllSchemas_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("*"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("table", "*", resources));
+        assertEquals(4, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("rice", "soup", "sushi", "stew")));
+    }
+
+    @Test
+    public void testListTables_SingleDb_SingleSchema_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("japan"));
+        List<String> result = service.lookupResource(getContext("table", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListTables_SingleDb_TwoSchemas_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("common", "japan"));
+        List<String> result = service.lookupResource(getContext("table", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListTables_SingleDb_AllSchemas_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("table", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListTables_TwoDbs_CommonSchema_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("common"));
+        List<String> result = service.lookupResource(getContext("table", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListTables_TwoDbs_SingleSchema_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("japan"));
+        List<String> result = service.lookupResource(getContext("table", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListTables_TwoDbs_AllSchemas_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("table", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListTables_AllDbs_AllSchemas_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("*"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("table", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListTables_SingleDb_SingleSchema_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("japan"));
+        List<String> result = service.lookupResource(getContext("table", "s", resources));
+        assertEquals(1, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("sushi")));
+    }
+
+    @Test
+    public void testListTables_SingleDb_TwoSchemas_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("common", "japan"));
+        List<String> result = service.lookupResource(getContext("table", "s", resources));
+        assertEquals(2, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("soup", "sushi")));
+    }
+
+    @Test
+    public void testListTables_SingleDb_AllSchemas_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("table", "s", resources));
+        assertEquals(2, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("soup", "sushi")));
+    }
+
+    @Test
+    public void testListTables_SingleDb_AllSchemas_FilteredPresent2() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("table", "r", resources));
+        assertEquals(1, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("rice")));
+    }
+
+    @Test
+    public void testListTables_TwoDbs_CommonSchema_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("common"));
+        List<String> result = service.lookupResource(getContext("table", "r", resources));
+        assertEquals(1, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("rice")));
+    }
+
+    @Test
+    public void testListTables_TwoDbs_SingleSchema_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("japan"));
+        List<String> result = service.lookupResource(getContext("table", "s", resources));
+        assertEquals(1, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("sushi")));
+    }
+
+    @Test
+    public void testListTables_TwoDbs_AllSchemas_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("table", "s", resources));
+        assertEquals(3, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("soup", "sushi", "stew")));
+    }
+
+    @Test
+    public void testListTables_AllDbs_AllSchemas_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("*"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("table", "s", resources));
+        assertEquals(3, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("soup", "sushi", "stew")));
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListTablespacesTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListTablespacesTest.java b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListTablespacesTest.java
new file mode 100644
index 0000000..65048db
--- /dev/null
+++ b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListTablespacesTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.hawq.ranger.integration.admin;
+
+import com.google.common.collect.Sets;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ListTablespacesTest extends LookupTestBase {
+
+    private static final Set<String> TABLESPACES = Sets.newHashSet("pg_default", "pg_global", "dfs_default");
+
+    @Test
+    public void testListTablespace_All() throws Exception {
+        List<String> result = service.lookupResource(getContext("tablespace", "*"));
+        assertEquals(3, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet(TABLESPACES)));
+    }
+
+    @Test
+    public void testListTablespace_FilteredPresent() throws Exception {
+        List<String> result = service.lookupResource(getContext("tablespace", "pg_d"));
+        assertEquals(1, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("pg_default")));
+    }
+
+    @Test
+    public void testListTablespace_FilteredAbsent() throws Exception {
+        List<String> result = service.lookupResource(getContext("tablespace", "z"));
+        assertTrue(result.isEmpty());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/LookupTestBase.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/LookupTestBase.java b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/LookupTestBase.java
new file mode 100644
index 0000000..25265f3
--- /dev/null
+++ b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/LookupTestBase.java
@@ -0,0 +1,65 @@
+/*
+ * 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.hawq.ranger.integration.admin;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hawq.ranger.service.RangerServiceHawq;
+import org.apache.ranger.plugin.service.ResourceLookupContext;
+import org.junit.Before;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public abstract class LookupTestBase {
+
+    protected static final Log LOG = LogFactory.getLog(LookupTestBase.class);
+    protected RangerServiceHawq service;
+
+    @Before
+    public void setup() {
+        Map<String, String> configs = new HashMap<>();
+        configs = new HashMap<>();
+        configs.put("username", "gpadmin");
+        configs.put("password", "dQSF8ViAE4/I38xmFwJfCg==");
+        configs.put("hostname", "localhost");
+        configs.put("port", "5432");
+        configs.put("jdbc.driverClassName", "org.postgresql.Driver");
+
+        service = new RangerServiceHawq();
+        service.setServiceName("hawq");
+        service.setServiceType("hawq");
+        service.setConfigs(configs);
+    }
+
+    protected ResourceLookupContext getContext(String resourceName, String userInput) {
+        ResourceLookupContext context = new ResourceLookupContext();
+        context.setResourceName(resourceName);
+        context.setUserInput(userInput);
+        return context;
+    }
+
+    protected ResourceLookupContext getContext(String resourceName, String userInput, Map<String, List<String>> resources) {
+        ResourceLookupContext context = getContext(resourceName, userInput);
+        context.setResources(resources);
+        return context;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/admin/src/test/resources/admin-tests-ddl.sql
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/admin/src/test/resources/admin-tests-ddl.sql b/ranger-plugin/integration/admin/src/test/resources/admin-tests-ddl.sql
new file mode 100644
index 0000000..d9e7fcc
--- /dev/null
+++ b/ranger-plugin/integration/admin/src/test/resources/admin-tests-ddl.sql
@@ -0,0 +1,61 @@
+-- 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.
+
+-- EAST Database and its objects
+DROP DATABASE IF EXISTS east;
+CREATE DATABASE east;
+\c east;
+CREATE SCHEMA common;
+CREATE TABLE common.rice (id integer);
+CREATE TABLE common.soup (id integer);
+CREATE SEQUENCE common.water;
+CREATE SEQUENCE common.sprite;
+CREATE FUNCTION common.eat(integer) RETURNS integer AS 'select $1;' LANGUAGE SQL;
+CREATE FUNCTION common.sleep(integer) RETURNS integer AS 'select $1;' LANGUAGE SQL;
+CREATE SCHEMA japan;
+CREATE TABLE japan.rice (id integer);
+CREATE TABLE japan.sushi (id integer);
+CREATE SEQUENCE japan.water;
+CREATE SEQUENCE japan.sake;
+CREATE FUNCTION japan.eat(integer) RETURNS integer AS 'select $1;' LANGUAGE SQL;
+CREATE FUNCTION japan.stand(integer) RETURNS integer AS 'select $1;' LANGUAGE SQL;
+CREATE LANGUAGE langdbeast HANDLER plpgsql_call_handler;
+
+-- WEST Database and its objects
+DROP DATABASE IF EXISTS west;
+CREATE DATABASE west;
+\c west;
+CREATE SCHEMA common;
+CREATE TABLE common.rice (id integer);
+CREATE TABLE common.soup (id integer);
+CREATE SEQUENCE common.water;
+CREATE SEQUENCE common.sprite;
+CREATE FUNCTION common.eat(integer) RETURNS integer AS 'select $1;' LANGUAGE SQL;
+CREATE FUNCTION common.sleep(integer) RETURNS integer AS 'select $1;' LANGUAGE SQL;
+CREATE SCHEMA france;
+CREATE TABLE france.rice (id integer);
+CREATE TABLE france.stew (id integer);
+CREATE SEQUENCE france.water;
+CREATE SEQUENCE france.scotch;
+CREATE FUNCTION france.eat(integer) RETURNS integer AS 'select $1;' LANGUAGE SQL;
+CREATE FUNCTION france.smile(integer) RETURNS integer AS 'select $1;' LANGUAGE SQL;
+CREATE LANGUAGE langdbwest HANDLER plpgsql_call_handler;
+CREATE SCHEMA jamaica;
+
+-- Database without an explicit schema
+DROP DATABASE IF EXISTS noschema_db;
+CREATE DATABASE noschema_db;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/admin/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/admin/src/test/resources/log4j.properties b/ranger-plugin/integration/admin/src/test/resources/log4j.properties
new file mode 100644
index 0000000..903f0b6
--- /dev/null
+++ b/ranger-plugin/integration/admin/src/test/resources/log4j.properties
@@ -0,0 +1,34 @@
+# 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.
+
+##-- To prevent junits from cluttering the build run by default all test runs send output to null appender
+log4j.appender.devnull=org.apache.log4j.varia.NullAppender
+#hawq.ranger.root.logger=FATAL,devnull
+
+##-- uncomment the following line during during development/debugging so see debug messages during test run to be emitted to console
+hawq.ranger.root.logger=DEBUG,console
+log4j.rootLogger=${hawq.ranger.root.logger}
+
+# Logging Threshold
+log4j.threshold=ALL
+
+#
+# console
+# Add "console" to rootlogger above if you want to use this
+#
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.target=System.err
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2}: %m%n

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/pom.xml
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/pom.xml b/ranger-plugin/integration/pom.xml
new file mode 100644
index 0000000..b6aac80
--- /dev/null
+++ b/ranger-plugin/integration/pom.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.hawq</groupId>
+    <artifactId>ranger-plugin-integration</artifactId>
+    <packaging>pom</packaging>
+    <name>HAWQ Ranger Plugin - Integration Tests</name>
+    <description>HAWQ Ranger Plugin - Integration Tests</description>
+
+    <parent>
+        <groupId>org.apache.hawq</groupId>
+        <artifactId>ranger-plugin</artifactId>
+        <version>2.1.0.0</version>
+        <relativePath>..</relativePath>
+    </parent>
+
+    <modules>
+        <module>admin</module>
+        <module>service</module>
+    </modules>
+
+    <properties>
+        <jackson.version>1.9</jackson.version>
+    </properties>
+
+    <build>
+        <testResources>
+            <testResource>
+                <directory>src/test/resources</directory>
+                <includes>
+                    <include>**/*</include>
+                </includes>
+                <filtering>true</filtering>
+            </testResource>
+        </testResources>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.7</source>
+                    <target>1.7</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/service/pom.xml
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/pom.xml b/ranger-plugin/integration/service/pom.xml
new file mode 100644
index 0000000..34ade8d
--- /dev/null
+++ b/ranger-plugin/integration/service/pom.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.hawq</groupId>
+    <artifactId>ranger-plugin-integration-service</artifactId>
+    <packaging>jar</packaging>
+    <name>HAWQ Ranger Plugin - Integration Tests</name>
+    <description>HAWQ Ranger Plugin - Integration Tests</description>
+
+    <parent>
+        <groupId>org.apache.hawq</groupId>
+        <artifactId>ranger-plugin-integration</artifactId>
+        <version>2.1.0.0</version>
+        <relativePath>..</relativePath>
+    </parent>
+
+    <dependencies>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>1.3.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-mapper-asl</artifactId>
+            <version>1.9.13</version>
+        </dependency>
+
+        <!-- Test Dependencies -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/DatabaseTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/DatabaseTest.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/DatabaseTest.java
new file mode 100644
index 0000000..451a289
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/DatabaseTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.hawq.ranger.integration.service.tests;
+
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class DatabaseTest extends ServiceBaseTest {
+
+    private static final List<String> PRIVILEGES = Arrays.asList("connect", "temp");
+
+    public void beforeTest()
+            throws IOException {
+        createPolicy("test-database.json");
+        resources.put("database", "sirotan");
+    }
+
+    @Test
+    public void testDatabases_UserMaria_SirotanDb_Allowed()
+            throws IOException {
+        assertTrue(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    }
+
+    @Test
+    public void testDatabases_UserMaria_DoesNotExistDb_Denied()
+            throws IOException {
+        resources.put("database", "doesnotexist");
+        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    }
+
+    @Test
+    public void testDatabases_UserBob_SirotanDb_Denied()
+            throws IOException {
+        assertFalse(hasAccess("bob", resources, PRIVILEGES));
+    }
+
+    @Test
+    public void testDatabases_UserMaria_SirotanDb_Denied()
+            throws IOException {
+        deletePolicy();
+        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/FunctionTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/FunctionTest.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/FunctionTest.java
new file mode 100644
index 0000000..1253c38
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/FunctionTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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.hawq.ranger.integration.service.tests;
+
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class FunctionTest extends ServiceBaseTest {
+
+    private static final List<String> PRIVILEGES = Arrays.asList("execute");
+
+    public void beforeTest()
+            throws IOException {
+        createPolicy("test-function.json");
+        resources.put("database", "sirotan");
+        resources.put("schema", "siroschema");
+        resources.put("function", "atan");
+    }
+
+    @Test
+    public void testFunctions_UserMaria_SirotanDb_AtanFunction_Allowed()
+            throws IOException {
+        assertTrue(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    }
+
+    @Test
+    public void testFunctions_UserMaria_OtherDb_AtanFunction_Denied()
+            throws IOException {
+        resources.put("database", "other");
+        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    }
+
+    @Test
+    public void testFunctions_UserMaria_SirotanDb_DoesNotExistFunction_Denied()
+            throws IOException {
+        resources.put("function", "doesnotexist");
+        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    }
+
+    @Test
+    public void testFunctions_UserBob_SirotanDb_AtanFunction_Denied()
+            throws IOException {
+        assertFalse(hasAccess("bob", resources, PRIVILEGES));
+    }
+
+    @Test
+    public void testFunctions_UserMaria_SirotanDb_AtanFunction_Denied()
+            throws IOException {
+        deletePolicy();
+        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    }
+
+    @Test
+    public void testFunctions_UserMaria_DoesNotExistDb_AtanFunction_Denied()
+            throws IOException {
+        resources.put("database", "doesnotexist");
+        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    }
+
+    @Test
+    public void testFunctions_UserMaria_SirotanDb_AtanFunction_Policy2_Allowed()
+            throws IOException {
+        deletePolicy();
+        createPolicy("test-function-2.json");
+        assertTrue(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/LanguageTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/LanguageTest.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/LanguageTest.java
new file mode 100644
index 0000000..6eedb08
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/LanguageTest.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.hawq.ranger.integration.service.tests;
+
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class LanguageTest extends ServiceBaseTest {
+
+    private static final List<String> PRIVILEGES = Arrays.asList("usage");
+
+    public void beforeTest()
+            throws IOException {
+        createPolicy("test-language.json");
+        resources.put("database", "sirotan");
+        resources.put("language", "sql");
+    }
+
+    @Test
+    public void testLanguages_UserMaria_SirotanDb_SqlLanguage_Allowed()
+            throws IOException {
+        assertTrue(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    }
+
+    @Test
+    public void testLanguages_UserMaria_SirotanDb_DoesNotExistLanguage_Denied()
+            throws IOException {
+        resources.put("language", "doesnotexist");
+        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    }
+
+    @Test
+    public void testLanguages_UserBob_SirotanDb_SqlLanguage_Denied()
+            throws IOException {
+        assertFalse(hasAccess("bob", resources, PRIVILEGES));
+    }
+
+    @Test
+    public void testLanguages_UserMaria_SirotanDb_SqlLanguage_Denied()
+            throws IOException {
+        deletePolicy();
+        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    }
+
+    @Test
+    public void testLanguages_UserMaria_DoesNotExistDb_SqlLanguage_Denied()
+            throws IOException {
+        resources.put("database", "doesnotexist");
+        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    }
+
+    @Test
+    public void testLanguages_UserMaria_SirotanDb_SqlLanguage_Policy2_Allowed()
+            throws IOException {
+        deletePolicy();
+        createPolicy("test-language-2.json");
+        assertTrue(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/ProtocolTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/ProtocolTest.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/ProtocolTest.java
new file mode 100644
index 0000000..f0e5c99
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/ProtocolTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.hawq.ranger.integration.service.tests;
+
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class ProtocolTest extends ServiceBaseTest {
+
+    private static final List<String> PRIVILEGES = Arrays.asList("select", "insert");
+
+    public void beforeTest()
+            throws IOException {
+        createPolicy("test-protocol.json");
+        resources.put("protocol", "pxf");
+    }
+
+    @Test
+    public void testProtocols_UserMaria_PxfProtocol_Allowed()
+            throws IOException {
+        assertTrue(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    }
+
+    @Test
+    public void testProtocols_UserMaria_DoesNotExistProtocol_Denied()
+            throws IOException {
+        resources.put("protocol", "doesnotexist");
+        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    }
+
+    @Test
+    public void testProtocols_UserBob_PxfProtocol_Denied()
+            throws IOException {
+        assertFalse(hasAccess("bob", resources, PRIVILEGES));
+    }
+
+    @Test
+    public void testProtocols_UserMaria_PxfProtocol_Denied()
+            throws IOException {
+        deletePolicy();
+        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/RPSRequest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/RPSRequest.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/RPSRequest.java
new file mode 100644
index 0000000..7e7787a
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/RPSRequest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.hawq.ranger.integration.service.tests;
+
+import org.codehaus.jackson.map.ObjectMapper;
+
+import java.io.IOException;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class RPSRequest {
+
+    String user;
+    Map<String, String> resources;
+    List<String> privileges;
+
+    public RPSRequest(String user,
+                      Map<String, String> resources,
+                      List<String> privileges) {
+        this.user = user;
+        this.resources = resources;
+        this.privileges = privileges;
+    }
+
+    public String getJsonString()
+            throws IOException {
+
+        Map<String, Object> request = new HashMap<>();
+        request.put("requestId", 9);
+        request.put("user", user);
+        request.put("clientIp", "123.0.0.21");
+        request.put("context", "CREATE DATABASE sirotan;");
+        Map<String, Object> accessHash = new HashMap<>();
+        accessHash.put("resource", resources);
+        accessHash.put("privileges", privileges);
+        request.put("access", Arrays.asList(accessHash));
+        return new ObjectMapper().writeValueAsString(request);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/RPSResponse.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/RPSResponse.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/RPSResponse.java
new file mode 100644
index 0000000..2ed1046
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/RPSResponse.java
@@ -0,0 +1,42 @@
+/*
+ * 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.hawq.ranger.integration.service.tests;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+import java.util.List;
+import java.util.Map;
+
+public class RPSResponse {
+
+    @JsonProperty
+    public int requestId;
+
+    @JsonProperty
+    public List<Map<String, Object>> access;
+
+    public List<Map<String, Object>> getAccess() {
+        return access;
+    }
+
+    public boolean hasAccess() {
+        return (boolean) access.get(0).get("allowed");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/ServiceBaseTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/ServiceBaseTest.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/ServiceBaseTest.java
new file mode 100644
index 0000000..8608584
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/ServiceBaseTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.hawq.ranger.integration.service.tests;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.rules.TestName;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public abstract class ServiceBaseTest {
+
+    protected final Log log = LogFactory.getLog(this.getClass());
+
+    @Rule
+    public final TestName testName = new TestName();
+    protected final String policyName = getClass().getSimpleName();
+    protected Map<String, String> resources = new HashMap<>();
+
+    public static String RANGER_PLUGIN_SERVICE_HOST = "localhost";
+    public static String RANGER_PLUGIN_SERVICE_PORT = "8432";
+    public static String RANGER_PLUGIN_SERVICE_URL =
+        "http://" + RANGER_PLUGIN_SERVICE_HOST + ":" + RANGER_PLUGIN_SERVICE_PORT + "/rps";
+    public static String RANGER_ADMIN_HOST = "localhost";
+    public static String RANGER_ADMIN_PORT = "6080";
+    public static String RANGER_URL =
+        "http://" + RANGER_ADMIN_HOST + ":" + RANGER_ADMIN_PORT + "/service/public/v2/api";
+    public static String RANGER_TEST_USER = "maria_dev";
+    public static int    POLICY_REFRESH_INTERVAL = 6000;
+
+    @Before
+    public void setUp()
+            throws IOException {
+        log.info("======================================================================================");
+        log.info("Running test " + testName.getMethodName());
+        log.info("======================================================================================");
+        beforeTest();
+    }
+
+    @After
+    public void tearDown()
+            throws IOException {
+        deletePolicy();
+    }
+
+    protected void createPolicy(String jsonFile)
+            throws IOException {
+
+        log.info("Creating policy " + policyName);
+        HttpPost httpPost = new HttpPost(RANGER_URL + "/policy");
+        httpPost.setEntity(new StringEntity(Utils.getPayload(jsonFile)));
+        Utils.processHttpRequest(httpPost);
+        waitForPolicyRefresh();
+    }
+
+    protected void deletePolicy()
+            throws IOException {
+
+        log.info("Deleting policy " + policyName);
+        String requestUrl = RANGER_URL + "/policy?servicename=hawq&policyname=" + policyName;
+        Utils.processHttpRequest(new HttpDelete(requestUrl));
+        waitForPolicyRefresh();
+    }
+
+    protected boolean hasAccess(String user,
+                                Map<String, String> resources,
+                                List<String> privileges)
+            throws IOException {
+
+        log.info("Checking access for user " + user);
+        RPSRequest request = new RPSRequest(user, resources, privileges);
+        HttpPost httpPost = new HttpPost(RANGER_PLUGIN_SERVICE_URL);
+        httpPost.setEntity(new StringEntity(request.getJsonString()));
+        String result = Utils.processHttpRequest(httpPost);
+        RPSResponse rpsResponse = Utils.getResponse(result);
+        return rpsResponse.hasAccess();
+    }
+
+    private void waitForPolicyRefresh() {
+
+        try {
+            Thread.sleep(POLICY_REFRESH_INTERVAL);
+        }
+        catch (InterruptedException e) {
+            log.error(e);
+        }
+    }
+
+    public abstract void beforeTest() throws IOException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/TablespaceTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/TablespaceTest.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/TablespaceTest.java
new file mode 100644
index 0000000..cfc41cb
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/TablespaceTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.hawq.ranger.integration.service.tests;
+
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class TablespaceTest extends ServiceBaseTest {
+
+    private static final List<String> PRIVILEGES = Arrays.asList("create");
+
+    public void beforeTest()
+            throws IOException {
+        createPolicy("test-tablespace.json");
+        resources.put("tablespace", "pg_global");
+    }
+
+    @Test
+    public void testTablespaces_UserMaria_PgGlobalTablespace_Allowed()
+            throws IOException {
+        assertTrue(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    }
+
+    @Test
+    public void testTablespaces_UserMaria_DoesNotExistTablespace_Denied()
+            throws IOException {
+        resources.put("tablespace", "doesnotexist");
+        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    }
+
+    @Test
+    public void testTablespaces_UserBob_PgGlobalTablespace_Denied()
+            throws IOException {
+        assertFalse(hasAccess("bob", resources, PRIVILEGES));
+    }
+
+    @Test
+    public void testTablespaces_UserMaria_PgGlobalTablespace_Denied()
+            throws IOException {
+        deletePolicy();
+        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/Utils.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/Utils.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/Utils.java
new file mode 100644
index 0000000..971e513
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/Utils.java
@@ -0,0 +1,76 @@
+/*
+ * 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.hawq.ranger.integration.service.tests;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.codehaus.jackson.map.ObjectMapper;
+
+import java.io.IOException;
+
+public class Utils {
+
+    protected static final Log log = LogFactory.getLog(Utils.class);
+
+    public static String getPayload(String jsonFile)
+            throws IOException {
+        return IOUtils.toString(Utils.class.getClassLoader().getResourceAsStream(jsonFile));
+    }
+
+    public static String getEncoding() {
+        return Base64.encodeBase64String("admin:admin".getBytes());
+    }
+
+    public static String processHttpRequest(HttpRequestBase request)
+            throws IOException {
+
+        if (log.isDebugEnabled()) {
+            log.debug("Request URI = " + request.getURI().toString());
+        }
+        request.setHeader("Authorization", "Basic " + getEncoding());
+        request.setHeader("Content-Type", "application/json");
+        HttpClient httpClient = HttpClientBuilder.create().build();
+        HttpResponse response = httpClient.execute(request);
+        int responseCode = response.getStatusLine().getStatusCode();
+        log.info("Response Code = " + responseCode);
+        HttpEntity entity = response.getEntity();
+        if (entity != null) {
+            String result = IOUtils.toString(entity.getContent());
+            if (log.isDebugEnabled()) {
+                log.debug(result);
+            }
+            return result;
+        }
+        return null;
+    }
+
+    public static RPSResponse getResponse(String result)
+            throws IOException {
+        return new ObjectMapper().readValue(result, RPSResponse.class);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/service/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/resources/log4j.properties b/ranger-plugin/integration/service/src/test/resources/log4j.properties
new file mode 100644
index 0000000..8578fd2
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/resources/log4j.properties
@@ -0,0 +1,35 @@
+# 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.
+
+##-- To prevent junits from cluttering the build run by default all test runs send output to null appender
+log4j.appender.devnull=org.apache.log4j.varia.NullAppender
+#hawq.ranger.root.logger=FATAL,devnull
+
+##-- uncomment the following line during during development/debugging so see debug messages during test run to be emitted to console
+hawq.ranger.root.logger=DEBUG,console
+log4j.rootLogger=${hawq.ranger.root.logger}
+log4j.logger.org.apache.http=WARN
+
+# Logging Threshold
+log4j.threshold=ALL
+
+#
+# console
+# Add "console" to rootlogger above if you want to use this
+#
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.target=System.err
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2}: %m%n

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/service/src/test/resources/test-database.json
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/resources/test-database.json b/ranger-plugin/integration/service/src/test/resources/test-database.json
new file mode 100644
index 0000000..ffa3bfe
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/resources/test-database.json
@@ -0,0 +1,46 @@
+{
+  "isEnabled": true,
+  "service": "hawq",
+  "name": "DatabaseTest",
+  "policyType": 0,
+  "description": "Test policy for database resource",
+  "isAuditEnabled": true,
+  "resources": {
+    "schema": {
+      "values": ["*"],
+      "isExcludes": false,
+      "isRecursive": false
+    },
+    "database": {
+      "values": ["sirotan"],
+      "isExcludes": false,
+      "isRecursive": false
+    },
+    "function": {
+      "values": ["*"],
+      "isExcludes": false,
+      "isRecursive": false
+    }
+  },
+  "policyItems": [{
+    "accesses": [{
+      "type": "create",
+      "isAllowed": true
+    }, {
+      "type": "connect",
+      "isAllowed": true
+    }, {
+      "type": "temp",
+      "isAllowed": true
+    }],
+    "users": ["maria_dev"],
+    "groups": [],
+    "conditions": [],
+    "delegateAdmin": true
+  }],
+  "denyPolicyItems": [],
+  "allowExceptions": [],
+  "denyExceptions": [],
+  "dataMaskPolicyItems": [],
+  "rowFilterPolicyItems": []
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/service/src/test/resources/test-function-2.json
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/resources/test-function-2.json b/ranger-plugin/integration/service/src/test/resources/test-function-2.json
new file mode 100644
index 0000000..5ae7f0b
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/resources/test-function-2.json
@@ -0,0 +1,40 @@
+{
+  "isEnabled": true,
+  "service": "hawq",
+  "name": "FunctionTest",
+  "policyType": 0,
+  "description": "Test policy for function resource",
+  "isAuditEnabled": true,
+  "resources": {
+    "schema": {
+      "values": ["*"],
+      "isExcludes": false,
+      "isRecursive": false
+    },
+    "database": {
+      "values": ["*"],
+      "isExcludes": false,
+      "isRecursive": false
+    },
+    "function": {
+      "values": ["atan"],
+      "isExcludes": false,
+      "isRecursive": false
+    }
+  },
+  "policyItems": [{
+    "accesses": [{
+      "type": "execute",
+      "isAllowed": true
+    }],
+    "users": ["maria_dev"],
+    "groups": [],
+    "conditions": [],
+    "delegateAdmin": true
+  }],
+  "denyPolicyItems": [],
+  "allowExceptions": [],
+  "denyExceptions": [],
+  "dataMaskPolicyItems": [],
+  "rowFilterPolicyItems": []
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/service/src/test/resources/test-function.json
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/resources/test-function.json b/ranger-plugin/integration/service/src/test/resources/test-function.json
new file mode 100644
index 0000000..74d5d83
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/resources/test-function.json
@@ -0,0 +1,40 @@
+{
+  "isEnabled": true,
+  "service": "hawq",
+  "name": "FunctionTest",
+  "policyType": 0,
+  "description": "Test policy for function resource",
+  "isAuditEnabled": true,
+  "resources": {
+    "schema": {
+      "values": ["siroschema"],
+      "isExcludes": false,
+      "isRecursive": false
+    },
+    "database": {
+      "values": ["sirotan"],
+      "isExcludes": false,
+      "isRecursive": false
+    },
+    "function": {
+      "values": ["atan"],
+      "isExcludes": false,
+      "isRecursive": false
+    }
+  },
+  "policyItems": [{
+    "accesses": [{
+      "type": "execute",
+      "isAllowed": true
+    }],
+    "users": ["maria_dev"],
+    "groups": [],
+    "conditions": [],
+    "delegateAdmin": true
+  }],
+  "denyPolicyItems": [],
+  "allowExceptions": [],
+  "denyExceptions": [],
+  "dataMaskPolicyItems": [],
+  "rowFilterPolicyItems": []
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/service/src/test/resources/test-language-2.json
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/resources/test-language-2.json b/ranger-plugin/integration/service/src/test/resources/test-language-2.json
new file mode 100644
index 0000000..93a41fe
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/resources/test-language-2.json
@@ -0,0 +1,35 @@
+{
+  "isEnabled": true,
+  "service": "hawq",
+  "name": "LanguageTest",
+  "policyType": 0,
+  "description": "Test policy for language resource",
+  "isAuditEnabled": true,
+  "resources": {
+    "language": {
+      "values": ["sql"],
+      "isExcludes": false,
+      "isRecursive": false
+    },
+    "database": {
+      "values": ["*"],
+      "isExcludes": false,
+      "isRecursive": false
+    }
+  },
+  "policyItems": [{
+    "accesses": [{
+      "type": "usage",
+      "isAllowed": true
+    }],
+    "users": ["maria_dev"],
+    "groups": [],
+    "conditions": [],
+    "delegateAdmin": true
+  }],
+  "denyPolicyItems": [],
+  "allowExceptions": [],
+  "denyExceptions": [],
+  "dataMaskPolicyItems": [],
+  "rowFilterPolicyItems": []
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/service/src/test/resources/test-language.json
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/resources/test-language.json b/ranger-plugin/integration/service/src/test/resources/test-language.json
new file mode 100644
index 0000000..cba2f43
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/resources/test-language.json
@@ -0,0 +1,35 @@
+{
+  "isEnabled": true,
+  "service": "hawq",
+  "name": "LanguageTest",
+  "policyType": 0,
+  "description": "Test policy for language resource",
+  "isAuditEnabled": true,
+  "resources": {
+    "language": {
+      "values": ["sql"],
+      "isExcludes": false,
+      "isRecursive": false
+    },
+    "database": {
+      "values": ["sirotan"],
+      "isExcludes": false,
+      "isRecursive": false
+    }
+  },
+  "policyItems": [{
+    "accesses": [{
+      "type": "usage",
+      "isAllowed": true
+    }],
+    "users": ["maria_dev"],
+    "groups": [],
+    "conditions": [],
+    "delegateAdmin": true
+  }],
+  "denyPolicyItems": [],
+  "allowExceptions": [],
+  "denyExceptions": [],
+  "dataMaskPolicyItems": [],
+  "rowFilterPolicyItems": []
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/service/src/test/resources/test-protocol.json
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/resources/test-protocol.json b/ranger-plugin/integration/service/src/test/resources/test-protocol.json
new file mode 100644
index 0000000..d59caed
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/resources/test-protocol.json
@@ -0,0 +1,33 @@
+{
+  "isEnabled": true,
+  "service": "hawq",
+  "name": "ProtocolTest",
+  "policyType": 0,
+  "description": "Test policy for protocol resource",
+  "isAuditEnabled": true,
+  "resources": {
+    "protocol": {
+      "values": ["pxf"],
+      "isExcludes": false,
+      "isRecursive": false
+    }
+  },
+  "policyItems": [{
+    "accesses": [{
+      "type": "select",
+      "isAllowed": true
+    }, {
+      "type": "insert",
+      "isAllowed": true
+    }],
+    "users": ["maria_dev"],
+    "groups": [],
+    "conditions": [],
+    "delegateAdmin": true
+  }],
+  "denyPolicyItems": [],
+  "allowExceptions": [],
+  "denyExceptions": [],
+  "dataMaskPolicyItems": [],
+  "rowFilterPolicyItems": []
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/service/src/test/resources/test-tablespace.json
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/resources/test-tablespace.json b/ranger-plugin/integration/service/src/test/resources/test-tablespace.json
new file mode 100644
index 0000000..a45ecea
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/resources/test-tablespace.json
@@ -0,0 +1,30 @@
+{
+  "isEnabled": true,
+  "service": "hawq",
+  "name": "TablespaceTest",
+  "policyType": 0,
+  "description": "Test policy for tablespace resource",
+  "isAuditEnabled": true,
+  "resources": {
+    "tablespace": {
+      "values": ["pg_global"],
+      "isExcludes": false,
+      "isRecursive": false
+    }
+  },
+  "policyItems": [{
+    "accesses": [{
+      "type": "create",
+      "isAllowed": true
+    }],
+    "users": ["maria_dev"],
+    "groups": [],
+    "conditions": [],
+    "delegateAdmin": true
+  }],
+  "denyPolicyItems": [],
+  "allowExceptions": [],
+  "denyExceptions": [],
+  "dataMaskPolicyItems": [],
+  "rowFilterPolicyItems": []
+}
\ No newline at end of file



[4/4] incubator-hawq git commit: HAWQ-1203. Ranger Plugin Service Implementation. (with contributions by Lav Jain and Leslie Chang) (close #1092)

Posted by ad...@apache.org.
HAWQ-1203. Ranger Plugin Service Implementation. (with contributions by Lav Jain and Leslie Chang)
(close #1092)


Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/7f36b35b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/7f36b35b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/7f36b35b

Branch: refs/heads/master
Commit: 7f36b35bd059412b45444f613fb5b5e108a3a83e
Parents: e46f06c
Author: Alexander Denissov <ad...@pivotal.io>
Authored: Mon Jan 16 11:46:36 2017 -0800
Committer: Alexander Denissov <ad...@pivotal.io>
Committed: Wed Jan 18 10:57:09 2017 -0800

----------------------------------------------------------------------
 .gitignore                                      |   7 +
 ranger-plugin/admin-plugin/pom.xml              |  90 +++++
 .../apache/hawq/ranger/model/HawqProtocols.java |  49 +++
 .../apache/hawq/ranger/model/HawqResource.java  |  29 ++
 .../apache/hawq/ranger/service/HawqClient.java  | 314 ++++++++++++++++++
 .../hawq/ranger/service/HawqResourceMgr.java    |  71 ++++
 .../hawq/ranger/service/RangerServiceHawq.java  |  66 ++++
 .../hawq/ranger/service/HawqClientTest.java     | 217 +++++++++++++
 .../ranger/service/RangerServiceHawqTest.java   |  90 +++++
 .../src/test/resources/log4j.properties         |  34 ++
 ranger-plugin/conf/ranger-servicedef-hawq.json  | 287 ++++++++++++++++
 ranger-plugin/conf/tomcat-server.xml            |  60 ++++
 ranger-plugin/integration/admin/pom.xml         |  70 ++++
 .../integration/admin/ListDatabasesTest.java    |  55 ++++
 .../integration/admin/ListFunctionsTest.java    | 250 ++++++++++++++
 .../integration/admin/ListLanguagesTest.java    | 118 +++++++
 .../integration/admin/ListProtocolsTest.java    |  55 ++++
 .../integration/admin/ListSchemasTest.java      | 126 +++++++
 .../integration/admin/ListSequencesTest.java    | 250 ++++++++++++++
 .../integration/admin/ListTablesTest.java       | 250 ++++++++++++++
 .../integration/admin/ListTablespacesTest.java  |  55 ++++
 .../integration/admin/LookupTestBase.java       |  65 ++++
 .../src/test/resources/admin-tests-ddl.sql      |  61 ++++
 .../admin/src/test/resources/log4j.properties   |  34 ++
 ranger-plugin/integration/pom.xml               |  67 ++++
 ranger-plugin/integration/service/pom.xml       |  68 ++++
 .../integration/service/tests/DatabaseTest.java |  67 ++++
 .../integration/service/tests/FunctionTest.java |  91 ++++++
 .../integration/service/tests/LanguageTest.java |  83 +++++
 .../integration/service/tests/ProtocolTest.java |  67 ++++
 .../integration/service/tests/RPSRequest.java   |  60 ++++
 .../integration/service/tests/RPSResponse.java  |  42 +++
 .../service/tests/ServiceBaseTest.java          | 116 +++++++
 .../service/tests/TablespaceTest.java           |  67 ++++
 .../ranger/integration/service/tests/Utils.java |  76 +++++
 .../service/src/test/resources/log4j.properties |  35 ++
 .../src/test/resources/test-database.json       |  46 +++
 .../src/test/resources/test-function-2.json     |  40 +++
 .../src/test/resources/test-function.json       |  40 +++
 .../src/test/resources/test-language-2.json     |  35 ++
 .../src/test/resources/test-language.json       |  35 ++
 .../src/test/resources/test-protocol.json       |  33 ++
 .../src/test/resources/test-tablespace.json     |  30 ++
 ranger-plugin/pom.xml                           | 248 ++++++++++++++
 ranger-plugin/scripts/register_hawq.sh          | 217 +++++++++++++
 ranger-plugin/scripts/rps.sh                    |  60 ++++
 ranger-plugin/scripts/rps_env.sh                |  30 ++
 ranger-plugin/service/pom.xml                   |  88 +++++
 .../ranger/authorization/HawqAuthorizer.java    |  36 ++
 .../authorization/RangerHawqAuthorizer.java     | 263 +++++++++++++++
 .../authorization/RangerHawqPluginResource.java |  86 +++++
 .../authorization/ServiceExceptionMapper.java   |  97 ++++++
 .../apache/hawq/ranger/authorization/Utils.java |  80 +++++
 .../model/AuthorizationRequest.java             | 115 +++++++
 .../model/AuthorizationResponse.java            |  63 ++++
 .../authorization/model/HawqPrivilege.java      |  61 ++++
 .../authorization/model/HawqResource.java       |  46 +++
 .../authorization/model/ResourceAccess.java     |  85 +++++
 .../service/src/main/resources/log4j.properties |  42 +++
 .../src/main/resources/ranger-hawq-security.xml |  92 ++++++
 .../service/src/main/resources/rps.properties   |  17 +
 .../service/src/main/webapp/WEB-INF/web.xml     |  72 ++++
 .../RangerHawqAuthorizerAppIdTest.java          |  39 +++
 .../authorization/RangerHawqAuthorizerTest.java | 325 +++++++++++++++++++
 .../RangerHawqPluginResourceTest.java           |  79 +++++
 .../ServiceExceptionMapperTest.java             |  61 ++++
 .../hawq/ranger/authorization/UtilsTest.java    |  48 +++
 .../authorization/model/HawqPrivilegeTest.java  |  71 ++++
 .../authorization/model/HawqResourceTest.java   |  48 +++
 .../service/src/test/resources/log4j.properties |  42 +++
 .../service/src/test/resources/rps.properties   |  17 +
 71 files changed, 6329 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 2076819..24039c6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,6 +41,12 @@ objfiles.txt
 .pydevproject
 .cproject
 .settings
+.classpath
+
+# IDEA Project
+*.iml
+.idea
+
 # Ctags
 **/tags
 
@@ -54,6 +60,7 @@ env.sh
 ext/
 plr.tgz
 autom4te.cache/
+**/target
 
 # coverage
 *.gcda

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/admin-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/ranger-plugin/admin-plugin/pom.xml b/ranger-plugin/admin-plugin/pom.xml
new file mode 100644
index 0000000..67c0824
--- /dev/null
+++ b/ranger-plugin/admin-plugin/pom.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.hawq</groupId>
+    <artifactId>ranger-plugin-admin</artifactId>
+    <packaging>jar</packaging>
+    <name>HAWQ Ranger Admin Plugin</name>
+    <description>HAWQ Ranger Admin Plugin</description>
+    <parent>
+        <groupId>org.apache.hawq</groupId>
+        <artifactId>ranger-plugin</artifactId>
+        <version>2.1.0.0</version>
+        <relativePath>..</relativePath>
+    </parent>
+
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>copy-dependencies</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/lib</outputDirectory>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+
+        <!-- Compilation Dependencies -->
+        <dependency>
+            <groupId>org.apache.ranger</groupId>
+            <artifactId>ranger-plugins-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+        </dependency>
+
+        <!-- Test Dependencies -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-module-junit4</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-api-mockito</artifactId>
+        </dependency>
+
+    </dependencies>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/admin-plugin/src/main/java/org/apache/hawq/ranger/model/HawqProtocols.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/admin-plugin/src/main/java/org/apache/hawq/ranger/model/HawqProtocols.java b/ranger-plugin/admin-plugin/src/main/java/org/apache/hawq/ranger/model/HawqProtocols.java
new file mode 100644
index 0000000..c6e51b0
--- /dev/null
+++ b/ranger-plugin/admin-plugin/src/main/java/org/apache/hawq/ranger/model/HawqProtocols.java
@@ -0,0 +1,49 @@
+/*
+ * 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.hawq.ranger.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public enum HawqProtocols {
+
+    PROTOCOL_FILE("file"),
+    PROTOCOL_FTP("ftp"),
+    PROTOCOL_HTTP("http"),
+    PROTOCOL_GPFDIST("gpfdist"),
+    PROTOCOL_GPFDISTS("gpfdists"),
+    PROTOCOL_PXF("pxf");
+
+    private final String name;
+
+    private HawqProtocols(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public static List<String> getAllProtocols() {
+        List<String> protocols = new ArrayList<>();
+        for(HawqProtocols protocol : HawqProtocols.values()) {
+            protocols.add(protocol.getName());
+        }
+        return protocols;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/admin-plugin/src/main/java/org/apache/hawq/ranger/model/HawqResource.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/admin-plugin/src/main/java/org/apache/hawq/ranger/model/HawqResource.java b/ranger-plugin/admin-plugin/src/main/java/org/apache/hawq/ranger/model/HawqResource.java
new file mode 100644
index 0000000..aae0b04
--- /dev/null
+++ b/ranger-plugin/admin-plugin/src/main/java/org/apache/hawq/ranger/model/HawqResource.java
@@ -0,0 +1,29 @@
+/*
+ * 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.hawq.ranger.model;
+
+public enum HawqResource {
+    DATABASE,
+    SCHEMA,
+    TABLE,
+    SEQUENCE,
+    FUNCTION,
+    LANGUAGE,
+    TABLESPACE,
+    PROTOCOL
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/admin-plugin/src/main/java/org/apache/hawq/ranger/service/HawqClient.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/admin-plugin/src/main/java/org/apache/hawq/ranger/service/HawqClient.java b/ranger-plugin/admin-plugin/src/main/java/org/apache/hawq/ranger/service/HawqClient.java
new file mode 100644
index 0000000..d2606be
--- /dev/null
+++ b/ranger-plugin/admin-plugin/src/main/java/org/apache/hawq/ranger/service/HawqClient.java
@@ -0,0 +1,314 @@
+/*
+ * 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.hawq.ranger.service;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hawq.ranger.model.HawqProtocols;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.ResultSet;
+import java.util.*;
+
+import static org.apache.ranger.plugin.client.BaseClient.generateResponseDataMap;
+
+public class HawqClient {
+
+    private static final Log LOG = LogFactory.getLog(HawqClient.class);
+
+    public static final String CONNECTION_SUCCESSFUL_MESSAGE = "ConnectionTest Successful";
+    public static final String CONNECTION_FAILURE_MESSAGE = "Unable to retrieve any databases using given parameters.";
+
+    public static final String DATABASE_LIST_QUERY = "SELECT datname from pg_database WHERE " +
+            "datname NOT IN ('template0', 'template1', 'hcatalog') and datname LIKE ?";
+    public static final String TABLESPACE_LIST_QUERY = "SELECT spcname from pg_tablespace WHERE spcname LIKE ?";
+    public static final String PROTOCOL_LIST_QUERY = "SELECT ptcname from pg_catalog.pg_extprotocol WHERE ptcname LIKE ?";
+    public static final String SCHEMA_LIST_QUERY = "SELECT schema_name from information_schema.schemata WHERE " +
+            "schema_name NOT IN ('pg_catalog', 'information_schema', 'hawq_toolkit', 'pg_bitmapindex', 'pg_aoseg') AND schema_name NOT LIKE 'pg_toast%' AND schema_name LIKE ?";
+    public static final String LANGUAGE_LIST_QUERY = "SELECT lanname from pg_language WHERE lanname LIKE ?";
+    public static final String SEQUENCE_LIST_QUERY = "SELECT schemaname, relname from pg_statio_all_sequences WHERE relname LIKE ?";
+    public static final String FUNCTION_LIST_QUERY = "SELECT n.nspname, p.proname FROM pg_catalog.pg_proc p " +
+            "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace WHERE n.nspname NOT IN " +
+            "('pg_catalog', 'information_schema', 'hawq_toolkit', 'pg_bitmapindex', 'pg_aoseg') AND n.nspname NOT LIKE 'pg_toast%' AND p.proname LIKE ?";
+    public static final String TABLE_LIST_QUERY = "SELECT c.relname, n.nspname FROM pg_catalog.pg_class c " +
+            "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('r','','v') AND n.nspname NOT IN " +
+            "('pg_catalog', 'information_schema', 'hawq_toolkit', 'pg_bitmapindex', 'pg_aoseg') AND n.nspname NOT LIKE 'pg_toast%' AND c.relname LIKE ?";
+
+    public static final String DATNAME = "datname";
+    public static final String SPCNAME = "spcname";
+    public static final String PTCNAME = "ptcname";
+    public static final String SCHEMA_NAME = "schema_name";
+    public static final String LANGUAGE_NAME = "lanname";
+    public static final String RELNAME = "relname";
+    public static final String SCHEMANAME = "schemaname";
+    public static final String PRONAME = "proname";
+    public static final String NSPNAME = "nspname";
+    public static final String WILDCARD = "*";
+
+    public static final List<String> INTERNAL_PROTOCOLS = HawqProtocols.getAllProtocols();
+    private static final String DEFAULT_DATABASE = "postgres";
+    private static final String JDBC_DRIVER_CLASS = "org.postgresql.Driver";
+
+    private Map<String, String> connectionProperties;
+
+    // we need to load class for the Postgres Driver directly to allow it to register with DriverManager
+    // since DriverManager's classloader will not be able to find it by itself due to plugin's special classloaders
+    static {
+        try {
+            Class.forName(JDBC_DRIVER_CLASS);
+        } catch (Throwable e) {
+            LOG.error("<== HawqClient.initializer : Unable to load JDBC driver " + JDBC_DRIVER_CLASS + " : " + e.getMessage());
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+
+    public HawqClient(Map<String, String> connectionProperties) throws SQLException {
+        this.connectionProperties = connectionProperties;
+    }
+
+    /**
+     * Uses the connectionProperties and attempts to connect to Hawq.
+     * Returns a message depending on success or failure.
+     *
+     * @param connectionProperties Map which contains hostname, port, username, and password
+     * @return Map which contains connectivityStatus, message, description, objectId, and fieldName
+     */
+
+    public HashMap<String, Object> checkConnection(Map<String, String> connectionProperties) throws Exception {
+
+        boolean isConnected = false;
+        HashMap<String, Object> result = new HashMap<>();
+        Connection conn = null;
+
+        String description = CONNECTION_FAILURE_MESSAGE;
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== HawqClient.checkConnection Starting connection to hawq");
+        }
+
+        try {
+            conn = getConnection(connectionProperties);
+            if(conn.getCatalog() != null) {
+                isConnected = true;
+                description = CONNECTION_SUCCESSFUL_MESSAGE;
+            }
+        } catch (SQLException e) {
+            LOG.error("<== HawqClient.checkConnection Error: Failed to connect" + e);
+            description = e.getMessage();
+        } finally {
+            closeConnection(conn);
+        }
+
+        String message = isConnected ? CONNECTION_SUCCESSFUL_MESSAGE : CONNECTION_FAILURE_MESSAGE;
+
+        generateResponseDataMap(isConnected, message, description, null, null, result);
+
+        return result;
+    }
+
+    public List<String> getDatabaseList(String userInput) throws SQLException {
+        return queryHawq(userInput, DATNAME, DATABASE_LIST_QUERY, null);
+    }
+
+    public List<String> getTablespaceList(String userInput) throws SQLException {
+        return queryHawq(userInput, SPCNAME, TABLESPACE_LIST_QUERY, null);
+    }
+
+    public List<String> getProtocolList(String userInput) throws SQLException {
+        Set<String> allProtocols = new HashSet<>();
+        for (String protocol : INTERNAL_PROTOCOLS) {
+            if(protocol.startsWith(userInput) || userInput.equals(WILDCARD)) {
+                allProtocols.add(protocol);
+            }
+        }
+        allProtocols.addAll(queryHawq(userInput, PTCNAME, PROTOCOL_LIST_QUERY, null));
+        return new ArrayList<>(allProtocols);
+    }
+
+    public List<String> getSchemaList(String userInput, Map<String, List<String>> resources) throws SQLException {
+        return queryHawqPerDb(userInput, resources.get("database"), SCHEMA_NAME, SCHEMA_LIST_QUERY);
+    }
+
+    public List<String> getLanguageList(String userInput,  Map<String, List<String>> resources) throws SQLException {
+        return queryHawqPerDb(userInput, resources.get("database"), LANGUAGE_NAME, LANGUAGE_LIST_QUERY);
+    }
+
+    public List<String> getTableList(String userInput, Map<String, List<String>> resources) throws SQLException {
+        return queryHawqPerDbAndSchema(userInput, resources, NSPNAME, RELNAME, TABLE_LIST_QUERY);
+    }
+
+    public List<String> getSequenceList(String userInput, Map<String, List<String>> resources) throws SQLException {
+        return queryHawqPerDbAndSchema(userInput, resources, SCHEMANAME, RELNAME, SEQUENCE_LIST_QUERY);
+    }
+
+    public List<String> getFunctionList(String userInput, Map<String, List<String>> resources) throws SQLException {
+        return queryHawqPerDbAndSchema(userInput, resources, NSPNAME, PRONAME, FUNCTION_LIST_QUERY);
+    }
+
+    private List<String> queryHawqPerDb(String userInput, List<String> databases, String columnName, String query) throws SQLException {
+        Set<String> uniqueResults = new HashSet<>();
+
+        //do for all databases
+        if (databases.contains(WILDCARD)) {
+            databases = getDatabaseList(WILDCARD);
+        }
+
+        for (String db : databases) {
+            uniqueResults.addAll(queryHawq(userInput, columnName, query, db));
+        }
+        return new ArrayList<>(uniqueResults);
+    }
+
+    private List<String> queryHawqPerDbAndSchema(String userInput, Map<String, List<String>> resources, String schemaColumnName, String resultColumnName, String query) throws SQLException {
+        Set<String> uniqueResults = new HashSet<>();
+        List<String> databases = resources.get("database");
+        List<String> schemas = resources.get("schema");
+
+        Connection conn = null;
+        PreparedStatement preparedStatement = null;
+        ResultSet resultSet = null;
+
+        if (databases.contains(WILDCARD)) {
+            databases = getDatabaseList(WILDCARD);
+        }
+
+        for (String db: databases) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("<== HawqClient.queryHawqPerDbAndSchema: Connecting to db: " + db);
+            }
+
+            try {
+                conn = getConnection(connectionProperties, db);
+                preparedStatement = handleWildcardPreparedStatement(userInput, query, conn);
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("<== HawqClient.queryHawqPerDbAndSchema Starting query: " + query);
+                }
+
+                resultSet = preparedStatement.executeQuery();
+
+                while(resultSet.next()) {
+                    if(schemas.contains(resultSet.getString(schemaColumnName)) || schemas.contains(WILDCARD)) {
+                        uniqueResults.add(resultSet.getString(resultColumnName));
+                    }
+                }
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("<== HawqClient.queryHawqPerDbAndSchema Query result: " + uniqueResults.toString());
+                }
+
+            } catch (SQLException e) {
+                LOG.error("<== HawqClient.queryHawqPerDbAndSchema Error: Failed to get results for query: " + query + ", Error: " + e);
+            } finally {
+                closeResultSet(resultSet);
+                closeStatement(preparedStatement);
+                closeConnection(conn);
+            }
+        }
+        return new ArrayList<>(uniqueResults);
+    }
+
+    private List<String> queryHawq(String userInput, String columnName, String query, String database) {
+        List<String> result = new ArrayList<>();
+        Connection conn = null;
+        PreparedStatement preparedStatement = null;
+        ResultSet resultSet = null;
+
+        try {
+            conn = getConnection(connectionProperties, database);
+            preparedStatement = handleWildcardPreparedStatement(userInput, query, conn);
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("<== HawqClient.queryHawq Starting query: " + query);
+            }
+
+            resultSet = preparedStatement.executeQuery();
+
+            while(resultSet.next()) {
+                result.add(resultSet.getString(columnName));
+            }
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("<== HawqClient.queryHawq Query result: " + result.toString());
+            }
+
+        } catch (SQLException e) {
+            LOG.error("<== HawqClient.queryHawq Error: Failed to get result from query: " + query + ", Error: " + e);
+        } finally {
+            closeResultSet(resultSet);
+            closeStatement(preparedStatement);
+            closeConnection(conn);
+        }
+
+        return result;
+    }
+
+    private Connection getConnection(Map<String, String> connectionProperties) throws SQLException {
+        return getConnection(connectionProperties, null);
+    }
+
+    private Connection getConnection(Map<String, String> connectionProperties, String database) throws SQLException {
+
+        String db = database != null ? database : DEFAULT_DATABASE;
+        String url = String.format("jdbc:postgresql://%s:%s/%s", connectionProperties.get("hostname"), connectionProperties.get("port"), db);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== HawqClient.checkConnection Connecting to: (" + url + ") with user: " + connectionProperties.get("username") );
+        }
+
+        Properties props = new Properties();
+        props.setProperty("user", connectionProperties.get("username"));
+        props.setProperty("password", connectionProperties.get("password"));
+        return DriverManager.getConnection(url, props);
+    }
+
+    private PreparedStatement handleWildcardPreparedStatement(String userInput, String query, Connection conn) throws SQLException {
+        PreparedStatement preparedStatement = conn.prepareStatement(query);
+        preparedStatement.setString(1, userInput.equals(WILDCARD) ? "%" : (userInput + "%"));
+        return preparedStatement;
+    }
+
+    private void closeResultSet(ResultSet rs) {
+        try {
+            if (rs != null) rs.close();
+        } catch (Exception e) {
+            // ignore
+        }
+    }
+
+    private void closeStatement(PreparedStatement st) {
+        try {
+            if (st != null) st.close();
+        } catch (Exception e) {
+            // ignore
+        }
+    }
+
+    private void closeConnection(Connection conn) {
+        try {
+            if (conn != null) conn.close();
+        } catch (Exception e) {
+            // ignore
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/admin-plugin/src/main/java/org/apache/hawq/ranger/service/HawqResourceMgr.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/admin-plugin/src/main/java/org/apache/hawq/ranger/service/HawqResourceMgr.java b/ranger-plugin/admin-plugin/src/main/java/org/apache/hawq/ranger/service/HawqResourceMgr.java
new file mode 100644
index 0000000..214ebdb
--- /dev/null
+++ b/ranger-plugin/admin-plugin/src/main/java/org/apache/hawq/ranger/service/HawqResourceMgr.java
@@ -0,0 +1,71 @@
+/*
+ * 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.hawq.ranger.service;
+
+import org.apache.hawq.ranger.model.HawqResource;
+import org.apache.ranger.plugin.service.ResourceLookupContext;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+import java.util.Collections;
+
+public abstract class HawqResourceMgr {
+
+    public static List<String> getHawqResources(Map<String, String> configs,
+                                                ResourceLookupContext context) throws SQLException {
+        String userInput = context.getUserInput();
+        HawqResource hawqResource = HawqResource.valueOf(context.getResourceName().toUpperCase());
+        Map<String, List<String>> resources = context.getResources();
+
+        List<String> result;
+        HawqClient hawqClient = new HawqClient(configs);
+
+        switch (hawqResource) {
+            case DATABASE:
+                result = hawqClient.getDatabaseList(userInput);
+                break;
+            case TABLESPACE:
+                result = hawqClient.getTablespaceList(userInput);
+                break;
+            case PROTOCOL:
+                result = hawqClient.getProtocolList(userInput);
+                break;
+            case SCHEMA:
+                result = hawqClient.getSchemaList(userInput, resources);
+                break;
+            case LANGUAGE:
+                result = hawqClient.getLanguageList(userInput, resources);
+                break;
+            case TABLE:
+                result = hawqClient.getTableList(userInput, resources);
+                break;
+            case SEQUENCE:
+                result = hawqClient.getSequenceList(userInput, resources);
+                break;
+            case FUNCTION:
+                result = hawqClient.getFunctionList(userInput, resources);
+                break;
+            default:
+                throw new IllegalArgumentException("Resource requested does not exist.");
+        }
+
+        Collections.sort(result);
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/admin-plugin/src/main/java/org/apache/hawq/ranger/service/RangerServiceHawq.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/admin-plugin/src/main/java/org/apache/hawq/ranger/service/RangerServiceHawq.java b/ranger-plugin/admin-plugin/src/main/java/org/apache/hawq/ranger/service/RangerServiceHawq.java
new file mode 100644
index 0000000..0f12191
--- /dev/null
+++ b/ranger-plugin/admin-plugin/src/main/java/org/apache/hawq/ranger/service/RangerServiceHawq.java
@@ -0,0 +1,66 @@
+/*
+ * 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.hawq.ranger.service;
+
+import org.apache.ranger.plugin.client.HadoopException;
+import org.apache.ranger.plugin.service.RangerBaseService;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.service.ResourceLookupContext;
+
+import java.util.*;
+
+public class RangerServiceHawq extends RangerBaseService {
+
+    private static final Log LOG = LogFactory.getLog(RangerServiceHawq.class);
+
+    @Override
+    public HashMap<String, Object> validateConfig() throws Exception {
+        boolean isDebugEnabled = LOG.isDebugEnabled();
+
+        if(isDebugEnabled) {
+            LOG.debug("==> RangerServiceHawq.validateConfig Service: (hawq)");
+        }
+
+        HashMap<String, Object> result = new HashMap<>();
+
+        if (configs != null) {
+            try  {
+                HawqClient hawqClient = new HawqClient(configs);
+                result = hawqClient.checkConnection(configs);
+            } catch (HadoopException e) {
+                LOG.error("<== RangerServiceHawq.validateConfig Error:" + e);
+                throw e;
+            }
+        }
+
+        if (isDebugEnabled) {
+            LOG.debug("<== RangerServiceHawq.validateConfig Response : (" + result + ")");
+        }
+        return result;
+    }
+
+    @Override
+    public List<String> lookupResource(ResourceLookupContext context) throws Exception {
+        List<String> resources = HawqResourceMgr.getHawqResources(getConfigs(), context);
+
+        return resources;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/admin-plugin/src/test/java/org/apache/hawq/ranger/service/HawqClientTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/admin-plugin/src/test/java/org/apache/hawq/ranger/service/HawqClientTest.java b/ranger-plugin/admin-plugin/src/test/java/org/apache/hawq/ranger/service/HawqClientTest.java
new file mode 100644
index 0000000..7d624d8
--- /dev/null
+++ b/ranger-plugin/admin-plugin/src/test/java/org/apache/hawq/ranger/service/HawqClientTest.java
@@ -0,0 +1,217 @@
+/*
+ * 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.hawq.ranger.service;
+
+import org.apache.ranger.plugin.client.BaseClient;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.List;
+import java.util.Arrays;
+import java.util.Collections;
+
+import static org.apache.hawq.ranger.service.HawqClient.*;
+import static org.junit.Assert.*;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyMap;
+import static org.mockito.Matchers.anyString;
+import static org.powermock.api.mockito.PowerMockito.*;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(HawqClient.class)
+public class HawqClientTest {
+
+    @Mock
+    public Connection conn;
+    @Mock
+    public PreparedStatement preparedStatement;
+    @Mock
+    public ResultSet resultSet;
+
+    public HawqClient hawqClientSpy;
+
+    public HawqClient hawqClient;
+    private Map<String, String> connectionProperties;
+    private Map<String, List<String>> resources;
+
+    @Before
+    public void setUp() throws SQLException {
+        connectionProperties = new HashMap<>();
+        connectionProperties.put("hostname", "hostname");
+        connectionProperties.put("port", "5432");
+        connectionProperties.put("hostname", "hostname");
+        connectionProperties.put("username", "username");
+        connectionProperties.put("password", "password");
+
+        mockStatic(DriverManager.class);
+        suppress(constructor(BaseClient.class, String.class, Map.class));
+        hawqClient = new HawqClient(connectionProperties);
+
+        hawqClientSpy = PowerMockito.spy(hawqClient);
+
+        resources = new HashMap<>();
+        List<String> dbs = Arrays.asList("db1", "db2");
+        List<String> schemas = Arrays.asList("schema1", "schema2");
+        resources.put("database", dbs);
+        resources.put("schema", schemas);
+    }
+
+    @Test
+    public void testCheckConnection_Failure() throws Exception {
+        when(DriverManager.getConnection(anyString(), any(Properties.class))).thenReturn(conn);
+        when(conn.getCatalog()).thenReturn(null);
+        Map<String, Object> response = hawqClient.checkConnection(connectionProperties);
+        assertEquals(CONNECTION_FAILURE_MESSAGE, response.get("message"));
+        assertFalse((Boolean) response.get("connectivityStatus"));
+    }
+
+    @Test
+    public void testCheckConnection_Success() throws Exception {
+        when(DriverManager.getConnection(anyString(), any(Properties.class))).thenReturn(conn);
+        when(conn.getCatalog()).thenReturn("catalog");
+        Map<String, Object> response = hawqClient.checkConnection(connectionProperties);
+        assertEquals(CONNECTION_SUCCESSFUL_MESSAGE, response.get("message"));
+        assertTrue((Boolean) response.get("connectivityStatus"));
+    }
+
+    @Test
+    public void testCheckConnection_ThrowsSQLException_Failure() throws Exception {
+        when(DriverManager.getConnection(anyString(), any(Properties.class))).thenThrow(new SQLException("Failed to connect"));
+        Map<String, Object> response = hawqClient.checkConnection(connectionProperties);
+        assertEquals(CONNECTION_FAILURE_MESSAGE, response.get("message"));
+        assertEquals("Failed to connect", response.get("description"));
+        assertFalse((Boolean) response.get("connectivityStatus"));
+    }
+
+    @Test
+    public void testDatabaseList_Success() throws Exception {
+        when(conn.prepareStatement(DATABASE_LIST_QUERY)).thenReturn(preparedStatement);
+        when(preparedStatement.executeQuery()).thenReturn(resultSet);
+        when(resultSet.next()).thenReturn(true).thenReturn(true).thenReturn(false);
+        when(resultSet.getString(DATNAME)).thenReturn("db1").thenReturn("db2");
+        PowerMockito.doReturn(conn).when(hawqClientSpy, "getConnection", anyMap(), anyString());
+        assertEquals(Arrays.asList("db1", "db2"), hawqClientSpy.getDatabaseList("d"));
+    }
+
+    @Test
+    public void testTablespaceList_Success() throws Exception {
+        doReturn(Arrays.asList("tablespace1", "tablespace2")).when(hawqClientSpy, "queryHawq", "t", SPCNAME, TABLESPACE_LIST_QUERY, null);
+        assertEquals(Arrays.asList("tablespace1", "tablespace2"), hawqClientSpy.getTablespaceList("t"));
+    }
+
+    @Test
+    public void testProtocolList_Success() throws Exception {
+        List<String> expectedResult = Arrays.asList("protocol1", "protocol2", "pxf");
+        doReturn(Arrays.asList("protocol1", "protocol2")).when(hawqClientSpy, "queryHawq", "p", PTCNAME, PROTOCOL_LIST_QUERY, null);
+        List<String> result = hawqClientSpy.getProtocolList("p");
+        Collections.sort(result);
+        assertEquals(expectedResult, result);
+    }
+
+    @Test
+    public void testSchemaList_MultipleDb_Success() throws Exception {
+        doReturn(Arrays.asList("schema1")).when(hawqClientSpy, "queryHawq", "s", SCHEMA_NAME, SCHEMA_LIST_QUERY, "db1");
+        doReturn(Arrays.asList("schema2")).when(hawqClientSpy, "queryHawq", "s", SCHEMA_NAME, SCHEMA_LIST_QUERY, "db2");
+        List<String> result = hawqClientSpy.getSchemaList("s", resources);
+        Collections.sort(result);
+        assertEquals(Arrays.asList("schema1", "schema2"), result);
+    }
+
+    @Test
+    public void testSchemaList_AllDb_Success() throws Exception {
+        resources.put("database", Arrays.asList(WILDCARD));
+        doReturn(Arrays.asList("db1", "db2", "db3")).when(hawqClientSpy, "getDatabaseList", WILDCARD);
+        doReturn(Arrays.asList("schema1")).when(hawqClientSpy, "queryHawq", "s", SCHEMA_NAME, SCHEMA_LIST_QUERY, "db1");
+        doReturn(Arrays.asList("schema2")).when(hawqClientSpy, "queryHawq", "s", SCHEMA_NAME, SCHEMA_LIST_QUERY, "db2");
+        doReturn(Arrays.asList("schema3")).when(hawqClientSpy, "queryHawq", "s", SCHEMA_NAME, SCHEMA_LIST_QUERY, "db3");
+        List<String> result = hawqClientSpy.getSchemaList("s", resources);
+        Collections.sort(result);
+        assertEquals(Arrays.asList("schema1", "schema2", "schema3"), result);
+    }
+
+    @Test
+    public void testLanguageList_Success() throws Exception {
+        doReturn(Arrays.asList("language1")).when(hawqClientSpy, "queryHawq", "l", LANGUAGE_NAME, LANGUAGE_LIST_QUERY, "db1");
+        doReturn(Arrays.asList("language2")).when(hawqClientSpy, "queryHawq", "l", LANGUAGE_NAME, LANGUAGE_LIST_QUERY, "db2");
+        List<String> result = hawqClientSpy.getLanguageList("l", resources);
+        Collections.sort(result);
+        assertEquals(Arrays.asList("language1", "language2"), result);
+    }
+
+    @Test
+    public void testTableList_Success() throws Exception {
+        PowerMockito.doReturn(conn).when(hawqClientSpy, "getConnection", anyMap(), anyString());
+        when(conn.prepareStatement(TABLE_LIST_QUERY)).thenReturn(preparedStatement);
+        when(preparedStatement.executeQuery()).thenReturn(resultSet);
+        when(resultSet.next()).thenReturn(true).thenReturn(true).thenReturn(false);
+        when(resultSet.getString(RELNAME)).thenReturn("table1").thenReturn("table2");
+        when(resultSet.getString(NSPNAME)).thenReturn("schema1").thenReturn("schema2");
+        List<String> result = hawqClientSpy.getTableList("t", resources);
+        Collections.sort(result);
+        assertEquals(Arrays.asList("table1", "table2"), result);
+    }
+
+    @Test
+    public void testSequenceList_Success() throws Exception {
+        PowerMockito.doReturn(conn).when(hawqClientSpy, "getConnection", anyMap(), anyString());
+        when(conn.prepareStatement(SEQUENCE_LIST_QUERY)).thenReturn(preparedStatement);
+        when(preparedStatement.executeQuery()).thenReturn(resultSet);
+        when(resultSet.next()).thenReturn(true).thenReturn(true).thenReturn(false);
+        when(resultSet.getString(RELNAME)).thenReturn("seq1").thenReturn("seq2");
+        when(resultSet.getString(SCHEMANAME)).thenReturn("schema1").thenReturn("schema2");
+        List<String> result = hawqClientSpy.getSequenceList("s", resources);
+        Collections.sort(result);
+        assertEquals(Arrays.asList("seq1", "seq2"), result);
+    }
+
+    @Test
+    public void testSequenceList_SchemaFiltered_Success() throws Exception {
+        PowerMockito.doReturn(conn).when(hawqClientSpy, "getConnection", anyMap(), anyString());
+        when(conn.prepareStatement(SEQUENCE_LIST_QUERY)).thenReturn(preparedStatement);
+        when(preparedStatement.executeQuery()).thenReturn(resultSet);
+        when(resultSet.next()).thenReturn(true).thenReturn(true).thenReturn(false);
+        when(resultSet.getString(RELNAME)).thenReturn("seq1").thenReturn("seq2");
+        when(resultSet.getString(SCHEMANAME)).thenReturn("schema1").thenReturn("schema3");
+        assertEquals(Arrays.asList("seq1"), hawqClientSpy.getSequenceList("s", resources));
+    }
+
+    @Test
+    public void testFunctionList_Success() throws Exception {
+        PowerMockito.doReturn(conn).when(hawqClientSpy, "getConnection", anyMap(), anyString());
+        when(conn.prepareStatement(FUNCTION_LIST_QUERY)).thenReturn(preparedStatement);
+        when(preparedStatement.executeQuery()).thenReturn(resultSet);
+        when(resultSet.next()).thenReturn(true).thenReturn(true).thenReturn(false);
+        when(resultSet.getString(PRONAME)).thenReturn("fxn1").thenReturn("fxn2");
+        when(resultSet.getString(NSPNAME)).thenReturn("schema1").thenReturn("schema2");
+        assertEquals(Arrays.asList("fxn1", "fxn2"), hawqClientSpy.getFunctionList("f", resources));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/admin-plugin/src/test/java/org/apache/hawq/ranger/service/RangerServiceHawqTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/admin-plugin/src/test/java/org/apache/hawq/ranger/service/RangerServiceHawqTest.java b/ranger-plugin/admin-plugin/src/test/java/org/apache/hawq/ranger/service/RangerServiceHawqTest.java
new file mode 100644
index 0000000..5264929
--- /dev/null
+++ b/ranger-plugin/admin-plugin/src/test/java/org/apache/hawq/ranger/service/RangerServiceHawqTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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.hawq.ranger.service;
+
+import org.apache.ranger.plugin.client.BaseClient;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import static org.apache.hawq.ranger.service.HawqClient.CONNECTION_SUCCESSFUL_MESSAGE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.powermock.api.mockito.PowerMockito.mockStatic;
+import static org.powermock.api.mockito.PowerMockito.when;
+import static org.powermock.api.support.membermodification.MemberMatcher.constructor;
+import static org.powermock.api.support.membermodification.MemberModifier.suppress;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(HawqClient.class)
+public class RangerServiceHawqTest {
+
+    private RangerServiceHawq service;
+    private Map<String, String> configs;
+
+    @Mock
+    HawqClient mockHawqClient;
+    @Mock
+    Connection conn;
+
+    @Before
+    public void setup() {
+        service = new RangerServiceHawq();
+        service.setServiceName("hawq");
+        service.setServiceType("hawq");
+
+        configs = new HashMap<>();
+        configs.put("username", "username");
+        configs.put("password", "password");
+        configs.put("hostname", "localhost");
+        configs.put("port", "5432");
+
+        service.setConfigs(configs);
+
+        mockStatic(DriverManager.class);
+    }
+
+    @Test
+    public void testValidateConfigSuccess() throws Exception {
+        HashMap<String, Object> result = new HashMap<>();
+        result.put("message", "ConnectionTest Successful");
+        result.put("description", "ConnectionTest Successful");
+        result.put("connectivityStatus", true);
+
+        suppress(constructor(BaseClient.class, String.class, Map.class));
+        PowerMockito.when(DriverManager.getConnection(anyString(), any(Properties.class))).thenReturn(conn);
+        when(conn.getCatalog()).thenReturn("catalog");
+
+        HashMap<String, Object> response = service.validateConfig();
+        assertEquals(CONNECTION_SUCCESSFUL_MESSAGE, response.get("description"));
+        assertEquals(CONNECTION_SUCCESSFUL_MESSAGE, response.get("message"));
+        assertTrue((Boolean) response.get("connectivityStatus"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/admin-plugin/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/ranger-plugin/admin-plugin/src/test/resources/log4j.properties b/ranger-plugin/admin-plugin/src/test/resources/log4j.properties
new file mode 100644
index 0000000..903f0b6
--- /dev/null
+++ b/ranger-plugin/admin-plugin/src/test/resources/log4j.properties
@@ -0,0 +1,34 @@
+# 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.
+
+##-- To prevent junits from cluttering the build run by default all test runs send output to null appender
+log4j.appender.devnull=org.apache.log4j.varia.NullAppender
+#hawq.ranger.root.logger=FATAL,devnull
+
+##-- uncomment the following line during during development/debugging so see debug messages during test run to be emitted to console
+hawq.ranger.root.logger=DEBUG,console
+log4j.rootLogger=${hawq.ranger.root.logger}
+
+# Logging Threshold
+log4j.threshold=ALL
+
+#
+# console
+# Add "console" to rootlogger above if you want to use this
+#
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.target=System.err
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2}: %m%n

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/conf/ranger-servicedef-hawq.json
----------------------------------------------------------------------
diff --git a/ranger-plugin/conf/ranger-servicedef-hawq.json b/ranger-plugin/conf/ranger-servicedef-hawq.json
new file mode 100644
index 0000000..03005bc
--- /dev/null
+++ b/ranger-plugin/conf/ranger-servicedef-hawq.json
@@ -0,0 +1,287 @@
+{
+  "name": "hawq",
+  "implClass": "org.apache.hawq.ranger.service.RangerServiceHawq",
+  "label": "HAWQ",
+  "description": "HAWQ",
+  "guid": "1ebb27ee-549a-401d-85ab-818342ca54af",
+  "resources":
+  [
+    {
+      "itemId": 1,
+      "name": "database",
+      "type": "string",
+      "level": 10,
+      "parent": "",
+      "mandatory": true,
+      "lookupSupported": true,
+      "recursiveSupported": false,
+      "excludesSupported": true,
+      "Matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+      "matcherOptions": {"wildCard":true, "ignoreCase":true},
+      "validationRegEx": "",
+      "validationMessage": "",
+      "uiHint": "",
+      "label": "Database",
+      "description": "HAWQ Database"
+    },
+    {
+      "itemId": 2,
+      "name": "schema",
+      "type": "string",
+      "level": 20,
+      "parent": "database",
+      "mandatory": true,
+      "lookupSupported": true,
+      "recursiveSupported": false,
+      "excludesSupported": true,
+      "Matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+      "matcherOptions": {"wildCard":true, "ignoreCase":true},
+      "validationRegEx": "",
+      "validationMessage": "",
+      "uiHint": "",
+      "label": "Schema",
+      "description": "HAWQ Schema"
+    },
+    {
+      "itemId": 3,
+      "name": "table",
+      "type": "string",
+      "level": 30,
+      "parent": "schema",
+      "mandatory": true,
+      "lookupSupported": true,
+      "recursiveSupported": false,
+      "excludesSupported": true,
+      "Matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+      "matcherOptions": {"wildCard":true, "ignoreCase":true},
+      "validationRegEx": "",
+      "validationMessage": "",
+      "uiHint": "",
+      "label": "Table",
+      "description": "HAWQ Table"
+    },
+    {
+      "itemId": 4,
+      "name": "sequence",
+      "type": "string",
+      "level": 30,
+      "parent": "schema",
+      "mandatory": true,
+      "lookupSupported": true,
+      "recursiveSupported": false,
+      "excludesSupported": true,
+      "Matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+      "matcherOptions": {"wildCard":true, "ignoreCase":true},
+      "validationRegEx": "",
+      "validationMessage": "",
+      "uiHint": "",
+      "label": "Sequence",
+      "description": "HAWQ Sequence"
+    },
+    {
+      "itemId": 5,
+      "name": "function",
+      "type": "string",
+      "level": 30,
+      "parent": "schema",
+      "mandatory": true,
+      "lookupSupported": true,
+      "recursiveSupported": false,
+      "excludesSupported": true,
+      "Matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+      "matcherOptions": {"wildCard":true, "ignoreCase":true},
+      "validationRegEx": "",
+      "validationMessage": "",
+      "uiHint": "",
+      "label": "Function",
+      "description": "HAWQ Function"
+    },
+    {
+      "itemId": 6,
+      "name": "language",
+      "type": "string",
+      "level": 20,
+      "parent": "database",
+      "mandatory": true,
+      "lookupSupported": true,
+      "recursiveSupported": false,
+      "excludesSupported": true,
+      "Matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+      "matcherOptions": {"wildCard":true, "ignoreCase":true},
+      "validationRegEx": "",
+      "validationMessage": "",
+      "uiHint": "",
+      "label": "Language",
+      "description": "HAWQ Language"
+    },
+    {
+      "itemId": 7,
+      "name": "tablespace",
+      "type": "string",
+      "level": 10,
+      "parent": "",
+      "mandatory": true,
+      "lookupSupported": true,
+      "recursiveSupported": false,
+      "excludesSupported": true,
+      "Matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+      "matcherOptions": {"wildCard":true, "ignoreCase":true},
+      "validationRegEx": "",
+      "validationMessage": "",
+      "uiHint": "",
+      "label": "Tablespace",
+      "description": "HAWQ Tablespace"
+    },
+    {
+      "itemId": 8,
+      "name": "protocol",
+      "type": "string",
+      "level": 10,
+      "parent": "",
+      "mandatory": true,
+      "lookupSupported": true,
+      "recursiveSupported": false,
+      "excludesSupported": true,
+      "Matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+      "matcherOptions": {"wildCard":true, "ignoreCase":true},
+      "validationRegEx": "",
+      "validationMessage": "",
+      "uiHint": "",
+      "label": "Protocol",
+      "description": "HAWQ Protocol"
+    }
+  ],
+  "accessTypes":
+  [
+    {
+      "itemId": 1,
+      "name": "select",
+      "label": "select"
+    },
+    {
+      "itemId": 2,
+      "name": "insert",
+      "label": "insert"
+    },
+    {
+      "itemId": 3,
+      "name": "update",
+      "label": "update"
+    },
+    {
+      "itemId": 4,
+      "name": "delete",
+      "label": "delete"
+    },
+    {
+      "itemId": 5,
+      "name": "references",
+      "label": "references"
+    },
+    {
+      "itemId": 6,
+      "name": "usage",
+      "label": "usage"
+    },
+    {
+      "itemId": 7,
+      "name": "create",
+      "label": "create"
+    },
+    {
+      "itemId": 8,
+      "name": "connect",
+      "label": "connect"
+    },
+    {
+      "itemId": 9,
+      "name": "execute",
+      "label": "execute"
+    },
+    {
+      "itemId": 10,
+      "name": "temp",
+      "label": "temp"
+    },
+    {
+      "itemId": 11,
+      "name": "create-schema",
+      "label": "create-schema"
+    },
+    {
+      "itemId": 12,
+      "name": "usage-schema",
+      "label": "usage-schema"
+    },
+    {
+      "itemId": 13,
+      "name": "all",
+      "label": "All",
+      "impliedGrants": [
+        "select",
+        "insert",
+        "update",
+        "delete",
+        "references",
+        "usage",
+        "create",
+        "connect",
+        "execute",
+        "temp",
+        "create-schema",
+        "usage-schema"
+      ]
+    }
+  ],
+
+  "configs":
+  [
+    {
+      "itemId": 1,
+      "name": "username",
+      "type": "string",
+      "mandatory": true,
+      "validationRegEx": "",
+      "validationMessage": "",
+      "uiHint": "",
+      "label": "HAWQ User Name",
+      "defaultValue": "gpadmin"
+    },
+    {
+      "itemId": 2,
+      "name": "password",
+      "type": "password",
+      "mandatory": true,
+      "validationRegEx": "",
+      "validationMessage": "",
+      "uiHint": "",
+      "label": "HAWQ User Password"
+    },
+    {
+      "itemId": 3,
+      "name": "hostname",
+      "type": "string",
+      "mandatory": true,
+      "validationRegEx": "",
+      "validationMessage": "",
+      "uiHint": "",
+      "label": "HAWQ Master Hostname"
+    },
+    {
+      "itemId": 4,
+      "name": "port",
+      "type": "int",
+      "mandatory": true,
+      "validationRegEx": "",
+      "validationMessage": "",
+      "uiHint": "",
+      "label": "HAWQ Master Port",
+      "defaultValue": 5432
+    }
+  ],
+  "enums": [],
+  "contextEnrichers": [],
+  "policyConditions": [],
+  "dataMaskDef": {},
+  "rowFilterDef": {}
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/conf/tomcat-server.xml
----------------------------------------------------------------------
diff --git a/ranger-plugin/conf/tomcat-server.xml b/ranger-plugin/conf/tomcat-server.xml
new file mode 100644
index 0000000..09f9088
--- /dev/null
+++ b/ranger-plugin/conf/tomcat-server.xml
@@ -0,0 +1,60 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!--
+  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.
+-->
+<!-- Note:  A "Server" is not itself a "Container", so you may not
+     define subcomponents such as "Valves" at this level.
+     Documentation at /docs/config/server.html
+ -->
+<Server port="8005" shutdown="SHUTDOWN">
+
+  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
+  <Listener className="org.apache.catalina.core.JasperListener" />
+  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
+  <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
+  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
+
+  <GlobalNamingResources>
+    <Resource name="UserDatabase" auth="Container"
+              type="org.apache.catalina.UserDatabase"
+              description="User database that can be updated and saved"
+              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
+              pathname="conf/tomcat-users.xml" />
+  </GlobalNamingResources>
+
+  <Service name="Catalina">
+
+    <Connector port="${http.port}" protocol="HTTP/1.1"
+               connectionTimeout="20000"
+               redirectPort="8443" />
+
+    <Engine name="Catalina" defaultHost="localhost">
+
+      <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+             resourceName="UserDatabase"/>
+
+      <Host name="${http.host}"  appBase="webapps"
+            unpackWARs="true" autoDeploy="true"
+            xmlValidation="false" xmlNamespaceAware="false">
+
+        <Context path="/rps"
+                 docBase="/usr/local/hawq/ranger/plugin-service/webapps/rps"
+                 reloadable="false" debug="0" cookies="false"></Context>
+
+      </Host>
+    </Engine>
+  </Service>
+</Server>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/admin/pom.xml
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/admin/pom.xml b/ranger-plugin/integration/admin/pom.xml
new file mode 100644
index 0000000..0a81941
--- /dev/null
+++ b/ranger-plugin/integration/admin/pom.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.hawq</groupId>
+    <artifactId>ranger-plugin-integration-admin</artifactId>
+    <packaging>jar</packaging>
+    <name>HAWQ Ranger Plugin - Integration Tests for Admin Plugin</name>
+    <description>HAWQ Ranger Plugin - Integration Tests for Admin Plugin</description>
+
+    <parent>
+        <groupId>org.apache.hawq</groupId>
+        <artifactId>ranger-plugin-integration</artifactId>
+        <version>2.1.0.0</version>
+        <relativePath>..</relativePath>
+    </parent>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.hawq</groupId>
+            <artifactId>ranger-plugin-admin</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.ranger</groupId>
+            <artifactId>ranger-plugins-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+        </dependency>
+
+        <!-- Test Dependencies -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListDatabasesTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListDatabasesTest.java b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListDatabasesTest.java
new file mode 100644
index 0000000..67eecdd
--- /dev/null
+++ b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListDatabasesTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.hawq.ranger.integration.admin;
+
+import com.google.common.collect.Sets;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ListDatabasesTest extends LookupTestBase {
+
+    private static final Set<String> DATABASES = Sets.newHashSet("postgres", "east", "west", "noschema_db");
+
+    @Test
+    public void testListDatabases_All() throws Exception {
+        List<String> result = service.lookupResource(getContext("database", "*"));
+        assertEquals(4, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet(DATABASES)));
+    }
+
+    @Test
+    public void testListDatabases_FilteredPresent() throws Exception {
+        List<String> result = service.lookupResource(getContext("database", "e"));
+        assertEquals(1, result.size());
+        assertEquals(result.get(0), "east");
+    }
+
+    @Test
+    public void testListDatabases_FilteredAbsent() throws Exception {
+        List<String> result = service.lookupResource(getContext("database", "z"));
+        assertTrue(result.isEmpty());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListFunctionsTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListFunctionsTest.java b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListFunctionsTest.java
new file mode 100644
index 0000000..7b68d78
--- /dev/null
+++ b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListFunctionsTest.java
@@ -0,0 +1,250 @@
+/*
+ * 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 schema governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.hawq.ranger.integration.admin;
+
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Arrays;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ListFunctionsTest extends LookupTestBase {
+
+    private Map<String, List<String>> resources;
+
+    @Before
+    public void setUp() {
+        resources = new HashMap<>();
+    }
+
+    @Test
+    public void testListFunctions_NoSchemaDb_AllSchemas_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("noschema_db"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("function", "*", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListFunctions_SingleDb_SingleSchema_AllFilter_NoFunctions() throws Exception {
+        resources.put("database", Arrays.asList("west"));
+        resources.put("schema", Arrays.asList("jamaica"));
+        List<String> result = service.lookupResource(getContext("function", "*", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListFunctions_SingleDb_SingleSchema_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("japan"));
+        List<String> result = service.lookupResource(getContext("function", "*", resources));
+        assertEquals(2, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("eat", "stand")));
+    }
+
+    @Test
+    public void testListFunctions_SingleDb_TwoSchemas_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("common", "japan"));
+        List<String> result = service.lookupResource(getContext("function", "*", resources));
+        assertEquals(3, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("eat", "sleep", "stand")));
+    }
+
+    @Test
+    public void testListFunctions_SingleDb_AllSchemas_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("function", "*", resources));
+        assertEquals(3, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("eat", "sleep", "stand")));
+    }
+
+    @Test
+    public void testListFunctions_TwoDb_CommonSchema_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("common"));
+        List<String> result = service.lookupResource(getContext("function", "*", resources));
+        assertEquals(2, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("eat", "sleep")));
+    }
+
+    @Test
+    public void testListFunctions_TwoDb_SingleSchema_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("japan"));
+        List<String> result = service.lookupResource(getContext("function", "*", resources));
+        assertEquals(2, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("eat", "stand")));
+    }
+
+    @Test
+    public void testListFunctions_TwoDb_AllSchemas_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("function", "*", resources));
+        assertEquals(4, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("eat", "sleep", "stand", "smile")));
+    }
+
+    @Test
+    public void testListFunctions_AllDb_AllSchemas_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("*"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("function", "*", resources));
+        assertEquals(4, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("eat", "sleep", "stand", "smile")));
+    }
+
+    @Test
+    public void testListFunctions_SingleDb_SingleSchema_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("japan"));
+        List<String> result = service.lookupResource(getContext("function", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListFunctions_SingleDb_TwoSchemas_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("common", "japan"));
+        List<String> result = service.lookupResource(getContext("function", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListFunctions_SingleDb_AllSchemas_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("function", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListFunctions_TwoDbs_CommonSchema_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("common"));
+        List<String> result = service.lookupResource(getContext("function", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListFunctions_TwoDbs_SingleSchema_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("japan"));
+        List<String> result = service.lookupResource(getContext("function", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListFunctions_TwoDbs_AllSchemas_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("function", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListFunctions_AllDbs_AllSchemas_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("*"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("function", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListFunctions_SingleDb_SingleSchema_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("japan"));
+        List<String> result = service.lookupResource(getContext("function", "s", resources));
+        assertEquals(1, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("stand")));
+    }
+
+    @Test
+    public void testListFunctions_SingleDb_TwoSchemas_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("common", "japan"));
+        List<String> result = service.lookupResource(getContext("function", "s", resources));
+        assertEquals(2, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("sleep", "stand")));
+    }
+
+    @Test
+    public void testListFunctions_SingleDb_AllSchemas_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("function", "s", resources));
+        assertEquals(2, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("sleep", "stand")));
+    }
+
+    @Test
+    public void testListFunctions_SingleDb_AllSchemas_FilteredPresent2() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("function", "e", resources));
+        assertEquals(1, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("eat")));
+    }
+
+    @Test
+    public void testListFunctions_TwoDbs_CommonSchema_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("common"));
+        List<String> result = service.lookupResource(getContext("function", "e", resources));
+        assertEquals(1, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("eat")));
+    }
+
+    @Test
+    public void testListFunctions_TwoDbs_SingleSchema_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("japan"));
+        List<String> result = service.lookupResource(getContext("function", "s", resources));
+        assertEquals(1, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("stand")));
+    }
+
+    @Test
+    public void testListFunctions_TwoDbs_AllSchemas_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("function", "s", resources));
+        assertEquals(3, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("sleep", "stand", "smile")));
+    }
+
+    @Test
+    public void testListFunctions_AllDbs_AllSchemas_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("*"));
+        resources.put("schema", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("function", "s", resources));
+        assertEquals(3, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("sleep", "stand", "smile")));
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListLanguagesTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListLanguagesTest.java b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListLanguagesTest.java
new file mode 100644
index 0000000..726ef7e
--- /dev/null
+++ b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListLanguagesTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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.hawq.ranger.integration.admin;
+
+import com.google.common.collect.Sets;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Set;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Arrays;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ListLanguagesTest extends LookupTestBase {
+
+    private static final Set<String> DEFAULT_LANGUAGES = Sets.newHashSet("c", "internal", "plpgsql", "sql");
+    private static final Set<String> EAST_LANGUAGES = Sets.newHashSet("langdbeast", "c", "internal", "plpgsql", "sql");
+
+    private Map<String, List<String>> resources = new HashMap<>();
+
+    @Test
+    public void testListLanguage_NoResources() throws Exception {
+        resources.put("database", Arrays.asList("noschema_db"));
+        List<String> result = service.lookupResource(getContext("language", "*", resources));
+        assertEquals(4, result.size());
+        assertTrue(Sets.newHashSet(result).equals(DEFAULT_LANGUAGES));
+    }
+
+    @Test
+    public void testListLanguages_SingleDb_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        List<String> result = service.lookupResource(getContext("language", "*", resources));
+        assertEquals(5, result.size());
+        assertTrue(Sets.newHashSet(result).equals(EAST_LANGUAGES));
+    }
+
+    @Test
+    public void testListLanguages_TwoDb_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        List<String> result = service.lookupResource(getContext("language", "*", resources));
+        assertEquals(6, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("langdbeast", "langdbwest", "c", "internal", "plpgsql", "sql")));
+    }
+
+    @Test
+    public void testListLanguages_AllDb_AllFilter() throws Exception {
+        resources.put("database", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("language", "*", resources));
+        assertEquals(6, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("langdbeast", "langdbwest", "c", "internal", "plpgsql", "sql")));
+    }
+
+    @Test
+    public void testListLanguages_SingleDb_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        List<String> result = service.lookupResource(getContext("language", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListLanguages_TwoDb_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        List<String> result = service.lookupResource(getContext("language", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListLanguages_AllDb_FilteredAbsent() throws Exception {
+        resources.put("database", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("language", "z", resources));
+        assertTrue(result.isEmpty());
+    }
+
+    @Test
+    public void testListLanguages_SingleDb_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east"));
+        List<String> result = service.lookupResource(getContext("language", "l", resources));
+        assertEquals(1, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("langdbeast")));
+    }
+
+    @Test
+    public void testListLanguages_TwoDb_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("east", "west"));
+        List<String> result = service.lookupResource(getContext("language", "l", resources));
+        assertEquals(2, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("langdbeast", "langdbwest")));
+    }
+
+    @Test
+    public void testListLanguages_AllDb_FilteredPresent() throws Exception {
+        resources.put("database", Arrays.asList("*"));
+        List<String> result = service.lookupResource(getContext("language", "l", resources));
+        assertEquals(2, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("langdbeast", "langdbwest")));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListProtocolsTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListProtocolsTest.java b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListProtocolsTest.java
new file mode 100644
index 0000000..d46febc
--- /dev/null
+++ b/ranger-plugin/integration/admin/src/test/java/org/apache/hawq/ranger/integration/admin/ListProtocolsTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.hawq.ranger.integration.admin;
+
+import com.google.common.collect.Sets;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ListProtocolsTest extends LookupTestBase {
+
+    private static final Set<String> PROTOCOLS = Sets.newHashSet("file", "ftp", "gpfdist", "gpfdists", "http", "pxf");
+
+    @Test
+    public void testListProtocols_All() throws Exception {
+        List<String> result = service.lookupResource(getContext("protocol", "*"));
+        assertEquals(6, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet(PROTOCOLS)));
+    }
+
+    @Test
+    public void testListProtocols_FilteredPresent() throws Exception {
+        List<String> result = service.lookupResource(getContext("protocol", "h"));
+        assertEquals(1, result.size());
+        assertTrue(Sets.newHashSet(result).equals(Sets.newHashSet("http")));
+    }
+
+    @Test
+    public void testListProtocols_FilteredAbsent() throws Exception {
+        List<String> result = service.lookupResource(getContext("protocol", "z"));
+        assertTrue(result.isEmpty());
+    }
+
+}



[2/4] incubator-hawq git commit: HAWQ-1203. Ranger Plugin Service Implementation. (with contributions by Lav Jain and Leslie Chang) (close #1092)

Posted by ad...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/ranger-plugin/pom.xml b/ranger-plugin/pom.xml
new file mode 100644
index 0000000..20d3112
--- /dev/null
+++ b/ranger-plugin/pom.xml
@@ -0,0 +1,248 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.hawq</groupId>
+    <artifactId>ranger-plugin</artifactId>
+    <version>2.1.0.0</version>
+    <packaging>pom</packaging>
+    <name>HAWQ Ranger Plugin</name>
+    <description>HAWQ Ranger Plugin</description>
+
+    <modules>
+        <module>admin-plugin</module>
+        <module>service</module>
+    </modules>
+
+    <properties>
+        <jackson.version>1.9</jackson.version>
+        <release.version>1</release.version>
+        <postgresql.version>9.1-901-1.jdbc4</postgresql.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <build>
+        <testResources>
+            <testResource>
+                <directory>src/test/resources</directory>
+                <includes>
+                    <include>**/*</include>
+                </includes>
+                <filtering>true</filtering>
+            </testResource>
+        </testResources>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>rpm-maven-plugin</artifactId>
+                <version>2.0.1</version>
+                <inherited>false</inherited>
+                <executions>
+                    <execution>
+                        <inherited>false</inherited>
+                        <phase>install</phase>
+                        <goals>
+                            <goal>rpm</goal>
+                        </goals>
+                    </execution>
+                </executions>
+
+                <configuration>
+                    <copyright>ASL 2.0</copyright>
+                    <group>org.apache.hawq.ranger</group>
+                    <defaultUsername>gpadmin</defaultUsername>
+                    <defaultGroupname>gpadmin</defaultGroupname>
+                    <description>
+                        HAWQ Ranger plugin.
+                    </description>
+                    <release>${release.version}</release>
+                    <requires>
+                        <require>bigtop-tomcat</require>
+                        <require>hawq_${hawq.name.version} &gt;= ${project.version}</require>
+                    </requires>
+                    <mappings>
+                        <mapping>
+                            <directory>/usr/local/hawq_${hawq.name.version}/ranger/bin</directory>
+                            <filemode>755</filemode>
+                            <sources>
+                                <source>
+                                    <location>scripts</location>
+                                </source>
+                            </sources>
+                        </mapping>
+                        <mapping>
+                            <directory>/usr/local/hawq_${hawq.name.version}/ranger/lib</directory>
+                            <sources>
+                                <source>
+                                    <location>admin-plugin/target/ranger-plugin-admin-${project.version}.jar</location>
+                                </source>
+                                <source>
+                                    <location>admin-plugin/target/lib/postgresql-${postgresql.version}.jar</location>
+                                </source>
+                            </sources>
+                        </mapping>
+                        <mapping>
+                            <directory>/usr/local/hawq_${hawq.name.version}/ranger/etc</directory>
+                            <sources>
+                                <source>
+                                    <location>conf/ranger-servicedef-hawq.json</location>
+                                </source>
+                            </sources>
+                        </mapping>
+                        <mapping>
+                            <directory>/usr/local/hawq_${hawq.name.version}/ranger/plugin-service</directory>
+                        </mapping>
+                        <mapping>
+                            <directory>/usr/local/hawq_${hawq.name.version}/ranger/plugin-service/bin</directory>
+                        </mapping>
+                        <mapping>
+                            <directory>/usr/local/hawq_${hawq.name.version}/ranger/plugin-service/logs</directory>
+                        </mapping>
+                        <mapping>
+                            <directory>/usr/local/hawq_${hawq.name.version}/ranger/plugin-service/temp</directory>
+                        </mapping>
+                        <mapping>
+                            <directory>/usr/local/hawq_${hawq.name.version}/ranger/plugin-service/work</directory>
+                        </mapping>
+                        <mapping>
+                            <directory>/usr/local/hawq_${hawq.name.version}/ranger/plugin-service/webapps</directory>
+                            <sources>
+                                <source>
+                                    <location>service/target/ranger-plugin-service-${project.version}.war</location>
+                                    <destination>rps.war</destination>
+                                </source>
+                            </sources>
+                        </mapping>
+                        <mapping>
+                            <directory>/usr/local/hawq_${hawq.name.version}/ranger/plugin-service/conf</directory>
+                            <sources>
+                                <source>
+                                    <location>conf/tomcat-server.xml</location>
+                                </source>
+                            </sources>
+                        </mapping>
+                    </mappings>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <version>1.7</version>
+                <executions>
+                    <execution>
+                        <id>regex-property</id>
+                        <goals>
+                            <goal>regex-property</goal>
+                        </goals>
+                        <configuration>
+                            <name>hawq.name.version</name>
+                            <value>${project.version}</value>
+                            <regex>^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)?$</regex>
+                            <replacement>$1_$2_$3_$4</replacement>
+                            <failIfNoMatch>true</failIfNoMatch>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.1</version>
+                <configuration>
+                    <source>1.7</source>
+                    <target>1.7</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.apache.ranger</groupId>
+                <artifactId>ranger-plugins-common</artifactId>
+                <version>0.6.0</version>
+            </dependency>
+            <dependency>
+                <groupId>log4j</groupId>
+                <artifactId>log4j</artifactId>
+                <version>1.2.17</version>
+            </dependency>
+            <dependency>
+                <groupId>commons-logging</groupId>
+                <artifactId>commons-logging</artifactId>
+                <version>1.2</version>
+            </dependency>
+            <dependency>
+                <groupId>postgresql</groupId>
+                <artifactId>postgresql</artifactId>
+                <version>${postgresql.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.codehaus.jackson</groupId>
+                <artifactId>jackson-xc</artifactId>
+                <version>1.9.13</version>
+            </dependency>
+            <dependency>
+              <groupId>com.google.guava</groupId>
+              <artifactId>guava</artifactId>
+              <version>11.0.2</version>
+            </dependency>
+            <dependency>
+                <groupId>javax.servlet</groupId>
+                <artifactId>servlet-api</artifactId>
+                <version>2.5</version>
+                <scope>provided</scope>
+            </dependency>
+            <dependency>
+                <groupId>javax.servlet.jsp</groupId>
+                <artifactId>jsp-api</artifactId>
+                <version>2.1</version>
+                <scope>provided</scope>
+            </dependency>
+            <dependency>
+                <groupId>junit</groupId>
+                <artifactId>junit</artifactId>
+                <version>4.12</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.mockito</groupId>
+                <artifactId>mockito-core</artifactId>
+                <version>1.10.19</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.powermock</groupId>
+                <artifactId>powermock-module-junit4</artifactId>
+                <version>1.6.5</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.powermock</groupId>
+                <artifactId>powermock-api-mockito</artifactId>
+                <version>1.6.5</version>
+                <scope>test</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/scripts/register_hawq.sh
----------------------------------------------------------------------
diff --git a/ranger-plugin/scripts/register_hawq.sh b/ranger-plugin/scripts/register_hawq.sh
new file mode 100755
index 0000000..11e2df8
--- /dev/null
+++ b/ranger-plugin/scripts/register_hawq.sh
@@ -0,0 +1,217 @@
+#!/usr/bin/env bash
+
+#
+# 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.
+#
+
+function usage() {
+  echo "USAGE: register_hawq.sh -r ranger_host:ranger_port -u ranger_user -p ranger_password -h hawq_host:hawq_port -w hawq_user -q hawq_password"
+  exit 1
+}
+
+function fail() {
+  echo "ERROR: $1"
+  exit 1
+}
+
+function mask() {
+  printf -v stars '%*s' ${#1} ''
+  echo "[${stars// /*}]"
+}
+
+function read_value() {
+  local input
+  read -p "Enter value for $1 : " input
+  echo $input
+}
+
+function read_password() {
+  local input
+  read -s -p "Enter value for $1 : " input
+  echo $input
+}
+
+function get_ranger_url() {
+  while [[ -z "$RANGER_URL" ]]
+  do
+    RANGER_URL=$(read_value "Ranger Admin host and port (e.g. abc.com:6080)")
+  done
+  local prefix="http://"
+  RANGER_URL=${RANGER_URL#$prefix}
+}
+
+function get_ranger_user() {
+  while [[ -z "$RANGER_USER" ]]
+  do
+    RANGER_USER=$(read_value "Ranger Admin user name")
+  done
+}
+
+function get_ranger_password() {
+  while [[ -z "$RANGER_PASSWORD" ]]
+  do
+    RANGER_PASSWORD=$(read_password "Ranger Admin password")
+    echo
+  done
+}
+
+function get_hawq_url() {
+  #todo read hawq-site.xml ?
+  local default=`hostname -f`
+  default="${default}:5432"
+  while [[ -z "$HAWQ_URL" ]]
+  do
+    HAWQ_URL=$(read_value "HAWQ Master host and port [${default}]")
+  done
+  local prefix="http://"
+  HAWQ_URL=${HAWQ_URL#$prefix}
+  local parts=(${HAWQ_URL//:/ })
+  if [ ${#parts[@]} != 2 ]; then
+    fail "Incorrect value for HAWQ Master host and port."
+  fi
+  HAWQ_HOST=${parts[0]}
+  HAWQ_PORT=${parts[1]}
+}
+
+function get_hawq_user() {
+  local default="gpadmin"
+  while [[ -z "$HAWQ_USER" ]]
+  do
+    HAWQ_USER=$(read_value "HAWQ user name [${default}]")
+  done
+}
+
+function get_hawq_password() {
+  while [[ -z "$HAWQ_PASSWORD" ]]
+  do
+    HAWQ_PASSWORD=$(read_password "HAWQ password")
+    echo
+  done
+}
+
+function parse_params() {
+  while [[ $# -gt 0 ]] 
+  do
+    key="$1"
+    case $key in
+      -r)
+        RANGER_URL="$2"
+        shift
+        ;;
+      -u)
+        RANGER_USER="$2"
+        shift
+        ;;
+      -p)
+        RANGER_PASSWORD="$2"
+        shift
+        ;;
+      -h)
+        HAWQ_URL="$2"
+        shift
+        ;;
+      -w)
+        HAWQ_USER="$2"
+        shift
+        ;;
+      -q)
+        HAWQ_PASSWORD="$2"
+        shift
+        ;;
+      *)
+        usage
+        ;;
+    esac
+    shift
+  done
+}
+
+function validate_params() {
+  get_ranger_url
+  get_ranger_user
+  get_ranger_password
+  get_hawq_url
+  get_hawq_user
+  get_hawq_password
+  echo "RANGER URL  = ${RANGER_URL}" 
+  echo "RANGER User = ${RANGER_USER}" 
+  echo "RANGER Password = $(mask ${RANGER_PASSWORD})" 
+  echo "HAWQ HOST = ${HAWQ_HOST}"
+  echo "HAWQ PORT = ${HAWQ_PORT}"  
+  echo "HAWQ User = ${HAWQ_USER}" 
+  echo "HAWQ Password = $(mask ${HAWQ_PASSWORD})" 
+}
+
+function check_hawq_service_definition() {
+  echo $(curl -sS -u ${RANGER_USER}:${RANGER_PASSWORD} http://${RANGER_URL}/service/public/v2/api/servicedef/name/hawq | grep hawq | wc -l)
+}
+
+function create_hawq_service_definition() {
+  if [ $(check_hawq_service_definition) == 0 ]; then
+    local json_file="$(dirname ${SCRIPT_DIR})/etc/ranger-servicedef-hawq.json"
+    if [ ! -f ${json_file} ]; then
+      fail "File ${json_file} not found."
+    fi
+    echo "HAWQ service definition was not found in Ranger Admin, creating it by uploading ${json_file}"
+    local output=$(curl -sS -u ${RANGER_USER}:${RANGER_PASSWORD} -H "Content-Type: application/json" -X POST http://${RANGER_URL}/service/plugins/definitions -d @${json_file})
+    local created=$(echo ${output} | grep created | wc -l)
+    if [ ${created} == 0 ] || [ $(check_hawq_service_definition) == 0 ]; then
+      fail "Creation of HAWQ service definition from ${json_file} in Ranger Admin at ${RANGER_URL} failed. ${output}"
+    fi
+  else
+    echo "HAWQ service definition already exists in Ranger Admin, nothing to do." 
+  fi
+}
+
+function check_hawq_service_instance() {
+  echo $(curl -sS -u ${RANGER_USER}:${RANGER_PASSWORD} http://${RANGER_URL}/service/public/v2/api/service/name/hawq | grep hawq | wc -l)
+}
+
+function create_hawq_service_instance() {
+  if [ $(check_hawq_service_instance) == 0 ]; then
+    local payload="{\"name\":\"hawq\",
+                    \"type\":\"hawq\",
+                    \"description\":\"HAWQ Master\",
+                    \"isEnabled\":true,
+                    \"configs\":{\"username\":\"${HAWQ_USER}\",
+                               \"password\":\"${HAWQ_PASSWORD}\",
+                               \"hostname\":\"${HAWQ_HOST}\",
+                               \"port\":\"${HAWQ_PORT}\"}}"
+
+    echo "HAWQ service instance was not found in Ranger Admin, creating it."
+    local output=$(curl -sS -u ${RANGER_USER}:${RANGER_PASSWORD} -H "Content-Type: application/json" -X POST http://${RANGER_URL}/service/public/v2/api/service -d "${payload}")
+    local created=$(echo ${output} | grep created | wc -l)
+    if [ ${created} == 0 ] || [ $(check_hawq_service_instance) == 0 ]; then
+      fail "Creation of HAWQ service instance in Ranger Admin at ${RANGER_URL} failed. ${output}"
+    fi
+  else
+    echo "HAWQ service instance already exists in Ranger Admin, nothing to do."
+  fi
+}
+
+main() {
+  if [[ $# -lt 1 ]]; then
+    usage
+  fi
+  SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+  parse_params "$@"
+  validate_params
+  create_hawq_service_definition
+  create_hawq_service_instance
+}
+main "$@"

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/scripts/rps.sh
----------------------------------------------------------------------
diff --git a/ranger-plugin/scripts/rps.sh b/ranger-plugin/scripts/rps.sh
new file mode 100755
index 0000000..e8ccf3a
--- /dev/null
+++ b/ranger-plugin/scripts/rps.sh
@@ -0,0 +1,60 @@
+#!/usr/bin/env bash
+
+#
+# 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.
+#
+
+if [ $# -le 0 ]; then
+  echo "Usage: rps (start|stop|init) [<catalina-args...>]"
+  exit 1
+fi
+
+actionCmd=$1
+shift
+
+CWDIR=$( cd $( dirname ${BASH_SOURCE[0]} ) && pwd )
+source $CWDIR/rps_env.sh
+
+setup_rps() {
+  echo "Initializing Hawq Ranger Plugin Service..."
+  cp $CATALINA_HOME/conf.template/* $CATALINA_BASE/conf
+  cp $CATALINA_BASE/conf/tomcat-server.xml $CATALINA_BASE/conf/server.xml
+  pushd $CATALINA_BASE/webapps >/dev/null
+  unzip -d rps rps.war >/dev/null
+  find . -name ranger-hawq-security.xml | xargs sed -i \
+    "s/localhost:6080/$RANGER_ADMIN_HOST:$RANGER_ADMIN_PORT/g"
+  popd >/dev/null
+  echo "Hawq Ranger Plugin Service installed on http://$RPS_HOST:$RPS_PORT/rps"
+  echo "Please use 'rps.sh start' to start the service"
+}
+
+case $actionCmd in
+  (init)
+    setup_rps
+    ;;
+  (start)
+    $CATALINA_HOME/bin/catalina.sh start "$@"
+    echo "Waiting for RPS service to start..."
+    sleep 15
+    ;;
+  (stop)
+    $CATALINA_HOME/bin/catalina.sh stop "$@"
+    echo "Waiting for RPS service to stop..."
+    sleep 10
+    ;;
+esac

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/scripts/rps_env.sh
----------------------------------------------------------------------
diff --git a/ranger-plugin/scripts/rps_env.sh b/ranger-plugin/scripts/rps_env.sh
new file mode 100755
index 0000000..ae36e8f
--- /dev/null
+++ b/ranger-plugin/scripts/rps_env.sh
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+
+#
+# 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.
+#
+
+export CATALINA_HOME=/usr/lib/bigtop-tomcat
+export CATALINA_BASE=/usr/local/hawq/ranger/plugin-service
+
+export RANGER_ADMIN_HOST=${RANGER_ADMIN_HOST:-localhost}
+export RANGER_ADMIN_PORT=${RANGER_ADMIN_PORT:-6080}
+
+export RPS_HOST=${RPS_HOST:-localhost}
+export RPS_PORT=${RPS_PORT:-8432}
+export CATALINA_OPTS="-Dhttp.host=$RPS_HOST -Dhttp.port=$RPS_PORT"

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/pom.xml
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/pom.xml b/ranger-plugin/service/pom.xml
new file mode 100644
index 0000000..3f2f9f8
--- /dev/null
+++ b/ranger-plugin/service/pom.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.hawq</groupId>
+    <artifactId>ranger-plugin-service</artifactId>
+    <packaging>war</packaging>
+    <name>HAWQ Ranger Service</name>
+    <description>HAWQ Ranger Service</description>
+    <parent>
+        <groupId>org.apache.hawq</groupId>
+        <artifactId>ranger-plugin</artifactId>
+        <version>2.1.0.0</version>
+        <relativePath>..</relativePath>
+    </parent>
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>true</filtering>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <!-- use mvn tomcat6:run-war to run the appserver with the app deployed -->
+                <groupId>org.apache.tomcat.maven</groupId>
+                <artifactId>tomcat6-maven-plugin</artifactId>
+                <version>2.2</version>
+                <configuration>
+                    <path>/rps</path>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-xc</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.ranger</groupId>
+            <artifactId>ranger-plugins-common</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-module-junit4</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-api-mockito</artifactId>
+        </dependency>
+    </dependencies>
+
+    
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/HawqAuthorizer.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/HawqAuthorizer.java b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/HawqAuthorizer.java
new file mode 100644
index 0000000..625ce50
--- /dev/null
+++ b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/HawqAuthorizer.java
@@ -0,0 +1,36 @@
+/*
+ * 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.hawq.ranger.authorization;
+
+import org.apache.hawq.ranger.authorization.model.AuthorizationRequest;
+import org.apache.hawq.ranger.authorization.model.AuthorizationResponse;
+
+/**
+ * Interface for making authorization decisions.
+ */
+public interface HawqAuthorizer {
+
+    /**
+     * Determines whether access should be allowed for the given authorization request.
+     * @param request authorization request
+     * @return authorization response
+     */
+    AuthorizationResponse isAccessAllowed(AuthorizationRequest request);
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/RangerHawqAuthorizer.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/RangerHawqAuthorizer.java b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/RangerHawqAuthorizer.java
new file mode 100644
index 0000000..04d6f99
--- /dev/null
+++ b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/RangerHawqAuthorizer.java
@@ -0,0 +1,263 @@
+/*
+ * 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.hawq.ranger.authorization;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hawq.ranger.authorization.model.AuthorizationRequest;
+import org.apache.hawq.ranger.authorization.model.AuthorizationResponse;
+import org.apache.hawq.ranger.authorization.model.HawqPrivilege;
+import org.apache.hawq.ranger.authorization.model.HawqResource;
+import org.apache.hawq.ranger.authorization.model.ResourceAccess;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
+import org.apache.ranger.plugin.policyengine.RangerAccessResource;
+import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl;
+import org.apache.ranger.plugin.policyengine.RangerAccessResult;
+import org.apache.ranger.plugin.service.RangerBasePlugin;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.apache.hawq.ranger.authorization.Utils.HAWQ;
+
+/**
+ * Authorizer implementation that uses Ranger to make access decision. Implemented as a singleton.
+ */
+public class RangerHawqAuthorizer implements HawqAuthorizer {
+
+    private static final Log LOG = LogFactory.getLog(RangerHawqAuthorizer.class);
+
+    private static final RangerHawqAuthorizer INSTANCE = new RangerHawqAuthorizer();
+
+    private RangerBasePlugin rangerPlugin;
+
+    /**
+     * Returns the instance of the RangerHawqAuthorizer.
+     * @return the singleton instance
+     */
+    public static RangerHawqAuthorizer getInstance() {
+        return INSTANCE;
+    }
+
+    /**
+     * Constructor. Initializes Ranger Base Plugin to fetch policies from Ranger.
+     */
+    private RangerHawqAuthorizer() {
+
+        LOG.info("Initializing RangerHawqAuthorizer");
+
+        String appId = Utils.getAppId();
+
+        LOG.info(String.format("Initializing RangerBasePlugin for service %s:%s", HAWQ, appId));
+        rangerPlugin = new RangerBasePlugin(HAWQ, appId);
+        rangerPlugin.init();
+        LOG.info(String.format("Initialized RangerBasePlugin for service %s:%s", HAWQ, appId));
+    }
+
+    @Override
+    public AuthorizationResponse isAccessAllowed(AuthorizationRequest request) {
+
+        // validate request to make sure no data is missing
+        validateRequest(request);
+
+        // prepare response object
+        AuthorizationResponse response = new AuthorizationResponse();
+        response.setRequestId(request.getRequestId());
+        Set<ResourceAccess> access = new HashSet<>();
+        response.setAccess(access);
+
+        // iterate over resource requests, augment processed ones with the decision and add to the response
+        for (ResourceAccess resourceAccess : request.getAccess()) {
+            boolean accessAllowed = authorizeResource(resourceAccess, request.getUser());
+            resourceAccess.setAllowed(accessAllowed);
+            access.add(resourceAccess);
+        }
+
+        return response;
+    }
+
+    /**
+     * Authorizes access to a single resource for a given user.
+     *
+     * @param resourceAccess resource to authorize access to
+     * @param user user requesting authorization
+     * @return true if access is authorized, false otherwise
+     */
+    private boolean authorizeResource(ResourceAccess resourceAccess, String user) {
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug(String.format("Request: access for user=%s to resource=%s with privileges=%s",
+                user, resourceAccess.getResource(), resourceAccess.getPrivileges()));
+        }
+
+        RangerAccessResourceImpl rangerResource = new RangerAccessResourceImpl();
+        //resource.setOwnerUser();
+        for (Map.Entry<HawqResource, String> resourceEntry : resourceAccess.getResource().entrySet()) {
+            rangerResource.setValue(resourceEntry.getKey().name(), resourceEntry.getValue());
+        }
+
+        boolean accessAllowed = true;
+        // iterate over all privileges requested
+        for (HawqPrivilege privilege : resourceAccess.getPrivileges()) {
+            // TODO not clear how we will get user groups -- Kerberos case ?
+            Set<String> userGroups = Collections.emptySet();
+            boolean privilegeAuthorized = authorizeResourcePrivilege(rangerResource, privilege.name(), user, userGroups);
+            // ALL model of evaluation -- all privileges must be authorized for access to be allowed
+            if (!privilegeAuthorized) {
+                accessAllowed = false;
+                break; // terminate early if even a single privilege is not authorized
+            }
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug(String.format("Decision: accessAllowed=%s for user=%s to resource=%s with privileges=%s",
+                    accessAllowed, user, resourceAccess.getResource(), resourceAccess.getPrivileges()));
+        }
+
+        return accessAllowed;
+    }
+
+    /**
+     * Authorizes access of a given type (privilege) to a single resource for a given user.
+     *
+     * @param rangerResource resource to authorize access to
+     * @param accessType privilege requested for a given resource
+     * @param user user requesting authorization
+     * @param userGroups groups a user belongs to
+     * @return true if access is authorized, false otherwise
+     */
+    private boolean authorizeResourcePrivilege(RangerAccessResource rangerResource, String accessType, String user, Set<String> userGroups) {
+
+        Map<String, String> resourceMap = rangerResource.getAsMap();
+        String database = resourceMap.get(HawqResource.database.name());
+        String schema = resourceMap.get(HawqResource.schema.name());
+        int resourceSize = resourceMap.size();
+
+        // special handling for non-leaf policies
+        if (accessType.equals(HawqPrivilege.create.name()) && database != null && schema == null && resourceSize == 1) {
+            accessType = HawqPrivilege.create_schema.toValue();
+            LOG.debug("accessType mapped to: create-schema");
+        } else if (accessType.equals(HawqPrivilege.usage.name()) && database != null && schema != null && resourceSize == 2) {
+            accessType = HawqPrivilege.usage_schema.toValue();
+            LOG.debug("accessType mapped to: usage-schema");
+        }
+
+        RangerAccessRequest rangerRequest = new RangerAccessRequestImpl(rangerResource, accessType, user, userGroups);
+        RangerAccessResult result = rangerPlugin.isAccessAllowed(rangerRequest);
+        boolean accessAllowed = result != null && result.getIsAllowed();
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug(String.format("--- RangerDecision: accessAllowed=%s for user=%s to resource=%s with privileges=%s, result present=%s",
+                    accessAllowed, user, rangerResource.getAsString(), accessType, result!=null));
+        }
+
+        return accessAllowed;
+    }
+
+    /**
+     * Validates that authorization requests do not have any missing data.
+     *
+     * @param request authorization request
+     * @throws IllegalArgumentException if any data is missing
+     */
+    private void validateRequest(AuthorizationRequest request) {
+        LOG.debug("Validating authorization request");
+
+        if (request == null) {
+            throw new IllegalArgumentException("request is null");
+        }
+
+        if (request.getRequestId() == null) {
+            throw new IllegalArgumentException("requestId field is missing or null in the request");
+        }
+
+        if (StringUtils.isEmpty(request.getUser())) {
+            throw new IllegalArgumentException("user field is missing or empty in the request");
+        }
+
+        if (StringUtils.isEmpty(request.getClientIp())) {
+            throw new IllegalArgumentException("clientIp field is missing or empty in the request");
+        }
+
+        if (StringUtils.isEmpty(request.getContext())) {
+            throw new IllegalArgumentException("context field is missing or empty in the request");
+        }
+
+        Set<ResourceAccess> accessSet = request.getAccess();
+        if (CollectionUtils.isEmpty(accessSet)) {
+            throw new IllegalArgumentException("access field is missing or empty in the request");
+        }
+
+        for (ResourceAccess access : accessSet) {
+            validateResourceAccess(access);
+        }
+
+        LOG.debug("Successfully validated authorization request");
+    }
+
+    /**
+     * Validates that resource access does not have any missing data.
+     *
+     * @param access resource access data
+     * @throws IllegalArgumentException if any data is missing
+     */
+    private void validateResourceAccess(ResourceAccess access) {
+        Map<HawqResource, String> resourceMap = access.getResource();
+        if  (MapUtils.isEmpty(resourceMap)) {
+            throw new IllegalArgumentException("resource field is missing or empty in the request");
+        }
+        for (Map.Entry<HawqResource, String> resourceEntry : resourceMap.entrySet()) {
+            if (StringUtils.isEmpty(resourceEntry.getValue())) {
+                throw new IllegalArgumentException(
+                        String.format("resource value is missing for key=%s in the request", resourceEntry.getKey())
+                );
+            }
+        }
+        if (CollectionUtils.isEmpty(access.getPrivileges())) {
+            throw new IllegalArgumentException("set of privileges is missing empty in the request");
+        }
+    }
+
+
+
+    /**
+     * Sets an instance of the Ranger Plugin for testing.
+     *
+     * @param plugin plugin instance to use while testing
+     */
+    void setRangerPlugin(RangerBasePlugin plugin) {
+        rangerPlugin = plugin;
+    }
+
+    /**
+     * Returns the instance of the Ranger Plugin for testing.
+     *
+     * @return BaseRangerPlugin instance
+     */
+    RangerBasePlugin getRangerPlugin() {
+        return rangerPlugin;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/RangerHawqPluginResource.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/RangerHawqPluginResource.java b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/RangerHawqPluginResource.java
new file mode 100644
index 0000000..26a7660
--- /dev/null
+++ b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/RangerHawqPluginResource.java
@@ -0,0 +1,86 @@
+/*
+ * 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.hawq.ranger.authorization;
+
+import com.sun.jersey.spi.resource.Singleton;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hawq.ranger.authorization.model.AuthorizationRequest;
+import org.apache.hawq.ranger.authorization.model.AuthorizationResponse;
+
+import javax.ws.rs.*;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.Date;
+
+/**
+ * JAX-RS resource for the authorization endpoint.
+ */
+@Path("/")
+@Singleton
+public class RangerHawqPluginResource {
+
+    private static final Log LOG = LogFactory.getLog(RangerHawqPluginResource.class);
+
+    private HawqAuthorizer authorizer;
+    private String version;
+
+    /**
+     * Constructor. Creates a new instance of the resource that uses <code>RangerHawqAuthorizer</code>.
+     */
+    public RangerHawqPluginResource() {
+        this.authorizer = RangerHawqAuthorizer.getInstance();
+    }
+
+
+    @Path("/version")
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response version()
+    {
+        String output = "{\"version\":\"" + Utils.getVersion() + "\"}";
+        return Response.status(200).entity(output).build();
+    }
+
+    /**
+     * Authorizes a request to access protected resources with requested privileges.
+     * @param request authorization request
+     * @return authorization response
+     */
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public AuthorizationResponse authorize(AuthorizationRequest request)
+    {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Received authorization request: " + request);
+        }
+
+        // exceptions are handled by ServiceExceptionMapper
+        AuthorizationResponse response = authorizer.isAccessAllowed(request);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Returning authorization response: " + response);
+        }
+        return response;
+    }
+}
+
+

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/ServiceExceptionMapper.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/ServiceExceptionMapper.java b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/ServiceExceptionMapper.java
new file mode 100644
index 0000000..b983d72
--- /dev/null
+++ b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/ServiceExceptionMapper.java
@@ -0,0 +1,97 @@
+/*
+ * 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.hawq.ranger.authorization;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+/**
+ * Maps service exceptions to HTTP response.
+ */
+@Provider
+public class ServiceExceptionMapper implements ExceptionMapper<Throwable> {
+
+    private static final Log LOG = LogFactory.getLog(ServiceExceptionMapper.class);
+
+    @Override
+    public Response toResponse(Throwable e) {
+
+        LOG.error("Service threw an exception: ", e);
+
+        // default to internal server error (HTTP 500)
+        Response.Status status = Response.Status.INTERNAL_SERVER_ERROR;
+
+        if (e instanceof IllegalArgumentException) {
+            status = Response.Status.BAD_REQUEST;
+        }
+
+        ErrorPayload error = new ErrorPayload(status.getStatusCode(), e.getMessage());
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug(String.format("Returning error response: status=%s message=%s",
+                                    error.getStatus(), error.getMessage()));
+        }
+
+        return Response.status(status)
+                .entity(error)
+                .type(MediaType.APPLICATION_JSON)
+                .build();
+    }
+
+    /**
+     * Represents payload to be serialized as JSON into response.
+     */
+    public static class ErrorPayload {
+        private int status;
+        private String message;
+
+        /**
+         * Constructor.
+         * @param status HTTP error status
+         * @param message error message
+         */
+        public ErrorPayload(int status, String message) {
+            this.status = status;
+            this.message = message;
+        }
+
+        /**
+         * Returns status code
+         * @return status code
+         */
+        public int getStatus() {
+            return status;
+        }
+
+        /**
+         * Returns error message
+         * @return error message
+         */
+        public String getMessage() {
+            return message;
+        }
+
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/Utils.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/Utils.java b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/Utils.java
new file mode 100644
index 0000000..86f7fc4
--- /dev/null
+++ b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/Utils.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.hawq.ranger.authorization;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+/**
+ * Utility class for reading values from the property file.
+ */
+public abstract class Utils {
+
+    public static final String HAWQ = "hawq";
+    public static final String UNKNOWN = "unknown";
+    public static final String APP_ID_PROPERTY = "ranger.hawq.instance";
+    public static final String VERSION_PROPERTY = "version";
+    public static final String RANGER_SERVICE_PROPERTY_FILE = "rps.properties";
+
+    private static final Log LOG = LogFactory.getLog(Utils.class);
+    private static final Properties properties = readPropertiesFromFile();
+
+    /**
+     * Retrieves the app id from the environment variable with the key ranger.hawq.instance
+     * or from the rps.properties file with the key ranger.hawq.instance
+     *
+     * If none exist, hawq is used as the default
+     *
+     * @return String id of the app
+     */
+    public static String getAppId() {
+        return System.getProperty(APP_ID_PROPERTY, properties.getProperty(APP_ID_PROPERTY, HAWQ));
+    }
+
+    /**
+     * Retrieves the version read from the property file.
+     *
+     * If none exist, unknown is used as the default
+     *
+     * @return version of the service
+     */
+    public static String getVersion() {
+        return properties.getProperty(VERSION_PROPERTY, UNKNOWN);
+    }
+
+    /**
+     * Reads properties from the property file.
+     * @return properties read from the file
+     */
+    private static Properties readPropertiesFromFile() {
+        Properties prop = new Properties();
+        InputStream inputStream = Utils.class.getClassLoader().getResourceAsStream(RANGER_SERVICE_PROPERTY_FILE);
+        try {
+            prop.load(inputStream);
+        } catch (IOException e) {
+            LOG.error("Failed to read from: " + RANGER_SERVICE_PROPERTY_FILE);
+        }
+        return prop;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/model/AuthorizationRequest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/model/AuthorizationRequest.java b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/model/AuthorizationRequest.java
new file mode 100644
index 0000000..6e8ab4f
--- /dev/null
+++ b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/model/AuthorizationRequest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.hawq.ranger.authorization.model;
+
+import java.util.Set;
+
+/**
+ * Model for submitting an authorization request for multiple resources.
+ */
+public class AuthorizationRequest {
+
+    private Integer requestId;
+    private String user;
+    private String clientIp;
+    private String context;
+    private Set<ResourceAccess> access;
+
+    /**
+     * Returns request id.
+     * @return id of the request
+     */
+    public Integer getRequestId() {
+        return requestId;
+    }
+
+    /**
+     * Sets request id.
+     * @param requestId id of the request
+     */
+    public void setRequestId(Integer requestId) {
+        this.requestId = requestId;
+    }
+
+    /**
+     * Returns user name for the user submitting the access request.
+     * @return name of the user
+     */
+    public String getUser() {
+        return user;
+    }
+
+    /**
+     * Sets user name for the user submitting the access request.
+     * @param user name of the user
+     */
+    public void setUser(String user) {
+        this.user = user;
+    }
+
+    /**
+     * Returns IP address of the client where the user request is made from.
+     * @return IP address of the user's client
+     */
+    public String getClientIp() {
+        return clientIp;
+    }
+
+    /**
+     * Sets IP address of the client where the user request is made from.
+     * @param clientIp IP address of the user's client
+     */
+    public void setClientIp(String clientIp) {
+        this.clientIp = clientIp;
+    }
+
+    /**
+     * Returns context of the request, usually a SQL query that the user ran
+     * @return context of the request
+     */
+    public String getContext() {
+        return context;
+    }
+
+    /**
+     * Sets the context of the request, usually a SQL query that the user ran
+     * @param context context of the request
+     */
+    public void setContext(String context) {
+        this.context = context;
+    }
+
+    /**
+     * Returns a set of <code>ResourceAccess</code> objects.
+     * @return s set of <code>ResourceAccess</code> objects
+     */
+    public Set<ResourceAccess> getAccess() {
+        return access;
+    }
+
+    /**
+     * Sets <code>ResourceAccess</code> objects
+     * @param access a set of <code>ResourceAccess</code> objects
+     */
+    public void setAccess(Set<ResourceAccess> access) {
+        this.access = access;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/model/AuthorizationResponse.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/model/AuthorizationResponse.java b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/model/AuthorizationResponse.java
new file mode 100644
index 0000000..f989b8d
--- /dev/null
+++ b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/model/AuthorizationResponse.java
@@ -0,0 +1,63 @@
+/*
+ * 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.hawq.ranger.authorization.model;
+
+import java.util.Set;
+
+/**
+ *  Model for response containing authorization decisions for access to multiple resources.
+ */
+public class AuthorizationResponse {
+
+    private Integer requestId;
+    private Set<ResourceAccess> access;
+
+    /**
+     * Returns request id.
+     * @return id of the request
+     */
+    public Integer getRequestId() {
+        return requestId;
+    }
+
+    /**
+     * Sets request id.
+     * @param requestId id of the request
+     */
+    public void setRequestId(Integer requestId) {
+        this.requestId = requestId;
+    }
+
+    /**
+     * Returns a set of <code>ResourceAccess</code> objects.
+     * @return a set of <code>ResourceAccess</code> objects
+     */
+    public Set<ResourceAccess> getAccess() {
+        return access;
+    }
+
+    /**
+     * Sets <code>ResourceAccess</code> objects
+     * @param access a set of <code>ResourceAccess</code> objects
+     */
+    public void setAccess(Set<ResourceAccess> access) {
+        this.access = access;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/model/HawqPrivilege.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/model/HawqPrivilege.java b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/model/HawqPrivilege.java
new file mode 100644
index 0000000..ffce67a
--- /dev/null
+++ b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/model/HawqPrivilege.java
@@ -0,0 +1,61 @@
+/*
+ * 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.hawq.ranger.authorization.model;
+
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonValue;
+
+/**
+ *  Model enumeration of types of HAWQ privileges.
+ */
+public enum HawqPrivilege {
+    select,
+    insert,
+    update,
+    delete,
+    references,
+    usage,
+    create,
+    connect,
+    execute,
+    temp,
+    create_schema,
+    usage_schema,
+    all;
+
+    /**
+     * Returns HawqPrivilege type by case-insensitive lookup of the value.
+     * @param key case insensitive string representation of the privilege
+     * @return instance of HawqPrivilege
+     */
+    @JsonCreator
+    public static HawqPrivilege fromString(String key) {
+        return key == null ? null : HawqPrivilege.valueOf(key.replace('-', '_').toLowerCase());
+    }
+
+    /**
+     * Returns string representation of the enum, replaces underscores with dashes.
+     * @return string representation of the enum
+     */
+    @JsonValue
+    public String toValue() {
+        return name().replace('_', '-');
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/model/HawqResource.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/model/HawqResource.java b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/model/HawqResource.java
new file mode 100644
index 0000000..c9de4e7
--- /dev/null
+++ b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/model/HawqResource.java
@@ -0,0 +1,46 @@
+/*
+ * 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.hawq.ranger.authorization.model;
+
+import org.codehaus.jackson.annotate.JsonCreator;
+
+/**
+ * Model enumeration of types of HAWQ resources.
+ */
+public enum HawqResource {
+    database,
+    schema,
+    table,
+    sequence,
+    function,
+    language,
+    tablespace,
+    protocol;
+
+    /**
+     * Returns HawqResource type by case-insensitive lookup of the value.
+     * @param key case insensitive string representation of the resource
+     * @return instance of HawqResource
+     */
+    @JsonCreator
+    public static HawqResource fromString(String key) {
+        return key == null ? null : HawqResource.valueOf(key.toLowerCase());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/model/ResourceAccess.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/model/ResourceAccess.java b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/model/ResourceAccess.java
new file mode 100644
index 0000000..df1631a
--- /dev/null
+++ b/ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/model/ResourceAccess.java
@@ -0,0 +1,85 @@
+/*
+ * 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.hawq.ranger.authorization.model;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Model object for requesting access to a single resource.
+ */
+public class ResourceAccess {
+
+    private Map<HawqResource, String> resource;
+    private Set<HawqPrivilege> privileges;
+    private boolean allowed = false;
+
+    public Set<HawqPrivilege> getPrivileges() {
+        return privileges;
+    }
+
+    public void setPrivileges(Set<HawqPrivilege> privileges) {
+        this.privileges = privileges;
+    }
+
+    public boolean isAllowed() {
+        return allowed;
+    }
+
+    public void setAllowed(boolean allowed) {
+        this.allowed = allowed;
+    }
+
+    public Map<HawqResource, String> getResource() {
+        return resource;
+    }
+
+    public void setResource(Map<HawqResource, String> resource) {
+        this.resource = resource;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this)
+                .append("resource", resource)
+                .append("privileges", privileges)
+                .append("allowed", allowed)
+                .toString();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ResourceAccess that = (ResourceAccess) o;
+        return allowed == that.allowed &&
+                Objects.equals(resource, that.resource) &&
+                Objects.equals(privileges, that.privileges);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(resource, privileges, allowed);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/main/resources/log4j.properties b/ranger-plugin/service/src/main/resources/log4j.properties
new file mode 100644
index 0000000..6bbdaed
--- /dev/null
+++ b/ranger-plugin/service/src/main/resources/log4j.properties
@@ -0,0 +1,42 @@
+# 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.
+
+# see debug messages during unit tests
+project.root.logger=DEBUG,console
+
+# suppress all logging output during unit tests
+#project.root.logger=FATAL,devnull
+
+#
+# Loggers
+#
+log4j.rootLogger=${project.root.logger}
+
+# ignore most errors from the Apache Ranger and Hadoop for unit tests
+log4j.logger.org.apache.ranger=FATAL
+log4j.logger.org.apache.hadoop=FATAL
+
+#
+# Appenders
+#
+
+# nothing
+log4j.appender.devnull=org.apache.log4j.varia.NullAppender
+
+# console
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.target=System.err
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2}: %m%n
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/main/resources/ranger-hawq-security.xml
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/main/resources/ranger-hawq-security.xml b/ranger-plugin/service/src/main/resources/ranger-hawq-security.xml
new file mode 100644
index 0000000..46dd75d
--- /dev/null
+++ b/ranger-plugin/service/src/main/resources/ranger-hawq-security.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+
+<!--
+  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.
+-->
+
+<configuration xmlns:xi="http://www.w3.org/2001/XInclude">
+    <property>
+        <name>ranger.plugin.hawq.service.name</name>
+        <value>hawq</value>
+        <description>
+            Name of the Ranger service containing policies for this HAWQ instance
+        </description>
+    </property>
+
+    <property>
+        <name>ranger.plugin.hawq.policy.source.impl</name>
+        <value>org.apache.ranger.admin.client.RangerAdminRESTClient</value>
+        <description>
+            Class to retrieve policies from the source
+        </description>
+    </property>
+
+    <property>
+        <name>ranger.plugin.hawq.policy.rest.url</name>
+        <value>http://localhost:6080</value>
+        <description>
+            URL to Ranger Admin
+        </description>
+    </property>
+
+    <property>
+        <name>ranger.plugin.hawq.policy.rest.ssl.config.file</name>
+        <value>/usr/local/hawq/ranger/etc/ranger-policymgr-ssl.xml</value>
+        <description>
+            Path to the file containing SSL details to contact Ranger Admin
+        </description>
+    </property>
+
+    <property>
+        <name>ranger.plugin.hawq.policy.pollIntervalMs</name>
+        <value>30000</value>
+        <description>
+            How often to poll for changes in policies?
+        </description>
+    </property>
+
+    <property>
+        <name>ranger.plugin.hawq.policy.cache.dir</name>
+        <value>/usr/local/hawq/ranger/policycache</value>
+        <description>
+            Directory where Ranger policies are cached after successful retrieval from the source
+        </description>
+    </property>
+
+    <!--
+    <property>
+        <name>xasecure.hive.update.xapolicies.on.grant.revoke</name>
+        <value>true</value>
+        <description>Should Hive plugin update Ranger policies for updates to permissions done using GRANT/REVOKE?</description>
+    </property>
+    -->
+    <property>
+        <name>ranger.plugin.hawq.policy.rest.client.connection.timeoutMs</name>
+        <value>120000</value>
+        <description>
+            RangerRESTClient Connection Timeout in Milliseconds
+        </description>
+    </property>
+
+    <property>
+        <name>ranger.plugin.hawq.policy.rest.client.read.timeoutMs</name>
+        <value>30000</value>
+        <description>
+            RangerRESTClient read Timeout in Milliseconds
+        </description>
+    </property>
+</configuration>

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/main/resources/rps.properties
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/main/resources/rps.properties b/ranger-plugin/service/src/main/resources/rps.properties
new file mode 100644
index 0000000..9e2b1f4
--- /dev/null
+++ b/ranger-plugin/service/src/main/resources/rps.properties
@@ -0,0 +1,17 @@
+# 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.
+
+ranger.hawq.instance=hawq
+version=${project.version}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/main/webapp/WEB-INF/web.xml b/ranger-plugin/service/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..36c976f
--- /dev/null
+++ b/ranger-plugin/service/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+
+<!--
+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.
+-->
+
+<web-app version="3.0"
+         xmlns="http://java.sun.com/xml/ns/javaee"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
+
+    <!--
+        This is the HAWQ Ranger Plugin Service webapp xml descriptor
+
+        servlet-class	Jersey entrypoint class
+        init-param		com.sun.jersey.config.property.packages
+                            Tells Jersey where are the REST components of this webapp
+                        jersey.config.server.provider.scanning.recursive
+                            Tells Jersey to recusively scan package for REST resources
+        load-on-startup	Initialize the webapp on app server startup
+        servlet-mapping	Maps the path of the servlet (ranger-plugin/*)
+        listener		A class called after the webapp was initialized and before it's about to go down
+    -->
+
+    <servlet>
+        <servlet-name>HAWQ_Ranger_Plugin_Service</servlet-name>
+        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
+        <init-param>
+            <param-name>com.sun.jersey.config.property.packages</param-name>
+            <param-value>org.apache.hawq.ranger.authorization</param-value>
+        </init-param>
+        <init-param>
+            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
+            <param-value>true</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>HAWQ_Ranger_Plugin_Service</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+
+    <!--
+    <listener>
+        <listener-class>org.apache.hawq.pxf.service.rest.ServletLifecycleListener</listener-class>
+    </listener>
+    -->
+    <!-- log4j configuration
+         Log4jConfigListener looks for a file under log4jConfigLocation.
+         When not using absolute path, the path starts from the webapp root directory.
+         If this file cannot be read, log4j will revert to using the default
+         pxf-log4j.properties inside the webapp. -->
+    <context-param>
+        <param-name>log4jConfigLocation</param-name>
+        <param-value>/etc/pxf/conf/pxf-log4j.properties</param-value>
+    </context-param>
+</web-app>

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/7f36b35b/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/RangerHawqAuthorizerAppIdTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/RangerHawqAuthorizerAppIdTest.java b/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/RangerHawqAuthorizerAppIdTest.java
new file mode 100644
index 0000000..461864e
--- /dev/null
+++ b/ranger-plugin/service/src/test/java/org/apache/hawq/ranger/authorization/RangerHawqAuthorizerAppIdTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.hawq.ranger.authorization;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(Utils.class)
+public class RangerHawqAuthorizerAppIdTest {
+
+    @Test
+    public void testAppIdIsSet() {
+        PowerMockito.mockStatic(Utils.class);
+        when(Utils.getAppId()).thenReturn("foo");
+        assertEquals("foo", RangerHawqAuthorizer.getInstance().getRangerPlugin().getAppId());
+    }
+}