Repository: incubator-hawq
Updated Branches:
  refs/heads/1485 [created] 0580d0902


HAWQ-1485. Use user/password instead of credentials cache in Ranger lookup for 
HAWQ with Kerberos enabled.


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

Branch: refs/heads/1485
Commit: 0580d09021f6fea41c1de7c1b5c6477bf90b3aa7
Parents: 444a73a
Author: interma <[email protected]>
Authored: Tue Jun 13 12:09:40 2017 +0800
Committer: Wen Lin <[email protected]>
Committed: Wed Jun 14 15:34:05 2017 +0800

----------------------------------------------------------------------
 .../apache/hawq/ranger/service/HawqClient.java  | 235 +++++++------------
 .../hawq/ranger/service/HawqResourceMgr.java    | 191 ++++++++-------
 .../hawq/ranger/service/RangerServiceHawq.java  |  80 +++++--
 .../hawq/ranger/service/HawqClientTest.java     |  23 +-
 .../ranger/service/RangerServiceHawqTest.java   |  24 +-
 5 files changed, 255 insertions(+), 298 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/0580d090/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
index 5d2cd71..bae2d2d 100644
--- 
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
@@ -22,6 +22,7 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hawq.ranger.model.HawqProtocols;
 import org.apache.ranger.plugin.client.BaseClient;
+
 import java.security.PrivilegedAction;
 import java.security.PrivilegedExceptionAction;
 import java.sql.Connection;
@@ -74,11 +75,7 @@ public class HawqClient extends BaseClient {
     private static final String DEFAULT_DATABASE_TEMPLATE = 
"DBTOBEREPLACEDINJDBCURL";
     private static final String JDBC_DRIVER_CLASS = "org.postgresql.Driver";
 
-    private boolean isKerberosAuth = false;
-    private Connection con;
-    private String jdbc_url_template = "";
-    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 {
@@ -91,125 +88,60 @@ public class HawqClient extends BaseClient {
     }
 
     public HawqClient(String serviceName, Map<String, String> 
connectionProperties) throws Exception {
-        super(serviceName,connectionProperties);
+        super(serviceName, connectionProperties);
         this.connectionProperties = connectionProperties;
-        initHawq();
     }
-    
-    public void initHawq() throws Exception {
-       if(connectionProperties.containsKey(AUTHENTICATION)) {
-               isKerberosAuth = 
connectionProperties.get(AUTHENTICATION).equals(KERBEROS);
-       }
-               if (isKerberosAuth) {
-                       LOG.info("Secured Mode: JDBC Connection done with 
preAuthenticated Subject");
-                       
-                       // do kinit in hawqclient by principal name and password
-                       final String userName = getConfigHolder().getUserName();
-                       final String password = getConfigHolder().getPassword();
-                       
-                       String[] kinitcmd ={
-                               "/bin/sh",
-                               "-c",
-                               "echo '"+password+"' | kinit " + userName
-                       };
-                       java.lang.Runtime rt = java.lang.Runtime.getRuntime();
-                       if (LOG.isDebugEnabled()) {
-                               LOG.debug("kinit command: "+"echo 
'"+password+"' | kinit " + userName);
-                       }
-                       java.lang.Process p = rt.exec(kinitcmd);
-                       
-                       Subject.doAs(getLoginSubject(), new 
PrivilegedExceptionAction<Void>(){
-                               public Void run() throws Exception {
-                                       final String lookupPricipalName = 
getConfigHolder().getUserName();
-                                       final String serverprincipal = 
connectionProperties.get("principal");
-                                       initConnectionKerberos(serverprincipal, 
lookupPricipalName);
-                                       return null;
-                       }});
-               }
-               else {
-                       LOG.info("Trying to use UnSecure client with username 
"+ getConfigHolder().getUserName() +" and password");
-                       final String userName = getConfigHolder().getUserName();
-                       final String password = getConfigHolder().getPassword();
-                       initConnection(userName, password);
-               }
-       }
-
-    private void initConnectionKerberos(String serverPricipal, String 
userPrincipal) throws SQLException{
-           try {
-                       String url = 
String.format("jdbc:postgresql://%s:%s/%s?kerberosServerName=%s&jaasApplicationName=pgjdbc&user=%s",
 
-                                       connectionProperties.get("hostname"), 
-                                       connectionProperties.get("port"), 
DEFAULT_DATABASE, 
-                                       serverPricipal, userPrincipal
-                                       );
-                       if (LOG.isDebugEnabled()) {
-                               LOG.debug("InitConnectionKerberos "+ url);
-                       }
-                       con = DriverManager.getConnection(url); 
-                       jdbc_url_template = 
String.format("jdbc:postgresql://%s:%s/%s?kerberosServerName=%s&jaasApplicationName=pgjdbc&user=%s",
 
-                                       connectionProperties.get("hostname"), 
-                                       connectionProperties.get("port"), 
DEFAULT_DATABASE_TEMPLATE, 
-                                       serverPricipal, userPrincipal
-                                       );
-           } catch (SQLException e) {
-             e.printStackTrace();
-          LOG.error("Unable to Connect to Hawq", e);
-          throw e;
-           } catch (SecurityException se) {
-                       se.printStackTrace();
-               }
-       }
-
-       
-       private void initConnection(String userName, String password) throws 
SQLException  {
-               try {
-                       String url = 
String.format("jdbc:postgresql://%s:%s/%s", 
connectionProperties.get("hostname"), connectionProperties.get("port"), 
DEFAULT_DATABASE);
-                       if (LOG.isDebugEnabled()) {
-                               LOG.debug("InitConnectionKerberos "+ url);
-                       }
-                       con = DriverManager.getConnection(url, userName, 
password);
-                       jdbc_url_template = 
String.format("jdbc:postgresql://%s:%s/%s", 
connectionProperties.get("hostname"), connectionProperties.get("port"), 
DEFAULT_DATABASE_TEMPLATE);
-               } catch (SQLException e) {
-                         e.printStackTrace();
-                 LOG.error("Unable to Connect to Hawq", e);
-                 throw e;
-               } catch (SecurityException se) {
-                       se.printStackTrace();
-               }
-       }
-
-       public void setConnection(Connection conn) {
-               con = conn;
-       }
-       
-       public void resetConnection(String db) throws SQLException{
-               try {
-                       if(db == null) {
-                               return;
-                       }
-                       String newdb = db;
-                       LOG.debug("resetconnectionbefore "+ jdbc_url_template + 
newdb);
-               String url = 
jdbc_url_template.replace(DEFAULT_DATABASE_TEMPLATE, newdb);
-               if (LOG.isDebugEnabled()) {
-                       LOG.debug("resetconnection "+ jdbc_url_template+ url);
-               }
-               if(con !=null && !con.isClosed()){
-                       con.close();
-               }
-               if (isKerberosAuth) {
-                       con = DriverManager.getConnection(url); 
-               } else {
-                       final String userName = getConfigHolder().getUserName();
-                       final String password = getConfigHolder().getPassword();
-                       con = DriverManager.getConnection(url, userName, 
password);
-               } 
-               } catch (SQLException e) {
-                       e.printStackTrace();
-                       LOG.error("Unable to Connect to Hawq", e);
-                       throw e;
-               } catch (SecurityException se) {
-                       se.printStackTrace();
-               }
-       }
+
+    /**
+     * clone a new Properties for debug logging:
+     *  1. remove password field for preventing plain password leak in log
+     *  2. add a _password_length field for debug
+     *
+     * @param connectionProperties
+     * @return a new cloned Map for debug logging
+     */
+    private Map<String, String> removePassword(Map<String, String> 
connectionProperties) {
+        Map<String, String> new_property = new HashMap<String, 
String>(connectionProperties);
+        if (new_property.containsKey("password")) {
+            String password = new_property.get("password");
+            new_property.remove("password");
+            new_property.put("_password_length", 
Integer.toString(password.length()));
+        }
+        return new_property;
+    }
+
+    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;
+        Properties props = new Properties();
+
+        if (LOG.isDebugEnabled()) {
+            Map<String, String> debugProperties = 
removePassword(connectionProperties);
+            LOG.debug("<== HawqClient.checkConnection configuration" + 
debugProperties );
+        }
+
+        if (connectionProperties.containsKey(AUTHENTICATION) && 
connectionProperties.get(AUTHENTICATION).equals(KERBEROS)) {
+            //kerberos mode
+            props.setProperty("kerberosServerName", 
connectionProperties.get("principal"));
+            props.setProperty("jaasApplicationName", "pgjdbc");
+        }
+
+
+        String url = String.format("jdbc:postgresql://%s:%s/%s", 
connectionProperties.get("hostname"), connectionProperties.get("port"), db);
+        props.setProperty("user", connectionProperties.get("username"));
+        props.setProperty("password", connectionProperties.get("password"));
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== HawqClient.checkConnection Connecting to: (" + url 
+ ") with user: " + connectionProperties.get("username"));
+        }
+
+        return DriverManager.getConnection(url, props);
+    }
+
 
     /**
      * Uses the connectionProperties and attempts to connect to Hawq.
@@ -230,8 +162,10 @@ public class HawqClient extends BaseClient {
             LOG.debug("<== HawqClient.checkConnection Starting connection to 
hawq");
         }
 
+        Connection conn = null;
         try {
-            if(con.getCatalog() != null) {
+            conn = getConnection(connectionProperties);
+            if (conn.getCatalog() != null) {
                 isConnected = true;
                 description = CONNECTION_SUCCESSFUL_MESSAGE;
             }
@@ -239,11 +173,12 @@ public class HawqClient extends BaseClient {
             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;
     }
 
@@ -258,7 +193,7 @@ public class HawqClient extends BaseClient {
     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)) {
+            if (protocol.startsWith(userInput) || userInput.equals(WILDCARD)) {
                 allProtocols.add(protocol);
             }
         }
@@ -270,7 +205,7 @@ public class HawqClient extends BaseClient {
         return queryHawqPerDb(userInput, resources.get("database"), 
SCHEMA_NAME, SCHEMA_LIST_QUERY);
     }
 
-    public List<String> getLanguageList(String userInput,  Map<String, 
List<String>> resources) throws SQLException {
+    public List<String> getLanguageList(String userInput, Map<String, 
List<String>> resources) throws SQLException {
         return queryHawqPerDb(userInput, resources.get("database"), 
LANGUAGE_NAME, LANGUAGE_LIST_QUERY);
     }
 
@@ -307,31 +242,30 @@ public class HawqClient extends BaseClient {
 
         PreparedStatement preparedStatement = null;
         ResultSet resultSet = null;
+        Connection conn = null;
 
         if (databases.contains(WILDCARD)) {
             databases = getDatabaseList(WILDCARD);
         }
 
-        if(con == null) {
-                       return new ArrayList<>(uniqueResults); 
-        }
-        for (String db: databases) {
-               resetConnection(db);
+        for (String db : databases) {
+
             if (LOG.isDebugEnabled()) {
                 LOG.debug("<== HawqClient.queryHawqPerDbAndSchema: Connecting 
to db: " + db);
             }
 
             try {
-                preparedStatement = handleWildcardPreparedStatement(userInput, 
query, con);
-                
+                conn = getConnection(connectionProperties, db);
+                preparedStatement = handleWildcardPreparedStatement(userInput, 
query, conn);
+
                 if (LOG.isDebugEnabled()) {
                     LOG.debug("<== HawqClient.queryHawqPerDbAndSchema Starting 
query: " + preparedStatement.toString());
                 }
-                
+
                 resultSet = preparedStatement.executeQuery();
-                while(resultSet.next()) {
-                               
if(schemas.contains(resultSet.getString(schemaColumnName)) || 
schemas.contains(WILDCARD)) {
-                                       
uniqueResults.add(resultSet.getString(resultColumnName));
+                while (resultSet.next()) {
+                    if 
(schemas.contains(resultSet.getString(schemaColumnName)) || 
schemas.contains(WILDCARD)) {
+                        
uniqueResults.add(resultSet.getString(resultColumnName));
                     }
                 }
 
@@ -344,23 +278,22 @@ public class HawqClient extends BaseClient {
             } finally {
                 closeResultSet(resultSet);
                 closeStatement(preparedStatement);
+                closeConnection(conn);
             }
+
         }
         return new ArrayList<>(uniqueResults);
     }
 
-    private List<String> queryHawq(String userInput, String columnName, String 
query, String database) throws SQLException{
+    private List<String> queryHawq(String userInput, String columnName, String 
query, String database) throws SQLException {
         List<String> result = new ArrayList<>();
         PreparedStatement preparedStatement = null;
         ResultSet resultSet = null;
+        Connection conn = null;
 
         try {
-            resetConnection(database);
-            if(con == null) {
-                       return result; 
-               }
-
-            preparedStatement = handleWildcardPreparedStatement(userInput, 
query, con);
+            conn = getConnection(connectionProperties, database);
+            preparedStatement = handleWildcardPreparedStatement(userInput, 
query, conn);
 
             if (LOG.isDebugEnabled()) {
                 LOG.debug("<== HawqClient.queryHawq Starting query: " + 
preparedStatement.toString());
@@ -368,7 +301,7 @@ public class HawqClient extends BaseClient {
 
             resultSet = preparedStatement.executeQuery();
 
-            while(resultSet.next()) {
+            while (resultSet.next()) {
                 result.add(resultSet.getString(columnName));
             }
 
@@ -382,6 +315,7 @@ public class HawqClient extends BaseClient {
         } finally {
             closeResultSet(resultSet);
             closeStatement(preparedStatement);
+            closeConnection(conn);
         }
 
         return result;
@@ -412,20 +346,11 @@ public class HawqClient extends BaseClient {
     private void closeConnection(Connection conn) {
         try {
             if (conn != null) {
-                       conn.close();
+                conn.close();
             }
         } catch (Exception e) {
             // ignore
         }
     }
-    
-       public void close() {
-               Subject.doAs(getLoginSubject(), new PrivilegedAction<Void>(){
-                       public Void run() {
-                               closeConnection(con);
-                               return null;
-                       }
-               });
-       }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/0580d090/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
index 6dc9cad..a90261d 100644
--- 
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
@@ -32,111 +32,104 @@ import java.util.Collections;
 
 public abstract class HawqResourceMgr {
 
-       private static final Logger LOG = 
Logger.getLogger(HawqResourceMgr.class);
-       
+    private static final Logger LOG = Logger.getLogger(HawqResourceMgr.class);
+
     public static List<String> getHawqResources(String serviceName, String 
serviceType, Map<String, String> configs,
                                                 ResourceLookupContext context) 
throws Exception {
-       final String userInput = context.getUserInput();
+        final String userInput = context.getUserInput();
         HawqResource hawqResource = 
HawqResource.valueOf(context.getResourceName().toUpperCase());
         final Map<String, List<String>> resources = context.getResources();
-        
+
         List<String> result = null;
         if (serviceName != null && userInput != null) {
-               try {
-                       
-                               if(LOG.isDebugEnabled()) {
-                                       LOG.debug("==> 
HawqResourceMgr.getHawqResources() UserInput: "+ userInput  + " configs: " + 
configs);
-                               }
-                               final HawqClient hawqClient =new 
HawqClient(serviceName, configs);
-                       Callable<List<String>> callableObj = null;
-                       
-                   if(hawqClient != null) {
-                           switch (hawqResource) {
-                               case DATABASE:
-                                       callableObj = new 
Callable<List<String>>() {
-                                                   @Override
-                                                   public List<String> call() 
throws SQLException{
-                                                   return 
hawqClient.getDatabaseList(userInput);
-                                                   }
-                                       };
-                                       break;
-                               case TABLESPACE:
-                                           callableObj = new 
Callable<List<String>>() {
-                                                       @Override
-                                                       public List<String> 
call() throws SQLException{
-                                                       return 
hawqClient.getTablespaceList(userInput);
-                                                       }
-                                           };
-                                           break;
-                               case PROTOCOL:
-                                           callableObj = new 
Callable<List<String>>() {
-                                                       @Override
-                                                       public List<String> 
call() throws SQLException{
-                                                       return 
hawqClient.getProtocolList(userInput);
-                                                       }
-                                           };
-                                           break;
-                               case SCHEMA:
-                                           callableObj = new 
Callable<List<String>>() {
-                                                       @Override
-                                                       public List<String> 
call() throws SQLException{
-                                                       return 
hawqClient.getSchemaList(userInput, resources);
-                                                       }
-                                           };
-                                           break;
-                               case LANGUAGE:
-                                           callableObj = new 
Callable<List<String>>() {
-                                                       @Override
-                                                       public List<String> 
call() throws SQLException{
-                                                       return 
hawqClient.getLanguageList(userInput, resources);
-                                                       }
-                                           };
-                                           break;
-                               case TABLE:
-                                           callableObj = new 
Callable<List<String>>() {
-                                                       @Override
-                                                       public List<String> 
call() throws SQLException{
-                                                       return 
hawqClient.getTableList(userInput, resources);
-                                                       }
-                                           };
-                                           break;
-                               case SEQUENCE:
-                                           callableObj = new 
Callable<List<String>>() {
-                                                       @Override
-                                                       public List<String> 
call() throws SQLException {
-                                                       return 
hawqClient.getSequenceList(userInput, resources);
-                                                       }
-                                           };
-                                           break;
-                               case FUNCTION:
-                                           callableObj = new 
Callable<List<String>>() {
-                                                       @Override
-                                                       public List<String> 
call() throws SQLException{
-                                                       return 
hawqClient.getFunctionList(userInput, resources);
-                                                       }
-                                           };
-                                           break;
-                                           default:
-                                               throw new 
IllegalArgumentException("Resource requested does not exist.");
-                                       }
-                       }
-                       
-                       if (callableObj != null) {
-                                       synchronized (hawqClient) {
-                                               result = 
TimedEventUtil.timedTask(callableObj, 5,
-                                                               
TimeUnit.SECONDS);
-                                       }
-                               } else {
-                                       LOG.error("Could not initiate at 
timedTask");
-                               }
-                     
-               
-                       Collections.sort(result);
-                       hawqClient.close();
-               } catch (Exception e) {
-                               LOG.error("Unable to get hive resources.", e);
-                               throw e;
-               }
+            try {
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("==> HawqResourceMgr.getHawqResources() 
UserInput: " + userInput);
+                }
+                final HawqClient hawqClient = new HawqClient(serviceName, 
configs);
+                Callable<List<String>> callableObj;
+
+                switch (hawqResource) {
+                    case DATABASE:
+                        callableObj = new Callable<List<String>>() {
+                            @Override
+                            public List<String> call() throws SQLException {
+                                return hawqClient.getDatabaseList(userInput);
+                            }
+                        };
+                        break;
+                    case TABLESPACE:
+                        callableObj = new Callable<List<String>>() {
+                            @Override
+                            public List<String> call() throws SQLException {
+                                return hawqClient.getTablespaceList(userInput);
+                            }
+                        };
+                        break;
+                    case PROTOCOL:
+                        callableObj = new Callable<List<String>>() {
+                            @Override
+                            public List<String> call() throws SQLException {
+                                return hawqClient.getProtocolList(userInput);
+                            }
+                        };
+                        break;
+                    case SCHEMA:
+                        callableObj = new Callable<List<String>>() {
+                            @Override
+                            public List<String> call() throws SQLException {
+                                return hawqClient.getSchemaList(userInput, 
resources);
+                            }
+                        };
+                        break;
+                    case LANGUAGE:
+                        callableObj = new Callable<List<String>>() {
+                            @Override
+                            public List<String> call() throws SQLException {
+                                return hawqClient.getLanguageList(userInput, 
resources);
+                            }
+                        };
+                        break;
+                    case TABLE:
+                        callableObj = new Callable<List<String>>() {
+                            @Override
+                            public List<String> call() throws SQLException {
+                                return hawqClient.getTableList(userInput, 
resources);
+                            }
+                        };
+                        break;
+                    case SEQUENCE:
+                        callableObj = new Callable<List<String>>() {
+                            @Override
+                            public List<String> call() throws SQLException {
+                                return hawqClient.getSequenceList(userInput, 
resources);
+                            }
+                        };
+                        break;
+                    case FUNCTION:
+                        callableObj = new Callable<List<String>>() {
+                            @Override
+                            public List<String> call() throws SQLException {
+                                return hawqClient.getFunctionList(userInput, 
resources);
+                            }
+                        };
+                        break;
+                    default:
+                        throw new IllegalArgumentException("Resource requested 
does not exist.");
+                }
+
+                synchronized (hawqClient) {
+                    result = TimedEventUtil.timedTask(callableObj, 5,
+                            TimeUnit.SECONDS);
+                }
+
+
+                Collections.sort(result);
+            } catch (Exception e) {
+                LOG.error("Unable to get Hawq resources.", e);
+                throw e;
+            }
         }
         return result;
     }

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/0580d090/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
index 9c1ccc8..967924a 100644
--- 
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
@@ -25,6 +25,7 @@ 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 org.apache.ranger.plugin.util.PasswordUtils;
 
 import java.util.*;
 
@@ -33,33 +34,38 @@ public class RangerServiceHawq extends RangerBaseService {
     private static final Log LOG = LogFactory.getLog(RangerServiceHawq.class);
 
     public RangerServiceHawq() {
-               super();
-       }
-       
-       @Override
-       public void init(RangerServiceDef serviceDef, RangerService service) {
-               super.init(serviceDef, service);
-       }
-       
+        super();
+    }
+
+    @Override
+    public void init(RangerServiceDef serviceDef, RangerService service) {
+        super.init(serviceDef, service);
+    }
+
     @Override
     public HashMap<String, Object> validateConfig() throws Exception {
         boolean isDebugEnabled = LOG.isDebugEnabled();
 
-        if(isDebugEnabled) {
+        if (isDebugEnabled) {
             LOG.debug("==> RangerServiceHawq.validateConfig Service: (hawq)");
         }
 
         HashMap<String, Object> result = new HashMap<>();
-        String         serviceName = getServiceName();
         if (configs != null) {
-            try  {
-                HawqClient hawqClient = new HawqClient(serviceName, configs);
-                result = hawqClient.checkConnection(configs);
-                hawqClient.close();
-            } catch (HadoopException e) {
-                LOG.error("<== RangerServiceHawq.validateConfig Error:" + e);
-                throw e;
+            boolean retry = false;
+
+            // try normal password (user input in RangerUI form)
+            result = checkConnection(configs);
+            if (result.containsKey("connectivityStatus") && 
!(boolean)(result.get("connectivityStatus"))) {
+                retry = true;
+            }
+
+            if (retry) {
+                // try decrypt password
+                decryptPassword(configs);
+                result = checkConnection(configs);
             }
+
         }
 
         if (isDebugEnabled) {
@@ -70,12 +76,44 @@ public class RangerServiceHawq extends RangerBaseService {
 
     @Override
     public List<String> lookupResource(ResourceLookupContext context) throws 
Exception {
-               String  serviceName = getServiceName();
-               String  serviceType = getServiceType();
-               
-        List<String> resources = HawqResourceMgr.getHawqResources(serviceName, 
serviceType, getConfigs(), context);
+        String serviceName = getServiceName();
+        String serviceType = getServiceType();
+
+        // lookup always need decrypt password (fetch from database)
+        decryptPassword(configs);
+
+        List<String> resources = HawqResourceMgr.getHawqResources(serviceName, 
serviceType, configs, context);
 
         return resources;
     }
 
+    private HashMap<String, Object> checkConnection(Map<String, String> 
configs) throws Exception {
+        HashMap<String, Object> result;
+        String serviceName = getServiceName();
+
+        try {
+            HawqClient hawqClient = new HawqClient(serviceName, configs);
+            result = hawqClient.checkConnection(configs);
+        } catch (HadoopException e) {
+            LOG.error("<== RangerServiceHawq.validateConfig Error:" + e);
+            throw e;
+        }
+
+        return result;
+    }
+
+    private void decryptPassword(Map<String, String> configs) throws Exception 
{
+        if (configs.containsKey("password")) {
+            String normal_password = configs.get("password");
+            try {
+                normal_password = 
PasswordUtils.decryptPassword(normal_password);
+            }
+            catch (java.io.IOException e) {
+                // when decrypt failed do nothing
+                LOG.warn("decrypt_password failed: " + e);
+            }
+            configs.put("password", normal_password);
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/0580d090/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
index be3be17..9b288f9 100644
--- 
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
@@ -27,20 +27,23 @@ 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.*;
-import static 
org.powermock.api.support.membermodification.MemberMatcher.method;
-import static 
org.powermock.api.support.membermodification.MemberModifier.suppress;
 
 @RunWith(PowerMockRunner.class)
 @PrepareForTest(HawqClient.class)
@@ -68,11 +71,10 @@ public class HawqClientTest {
         connectionProperties.put("username", "username");
         connectionProperties.put("password", "password");
 
+        mockStatic(DriverManager.class);
         suppress(constructor(BaseClient.class, String.class, Map.class));
-        suppress(method(HawqClient.class, "initHawq"));
-        suppress(method(HawqClient.class, "resetConnection"));
         hawqClient = new HawqClient("hawq", connectionProperties);
-        hawqClient.setConnection(conn);
+
         hawqClientSpy = PowerMockito.spy(hawqClient);
 
         resources = new HashMap<>();
@@ -84,6 +86,7 @@ public class HawqClientTest {
 
     @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"));
@@ -92,6 +95,7 @@ public class HawqClientTest {
 
     @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"));
@@ -100,8 +104,8 @@ public class HawqClientTest {
 
     @Test
     public void testCheckConnection_ThrowsSQLException_Failure() throws 
Exception {
-               when(conn.getCatalog()).thenThrow(new SQLException("Failed to 
connect"));
-               Map<String, Object> response = 
hawqClient.checkConnection(connectionProperties);
+        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"));
@@ -113,6 +117,7 @@ public class HawqClientTest {
         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"));
     }
 
@@ -163,6 +168,7 @@ public class HawqClientTest {
 
     @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);
@@ -175,6 +181,7 @@ public class HawqClientTest {
 
     @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);
@@ -187,6 +194,7 @@ public class HawqClientTest {
 
     @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);
@@ -197,6 +205,7 @@ public class HawqClientTest {
 
     @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);

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/0580d090/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
index 7ef3096..5264929 100644
--- 
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
@@ -18,7 +18,6 @@
 package org.apache.hawq.ranger.service;
 
 import org.apache.ranger.plugin.client.BaseClient;
-import org.apache.hawq.ranger.service.HawqClient;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -26,25 +25,25 @@ import org.mockito.Mock;
 import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
-import static org.powermock.api.mockito.PowerMockito.*;
+
 import java.sql.Connection;
 import java.sql.DriverManager;
 import java.util.HashMap;
 import java.util.Map;
-import static org.mockito.Matchers.*;
+import java.util.Properties;
 
-import static 
org.powermock.api.support.membermodification.MemberMatcher.method;
 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, RangerServiceHawq.class})
+@PrepareForTest(HawqClient.class)
 public class RangerServiceHawqTest {
 
     private RangerServiceHawq service;
@@ -54,8 +53,6 @@ public class RangerServiceHawqTest {
     HawqClient mockHawqClient;
     @Mock
     Connection conn;
-    
-    private Map<String, String> connectionProperties;
 
     @Before
     public void setup() {
@@ -76,18 +73,13 @@ public class RangerServiceHawqTest {
 
     @Test
     public void testValidateConfigSuccess() throws Exception {
-               suppress(constructor(BaseClient.class, String.class, 
Map.class));
-               suppress(method(HawqClient.class, "initHawq"));
-           
         HashMap<String, Object> result = new HashMap<>();
         result.put("message", "ConnectionTest Successful");
         result.put("description", "ConnectionTest Successful");
         result.put("connectivityStatus", true);
-        
-        mockHawqClient = new HawqClient("hawq", connectionProperties);
-        mockHawqClient.setConnection(conn);
-        
PowerMockito.whenNew(HawqClient.class).withArguments(anyObject(),anyObject()).thenReturn(mockHawqClient);
-        
+
+        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();


Reply via email to