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