You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2015/01/07 20:32:01 UTC

[02/27] incubator-ranger git commit: Ranger-201:Update UserSync to optimize the REST calls made to sync users and group

Ranger-201:Update UserSync to optimize the REST calls made to sync users and group


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

Branch: refs/heads/stack
Commit: 2203ffbeb756e63781c7806edcdada28ea415817
Parents: a0d23c7
Author: rmani <rm...@hortonworks.com>
Authored: Fri Dec 19 23:40:07 2014 -0800
Committer: rmani <rm...@hortonworks.com>
Committed: Fri Dec 19 23:40:07 2014 -0800

----------------------------------------------------------------------
 .../java/org/apache/ranger/biz/XUserMgr.java    |  27 +++
 .../java/org/apache/ranger/rest/XUserREST.java  |   8 +
 .../org/apache/ranger/view/VXUserGroupInfo.java |  66 ++++++
 .../org/apache/ranger/biz/TestXUserMgr.java     |  51 +++++
 .../config/UserGroupSyncConfig.java             |   6 +
 .../unixusersync/model/UserGroupInfo.java       |  41 ++++
 .../unixusersync/model/UserGroupList.java       |  57 ++++++
 .../process/FileSourceUserGroupBuilder.java     | 161 +++++++++++++++
 .../process/PolicyMgrUserGroupBuilder.java      | 204 ++++++++++---------
 .../conf.dist/unixauthservice.properties        |   9 +-
 10 files changed, 538 insertions(+), 92 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2203ffbe/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
index 64ae9b3..fa03f2f 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
@@ -42,6 +42,7 @@ import org.apache.ranger.view.VXGroupUser;
 import org.apache.ranger.view.VXGroupUserList;
 import org.apache.ranger.view.VXPortalUser;
 import org.apache.ranger.view.VXUser;
+import org.apache.ranger.view.VXUserGroupInfo;
 import org.apache.ranger.view.VXUserList;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
@@ -299,6 +300,32 @@ public class XUserMgr extends XUserMgrBase {
 
 		return vXUser;
 	}
+	
+	public VXUserGroupInfo createXUserGroupFromMap(VXUserGroupInfo vXUserGroupInfo) {
+		
+		VXUserGroupInfo vxUGInfo = new VXUserGroupInfo();
+		
+		VXUser vXUser = vXUserGroupInfo.getXuserInfo();
+		
+		vXUser = xUserService.createXUserWithOutLogin(vXUser);
+		
+		vxUGInfo.setXuserInfo(vXUser);
+		
+		List<VXGroup> vxg = new ArrayList<VXGroup>();
+		
+		for(VXGroup vXGroup : vXUserGroupInfo.getXgroupInfo()){
+			VXGroup VvXGroup = xGroupService.createXGroupWithOutLogin(vXGroup);
+			vxg.add(VvXGroup);
+			VXGroupUser vXGroupUser = new VXGroupUser();
+			vXGroupUser.setUserId(vXUser.getId());
+			vXGroupUser.setName(VvXGroup.getName());
+			vXGroupUser = xGroupUserService.createXGroupUserWithOutLogin(vXGroupUser);
+		}
+		
+		vxUGInfo.setXgroupInfo(vxg);
+		
+		return vxUGInfo;
+	}
 
 	public VXUser createXUserWithOutLogin(VXUser vXUser) {		
 		return xUserService.createXUserWithOutLogin(vXUser);

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2203ffbe/security-admin/src/main/java/org/apache/ranger/rest/XUserREST.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/XUserREST.java b/security-admin/src/main/java/org/apache/ranger/rest/XUserREST.java
index 5e6243e..9ebdd63 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/XUserREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/XUserREST.java
@@ -60,6 +60,7 @@ import org.apache.ranger.view.VXLong;
 import org.apache.ranger.view.VXPermMap;
 import org.apache.ranger.view.VXPermMapList;
 import org.apache.ranger.view.VXUser;
+import org.apache.ranger.view.VXUserGroupInfo;
 import org.apache.ranger.view.VXUserList;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Scope;
@@ -218,6 +219,13 @@ public class XUserREST {
 	}
 	
 	@POST
+	@Path("/users/userinfo")
+	@Produces({ "application/xml", "application/json" })
+	public VXUserGroupInfo createXUserGroupFromMap(VXUserGroupInfo vXUserGroupInfo) {
+		return  xUserMgr.createXUserGroupFromMap(vXUserGroupInfo);
+	} 
+	
+	@POST
 	@Path("/secure/users")
 	@Produces({ "application/xml", "application/json" })
 	public VXUser secureCreateXUser(VXUser vXUser) {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2203ffbe/security-admin/src/main/java/org/apache/ranger/view/VXUserGroupInfo.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/view/VXUserGroupInfo.java b/security-admin/src/main/java/org/apache/ranger/view/VXUserGroupInfo.java
new file mode 100644
index 0000000..09cc1aa
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/view/VXUserGroupInfo.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+ package org.apache.ranger.view;
+
+/**
+ * UserGroupInfo
+ * 
+ */
+
+import java.util.List;
+
+import javax.xml.bind.annotation.*;
+
+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;
+
+@JsonAutoDetect(getterVisibility=Visibility.NONE, setterVisibility=Visibility.NONE, fieldVisibility=Visibility.ANY)
+@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL )
+@JsonIgnoreProperties(ignoreUnknown=true)
+@XmlRootElement
+public class VXUserGroupInfo extends VXDataObject implements java.io.Serializable  {
+	
+	private static final long serialVersionUID = 1L;
+	
+	VXUser xuserInfo;
+	List<VXGroup> xgroupInfo;
+	
+	public VXUserGroupInfo ( ) {
+	}
+
+	public VXUser getXuserInfo() {
+		return xuserInfo;
+	}
+
+	public void setXuserInfo(VXUser xuserInfo) {
+		this.xuserInfo = xuserInfo;
+	}
+
+	public List<VXGroup> getXgroupInfo() {
+		return xgroupInfo;
+	}
+
+	public void setXgroupInfo(List<VXGroup> xgroupInfo) {
+		this.xgroupInfo = xgroupInfo;
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2203ffbe/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java
----------------------------------------------------------------------
diff --git a/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java b/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java
index 972e7b7..b05ebb4 100644
--- a/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java
+++ b/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java
@@ -18,6 +18,7 @@ package org.apache.ranger.biz;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 
 import org.apache.ranger.common.ContextUtil;
 import org.apache.ranger.common.RESTErrorUtil;
@@ -40,6 +41,7 @@ import org.apache.ranger.view.VXGroupUser;
 import org.apache.ranger.view.VXGroupUserList;
 import org.apache.ranger.view.VXPortalUser;
 import org.apache.ranger.view.VXUser;
+import org.apache.ranger.view.VXUserGroupInfo;
 import org.apache.ranger.view.VXUserList;
 import org.junit.Assert;
 import org.junit.FixMethodOrder;
@@ -393,4 +395,53 @@ public class TestXUserMgr {
 		Mockito.verify(xGroupUserService).searchXGroupUsers((SearchCriteria) Mockito
 				.anyObject());
 	}
+	
+	@Test
+	public void test24CreateVXUserGroupInfo(){
+	
+		VXUserGroupInfo vXUserGroupInfo = new VXUserGroupInfo();
+		VXUser vXUser = new VXUser();
+		vXUser.setName("user1");
+		vXUser.setDescription("testuser1 -added for unit testing");
+		
+		List<VXGroupUser> vXGroupUserList = new ArrayList<VXGroupUser>();
+		List<VXGroup> vXGroupList = new ArrayList<VXGroup>();
+		
+		final VXGroup vXGroup1 = new VXGroup();
+		vXGroup1.setName("users");
+		vXGroup1.setDescription("users -added for unit testing");
+		vXGroupList.add(vXGroup1);
+		
+		VXGroupUser vXGroupUser1 = new VXGroupUser();
+		vXGroupUser1.setName("users");
+		vXGroupUserList.add(vXGroupUser1);
+		
+		final VXGroup vXGroup2 = new VXGroup();
+		vXGroup2.setName("user1");
+		vXGroup2.setDescription("user1 -added for unit testing");
+		vXGroupList.add(vXGroup2);
+		
+		VXGroupUser vXGroupUser2 = new VXGroupUser();
+		vXGroupUser2.setName("user1");
+		vXGroupUserList.add(vXGroupUser2);
+		
+		vXUserGroupInfo.setXuserInfo(vXUser);
+		vXUserGroupInfo.setXgroupInfo(vXGroupList);
+		
+		Mockito.when(xUserService.createXUserWithOutLogin(vXUser)).thenReturn(vXUser);
+		Mockito.when(xGroupService.createXGroupWithOutLogin(vXGroup1)).thenReturn(vXGroup1);
+		Mockito.when(xGroupService.createXGroupWithOutLogin(vXGroup2)).thenReturn(vXGroup2);
+		Mockito.when(xGroupUserService.createXGroupUserWithOutLogin(vXGroupUser1)).thenReturn(vXGroupUser1);
+		Mockito.when(xGroupUserService.createXGroupUserWithOutLogin(vXGroupUser2)).thenReturn(vXGroupUser2);
+		
+		VXUserGroupInfo vxUserGroupTest = xUserMgr.createXUserGroupFromMap(vXUserGroupInfo);
+		Assert.assertEquals("user1", vxUserGroupTest
+				.getXuserInfo()
+				.getName());
+		List<VXGroup> result = vxUserGroupTest.getXgroupInfo();
+		List<VXGroup> expected = new ArrayList<VXGroup>();
+		expected.add(vXGroup1);
+		expected.add(vXGroup2);
+		Assert.assertTrue(result.containsAll(expected));
+	}	
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2203ffbe/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java
----------------------------------------------------------------------
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 b9ea343..28372f1 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
@@ -46,6 +46,8 @@ public class UserGroupSyncConfig  {
 
 	public static final String  UGSYNC_MOCK_RUN_PROP  = 	"usergroupSync.policymanager.mockRun" ;
 	
+	public static final String UGSYNC_SOURCE_FILE_PROC =	"usergroupSync.filesource.file";
+	
 	private static final String SSL_KEYSTORE_PATH_PARAM = "keyStore" ;
 
 	private static final String SSL_KEYSTORE_PATH_PASSWORD_PARAM = "keyStorePassword" ;
@@ -174,6 +176,10 @@ public class UserGroupSyncConfig  {
 		return ret;
 	}
 	
+	public String getUserSyncFileSource(){
+		String val = prop.getProperty(UGSYNC_SOURCE_FILE_PROC) ;
+		return val;
+	}
 	
 	public boolean isUserSyncEnabled() {
 		String val = prop.getProperty(UGSYNC_ENABLED_PROP) ;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2203ffbe/ugsync/src/main/java/org/apache/ranger/unixusersync/model/UserGroupInfo.java
----------------------------------------------------------------------
diff --git a/ugsync/src/main/java/org/apache/ranger/unixusersync/model/UserGroupInfo.java b/ugsync/src/main/java/org/apache/ranger/unixusersync/model/UserGroupInfo.java
new file mode 100644
index 0000000..d720eae
--- /dev/null
+++ b/ugsync/src/main/java/org/apache/ranger/unixusersync/model/UserGroupInfo.java
@@ -0,0 +1,41 @@
+/*
+ * 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.model;
+
+import java.util.List;
+
+public class UserGroupInfo {
+
+	XUserInfo xuserInfo;
+	List<XGroupInfo> xgroupInfo;
+
+	public XUserInfo getXuserInfo() {
+		return xuserInfo;
+	}
+	public void setXuserInfo(XUserInfo xuserInfo) {
+		this.xuserInfo = xuserInfo;
+	}
+	public List<XGroupInfo> getXgroupInfo() {
+		return xgroupInfo;
+	}
+	public void setXgroupInfo(List<XGroupInfo> xgroupInfo) {
+		this.xgroupInfo = xgroupInfo;
+	}
+} 
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2203ffbe/ugsync/src/main/java/org/apache/ranger/unixusersync/model/UserGroupList.java
----------------------------------------------------------------------
diff --git a/ugsync/src/main/java/org/apache/ranger/unixusersync/model/UserGroupList.java b/ugsync/src/main/java/org/apache/ranger/unixusersync/model/UserGroupList.java
new file mode 100644
index 0000000..0eec94c
--- /dev/null
+++ b/ugsync/src/main/java/org/apache/ranger/unixusersync/model/UserGroupList.java
@@ -0,0 +1,57 @@
+/*
+ * 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.model;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+@JsonAutoDetect(getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE, fieldVisibility = Visibility.ANY)
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+@XmlRootElement
+public class UserGroupList {
+
+	String user;
+	
+	List<String> groups;
+
+	public String getUser() {
+		return user;
+	}
+
+	public void setUser(String user) {
+		this.user = user;
+	}
+
+	public List<String> getGroups() {
+		return groups;
+	}
+
+	public void setGroups(List<String> groups) {
+		this.groups = groups;
+	}
+
+} 
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2203ffbe/ugsync/src/main/java/org/apache/ranger/unixusersync/process/FileSourceUserGroupBuilder.java
----------------------------------------------------------------------
diff --git a/ugsync/src/main/java/org/apache/ranger/unixusersync/process/FileSourceUserGroupBuilder.java b/ugsync/src/main/java/org/apache/ranger/unixusersync/process/FileSourceUserGroupBuilder.java
new file mode 100644
index 0000000..8ebe71c
--- /dev/null
+++ b/ugsync/src/main/java/org/apache/ranger/unixusersync/process/FileSourceUserGroupBuilder.java
@@ -0,0 +1,161 @@
+/*
+ * 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.process;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.apache.ranger.unixusersync.config.UserGroupSyncConfig;
+import org.apache.ranger.unixusersync.model.UserGroupList;
+import org.apache.ranger.usergroupsync.UserGroupSink;
+import org.apache.ranger.usergroupsync.UserGroupSource;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+public class FileSourceUserGroupBuilder  implements UserGroupSource {
+
+	private static final Logger LOG = Logger.getLogger(FileSourceUserGroupBuilder.class) ;
+	
+	public static  String DEFAULT_USER_GROUP_FILE = null;
+	public static String USER_GROUP_FILE = null;
+	
+	private static boolean isManualRun=false;
+	private Map<String,List<String>>  user2GroupListMap = new HashMap<String,List<String>>();
+	private UserGroupSyncConfig config = UserGroupSyncConfig.getInstance() ;
+	private UserGroupSink ugSink     = null ;
+	private long  usergroupFileModified = 0 ;
+	
+	public static void main(String[] args) throws Throwable {
+		if (args.length > 0) {
+			isManualRun=true;
+			USER_GROUP_FILE = args[0];
+		}	
+		FileSourceUserGroupBuilder  filesourceUGBuilder = new FileSourceUserGroupBuilder() ;
+		filesourceUGBuilder.init();
+		if ( LOG.isDebugEnabled()) {
+			filesourceUGBuilder.print(); 
+		}
+	}
+	
+	@Override
+	public void init() throws Throwable {
+		DEFAULT_USER_GROUP_FILE = config.getUserSyncFileSource();
+		buildUserGroupInfo();
+		if (isManualRun) {
+			ugSink = UserGroupSyncConfig.getInstance().getUserGroupSink();
+			LOG.info("initializing sink: " + ugSink.getClass().getName());
+			ugSink.init();
+			updateSink(ugSink);
+		}
+	}
+
+	private void print() {
+		for(String user : user2GroupListMap.keySet()) {
+			LOG.debug("USER:" + user) ;
+			List<String> groups = user2GroupListMap.get(user) ;
+			if (groups != null) {
+				for(String group : groups) {
+					LOG.debug("\tGROUP: " + group) ;
+				}
+			}
+		}
+	}
+	
+	@Override
+	public boolean isChanged() {
+		long TempUserGroupFileModifedAt = new File(DEFAULT_USER_GROUP_FILE).lastModified() ;
+		if (usergroupFileModified != TempUserGroupFileModifedAt) {
+			return true ;
+		}
+		return false;
+	}
+
+	@Override
+	public void updateSink(UserGroupSink sink) throws Throwable {
+		buildUserGroupInfo() ;
+		for (Map.Entry<String, List<String>> entry : user2GroupListMap.entrySet()) {
+		    String       user   = entry.getKey();
+		    List<String> groups = entry.getValue();
+		    sink.addOrUpdateUser(user, groups);
+		}
+	}
+
+	public void buildUserGroupInfo() throws Throwable {
+		user2GroupListMap = new HashMap<String,List<String>>();
+		buildUserGroupList();
+		if ( LOG.isDebugEnabled()) {
+			print(); 
+		}
+	}
+	
+	public void buildUserGroupList() throws Throwable {
+	
+		Gson gson = new GsonBuilder().create() ;
+		
+		UserGroupList usergrouplist = new UserGroupList();
+		
+		String usergroupFile = null;
+		
+		if (isManualRun) {
+			usergroupFile = USER_GROUP_FILE;
+		} else {
+			usergroupFile = DEFAULT_USER_GROUP_FILE;
+		}
+		
+		if (usergroupFile == null){
+			throw new Exception("User Group Source File is not Configured. Please maintain in unixauthservice.properties or pass it as command line argument for org.apache.ranger.unixusersync.process.FileSourceUserGroupBuilder");
+		}
+		
+		File f = new File(usergroupFile);
+		
+		if (f.exists()) {
+			
+			BufferedReader bfr  = new BufferedReader(new FileReader(f));
+			
+			String line = null ;
+			
+			while ((line = bfr.readLine()) != null) {
+			
+				if (line.trim().isEmpty()) 
+					continue ;
+				
+				usergrouplist = gson.fromJson(line,UserGroupList.class);
+				
+				String user = usergrouplist.getUser();
+				
+				List<String> groups = usergrouplist.getGroups();
+				
+				if ( user != null) {
+					user2GroupListMap.put(user, groups);
+				}
+			}
+			
+			bfr.close();
+			usergroupFileModified = f.lastModified() ;
+		}
+
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2203ffbe/ugsync/src/main/java/org/apache/ranger/unixusersync/process/PolicyMgrUserGroupBuilder.java
----------------------------------------------------------------------
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 db25943..acbee13 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
@@ -42,15 +42,6 @@ import javax.ws.rs.core.MediaType;
 
 import org.apache.log4j.Level;
 import org.apache.log4j.Logger;
-import org.apache.ranger.unixusersync.config.UserGroupSyncConfig;
-import org.apache.ranger.unixusersync.model.GetXGroupListResponse;
-import org.apache.ranger.unixusersync.model.GetXUserGroupListResponse;
-import org.apache.ranger.unixusersync.model.GetXUserListResponse;
-import org.apache.ranger.unixusersync.model.MUserInfo;
-import org.apache.ranger.unixusersync.model.XGroupInfo;
-import org.apache.ranger.unixusersync.model.XUserGroupInfo;
-import org.apache.ranger.unixusersync.model.XUserInfo;
-import org.apache.ranger.usergroupsync.UserGroupSink;
 
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
@@ -60,6 +51,16 @@ 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.client.urlconnection.HTTPSProperties;
+import org.apache.ranger.unixusersync.config.UserGroupSyncConfig;
+import org.apache.ranger.unixusersync.model.GetXGroupListResponse;
+import org.apache.ranger.unixusersync.model.GetXUserGroupListResponse;
+import org.apache.ranger.unixusersync.model.GetXUserListResponse;
+import org.apache.ranger.unixusersync.model.MUserInfo;
+import org.apache.ranger.unixusersync.model.XGroupInfo;
+import org.apache.ranger.unixusersync.model.XUserGroupInfo;
+import org.apache.ranger.unixusersync.model.XUserInfo;
+import org.apache.ranger.unixusersync.model.UserGroupInfo;
+import org.apache.ranger.usergroupsync.UserGroupSink;
 
 public class PolicyMgrUserGroupBuilder implements UserGroupSink {
 	
@@ -67,10 +68,12 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink {
 	
 	public static final String PM_USER_LIST_URI  = "/service/xusers/users/" ;				// GET
 	private static final String PM_ADD_USER_URI  = "/service/xusers/users/" ;				// POST
+	private static final String PM_ADD_USER_GROUP_INFO_URI = "/service/xusers/users/userinfo" ;	// POST
 	
 	public static final String PM_GROUP_LIST_URI = "/service/xusers/groups/" ;				// GET
 	private static final String PM_ADD_GROUP_URI = "/service/xusers/groups/" ;				// POST
 	
+	
 	public static final String PM_USER_GROUP_MAP_LIST_URI = "/service/xusers/groupusers/" ;		// GET
 	private static final String PM_ADD_USER_GROUP_LINK_URI = "/service/xusers/groupusers/" ;	// POST
 	
@@ -85,6 +88,7 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink {
 	
 	private UserGroupSyncConfig  config = UserGroupSyncConfig.getInstance() ;
 
+	private UserGroupInfo				usergroupInfo = new UserGroupInfo();
 	private List<XGroupInfo> 			xgroupList = new ArrayList<XGroupInfo>() ;
 	private List<XUserInfo> 			xuserList = new ArrayList<XUserInfo>() ;
 	private List<XUserGroupInfo> 		xusergroupList = new ArrayList<XUserGroupInfo>() ;
@@ -162,7 +166,6 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink {
 	}
 	
 	
-	
 	private void rebuildUserGroupMap() {
 		
 		for(XUserInfo user : xuserList) {
@@ -173,9 +176,12 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink {
 			addGroupToList(group);
 		}
 		
+		
 		for(XUserGroupInfo ug : xusergroupList) {
 			addUserGroupToList(ug);
 		}
+		
+		
 	}
 	
 	
@@ -210,7 +216,6 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink {
 
 	}
 	
-	
 	private void addUserGroupToList(XUserGroupInfo ugInfo) {
 		String userId = ugInfo.getUserId() ;
 		
@@ -225,6 +230,21 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink {
 			}
 		}
 	}
+	
+	private void addUserGroupInfoToList(XUserInfo userInfo, XGroupInfo groupInfo) {
+		String userId = userInfo.getId();
+		
+		if (userId != null) {
+			XUserInfo user = userId2XUserInfoMap.get(userId) ;
+			
+			if (user != null) {
+				List<String> groups = user.getGroups() ;
+				if (! groups.contains(groupInfo.getName())) {
+					groups.add(groupInfo.getName()) ;
+				}
+			}
+		}
+	}
 
 	private void delUserGroupFromList(XUserInfo userInfo, XGroupInfo groupInfo) {
 		List<String> groups = userInfo.getGroups() ;
@@ -252,26 +272,20 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink {
 		}
 		
 		if (user == null) {    // Does not exists
+
 			LOG.debug("INFO: addPMAccount(" + userName + ")" ) ;
 			if (! isMockRun) {
 				addMUser(userName) ;
 			}
 			
-			LOG.debug("INFO: addPMXAUser(" + userName + ")" ) ;
-			if (! isMockRun) {
-				user = addXUserInfo(userName) ;
-			}
-			
- 			for(String g : groups) {
- 				LOG.debug("INFO: addPMXAGroupToUser(" + userName + "," + g + ")" ) ;
- 			}
- 			if (! isMockRun ) { 
- 				addXUserGroupInfo(user, groups) ;
+			//* Build the user group info object and do the rest call
+ 			if ( ! isMockRun ) {
+ 				addUserGroupInfo(userName,groups);
  			}
+
 		}
 		else {					// Validate group memberships
 			List<String> oldGroups = user.getGroups() ;
-			
 			List<String> addGroups = new ArrayList<String>() ;
 			List<String> delGroups = new ArrayList<String>() ;
 			
@@ -414,108 +428,115 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink {
 	}
 	
 	
+	private UserGroupInfo addUserGroupInfo(String userName, List<String> groups){
 	
-	private XUserInfo addXUserInfo(String aUserName) {
-		XUserInfo ret = null ;
+		UserGroupInfo ret = null;
 		
-		XUserInfo addUser = new XUserInfo() ;
-		addUser.setName(aUserName);
-		addUser.setDescription(aUserName + " - add from Unix box") ;
+		XUserInfo user = null;
 		
-	    Client c = getClient() ;
-	    
-	    WebResource r = c.resource(getURL(PM_ADD_USER_URI)) ;
-	    
-	    Gson gson = new GsonBuilder().create() ;
+		LOG.debug("INFO: addPMXAUser(" + userName + ")" ) ;
+		if (! isMockRun) {
+			user = addXUserInfo(userName) ;
+		}
+		
+		for(String g : groups) {
+				LOG.debug("INFO: addPMXAGroupToUser(" + userName + "," + g + ")" ) ;
+		}
+		if (! isMockRun ) { 
+			addXUserGroupInfo(user, groups) ;
+		}
+		
+		Client c = new Client();
+		
+		WebResource r = c.resource(getURL(PM_ADD_USER_GROUP_INFO_URI));
+		
+		Gson gson = new GsonBuilder().create();
+		
+		String jsonString = gson.toJson(usergroupInfo);
+		
+		LOG.debug("USER GROUP MAPPING" + jsonString);
+		
+		String response = r.accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).post(String.class, jsonString) ;
+		
+		LOG.debug("RESPONSE: [" + response + "]") ;
+		
+		ret = gson.fromJson(response, UserGroupInfo.class);
+		
+		if ( ret != null) {
+			
+			XUserInfo xUserInfo = ret.getXuserInfo();
+			addUserToList(xUserInfo);
+			
+			for(XGroupInfo xGroupInfo : ret.getXgroupInfo()) {
+				addGroupToList(xGroupInfo);
+				addUserGroupInfoToList(xUserInfo,xGroupInfo);
+			}
+		}
+		
+		return ret;	
+	}
 
-	    String jsonString = gson.toJson(addUser) ;
-	    
-	    String response = r.accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).post(String.class, jsonString) ;
-	    
-	    LOG.debug("RESPONSE: [" + response + "]") ;
 
-	    ret = gson.fromJson(response, XUserInfo.class) ;
+	private XUserInfo addXUserInfo(String aUserName) {
+		
+		XUserInfo xuserInfo = new XUserInfo() ;
 
-	    if (ret != null) {
-	    	addUserToList(ret);
-	    }
+		xuserInfo.setName(aUserName);
 		
-		return ret ;
+		xuserInfo.setDescription(aUserName + " - add from Unix box") ;
+	   	
+		usergroupInfo.setXuserInfo(xuserInfo);
+		
+		return xuserInfo ;
 	}
 	
+
 	private XGroupInfo addXGroupInfo(String aGroupName) {
 		
-		XGroupInfo ret = null ;
-		
 		XGroupInfo addGroup = new XGroupInfo() ;
+		
 		addGroup.setName(aGroupName);
+		
 		addGroup.setDescription(aGroupName + " - add from Unix box") ;
-		addGroup.setGroupType("1") ;
 		
-	    Client c = getClient() ;
-	    
-	    WebResource r = c.resource(getURL(PM_ADD_GROUP_URI)) ;
-	    
-	    Gson gson = new GsonBuilder().create() ;
-
-	    String jsonString = gson.toJson(addGroup) ;
-	    
-	    String response = r.accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).post(String.class, jsonString) ;
-	    
-	    LOG.debug("RESPONSE: [" + response + "]") ;
+		addGroup.setGroupType("1") ;
 
-	    ret = gson.fromJson(response, XGroupInfo.class) ;
-	    
-	    if (ret != null) {
-	    	addGroupToList(ret);
-	    }
-		
-		return ret ;
+		return addGroup ;
 	}
-	
-	
+
 	
 	private void addXUserGroupInfo(XUserInfo aUserInfo, List<String> aGroupList) {
+		
+		List<XGroupInfo> xGroupInfoList = new ArrayList<XGroupInfo>();
+		
 		for(String groupName : aGroupList) {
 			XGroupInfo group = groupName2XGroupInfoMap.get(groupName) ;
 			if (group == null) {
 				group = addXGroupInfo(groupName) ;
 			}
+			xGroupInfoList.add(group);
 			addXUserGroupInfo(aUserInfo, group) ;
 		}
+		
+		usergroupInfo.setXgroupInfo(xGroupInfoList);
 	}
+	
+	
 
-	private XUserGroupInfo addXUserGroupInfo(XUserInfo aUserInfo, XGroupInfo aGroupInfo) {
-		
-		XUserGroupInfo ret = null ;
+	
+   private XUserGroupInfo addXUserGroupInfo(XUserInfo aUserInfo, XGroupInfo aGroupInfo) {
 		
-		XUserGroupInfo ugInfo = new XUserGroupInfo() ;
+	    XUserGroupInfo ugInfo = new XUserGroupInfo() ;
 		
 		ugInfo.setUserId(aUserInfo.getId());
-		ugInfo.setGroupName(aGroupInfo.getName()) ;
-		// ugInfo.setParentGroupId("1");
 		
-	    Client c = getClient() ;
-	    
-	    WebResource r = c.resource(getURL(PM_ADD_USER_GROUP_LINK_URI)) ;
-	    
-	    Gson gson = new GsonBuilder().create() ;
-
-	    String jsonString = gson.toJson(ugInfo) ;
-	    
-	    String response = r.accept(MediaType.APPLICATION_JSON_TYPE).type(MediaType.APPLICATION_JSON_TYPE).post(String.class, jsonString) ;
-	    
-	    LOG.debug("RESPONSE: [" + response + "]") ;
-
-	    ret = gson.fromJson(response, XUserGroupInfo.class) ;
-	    
-	    if (ret != null) {
-	    	addUserGroupToList(ret);
-	    }
+		ugInfo.setGroupName(aGroupInfo.getName()) ;
 		
-		return ret ;
+		// ugInfo.setParentGroupId("1");
 		
+	    return ugInfo ;
 	}
+
 	
 	private void delXUserGroupInfo(XUserInfo aUserInfo, List<String> aGroupList) {
 		for(String groupName : aGroupList) {
@@ -556,7 +577,7 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink {
 		userInfo.setFirstName(aUserName);
 		userInfo.setLastName(aUserName);
 		userInfo.setEmailAddress(aUserName + "@" + LOCAL_HOSTNAME);
-		
+	
 	    Client c = getClient() ;
 	    
 	    WebResource r = c.resource(getURL(PM_ADD_LOGIN_USER_URI)) ;
@@ -574,10 +595,11 @@ public class PolicyMgrUserGroupBuilder implements UserGroupSink {
 	    LOG.debug("MUser Creation successful " + ret);
 		
 		return ret ;
+		
 
 	}
-
 	
+
 	private synchronized Client getClient() {
 		
 		Client ret = null; 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2203ffbe/unixauthservice/conf.dist/unixauthservice.properties
----------------------------------------------------------------------
diff --git a/unixauthservice/conf.dist/unixauthservice.properties b/unixauthservice/conf.dist/unixauthservice.properties
index 993f80c..25b8887 100644
--- a/unixauthservice/conf.dist/unixauthservice.properties
+++ b/unixauthservice/conf.dist/unixauthservice.properties
@@ -74,12 +74,19 @@ usergroupSync.unix.minUserId = 500
 usergroupSync.sleepTimeInMillisBetweenSyncCycle =
 
 # sync source class
-# we provide 2 classes out of box
+# we provide 3 classes out of box
 # org.apache.ranger.unixusersync.process.UnixUserGroupBuilder
 # org.apache.ranger.ldapusersync.process.LdapUserGroupBuilder
+# org.apache.ranger.unixusersync.process.FileSourceUserGroupBuilder
 # default value:  org.apache.ranger.unixusersync.process.UnixUserGroupBuilder
 usergroupSync.source.impl.class =
 
+# ---------------------------------------------------------------
+# The following properties are relevant
+# only if value of usergroupSync.source.impl.class is
+# org.apache.ranger.unixusersync.process.FileSourceUserGroupBuilder
+# ---------------------------------------------------------------
+usergroupSync.filesource.file =
 
 # ---------------------------------------------------------------
 # The following properties are relevant