You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hawq.apache.org by es...@apache.org on 2017/02/03 09:00:34 UTC

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

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/2.1.0.0-incubating
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());
+    }
+
+}