RANGER-504: Fixed KMS Client to handle multiple KMS instances in URL

Signed-off-by: sneethiraj <[email protected]>


Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/14ec7d52
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/14ec7d52
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/14ec7d52

Branch: refs/heads/ranger-0.5
Commit: 14ec7d526b344a597f81b31613416c383c94f467
Parents: 0421271
Author: Velmurugan Periasamy <[email protected]>
Authored: Fri May 22 20:15:03 2015 -0400
Committer: sneethiraj <[email protected]>
Committed: Fri May 22 20:24:41 2015 -0400

----------------------------------------------------------------------
 .../ranger/services/kms/client/KMSClient.java   | 306 +++++++++++------
 .../java/org/apache/ranger/biz/KmsKeyMgr.java   | 331 ++++++++++++++-----
 2 files changed, 457 insertions(+), 180 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/14ec7d52/plugin-kms/src/main/java/org/apache/ranger/services/kms/client/KMSClient.java
----------------------------------------------------------------------
diff --git 
a/plugin-kms/src/main/java/org/apache/ranger/services/kms/client/KMSClient.java 
b/plugin-kms/src/main/java/org/apache/ranger/services/kms/client/KMSClient.java
index 60e9bd3..59fa634 100755
--- 
a/plugin-kms/src/main/java/org/apache/ranger/services/kms/client/KMSClient.java
+++ 
b/plugin-kms/src/main/java/org/apache/ranger/services/kms/client/KMSClient.java
@@ -19,17 +19,25 @@
 
 package org.apache.ranger.services.kms.client;
 
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.regex.Pattern;
 
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.security.ProviderUtils;
 import org.apache.log4j.Logger;
 import org.apache.ranger.plugin.client.BaseClient;
 import org.apache.ranger.plugin.client.HadoopException;
 import org.apache.ranger.services.kms.client.KMSClient;
 
+import com.google.common.base.Strings;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.sun.jersey.api.client.Client;
@@ -38,122 +46,209 @@ import com.sun.jersey.api.client.WebResource;
 
 public class KMSClient {
 
-       public static final Logger LOG = Logger.getLogger(KMSClient.class) ;
+       public static final Logger LOG = Logger.getLogger(KMSClient.class);
 
        private static final String EXPECTED_MIME_TYPE = "application/json";
-       
-       private static final String KMS_LIST_API_ENDPOINT = 
"v1/keys/names?user.name=${userName}";                      //GET
-       
-       private static final String errMessage =  " You can still save the 
repository and start creating "
-                                                                               
          + "policies, but you would not be able to use autocomplete for "
-                                                                               
          + "resource names. Check xa_portal.log for more info.";
-       
+
+       private static final String KMS_LIST_API_ENDPOINT = 
"v1/keys/names?user.name=${userName}"; // GET
+
+       private static final String errMessage = " You can still save the 
repository and start creating "
+                       + "policies, but you would not be able to use 
autocomplete for "
+                       + "resource names. Check xa_portal.log for more info.";
+
        String provider;
        String username;
        String password;
 
-       public  KMSClient(String provider, String username, String password) {
-               provider = provider.replaceAll("kms://","");
-               provider = provider.replaceAll("http@","http://";);              
+       public KMSClient(String provider, String username, String password) {
                this.provider = provider;
-               this.username = username ;
+               this.username = username;
                this.password = password;
-               
+
                if (LOG.isDebugEnabled()) {
-                       LOG.debug("Kms Client is build with url [" + provider + 
"] user: [" + username + "]");
-               }               
+                       LOG.debug("Kms Client is build with url [" + provider + 
"] user: ["
+                                       + username + "]");
+               }
+       }
+
+       private String[] createProvider(String uri) throws IOException,
+                       URISyntaxException {
+               URI providerUri = new URI(uri);
+               URL origUrl = new URL(extractKMSPath(providerUri).toString());
+               String authority = origUrl.getAuthority();
+               // check for ';' which delimits the backup hosts
+               if (Strings.isNullOrEmpty(authority)) {
+                       throw new IOException("No valid authority in kms uri [" 
+ origUrl
+                                       + "]");
+               }
+               // Check if port is present in authority
+               // In the current scheme, all hosts have to run on the same port
+               int port = -1;
+               String hostsPart = authority;
+               if (authority.contains(":")) {
+                       String[] t = authority.split(":");
+                       try {
+                               port = Integer.parseInt(t[1]);
+                       } catch (Exception e) {
+                               throw new IOException("Could not parse port in 
kms uri ["
+                                               + origUrl + "]");
+                       }
+                       hostsPart = t[0];
+               }
+               return createProvider(providerUri, origUrl, port, hostsPart);
+       }
+
+       private static Path extractKMSPath(URI uri) throws 
MalformedURLException,
+                       IOException {
+               return ProviderUtils.unnestUri(uri);
        }
-       
-       public List<String> getKeyList(final String keyNameMatching, final 
List<String> existingKeyList) {
+
+       private String[] createProvider(URI providerUri, URL origUrl, int port,
+                       String hostsPart) throws IOException {
+               String[] hosts = hostsPart.split(";");
+               String[] providers = new String[hosts.length];
+               if (hosts.length == 1) {
+                       providers[0] = origUrl.toString();
+               } else {
+                       for (int i = 0; i < hosts.length; i++) {
+                               try {
+                                       String url = origUrl.getProtocol() + 
"://" + hosts[i] + ":"
+                                                       + port + 
origUrl.getPath();
+                                       providers[i] = new URI(url).toString();
+                               } catch (URISyntaxException e) {
+                                       throw new IOException("Could not Prase 
KMS URL..", e);
+                               }
+                       }
+               }
+               return providers;
+       }
+
+       public List<String> getKeyList(final String keyNameMatching,
+                       final List<String> existingKeyList) {
                
-               if (LOG.isDebugEnabled()) {
-                       LOG.debug("Getting Kms Key list for keyNameMatching : " 
+ keyNameMatching);
+               String providers[] = null;
+               try {
+                       providers = createProvider(provider);
+               } catch (IOException | URISyntaxException e) {
+                       return null;
                }
                final String errMsg = errMessage;
-               List<String> lret = new ArrayList<String>();                    
        
-               String keyLists = 
KMS_LIST_API_ENDPOINT.replaceAll(Pattern.quote("${userName}"), username);
-               String uri = provider + (provider.endsWith("/") ? keyLists : 
("/" + keyLists));         
-               Client client = null ;
-               ClientResponse response = null ;
-                               
-               try {
-                       client = Client.create() ;
-                       
-                       WebResource webResource = client.resource(uri);
-                       
-                       response = 
webResource.accept(EXPECTED_MIME_TYPE).get(ClientResponse.class);
-                       
+               List<String> lret = null;
+               for (int i = 0; i < providers.length; i++) {
+                       lret  = new ArrayList<String>();
                        if (LOG.isDebugEnabled()) {
-                               LOG.debug("getKeyList():calling " + uri);
+                               LOG.debug("Getting Kms Key list for 
keyNameMatching : "
+                                               + keyNameMatching);
                        }
-                       
-                       if (response != null) {
+                       String keyLists = KMS_LIST_API_ENDPOINT.replaceAll(
+                                       Pattern.quote("${userName}"), username);
+                       String uri = providers[i]
+                                       + (providers[i].endsWith("/") ? 
keyLists : ("/" + keyLists));
+                       Client client = null;
+                       ClientResponse response = null;
+
+                       try {
+                               client = Client.create();
+
+                               WebResource webResource = client.resource(uri);
+
+                               response = 
webResource.accept(EXPECTED_MIME_TYPE).get(
+                                               ClientResponse.class);
+
                                if (LOG.isDebugEnabled()) {
-                                       
LOG.debug("getKeyList():response.getStatus()= " + response.getStatus());        
+                                       LOG.debug("getKeyList():calling " + 
uri);
                                }
-                               if (response.getStatus() == 200) {
-                                       String jsonString = 
response.getEntity(String.class);
-                                       Gson gson = new 
GsonBuilder().setPrettyPrinting().create();
-                                       @SuppressWarnings("unchecked")
-                                       List<String> keys = 
gson.fromJson(jsonString, List.class) ;                                     
-                                       if (keys != null) {
-                                               for ( String key : keys) {
-                                                       if ( existingKeyList != 
null && existingKeyList.contains(key)) {
-                                                               continue;
-                                                       }
-                                                               if 
(keyNameMatching == null || keyNameMatching.isEmpty() || 
key.startsWith(keyNameMatching)) {
-                                                                               
if (LOG.isDebugEnabled()) {
-                                                                               
        LOG.debug("getKeyList():Adding kmsKey " + key);
-                                                                               
}
-                                                                               
lret.add(key) ;
+                               if (response != null) {
+                                       if (LOG.isDebugEnabled()) {
+                                               
LOG.debug("getKeyList():response.getStatus()= "
+                                                               + 
response.getStatus());
+                                       }
+                                       if (response.getStatus() == 200) {
+                                               String jsonString = 
response.getEntity(String.class);
+                                               Gson gson = new 
GsonBuilder().setPrettyPrinting()
+                                                               .create();
+                                               @SuppressWarnings("unchecked")
+                                               List<String> keys = 
gson.fromJson(jsonString,
+                                                               List.class);
+                                               if (keys != null) {
+                                                       for (String key : keys) 
{
+                                                               if 
(existingKeyList != null
+                                                                               
&& existingKeyList.contains(key)) {
+                                                                       
continue;
+                                                               }
+                                                               if 
(keyNameMatching == null
+                                                                               
|| keyNameMatching.isEmpty()
+                                                                               
|| key.startsWith(keyNameMatching)) {
+                                                                       if 
(LOG.isDebugEnabled()) {
+                                                                               
LOG.debug("getKeyList():Adding kmsKey "
+                                                                               
                + key);
                                                                        }
+                                                                       
lret.add(key);
+                                                               }
                                                        }
-                                               }                               
                        
-                                }else if (response.getStatus() == 401) {
-                                        
LOG.info("getKeyList():response.getStatus()= " + response.getStatus() + " for 
URL " + uri + ", so returning null list");
-                                        return lret;
-                                }else if (response.getStatus() == 403) {
-                                        
LOG.info("getKeyList():response.getStatus()= " + response.getStatus() + " for 
URL " + uri + ", so returning null list");
-                                        return lret;
-                                }else {
-                                        
LOG.info("getKeyList():response.getStatus()= " + response.getStatus() + " for 
URL " + uri + ", so returning null list");       
-                                        String jsonString = 
response.getEntity(String.class);
-                                        LOG.info(jsonString);
-                                        lret = null;
+                                                       return lret;
+                                               }                               
                
+                                       } else if (response.getStatus() == 401) 
{
+                                               
LOG.info("getKeyList():response.getStatus()= "
+                                                               + 
response.getStatus() + " for URL " + uri
+                                                               + ", so 
returning null list");
+                                               return lret;
+                                       } else if (response.getStatus() == 403) 
{
+                                               
LOG.info("getKeyList():response.getStatus()= "
+                                                               + 
response.getStatus() + " for URL " + uri
+                                                               + ", so 
returning null list");
+                                               return lret;
+                                       } else {
+                                               
LOG.info("getKeyList():response.getStatus()= "
+                                                               + 
response.getStatus() + " for URL " + uri
+                                                               + ", so 
returning null list");
+                                               String jsonString = 
response.getEntity(String.class);
+                                               LOG.info(jsonString);
+                                               lret = null;
+                                       }
+                               } else {
+                                       String msgDesc = "Unable to get a valid 
response for "
+                                                       + "expected mime type : 
[" + EXPECTED_MIME_TYPE
+                                                       + "] URL : " + uri + " 
- got null response.";
+                                       LOG.error(msgDesc);
+                                       HadoopException hdpException = new 
HadoopException(msgDesc);
+                                       
hdpException.generateResponseDataMap(false, msgDesc,
+                                                       msgDesc + errMsg, null, 
null);
+                                       lret = null;
+                                       throw hdpException;
                                }
-                       }else {
-                               String msgDesc = "Unable to get a valid 
response for "
-                                               + "expected mime type : [" + 
EXPECTED_MIME_TYPE
-                                               + "] URL : " + uri + " - got 
null response.";
-                               LOG.error(msgDesc);
-                               HadoopException hdpException = new 
HadoopException(msgDesc);
-                               hdpException.generateResponseDataMap(false, 
msgDesc, msgDesc + errMsg, null, null);
+                       } catch (HadoopException he) {
+                               lret = null;
+                               throw he;
+                       } catch (Throwable t) {
+                               String msgDesc = "Exception while getting Kms 
Key List. URL : "
+                                               + uri;
+                               HadoopException hdpException = new 
HadoopException(msgDesc, t);
+                               LOG.error(msgDesc, t);
+                               hdpException.generateResponseDataMap(false,
+                                               BaseClient.getMessage(t), 
msgDesc + errMsg, null, null);
                                lret = null;
                                throw hdpException;
-                       }
-               } catch (HadoopException he) {
-                       lret = null;
-                       throw he;
-               }catch (Throwable t) {
-                       String msgDesc = "Exception while getting Kms Key List. 
URL : " + uri;
-                       HadoopException hdpException = new 
HadoopException(msgDesc, t);
-                       LOG.error(msgDesc, t);
-                       hdpException.generateResponseDataMap(false, 
BaseClient.getMessage(t), msgDesc + errMsg, null, null);
-                       lret = null;
-                       throw hdpException;                                     
-               } finally {
-                       if (response != null) {
-                               response.close();
-                       }
-                       
-                       if (client != null) {
-                               client.destroy(); 
-                       }                               
+                       } finally {
+                               if (response != null) {
+                                       response.close();
+                               }
+
+                               if (client != null) {
+                                       client.destroy();
+                               }
+                               
+                               if(lret == null){
+                                       if (i != providers.length - 1)
+                                               continue;                       
                
+                               }
+                       }                       
                }
-               return lret ;                   
+               return lret;
        }
-               
-       public static HashMap<String, Object> testConnection(String 
serviceName, Map<String, String> configs) {
+
+       public static HashMap<String, Object> testConnection(String serviceName,
+                       Map<String, String> configs) {
 
                List<String> strList = new ArrayList<String>();
                String errMsg = errMessage;
@@ -170,7 +265,7 @@ public class KMSClient {
                        BaseClient.generateResponseDataMap(connectivityStatus, 
successMsg,
                                        successMsg, null, null, responseData);
                } else {
-                       String failureMsg = "Unable to retrieve any Kms Key 
using given parameters.";
+                       String failureMsg = "Unable to retrieve any Kms Key 
using given URL.";
                        BaseClient.generateResponseDataMap(connectivityStatus, 
failureMsg,
                                        failureMsg + errMsg, null, null, 
responseData);
                }
@@ -194,17 +289,17 @@ public class KMSClient {
                                        + errMsg, null, null);
                        throw hdpException;
                } else {
-                       String kmsUrl           = configs.get("provider");
+                       String kmsUrl = configs.get("provider");
                        String kmsUserName = configs.get("username");
                        String kmsPassWord = configs.get("password");
-                       kmsClient                       = new KMSClient 
(kmsUrl, kmsUserName,
-                                                                               
                  kmsPassWord);
-       
+                       kmsClient = new KMSClient(kmsUrl, kmsUserName, 
kmsPassWord);
+
                }
                return kmsClient;
        }
 
-       public static List<String> getKmsKey (final KMSClient kmsClient, String 
keyName, List<String> existingKeyName) {
+       public static List<String> getKmsKey(final KMSClient kmsClient,
+                       String keyName, List<String> existingKeyName) {
 
                List<String> resultList = new ArrayList<String>();
                String errMsg = errMessage;
@@ -221,10 +316,12 @@ public class KMSClient {
 
                        if (keyName != null) {
                                String finalkmsKeyName = keyName.trim();
-                               resultList = 
kmsClient.getKeyList(finalkmsKeyName,existingKeyName);
+                               resultList = 
kmsClient.getKeyList(finalkmsKeyName,
+                                               existingKeyName);
                                if (resultList != null) {
                                        if (LOG.isDebugEnabled()) {
-                                               LOG.debug("Returning list of " 
+ resultList.size() + " Kms Keys");
+                                               LOG.debug("Returning list of " 
+ resultList.size()
+                                                               + " Kms Keys");
                                        }
                                }
                        }
@@ -232,13 +329,14 @@ public class KMSClient {
                        resultList = null;
                        throw he;
                } catch (Exception e) {
-                       String msgDesc = "Unable to get a valid response from 
the provider";
+                       String msgDesc = "Unable to get a valid response from 
the provider : "+e.getMessage();
                        LOG.error(msgDesc, e);
                        HadoopException hdpException = new 
HadoopException(msgDesc);
-                       hdpException.generateResponseDataMap(false, msgDesc, 
msgDesc + errMsg, null, null);
+                       hdpException.generateResponseDataMap(false, msgDesc, 
msgDesc
+                                       + errMsg, null, null);
                        resultList = null;
                        throw hdpException;
                }
                return resultList;
-       }       
-}
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/14ec7d52/security-admin/src/main/java/org/apache/ranger/biz/KmsKeyMgr.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/KmsKeyMgr.java 
b/security-admin/src/main/java/org/apache/ranger/biz/KmsKeyMgr.java
index 5f2d4af..7446d1e 100755
--- a/security-admin/src/main/java/org/apache/ranger/biz/KmsKeyMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/KmsKeyMgr.java
@@ -19,9 +19,15 @@
 
 package org.apache.ranger.biz;
 
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.regex.Pattern;
 
 import javax.servlet.http.HttpServletRequest;
@@ -32,6 +38,8 @@ import org.apache.commons.collections.MapUtils;
 import org.apache.commons.collections.Predicate;
 import org.apache.commons.collections.PredicateUtils;
 import org.apache.commons.lang.StringUtils;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.security.ProviderUtils;
 import org.apache.log4j.Logger;
 import org.apache.ranger.common.ContextUtil;
 import org.apache.ranger.common.MessageEnums;
@@ -46,10 +54,11 @@ import org.apache.ranger.view.VXKmsKeyList;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import com.google.common.base.Strings;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.sun.jersey.api.client.Client;
-import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.UniformInterfaceException;
 import com.sun.jersey.api.client.WebResource;
 import com.sun.jersey.api.client.config.ClientConfig;
 import com.sun.jersey.api.client.config.DefaultClientConfig;
@@ -65,6 +74,8 @@ public class KmsKeyMgr {
        private static final String KMS_DELETE_KEY_URI          = 
"v1/key/${alias}?user.name=${userName}";                      //DELETE
        private static final String KMS_KEY_METADATA_URI        = 
"v1/key/${alias}/_metadata?user.name=${userName}";  //GET
        private static final String KMS_URL_CONFIG                      = 
"provider"; 
+       private static Map<String, String> providerList = new HashMap<String, 
String>(); 
+       private static int nextProvider = 0;
        
        @Autowired
        ServiceDBStore svcStore;        
@@ -75,28 +86,46 @@ public class KmsKeyMgr {
        @Autowired
        RangerConfigUtil configUtil;
        
+       @SuppressWarnings("unchecked")
        public VXKmsKeyList searchKeys(String repoName){
-               String provider = null;
+               String providers[] = null;
                try {
-                       provider = getKMSURL(repoName);
+                       providers = getKMSURL(repoName);
                } catch (Exception e) {
                        logger.error("getKey(" + repoName + ") failed", e);
                }
-               Client c = getClient() ;
-               String currentUserLoginId = ContextUtil.getCurrentUserLoginId();
-               String keyLists = 
KMS_KEY_LIST_URI.replaceAll(Pattern.quote("${userName}"), currentUserLoginId);
-               String uri = provider + (provider.endsWith("/") ? keyLists : 
("/" + keyLists));         
+               List<VXKmsKey> vXKeys = new ArrayList<VXKmsKey>();
                VXKmsKeyList vxKmsKeyList = new VXKmsKeyList();
-               WebResource r = c.resource(uri) ;
-               String response = 
r.accept(MediaType.APPLICATION_JSON_TYPE).get(String.class);
-               Gson gson = new GsonBuilder().create() ;
-               logger.debug(" Search Key RESPONSE: [" + response + "]") ;
-               List<VXKmsKey> vXKeys = new ArrayList<VXKmsKey>();          
-               @SuppressWarnings("unchecked")
-               List<String> keys = gson.fromJson(response, List.class) ;
-               if(keys != null && keys.size() > 0){
-                       for(String name : keys){
-                               VXKmsKey key = getKey(repoName, name);
+               List<String> keys = null;
+               String connProvider = null;
+               for (int i = 0; i < providers.length; i++) {
+                       Client c = getClient();
+                       String currentUserLoginId = 
ContextUtil.getCurrentUserLoginId();
+                       String keyLists = KMS_KEY_LIST_URI.replaceAll(
+                                       Pattern.quote("${userName}"), 
currentUserLoginId);
+                       connProvider = providers[i];
+                       String uri = providers[i]
+                                       + (providers[i].endsWith("/") ? 
keyLists : ("/" + keyLists));
+
+                       WebResource r = c.resource(uri);
+                       try {
+                               String response = 
r.accept(MediaType.APPLICATION_JSON_TYPE)
+                                               .get(String.class);
+                               Gson gson = new GsonBuilder().create();
+                               logger.debug(" Search Key RESPONSE: [" + 
response + "]");
+
+                               keys = gson.fromJson(response, List.class);
+                               break;
+                       } catch (Exception e) {
+                               if (e instanceof UniformInterfaceException || i 
== providers.length - 1)
+                                       throw e;                                
                                
+                               else
+                                       continue;
+                       }
+               }
+               if (keys != null && keys.size() > 0) {
+                       for (String name : keys) {
+                               VXKmsKey key = getKeyFromUri(connProvider, 
name);
                                vXKeys.add(key);
                        }
                        vxKmsKeyList.setResultSize(vXKeys.size());
@@ -105,102 +134,252 @@ public class KmsKeyMgr {
                        vxKmsKeyList.setPageSize(vXKeys.size());
                }
                vxKmsKeyList.setVXKeys(vXKeys);
-           return vxKmsKeyList;
+               return vxKmsKeyList;
        }
 
        public VXKmsKey rolloverKey(String provider, VXKmsKey vXKey){
+               String providers[] = null;
                try {
-                       provider = getKMSURL(provider);
+                       providers = getKMSURL(provider);
                } catch (Exception e) {
-                       logger.error("rolloverKey(" + provider + ", "+ 
vXKey.getName() +") failed", e);
+                       logger.error("rolloverKey(" + provider + ", " + 
vXKey.getName()
+                                       + ") failed", e);
                }
-               VXKmsKey ret = null ;
-               Client c = getClient() ;
-               String rollRest = 
KMS_ROLL_KEY_URI.replaceAll(Pattern.quote("${alias}"), vXKey.getName());
-               String currentUserLoginId = ContextUtil.getCurrentUserLoginId();
-               rollRest = rollRest.replaceAll(Pattern.quote("${userName}"), 
currentUserLoginId);
-               String uri = provider + (provider.endsWith("/") ? rollRest : 
("/" + rollRest));
-               WebResource r = c.resource(uri) ;
-               Gson gson = new GsonBuilder().create() ;
-               String jsonString = gson.toJson(vXKey) ;
-               String response = 
r.accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).post(String.class,
 jsonString) ;
-               logger.debug("Roll RESPONSE: [" + response + "]") ;
-               ret = gson.fromJson(response, VXKmsKey.class) ;
-               return ret ;
+               VXKmsKey ret = null;
+               for (int i = 0; i < providers.length; i++) {
+                       Client c = getClient();
+                       String rollRest = KMS_ROLL_KEY_URI.replaceAll(
+                                       Pattern.quote("${alias}"), 
vXKey.getName());
+                       String currentUserLoginId = 
ContextUtil.getCurrentUserLoginId();
+                       rollRest = 
rollRest.replaceAll(Pattern.quote("${userName}"),
+                                       currentUserLoginId);
+                       String uri = providers[i]
+                                       + (providers[i].endsWith("/") ? 
rollRest : ("/" + rollRest));
+                       WebResource r = c.resource(uri);
+                       Gson gson = new GsonBuilder().create();
+                       String jsonString = gson.toJson(vXKey);
+                       try {
+                               String response = 
r.accept(MediaType.APPLICATION_JSON_TYPE)
+                                               
.type(MediaType.APPLICATION_JSON_TYPE)
+                                               .post(String.class, jsonString);
+                               logger.debug("Roll RESPONSE: [" + response + 
"]");
+                               ret = gson.fromJson(response, VXKmsKey.class);
+                               break;
+                       } catch (Exception e) {
+                               if (e instanceof UniformInterfaceException || i 
== providers.length - 1)
+                                       throw e;                                
                                
+                               else
+                                       continue;
+                       }
+               }
+               return ret;
        }
 
        public void deleteKey(String provider, String name){
+               String providers[] = null;
                try {
-                       provider = getKMSURL(provider);
+                       providers = getKMSURL(provider);
                } catch (Exception e) {
-                       logger.error("deleteKey(" + provider + ", "+ name +") 
failed", e);
+                       logger.error("deleteKey(" + provider + ", " + name + ") 
failed", e);
                }
-               Client c = getClient() ;
-               String deleteRest = 
KMS_DELETE_KEY_URI.replaceAll(Pattern.quote("${alias}"), name);
-               String currentUserLoginId = ContextUtil.getCurrentUserLoginId();
-               deleteRest = 
deleteRest.replaceAll(Pattern.quote("${userName}"), currentUserLoginId);
-               String uri = provider + (provider.endsWith("/") ? deleteRest : 
("/" + deleteRest));
-               WebResource r = c.resource(uri) ;
-               String response = r.delete(String.class) ;
-               logger.debug("delete RESPONSE: [" + response + "]") ;           
        
+               for (int i = 0; i < providers.length; i++) {
+                       Client c = getClient();
+                       String deleteRest = KMS_DELETE_KEY_URI.replaceAll(
+                                       Pattern.quote("${alias}"), name);
+                       String currentUserLoginId = 
ContextUtil.getCurrentUserLoginId();
+                       deleteRest = 
deleteRest.replaceAll(Pattern.quote("${userName}"),
+                                       currentUserLoginId);
+                       String uri = providers[i]
+                                       + (providers[i].endsWith("/") ? 
deleteRest
+                                                       : ("/" + deleteRest));
+                       WebResource r = c.resource(uri);
+                       try {
+                               String response = r.delete(String.class) ;
+                               logger.debug("delete RESPONSE: [" + response + 
"]") ;   
+                               break;
+                       } catch (Exception e) {
+                               if (e instanceof UniformInterfaceException || i 
== providers.length - 1)
+                                       throw e;                                
                                
+                               else
+                                       continue;
+                       }
+               }                       
        }
 
        public VXKmsKey createKey(String provider, VXKmsKey vXKey){
+               String providers[] = null;
                try {
-                       provider = getKMSURL(provider);
+                       providers = getKMSURL(provider);
                } catch (Exception e) {
-                       logger.error("createKey(" + provider + ", "+ 
vXKey.getName() +") failed", e);
+                       logger.error("createKey(" + provider + ", " + 
vXKey.getName()
+                                       + ") failed", e);
                }
-               VXKmsKey ret = null ;
-               Client c = getClient() ;
-               String currentUserLoginId = ContextUtil.getCurrentUserLoginId();
-               String createRest = 
KMS_ADD_KEY_URI.replaceAll(Pattern.quote("${userName}"), currentUserLoginId);
-               String uri = provider + (provider.endsWith("/") ? createRest : 
("/" + createRest));
-               WebResource r = c.resource(uri) ;
-               Gson gson = new GsonBuilder().create() ;
-               String jsonString = gson.toJson(vXKey) ;
-        String response = 
r.accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).post(String.class,
 jsonString) ;
-        logger.debug("Create RESPONSE: [" + response + "]") ;
-        ret = gson.fromJson(response, VXKmsKey.class) ;
-           return ret ;                
+               VXKmsKey ret = null;
+               for (int i = 0; i < providers.length; i++) {
+                       Client c = getClient();
+                       String currentUserLoginId = 
ContextUtil.getCurrentUserLoginId();
+                       String createRest = KMS_ADD_KEY_URI.replaceAll(
+                                       Pattern.quote("${userName}"), 
currentUserLoginId);
+                       String uri = providers[i]
+                                       + (providers[i].endsWith("/") ? 
createRest
+                                                       : ("/" + createRest));
+                       WebResource r = c.resource(uri);
+                       Gson gson = new GsonBuilder().create();
+                       String jsonString = gson.toJson(vXKey);
+                       try {
+                               String response = 
r.accept(MediaType.APPLICATION_JSON_TYPE)
+                                               
.type(MediaType.APPLICATION_JSON_TYPE)
+                                               .post(String.class, jsonString);
+                               logger.debug("Create RESPONSE: [" + response + 
"]");
+                               ret = gson.fromJson(response, VXKmsKey.class);
+                               return ret;
+                       } catch (Exception e) {
+                               if (e instanceof UniformInterfaceException || i 
== providers.length - 1)
+                                       throw e;                                
                                
+                               else
+                                       continue;
+                       }
+               }
+               return ret;     
        }
        
        public VXKmsKey getKey(String provider, String name){
+               String providers[] = null;
                try {
-                       provider = getKMSURL(provider);
+                       providers = getKMSURL(provider);
                } catch (Exception e) {
-                       logger.error("getKey(" + provider + ", "+ name +") 
failed", e);
+                       logger.error("getKey(" + provider + ", " + name + ") 
failed", e);
+               }
+               for (int i = 0; i < providers.length; i++) {
+                       Client c = getClient();
+                       String keyRest = KMS_KEY_METADATA_URI.replaceAll(
+                                       Pattern.quote("${alias}"), name);
+                       String currentUserLoginId = 
ContextUtil.getCurrentUserLoginId();
+                       keyRest = 
keyRest.replaceAll(Pattern.quote("${userName}"),
+                                       currentUserLoginId);
+                       String uri = providers[i]
+                                       + (providers[i].endsWith("/") ? keyRest 
: ("/" + keyRest));
+                       WebResource r = c.resource(uri);
+                       try {
+                               String response = 
r.accept(MediaType.APPLICATION_JSON_TYPE)
+                                               .get(String.class);
+                               Gson gson = new GsonBuilder().create();
+                               logger.debug("RESPONSE: [" + response + "]");
+                               VXKmsKey key = gson.fromJson(response, 
VXKmsKey.class);
+                               return key;
+                       } catch (Exception e) {
+                               if (e instanceof UniformInterfaceException || i 
== providers.length - 1)
+                                       throw e;                                
                                
+                               else
+                                       continue;
+                       }
                }
-               Client c = getClient() ;
-               String keyRest = 
KMS_KEY_METADATA_URI.replaceAll(Pattern.quote("${alias}"), name);
+               return null;
+       }
+       
+       public VXKmsKey getKeyFromUri(String provider, String name) {
+               Client c = getClient();
+               String keyRest = KMS_KEY_METADATA_URI.replaceAll(
+                               Pattern.quote("${alias}"), name);
                String currentUserLoginId = ContextUtil.getCurrentUserLoginId();
-               keyRest = keyRest.replaceAll(Pattern.quote("${userName}"), 
currentUserLoginId);
+               keyRest = keyRest.replaceAll(Pattern.quote("${userName}"),
+                               currentUserLoginId);
                String uri = provider + (provider.endsWith("/") ? keyRest : 
("/" + keyRest));
-               WebResource r = c.resource(uri) ;
+               WebResource r = c.resource(uri);
                String response = 
r.accept(MediaType.APPLICATION_JSON_TYPE).get(String.class);
-               Gson gson = new GsonBuilder().create() ;
-               logger.debug("RESPONSE: [" + response + "]") ;
-               VXKmsKey key = gson.fromJson(response, VXKmsKey.class) ;
-               return key;
+               Gson gson = new GsonBuilder().create();
+               logger.debug("RESPONSE: [" + response + "]");
+               VXKmsKey key = gson.fromJson(response, VXKmsKey.class);
+               return key;                     
        }
        
-       private String getKMSURL(String name) throws Exception{
-               String provider = null;
+       private String[] getKMSURL(String name) throws Exception{
+               String providers[] = null;
                RangerService rangerService = null;
                try {
                        rangerService = svcStore.getServiceByName(name);
-                       provider = 
rangerService.getConfigs().get(KMS_URL_CONFIG);
-                       provider = provider.replaceAll("kms://","");
-                       provider = provider.replaceAll("http@","http://";);
-               } catch(Exception excp) {
+                       String kmsUrl = 
rangerService.getConfigs().get(KMS_URL_CONFIG);
+                       String dbKmsUrl = kmsUrl;
+                       if(providerList.containsKey(kmsUrl)){
+                               kmsUrl = providerList.get(kmsUrl);              
                
+                       }else{
+                               providerList.put(kmsUrl, kmsUrl);
+                       }
+                       providers = createProvider(dbKmsUrl,kmsUrl);
+               } catch (Exception excp) {
                        logger.error("getServiceByName(" + name + ") failed", 
excp);
                        throw new Exception("getServiceByName(" + name + ") 
failed", excp);
                }
 
-               if(rangerService == null || provider == null) {
-                       throw new Exception("Provider "+provider+" not found");
+               if (rangerService == null || providers == null) {
+                       throw new Exception("Provider " + name + " not found");
+               }
+               return providers;
+       }
+       
+       private String[] createProvider(String dbKmsUrl, String uri) throws 
IOException,URISyntaxException {            
+               URI providerUri = new URI(uri);
+               URL origUrl = new URL(extractKMSPath(providerUri).toString());
+               String authority = origUrl.getAuthority();
+               //      check for ';' which delimits the backup hosts
+               if (Strings.isNullOrEmpty(authority)) {
+                       throw new IOException("No valid authority in kms uri [" 
+ origUrl+ "]");
+               }
+               //      Check if port is present in authority
+               //      In the current scheme, all hosts have to run on the 
same port
+               int port = -1;
+               String hostsPart = authority;
+               if (authority.contains(":")) {
+                       String[] t = authority.split(":");
+                       try {
+                               port = Integer.parseInt(t[1]);
+                       } catch (Exception e) {
+                               throw new IOException("Could not parse port in 
kms uri ["
+                               + origUrl + "]");
+                       }
+                       hostsPart = t[0];
+               }
+               return createProvider(dbKmsUrl, providerUri, origUrl, port, 
hostsPart);
+       }
+
+       private static Path extractKMSPath(URI uri) throws 
MalformedURLException,IOException {
+               return ProviderUtils.unnestUri(uri);
+       }
+
+       private String[] createProvider(String dbkmsUrl, URI providerUri, URL 
origUrl, int port,
+                       String hostsPart) throws IOException {
+               String[] hosts = hostsPart.split(";");
+               String[] providers = new String[hosts.length];
+               if (hosts.length == 1) {
+                       providers[0] = origUrl.toString();
+               } else {
+                       String 
providerNext=providerUri.getScheme()+"://"+origUrl.getProtocol()+"@";
+                       for(int i=nextProvider; i<hosts.length; i++){
+                               providerNext = providerNext+hosts[i];
+                               if(i!=(hosts.length-1)){
+                                       providerNext = providerNext+";";
+                               }
+                       }
+                       for(int i=0; i<nextProvider; i++){
+                               providerNext = providerNext+";"+hosts[i];
+                       }
+                       if(nextProvider != hosts.length-1){
+                               nextProvider = nextProvider+1;
+                       }else{
+                               nextProvider = 0;
+                       }
+                       providerNext = providerNext +":"+port+origUrl.getPath();
+                       providerList.put(dbkmsUrl, providerNext);
+                       for (int i = 0; i < hosts.length; i++) {
+                               try {
+                                       String url = 
origUrl.getProtocol()+"://"+hosts[i]+":"+port+origUrl.getPath();
+                                       providers[i] = new URI(url).toString();
+                               } catch (URISyntaxException e) {
+                                       throw new IOException("Could not Prase 
KMS URL..", e);
+                               }
+                       }
                }
-               return provider;
+               return providers;
        }
 
        private synchronized Client getClient() {

Reply via email to