hive-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "ASF GitHub Bot (Jira)" <j...@apache.org>
Subject [jira] [Work logged] (HIVE-23351) Ranger Replication Scheduling
Date Fri, 08 May 2020 13:00:00 GMT

     [ https://issues.apache.org/jira/browse/HIVE-23351?focusedWorklogId=432103&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-432103 ]

ASF GitHub Bot logged work on HIVE-23351:
-----------------------------------------

                Author: ASF GitHub Bot
            Created on: 08/May/20 12:59
            Start Date: 08/May/20 12:59
    Worklog Time Spent: 10m 
      Work Description: pkumarsinha commented on a change in pull request #1004:
URL: https://github.com/apache/hive/pull/1004#discussion_r421996357



##########
File path: common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
##########
@@ -526,6 +526,22 @@ private static void populateLlapDaemonVarsSet(Set<String> llapDaemonVarsSetLocal
         "This is the base directory on the target/replica warehouse under which data for "
             + "external tables is stored. This is relative base path and hence prefixed to the source "
             + "external table path on target cluster."),
+    REPL_INCLUDE_AUTHORIZATION_METADATA("hive.repl.include.authorization.metadata", false,
+            "This configuration will enable security and authorization related metadata along "
+                    + "with the hive data and metadata replication. "),
+    REPL_AUTHORIZATION_PROVIDER_SERVICE("hive.repl.authorization.provider.service", "ranger",
+            "This configuration will define which service will provide the security and authorization "
+                    + "related metadata that needs to be replicated along "
+                    + "with the hive data and metadata replication. Set the configuration "
+                    + "hive.repl.include.authorization.metadata to false to disable "
+                    + "security policies being replicated "),
+    REPL_AUTHORIZATION_PROVIDER_SERVICE_ENDPOINT("hive.repl.authorization.provider.service.endpoint",
+            "",
+            "This configuration will define the authorization service endpoint"),
+    REPL_RANGER_SERVICE_NAME("hive.repl.ranger.service.name",
+            "cm_hive",

Review comment:
       How is the default derived here?

##########
File path: ql/src/java/org/apache/hadoop/hive/ql/exec/repl/ReplDumpTask.java
##########
@@ -144,6 +145,11 @@ public int execute() {
         if (shouldDump(previousValidHiveDumpPath)) {
           Path currentDumpPath = getCurrentDumpPath(dumpRoot, isBootstrap);
           Path hiveDumpRoot = new Path(currentDumpPath, ReplUtils.REPL_HIVE_BASE_DIR);
+          work.setCurrentDumpPath(currentDumpPath);
+          if (shouldDumpAuthorizationMetadata()) {
+            LOG.info("Dumping authorization data");

Review comment:
       Log message may be misleading as at this point we are not dumping the data. 

##########
File path: ql/src/java/org/apache/hadoop/hive/ql/exec/repl/ReplDumpTask.java
##########
@@ -170,6 +175,26 @@ public int execute() {
     return 0;
   }
 
+  private void initiateAuthorizationDumpTask(Path currentDumpPath) throws SemanticException {
+    if (RANGER_AUTHORIZER.equalsIgnoreCase(conf.getVar(HiveConf.ConfVars.REPL_AUTHORIZATION_PROVIDER_SERVICE))) {
+      Path rangerDumpRoot = new Path(currentDumpPath, ReplUtils.REPL_RANGER_BASE_DIR);
+      LOG.info("Exporting Authorization Metadata at {} ", rangerDumpRoot);
+      RangerDumpWork rangerDumpWork = new RangerDumpWork(rangerDumpRoot, work.dbNameOrPattern);
+      Task<RangerDumpWork> rangerDumpTask = TaskFactory.get(rangerDumpWork, conf);
+      if (childTasks == null) {

Review comment:
       Shouldn't the child task must be null when we are trying to add ranger authorization task? And we should throw error if it is not?

##########
File path: ql/src/java/org/apache/hadoop/hive/ql/exec/repl/ReplDumpTask.java
##########
@@ -170,6 +175,26 @@ public int execute() {
     return 0;
   }
 
+  private void initiateAuthorizationDumpTask(Path currentDumpPath) throws SemanticException {
+    if (RANGER_AUTHORIZER.equalsIgnoreCase(conf.getVar(HiveConf.ConfVars.REPL_AUTHORIZATION_PROVIDER_SERVICE))) {
+      Path rangerDumpRoot = new Path(currentDumpPath, ReplUtils.REPL_RANGER_BASE_DIR);
+      LOG.info("Exporting Authorization Metadata at {} ", rangerDumpRoot);
+      RangerDumpWork rangerDumpWork = new RangerDumpWork(rangerDumpRoot, work.dbNameOrPattern);
+      Task<RangerDumpWork> rangerDumpTask = TaskFactory.get(rangerDumpWork, conf);
+      if (childTasks == null) {
+        childTasks = new ArrayList<>();
+      }
+      childTasks.add(rangerDumpTask);
+    } else {
+      throw new SemanticException("Authorizer " + conf.getVar(HiveConf.ConfVars.REPL_AUTHORIZATION_PROVIDER_SERVICE)

Review comment:
       Add a test for this.

##########
File path: ql/src/java/org/apache/hadoop/hive/ql/exec/repl/ReplDumpTask.java
##########
@@ -198,7 +223,12 @@ private void initiateDataCopyTasks() throws SemanticException {
       finishRemainingTasks();
     } else {
       DAGTraversal.traverse(childTasks, new AddDependencyToLeaves(TaskFactory.get(work, conf)));
-      this.childTasks = childTasks;
+      if (this.childTasks.isEmpty()) {

Review comment:
       Isn't this.childTask null by defualt? If so, then when ranger repl is not configured, this might lead to NPE?

##########
File path: ql/src/gen/thrift/gen-javabean/org/apache/hadoop/hive/ql/plan/api/StageType.java
##########
@@ -26,7 +26,9 @@
   REPL_TXN(15),
   REPL_INCREMENTAL_LOAD(16),
   SCHEDULED_QUERY_MAINT(17),
-  ACK(18);
+  ACK(18),
+  RANGER_DUMP(19),
+  RANGER_LOAD(20);

Review comment:
       Don't we require to fix findByValue() as well?

##########
File path: ql/src/java/org/apache/hadoop/hive/ql/exec/repl/ReplLoadTask.java
##########
@@ -103,13 +105,43 @@ public int execute() {
     }
     work.setRootTask(this);
     this.parentTasks = null;
+    if (shouldLoadAuthorizationMetadata()) {
+      LOG.info("Loading authorization data");
+      try {

Review comment:
       Either move the exception handling during executeIncrementalLoad() and executeBootStrapLoad() here and have one try/catch block for all three of the method execution or handle the initiateAuthorizationLoadTask() related exception inside that. It might look more aligned. I would prefer first one if possible.

##########
File path: ql/src/java/org/apache/hadoop/hive/ql/exec/repl/ReplDumpTask.java
##########
@@ -198,7 +223,12 @@ private void initiateDataCopyTasks() throws SemanticException {
       finishRemainingTasks();
     } else {
       DAGTraversal.traverse(childTasks, new AddDependencyToLeaves(TaskFactory.get(work, conf)));
-      this.childTasks = childTasks;

Review comment:
       finishRemainingTasks() also creates ack file. I see a possibility that ack file will be created before ranger dump and in case ranger dump fails, the dump will be in inconsistent state but will still be picked by load as the ack exists. the side effect will further escalate.

##########
File path: ql/src/java/org/apache/hadoop/hive/ql/exec/repl/ReplLoadTask.java
##########
@@ -103,13 +105,43 @@ public int execute() {
     }
     work.setRootTask(this);
     this.parentTasks = null;
+    if (shouldLoadAuthorizationMetadata()) {
+      LOG.info("Loading authorization data");

Review comment:
       We may change the log to something like "Load authorization data is enabled" or similar

##########
File path: ql/src/java/org/apache/hadoop/hive/ql/exec/repl/ReplLoadTask.java
##########
@@ -103,13 +105,43 @@ public int execute() {
     }
     work.setRootTask(this);
     this.parentTasks = null;
+    if (shouldLoadAuthorizationMetadata()) {
+      LOG.info("Loading authorization data");
+      try {
+        initiateAuthorizationLoadTask(work.dumpDirectory);
+      } catch (Exception e) {
+        LOG.error("failed", e);
+        setException(e);
+        return ErrorMsg.getErrorMsg(e.getMessage()).getErrorCode();
+      }
+    }
     if (work.isIncrementalLoad()) {
       return executeIncrementalLoad();
     } else {
       return executeBootStrapLoad();
     }
   }
 
+  private boolean shouldLoadAuthorizationMetadata() {
+    return conf.getBoolVar(HiveConf.ConfVars.REPL_INCLUDE_AUTHORIZATION_METADATA);
+  }
+
+  private void initiateAuthorizationLoadTask(String hiveDumpDirectory) throws SemanticException {
+    if (RANGER_AUTHORIZER.equalsIgnoreCase(conf.getVar(HiveConf.ConfVars.REPL_AUTHORIZATION_PROVIDER_SERVICE))) {
+      Path rangerLoadRoot = new Path(new Path(hiveDumpDirectory).getParent(), ReplUtils.REPL_RANGER_BASE_DIR);
+      LOG.info("Importing Authorization Metadata from {} ", rangerLoadRoot);

Review comment:
       Change the log message to align with current state.

##########
File path: ql/src/java/org/apache/hadoop/hive/ql/exec/repl/ReplLoadTask.java
##########
@@ -103,13 +105,43 @@ public int execute() {
     }
     work.setRootTask(this);
     this.parentTasks = null;
+    if (shouldLoadAuthorizationMetadata()) {
+      LOG.info("Loading authorization data");
+      try {
+        initiateAuthorizationLoadTask(work.dumpDirectory);
+      } catch (Exception e) {
+        LOG.error("failed", e);
+        setException(e);
+        return ErrorMsg.getErrorMsg(e.getMessage()).getErrorCode();
+      }
+    }
     if (work.isIncrementalLoad()) {
       return executeIncrementalLoad();
     } else {
       return executeBootStrapLoad();
     }
   }
 
+  private boolean shouldLoadAuthorizationMetadata() {
+    return conf.getBoolVar(HiveConf.ConfVars.REPL_INCLUDE_AUTHORIZATION_METADATA);
+  }
+
+  private void initiateAuthorizationLoadTask(String hiveDumpDirectory) throws SemanticException {
+    if (RANGER_AUTHORIZER.equalsIgnoreCase(conf.getVar(HiveConf.ConfVars.REPL_AUTHORIZATION_PROVIDER_SERVICE))) {
+      Path rangerLoadRoot = new Path(new Path(hiveDumpDirectory).getParent(), ReplUtils.REPL_RANGER_BASE_DIR);
+      LOG.info("Importing Authorization Metadata from {} ", rangerLoadRoot);
+      RangerLoadWork rangerLoadWork = new RangerLoadWork(rangerLoadRoot, work.getSourceDbName(), work.dbNameToLoadIn);
+      Task<RangerLoadWork> rangerLoadTask = TaskFactory.get(rangerLoadWork, conf);
+      if (childTasks == null) {
+        childTasks = new ArrayList<>();
+      }
+      childTasks.add(rangerLoadTask);

Review comment:
       This will run  ranger load after hive db/table meta data. Ideally the ranger/atlas should run prior to it.

##########
File path: ql/src/test/org/apache/hadoop/hive/ql/exec/repl/TestRangerDumpTask.java
##########
@@ -0,0 +1,123 @@
+  /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hive.ql.exec.repl;
+
+import com.google.gson.Gson;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.ql.exec.repl.ranger.RangerExportPolicyList;
+import org.apache.hadoop.hive.ql.exec.repl.ranger.RangerRestClientImpl;
+import org.apache.hadoop.hive.ql.exec.repl.ranger.RangerPolicy;
+import org.apache.hadoop.hive.ql.exec.repl.util.ReplUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+
+import static org.apache.hadoop.hive.conf.HiveConf.ConfVars.REPL_AUTHORIZATION_PROVIDER_SERVICE_ENDPOINT;
+import static org.apache.hadoop.hive.conf.HiveConf.ConfVars.REPL_RANGER_SERVICE_NAME;
+
+  @RunWith(MockitoJUnitRunner.class)
+public class TestRangerDumpTask {
+
+  protected static final Logger LOG = LoggerFactory.getLogger(TestRangerDumpTask.class);
+  private RangerDumpTask task;
+
+  @Mock
+  private RangerRestClientImpl mockClient;
+
+  @Mock
+  private HiveConf conf;
+
+  @Mock
+  private RangerDumpWork work;
+
+  @Before
+  public void setup() throws Exception {
+    task = new RangerDumpTask(mockClient, conf, work);
+    Mockito.when(mockClient.removeMultiResourcePolicies(Mockito.anyList())).thenCallRealMethod();
+    Mockito.when(mockClient.saveRangerPoliciesToFile(Mockito.any(), Mockito.any(), Mockito.anyString()))
+        .thenCallRealMethod();
+    Mockito.when(mockClient.readRangerPoliciesFromJsonFile(Mockito.any())).thenCallRealMethod();
+    Mockito.when(mockClient.checkConnection(Mockito.anyString())).thenReturn(true);
+  }
+
+  @Test
+  public void testFailureInvalidAuthProviderEndpoint() throws Exception {
+    Mockito.when(conf.getVar(REPL_AUTHORIZATION_PROVIDER_SERVICE_ENDPOINT)).thenReturn(null);
+    int status = task.execute();
+    Assert.assertEquals(40000, status);
+  }
+
+  @Test
+  public void testSuccessValidAuthProviderEndpoint() throws Exception {
+    RangerExportPolicyList rangerPolicyList = new RangerExportPolicyList();
+    rangerPolicyList.setPolicies(new ArrayList<RangerPolicy>());
+    Mockito.when(mockClient.exportRangerPolicies(Mockito.anyString(), Mockito.anyString(), Mockito.anyString()))
+        .thenReturn(rangerPolicyList);
+    Mockito.when(conf.getVar(REPL_AUTHORIZATION_PROVIDER_SERVICE_ENDPOINT)).thenReturn("rangerEndpoint");
+    Mockito.when(conf.getVar(REPL_RANGER_SERVICE_NAME)).thenReturn("cm_hive");
+    Mockito.when(work.getDbName()).thenReturn("testdb");
+    int status = task.execute();
+    Assert.assertEquals(0, status);
+  }
+
+  @Test
+  public void testSuccessNonEmptyRangerPolicies() throws Exception {
+    String rangerResponse = "{\"metaDataInfo\":{\"Host name\":\"quasar-nnwpyd-1.quasar-nnwpyd.root.hwx.site\","
+        + "\"Exported by\":\"hive\",\"Export time\":\"May 5, 2020, 8:55:03 AM\",\"Ranger apache version\""
+        + ":\"2.0.0.7.2.0.0-61\"},\"policies\":[{\"service\":\"cm_hive\",\"name\":\"db-level\",\"policyType\":0,"
+        + "\"description\":\"\",\"isAuditEnabled\":true,\"resources\":{\"database\":{\"values\":[\"aa\"],"
+        + "\"isExcludes\":false,\"isRecursive\":false},\"column\":{\"values\":[\"id\"],\"isExcludes\":false,"
+        + "\"isRecursive\":false},\"table\":{\"values\":[\"*\"],\"isExcludes\":false,\"isRecursive\":false}},"
+        + "\"policyItems\":[{\"accesses\":[{\"type\":\"select\",\"isAllowed\":true},{\"type\":\"update\","
+        + "\"isAllowed\":true}],\"users\":[\"admin\"],\"groups\":[\"public\"],\"conditions\":[],"
+        + "\"delegateAdmin\":false}],\"denyPolicyItems\":[],\"allowExceptions\":[],\"denyExceptions\":[],"
+        + "\"dataMaskPolicyItems\":[],\"rowFilterPolicyItems\":[],\"id\":40,\"guid\":"
+        + "\"4e2b3406-7b9a-4004-8cdf-7a239c8e2cae\",\"isEnabled\":true,\"version\":1}]}";
+    RangerExportPolicyList rangerPolicyList = new Gson().fromJson(rangerResponse, RangerExportPolicyList.class);
+    Mockito.when(mockClient.exportRangerPolicies(Mockito.anyString(), Mockito.anyString(), Mockito.anyString()))
+        .thenReturn(rangerPolicyList);
+    Mockito.when(conf.getVar(REPL_AUTHORIZATION_PROVIDER_SERVICE_ENDPOINT)).thenReturn("rangerEndpoint");
+    Mockito.when(conf.getVar(REPL_RANGER_SERVICE_NAME)).thenReturn("cm_hive");
+    Mockito.when(work.getDbName()).thenReturn("testdb");
+    Path rangerDumpPath = new Path("/tmp");
+    Mockito.when(work.getCurrentDumpPath()).thenReturn(rangerDumpPath);
+    int status = task.execute();
+    Assert.assertEquals(0, status);
+    Path policyFile = new Path(rangerDumpPath, ReplUtils.HIVE_RANGER_POLICIES_FILE_NAME + ".json");
+    Assert.assertTrue(rangerDumpPath.getFileSystem(new Configuration()).exists(policyFile));
+    RangerExportPolicyList actualRangerExportPolicyList = mockClient.readRangerPoliciesFromJsonFile(policyFile);
+    Assert.assertEquals(1, actualRangerExportPolicyList.getPolicies().size());
+    Assert.assertEquals(4, actualRangerExportPolicyList.getMetaDataInfo().size());
+    Assert.assertEquals("quasar-nnwpyd-1.quasar-nnwpyd.root.hwx.site", actualRangerExportPolicyList

Review comment:
       Use some example hostname under apache.org domain

##########
File path: ql/src/test/org/apache/hadoop/hive/ql/exec/repl/TestRangerLoadTask.java
##########
@@ -0,0 +1,107 @@
+  /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hive.ql.exec.repl;
+
+  import com.google.gson.Gson;
+  import org.apache.hadoop.conf.Configuration;
+  import org.apache.hadoop.fs.Path;
+  import org.apache.hadoop.hive.conf.HiveConf;
+  import org.apache.hadoop.hive.ql.exec.repl.ranger.RangerExportPolicyList;
+  import org.apache.hadoop.hive.ql.exec.repl.ranger.RangerPolicy;
+  import org.apache.hadoop.hive.ql.exec.repl.ranger.RangerRestClientImpl;
+  import org.apache.hadoop.hive.ql.exec.repl.util.ReplUtils;
+  import org.junit.Assert;
+  import org.junit.Before;
+  import org.junit.Test;
+  import org.junit.runner.RunWith;
+  import org.mockito.Mock;
+  import org.mockito.Mockito;
+  import org.mockito.junit.MockitoJUnitRunner;
+  import org.slf4j.Logger;
+  import org.slf4j.LoggerFactory;
+
+  import java.util.ArrayList;
+
+  import static org.apache.hadoop.hive.conf.HiveConf.ConfVars.REPL_AUTHORIZATION_PROVIDER_SERVICE_ENDPOINT;
+  import static org.apache.hadoop.hive.conf.HiveConf.ConfVars.REPL_RANGER_SERVICE_NAME;
+
+  @RunWith(MockitoJUnitRunner.class)
+public class TestRangerLoadTask {
+
+  protected static final Logger LOG = LoggerFactory.getLogger(TestRangerLoadTask.class);
+  private RangerLoadTask task;
+
+  @Mock
+  private RangerRestClientImpl mockClient;
+
+  @Mock
+  private HiveConf conf;
+
+  @Mock
+  private RangerLoadWork work;
+
+  @Before
+  public void setup() throws Exception {
+    task = new RangerLoadTask(mockClient, conf, work);
+    Mockito.when(mockClient.changeDataSet(Mockito.anyList(), Mockito.anyString(), Mockito.anyString()))
+        .thenCallRealMethod();
+    Mockito.when(mockClient.readRangerPoliciesFromJsonFile(Mockito.any())).thenCallRealMethod();
+    Mockito.when(mockClient.checkConnection(Mockito.anyString())).thenReturn(true);
+  }
+
+  @Test
+  public void testFailureInvalidAuthProviderEndpoint() {
+    Mockito.when(conf.getVar(REPL_AUTHORIZATION_PROVIDER_SERVICE_ENDPOINT)).thenReturn(null);
+    int status = task.execute();
+    Assert.assertEquals(40000, status);
+  }
+
+  @Test
+  public void testSuccessValidAuthProviderEndpoint() {
+    Mockito.when(conf.getVar(REPL_AUTHORIZATION_PROVIDER_SERVICE_ENDPOINT)).thenReturn("rangerEndpoint");
+    Mockito.when(work.getSourceDbName()).thenReturn("srcdb");
+    Mockito.when(work.getTargetDbName()).thenReturn("tgtdb");
+    int status = task.execute();
+    Assert.assertEquals(0, status);
+  }
+
+  @Test
+  public void testSuccessNonEmptyRangerPolicies() throws Exception {
+    String rangerResponse = "{\"metaDataInfo\":{\"Host name\":\"quasar-nnwpyd-1.quasar-nnwpyd.root.hwx.site\","

Review comment:
       Use some example hostname under apache.org domain

##########
File path: ql/src/java/org/apache/hadoop/hive/ql/exec/repl/ranger/RangerRestClientImpl.java
##########
@@ -0,0 +1,356 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.ql.exec.repl.ranger;
+
+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.WebResource;
+import com.sun.jersey.api.client.config.ClientConfig;
+import com.sun.jersey.api.client.config.DefaultClientConfig;
+import com.sun.jersey.multipart.FormDataMultiPart;
+import com.sun.jersey.multipart.MultiPart;
+import com.sun.jersey.multipart.file.StreamDataBodyPart;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.eclipse.jetty.util.MultiPartWriter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.MediaType;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.File;
+import java.io.Reader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+
+/**
+ * RangerRestClientImpl to connect to Ranger and export policies.
+ */
+public class RangerRestClientImpl implements RangerRestClient {
+  private static final Logger LOG = LoggerFactory.getLogger(RangerRestClientImpl.class);
+  private static final String RANGER_REST_URL_EXPORTJSONFILE = "/service/plugins/policies/exportJson";
+  private static final String RANGER_REST_URL_IMPORTJSONFILE =
+      "/service/plugins/policies/importPoliciesFromFile?updateIfExists=true";
+
+  public RangerExportPolicyList exportRangerPolicies(String sourceRangerEndpoint,
+                                                     String dbName, String rangerHiveServiceName) throws Exception {
+    LOG.info("Ranger endpoint for cluster " + sourceRangerEndpoint);
+    ClientResponse clientResp = null;
+    String uri = null;
+    if (!StringUtils.isEmpty(rangerHiveServiceName)) {

Review comment:
       It should be error if it is empty.

##########
File path: ql/src/java/org/apache/hadoop/hive/ql/exec/repl/ranger/RangerRestClientImpl.java
##########
@@ -0,0 +1,356 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.ql.exec.repl.ranger;
+
+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.WebResource;
+import com.sun.jersey.api.client.config.ClientConfig;
+import com.sun.jersey.api.client.config.DefaultClientConfig;
+import com.sun.jersey.multipart.FormDataMultiPart;
+import com.sun.jersey.multipart.MultiPart;
+import com.sun.jersey.multipart.file.StreamDataBodyPart;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.eclipse.jetty.util.MultiPartWriter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.MediaType;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.File;
+import java.io.Reader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+
+/**
+ * RangerRestClientImpl to connect to Ranger and export policies.
+ */
+public class RangerRestClientImpl implements RangerRestClient {
+  private static final Logger LOG = LoggerFactory.getLogger(RangerRestClientImpl.class);
+  private static final String RANGER_REST_URL_EXPORTJSONFILE = "/service/plugins/policies/exportJson";
+  private static final String RANGER_REST_URL_IMPORTJSONFILE =
+      "/service/plugins/policies/importPoliciesFromFile?updateIfExists=true";
+
+  public RangerExportPolicyList exportRangerPolicies(String sourceRangerEndpoint,
+                                                     String dbName, String rangerHiveServiceName) throws Exception {
+    LOG.info("Ranger endpoint for cluster " + sourceRangerEndpoint);
+    ClientResponse clientResp = null;
+    String uri = null;
+    if (!StringUtils.isEmpty(rangerHiveServiceName)) {
+      uri = RANGER_REST_URL_EXPORTJSONFILE + "?serviceName=" + rangerHiveServiceName + "&polResource="
+          + dbName + "&resource:database=" + dbName
+          + "&serviceType=hive&resourceMatchScope=self_or_ancestor&resourceMatch=full";
+    }
+    if (sourceRangerEndpoint.endsWith("/")) {
+      sourceRangerEndpoint = StringUtils.removePattern(sourceRangerEndpoint, "/+$");
+    }
+    String url = sourceRangerEndpoint + (uri != null ? (uri.startsWith("/") ? uri : ("/" + uri)) : "");
+    LOG.debug("URL to export policies from source Ranger: {}", url);
+    RangerExportPolicyList rangerExportPolicyList = new RangerExportPolicyList();
+    WebResource.Builder builder = getRangerResourceBuilder(url);
+    clientResp = builder.get(ClientResponse.class);
+
+    String response = null;
+    if (clientResp != null) {
+      if (clientResp.getStatus() == HttpServletResponse.SC_OK) {
+        Gson gson = new GsonBuilder().create();
+        response = clientResp.getEntity(String.class);
+        LOG.debug("Response received for ranger export {} ", response);
+        if (StringUtils.isNotEmpty(response)) {
+          rangerExportPolicyList = gson.fromJson(response, RangerExportPolicyList.class);
+          return rangerExportPolicyList;
+        }
+      } else if (clientResp.getStatus() == HttpServletResponse.SC_NO_CONTENT) {
+        LOG.debug("Ranger policy export request returned empty list");
+        return rangerExportPolicyList;
+      } else if (clientResp.getStatus() == HttpServletResponse.SC_UNAUTHORIZED) {
+        throw new Exception("Authentication Failure while communicating to Ranger admin");
+      } else if (clientResp.getStatus() == HttpServletResponse.SC_FORBIDDEN) {
+        throw new Exception("Authorization Failure while communicating to Ranger admin");
+      }
+    }
+    if (StringUtils.isEmpty(response)) {
+      LOG.debug("Ranger policy export request returned empty list or failed, Please refer Ranger admin logs.");
+    }
+    return rangerExportPolicyList;
+  }
+
+  public List<RangerPolicy> removeMultiResourcePolicies(List<RangerPolicy> rangerPolicies) {
+    List<RangerPolicy> rangerPoliciesToImport = new ArrayList<RangerPolicy>();
+    if (CollectionUtils.isNotEmpty(rangerPolicies)) {
+      Map<String, RangerPolicy.RangerPolicyResource> rangerPolicyResourceMap = null;
+      RangerPolicy.RangerPolicyResource rangerPolicyResource = null;
+      List<String> resourceNameList = null;
+      for (RangerPolicy rangerPolicy : rangerPolicies) {
+        if (rangerPolicy != null) {
+          rangerPolicyResourceMap = rangerPolicy.getResources();
+          if (rangerPolicyResourceMap != null) {
+            rangerPolicyResource = rangerPolicyResourceMap.get("database");
+            if (rangerPolicyResource != null) {
+              resourceNameList = rangerPolicyResource.getValues();
+              if (CollectionUtils.isNotEmpty(resourceNameList) && resourceNameList.size() == 1) {
+                rangerPoliciesToImport.add(rangerPolicy);
+              }
+            }
+          }
+        }
+      }
+    }
+    return rangerPoliciesToImport;
+  }
+
+  @Override
+  public RangerExportPolicyList importRangerPolicies(RangerExportPolicyList rangerExportPolicyList, String dbName,
+                                                     String baseUrl,
+                                                     String rangerHiveServiceName)
+      throws Exception {
+    String sourceClusterServiceName = null;
+    String serviceMapJsonFileName = "hive_servicemap.json";
+    String rangerPoliciesJsonFileName = "hive_replicationPolicies.json";
+    String uri = RANGER_REST_URL_IMPORTJSONFILE + "&polResource=" + dbName;
+
+    if (rangerExportPolicyList.getPolicies().size() > 0) {
+      sourceClusterServiceName = rangerExportPolicyList.getPolicies().get(0).getService();
+    }
+
+    if (StringUtils.isEmpty(sourceClusterServiceName)) {
+      sourceClusterServiceName = rangerHiveServiceName;
+    }
+
+    Map<String, String> serviceMap = new LinkedHashMap<String, String>();
+    if (!StringUtils.isEmpty(sourceClusterServiceName) && !StringUtils.isEmpty(rangerHiveServiceName)) {
+      serviceMap.put(sourceClusterServiceName, rangerHiveServiceName);
+    }
+
+    Gson gson = new GsonBuilder().create();
+    String jsonServiceMap = gson.toJson(serviceMap);
+
+    String jsonRangerExportPolicyList = gson.toJson(rangerExportPolicyList);
+
+    String url = baseUrl
+        + (uri.startsWith("/") ? uri : ("/" + uri));
+
+    LOG.debug("URL to import policies on target Ranger: {}", url);
+    ClientResponse clientResp = null;
+
+    StreamDataBodyPart filePartPolicies = new StreamDataBodyPart("file",
+        new ByteArrayInputStream(jsonRangerExportPolicyList.getBytes(StandardCharsets.UTF_8)),
+        rangerPoliciesJsonFileName);
+    StreamDataBodyPart filePartServiceMap = new StreamDataBodyPart("servicesMapJson",
+        new ByteArrayInputStream(jsonServiceMap.getBytes(StandardCharsets.UTF_8)), serviceMapJsonFileName);
+
+    FormDataMultiPart formDataMultiPart = new FormDataMultiPart();
+    MultiPart multipartEntity = null;
+    try {
+      multipartEntity = formDataMultiPart.bodyPart(filePartPolicies).bodyPart(filePartServiceMap);
+      WebResource.Builder builder = getRangerResourceBuilder(url);
+      clientResp = builder.accept(MediaType.APPLICATION_JSON).type(MediaType.MULTIPART_FORM_DATA)
+          .post(ClientResponse.class, multipartEntity);
+      if (clientResp != null) {
+        if (clientResp.getStatus() == HttpServletResponse.SC_NO_CONTENT) {
+          LOG.debug("Ranger policy import finished successfully");
+
+        } else if (clientResp.getStatus() == HttpServletResponse.SC_UNAUTHORIZED) {
+          throw new Exception("Authentication Failure while communicating to Ranger admin");
+        } else {
+          throw new Exception("Ranger policy import failed, Please refer target Ranger admin logs.");
+        }
+      }
+    } finally {
+      try {
+        if (filePartPolicies != null) {
+          filePartPolicies.cleanup();
+        }
+        if (filePartServiceMap != null) {
+          filePartServiceMap.cleanup();
+        }
+        if (formDataMultiPart != null) {
+          formDataMultiPart.close();
+        }
+        if (multipartEntity != null) {
+          multipartEntity.close();
+        }
+      } catch (IOException e) {
+        LOG.error("Exception occurred while closing resources: {}", e);
+      }
+    }
+    return rangerExportPolicyList;
+  }
+
+  private synchronized Client getRangerClient() {
+    Client ret = null;
+    ClientConfig config = new DefaultClientConfig();
+    config.getClasses().add(MultiPartWriter.class);
+    config.getProperties().put(ClientConfig.PROPERTY_FOLLOW_REDIRECTS, true);
+    ret = Client.create(config);
+    return ret;
+  }
+
+  @Override
+  public List<RangerPolicy> changeDataSet(List<RangerPolicy> rangerPolicies, String sourceDbName,
+                                          String targetDbName) {
+    if (sourceDbName.endsWith("/")) {
+      sourceDbName = StringUtils.removePattern(sourceDbName, "/+$");
+    }
+    if (targetDbName.endsWith("/")) {
+      targetDbName = StringUtils.removePattern(targetDbName, "/+$");
+    }
+    if (targetDbName.equals(sourceDbName)) {
+      return rangerPolicies;
+    }
+    if (CollectionUtils.isNotEmpty(rangerPolicies)) {
+      Map<String, RangerPolicy.RangerPolicyResource> rangerPolicyResourceMap = null;
+      RangerPolicy.RangerPolicyResource rangerPolicyResource = null;
+      List<String> resourceNameList = null;
+      for (RangerPolicy rangerPolicy : rangerPolicies) {
+        if (rangerPolicy != null) {
+          rangerPolicyResourceMap = rangerPolicy.getResources();
+          if (rangerPolicyResourceMap != null) {
+            rangerPolicyResource = rangerPolicyResourceMap.get("database");
+            if (rangerPolicyResource != null) {
+              resourceNameList = rangerPolicyResource.getValues();
+              if (CollectionUtils.isNotEmpty(resourceNameList)) {
+                for (int i = 0; i < resourceNameList.size(); i++) {
+                  String resourceName = resourceNameList.get(i);
+                  if (resourceName.equals(sourceDbName)) {
+                    resourceNameList.set(i, targetDbName);
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+    return rangerPolicies;
+  }
+
+  private Path writeExportedRangerPoliciesToJsonFile(String jsonString, String fileName, Path stagingDirPath)
+      throws Exception {
+    String filePath = "";
+    Path newPath = null;
+    FSDataOutputStream outStream = null;
+    OutputStreamWriter writer = null;
+    try {
+      if (!StringUtils.isEmpty(jsonString)) {
+        FileSystem fileSystem = getFileSystem(stagingDirPath);
+        if (fileSystem != null) {
+          if (!fileSystem.exists(stagingDirPath)) {
+            fileSystem.mkdirs(stagingDirPath);
+          }
+          newPath = stagingDirPath.suffix(File.separator + fileName);
+          outStream = fileSystem.create(newPath, true);
+          writer = new OutputStreamWriter(outStream, "UTF-8");
+          writer.write(jsonString);
+        }
+      }
+    } catch (IOException ex) {
+      if (newPath != null) {
+        filePath = newPath.toString();
+      }
+      throw new Exception("Failed to write json string to file:" + filePath, ex);
+    } catch (Exception ex) {
+      if (newPath != null) {
+        filePath = newPath.toString();
+      }
+      throw new Exception("Failed to write json string to file:" + filePath, ex);
+    } finally {
+      try {
+        if (writer != null) {
+          writer.close();
+        }
+        if (outStream != null) {
+          outStream.close();
+        }
+      } catch (Exception ex) {
+        LOG.error("Unable to close writer/outStream.", ex);
+      }
+    }
+    return newPath;
+  }
+
+  private FileSystem getFileSystem(Path path) throws IOException {
+    Configuration conf = new Configuration();
+    FileSystem fileSystem = path.getFileSystem(conf);

Review comment:
       Shouldn't the conf used here be HiveConf?

##########
File path: ql/src/java/org/apache/hadoop/hive/ql/exec/repl/ranger/RangerRestClientImpl.java
##########
@@ -0,0 +1,356 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.ql.exec.repl.ranger;
+
+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.WebResource;
+import com.sun.jersey.api.client.config.ClientConfig;
+import com.sun.jersey.api.client.config.DefaultClientConfig;
+import com.sun.jersey.multipart.FormDataMultiPart;
+import com.sun.jersey.multipart.MultiPart;
+import com.sun.jersey.multipart.file.StreamDataBodyPart;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.eclipse.jetty.util.MultiPartWriter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.MediaType;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.File;
+import java.io.Reader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+
+/**
+ * RangerRestClientImpl to connect to Ranger and export policies.
+ */
+public class RangerRestClientImpl implements RangerRestClient {
+  private static final Logger LOG = LoggerFactory.getLogger(RangerRestClientImpl.class);
+  private static final String RANGER_REST_URL_EXPORTJSONFILE = "/service/plugins/policies/exportJson";
+  private static final String RANGER_REST_URL_IMPORTJSONFILE =
+      "/service/plugins/policies/importPoliciesFromFile?updateIfExists=true";
+
+  public RangerExportPolicyList exportRangerPolicies(String sourceRangerEndpoint,
+                                                     String dbName, String rangerHiveServiceName) throws Exception {
+    LOG.info("Ranger endpoint for cluster " + sourceRangerEndpoint);
+    ClientResponse clientResp = null;
+    String uri = null;
+    if (!StringUtils.isEmpty(rangerHiveServiceName)) {
+      uri = RANGER_REST_URL_EXPORTJSONFILE + "?serviceName=" + rangerHiveServiceName + "&polResource="
+          + dbName + "&resource:database=" + dbName
+          + "&serviceType=hive&resourceMatchScope=self_or_ancestor&resourceMatch=full";
+    }
+    if (sourceRangerEndpoint.endsWith("/")) {
+      sourceRangerEndpoint = StringUtils.removePattern(sourceRangerEndpoint, "/+$");
+    }
+    String url = sourceRangerEndpoint + (uri != null ? (uri.startsWith("/") ? uri : ("/" + uri)) : "");
+    LOG.debug("URL to export policies from source Ranger: {}", url);
+    RangerExportPolicyList rangerExportPolicyList = new RangerExportPolicyList();
+    WebResource.Builder builder = getRangerResourceBuilder(url);
+    clientResp = builder.get(ClientResponse.class);
+
+    String response = null;
+    if (clientResp != null) {
+      if (clientResp.getStatus() == HttpServletResponse.SC_OK) {
+        Gson gson = new GsonBuilder().create();
+        response = clientResp.getEntity(String.class);
+        LOG.debug("Response received for ranger export {} ", response);
+        if (StringUtils.isNotEmpty(response)) {
+          rangerExportPolicyList = gson.fromJson(response, RangerExportPolicyList.class);
+          return rangerExportPolicyList;
+        }
+      } else if (clientResp.getStatus() == HttpServletResponse.SC_NO_CONTENT) {
+        LOG.debug("Ranger policy export request returned empty list");
+        return rangerExportPolicyList;
+      } else if (clientResp.getStatus() == HttpServletResponse.SC_UNAUTHORIZED) {
+        throw new Exception("Authentication Failure while communicating to Ranger admin");
+      } else if (clientResp.getStatus() == HttpServletResponse.SC_FORBIDDEN) {
+        throw new Exception("Authorization Failure while communicating to Ranger admin");
+      }
+    }
+    if (StringUtils.isEmpty(response)) {
+      LOG.debug("Ranger policy export request returned empty list or failed, Please refer Ranger admin logs.");
+    }
+    return rangerExportPolicyList;
+  }
+
+  public List<RangerPolicy> removeMultiResourcePolicies(List<RangerPolicy> rangerPolicies) {
+    List<RangerPolicy> rangerPoliciesToImport = new ArrayList<RangerPolicy>();
+    if (CollectionUtils.isNotEmpty(rangerPolicies)) {
+      Map<String, RangerPolicy.RangerPolicyResource> rangerPolicyResourceMap = null;
+      RangerPolicy.RangerPolicyResource rangerPolicyResource = null;
+      List<String> resourceNameList = null;
+      for (RangerPolicy rangerPolicy : rangerPolicies) {
+        if (rangerPolicy != null) {
+          rangerPolicyResourceMap = rangerPolicy.getResources();
+          if (rangerPolicyResourceMap != null) {
+            rangerPolicyResource = rangerPolicyResourceMap.get("database");
+            if (rangerPolicyResource != null) {
+              resourceNameList = rangerPolicyResource.getValues();
+              if (CollectionUtils.isNotEmpty(resourceNameList) && resourceNameList.size() == 1) {
+                rangerPoliciesToImport.add(rangerPolicy);
+              }
+            }
+          }
+        }
+      }
+    }
+    return rangerPoliciesToImport;
+  }
+
+  @Override
+  public RangerExportPolicyList importRangerPolicies(RangerExportPolicyList rangerExportPolicyList, String dbName,
+                                                     String baseUrl,
+                                                     String rangerHiveServiceName)
+      throws Exception {
+    String sourceClusterServiceName = null;
+    String serviceMapJsonFileName = "hive_servicemap.json";
+    String rangerPoliciesJsonFileName = "hive_replicationPolicies.json";
+    String uri = RANGER_REST_URL_IMPORTJSONFILE + "&polResource=" + dbName;
+
+    if (rangerExportPolicyList.getPolicies().size() > 0) {
+      sourceClusterServiceName = rangerExportPolicyList.getPolicies().get(0).getService();
+    }
+
+    if (StringUtils.isEmpty(sourceClusterServiceName)) {
+      sourceClusterServiceName = rangerHiveServiceName;
+    }
+
+    Map<String, String> serviceMap = new LinkedHashMap<String, String>();
+    if (!StringUtils.isEmpty(sourceClusterServiceName) && !StringUtils.isEmpty(rangerHiveServiceName)) {
+      serviceMap.put(sourceClusterServiceName, rangerHiveServiceName);
+    }
+
+    Gson gson = new GsonBuilder().create();
+    String jsonServiceMap = gson.toJson(serviceMap);
+
+    String jsonRangerExportPolicyList = gson.toJson(rangerExportPolicyList);
+
+    String url = baseUrl
+        + (uri.startsWith("/") ? uri : ("/" + uri));
+
+    LOG.debug("URL to import policies on target Ranger: {}", url);
+    ClientResponse clientResp = null;
+
+    StreamDataBodyPart filePartPolicies = new StreamDataBodyPart("file",
+        new ByteArrayInputStream(jsonRangerExportPolicyList.getBytes(StandardCharsets.UTF_8)),
+        rangerPoliciesJsonFileName);
+    StreamDataBodyPart filePartServiceMap = new StreamDataBodyPart("servicesMapJson",
+        new ByteArrayInputStream(jsonServiceMap.getBytes(StandardCharsets.UTF_8)), serviceMapJsonFileName);
+
+    FormDataMultiPart formDataMultiPart = new FormDataMultiPart();
+    MultiPart multipartEntity = null;
+    try {
+      multipartEntity = formDataMultiPart.bodyPart(filePartPolicies).bodyPart(filePartServiceMap);
+      WebResource.Builder builder = getRangerResourceBuilder(url);
+      clientResp = builder.accept(MediaType.APPLICATION_JSON).type(MediaType.MULTIPART_FORM_DATA)
+          .post(ClientResponse.class, multipartEntity);
+      if (clientResp != null) {
+        if (clientResp.getStatus() == HttpServletResponse.SC_NO_CONTENT) {
+          LOG.debug("Ranger policy import finished successfully");
+
+        } else if (clientResp.getStatus() == HttpServletResponse.SC_UNAUTHORIZED) {
+          throw new Exception("Authentication Failure while communicating to Ranger admin");
+        } else {
+          throw new Exception("Ranger policy import failed, Please refer target Ranger admin logs.");
+        }
+      }
+    } finally {
+      try {
+        if (filePartPolicies != null) {
+          filePartPolicies.cleanup();
+        }
+        if (filePartServiceMap != null) {
+          filePartServiceMap.cleanup();
+        }
+        if (formDataMultiPart != null) {
+          formDataMultiPart.close();
+        }
+        if (multipartEntity != null) {
+          multipartEntity.close();
+        }
+      } catch (IOException e) {
+        LOG.error("Exception occurred while closing resources: {}", e);
+      }
+    }
+    return rangerExportPolicyList;
+  }
+
+  private synchronized Client getRangerClient() {
+    Client ret = null;
+    ClientConfig config = new DefaultClientConfig();
+    config.getClasses().add(MultiPartWriter.class);
+    config.getProperties().put(ClientConfig.PROPERTY_FOLLOW_REDIRECTS, true);
+    ret = Client.create(config);
+    return ret;
+  }
+
+  @Override
+  public List<RangerPolicy> changeDataSet(List<RangerPolicy> rangerPolicies, String sourceDbName,
+                                          String targetDbName) {
+    if (sourceDbName.endsWith("/")) {
+      sourceDbName = StringUtils.removePattern(sourceDbName, "/+$");
+    }
+    if (targetDbName.endsWith("/")) {
+      targetDbName = StringUtils.removePattern(targetDbName, "/+$");
+    }
+    if (targetDbName.equals(sourceDbName)) {
+      return rangerPolicies;
+    }
+    if (CollectionUtils.isNotEmpty(rangerPolicies)) {
+      Map<String, RangerPolicy.RangerPolicyResource> rangerPolicyResourceMap = null;
+      RangerPolicy.RangerPolicyResource rangerPolicyResource = null;
+      List<String> resourceNameList = null;
+      for (RangerPolicy rangerPolicy : rangerPolicies) {
+        if (rangerPolicy != null) {
+          rangerPolicyResourceMap = rangerPolicy.getResources();
+          if (rangerPolicyResourceMap != null) {
+            rangerPolicyResource = rangerPolicyResourceMap.get("database");
+            if (rangerPolicyResource != null) {
+              resourceNameList = rangerPolicyResource.getValues();
+              if (CollectionUtils.isNotEmpty(resourceNameList)) {
+                for (int i = 0; i < resourceNameList.size(); i++) {
+                  String resourceName = resourceNameList.get(i);
+                  if (resourceName.equals(sourceDbName)) {
+                    resourceNameList.set(i, targetDbName);
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+    return rangerPolicies;
+  }
+
+  private Path writeExportedRangerPoliciesToJsonFile(String jsonString, String fileName, Path stagingDirPath)
+      throws Exception {
+    String filePath = "";
+    Path newPath = null;
+    FSDataOutputStream outStream = null;
+    OutputStreamWriter writer = null;
+    try {
+      if (!StringUtils.isEmpty(jsonString)) {
+        FileSystem fileSystem = getFileSystem(stagingDirPath);
+        if (fileSystem != null) {

Review comment:
       Shouldn't it fail when fileSystem is null?

##########
File path: ql/src/test/org/apache/hadoop/hive/ql/exec/repl/TestRangerDumpTask.java
##########
@@ -0,0 +1,123 @@
+  /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hive.ql.exec.repl;
+
+import com.google.gson.Gson;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.ql.exec.repl.ranger.RangerExportPolicyList;
+import org.apache.hadoop.hive.ql.exec.repl.ranger.RangerRestClientImpl;
+import org.apache.hadoop.hive.ql.exec.repl.ranger.RangerPolicy;
+import org.apache.hadoop.hive.ql.exec.repl.util.ReplUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+
+import static org.apache.hadoop.hive.conf.HiveConf.ConfVars.REPL_AUTHORIZATION_PROVIDER_SERVICE_ENDPOINT;
+import static org.apache.hadoop.hive.conf.HiveConf.ConfVars.REPL_RANGER_SERVICE_NAME;
+
+  @RunWith(MockitoJUnitRunner.class)
+public class TestRangerDumpTask {
+
+  protected static final Logger LOG = LoggerFactory.getLogger(TestRangerDumpTask.class);
+  private RangerDumpTask task;
+
+  @Mock
+  private RangerRestClientImpl mockClient;
+
+  @Mock
+  private HiveConf conf;
+
+  @Mock
+  private RangerDumpWork work;
+
+  @Before
+  public void setup() throws Exception {
+    task = new RangerDumpTask(mockClient, conf, work);
+    Mockito.when(mockClient.removeMultiResourcePolicies(Mockito.anyList())).thenCallRealMethod();
+    Mockito.when(mockClient.saveRangerPoliciesToFile(Mockito.any(), Mockito.any(), Mockito.anyString()))
+        .thenCallRealMethod();
+    Mockito.when(mockClient.readRangerPoliciesFromJsonFile(Mockito.any())).thenCallRealMethod();
+    Mockito.when(mockClient.checkConnection(Mockito.anyString())).thenReturn(true);
+  }
+
+  @Test
+  public void testFailureInvalidAuthProviderEndpoint() throws Exception {
+    Mockito.when(conf.getVar(REPL_AUTHORIZATION_PROVIDER_SERVICE_ENDPOINT)).thenReturn(null);
+    int status = task.execute();
+    Assert.assertEquals(40000, status);
+  }
+
+  @Test
+  public void testSuccessValidAuthProviderEndpoint() throws Exception {
+    RangerExportPolicyList rangerPolicyList = new RangerExportPolicyList();
+    rangerPolicyList.setPolicies(new ArrayList<RangerPolicy>());
+    Mockito.when(mockClient.exportRangerPolicies(Mockito.anyString(), Mockito.anyString(), Mockito.anyString()))
+        .thenReturn(rangerPolicyList);
+    Mockito.when(conf.getVar(REPL_AUTHORIZATION_PROVIDER_SERVICE_ENDPOINT)).thenReturn("rangerEndpoint");
+    Mockito.when(conf.getVar(REPL_RANGER_SERVICE_NAME)).thenReturn("cm_hive");
+    Mockito.when(work.getDbName()).thenReturn("testdb");
+    int status = task.execute();
+    Assert.assertEquals(0, status);
+  }
+
+  @Test
+  public void testSuccessNonEmptyRangerPolicies() throws Exception {
+    String rangerResponse = "{\"metaDataInfo\":{\"Host name\":\"quasar-nnwpyd-1.quasar-nnwpyd.root.hwx.site\","

Review comment:
       Use some example hostname under apache.org domain

##########
File path: ql/src/java/org/apache/hadoop/hive/ql/exec/repl/ranger/RangerRestClientImpl.java
##########
@@ -0,0 +1,356 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.ql.exec.repl.ranger;
+
+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.WebResource;
+import com.sun.jersey.api.client.config.ClientConfig;
+import com.sun.jersey.api.client.config.DefaultClientConfig;
+import com.sun.jersey.multipart.FormDataMultiPart;
+import com.sun.jersey.multipart.MultiPart;
+import com.sun.jersey.multipart.file.StreamDataBodyPart;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.eclipse.jetty.util.MultiPartWriter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.MediaType;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.File;
+import java.io.Reader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+
+/**
+ * RangerRestClientImpl to connect to Ranger and export policies.
+ */
+public class RangerRestClientImpl implements RangerRestClient {
+  private static final Logger LOG = LoggerFactory.getLogger(RangerRestClientImpl.class);
+  private static final String RANGER_REST_URL_EXPORTJSONFILE = "/service/plugins/policies/exportJson";
+  private static final String RANGER_REST_URL_IMPORTJSONFILE =
+      "/service/plugins/policies/importPoliciesFromFile?updateIfExists=true";
+
+  public RangerExportPolicyList exportRangerPolicies(String sourceRangerEndpoint,
+                                                     String dbName, String rangerHiveServiceName) throws Exception {
+    LOG.info("Ranger endpoint for cluster " + sourceRangerEndpoint);
+    ClientResponse clientResp = null;
+    String uri = null;
+    if (!StringUtils.isEmpty(rangerHiveServiceName)) {
+      uri = RANGER_REST_URL_EXPORTJSONFILE + "?serviceName=" + rangerHiveServiceName + "&polResource="
+          + dbName + "&resource:database=" + dbName
+          + "&serviceType=hive&resourceMatchScope=self_or_ancestor&resourceMatch=full";
+    }
+    if (sourceRangerEndpoint.endsWith("/")) {
+      sourceRangerEndpoint = StringUtils.removePattern(sourceRangerEndpoint, "/+$");
+    }
+    String url = sourceRangerEndpoint + (uri != null ? (uri.startsWith("/") ? uri : ("/" + uri)) : "");
+    LOG.debug("URL to export policies from source Ranger: {}", url);
+    RangerExportPolicyList rangerExportPolicyList = new RangerExportPolicyList();
+    WebResource.Builder builder = getRangerResourceBuilder(url);
+    clientResp = builder.get(ClientResponse.class);
+
+    String response = null;
+    if (clientResp != null) {
+      if (clientResp.getStatus() == HttpServletResponse.SC_OK) {
+        Gson gson = new GsonBuilder().create();
+        response = clientResp.getEntity(String.class);
+        LOG.debug("Response received for ranger export {} ", response);
+        if (StringUtils.isNotEmpty(response)) {
+          rangerExportPolicyList = gson.fromJson(response, RangerExportPolicyList.class);
+          return rangerExportPolicyList;
+        }
+      } else if (clientResp.getStatus() == HttpServletResponse.SC_NO_CONTENT) {
+        LOG.debug("Ranger policy export request returned empty list");
+        return rangerExportPolicyList;
+      } else if (clientResp.getStatus() == HttpServletResponse.SC_UNAUTHORIZED) {
+        throw new Exception("Authentication Failure while communicating to Ranger admin");
+      } else if (clientResp.getStatus() == HttpServletResponse.SC_FORBIDDEN) {
+        throw new Exception("Authorization Failure while communicating to Ranger admin");
+      }
+    }
+    if (StringUtils.isEmpty(response)) {
+      LOG.debug("Ranger policy export request returned empty list or failed, Please refer Ranger admin logs.");
+    }
+    return rangerExportPolicyList;
+  }
+
+  public List<RangerPolicy> removeMultiResourcePolicies(List<RangerPolicy> rangerPolicies) {
+    List<RangerPolicy> rangerPoliciesToImport = new ArrayList<RangerPolicy>();
+    if (CollectionUtils.isNotEmpty(rangerPolicies)) {
+      Map<String, RangerPolicy.RangerPolicyResource> rangerPolicyResourceMap = null;
+      RangerPolicy.RangerPolicyResource rangerPolicyResource = null;
+      List<String> resourceNameList = null;
+      for (RangerPolicy rangerPolicy : rangerPolicies) {
+        if (rangerPolicy != null) {
+          rangerPolicyResourceMap = rangerPolicy.getResources();
+          if (rangerPolicyResourceMap != null) {
+            rangerPolicyResource = rangerPolicyResourceMap.get("database");
+            if (rangerPolicyResource != null) {
+              resourceNameList = rangerPolicyResource.getValues();
+              if (CollectionUtils.isNotEmpty(resourceNameList) && resourceNameList.size() == 1) {
+                rangerPoliciesToImport.add(rangerPolicy);
+              }
+            }
+          }
+        }
+      }
+    }
+    return rangerPoliciesToImport;
+  }
+
+  @Override
+  public RangerExportPolicyList importRangerPolicies(RangerExportPolicyList rangerExportPolicyList, String dbName,
+                                                     String baseUrl,
+                                                     String rangerHiveServiceName)
+      throws Exception {
+    String sourceClusterServiceName = null;
+    String serviceMapJsonFileName = "hive_servicemap.json";
+    String rangerPoliciesJsonFileName = "hive_replicationPolicies.json";
+    String uri = RANGER_REST_URL_IMPORTJSONFILE + "&polResource=" + dbName;
+
+    if (rangerExportPolicyList.getPolicies().size() > 0) {

Review comment:
       replace with rangerExportPolicyList.getPolicies().isEmpty()

##########
File path: ql/src/java/org/apache/hadoop/hive/ql/exec/repl/util/ReplUtils.java
##########
@@ -100,6 +103,10 @@
 
   // Reserved number of items to accommodate operational files in the dump root dir.
   public static final int RESERVED_DIR_ITEMS_COUNT = 10;
+
+  public static final String RANGER_AUTHORIZER = "ranger";
+
+  public static final String HIVE_RANGER_POLICIES_FILE_NAME = "ranger_policies";

Review comment:
       Shouldn't we use extension as well, e.g. ranger_policies.json

##########
File path: ql/src/java/org/apache/hadoop/hive/ql/exec/repl/ranger/RangerRestClientImpl.java
##########
@@ -0,0 +1,356 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.ql.exec.repl.ranger;
+
+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.WebResource;
+import com.sun.jersey.api.client.config.ClientConfig;
+import com.sun.jersey.api.client.config.DefaultClientConfig;
+import com.sun.jersey.multipart.FormDataMultiPart;
+import com.sun.jersey.multipart.MultiPart;
+import com.sun.jersey.multipart.file.StreamDataBodyPart;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.eclipse.jetty.util.MultiPartWriter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.MediaType;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.File;
+import java.io.Reader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+
+/**
+ * RangerRestClientImpl to connect to Ranger and export policies.
+ */
+public class RangerRestClientImpl implements RangerRestClient {
+  private static final Logger LOG = LoggerFactory.getLogger(RangerRestClientImpl.class);
+  private static final String RANGER_REST_URL_EXPORTJSONFILE = "/service/plugins/policies/exportJson";
+  private static final String RANGER_REST_URL_IMPORTJSONFILE =
+      "/service/plugins/policies/importPoliciesFromFile?updateIfExists=true";
+
+  public RangerExportPolicyList exportRangerPolicies(String sourceRangerEndpoint,
+                                                     String dbName, String rangerHiveServiceName) throws Exception {
+    LOG.info("Ranger endpoint for cluster " + sourceRangerEndpoint);
+    ClientResponse clientResp = null;
+    String uri = null;
+    if (!StringUtils.isEmpty(rangerHiveServiceName)) {
+      uri = RANGER_REST_URL_EXPORTJSONFILE + "?serviceName=" + rangerHiveServiceName + "&polResource="
+          + dbName + "&resource:database=" + dbName
+          + "&serviceType=hive&resourceMatchScope=self_or_ancestor&resourceMatch=full";
+    }
+    if (sourceRangerEndpoint.endsWith("/")) {
+      sourceRangerEndpoint = StringUtils.removePattern(sourceRangerEndpoint, "/+$");
+    }
+    String url = sourceRangerEndpoint + (uri != null ? (uri.startsWith("/") ? uri : ("/" + uri)) : "");
+    LOG.debug("URL to export policies from source Ranger: {}", url);
+    RangerExportPolicyList rangerExportPolicyList = new RangerExportPolicyList();
+    WebResource.Builder builder = getRangerResourceBuilder(url);
+    clientResp = builder.get(ClientResponse.class);
+
+    String response = null;
+    if (clientResp != null) {
+      if (clientResp.getStatus() == HttpServletResponse.SC_OK) {
+        Gson gson = new GsonBuilder().create();
+        response = clientResp.getEntity(String.class);
+        LOG.debug("Response received for ranger export {} ", response);
+        if (StringUtils.isNotEmpty(response)) {
+          rangerExportPolicyList = gson.fromJson(response, RangerExportPolicyList.class);
+          return rangerExportPolicyList;
+        }
+      } else if (clientResp.getStatus() == HttpServletResponse.SC_NO_CONTENT) {
+        LOG.debug("Ranger policy export request returned empty list");
+        return rangerExportPolicyList;
+      } else if (clientResp.getStatus() == HttpServletResponse.SC_UNAUTHORIZED) {
+        throw new Exception("Authentication Failure while communicating to Ranger admin");
+      } else if (clientResp.getStatus() == HttpServletResponse.SC_FORBIDDEN) {
+        throw new Exception("Authorization Failure while communicating to Ranger admin");
+      }
+    }
+    if (StringUtils.isEmpty(response)) {
+      LOG.debug("Ranger policy export request returned empty list or failed, Please refer Ranger admin logs.");
+    }
+    return rangerExportPolicyList;
+  }
+
+  public List<RangerPolicy> removeMultiResourcePolicies(List<RangerPolicy> rangerPolicies) {
+    List<RangerPolicy> rangerPoliciesToImport = new ArrayList<RangerPolicy>();
+    if (CollectionUtils.isNotEmpty(rangerPolicies)) {
+      Map<String, RangerPolicy.RangerPolicyResource> rangerPolicyResourceMap = null;
+      RangerPolicy.RangerPolicyResource rangerPolicyResource = null;
+      List<String> resourceNameList = null;
+      for (RangerPolicy rangerPolicy : rangerPolicies) {
+        if (rangerPolicy != null) {
+          rangerPolicyResourceMap = rangerPolicy.getResources();
+          if (rangerPolicyResourceMap != null) {
+            rangerPolicyResource = rangerPolicyResourceMap.get("database");
+            if (rangerPolicyResource != null) {
+              resourceNameList = rangerPolicyResource.getValues();
+              if (CollectionUtils.isNotEmpty(resourceNameList) && resourceNameList.size() == 1) {
+                rangerPoliciesToImport.add(rangerPolicy);
+              }
+            }
+          }
+        }
+      }
+    }
+    return rangerPoliciesToImport;
+  }
+
+  @Override
+  public RangerExportPolicyList importRangerPolicies(RangerExportPolicyList rangerExportPolicyList, String dbName,
+                                                     String baseUrl,
+                                                     String rangerHiveServiceName)
+      throws Exception {
+    String sourceClusterServiceName = null;
+    String serviceMapJsonFileName = "hive_servicemap.json";
+    String rangerPoliciesJsonFileName = "hive_replicationPolicies.json";
+    String uri = RANGER_REST_URL_IMPORTJSONFILE + "&polResource=" + dbName;
+
+    if (rangerExportPolicyList.getPolicies().size() > 0) {
+      sourceClusterServiceName = rangerExportPolicyList.getPolicies().get(0).getService();
+    }
+
+    if (StringUtils.isEmpty(sourceClusterServiceName)) {
+      sourceClusterServiceName = rangerHiveServiceName;
+    }
+
+    Map<String, String> serviceMap = new LinkedHashMap<String, String>();
+    if (!StringUtils.isEmpty(sourceClusterServiceName) && !StringUtils.isEmpty(rangerHiveServiceName)) {
+      serviceMap.put(sourceClusterServiceName, rangerHiveServiceName);
+    }
+
+    Gson gson = new GsonBuilder().create();
+    String jsonServiceMap = gson.toJson(serviceMap);
+
+    String jsonRangerExportPolicyList = gson.toJson(rangerExportPolicyList);
+
+    String url = baseUrl
+        + (uri.startsWith("/") ? uri : ("/" + uri));
+
+    LOG.debug("URL to import policies on target Ranger: {}", url);
+    ClientResponse clientResp = null;
+
+    StreamDataBodyPart filePartPolicies = new StreamDataBodyPart("file",
+        new ByteArrayInputStream(jsonRangerExportPolicyList.getBytes(StandardCharsets.UTF_8)),
+        rangerPoliciesJsonFileName);
+    StreamDataBodyPart filePartServiceMap = new StreamDataBodyPart("servicesMapJson",
+        new ByteArrayInputStream(jsonServiceMap.getBytes(StandardCharsets.UTF_8)), serviceMapJsonFileName);
+
+    FormDataMultiPart formDataMultiPart = new FormDataMultiPart();
+    MultiPart multipartEntity = null;
+    try {
+      multipartEntity = formDataMultiPart.bodyPart(filePartPolicies).bodyPart(filePartServiceMap);
+      WebResource.Builder builder = getRangerResourceBuilder(url);
+      clientResp = builder.accept(MediaType.APPLICATION_JSON).type(MediaType.MULTIPART_FORM_DATA)
+          .post(ClientResponse.class, multipartEntity);
+      if (clientResp != null) {
+        if (clientResp.getStatus() == HttpServletResponse.SC_NO_CONTENT) {
+          LOG.debug("Ranger policy import finished successfully");
+
+        } else if (clientResp.getStatus() == HttpServletResponse.SC_UNAUTHORIZED) {
+          throw new Exception("Authentication Failure while communicating to Ranger admin");
+        } else {
+          throw new Exception("Ranger policy import failed, Please refer target Ranger admin logs.");
+        }
+      }
+    } finally {
+      try {
+        if (filePartPolicies != null) {
+          filePartPolicies.cleanup();
+        }
+        if (filePartServiceMap != null) {
+          filePartServiceMap.cleanup();
+        }
+        if (formDataMultiPart != null) {
+          formDataMultiPart.close();
+        }
+        if (multipartEntity != null) {
+          multipartEntity.close();
+        }
+      } catch (IOException e) {
+        LOG.error("Exception occurred while closing resources: {}", e);
+      }
+    }
+    return rangerExportPolicyList;
+  }
+
+  private synchronized Client getRangerClient() {
+    Client ret = null;
+    ClientConfig config = new DefaultClientConfig();
+    config.getClasses().add(MultiPartWriter.class);
+    config.getProperties().put(ClientConfig.PROPERTY_FOLLOW_REDIRECTS, true);
+    ret = Client.create(config);
+    return ret;
+  }
+
+  @Override
+  public List<RangerPolicy> changeDataSet(List<RangerPolicy> rangerPolicies, String sourceDbName,
+                                          String targetDbName) {
+    if (sourceDbName.endsWith("/")) {
+      sourceDbName = StringUtils.removePattern(sourceDbName, "/+$");
+    }
+    if (targetDbName.endsWith("/")) {
+      targetDbName = StringUtils.removePattern(targetDbName, "/+$");
+    }
+    if (targetDbName.equals(sourceDbName)) {
+      return rangerPolicies;
+    }
+    if (CollectionUtils.isNotEmpty(rangerPolicies)) {
+      Map<String, RangerPolicy.RangerPolicyResource> rangerPolicyResourceMap = null;
+      RangerPolicy.RangerPolicyResource rangerPolicyResource = null;
+      List<String> resourceNameList = null;
+      for (RangerPolicy rangerPolicy : rangerPolicies) {
+        if (rangerPolicy != null) {
+          rangerPolicyResourceMap = rangerPolicy.getResources();
+          if (rangerPolicyResourceMap != null) {
+            rangerPolicyResource = rangerPolicyResourceMap.get("database");
+            if (rangerPolicyResource != null) {
+              resourceNameList = rangerPolicyResource.getValues();
+              if (CollectionUtils.isNotEmpty(resourceNameList)) {
+                for (int i = 0; i < resourceNameList.size(); i++) {
+                  String resourceName = resourceNameList.get(i);
+                  if (resourceName.equals(sourceDbName)) {
+                    resourceNameList.set(i, targetDbName);
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+    return rangerPolicies;
+  }
+
+  private Path writeExportedRangerPoliciesToJsonFile(String jsonString, String fileName, Path stagingDirPath)

Review comment:
       Make it as retriable command.

##########
File path: ql/src/java/org/apache/hadoop/hive/ql/exec/repl/ranger/RangerRestClientImpl.java
##########
@@ -0,0 +1,356 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.ql.exec.repl.ranger;
+
+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.WebResource;
+import com.sun.jersey.api.client.config.ClientConfig;
+import com.sun.jersey.api.client.config.DefaultClientConfig;
+import com.sun.jersey.multipart.FormDataMultiPart;
+import com.sun.jersey.multipart.MultiPart;
+import com.sun.jersey.multipart.file.StreamDataBodyPart;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.eclipse.jetty.util.MultiPartWriter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.MediaType;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.File;
+import java.io.Reader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+
+/**
+ * RangerRestClientImpl to connect to Ranger and export policies.
+ */
+public class RangerRestClientImpl implements RangerRestClient {
+  private static final Logger LOG = LoggerFactory.getLogger(RangerRestClientImpl.class);
+  private static final String RANGER_REST_URL_EXPORTJSONFILE = "/service/plugins/policies/exportJson";
+  private static final String RANGER_REST_URL_IMPORTJSONFILE =
+      "/service/plugins/policies/importPoliciesFromFile?updateIfExists=true";
+
+  public RangerExportPolicyList exportRangerPolicies(String sourceRangerEndpoint,
+                                                     String dbName, String rangerHiveServiceName) throws Exception {
+    LOG.info("Ranger endpoint for cluster " + sourceRangerEndpoint);
+    ClientResponse clientResp = null;
+    String uri = null;
+    if (!StringUtils.isEmpty(rangerHiveServiceName)) {
+      uri = RANGER_REST_URL_EXPORTJSONFILE + "?serviceName=" + rangerHiveServiceName + "&polResource="
+          + dbName + "&resource:database=" + dbName
+          + "&serviceType=hive&resourceMatchScope=self_or_ancestor&resourceMatch=full";
+    }
+    if (sourceRangerEndpoint.endsWith("/")) {
+      sourceRangerEndpoint = StringUtils.removePattern(sourceRangerEndpoint, "/+$");
+    }
+    String url = sourceRangerEndpoint + (uri != null ? (uri.startsWith("/") ? uri : ("/" + uri)) : "");
+    LOG.debug("URL to export policies from source Ranger: {}", url);
+    RangerExportPolicyList rangerExportPolicyList = new RangerExportPolicyList();
+    WebResource.Builder builder = getRangerResourceBuilder(url);
+    clientResp = builder.get(ClientResponse.class);
+
+    String response = null;
+    if (clientResp != null) {
+      if (clientResp.getStatus() == HttpServletResponse.SC_OK) {
+        Gson gson = new GsonBuilder().create();
+        response = clientResp.getEntity(String.class);
+        LOG.debug("Response received for ranger export {} ", response);
+        if (StringUtils.isNotEmpty(response)) {
+          rangerExportPolicyList = gson.fromJson(response, RangerExportPolicyList.class);
+          return rangerExportPolicyList;
+        }
+      } else if (clientResp.getStatus() == HttpServletResponse.SC_NO_CONTENT) {
+        LOG.debug("Ranger policy export request returned empty list");
+        return rangerExportPolicyList;
+      } else if (clientResp.getStatus() == HttpServletResponse.SC_UNAUTHORIZED) {

Review comment:
       Should we introduce new exception MetadatReplException or so, and use that during metadata replication?

##########
File path: ql/src/java/org/apache/hadoop/hive/ql/exec/repl/ranger/RangerRestClientImpl.java
##########
@@ -0,0 +1,356 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.ql.exec.repl.ranger;
+
+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.WebResource;
+import com.sun.jersey.api.client.config.ClientConfig;
+import com.sun.jersey.api.client.config.DefaultClientConfig;
+import com.sun.jersey.multipart.FormDataMultiPart;
+import com.sun.jersey.multipart.MultiPart;
+import com.sun.jersey.multipart.file.StreamDataBodyPart;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.eclipse.jetty.util.MultiPartWriter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.MediaType;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.File;
+import java.io.Reader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+
+/**
+ * RangerRestClientImpl to connect to Ranger and export policies.
+ */
+public class RangerRestClientImpl implements RangerRestClient {
+  private static final Logger LOG = LoggerFactory.getLogger(RangerRestClientImpl.class);
+  private static final String RANGER_REST_URL_EXPORTJSONFILE = "/service/plugins/policies/exportJson";
+  private static final String RANGER_REST_URL_IMPORTJSONFILE =
+      "/service/plugins/policies/importPoliciesFromFile?updateIfExists=true";
+
+  public RangerExportPolicyList exportRangerPolicies(String sourceRangerEndpoint,
+                                                     String dbName, String rangerHiveServiceName) throws Exception {
+    LOG.info("Ranger endpoint for cluster " + sourceRangerEndpoint);
+    ClientResponse clientResp = null;
+    String uri = null;
+    if (!StringUtils.isEmpty(rangerHiveServiceName)) {
+      uri = RANGER_REST_URL_EXPORTJSONFILE + "?serviceName=" + rangerHiveServiceName + "&polResource="
+          + dbName + "&resource:database=" + dbName
+          + "&serviceType=hive&resourceMatchScope=self_or_ancestor&resourceMatch=full";
+    }
+    if (sourceRangerEndpoint.endsWith("/")) {
+      sourceRangerEndpoint = StringUtils.removePattern(sourceRangerEndpoint, "/+$");
+    }
+    String url = sourceRangerEndpoint + (uri != null ? (uri.startsWith("/") ? uri : ("/" + uri)) : "");
+    LOG.debug("URL to export policies from source Ranger: {}", url);
+    RangerExportPolicyList rangerExportPolicyList = new RangerExportPolicyList();
+    WebResource.Builder builder = getRangerResourceBuilder(url);
+    clientResp = builder.get(ClientResponse.class);
+
+    String response = null;
+    if (clientResp != null) {
+      if (clientResp.getStatus() == HttpServletResponse.SC_OK) {
+        Gson gson = new GsonBuilder().create();
+        response = clientResp.getEntity(String.class);
+        LOG.debug("Response received for ranger export {} ", response);
+        if (StringUtils.isNotEmpty(response)) {
+          rangerExportPolicyList = gson.fromJson(response, RangerExportPolicyList.class);
+          return rangerExportPolicyList;
+        }
+      } else if (clientResp.getStatus() == HttpServletResponse.SC_NO_CONTENT) {
+        LOG.debug("Ranger policy export request returned empty list");
+        return rangerExportPolicyList;
+      } else if (clientResp.getStatus() == HttpServletResponse.SC_UNAUTHORIZED) {
+        throw new Exception("Authentication Failure while communicating to Ranger admin");
+      } else if (clientResp.getStatus() == HttpServletResponse.SC_FORBIDDEN) {
+        throw new Exception("Authorization Failure while communicating to Ranger admin");
+      }
+    }
+    if (StringUtils.isEmpty(response)) {
+      LOG.debug("Ranger policy export request returned empty list or failed, Please refer Ranger admin logs.");
+    }
+    return rangerExportPolicyList;
+  }
+
+  public List<RangerPolicy> removeMultiResourcePolicies(List<RangerPolicy> rangerPolicies) {
+    List<RangerPolicy> rangerPoliciesToImport = new ArrayList<RangerPolicy>();
+    if (CollectionUtils.isNotEmpty(rangerPolicies)) {
+      Map<String, RangerPolicy.RangerPolicyResource> rangerPolicyResourceMap = null;
+      RangerPolicy.RangerPolicyResource rangerPolicyResource = null;
+      List<String> resourceNameList = null;
+      for (RangerPolicy rangerPolicy : rangerPolicies) {
+        if (rangerPolicy != null) {
+          rangerPolicyResourceMap = rangerPolicy.getResources();
+          if (rangerPolicyResourceMap != null) {
+            rangerPolicyResource = rangerPolicyResourceMap.get("database");
+            if (rangerPolicyResource != null) {
+              resourceNameList = rangerPolicyResource.getValues();
+              if (CollectionUtils.isNotEmpty(resourceNameList) && resourceNameList.size() == 1) {
+                rangerPoliciesToImport.add(rangerPolicy);
+              }
+            }
+          }
+        }
+      }
+    }
+    return rangerPoliciesToImport;
+  }
+
+  @Override
+  public RangerExportPolicyList importRangerPolicies(RangerExportPolicyList rangerExportPolicyList, String dbName,
+                                                     String baseUrl,
+                                                     String rangerHiveServiceName)
+      throws Exception {
+    String sourceClusterServiceName = null;
+    String serviceMapJsonFileName = "hive_servicemap.json";
+    String rangerPoliciesJsonFileName = "hive_replicationPolicies.json";
+    String uri = RANGER_REST_URL_IMPORTJSONFILE + "&polResource=" + dbName;
+
+    if (rangerExportPolicyList.getPolicies().size() > 0) {
+      sourceClusterServiceName = rangerExportPolicyList.getPolicies().get(0).getService();
+    }
+
+    if (StringUtils.isEmpty(sourceClusterServiceName)) {
+      sourceClusterServiceName = rangerHiveServiceName;
+    }
+
+    Map<String, String> serviceMap = new LinkedHashMap<String, String>();
+    if (!StringUtils.isEmpty(sourceClusterServiceName) && !StringUtils.isEmpty(rangerHiveServiceName)) {
+      serviceMap.put(sourceClusterServiceName, rangerHiveServiceName);
+    }
+
+    Gson gson = new GsonBuilder().create();
+    String jsonServiceMap = gson.toJson(serviceMap);
+
+    String jsonRangerExportPolicyList = gson.toJson(rangerExportPolicyList);
+
+    String url = baseUrl
+        + (uri.startsWith("/") ? uri : ("/" + uri));
+
+    LOG.debug("URL to import policies on target Ranger: {}", url);
+    ClientResponse clientResp = null;
+
+    StreamDataBodyPart filePartPolicies = new StreamDataBodyPart("file",
+        new ByteArrayInputStream(jsonRangerExportPolicyList.getBytes(StandardCharsets.UTF_8)),
+        rangerPoliciesJsonFileName);
+    StreamDataBodyPart filePartServiceMap = new StreamDataBodyPart("servicesMapJson",
+        new ByteArrayInputStream(jsonServiceMap.getBytes(StandardCharsets.UTF_8)), serviceMapJsonFileName);
+
+    FormDataMultiPart formDataMultiPart = new FormDataMultiPart();
+    MultiPart multipartEntity = null;
+    try {
+      multipartEntity = formDataMultiPart.bodyPart(filePartPolicies).bodyPart(filePartServiceMap);
+      WebResource.Builder builder = getRangerResourceBuilder(url);
+      clientResp = builder.accept(MediaType.APPLICATION_JSON).type(MediaType.MULTIPART_FORM_DATA)
+          .post(ClientResponse.class, multipartEntity);
+      if (clientResp != null) {
+        if (clientResp.getStatus() == HttpServletResponse.SC_NO_CONTENT) {
+          LOG.debug("Ranger policy import finished successfully");
+
+        } else if (clientResp.getStatus() == HttpServletResponse.SC_UNAUTHORIZED) {
+          throw new Exception("Authentication Failure while communicating to Ranger admin");
+        } else {
+          throw new Exception("Ranger policy import failed, Please refer target Ranger admin logs.");
+        }
+      }
+    } finally {
+      try {
+        if (filePartPolicies != null) {
+          filePartPolicies.cleanup();
+        }
+        if (filePartServiceMap != null) {
+          filePartServiceMap.cleanup();
+        }
+        if (formDataMultiPart != null) {
+          formDataMultiPart.close();
+        }
+        if (multipartEntity != null) {
+          multipartEntity.close();
+        }
+      } catch (IOException e) {
+        LOG.error("Exception occurred while closing resources: {}", e);
+      }
+    }
+    return rangerExportPolicyList;
+  }
+
+  private synchronized Client getRangerClient() {
+    Client ret = null;
+    ClientConfig config = new DefaultClientConfig();
+    config.getClasses().add(MultiPartWriter.class);
+    config.getProperties().put(ClientConfig.PROPERTY_FOLLOW_REDIRECTS, true);
+    ret = Client.create(config);
+    return ret;
+  }
+
+  @Override
+  public List<RangerPolicy> changeDataSet(List<RangerPolicy> rangerPolicies, String sourceDbName,
+                                          String targetDbName) {
+    if (sourceDbName.endsWith("/")) {
+      sourceDbName = StringUtils.removePattern(sourceDbName, "/+$");
+    }
+    if (targetDbName.endsWith("/")) {
+      targetDbName = StringUtils.removePattern(targetDbName, "/+$");
+    }
+    if (targetDbName.equals(sourceDbName)) {
+      return rangerPolicies;
+    }
+    if (CollectionUtils.isNotEmpty(rangerPolicies)) {
+      Map<String, RangerPolicy.RangerPolicyResource> rangerPolicyResourceMap = null;
+      RangerPolicy.RangerPolicyResource rangerPolicyResource = null;
+      List<String> resourceNameList = null;
+      for (RangerPolicy rangerPolicy : rangerPolicies) {
+        if (rangerPolicy != null) {
+          rangerPolicyResourceMap = rangerPolicy.getResources();
+          if (rangerPolicyResourceMap != null) {
+            rangerPolicyResource = rangerPolicyResourceMap.get("database");
+            if (rangerPolicyResource != null) {
+              resourceNameList = rangerPolicyResource.getValues();
+              if (CollectionUtils.isNotEmpty(resourceNameList)) {
+                for (int i = 0; i < resourceNameList.size(); i++) {
+                  String resourceName = resourceNameList.get(i);
+                  if (resourceName.equals(sourceDbName)) {
+                    resourceNameList.set(i, targetDbName);
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+    return rangerPolicies;
+  }
+
+  private Path writeExportedRangerPoliciesToJsonFile(String jsonString, String fileName, Path stagingDirPath)
+      throws Exception {
+    String filePath = "";
+    Path newPath = null;
+    FSDataOutputStream outStream = null;
+    OutputStreamWriter writer = null;
+    try {
+      if (!StringUtils.isEmpty(jsonString)) {
+        FileSystem fileSystem = getFileSystem(stagingDirPath);
+        if (fileSystem != null) {
+          if (!fileSystem.exists(stagingDirPath)) {
+            fileSystem.mkdirs(stagingDirPath);
+          }
+          newPath = stagingDirPath.suffix(File.separator + fileName);
+          outStream = fileSystem.create(newPath, true);
+          writer = new OutputStreamWriter(outStream, "UTF-8");
+          writer.write(jsonString);
+        }
+      }
+    } catch (IOException ex) {
+      if (newPath != null) {
+        filePath = newPath.toString();
+      }
+      throw new Exception("Failed to write json string to file:" + filePath, ex);
+    } catch (Exception ex) {
+      if (newPath != null) {
+        filePath = newPath.toString();
+      }
+      throw new Exception("Failed to write json string to file:" + filePath, ex);
+    } finally {
+      try {
+        if (writer != null) {
+          writer.close();
+        }
+        if (outStream != null) {
+          outStream.close();
+        }
+      } catch (Exception ex) {
+        LOG.error("Unable to close writer/outStream.", ex);

Review comment:
       In other places, for a failure during stream close, we are throwing exception back. Shouldn't we be consistent in this case as well?

##########
File path: ql/src/java/org/apache/hadoop/hive/ql/exec/repl/ranger/RangerPolicy.java
##########
@@ -0,0 +1,1513 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.ql.exec.repl.ranger;
+
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * RangerPolicy class to contain Ranger Policy details.
+ */
+@JsonAutoDetect(fieldVisibility = Visibility.ANY)
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+public class RangerPolicy extends RangerBaseModelObject implements java.io.Serializable {
+  public static final int POLICY_TYPE_ACCESS = 0;
+  public static final int POLICY_TYPE_DATAMASK = 1;
+  public static final int POLICY_TYPE_ROWFILTER = 2;
+
+  public static final int[] POLICY_TYPES = new int[]{
+      POLICY_TYPE_ACCESS,
+      POLICY_TYPE_DATAMASK,
+      POLICY_TYPE_ROWFILTER,
+  };
+
+  public static final String MASK_TYPE_NULL = "MASK_NULL";
+  public static final String MASK_TYPE_NONE = "MASK_NONE";
+  public static final String MASK_TYPE_CUSTOM = "CUSTOM";
+
+  private static final long serialVersionUID = 1L;
+
+  private String service;
+  private String name;
+  private Integer policyType;
+  private String description;
+  private String resourceSignature;
+  private Boolean isAuditEnabled;
+  private Map<String, RangerPolicyResource> resources;
+  private List<RangerPolicyItem> policyItems;
+  private List<RangerPolicyItem> denyPolicyItems;
+  private List<RangerPolicyItem> allowExceptions;
+  private List<RangerPolicyItem> denyExceptions;
+  private List<RangerDataMaskPolicyItem> dataMaskPolicyItems;
+  private List<RangerRowFilterPolicyItem> rowFilterPolicyItems;
+
+
+  /**
+   * Ranger Policy default constructor.
+   */
+  public RangerPolicy() {
+    this(null, null, null, null, null, null, null);
+  }
+
+  /**
+   * @param service
+   * @param name
+   * @param policyType
+   * @param description
+   * @param resources
+   * @param policyItems
+   * @param resourceSignature TODO
+   */
+  public RangerPolicy(String service, String name, Integer policyType, String description,
+                      Map<String, RangerPolicyResource> resources, List<RangerPolicyItem> policyItems,
+                      String resourceSignature) {
+    super();
+    setService(service);
+    setName(name);
+    setPolicyType(policyType);
+    setDescription(description);
+    setResourceSignature(resourceSignature);
+    setIsAuditEnabled(null);
+    setResources(resources);
+    setPolicyItems(policyItems);
+    setDenyPolicyItems(null);
+    setAllowExceptions(null);
+    setDenyExceptions(null);
+    setDataMaskPolicyItems(null);
+    setRowFilterPolicyItems(null);
+  }
+
+  /**
+   * @param other
+   */
+  public void updateFrom(RangerPolicy other) {
+    super.updateFrom(other);
+
+    setService(other.getService());
+    setName(other.getName());
+    setPolicyType(other.getPolicyType());
+    setDescription(other.getDescription());
+    setResourceSignature(other.getResourceSignature());
+    setIsAuditEnabled(other.getIsAuditEnabled());
+    setResources(other.getResources());
+    setPolicyItems(other.getPolicyItems());
+    setDenyPolicyItems(other.getDenyPolicyItems());
+    setAllowExceptions(other.getAllowExceptions());
+    setDenyExceptions(other.getDenyExceptions());
+    setDataMaskPolicyItems(other.getDataMaskPolicyItems());
+    setRowFilterPolicyItems(other.getRowFilterPolicyItems());
+  }
+
+  /**
+   * @return the type
+   */
+  public String getService() {
+    return service;
+  }
+
+  /**
+   * @param service the type to set
+   */
+  public void setService(String service) {
+    this.service = service;
+  }
+
+  /**
+   * @return the name
+   */
+  public String getName() {
+    return name;
+  }
+
+  /**
+   * @param name the name to set
+   */
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  /**
+   * @return the policyType
+   */
+  public Integer getPolicyType() {
+    return policyType;
+  }
+
+  /**
+   * @param policyType the policyType to set
+   */
+  public void setPolicyType(Integer policyType) {
+    this.policyType = policyType;
+  }
+
+  /**
+   * @return the description
+   */
+  public String getDescription() {
+    return description;
+  }
+
+  /**
+   * @param description the description to set
+   */
+  public void setDescription(String description) {
+    this.description = description;
+  }
+
+  /**
+   * @return the resourceSignature
+   */
+  public String getResourceSignature() {
+    return resourceSignature;
+  }
+
+  /**
+   * @param resourceSignature the resourceSignature to set
+   */
+  public void setResourceSignature(String resourceSignature) {
+    this.resourceSignature = resourceSignature;
+  }
+
+  /**
+   * @return the isAuditEnabled
+   */
+  public Boolean getIsAuditEnabled() {
+    return isAuditEnabled;
+  }
+
+  /**
+   * @param isAuditEnabled the isEnabled to set
+   */
+  public void setIsAuditEnabled(Boolean isAuditEnabled) {
+    this.isAuditEnabled = isAuditEnabled == null ? Boolean.TRUE : isAuditEnabled;
+  }
+
+  /**
+   * @return the resources
+   */
+  public Map<String, RangerPolicyResource> getResources() {
+    return resources;
+  }
+
+  /**
+   * @param resources the resources to set
+   */
+  public void setResources(Map<String, RangerPolicyResource> resources) {
+    if (this.resources == null) {
+      this.resources = new HashMap<>();
+    }
+
+    if (this.resources == resources) {
+      return;
+    }
+
+    this.resources.clear();
+
+    if (resources != null) {
+      for (Map.Entry<String, RangerPolicyResource> e : resources.entrySet()) {
+        this.resources.put(e.getKey(), e.getValue());
+      }
+    }
+  }
+
+  /**
+   * @return the policyItems
+   */
+  public List<RangerPolicyItem> getPolicyItems() {
+    return policyItems;
+  }
+
+  /**
+   * @param policyItems the policyItems to set
+   */
+  public void setPolicyItems(List<RangerPolicyItem> policyItems) {
+    if (this.policyItems == null) {
+      this.policyItems = new ArrayList<>();
+    }
+
+    if (this.policyItems == policyItems) {
+      return;
+    }
+
+    this.policyItems.clear();
+
+    if (policyItems != null) {
+      this.policyItems.addAll(policyItems);
+    }
+  }
+
+  /**
+   * @return the denyPolicyItems
+   */
+  public List<RangerPolicyItem> getDenyPolicyItems() {
+    return denyPolicyItems;
+  }
+
+  /**
+   * @param denyPolicyItems the denyPolicyItems to set
+   */
+  public void setDenyPolicyItems(List<RangerPolicyItem> denyPolicyItems) {
+    if (this.denyPolicyItems == null) {
+      this.denyPolicyItems = new ArrayList<>();
+    }
+
+    if (this.denyPolicyItems == denyPolicyItems) {
+      return;
+    }
+
+    this.denyPolicyItems.clear();
+
+    if (denyPolicyItems != null) {
+      this.denyPolicyItems.addAll(denyPolicyItems);
+    }
+  }
+
+  /**
+   * @return the allowExceptions
+   */
+  public List<RangerPolicyItem> getAllowExceptions() {
+    return allowExceptions;
+  }
+
+  /**
+   * @param allowExceptions the allowExceptions to set
+   */
+  public void setAllowExceptions(List<RangerPolicyItem> allowExceptions) {
+    if (this.allowExceptions == null) {
+      this.allowExceptions = new ArrayList<>();
+    }
+
+    if (this.allowExceptions == allowExceptions) {
+      return;
+    }
+
+    this.allowExceptions.clear();
+
+    if (allowExceptions != null) {
+      this.allowExceptions.addAll(allowExceptions);
+    }
+  }
+
+  /**
+   * @return the denyExceptions
+   */
+  public List<RangerPolicyItem> getDenyExceptions() {
+    return denyExceptions;
+  }
+
+  /**
+   * @param denyExceptions the denyExceptions to set
+   */
+  public void setDenyExceptions(List<RangerPolicyItem> denyExceptions) {
+    if (this.denyExceptions == null) {
+      this.denyExceptions = new ArrayList<>();
+    }
+
+    if (this.denyExceptions == denyExceptions) {
+      return;
+    }
+
+    this.denyExceptions.clear();
+
+    if (denyExceptions != null) {
+      this.denyExceptions.addAll(denyExceptions);
+    }
+  }
+
+  public List<RangerDataMaskPolicyItem> getDataMaskPolicyItems() {
+    return dataMaskPolicyItems;
+  }
+
+  public void setDataMaskPolicyItems(List<RangerDataMaskPolicyItem> dataMaskPolicyItems) {
+    if (this.dataMaskPolicyItems == null) {
+      this.dataMaskPolicyItems = new ArrayList<>();
+    }
+
+    if (this.dataMaskPolicyItems == dataMaskPolicyItems) {
+      return;
+    }
+
+    this.dataMaskPolicyItems.clear();
+
+    if (dataMaskPolicyItems != null) {
+      this.dataMaskPolicyItems.addAll(dataMaskPolicyItems);
+    }
+  }
+
+  public List<RangerRowFilterPolicyItem> getRowFilterPolicyItems() {
+    return rowFilterPolicyItems;
+  }
+
+  public void setRowFilterPolicyItems(List<RangerRowFilterPolicyItem> rowFilterPolicyItems) {
+    if (this.rowFilterPolicyItems == null) {
+      this.rowFilterPolicyItems = new ArrayList<>();
+    }
+
+    if (this.rowFilterPolicyItems == rowFilterPolicyItems) {
+      return;
+    }
+
+    this.rowFilterPolicyItems.clear();
+
+    if (rowFilterPolicyItems != null) {
+      this.rowFilterPolicyItems.addAll(rowFilterPolicyItems);
+    }
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder();
+    toString(sb);
+    return sb.toString();
+  }
+
+  public StringBuilder toString(StringBuilder sb) {
+    sb.append("RangerPolicy={");
+
+    super.toString(sb);
+
+    sb.append("service={").append(service).append("} ");
+    sb.append("name={").append(name).append("} ");
+    sb.append("policyType={").append(policyType).append("} ");
+    sb.append("description={").append(description).append("} ");
+    sb.append("resourceSignature={").append(resourceSignature).append("} ");
+    sb.append("isAuditEnabled={").append(isAuditEnabled).append("} ");
+
+    sb.append("resources={");
+    if (resources != null) {
+      for (Map.Entry<String, RangerPolicyResource> e : resources.entrySet()) {
+        sb.append(e.getKey()).append("={");
+        e.getValue().toString(sb);
+        sb.append("} ");
+      }
+    }
+    sb.append("} ");
+
+    sb.append("policyItems={");
+    if (policyItems != null) {
+      for (RangerPolicyItem policyItem : policyItems) {
+        if (policyItem != null) {
+          policyItem.toString(sb);
+        }
+      }
+    }
+    sb.append("} ");
+
+    sb.append("denyPolicyItems={");
+    if (denyPolicyItems != null) {
+      for (RangerPolicyItem policyItem : denyPolicyItems) {
+        if (policyItem != null) {
+          policyItem.toString(sb);
+        }
+      }
+    }
+    sb.append("} ");
+
+    sb.append("allowExceptions={");
+    if (allowExceptions != null) {
+      for (RangerPolicyItem policyItem : allowExceptions) {
+        if (policyItem != null) {
+          policyItem.toString(sb);
+        }
+      }
+    }
+    sb.append("} ");
+
+    sb.append("denyExceptions={");
+    if (denyExceptions != null) {
+      for (RangerPolicyItem policyItem : denyExceptions) {
+        if (policyItem != null) {
+          policyItem.toString(sb);
+        }
+      }
+    }
+    sb.append("} ");
+
+    sb.append("dataMaskPolicyItems={");
+    if (dataMaskPolicyItems != null) {
+      for (RangerDataMaskPolicyItem dataMaskPolicyItem : dataMaskPolicyItems) {
+        if (dataMaskPolicyItem != null) {
+          dataMaskPolicyItem.toString(sb);
+        }
+      }
+    }
+    sb.append("} ");
+
+    sb.append("rowFilterPolicyItems={");
+    if (rowFilterPolicyItems != null) {
+      for (RangerRowFilterPolicyItem rowFilterPolicyItem : rowFilterPolicyItems) {
+        if (rowFilterPolicyItem != null) {
+          rowFilterPolicyItem.toString(sb);
+        }
+      }
+    }
+    sb.append("} ");
+
+    sb.append("}");
+
+    return sb;
+  }
+
+  /**
+   * RangerPolicyResource class to store the resource path values.
+   */
+  @JsonAutoDetect(fieldVisibility = Visibility.ANY)
+  @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+  @JsonIgnoreProperties(ignoreUnknown = true)
+  @XmlRootElement
+  @XmlAccessorType(XmlAccessType.FIELD)
+  public static class RangerPolicyResource implements java.io.Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private List<String> values;
+    private Boolean isExcludes;
+    private Boolean isRecursive;
+
+    public RangerPolicyResource() {
+      this((List<String>) null, null, null);
+    }
+
+    public RangerPolicyResource(String value) {
+      setValue(value);
+      setIsExcludes(null);
+      setIsRecursive(null);
+    }
+
+    public RangerPolicyResource(String value, Boolean isExcludes, Boolean isRecursive) {
+      setValue(value);
+      setIsExcludes(isExcludes);
+      setIsRecursive(isRecursive);
+    }
+
+    public RangerPolicyResource(List<String> values, Boolean isExcludes, Boolean isRecursive) {
+      setValues(values);
+      setIsExcludes(isExcludes);
+      setIsRecursive(isRecursive);
+    }
+
+    /**
+     * @return the values
+     */
+    public List<String> getValues() {
+      return values;
+    }
+
+    /**
+     * @param values the values to set
+     */
+    public void setValues(List<String> values) {
+      if (this.values == null) {
+        this.values = new ArrayList<>();
+      }
+      if (this.values == values) {
+        return;
+      }
+      this.values.clear();
+      if (values != null) {
+        this.values.addAll(values);
+      }
+    }
+
+    /**
+     * @param value the value to set
+     */
+    public void setValue(String value) {
+      if (this.values == null) {
+        this.values = new ArrayList<>();
+      }
+      this.values.clear();
+      this.values.add(value);
+    }
+
+    /**
+     * @return the isExcludes
+     */
+    public Boolean getIsExcludes() {
+      return isExcludes;
+    }
+
+    /**
+     * @param isExcludes the isExcludes to set
+     */
+    public void setIsExcludes(Boolean isExcludes) {
+      this.isExcludes = isExcludes == null ? Boolean.FALSE : isExcludes;
+    }
+
+    /**
+     * @return the isRecursive
+     */
+    public Boolean getIsRecursive() {
+      return isRecursive;
+    }
+
+    /**
+     * @param isRecursive the isRecursive to set
+     */
+    public void setIsRecursive(Boolean isRecursive) {
+      this.isRecursive = isRecursive == null ? Boolean.FALSE : isRecursive;
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder();
+      toString(sb);
+      return sb.toString();
+    }
+
+    public StringBuilder toString(StringBuilder sb) {
+      sb.append("RangerPolicyResource={");
+      sb.append("values={");
+      if (values != null) {
+        for (String value : values) {
+          sb.append(value).append(" ");
+        }
+      }
+      sb.append("} ");
+      sb.append("isExcludes={").append(isExcludes).append("} ");
+      sb.append("isRecursive={").append(isRecursive).append("} ");
+      sb.append("}");
+
+      return sb;
+    }
+
+    @Override
+    public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result
+          + ((isExcludes == null) ? 0 : isExcludes.hashCode());
+      result = prime * result
+          + ((isRecursive == null) ? 0 : isRecursive.hashCode());
+      result = prime * result
+          + ((values == null) ? 0 : values.hashCode());
+      return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (this == obj) {
+        return true;
+      }
+      if (obj == null) {
+        return false;
+      }
+      if (getClass() != obj.getClass()) {
+        return false;
+      }
+      RangerPolicyResource other = (RangerPolicyResource) obj;
+      if (isExcludes == null) {
+        if (other.isExcludes != null) {
+          return false;
+        }
+      } else if (!isExcludes.equals(other.isExcludes)) {
+        return false;
+      }
+      if (isRecursive == null) {
+        if (other.isRecursive != null) {
+          return false;
+        }
+      } else if (!isRecursive.equals(other.isRecursive)) {
+        return false;
+      }
+      if (values == null) {
+        if (other.values != null) {
+          return false;
+        }
+      } else if (!values.equals(other.values)) {
+        return false;
+      }
+      return true;
+    }
+  }
+
+  /**
+   * RangerPolicyItem class contains ranger policy items like access and permissions.
+   */
+  @JsonAutoDetect(fieldVisibility = Visibility.ANY)
+  @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+  @JsonIgnoreProperties(ignoreUnknown = true)
+  @XmlRootElement
+  @XmlAccessorType(XmlAccessType.FIELD)
+  public static class RangerPolicyItem implements java.io.Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private List<RangerPolicyItemAccess> accesses;
+    private List<String> users;
+    private List<String> groups;
+    private List<RangerPolicyItemCondition> conditions;
+    private Boolean delegateAdmin;
+
+    public RangerPolicyItem() {
+      this(null, null, null, null, null);
+    }
+
+    public RangerPolicyItem(List<RangerPolicyItemAccess> accessTypes, List<String> users, List<String> groups,
+                            List<RangerPolicyItemCondition> conditions, Boolean delegateAdmin) {
+      setAccesses(accessTypes);
+      setUsers(users);
+      setGroups(groups);
+      setConditions(conditions);
+      setDelegateAdmin(delegateAdmin);
+    }
+
+    /**
+     * @return the accesses
+     */
+    public List<RangerPolicyItemAccess> getAccesses() {
+      return accesses;
+    }
+
+    /**
+     * @param accesses the accesses to set
+     */
+    public void setAccesses(List<RangerPolicyItemAccess> accesses) {
+      if (this.accesses == null) {
+        this.accesses = new ArrayList<>();
+      }
+
+      if (this.accesses == accesses) {
+        return;
+      }
+
+      this.accesses.clear();
+
+      if (accesses != null) {
+        this.accesses.addAll(accesses);
+      }
+    }
+
+    /**
+     * @return the users
+     */
+    public List<String> getUsers() {
+      return users;
+    }
+
+    /**
+     * @param users the users to set
+     */
+    public void setUsers(List<String> users) {
+      if (this.users == null) {
+        this.users = new ArrayList<>();
+      }
+
+      if (this.users == users) {
+        return;
+      }
+
+      this.users.clear();
+
+      if (users != null) {
+        this.users.addAll(users);
+      }
+    }
+
+    /**
+     * @return the groups
+     */
+    public List<String> getGroups() {
+      return groups;
+    }
+
+    /**
+     * @param groups the groups to set
+     */
+    public void setGroups(List<String> groups) {
+      if (this.groups == null) {
+        this.groups = new ArrayList<>();
+      }
+      if (this.groups == groups) {
+        return;
+      }
+      this.groups.clear();
+      if (groups != null) {
+        this.groups.addAll(groups);
+      }
+    }
+
+    /**
+     * @return the conditions
+     */
+    public List<RangerPolicyItemCondition> getConditions() {
+      return conditions;
+    }
+
+    /**
+     * @param conditions the conditions to set
+     */
+    public void setConditions(List<RangerPolicyItemCondition> conditions) {
+      if (this.conditions == null) {
+        this.conditions = new ArrayList<>();
+      }
+      if (this.conditions == conditions) {
+        return;
+      }
+      this.conditions.clear();
+      if (conditions != null) {
+        this.conditions.addAll(conditions);
+      }
+    }
+
+    /**
+     * @return the delegateAdmin
+     */
+    public Boolean getDelegateAdmin() {
+      return delegateAdmin;
+    }
+
+    /**
+     * @param delegateAdmin the delegateAdmin to set
+     */
+    public void setDelegateAdmin(Boolean delegateAdmin) {
+      this.delegateAdmin = delegateAdmin == null ? Boolean.FALSE : delegateAdmin;
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder();
+      toString(sb);
+      return sb.toString();
+    }
+
+    public StringBuilder toString(StringBuilder sb) {
+      sb.append("RangerPolicyItem={");
+      sb.append("accessTypes={");
+      if (accesses != null) {
+        for (RangerPolicyItemAccess access : accesses) {
+          if (access != null) {
+            access.toString(sb);
+          }
+        }
+      }
+      sb.append("} ");
+      sb.append("users={");
+      if (users != null) {
+        for (String user : users) {
+          if (user != null) {
+            sb.append(user).append(" ");
+          }
+        }
+      }
+      sb.append("} ");
+      sb.append("groups={");
+      if (groups != null) {
+        for (String group : groups) {
+          if (group != null) {
+            sb.append(group).append(" ");
+          }
+        }
+      }
+      sb.append("} ");
+      sb.append("conditions={");
+      if (conditions != null) {
+        for (RangerPolicyItemCondition condition : conditions) {
+          if (condition != null) {
+            condition.toString(sb);
+          }
+        }
+      }
+      sb.append("} ");
+      sb.append("delegateAdmin={").append(delegateAdmin).append("} ");
+      sb.append("}");
+
+      return sb;
+    }
+
+    @Override
+    public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result
+          + ((accesses == null) ? 0 : accesses.hashCode());
+      result = prime * result
+          + ((conditions == null) ? 0 : conditions.hashCode());
+      result = prime * result
+          + ((delegateAdmin == null) ? 0 : delegateAdmin.hashCode());
+      result = prime * result
+          + ((groups == null) ? 0 : groups.hashCode());
+      result = prime * result + ((users == null) ? 0 : users.hashCode());
+      return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (this == obj) {
+        return true;
+      }
+      if (obj == null) {
+        return false;
+      }
+      if (getClass() != obj.getClass()) {
+        return false;
+      }
+      RangerPolicyItem other = (RangerPolicyItem) obj;
+      if (accesses == null) {
+        if (other.accesses != null) {
+          return false;
+        }
+      } else if (!accesses.equals(other.accesses)) {
+        return false;
+      }
+      if (conditions == null) {
+        if (other.conditions != null) {
+          return false;
+        }
+      } else if (!conditions.equals(other.conditions)) {
+        return false;
+      }
+      if (delegateAdmin == null) {
+        if (other.delegateAdmin != null) {
+          return false;
+        }
+      } else if (!delegateAdmin.equals(other.delegateAdmin)) {
+        return false;
+      }
+      if (groups == null) {
+        if (other.groups != null) {
+          return false;
+        }
+      } else if (!groups.equals(other.groups)) {
+        return false;
+      }
+      if (users == null) {
+        if (other.users != null) {
+          return false;
+        }
+      } else if (!users.equals(other.users)) {
+        return false;
+      }
+      return true;
+
+    }
+  }
+
+  /**
+   * RangerDataMaskPolicyItem class.
+   */
+  @JsonAutoDetect(fieldVisibility = Visibility.ANY)
+  @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+  @JsonIgnoreProperties(ignoreUnknown = true)
+  @XmlRootElement
+  @XmlAccessorType(XmlAccessType.FIELD)
+  public static class RangerDataMaskPolicyItem extends RangerPolicyItem implements java.io.Serializable {
+    private static final long serialVersionUID = 1L;
+    private RangerPolicyItemDataMaskInfo dataMaskInfo;
+
+    public RangerDataMaskPolicyItem() {
+      this(null, null, null, null, null, null);
+    }
+
+    public RangerDataMaskPolicyItem(List<RangerPolicyItemAccess> accesses,
+                                    RangerPolicyItemDataMaskInfo dataMaskDetail, List<String> users,
+                                    List<String> groups,
+                                    List<RangerPolicyItemCondition> conditions, Boolean delegateAdmin) {
+      super(accesses, users, groups, conditions, delegateAdmin);
+      setDataMaskInfo(dataMaskDetail);
+    }
+
+    /**
+     * @return the dataMaskInfo
+     */
+    public RangerPolicyItemDataMaskInfo getDataMaskInfo() {
+      return dataMaskInfo;
+    }
+
+    /**
+     * @param dataMaskInfo the dataMaskInfo to set
+     */
+    public void setDataMaskInfo(RangerPolicyItemDataMaskInfo dataMaskInfo) {
+      this.dataMaskInfo = dataMaskInfo == null ? new RangerPolicyItemDataMaskInfo() : dataMaskInfo;
+    }
+
+    @Override
+    public int hashCode() {
+      final int prime = 31;
+      int result = super.hashCode();
+      result = prime * result + ((dataMaskInfo == null) ? 0 : dataMaskInfo.hashCode());
+      return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (!super.equals(obj)) {
+        return false;
+      }
+      if (this == obj) {
+        return true;
+      }
+      if (obj == null) {
+        return false;
+      }
+      if (getClass() != obj.getClass()) {
+        return false;
+      }
+      RangerDataMaskPolicyItem other = (RangerDataMaskPolicyItem) obj;
+      if (dataMaskInfo == null) {
+        if (other.dataMaskInfo != null) {
+          return false;
+        }
+      } else if (!dataMaskInfo.equals(other.dataMaskInfo)) {
+        return false;
+      }
+      return true;
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder();
+      toString(sb);
+      return sb.toString();
+    }
+
+    public StringBuilder toString(StringBuilder sb) {
+      sb.append("RangerDataMaskPolicyItem={");
+      super.toString(sb);
+      sb.append("dataMaskInfo={");
+      if (dataMaskInfo != null) {
+        dataMaskInfo.toString(sb);
+      }
+      sb.append("} ");
+      sb.append("}");
+      return sb;
+    }
+  }
+
+  /**
+   * RangerRowFilterPolicyItem class.
+   */
+  @JsonAutoDetect(fieldVisibility = Visibility.ANY)
+  @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+  @JsonIgnoreProperties(ignoreUnknown = true)
+  @XmlRootElement
+  @XmlAccessorType(XmlAccessType.FIELD)
+  public static class RangerRowFilterPolicyItem extends RangerPolicyItem implements java.io.Serializable {
+    private static final long serialVersionUID = 1L;
+    private RangerPolicyItemRowFilterInfo rowFilterInfo;
+
+    public RangerRowFilterPolicyItem() {

Review comment:
       Unused? Remove it.

##########
File path: ql/src/java/org/apache/hadoop/hive/ql/exec/repl/ranger/RangerPolicy.java
##########
@@ -0,0 +1,1513 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.ql.exec.repl.ranger;
+
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * RangerPolicy class to contain Ranger Policy details.
+ */
+@JsonAutoDetect(fieldVisibility = Visibility.ANY)
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+public class RangerPolicy extends RangerBaseModelObject implements java.io.Serializable {
+  public static final int POLICY_TYPE_ACCESS = 0;
+  public static final int POLICY_TYPE_DATAMASK = 1;
+  public static final int POLICY_TYPE_ROWFILTER = 2;
+
+  public static final int[] POLICY_TYPES = new int[]{
+      POLICY_TYPE_ACCESS,
+      POLICY_TYPE_DATAMASK,
+      POLICY_TYPE_ROWFILTER,
+  };
+
+  public static final String MASK_TYPE_NULL = "MASK_NULL";
+  public static final String MASK_TYPE_NONE = "MASK_NONE";
+  public static final String MASK_TYPE_CUSTOM = "CUSTOM";
+
+  private static final long serialVersionUID = 1L;
+
+  private String service;
+  private String name;
+  private Integer policyType;
+  private String description;
+  private String resourceSignature;
+  private Boolean isAuditEnabled;
+  private Map<String, RangerPolicyResource> resources;
+  private List<RangerPolicyItem> policyItems;
+  private List<RangerPolicyItem> denyPolicyItems;
+  private List<RangerPolicyItem> allowExceptions;
+  private List<RangerPolicyItem> denyExceptions;
+  private List<RangerDataMaskPolicyItem> dataMaskPolicyItems;
+  private List<RangerRowFilterPolicyItem> rowFilterPolicyItems;
+
+
+  /**
+   * Ranger Policy default constructor.
+   */
+  public RangerPolicy() {
+    this(null, null, null, null, null, null, null);
+  }
+
+  /**
+   * @param service
+   * @param name
+   * @param policyType
+   * @param description
+   * @param resources
+   * @param policyItems
+   * @param resourceSignature TODO
+   */
+  public RangerPolicy(String service, String name, Integer policyType, String description,
+                      Map<String, RangerPolicyResource> resources, List<RangerPolicyItem> policyItems,
+                      String resourceSignature) {
+    super();
+    setService(service);
+    setName(name);
+    setPolicyType(policyType);
+    setDescription(description);
+    setResourceSignature(resourceSignature);
+    setIsAuditEnabled(null);
+    setResources(resources);
+    setPolicyItems(policyItems);
+    setDenyPolicyItems(null);
+    setAllowExceptions(null);
+    setDenyExceptions(null);
+    setDataMaskPolicyItems(null);
+    setRowFilterPolicyItems(null);
+  }
+
+  /**
+   * @param other
+   */
+  public void updateFrom(RangerPolicy other) {
+    super.updateFrom(other);
+
+    setService(other.getService());
+    setName(other.getName());
+    setPolicyType(other.getPolicyType());
+    setDescription(other.getDescription());
+    setResourceSignature(other.getResourceSignature());
+    setIsAuditEnabled(other.getIsAuditEnabled());
+    setResources(other.getResources());
+    setPolicyItems(other.getPolicyItems());
+    setDenyPolicyItems(other.getDenyPolicyItems());
+    setAllowExceptions(other.getAllowExceptions());
+    setDenyExceptions(other.getDenyExceptions());
+    setDataMaskPolicyItems(other.getDataMaskPolicyItems());
+    setRowFilterPolicyItems(other.getRowFilterPolicyItems());
+  }
+
+  /**
+   * @return the type
+   */
+  public String getService() {
+    return service;
+  }
+
+  /**
+   * @param service the type to set
+   */
+  public void setService(String service) {
+    this.service = service;
+  }
+
+  /**
+   * @return the name
+   */
+  public String getName() {
+    return name;
+  }
+
+  /**
+   * @param name the name to set
+   */
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  /**
+   * @return the policyType
+   */
+  public Integer getPolicyType() {
+    return policyType;
+  }
+
+  /**
+   * @param policyType the policyType to set
+   */
+  public void setPolicyType(Integer policyType) {
+    this.policyType = policyType;
+  }
+
+  /**
+   * @return the description
+   */
+  public String getDescription() {
+    return description;
+  }
+
+  /**
+   * @param description the description to set
+   */
+  public void setDescription(String description) {
+    this.description = description;
+  }
+
+  /**
+   * @return the resourceSignature
+   */
+  public String getResourceSignature() {
+    return resourceSignature;
+  }
+
+  /**
+   * @param resourceSignature the resourceSignature to set
+   */
+  public void setResourceSignature(String resourceSignature) {
+    this.resourceSignature = resourceSignature;
+  }
+
+  /**
+   * @return the isAuditEnabled
+   */
+  public Boolean getIsAuditEnabled() {
+    return isAuditEnabled;
+  }
+
+  /**
+   * @param isAuditEnabled the isEnabled to set
+   */
+  public void setIsAuditEnabled(Boolean isAuditEnabled) {
+    this.isAuditEnabled = isAuditEnabled == null ? Boolean.TRUE : isAuditEnabled;
+  }
+
+  /**
+   * @return the resources
+   */
+  public Map<String, RangerPolicyResource> getResources() {
+    return resources;
+  }
+
+  /**
+   * @param resources the resources to set
+   */
+  public void setResources(Map<String, RangerPolicyResource> resources) {
+    if (this.resources == null) {
+      this.resources = new HashMap<>();
+    }
+
+    if (this.resources == resources) {
+      return;
+    }
+
+    this.resources.clear();
+
+    if (resources != null) {
+      for (Map.Entry<String, RangerPolicyResource> e : resources.entrySet()) {
+        this.resources.put(e.getKey(), e.getValue());
+      }
+    }
+  }
+
+  /**
+   * @return the policyItems
+   */
+  public List<RangerPolicyItem> getPolicyItems() {
+    return policyItems;
+  }
+
+  /**
+   * @param policyItems the policyItems to set
+   */
+  public void setPolicyItems(List<RangerPolicyItem> policyItems) {
+    if (this.policyItems == null) {
+      this.policyItems = new ArrayList<>();
+    }
+
+    if (this.policyItems == policyItems) {
+      return;
+    }
+
+    this.policyItems.clear();
+
+    if (policyItems != null) {
+      this.policyItems.addAll(policyItems);
+    }
+  }
+
+  /**
+   * @return the denyPolicyItems
+   */
+  public List<RangerPolicyItem> getDenyPolicyItems() {
+    return denyPolicyItems;
+  }
+
+  /**
+   * @param denyPolicyItems the denyPolicyItems to set
+   */
+  public void setDenyPolicyItems(List<RangerPolicyItem> denyPolicyItems) {
+    if (this.denyPolicyItems == null) {
+      this.denyPolicyItems = new ArrayList<>();
+    }
+
+    if (this.denyPolicyItems == denyPolicyItems) {
+      return;
+    }
+
+    this.denyPolicyItems.clear();
+
+    if (denyPolicyItems != null) {
+      this.denyPolicyItems.addAll(denyPolicyItems);
+    }
+  }
+
+  /**
+   * @return the allowExceptions
+   */
+  public List<RangerPolicyItem> getAllowExceptions() {
+    return allowExceptions;
+  }
+
+  /**
+   * @param allowExceptions the allowExceptions to set
+   */
+  public void setAllowExceptions(List<RangerPolicyItem> allowExceptions) {
+    if (this.allowExceptions == null) {
+      this.allowExceptions = new ArrayList<>();
+    }
+
+    if (this.allowExceptions == allowExceptions) {
+      return;
+    }
+
+    this.allowExceptions.clear();
+
+    if (allowExceptions != null) {
+      this.allowExceptions.addAll(allowExceptions);
+    }
+  }
+
+  /**
+   * @return the denyExceptions
+   */
+  public List<RangerPolicyItem> getDenyExceptions() {
+    return denyExceptions;
+  }
+
+  /**
+   * @param denyExceptions the denyExceptions to set
+   */
+  public void setDenyExceptions(List<RangerPolicyItem> denyExceptions) {
+    if (this.denyExceptions == null) {
+      this.denyExceptions = new ArrayList<>();
+    }
+
+    if (this.denyExceptions == denyExceptions) {
+      return;
+    }
+
+    this.denyExceptions.clear();
+
+    if (denyExceptions != null) {
+      this.denyExceptions.addAll(denyExceptions);
+    }
+  }
+
+  public List<RangerDataMaskPolicyItem> getDataMaskPolicyItems() {
+    return dataMaskPolicyItems;
+  }
+
+  public void setDataMaskPolicyItems(List<RangerDataMaskPolicyItem> dataMaskPolicyItems) {
+    if (this.dataMaskPolicyItems == null) {
+      this.dataMaskPolicyItems = new ArrayList<>();
+    }
+
+    if (this.dataMaskPolicyItems == dataMaskPolicyItems) {
+      return;
+    }
+
+    this.dataMaskPolicyItems.clear();
+
+    if (dataMaskPolicyItems != null) {
+      this.dataMaskPolicyItems.addAll(dataMaskPolicyItems);
+    }
+  }
+
+  public List<RangerRowFilterPolicyItem> getRowFilterPolicyItems() {
+    return rowFilterPolicyItems;
+  }
+
+  public void setRowFilterPolicyItems(List<RangerRowFilterPolicyItem> rowFilterPolicyItems) {
+    if (this.rowFilterPolicyItems == null) {
+      this.rowFilterPolicyItems = new ArrayList<>();
+    }
+
+    if (this.rowFilterPolicyItems == rowFilterPolicyItems) {
+      return;
+    }
+
+    this.rowFilterPolicyItems.clear();
+
+    if (rowFilterPolicyItems != null) {
+      this.rowFilterPolicyItems.addAll(rowFilterPolicyItems);
+    }
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder();
+    toString(sb);
+    return sb.toString();
+  }
+
+  public StringBuilder toString(StringBuilder sb) {
+    sb.append("RangerPolicy={");
+
+    super.toString(sb);
+
+    sb.append("service={").append(service).append("} ");
+    sb.append("name={").append(name).append("} ");
+    sb.append("policyType={").append(policyType).append("} ");
+    sb.append("description={").append(description).append("} ");
+    sb.append("resourceSignature={").append(resourceSignature).append("} ");
+    sb.append("isAuditEnabled={").append(isAuditEnabled).append("} ");
+
+    sb.append("resources={");
+    if (resources != null) {
+      for (Map.Entry<String, RangerPolicyResource> e : resources.entrySet()) {
+        sb.append(e.getKey()).append("={");
+        e.getValue().toString(sb);
+        sb.append("} ");
+      }
+    }
+    sb.append("} ");
+
+    sb.append("policyItems={");
+    if (policyItems != null) {
+      for (RangerPolicyItem policyItem : policyItems) {
+        if (policyItem != null) {
+          policyItem.toString(sb);
+        }
+      }
+    }
+    sb.append("} ");
+
+    sb.append("denyPolicyItems={");
+    if (denyPolicyItems != null) {
+      for (RangerPolicyItem policyItem : denyPolicyItems) {
+        if (policyItem != null) {
+          policyItem.toString(sb);
+        }
+      }
+    }
+    sb.append("} ");
+
+    sb.append("allowExceptions={");
+    if (allowExceptions != null) {
+      for (RangerPolicyItem policyItem : allowExceptions) {
+        if (policyItem != null) {
+          policyItem.toString(sb);
+        }
+      }
+    }
+    sb.append("} ");
+
+    sb.append("denyExceptions={");
+    if (denyExceptions != null) {
+      for (RangerPolicyItem policyItem : denyExceptions) {
+        if (policyItem != null) {
+          policyItem.toString(sb);
+        }
+      }
+    }
+    sb.append("} ");
+
+    sb.append("dataMaskPolicyItems={");
+    if (dataMaskPolicyItems != null) {
+      for (RangerDataMaskPolicyItem dataMaskPolicyItem : dataMaskPolicyItems) {
+        if (dataMaskPolicyItem != null) {
+          dataMaskPolicyItem.toString(sb);
+        }
+      }
+    }
+    sb.append("} ");
+
+    sb.append("rowFilterPolicyItems={");
+    if (rowFilterPolicyItems != null) {
+      for (RangerRowFilterPolicyItem rowFilterPolicyItem : rowFilterPolicyItems) {
+        if (rowFilterPolicyItem != null) {
+          rowFilterPolicyItem.toString(sb);
+        }
+      }
+    }
+    sb.append("} ");
+
+    sb.append("}");
+
+    return sb;
+  }
+
+  /**
+   * RangerPolicyResource class to store the resource path values.
+   */
+  @JsonAutoDetect(fieldVisibility = Visibility.ANY)
+  @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+  @JsonIgnoreProperties(ignoreUnknown = true)
+  @XmlRootElement
+  @XmlAccessorType(XmlAccessType.FIELD)
+  public static class RangerPolicyResource implements java.io.Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private List<String> values;
+    private Boolean isExcludes;
+    private Boolean isRecursive;
+
+    public RangerPolicyResource() {
+      this((List<String>) null, null, null);
+    }
+
+    public RangerPolicyResource(String value) {
+      setValue(value);
+      setIsExcludes(null);
+      setIsRecursive(null);
+    }
+
+    public RangerPolicyResource(String value, Boolean isExcludes, Boolean isRecursive) {
+      setValue(value);
+      setIsExcludes(isExcludes);
+      setIsRecursive(isRecursive);
+    }
+
+    public RangerPolicyResource(List<String> values, Boolean isExcludes, Boolean isRecursive) {
+      setValues(values);
+      setIsExcludes(isExcludes);
+      setIsRecursive(isRecursive);
+    }
+
+    /**
+     * @return the values
+     */
+    public List<String> getValues() {
+      return values;
+    }
+
+    /**
+     * @param values the values to set
+     */
+    public void setValues(List<String> values) {
+      if (this.values == null) {
+        this.values = new ArrayList<>();
+      }
+      if (this.values == values) {
+        return;
+      }
+      this.values.clear();
+      if (values != null) {
+        this.values.addAll(values);
+      }
+    }
+
+    /**
+     * @param value the value to set
+     */
+    public void setValue(String value) {
+      if (this.values == null) {
+        this.values = new ArrayList<>();
+      }
+      this.values.clear();
+      this.values.add(value);
+    }
+
+    /**
+     * @return the isExcludes
+     */
+    public Boolean getIsExcludes() {
+      return isExcludes;
+    }
+
+    /**
+     * @param isExcludes the isExcludes to set
+     */
+    public void setIsExcludes(Boolean isExcludes) {
+      this.isExcludes = isExcludes == null ? Boolean.FALSE : isExcludes;
+    }
+
+    /**
+     * @return the isRecursive
+     */
+    public Boolean getIsRecursive() {
+      return isRecursive;
+    }
+
+    /**
+     * @param isRecursive the isRecursive to set
+     */
+    public void setIsRecursive(Boolean isRecursive) {
+      this.isRecursive = isRecursive == null ? Boolean.FALSE : isRecursive;
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder();
+      toString(sb);
+      return sb.toString();
+    }
+
+    public StringBuilder toString(StringBuilder sb) {
+      sb.append("RangerPolicyResource={");
+      sb.append("values={");
+      if (values != null) {
+        for (String value : values) {
+          sb.append(value).append(" ");
+        }
+      }
+      sb.append("} ");
+      sb.append("isExcludes={").append(isExcludes).append("} ");
+      sb.append("isRecursive={").append(isRecursive).append("} ");
+      sb.append("}");
+
+      return sb;
+    }
+
+    @Override
+    public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result
+          + ((isExcludes == null) ? 0 : isExcludes.hashCode());
+      result = prime * result
+          + ((isRecursive == null) ? 0 : isRecursive.hashCode());
+      result = prime * result
+          + ((values == null) ? 0 : values.hashCode());
+      return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (this == obj) {
+        return true;
+      }
+      if (obj == null) {
+        return false;
+      }
+      if (getClass() != obj.getClass()) {
+        return false;
+      }
+      RangerPolicyResource other = (RangerPolicyResource) obj;
+      if (isExcludes == null) {
+        if (other.isExcludes != null) {
+          return false;
+        }
+      } else if (!isExcludes.equals(other.isExcludes)) {
+        return false;
+      }
+      if (isRecursive == null) {
+        if (other.isRecursive != null) {
+          return false;
+        }
+      } else if (!isRecursive.equals(other.isRecursive)) {
+        return false;
+      }
+      if (values == null) {
+        if (other.values != null) {
+          return false;
+        }
+      } else if (!values.equals(other.values)) {
+        return false;
+      }
+      return true;
+    }
+  }
+
+  /**
+   * RangerPolicyItem class contains ranger policy items like access and permissions.
+   */
+  @JsonAutoDetect(fieldVisibility = Visibility.ANY)
+  @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+  @JsonIgnoreProperties(ignoreUnknown = true)
+  @XmlRootElement
+  @XmlAccessorType(XmlAccessType.FIELD)
+  public static class RangerPolicyItem implements java.io.Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private List<RangerPolicyItemAccess> accesses;
+    private List<String> users;
+    private List<String> groups;
+    private List<RangerPolicyItemCondition> conditions;
+    private Boolean delegateAdmin;
+
+    public RangerPolicyItem() {
+      this(null, null, null, null, null);
+    }
+
+    public RangerPolicyItem(List<RangerPolicyItemAccess> accessTypes, List<String> users, List<String> groups,
+                            List<RangerPolicyItemCondition> conditions, Boolean delegateAdmin) {
+      setAccesses(accessTypes);
+      setUsers(users);
+      setGroups(groups);
+      setConditions(conditions);
+      setDelegateAdmin(delegateAdmin);
+    }
+
+    /**
+     * @return the accesses
+     */
+    public List<RangerPolicyItemAccess> getAccesses() {
+      return accesses;
+    }
+
+    /**
+     * @param accesses the accesses to set
+     */
+    public void setAccesses(List<RangerPolicyItemAccess> accesses) {
+      if (this.accesses == null) {
+        this.accesses = new ArrayList<>();
+      }
+
+      if (this.accesses == accesses) {
+        return;
+      }
+
+      this.accesses.clear();
+
+      if (accesses != null) {
+        this.accesses.addAll(accesses);
+      }
+    }
+
+    /**
+     * @return the users
+     */
+    public List<String> getUsers() {
+      return users;
+    }
+
+    /**
+     * @param users the users to set
+     */
+    public void setUsers(List<String> users) {
+      if (this.users == null) {
+        this.users = new ArrayList<>();
+      }
+
+      if (this.users == users) {
+        return;
+      }
+
+      this.users.clear();
+
+      if (users != null) {
+        this.users.addAll(users);
+      }
+    }
+
+    /**
+     * @return the groups
+     */
+    public List<String> getGroups() {
+      return groups;
+    }
+
+    /**
+     * @param groups the groups to set
+     */
+    public void setGroups(List<String> groups) {
+      if (this.groups == null) {
+        this.groups = new ArrayList<>();
+      }
+      if (this.groups == groups) {
+        return;
+      }
+      this.groups.clear();
+      if (groups != null) {
+        this.groups.addAll(groups);
+      }
+    }
+
+    /**
+     * @return the conditions
+     */
+    public List<RangerPolicyItemCondition> getConditions() {
+      return conditions;
+    }
+
+    /**
+     * @param conditions the conditions to set
+     */
+    public void setConditions(List<RangerPolicyItemCondition> conditions) {
+      if (this.conditions == null) {
+        this.conditions = new ArrayList<>();
+      }
+      if (this.conditions == conditions) {
+        return;
+      }
+      this.conditions.clear();
+      if (conditions != null) {
+        this.conditions.addAll(conditions);
+      }
+    }
+
+    /**
+     * @return the delegateAdmin
+     */
+    public Boolean getDelegateAdmin() {
+      return delegateAdmin;
+    }
+
+    /**
+     * @param delegateAdmin the delegateAdmin to set
+     */
+    public void setDelegateAdmin(Boolean delegateAdmin) {
+      this.delegateAdmin = delegateAdmin == null ? Boolean.FALSE : delegateAdmin;
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder();
+      toString(sb);
+      return sb.toString();
+    }
+
+    public StringBuilder toString(StringBuilder sb) {
+      sb.append("RangerPolicyItem={");
+      sb.append("accessTypes={");
+      if (accesses != null) {
+        for (RangerPolicyItemAccess access : accesses) {
+          if (access != null) {
+            access.toString(sb);
+          }
+        }
+      }
+      sb.append("} ");
+      sb.append("users={");
+      if (users != null) {
+        for (String user : users) {
+          if (user != null) {
+            sb.append(user).append(" ");
+          }
+        }
+      }
+      sb.append("} ");
+      sb.append("groups={");
+      if (groups != null) {
+        for (String group : groups) {
+          if (group != null) {
+            sb.append(group).append(" ");
+          }
+        }
+      }
+      sb.append("} ");
+      sb.append("conditions={");
+      if (conditions != null) {
+        for (RangerPolicyItemCondition condition : conditions) {
+          if (condition != null) {
+            condition.toString(sb);
+          }
+        }
+      }
+      sb.append("} ");
+      sb.append("delegateAdmin={").append(delegateAdmin).append("} ");
+      sb.append("}");
+
+      return sb;
+    }
+
+    @Override
+    public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result
+          + ((accesses == null) ? 0 : accesses.hashCode());
+      result = prime * result
+          + ((conditions == null) ? 0 : conditions.hashCode());
+      result = prime * result
+          + ((delegateAdmin == null) ? 0 : delegateAdmin.hashCode());
+      result = prime * result
+          + ((groups == null) ? 0 : groups.hashCode());
+      result = prime * result + ((users == null) ? 0 : users.hashCode());
+      return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (this == obj) {
+        return true;
+      }
+      if (obj == null) {
+        return false;
+      }
+      if (getClass() != obj.getClass()) {
+        return false;
+      }
+      RangerPolicyItem other = (RangerPolicyItem) obj;
+      if (accesses == null) {
+        if (other.accesses != null) {
+          return false;
+        }
+      } else if (!accesses.equals(other.accesses)) {
+        return false;
+      }
+      if (conditions == null) {
+        if (other.conditions != null) {
+          return false;
+        }
+      } else if (!conditions.equals(other.conditions)) {
+        return false;
+      }
+      if (delegateAdmin == null) {
+        if (other.delegateAdmin != null) {
+          return false;
+        }
+      } else if (!delegateAdmin.equals(other.delegateAdmin)) {
+        return false;
+      }
+      if (groups == null) {
+        if (other.groups != null) {
+          return false;
+        }
+      } else if (!groups.equals(other.groups)) {
+        return false;
+      }
+      if (users == null) {
+        if (other.users != null) {
+          return false;
+        }
+      } else if (!users.equals(other.users)) {
+        return false;
+      }
+      return true;
+
+    }
+  }
+
+  /**
+   * RangerDataMaskPolicyItem class.
+   */
+  @JsonAutoDetect(fieldVisibility = Visibility.ANY)
+  @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+  @JsonIgnoreProperties(ignoreUnknown = true)
+  @XmlRootElement
+  @XmlAccessorType(XmlAccessType.FIELD)
+  public static class RangerDataMaskPolicyItem extends RangerPolicyItem implements java.io.Serializable {
+    private static final long serialVersionUID = 1L;
+    private RangerPolicyItemDataMaskInfo dataMaskInfo;
+
+    public RangerDataMaskPolicyItem() {
+      this(null, null, null, null, null, null);
+    }
+
+    public RangerDataMaskPolicyItem(List<RangerPolicyItemAccess> accesses,
+                                    RangerPolicyItemDataMaskInfo dataMaskDetail, List<String> users,
+                                    List<String> groups,
+                                    List<RangerPolicyItemCondition> conditions, Boolean delegateAdmin) {
+      super(accesses, users, groups, conditions, delegateAdmin);
+      setDataMaskInfo(dataMaskDetail);
+    }
+
+    /**
+     * @return the dataMaskInfo
+     */
+    public RangerPolicyItemDataMaskInfo getDataMaskInfo() {
+      return dataMaskInfo;
+    }
+
+    /**
+     * @param dataMaskInfo the dataMaskInfo to set
+     */
+    public void setDataMaskInfo(RangerPolicyItemDataMaskInfo dataMaskInfo) {
+      this.dataMaskInfo = dataMaskInfo == null ? new RangerPolicyItemDataMaskInfo() : dataMaskInfo;
+    }
+
+    @Override
+    public int hashCode() {
+      final int prime = 31;
+      int result = super.hashCode();
+      result = prime * result + ((dataMaskInfo == null) ? 0 : dataMaskInfo.hashCode());
+      return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (!super.equals(obj)) {
+        return false;
+      }
+      if (this == obj) {
+        return true;
+      }
+      if (obj == null) {
+        return false;
+      }
+      if (getClass() != obj.getClass()) {
+        return false;
+      }
+      RangerDataMaskPolicyItem other = (RangerDataMaskPolicyItem) obj;
+      if (dataMaskInfo == null) {
+        if (other.dataMaskInfo != null) {
+          return false;
+        }
+      } else if (!dataMaskInfo.equals(other.dataMaskInfo)) {
+        return false;
+      }
+      return true;
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder();
+      toString(sb);
+      return sb.toString();
+    }
+
+    public StringBuilder toString(StringBuilder sb) {
+      sb.append("RangerDataMaskPolicyItem={");
+      super.toString(sb);
+      sb.append("dataMaskInfo={");
+      if (dataMaskInfo != null) {
+        dataMaskInfo.toString(sb);
+      }
+      sb.append("} ");
+      sb.append("}");
+      return sb;
+    }
+  }
+
+  /**
+   * RangerRowFilterPolicyItem class.
+   */
+  @JsonAutoDetect(fieldVisibility = Visibility.ANY)
+  @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+  @JsonIgnoreProperties(ignoreUnknown = true)
+  @XmlRootElement
+  @XmlAccessorType(XmlAccessType.FIELD)
+  public static class RangerRowFilterPolicyItem extends RangerPolicyItem implements java.io.Serializable {
+    private static final long serialVersionUID = 1L;
+    private RangerPolicyItemRowFilterInfo rowFilterInfo;
+
+    public RangerRowFilterPolicyItem() {
+      this(null, null, null, null, null, null);
+    }
+
+    public RangerRowFilterPolicyItem(RangerPolicyItemRowFilterInfo rowFilterInfo,
+                                     List<RangerPolicyItemAccess> accesses, List<String> users, List<String> groups,
+                                     List<RangerPolicyItemCondition> conditions, Boolean delegateAdmin) {
+      super(accesses, users, groups, conditions, delegateAdmin);
+      setRowFilterInfo(rowFilterInfo);
+    }
+
+    /**
+     * @return the rowFilterInfo
+     */
+    public RangerPolicyItemRowFilterInfo getRowFilterInfo() {
+      return rowFilterInfo;
+    }
+
+    /**
+     * @param rowFilterInfo the rowFilterInfo to set
+     */
+    public void setRowFilterInfo(RangerPolicyItemRowFilterInfo rowFilterInfo) {
+      this.rowFilterInfo = rowFilterInfo == null ? new RangerPolicyItemRowFilterInfo() : rowFilterInfo;
+    }
+
+    @Override
+    public int hashCode() {
+      final int prime = 31;
+      int result = super.hashCode();
+      result = prime * result + ((rowFilterInfo == null) ? 0 : rowFilterInfo.hashCode());
+      return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (!super.equals(obj)) {
+        return false;
+      }
+      if (this == obj) {
+        return true;
+      }
+      if (obj == null) {
+        return false;
+      }
+      if (getClass() != obj.getClass()) {
+        return false;
+      }
+      RangerRowFilterPolicyItem other = (RangerRowFilterPolicyItem) obj;
+      if (rowFilterInfo == null) {
+        if (other.rowFilterInfo != null) {
+          return false;
+        }
+      } else if (!rowFilterInfo.equals(other.rowFilterInfo)) {
+        return false;
+      }
+      return true;
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder();
+      toString(sb);
+      return sb.toString();
+    }
+
+    public StringBuilder toString(StringBuilder sb) {

Review comment:
       Mark it private, may change the signature as well. It is toString() but returns StringBuilder

##########
File path: ql/src/java/org/apache/hadoop/hive/ql/exec/repl/ranger/RangerPolicy.java
##########
@@ -0,0 +1,1513 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.ql.exec.repl.ranger;
+
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * RangerPolicy class to contain Ranger Policy details.
+ */
+@JsonAutoDetect(fieldVisibility = Visibility.ANY)
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+public class RangerPolicy extends RangerBaseModelObject implements java.io.Serializable {
+  public static final int POLICY_TYPE_ACCESS = 0;
+  public static final int POLICY_TYPE_DATAMASK = 1;
+  public static final int POLICY_TYPE_ROWFILTER = 2;
+
+  public static final int[] POLICY_TYPES = new int[]{
+      POLICY_TYPE_ACCESS,
+      POLICY_TYPE_DATAMASK,
+      POLICY_TYPE_ROWFILTER,
+  };
+
+  public static final String MASK_TYPE_NULL = "MASK_NULL";
+  public static final String MASK_TYPE_NONE = "MASK_NONE";
+  public static final String MASK_TYPE_CUSTOM = "CUSTOM";
+
+  private static final long serialVersionUID = 1L;
+
+  private String service;
+  private String name;
+  private Integer policyType;
+  private String description;
+  private String resourceSignature;
+  private Boolean isAuditEnabled;
+  private Map<String, RangerPolicyResource> resources;
+  private List<RangerPolicyItem> policyItems;
+  private List<RangerPolicyItem> denyPolicyItems;
+  private List<RangerPolicyItem> allowExceptions;
+  private List<RangerPolicyItem> denyExceptions;
+  private List<RangerDataMaskPolicyItem> dataMaskPolicyItems;
+  private List<RangerRowFilterPolicyItem> rowFilterPolicyItems;
+
+
+  /**
+   * Ranger Policy default constructor.
+   */
+  public RangerPolicy() {
+    this(null, null, null, null, null, null, null);
+  }
+
+  /**
+   * @param service
+   * @param name
+   * @param policyType
+   * @param description
+   * @param resources
+   * @param policyItems
+   * @param resourceSignature TODO
+   */
+  public RangerPolicy(String service, String name, Integer policyType, String description,
+                      Map<String, RangerPolicyResource> resources, List<RangerPolicyItem> policyItems,
+                      String resourceSignature) {
+    super();
+    setService(service);
+    setName(name);
+    setPolicyType(policyType);
+    setDescription(description);
+    setResourceSignature(resourceSignature);
+    setIsAuditEnabled(null);
+    setResources(resources);
+    setPolicyItems(policyItems);
+    setDenyPolicyItems(null);
+    setAllowExceptions(null);
+    setDenyExceptions(null);
+    setDataMaskPolicyItems(null);
+    setRowFilterPolicyItems(null);
+  }
+
+  /**
+   * @param other
+   */
+  public void updateFrom(RangerPolicy other) {
+    super.updateFrom(other);
+
+    setService(other.getService());
+    setName(other.getName());
+    setPolicyType(other.getPolicyType());
+    setDescription(other.getDescription());
+    setResourceSignature(other.getResourceSignature());
+    setIsAuditEnabled(other.getIsAuditEnabled());
+    setResources(other.getResources());
+    setPolicyItems(other.getPolicyItems());
+    setDenyPolicyItems(other.getDenyPolicyItems());
+    setAllowExceptions(other.getAllowExceptions());
+    setDenyExceptions(other.getDenyExceptions());
+    setDataMaskPolicyItems(other.getDataMaskPolicyItems());
+    setRowFilterPolicyItems(other.getRowFilterPolicyItems());
+  }
+
+  /**
+   * @return the type
+   */
+  public String getService() {
+    return service;
+  }
+
+  /**
+   * @param service the type to set
+   */
+  public void setService(String service) {
+    this.service = service;
+  }
+
+  /**
+   * @return the name
+   */
+  public String getName() {
+    return name;
+  }
+
+  /**
+   * @param name the name to set
+   */
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  /**
+   * @return the policyType
+   */
+  public Integer getPolicyType() {
+    return policyType;
+  }
+
+  /**
+   * @param policyType the policyType to set
+   */
+  public void setPolicyType(Integer policyType) {
+    this.policyType = policyType;
+  }
+
+  /**
+   * @return the description
+   */
+  public String getDescription() {
+    return description;
+  }
+
+  /**
+   * @param description the description to set
+   */
+  public void setDescription(String description) {
+    this.description = description;
+  }
+
+  /**
+   * @return the resourceSignature
+   */
+  public String getResourceSignature() {
+    return resourceSignature;
+  }
+
+  /**
+   * @param resourceSignature the resourceSignature to set
+   */
+  public void setResourceSignature(String resourceSignature) {
+    this.resourceSignature = resourceSignature;
+  }
+
+  /**
+   * @return the isAuditEnabled
+   */
+  public Boolean getIsAuditEnabled() {
+    return isAuditEnabled;
+  }
+
+  /**
+   * @param isAuditEnabled the isEnabled to set
+   */
+  public void setIsAuditEnabled(Boolean isAuditEnabled) {
+    this.isAuditEnabled = isAuditEnabled == null ? Boolean.TRUE : isAuditEnabled;
+  }
+
+  /**
+   * @return the resources
+   */
+  public Map<String, RangerPolicyResource> getResources() {
+    return resources;
+  }
+
+  /**
+   * @param resources the resources to set
+   */
+  public void setResources(Map<String, RangerPolicyResource> resources) {
+    if (this.resources == null) {
+      this.resources = new HashMap<>();
+    }
+
+    if (this.resources == resources) {
+      return;
+    }
+
+    this.resources.clear();
+
+    if (resources != null) {
+      for (Map.Entry<String, RangerPolicyResource> e : resources.entrySet()) {
+        this.resources.put(e.getKey(), e.getValue());
+      }
+    }
+  }
+
+  /**
+   * @return the policyItems
+   */
+  public List<RangerPolicyItem> getPolicyItems() {
+    return policyItems;
+  }
+
+  /**
+   * @param policyItems the policyItems to set
+   */
+  public void setPolicyItems(List<RangerPolicyItem> policyItems) {
+    if (this.policyItems == null) {
+      this.policyItems = new ArrayList<>();
+    }
+
+    if (this.policyItems == policyItems) {
+      return;
+    }
+
+    this.policyItems.clear();
+
+    if (policyItems != null) {
+      this.policyItems.addAll(policyItems);
+    }
+  }
+
+  /**
+   * @return the denyPolicyItems
+   */
+  public List<RangerPolicyItem> getDenyPolicyItems() {
+    return denyPolicyItems;
+  }
+
+  /**
+   * @param denyPolicyItems the denyPolicyItems to set
+   */
+  public void setDenyPolicyItems(List<RangerPolicyItem> denyPolicyItems) {
+    if (this.denyPolicyItems == null) {
+      this.denyPolicyItems = new ArrayList<>();
+    }
+
+    if (this.denyPolicyItems == denyPolicyItems) {
+      return;
+    }
+
+    this.denyPolicyItems.clear();
+
+    if (denyPolicyItems != null) {
+      this.denyPolicyItems.addAll(denyPolicyItems);
+    }
+  }
+
+  /**
+   * @return the allowExceptions
+   */
+  public List<RangerPolicyItem> getAllowExceptions() {
+    return allowExceptions;
+  }
+
+  /**
+   * @param allowExceptions the allowExceptions to set
+   */
+  public void setAllowExceptions(List<RangerPolicyItem> allowExceptions) {
+    if (this.allowExceptions == null) {
+      this.allowExceptions = new ArrayList<>();
+    }
+
+    if (this.allowExceptions == allowExceptions) {
+      return;
+    }
+
+    this.allowExceptions.clear();
+
+    if (allowExceptions != null) {
+      this.allowExceptions.addAll(allowExceptions);
+    }
+  }
+
+  /**
+   * @return the denyExceptions
+   */
+  public List<RangerPolicyItem> getDenyExceptions() {
+    return denyExceptions;
+  }
+
+  /**
+   * @param denyExceptions the denyExceptions to set
+   */
+  public void setDenyExceptions(List<RangerPolicyItem> denyExceptions) {
+    if (this.denyExceptions == null) {
+      this.denyExceptions = new ArrayList<>();
+    }
+
+    if (this.denyExceptions == denyExceptions) {
+      return;
+    }
+
+    this.denyExceptions.clear();
+
+    if (denyExceptions != null) {
+      this.denyExceptions.addAll(denyExceptions);
+    }
+  }
+
+  public List<RangerDataMaskPolicyItem> getDataMaskPolicyItems() {
+    return dataMaskPolicyItems;
+  }
+
+  public void setDataMaskPolicyItems(List<RangerDataMaskPolicyItem> dataMaskPolicyItems) {
+    if (this.dataMaskPolicyItems == null) {
+      this.dataMaskPolicyItems = new ArrayList<>();
+    }
+
+    if (this.dataMaskPolicyItems == dataMaskPolicyItems) {
+      return;
+    }
+
+    this.dataMaskPolicyItems.clear();
+
+    if (dataMaskPolicyItems != null) {
+      this.dataMaskPolicyItems.addAll(dataMaskPolicyItems);
+    }
+  }
+
+  public List<RangerRowFilterPolicyItem> getRowFilterPolicyItems() {
+    return rowFilterPolicyItems;
+  }
+
+  public void setRowFilterPolicyItems(List<RangerRowFilterPolicyItem> rowFilterPolicyItems) {
+    if (this.rowFilterPolicyItems == null) {
+      this.rowFilterPolicyItems = new ArrayList<>();
+    }
+
+    if (this.rowFilterPolicyItems == rowFilterPolicyItems) {
+      return;
+    }
+
+    this.rowFilterPolicyItems.clear();
+
+    if (rowFilterPolicyItems != null) {
+      this.rowFilterPolicyItems.addAll(rowFilterPolicyItems);
+    }
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder();
+    toString(sb);
+    return sb.toString();
+  }
+
+  public StringBuilder toString(StringBuilder sb) {
+    sb.append("RangerPolicy={");
+
+    super.toString(sb);
+
+    sb.append("service={").append(service).append("} ");
+    sb.append("name={").append(name).append("} ");
+    sb.append("policyType={").append(policyType).append("} ");
+    sb.append("description={").append(description).append("} ");
+    sb.append("resourceSignature={").append(resourceSignature).append("} ");
+    sb.append("isAuditEnabled={").append(isAuditEnabled).append("} ");
+
+    sb.append("resources={");
+    if (resources != null) {
+      for (Map.Entry<String, RangerPolicyResource> e : resources.entrySet()) {
+        sb.append(e.getKey()).append("={");
+        e.getValue().toString(sb);
+        sb.append("} ");
+      }
+    }
+    sb.append("} ");
+
+    sb.append("policyItems={");
+    if (policyItems != null) {
+      for (RangerPolicyItem policyItem : policyItems) {
+        if (policyItem != null) {
+          policyItem.toString(sb);
+        }
+      }
+    }
+    sb.append("} ");
+
+    sb.append("denyPolicyItems={");
+    if (denyPolicyItems != null) {
+      for (RangerPolicyItem policyItem : denyPolicyItems) {
+        if (policyItem != null) {
+          policyItem.toString(sb);
+        }
+      }
+    }
+    sb.append("} ");
+
+    sb.append("allowExceptions={");
+    if (allowExceptions != null) {
+      for (RangerPolicyItem policyItem : allowExceptions) {
+        if (policyItem != null) {
+          policyItem.toString(sb);
+        }
+      }
+    }
+    sb.append("} ");
+
+    sb.append("denyExceptions={");
+    if (denyExceptions != null) {
+      for (RangerPolicyItem policyItem : denyExceptions) {
+        if (policyItem != null) {
+          policyItem.toString(sb);
+        }
+      }
+    }
+    sb.append("} ");
+
+    sb.append("dataMaskPolicyItems={");
+    if (dataMaskPolicyItems != null) {
+      for (RangerDataMaskPolicyItem dataMaskPolicyItem : dataMaskPolicyItems) {
+        if (dataMaskPolicyItem != null) {
+          dataMaskPolicyItem.toString(sb);
+        }
+      }
+    }
+    sb.append("} ");
+
+    sb.append("rowFilterPolicyItems={");
+    if (rowFilterPolicyItems != null) {
+      for (RangerRowFilterPolicyItem rowFilterPolicyItem : rowFilterPolicyItems) {
+        if (rowFilterPolicyItem != null) {
+          rowFilterPolicyItem.toString(sb);
+        }
+      }
+    }
+    sb.append("} ");
+
+    sb.append("}");
+
+    return sb;
+  }
+
+  /**
+   * RangerPolicyResource class to store the resource path values.
+   */
+  @JsonAutoDetect(fieldVisibility = Visibility.ANY)
+  @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+  @JsonIgnoreProperties(ignoreUnknown = true)
+  @XmlRootElement
+  @XmlAccessorType(XmlAccessType.FIELD)
+  public static class RangerPolicyResource implements java.io.Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private List<String> values;
+    private Boolean isExcludes;
+    private Boolean isRecursive;
+
+    public RangerPolicyResource() {
+      this((List<String>) null, null, null);
+    }
+
+    public RangerPolicyResource(String value) {
+      setValue(value);
+      setIsExcludes(null);
+      setIsRecursive(null);
+    }
+
+    public RangerPolicyResource(String value, Boolean isExcludes, Boolean isRecursive) {
+      setValue(value);
+      setIsExcludes(isExcludes);
+      setIsRecursive(isRecursive);
+    }
+
+    public RangerPolicyResource(List<String> values, Boolean isExcludes, Boolean isRecursive) {
+      setValues(values);
+      setIsExcludes(isExcludes);
+      setIsRecursive(isRecursive);
+    }
+
+    /**
+     * @return the values
+     */
+    public List<String> getValues() {
+      return values;
+    }
+
+    /**
+     * @param values the values to set
+     */
+    public void setValues(List<String> values) {
+      if (this.values == null) {
+        this.values = new ArrayList<>();
+      }
+      if (this.values == values) {
+        return;
+      }
+      this.values.clear();
+      if (values != null) {
+        this.values.addAll(values);
+      }
+    }
+
+    /**
+     * @param value the value to set
+     */
+    public void setValue(String value) {
+      if (this.values == null) {
+        this.values = new ArrayList<>();
+      }
+      this.values.clear();
+      this.values.add(value);
+    }
+
+    /**
+     * @return the isExcludes
+     */
+    public Boolean getIsExcludes() {
+      return isExcludes;
+    }
+
+    /**
+     * @param isExcludes the isExcludes to set
+     */
+    public void setIsExcludes(Boolean isExcludes) {
+      this.isExcludes = isExcludes == null ? Boolean.FALSE : isExcludes;
+    }
+
+    /**
+     * @return the isRecursive
+     */
+    public Boolean getIsRecursive() {
+      return isRecursive;
+    }
+
+    /**
+     * @param isRecursive the isRecursive to set
+     */
+    public void setIsRecursive(Boolean isRecursive) {
+      this.isRecursive = isRecursive == null ? Boolean.FALSE : isRecursive;
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder();
+      toString(sb);
+      return sb.toString();
+    }
+
+    public StringBuilder toString(StringBuilder sb) {
+      sb.append("RangerPolicyResource={");
+      sb.append("values={");
+      if (values != null) {
+        for (String value : values) {
+          sb.append(value).append(" ");
+        }
+      }
+      sb.append("} ");
+      sb.append("isExcludes={").append(isExcludes).append("} ");
+      sb.append("isRecursive={").append(isRecursive).append("} ");
+      sb.append("}");
+
+      return sb;
+    }
+
+    @Override
+    public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result
+          + ((isExcludes == null) ? 0 : isExcludes.hashCode());
+      result = prime * result
+          + ((isRecursive == null) ? 0 : isRecursive.hashCode());
+      result = prime * result
+          + ((values == null) ? 0 : values.hashCode());
+      return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (this == obj) {
+        return true;
+      }
+      if (obj == null) {
+        return false;
+      }
+      if (getClass() != obj.getClass()) {
+        return false;
+      }
+      RangerPolicyResource other = (RangerPolicyResource) obj;
+      if (isExcludes == null) {
+        if (other.isExcludes != null) {
+          return false;
+        }
+      } else if (!isExcludes.equals(other.isExcludes)) {
+        return false;
+      }
+      if (isRecursive == null) {
+        if (other.isRecursive != null) {
+          return false;
+        }
+      } else if (!isRecursive.equals(other.isRecursive)) {
+        return false;
+      }
+      if (values == null) {
+        if (other.values != null) {
+          return false;
+        }
+      } else if (!values.equals(other.values)) {
+        return false;
+      }
+      return true;
+    }
+  }
+
+  /**
+   * RangerPolicyItem class contains ranger policy items like access and permissions.
+   */
+  @JsonAutoDetect(fieldVisibility = Visibility.ANY)
+  @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+  @JsonIgnoreProperties(ignoreUnknown = true)
+  @XmlRootElement
+  @XmlAccessorType(XmlAccessType.FIELD)
+  public static class RangerPolicyItem implements java.io.Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private List<RangerPolicyItemAccess> accesses;
+    private List<String> users;
+    private List<String> groups;
+    private List<RangerPolicyItemCondition> conditions;
+    private Boolean delegateAdmin;
+
+    public RangerPolicyItem() {

Review comment:
       Unused? Remove it.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Issue Time Tracking
-------------------

    Worklog Id:     (was: 432103)
    Time Spent: 40m  (was: 0.5h)

> Ranger Replication Scheduling
> -----------------------------
>
>                 Key: HIVE-23351
>                 URL: https://issues.apache.org/jira/browse/HIVE-23351
>             Project: Hive
>          Issue Type: Task
>            Reporter: Aasha Medhi
>            Assignee: Aasha Medhi
>            Priority: Major
>              Labels: pull-request-available
>         Attachments: HIVE-23351.01.patch, HIVE-23351.02.patch, HIVE-23351.03.patch, HIVE-23351.04.patch, HIVE-23351.05.patch, HIVE-23351.06.patch
>
>          Time Spent: 40m
>  Remaining Estimate: 0h
>




--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Mime
View raw message