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 <adenis...@pivotal.io> Authored: Mon Jan 16 11:46:36 2017 -0800 Committer: Alexander Denissov <adenis...@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()); + } + +}