Yair Zaslavsky has uploaded a new change for review.

Change subject: aaa: Fixing Sync
......................................................................

aaa: Fixing Sync

Change-Id: I3a66a7c235f16ff26cac3a779de688c73d67f4a2
Topic: AAA
Signed-off-by: Yair Zaslavsky <yzasl...@redhat.com>
---
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/DbUserCacheManager.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/DirectoryEntryKey.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/SyncUsers.java
3 files changed, 145 insertions(+), 207 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/15/29915/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/DbUserCacheManager.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/DbUserCacheManager.java
index b348104..83f89ee 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/DbUserCacheManager.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/DbUserCacheManager.java
@@ -1,29 +1,13 @@
 package org.ovirt.engine.core.bll;
 
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
-import org.apache.commons.lang.StringUtils;
-import org.ovirt.engine.core.aaa.AuthzUtils;
-import org.ovirt.engine.core.aaa.DirectoryGroup;
-import org.ovirt.engine.core.aaa.DirectoryUser;
-import org.ovirt.engine.core.aaa.DirectoryUtils;
 import org.ovirt.engine.core.common.businessentities.DbGroup;
-import org.ovirt.engine.core.common.businessentities.DbUser;
 import org.ovirt.engine.core.common.config.Config;
 import org.ovirt.engine.core.common.config.ConfigValues;
-import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.core.dal.dbbroker.DbFacade;
-import org.ovirt.engine.core.dao.DbGroupDAO;
-import org.ovirt.engine.core.dao.DbUserDAO;
-import org.ovirt.engine.core.extensions.mgr.ExtensionProxy;
-import org.ovirt.engine.core.utils.collections.MultiValueMapUtils;
-import org.ovirt.engine.core.utils.extensionsmgr.EngineExtensionsManager;
 import org.ovirt.engine.core.utils.log.Log;
 import org.ovirt.engine.core.utils.log.LogFactory;
 import org.ovirt.engine.core.utils.timer.OnTimerMethodAnnotation;
@@ -68,197 +52,7 @@
      */
     @OnTimerMethodAnnotation("refreshAllUsers")
     public void refreshAllUsers() {
-        // We will need the DAO:
-        DbUserDAO dao = DbFacade.getInstance().getDbUserDao();
-
-        // Retrieve all the users from the database:
-        List<DbUser> dbUsers = dao.getAll();
-        List<DbGroup> dbGroups = 
DbFacade.getInstance().getDbGroupDao().getAll();
-        for (DbGroup group : dbGroups) {
-            groupsMap.put(group.getExternalId(), group);
-        }
-
-        // Classify the users by directory. Note that the resulting map may 
have an entry with a null key, that
-        // corresponds to the users whose directory has been removed from the 
configuration.
-        Map<String, List<DbUser>> authzToPrincipalMap = new HashMap<>();
-        Map<String, ExtensionProxy> authzMap = new HashMap<>();
-
-        for (DbUser dbUser : dbUsers) {
-            ExtensionProxy authz = 
EngineExtensionsManager.getInstance().getExtensionByName(dbUser.getDomain());
-            if (authz == null) {
-                log.warn(String.format("No authz extension was found for user 
%1$s. It is possible that the relevant " +
-                        "domain for the user was removed for the user. Marking 
the user as inactive",
-                        dbUser.getLoginName()));
-                if (dbUser.isActive()) {
-                    dbUser.setActive(false);
-                    dao.update(dbUser);
-                }
-                continue;
-
-            }
-            String auhtzName = AuthzUtils.getName(authz);
-            MultiValueMapUtils.addToMap(auhtzName, dbUser, 
authzToPrincipalMap);
-            authzMap.put(auhtzName, authz);
-        }
-
-        // Refresh the users for each directory:
-        List<DbUser> updates = new ArrayList<>();
-        for (Map.Entry<String, List<DbUser>> entry : 
authzToPrincipalMap.entrySet()) {
-            List<DbUser> refreshed = refreshUsers(entry.getValue(), 
authzMap.get(entry.getKey()));
-            updates.addAll(refreshed);
-        }
-
-        // Actually update the users in the database (note that this should be 
done with a batch update, but we don't
-        // have support for that yet):
-        for (DbUser dbUser : updates) {
-            dao.update(dbUser);
-        }
+      SyncUsers.sync(DbFacade.getInstance().getDbUserDao().getAll());
     }
 
-    /**
-     * Refresh a list of users retrieving their data from a given directory.
-     *
-     * @param dbUsers the list of users to refresh
-     * @param authz the authz extension where the data of the users will be 
extracted from, it may be {@code null} if the
-     *     directory has already been removed from the configuration
-     * @return the list of database users that have been actually modified and 
that need to be updated in the database
-     */
-    private List<DbUser> refreshUsers(List<DbUser> dbUsers, ExtensionProxy 
authz) {
-        // Find all the users in the directory using a batch operation to 
improve performance:
-        Map<String, List<String>> idsPerNamespace = new HashMap<>();
-
-        List<DbUser> refreshed = new ArrayList<>();
-        List<String> ids = new ArrayList<>(dbUsers.size());
-        for (DbUser dbUser : dbUsers) {
-            MultiValueMapUtils.addToMap(dbUser.getNamespace(), 
dbUser.getExternalId(), idsPerNamespace);
-        }
-        for (String namespace : idsPerNamespace.keySet()) {
-            List<DirectoryUser> directoryUsers = null;
-            if (authz != null) {
-                directoryUsers = DirectoryUtils.findDirectoryUserByIds(authz, 
namespace, ids, true, false);
-            }
-            else {
-                directoryUsers = Collections.emptyList();
-            }
-
-            // Build a map of users indexed by directory id to simplify the 
next step where we want to find the directory
-            // user corresponding to each database user:
-            Map<String, DirectoryUser> index = new HashMap<>();
-            for (DirectoryUser directoryUser : directoryUsers) {
-                index.put(directoryUser.getId(), directoryUser);
-            }
-
-            // For each database user refresh it using the corresponding 
directory user and collect those users that need to
-            // be updated:
-            for (DbUser dbUser : dbUsers) {
-                DirectoryUser directoryUser = 
index.get(dbUser.getExternalId());
-                if (directoryUser != null) {
-                    dbUser.setActive(false);
-                    // TODO: will be fixed in next patch in series
-                    // 
dbUser.setGroupIds(DirectoryUtils.getGroupIdsFromUser(directoryUser));
-                    dbUser = refreshUser(dbUser, directoryUser);
-                    if (dbUser != null) {
-                        refreshed.add(dbUser);
-                    }
-                }
-            }
-
-        }
-
-        return refreshed;
-    }
-
-    /**
-     * Detect differences between a user as stored in the database and the 
same user retrieved from the directory.
-     *
-     * @param dbUser the database user
-     * @param directoryUser the directory user, it may be {@code null} if the 
user doesn't exist in the directory
-     * @return the updated database user if it was actually updated or {@code 
null} if it doesn't need to be updated
-     */
-    private DbUser refreshUser(DbUser dbUser, DirectoryUser directoryUser) {
-        // If there the user doesn't exist in the directory then we only need 
to mark the database user as not active
-        // if it isn't marked already:
-        if (directoryUser == null) {
-            if (dbUser.isActive()) {
-                log.warnFormat(
-                    "User \"{0}\" will be marked as not active as it wasn't 
found in the directory \"{1}\".",
-                    dbUser.getLoginName(), dbUser.getDomain()
-                );
-            }
-            return dbUser;
-        }
-
-        // This flag indicates if there are any differences and thus if the 
database update should actually be
-        // performed:
-        boolean update = false;
-
-        // If the user was marked as not active in the database then mark it 
as active:
-        if (!dbUser.isActive()) {
-            log.infoFormat(
-                "User \"{0}\" will be marked as active as it was found in 
directory \"{1}\".",
-                dbUser.getLoginName(), dbUser.getDomain()
-            );
-            dbUser.setActive(true);
-            update = true;
-        }
-
-        // Compare the attributes of the database user with those of the 
directory, copy those that changed and update
-        // the flag that indicates that the database needs to be updated:
-        if (!StringUtils.equals(dbUser.getFirstName(), 
directoryUser.getFirstName())) {
-            dbUser.setFirstName(directoryUser.getFirstName());
-            update = true;
-        }
-        if (!StringUtils.equals(dbUser.getLastName(), 
directoryUser.getLastName())) {
-            dbUser.setLastName(directoryUser.getLastName());
-            update = true;
-        }
-        if (!StringUtils.equals(dbUser.getDomain(), 
directoryUser.getDirectoryName())) {
-            dbUser.setDomain(directoryUser.getDirectoryName());
-            update = true;
-        }
-        if (!StringUtils.equals(dbUser.getLoginName(), 
directoryUser.getName())) {
-            dbUser.setLoginName(directoryUser.getName());
-            update = true;
-        }
-        if (!StringUtils.equals(dbUser.getDepartment(), 
directoryUser.getDepartment())) {
-            dbUser.setDepartment(directoryUser.getDepartment());
-            update = true;
-        }
-        if (!StringUtils.equals(dbUser.getRole(), directoryUser.getTitle())) {
-            dbUser.setRole(directoryUser.getTitle());
-            update = true;
-        }
-        if (!StringUtils.equals(dbUser.getEmail(), directoryUser.getEmail())) {
-            dbUser.setEmail(directoryUser.getEmail());
-            update = true;
-        }
-
-        // Compare the new list of group names and identifiers:
-        List<String> groupNamesFromDirectory = new ArrayList<>();
-        DbGroupDAO groupDao = DbFacade.getInstance().getDbGroupDao();
-        HashSet<Guid> groupIds = new HashSet<>();
-        for (DirectoryGroup directoryGroup : directoryUser.getGroups()) {
-            DbGroup dbGroup = groupsMap.get(directoryGroup.getId());
-            if (dbGroup == null) {
-                dbGroup = groupDao.getByExternalId(dbUser.getDomain(), 
directoryGroup.getId());
-            }
-            if (dbGroup != null) {
-                groupIds.add(dbGroup.getId());
-            }
-            groupNamesFromDirectory.add(directoryGroup.getName());
-        }
-        Collections.sort(groupNamesFromDirectory);
-        List<String> groupNamesFromDb = new 
ArrayList<String>(dbUser.getGroupNames());
-        Collections.sort(groupNamesFromDb);
-        if (!groupNamesFromDb.equals(groupNamesFromDirectory)) {
-            dbUser.setGroupNames(new HashSet<String>(groupNamesFromDirectory));
-            update = true;
-        }
-
-        if (!groupIds.equals(dbUser.getGroupIds())) {
-            dbUser.setGroupIds(groupIds);
-            update = true;
-        }
-        return update? dbUser: null;
-    }
 }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/DirectoryEntryKey.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/DirectoryEntryKey.java
new file mode 100644
index 0000000..c3964a9
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/DirectoryEntryKey.java
@@ -0,0 +1,60 @@
+package org.ovirt.engine.core.bll;
+
+import org.ovirt.engine.core.common.businessentities.DbUser;
+
+
+public class DirectoryEntryKey {
+
+    private String authz;
+    private String externalId;
+
+    public DirectoryEntryKey(String authz, String externalId) {
+        this.authz = authz;
+        this.externalId = externalId;
+    }
+
+    public DirectoryEntryKey(DbUser dbUser) {
+        this(dbUser.getDomain(), dbUser.getExternalId());
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((authz == null) ? 0 : authz.hashCode());
+        result = prime * result + ((externalId == null) ? 0 : 
externalId.hashCode());
+        return result;
+    }
+
+    public String getAuthz() {
+        return authz;
+    }
+
+    public String getExternalId() {
+        return externalId;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        DirectoryEntryKey other = (DirectoryEntryKey) obj;
+        if (authz == null) {
+            if (other.authz != null)
+                return false;
+        } else if (!authz.equals(other.authz))
+            return false;
+        if (externalId == null) {
+            if (other.externalId != null)
+                return false;
+        } else if (!externalId.equals(other.externalId))
+            return false;
+        return true;
+    }
+
+}
+
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/SyncUsers.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/SyncUsers.java
new file mode 100644
index 0000000..cb80065
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/SyncUsers.java
@@ -0,0 +1,84 @@
+package org.ovirt.engine.core.bll;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.ovirt.engine.api.extensions.ExtMap;
+import org.ovirt.engine.core.aaa.AuthzUtils;
+import org.ovirt.engine.core.aaa.DirectoryUtils;
+import org.ovirt.engine.core.common.businessentities.DbUser;
+import org.ovirt.engine.core.dal.dbbroker.DbFacade;
+import org.ovirt.engine.core.extensions.mgr.ExtensionProxy;
+import org.ovirt.engine.core.utils.collections.MultiValueMapUtils;
+import org.ovirt.engine.core.utils.extensionsmgr.EngineExtensionsManager;
+import org.ovirt.engine.core.utils.log.Log;
+import org.ovirt.engine.core.utils.log.LogFactory;
+
+public class SyncUsers {
+
+    private static final Log log = LogFactory.getLog(SyncUsers.class);
+
+    public static void sync(List<DbUser> dbUsers) {
+        Map<String, Map<String, Set<String>>> authzToNamespaceToUserIds = new 
HashMap<>();
+        Map<DirectoryEntryKey, DbUser> originalDbUsersMap = new HashMap<>();
+        Map<String, List<DbUser>> dbUsersPerAuthz = new HashMap<>();
+
+        //Initialize the entries based on authz in the map
+        for (DbUser dbUser : dbUsers) {
+            MultiValueMapUtils.addToMap(dbUser.getDomain(), dbUser, 
dbUsersPerAuthz);
+            if (!authzToNamespaceToUserIds.containsKey(dbUser.getDomain())) {
+                authzToNamespaceToUserIds.put(dbUser.getDomain(), new 
HashMap<String, Set<String>>());
+            }
+            MultiValueMapUtils.addToMapOfSets(dbUser.getNamespace(), 
dbUser.getExternalId(), authzToNamespaceToUserIds.get(dbUser.getDomain()));
+            originalDbUsersMap.put(new DirectoryEntryKey(dbUser), dbUser);
+        }
+
+        for (Entry<String, Map<String, Set<String>>> entry : 
authzToNamespaceToUserIds.entrySet()) {
+            Map<String, DbUser> activeUsers = new HashMap<>();
+            String authz = entry.getKey();
+            try {
+                ExtensionProxy authzExtension = 
EngineExtensionsManager.getInstance().getExtensionByName(authz);
+                for (Entry<String, Set<String>> userIdsPerNamespace : 
entry.getValue().entrySet()) {
+                    for (
+                        ExtMap principal :
+                        AuthzUtils.fetchPrincipalsByIdsRecursively(
+                                authzExtension, userIdsPerNamespace.getKey(),
+                                new 
ArrayList<String>(userIdsPerNamespace.getValue()))
+                        ) {
+                            DirectoryUtils.flatGroups(principal);
+                            DbUser dbUser = 
DirectoryUtils.mapPrincipalRecordToDbUser(authz, principal);
+                            
dbUser.setGroupIds(DirectoryUtils.getGroupIdsFromPrincipal(authz, principal));
+                            activeUsers.put(dbUser.getExternalId(), dbUser);
+                    }
+                }
+
+                for (DbUser dbUser : dbUsersPerAuthz.get(authz)) {
+                    DbUser activeUser = 
activeUsers.get(dbUser.getExternalId());
+                    if (activeUser != null) {
+                        if (!activeUser.equals(dbUser)) {
+                            activeUser.setId(dbUser.getId());
+                            log.info(String.format("The user %1$s from authz 
extension %2$s got updated since last interval",
+                                    activeUser.getLoginName(),
+                                    activeUser.getDomain()));
+                            
DbFacade.getInstance().getDbUserDao().update(activeUser);
+                        }
+                    } else {
+                        log.info(String.format("The user %1$s from authz 
extension %2$s could not be found, and will be marked as inactive",
+                                dbUser.getLoginName(),
+                                dbUser.getDomain()));
+                        dbUser.setActive(false);
+                        DbFacade.getInstance().getDbUserDao().update(dbUser);
+                    }
+                }
+            } catch (Exception ex) {
+                log.error(String.format("Error during user synchronization of 
extension %1$s. Exception message is %2$s",
+                        authz, ex.getMessage()));
+                log.debug("", ex);
+            }
+        }
+    }
+}


-- 
To view, visit http://gerrit.ovirt.org/29915
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I3a66a7c235f16ff26cac3a779de688c73d67f4a2
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: ovirt-engine-3.5
Gerrit-Owner: Yair Zaslavsky <yzasl...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to