This is an automated email from the ASF dual-hosted git repository.

dineshkumar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/master by this push:
     new 17479f030 RANGER-4150 : Create HA support for UserSync
17479f030 is described below

commit 17479f030ee26ac04f282c6e2fac68d3529486c3
Author: Dineshkumar Yadav <[email protected]>
AuthorDate: Wed Apr 5 16:56:53 2023 +0530

    RANGER-4150 : Create HA support for UserSync
    
    Signed-off-by: Dineshkumar Yadav <[email protected]>
---
 .../ranger/plugin/util/RangerMetricsUtil.java      |  13 ++-
 distro/src/main/assembly/usersync.xml              |   6 ++
 ugsync/pom.xml                                     |  13 +++
 .../unixusersync/config/UserGroupSyncConfig.java   |  22 +++++
 .../unixusersync/ha/UserSyncHAInitializerImpl.java | 110 +++++++++++++++++++++
 .../process/PolicyMgrUserGroupBuilder.java         |  26 ++++-
 .../apache/ranger/usergroupsync/UserGroupSync.java |  56 +++++++----
 .../usergroupsync/UserSyncMetricsProducer.java     |  10 ++
 .../scripts/templates/ranger-ugsync-template.xml   |  58 +++++++++++
 .../authentication/UnixAuthenticationService.java  |   7 ++
 10 files changed, 294 insertions(+), 27 deletions(-)

diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerMetricsUtil.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerMetricsUtil.java
index d85009d18..588605a6a 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerMetricsUtil.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerMetricsUtil.java
@@ -55,7 +55,7 @@ public class RangerMetricsUtil {
     private static final String JVM_MACHINE_REPRESENTATION_NAME = 
RUNTIME.getName();
     private static final long UP_TIME_OF_JVM = RUNTIME.getUptime();
     private static final String JVM_VENDOR_NAME =  RUNTIME.getVmVendor();
-
+    private static int IS_ROLE_ACTIVE =  0;
 
     static {
         OS = ManagementFactory.getOperatingSystemMXBean();
@@ -158,6 +158,7 @@ public class RangerMetricsUtil {
                vmDetails.put("Up time of JVM", UP_TIME_OF_JVM);
                vmDetails.put("JVM Vendor Name", JVM_VENDOR_NAME);
                vmDetails.putAll(getValues());
+        vmDetails.put("isRoleActive",getIsRoleActive());
                jvm.put("jvm", vmDetails);
 
                if (LOG.isDebugEnabled()) {
@@ -167,7 +168,15 @@ public class RangerMetricsUtil {
                return new RangerMetrics(jvm);
        }
 
-       public void writeMetricsToFile(File filePath) throws Throwable {
+    public static int getIsRoleActive() {
+        return IS_ROLE_ACTIVE;
+    }
+
+    public static void setIsRoleActive(int isRoleActive) {
+        IS_ROLE_ACTIVE = isRoleActive;
+    }
+
+    public void writeMetricsToFile(File filePath) throws Throwable {
 
                RangerMetrics rangerMetrics = null;
                rangerMetrics = getVMStatus();
diff --git a/distro/src/main/assembly/usersync.xml 
b/distro/src/main/assembly/usersync.xml
index 187d535e4..2fbdf4b4d 100644
--- a/distro/src/main/assembly/usersync.xml
+++ b/distro/src/main/assembly/usersync.xml
@@ -57,6 +57,12 @@
                                                        
<include>org.apache.httpcomponents:httpclient:jar:${httpcomponents.httpclient.version}</include>
                                                        
<include>commons-codec:commons-codec</include>
                                                        
<include>org.apache.ranger:ranger-plugins-common</include>
+                                                       
<include>org.apache.ranger:ranger-common-ha:jar:${project.version}</include>
+                                                       
<include>org.apache.curator:curator-framework:jar:${curator.version}</include>
+                                                       
<include>org.apache.curator:curator-recipes:jar:${curator.version}</include>
+                                                       
<include>org.apache.curator:curator-client:jar:${curator.version}</include>
+                                                       
<include>org.apache.zookeeper:zookeeper:jar:${zookeeper.version}</include>
+                                                       
<include>org.apache.zookeeper:zookeeper-jute:jar:${zookeeper.version}</include>
                                                        
<include>org.apache.ranger:ugsync-util</include>
                                                        
<include>org.apache.htrace:htrace-core4</include>
                                                        
<include>com.kstruct:gethostname4j:jar:${kstruct.gethostname4j.version}</include>
diff --git a/ugsync/pom.xml b/ugsync/pom.xml
index 62e6b41ce..ecb03c97a 100644
--- a/ugsync/pom.xml
+++ b/ugsync/pom.xml
@@ -106,6 +106,14 @@
                     <groupId>org.slf4j</groupId>
                     <artifactId>*</artifactId>
                 </exclusion>
+                <exclusion>
+                    <groupId>org.apache.curator</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.zookeeper</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
             </exclusions>
         </dependency>
         <dependency>
@@ -188,6 +196,11 @@
             <artifactId>ugsync-util</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.ranger</groupId>
+            <artifactId>ranger-common-ha</artifactId>
+            <version>${project.version}</version>
+        </dependency>
     </dependencies>
 
     <build>
diff --git 
a/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java
 
b/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java
index ad440f257..b29b9b177 100644
--- 
a/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java
+++ 
b/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java
@@ -37,6 +37,7 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.ranger.credentialapi.CredentialReader;
 import org.apache.ranger.plugin.util.RangerCommonConstants;
 import org.apache.ranger.plugin.util.XMLUtils;
+import org.apache.ranger.unixusersync.ha.UserSyncHAInitializerImpl;
 import org.apache.ranger.usergroupsync.UserGroupSink;
 import org.apache.ranger.usergroupsync.UserGroupSource;
 
@@ -286,8 +287,11 @@ public class UserGroupSyncConfig  {
        private static final long    DEFAULT_UGSYNC_DELETES_FREQUENCY = 10L; // 
After every 10 sync cycles
        public static final String UGSYNC_NAME_VALIDATION_ENABLED = 
"ranger.usersync.name.validation.enabled";
        private static final boolean DEFAULT_UGSYNC_NAME_VALIDATION_ENABLED = 
false;
+       private static final long 
UGSYNC_INIT_SLEEP_TIME_IN_MILLIS_BETWEEN_CYCLE_MIN_VALUE_FOR_HA = 5000L;
+       public static final String UGSYNC_SERVER_HA_ENABLED_PARAM = 
"ranger-ugsync.server.ha.enabled";
 
     private Properties prop = new Properties();
+       private Configuration userGroupConfig = null;
 
        private static volatile UserGroupSyncConfig me = null;
 
@@ -312,6 +316,7 @@ public class UserGroupSyncConfig  {
                XMLUtils.loadConfig(DEFAULT_CONFIG_FILE, prop);
                XMLUtils.loadConfig(CORE_SITE_CONFIG_FILE, prop);
                XMLUtils.loadConfig(CONFIG_FILE, prop);
+               userGroupConfig = getConfig();
        }
 
        public Configuration getConfig() {
@@ -324,6 +329,13 @@ public class UserGroupSyncConfig  {
                return ret;
        }
 
+       public Configuration getUserGroupConfig(){
+               return userGroupConfig;
+       }
+       synchronized public static boolean isUgsyncServiceActive() {
+               return 
UserSyncHAInitializerImpl.getInstance(UserGroupSyncConfig.getInstance().getUserGroupConfig()).isActive();
+       }
+
        public String getUserSyncFileSource(){
                String val = prop.getProperty(UGSYNC_SOURCE_FILE_PROC);
                return val;
@@ -491,6 +503,16 @@ public class UserGroupSyncConfig  {
                return ret;
        }
 
+       public long getInitSleepTimeInMillisBetweenCycle() throws Throwable{
+               long initSleepValue = 0;
+               Configuration config = getUserGroupConfig();
+               if(config.getBoolean(UGSYNC_SERVER_HA_ENABLED_PARAM, false)){
+                       initSleepValue = 
UGSYNC_INIT_SLEEP_TIME_IN_MILLIS_BETWEEN_CYCLE_MIN_VALUE_FOR_HA;
+               }else{
+                       initSleepValue = getSleepTimeInMillisBetweenCycle();
+               }
+               return initSleepValue;
+       }
        public long getSleepTimeInMillisBetweenCycle() throws Throwable {
                String val =  
prop.getProperty(UGSYNC_SLEEP_TIME_IN_MILLIS_BETWEEN_CYCLE_PARAM);
                String className = getUserGroupSource().getClass().getName();
diff --git 
a/ugsync/src/main/java/org/apache/ranger/unixusersync/ha/UserSyncHAInitializerImpl.java
 
b/ugsync/src/main/java/org/apache/ranger/unixusersync/ha/UserSyncHAInitializerImpl.java
new file mode 100644
index 000000000..8e892c44a
--- /dev/null
+++ 
b/ugsync/src/main/java/org/apache/ranger/unixusersync/ha/UserSyncHAInitializerImpl.java
@@ -0,0 +1,110 @@
+/*
+ * 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.ranger.unixusersync.ha;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.ranger.RangerHAInitializer;
+import org.apache.ranger.ha.ActiveInstanceElectorService;
+import org.apache.ranger.ha.ActiveStateChangeHandler;
+import org.apache.ranger.ha.ServiceState;
+import org.apache.ranger.ha.service.HARangerService;
+import org.apache.ranger.ha.service.ServiceManager;
+import org.apache.ranger.unixusersync.config.UserGroupSyncConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class UserSyncHAInitializerImpl extends RangerHAInitializer {
+    private static final Logger LOG = 
LoggerFactory.getLogger(UserSyncHAInitializerImpl.class);
+    ActiveInstanceElectorService activeInstanceElectorService = null;
+    ActiveStateChangeHandler activeStateChangeHandler = null;
+    List<HARangerService> haRangerService = null;
+    ServiceManager serviceManager = null;
+    private static UserSyncHAInitializerImpl theInstance = null;
+
+    private UserSyncHAInitializerImpl(Configuration configuration) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> 
UserSyncHAInitializerImpl.UserSyncHAInitializerImpl()");
+        }
+        try {
+            LOG.info("Ranger UserSync server is HA enabled : 
"+configuration.getBoolean(UserGroupSyncConfig.UGSYNC_SERVER_HA_ENABLED_PARAM, 
false) );
+            init(configuration);
+        } catch (Exception e) {
+            LOG.error("UserSyncHAInitializerImpl initialization failed", 
e.getMessage());
+        }
+        if (LOG.isDebugEnabled()) {
+            LOG.info("<== 
UserSyncHAInitializerImpl.UserSyncHAInitializerImpl()");
+        }
+    }
+
+    public void init(Configuration configuration) throws Exception {
+        super.init(configuration);
+        LOG.info("==> UserSyncHAInitializerImpl.init() initialization started 
");
+
+        Set<ActiveStateChangeHandler> activeStateChangeHandlerProviders = new 
HashSet<ActiveStateChangeHandler>();
+        activeInstanceElectorService = new 
ActiveInstanceElectorService(activeStateChangeHandlerProviders,
+                curatorFactory, activeInstanceState, serviceState, 
configuration);
+
+        haRangerService = new ArrayList<HARangerService>();
+        haRangerService.add(activeInstanceElectorService);
+        serviceManager = new ServiceManager(haRangerService);
+        LOG.info("<== UserSyncHAInitializerImpl.init() initialization 
completed.");
+    }
+
+    @Override
+    public void stop() {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> UserSyncHAInitializerImpl.stop()");
+        }
+        if (serviceManager != null) {
+            serviceManager.stop();
+        }
+        if (curatorFactory != null) {
+            curatorFactory.close();
+        }
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== UserSyncHAInitializerImpl.stop()");
+        }
+    }
+
+    public static UserSyncHAInitializerImpl getInstance(Configuration 
configuration) {
+        if(theInstance == null){
+            synchronized(UserSyncHAInitializerImpl.class){
+                if(theInstance == null){
+                    theInstance =  new 
UserSyncHAInitializerImpl(configuration);
+                }
+            }
+        }
+        return theInstance;
+    }
+    public boolean isActive() {
+        try {
+            // To let the curator thread a chance to run and set the active 
state if needed
+            Thread.sleep(0L);
+        } catch (InterruptedException exception) {
+            // Ignore
+        }
+        return 
serviceState.getState().equals(ServiceState.ServiceStateValue.ACTIVE);
+    }
+}
diff --git 
a/ugsync/src/main/java/org/apache/ranger/unixusersync/process/PolicyMgrUserGroupBuilder.java
 
b/ugsync/src/main/java/org/apache/ranger/unixusersync/process/PolicyMgrUserGroupBuilder.java
index 27e48202e..31fc7829e 100644
--- 
a/ugsync/src/main/java/org/apache/ranger/unixusersync/process/PolicyMgrUserGroupBuilder.java
+++ 
b/ugsync/src/main/java/org/apache/ranger/unixusersync/process/PolicyMgrUserGroupBuilder.java
@@ -147,6 +147,7 @@ public class PolicyMgrUserGroupBuilder extends 
AbstractUserGroupSource implement
 
        private boolean isRangerCookieEnabled;
        private String rangerCookieName;
+       private static String errMsgForInactiveServer = "This userGroupSync 
server is not in active state. Cannot commit transaction!";
        static {
                try {
                        LOCAL_HOSTNAME = 
java.net.InetAddress.getLocalHost().getCanonicalHostName();
@@ -282,6 +283,7 @@ public class PolicyMgrUserGroupBuilder extends 
AbstractUserGroupSource implement
                }
 
                if (!isMockRun) {
+                       checkStatus();
                        addUserGroupAuditInfo(ugsyncAuditInfo);
                }
 
@@ -292,6 +294,7 @@ public class PolicyMgrUserGroupBuilder extends 
AbstractUserGroupSource implement
                                                                           
Map<String, Map<String, String>> sourceUsers,
                                                                           
Map<String, Set<String>> sourceGroupUsers,
                                                                           
boolean computeDeletes) throws Throwable {
+               checkStatus();
 
                noOfNewUsers = 0;
                noOfNewGroups = 0;
@@ -966,6 +969,7 @@ public class PolicyMgrUserGroupBuilder extends 
AbstractUserGroupSource implement
                int uploadedCount = 0;
                int pageSize = Integer.valueOf(recordsToPullPerCall);
                while (uploadedCount < totalCount) {
+                       checkStatus();
                        String response = null;
                        ClientResponse clientRes = null;
                        GetXUserListResponse pagedXUserList = new 
GetXUserListResponse();
@@ -1062,11 +1066,13 @@ public class PolicyMgrUserGroupBuilder extends 
AbstractUserGroupSource implement
                if(LOG.isDebugEnabled()){
                        LOG.debug("==> PolicyMgrUserGroupBuilder.getGroups()");
                }
+
                int ret = 0;
                int totalCount = xGroupList.getTotalCount();
                int uploadedCount = 0;
                int pageSize = Integer.valueOf(recordsToPullPerCall);
                while (uploadedCount < totalCount) {
+                       checkStatus();
                        String response = null;
                        ClientResponse clientRes = null;
                        GetXGroupListResponse pagedXGroupList = new 
GetXGroupListResponse();
@@ -1160,6 +1166,7 @@ public class PolicyMgrUserGroupBuilder extends 
AbstractUserGroupSource implement
                int uploadedCount = 0;
                int pageSize = Integer.valueOf(recordsToPullPerCall);
                while (uploadedCount < totalCount) {
+                       checkStatus();
                        String response = null;
                        ClientResponse clientRes = null;
 
@@ -1245,6 +1252,7 @@ public class PolicyMgrUserGroupBuilder extends 
AbstractUserGroupSource implement
                        int uploadedCount = 0;
                        int pageSize = Integer.valueOf(recordsToPullPerCall);
                        while (uploadedCount < totalCount) {
+                               checkStatus();
                                int pagedUgRoleAssignmentsListLen = 
uploadedCount + pageSize;
                                UsersGroupRoleAssignments 
pagedUgRoleAssignmentsList = new UsersGroupRoleAssignments();
                                
pagedUgRoleAssignmentsList.setUsers(ugRoleAssignments.getUsers().subList(uploadedCount,
@@ -1295,7 +1303,7 @@ public class PolicyMgrUserGroupBuilder extends 
AbstractUserGroupSource implement
                return ret;
        }
 
-       private void addUserGroupAuditInfo(UgsyncAuditInfo auditInfo) {
+       private void addUserGroupAuditInfo(UgsyncAuditInfo auditInfo) throws 
Throwable{
                if (LOG.isDebugEnabled()) {
                        LOG.debug("==> PolicyMgrUserGroupBuilder.addAuditInfo(" 
+ auditInfo.getNoOfNewUsers() + ", " + auditInfo.getNoOfNewGroups() +
                                        ", " + auditInfo.getNoOfModifiedUsers() 
+ ", " + auditInfo.getNoOfModifiedGroups() +
@@ -1314,7 +1322,7 @@ public class PolicyMgrUserGroupBuilder extends 
AbstractUserGroupSource implement
                                        public Void run() {
                                                try {
                                                        
getUserGroupAuditInfo(auditInfoFinal);
-                                               } catch (Exception e) {
+                                               } catch (Throwable e) {
                                                        LOG.error("Failed to 
add User : ", e);
                                                }
                                                return null;
@@ -1331,10 +1339,11 @@ public class PolicyMgrUserGroupBuilder extends 
AbstractUserGroupSource implement
        }
 
 
-       private void getUserGroupAuditInfo(UgsyncAuditInfo userInfo) {
+       private void getUserGroupAuditInfo(UgsyncAuditInfo userInfo) throws 
Throwable{
                if(LOG.isDebugEnabled()){
                        LOG.debug("==> 
PolicyMgrUserGroupBuilder.getUserGroupAuditInfo()");
                }
+               checkStatus();
                String response = null;
                ClientResponse clientRes = null;
                Gson gson = new GsonBuilder().create();
@@ -1404,7 +1413,6 @@ public class PolicyMgrUserGroupBuilder extends 
AbstractUserGroupSource implement
                }
                String response = null;
                ClientResponse clientResp = null;
-
                try {
                        clientResp = ldapUgSyncClient.post(apiURL, null, obj, 
sessionId);
                }
@@ -1800,6 +1808,7 @@ public class PolicyMgrUserGroupBuilder extends 
AbstractUserGroupSource implement
                if(LOG.isDebugEnabled()){
                        LOG.debug("==> 
PolicyMgrUserGroupBuilder.getDeletedGroups()");
                }
+               checkStatus();
                int ret = 0;
                String response = null;
                ClientResponse clientRes = null;
@@ -1920,6 +1929,7 @@ public class PolicyMgrUserGroupBuilder extends 
AbstractUserGroupSource implement
                if(LOG.isDebugEnabled()){
                        LOG.debug("==> 
PolicyMgrUserGroupBuilder.getDeletedUsers()");
                }
+               checkStatus();
                int ret = 0;
                String response = null;
                ClientResponse clientRes = null;
@@ -1965,4 +1975,12 @@ public class PolicyMgrUserGroupBuilder extends 
AbstractUserGroupSource implement
                
config.setProperty(UserGroupSyncConfig.UGSYNC_NAME_VALIDATION_ENABLED, 
isNameValidationEnabled);
                this.isUserSyncNameValidationEnabled = 
config.isUserSyncNameValidationEnabled();
        }
+
+       // This will throw RuntimeException if Server is not Active
+       private void checkStatus() throws Exception {
+               if(!UserGroupSyncConfig.isUgsyncServiceActive()) {
+                       LOG.error(errMsgForInactiveServer);
+                       throw new RuntimeException(errMsgForInactiveServer);
+               }
+       }
 }
diff --git 
a/ugsync/src/main/java/org/apache/ranger/usergroupsync/UserGroupSync.java 
b/ugsync/src/main/java/org/apache/ranger/usergroupsync/UserGroupSync.java
index 575042620..361842c2e 100644
--- a/ugsync/src/main/java/org/apache/ranger/usergroupsync/UserGroupSync.java
+++ b/ugsync/src/main/java/org/apache/ranger/usergroupsync/UserGroupSync.java
@@ -39,30 +39,38 @@ public class UserGroupSync implements Runnable {
        public void run() {
                try {
                        long sleepTimeBetweenCycleInMillis = 
UserGroupSyncConfig.getInstance().getSleepTimeInMillisBetweenCycle();
-
+                       long initSleepTimeBetweenCycleInMillis = 
UserGroupSyncConfig.getInstance().getInitSleepTimeInMillisBetweenCycle();
                        boolean initPending = true;
 
                        while (initPending) {
                                try {
-                                       ugSink = 
UserGroupSyncConfig.getInstance().getUserGroupSink();
-                                       LOG.info("initializing sink: " + 
ugSink.getClass().getName());
-                                       ugSink.init();
-
-                                       ugSource = 
UserGroupSyncConfig.getInstance().getUserGroupSource();
-                                       LOG.info("initializing source: " + 
ugSource.getClass().getName());
-                                       ugSource.init();
-
-                                       LOG.info("Begin: initial load of 
user/group from source==>sink");
-                                       syncUserGroup();
-                                       LOG.info("End: initial load of 
user/group from source==>sink");
-
-                                       initPending = false;
-
-                                       LOG.info("Done initializing user/group 
source and sink");
+                                       if 
(UserGroupSyncConfig.isUgsyncServiceActive()) {
+                                               ugSink = 
UserGroupSyncConfig.getInstance().getUserGroupSink();
+                                               LOG.info("initializing sink: " 
+ ugSink.getClass().getName());
+                                               ugSink.init();
+
+                                               ugSource = 
UserGroupSyncConfig.getInstance().getUserGroupSource();
+                                               LOG.info("initializing source: 
" + ugSource.getClass().getName());
+                                               ugSource.init();
+
+                                               LOG.info("Begin: initial load 
of user/group from source==>sink");
+                                               syncUserGroup();
+                                               LOG.info("End: initial load of 
user/group from source==>sink");
+
+                                               initPending = false;
+                                               LOG.info("Done initializing 
user/group source and sink");
+                                       }else {
+                                               if (LOG.isDebugEnabled()){
+                                                       LOG.debug("Sleeping for 
[" + initSleepTimeBetweenCycleInMillis + "] milliSeconds as this server is 
running in passive mode");
+                                               }
+                                               
Thread.sleep(initSleepTimeBetweenCycleInMillis);
+                                       }
                                } catch (Throwable t) {
                                        LOG.error("Failed to initialize 
UserGroup source/sink. Will retry after " + sleepTimeBetweenCycleInMillis + " 
milliseconds. Error details: ", t);
                                        try {
-                                               LOG.debug("Sleeping for [" + 
sleepTimeBetweenCycleInMillis + "] milliSeconds");
+                                               if (LOG.isDebugEnabled()){
+                                                       LOG.debug("Sleeping for 
[" + sleepTimeBetweenCycleInMillis + "] milliSeconds");
+                                               }
                                                
Thread.sleep(sleepTimeBetweenCycleInMillis);
                                        } catch (Exception e) {
                                                LOG.error("Failed to wait for 
[" + sleepTimeBetweenCycleInMillis + "] milliseconds before attempting to 
initialize UserGroup source/sink", e);
@@ -72,16 +80,22 @@ public class UserGroupSync implements Runnable {
 
                        while (true) {
                                try {
-                                       LOG.debug("Sleeping for [" + 
sleepTimeBetweenCycleInMillis + "] milliSeconds");
+                                       if (LOG.isDebugEnabled()){
+                                               LOG.debug("Sleeping for [" + 
sleepTimeBetweenCycleInMillis + "] milliSeconds");
+                                       }
                                        
Thread.sleep(sleepTimeBetweenCycleInMillis);
                                } catch (InterruptedException e) {
                                        LOG.error("Failed to wait for [" + 
sleepTimeBetweenCycleInMillis + "] milliseconds before attempting to 
synchronize UserGroup information", e);
                                }
 
                                try {
-                                       LOG.info("Begin: update user/group from 
source==>sink");
-                                       syncUserGroup();
-                                       LOG.info("End: update user/group from 
source==>sink");
+                                       if 
(UserGroupSyncConfig.isUgsyncServiceActive()) {
+                                               LOG.info("Begin: update 
user/group from source==>sink");
+                                               syncUserGroup();
+                                               LOG.info("End: update 
user/group from source==>sink");
+                                       } else {
+                                               LOG.info("Sleeping for [" + 
sleepTimeBetweenCycleInMillis + "] milliSeconds as this server is running in 
passive mode");
+                                       }
                                } catch (Throwable t) {
                                        LOG.error("Failed to synchronize 
UserGroup information. Error details: ", t);
                                }
diff --git 
a/ugsync/src/main/java/org/apache/ranger/usergroupsync/UserSyncMetricsProducer.java
 
b/ugsync/src/main/java/org/apache/ranger/usergroupsync/UserSyncMetricsProducer.java
index 9846a1bf5..1e80c5da8 100644
--- 
a/ugsync/src/main/java/org/apache/ranger/usergroupsync/UserSyncMetricsProducer.java
+++ 
b/ugsync/src/main/java/org/apache/ranger/usergroupsync/UserSyncMetricsProducer.java
@@ -21,6 +21,7 @@ package org.apache.ranger.usergroupsync;
 
 import java.io.File;
 
+import org.apache.hadoop.conf.Configuration;
 import org.apache.ranger.plugin.util.RangerMetricsUtil;
 import org.apache.ranger.unixusersync.config.UserGroupSyncConfig;
 import org.slf4j.Logger;
@@ -79,11 +80,20 @@ public class UserSyncMetricsProducer implements Runnable {
        private void writeJVMMetrics(String logFileNameWithPath) throws 
Throwable {
                try {
                        File userMetricFile = null;
+                       UserGroupSyncConfig userConfig = 
UserGroupSyncConfig.getInstance();
+                       Configuration config = userConfig.getUserGroupConfig();
                        userMetricFile = new File(logFileNameWithPath);
                        if (!userMetricFile.exists()) {
                                userMetricFile.createNewFile();
                        }
                        RangerMetricsUtil rangerMetricsUtil = new 
RangerMetricsUtil();
+                       if 
(config.getBoolean(UserGroupSyncConfig.UGSYNC_SERVER_HA_ENABLED_PARAM, false)) {
+                               if(userConfig.isUgsyncServiceActive()){
+                                       rangerMetricsUtil.setIsRoleActive(1);
+                               }else{
+                                       rangerMetricsUtil.setIsRoleActive(0);
+                               }
+                       }
                        rangerMetricsUtil.writeMetricsToFile(userMetricFile);
                } catch (Throwable t) {
                        LOG.error("UserSyncMetricsProducer.writeJVMMetrics() 
failed to write metrics into file. Error details: ", t);
diff --git a/unixauthservice/scripts/templates/ranger-ugsync-template.xml 
b/unixauthservice/scripts/templates/ranger-ugsync-template.xml
index 0ae76eb55..52f027a5c 100644
--- a/unixauthservice/scripts/templates/ranger-ugsync-template.xml
+++ b/unixauthservice/scripts/templates/ranger-ugsync-template.xml
@@ -241,4 +241,62 @@
                <name>ranger.usersync.metrics.filename</name>
                <value></value>
     </property>
+
+       <!-- HA property -->
+       <property>
+               <name>ranger.service.name</name>
+               <value>ranger-ugsync</value>
+       </property>
+       <property>
+               <name>ranger-ugsync.server.ha.enabled</name>
+               <value>false</value>
+       </property>
+       <property>
+               <name>ranger-ugsync.server.ha.zookeeper.zkroot</name>
+               <value>/ranger-ugsync</value>
+       </property>
+       <property>
+               <name>ranger-ugsync.server.ha.zookeeper.connect</name>
+               <value></value>
+       </property>
+       <property>
+               <name>ranger-ugsync.server.ha.ids</name>
+               <value>id1,id2</value>
+       </property>
+       <property>
+               <name>ranger-ugsync.server.ha.address.id1</name>
+               <value></value>
+       </property>
+       <property>
+               <name>ranger-ugsync.server.ha.address.id2</name>
+               <value></value>
+       </property>
+       <property>
+               
<name>ranger-ugsync.server.ha.zookeeper.retry.sleeptime.ms</name>
+               <value>1000</value>
+       </property>
+       <property>
+               
<name>ranger-ugsync.server.ha.zookeeper.session.timeout.ms</name>
+               <value>20000</value>
+       </property>
+       <property>
+               <name>ranger-ugsync.server.ha.zookeeper.num.retries</name>
+               <value>3</value>
+       </property>
+       <property>
+               <name>ranger-ugsync.server.ha.zookeeper.acl</name>
+               <value></value>
+       </property>
+       <property>
+               <name>ranger-ugsync.server.ha.zookeeper.auth</name>
+               <value></value>
+       </property>
+       <property>
+               <name>ranger-ugsync.server.ha.http.port</name>
+               <value></value>
+       </property>
+       <property>
+               <name>ranger-ugsync.server.ha.https.port</name>
+               <value></value>
+       </property>
 </configuration>
diff --git 
a/unixauthservice/src/main/java/org/apache/ranger/authentication/UnixAuthenticationService.java
 
b/unixauthservice/src/main/java/org/apache/ranger/authentication/UnixAuthenticationService.java
index d03f45087..e226662e1 100644
--- 
a/unixauthservice/src/main/java/org/apache/ranger/authentication/UnixAuthenticationService.java
+++ 
b/unixauthservice/src/main/java/org/apache/ranger/authentication/UnixAuthenticationService.java
@@ -43,6 +43,7 @@ import javax.net.ssl.SSLServerSocketFactory;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.TrustManagerFactory;
 
+import org.apache.ranger.unixusersync.ha.UserSyncHAInitializerImpl;
 import org.apache.ranger.credentialapi.CredentialReader;
 import org.apache.ranger.plugin.util.XMLUtils;
 import org.apache.ranger.unixusersync.config.UserGroupSyncConfig;
@@ -86,6 +87,7 @@ public class UnixAuthenticationService {
        private String trustStoreType;
        private List<String>  adminUserList = new ArrayList<String>();
        private String adminRoleNames;
+       private UserSyncHAInitializerImpl userSyncHAInitializerImpl = null;
        
        private int  portNum;
        
@@ -105,6 +107,7 @@ public class UnixAuthenticationService {
                        }
                }
                UnixAuthenticationService service = new 
UnixAuthenticationService();
+               service.userSyncHAInitializerImpl = 
UserSyncHAInitializerImpl.getInstance(UserGroupSyncConfig.getInstance().getUserGroupConfig());
                service.run();
        }
 
@@ -130,6 +133,10 @@ public class UnixAuthenticationService {
                }
                finally {
                        LOG.info("Service: " + serviceName + " - STOPPED.");
+                       if(this.userSyncHAInitializerImpl != null) {
+                               LOG.info("Stopping curator leader latch service 
as main thread is closing");
+                               this.userSyncHAInitializerImpl.stop();
+                       }
                }
        }
 

Reply via email to