Alon Bar-Lev has posted comments on this change.

Change subject: aaa: Fix sync
......................................................................


Patch Set 13:

(13 comments)

thank you for such quick round!

please see the notes, I think that we should completely detach from the db 
entities in aaa, and move to a very simple signature for the fetch principals 
function... as the Authz entities are sufficient for all you need.

Maybe I am wrong, be happy to understand why.

http://gerrit.ovirt.org/#/c/28561/13/backend/manager/modules/aaa/src/main/java/org/ovirt/engine/core/aaa/sync/SyncAAAEntries.java
File 
backend/manager/modules/aaa/src/main/java/org/ovirt/engine/core/aaa/sync/SyncAAAEntries.java:

Line 19: import 
org.ovirt.engine.core.utils.extensionsmgr.EngineExtensionsManager;
Line 20: import org.ovirt.engine.core.utils.log.Log;
Line 21: import org.ovirt.engine.core.utils.log.LogFactory;
Line 22: 
Line 23: public class SyncAAAEntries {
I know I am peaky... but this is no sync, but fetch... :))

the fact that we use this fetch to sync (fetch from database, fetch from authz, 
update database) is for bll to mind.
Line 24: 
Line 25:     private static final Log log = 
LogFactory.getLog(SyncAAAEntries.class);
Line 26: 
Line 27:     // Load all the users from the database and refresh them. The 
refresh logic is as follows :


Line 30:     // 3. Fetch groups from DB
Line 31:     // 4. Resolve the fetched groups (for each group that was not 
already resolved)
Line 32:     // 5. Resolve recursively all groups
Line 33:     // 6. Compare the user from db and the fetched user from the 
directory + store in DB if there is a change
Line 34:     public void sync(
fetchUsers?
Line 35:             Map<String, Map<String, Set<String>>> userIdsToFetch,
Line 36:             Set<String> activeGroupIds,
Line 37:             Map<String, DirectoryGroup> outDirectoryGroupsByIds,
Line 38:             Map<String, DirectoryUser> outDirectoryUserByIds,


Line 31:     // 4. Resolve the fetched groups (for each group that was not 
already resolved)
Line 32:     // 5. Resolve recursively all groups
Line 33:     // 6. Compare the user from db and the fetched user from the 
directory + store in DB if there is a change
Line 34:     public void sync(
Line 35:             Map<String, Map<String, Set<String>>> userIdsToFetch,
userIdsToFetchPerAuthz? to make it clear what is the 2nd dimension.
Line 36:             Set<String> activeGroupIds,
Line 37:             Map<String, DirectoryGroup> outDirectoryGroupsByIds,
Line 38:             Map<String, DirectoryUser> outDirectoryUserByIds,
Line 39:             List<String> outNonActiveUserIds,


Line 32:     // 5. Resolve recursively all groups
Line 33:     // 6. Compare the user from db and the fetched user from the 
directory + store in DB if there is a change
Line 34:     public void sync(
Line 35:             Map<String, Map<String, Set<String>>> userIdsToFetch,
Line 36:             Set<String> activeGroupIds,
this is not required as it can be concluded from the output, no?
Line 37:             Map<String, DirectoryGroup> outDirectoryGroupsByIds,
Line 38:             Map<String, DirectoryUser> outDirectoryUserByIds,
Line 39:             List<String> outNonActiveUserIds,
Line 40:             List<String> outNonActiveGroupIds) {


Line 34:     public void sync(
Line 35:             Map<String, Map<String, Set<String>>> userIdsToFetch,
Line 36:             Set<String> activeGroupIds,
Line 37:             Map<String, DirectoryGroup> outDirectoryGroupsByIds,
Line 38:             Map<String, DirectoryUser> outDirectoryUserByIds,
I would like to avoid database entities as much as possible during this logic.
Line 39:             List<String> outNonActiveUserIds,
Line 40:             List<String> outNonActiveGroupIds) {
Line 41:         Map<String, DirectoryGroup> fetchedGroupsCache = new 
HashMap<>();
Line 42:         Set<String> authzEntries = userIdsToFetch.keySet();


Line 36:             Set<String> activeGroupIds,
Line 37:             Map<String, DirectoryGroup> outDirectoryGroupsByIds,
Line 38:             Map<String, DirectoryUser> outDirectoryUserByIds,
Line 39:             List<String> outNonActiveUserIds,
Line 40:             List<String> outNonActiveGroupIds) {
these should be concluded by the caller based on all above data.

 non active users = user ids to fetch - outDirectoryUserByIds.keySet()

for the non active group ids - I thought there is no need... as we always go 
via users, never fetch group, so we do not care if group exists in directory or 
not.
Line 41:         Map<String, DirectoryGroup> fetchedGroupsCache = new 
HashMap<>();
Line 42:         Set<String> authzEntries = userIdsToFetch.keySet();
Line 43:         for (String authz : authzEntries) {
Line 44:             ExtensionProxy authzExtension = null;


Line 38:             Map<String, DirectoryUser> outDirectoryUserByIds,
Line 39:             List<String> outNonActiveUserIds,
Line 40:             List<String> outNonActiveGroupIds) {
Line 41:         Map<String, DirectoryGroup> fetchedGroupsCache = new 
HashMap<>();
Line 42:         Set<String> authzEntries = userIdsToFetch.keySet();
temp variable not needed
Line 43:         for (String authz : authzEntries) {
Line 44:             ExtensionProxy authzExtension = null;
Line 45:             try {
Line 46:                 authzExtension = 
EngineExtensionsManager.getInstance().getExtensionByName(authz);


Line 46:                 authzExtension = 
EngineExtensionsManager.getInstance().getExtensionByName(authz);
Line 47:             } catch (ConfigurationException ex) {
Line 48:                 log.warn(String.format("The extension %1$s could not 
be found. Users associated with this authz extension will not be refreshed.",
Line 49:                         authz));
Line 50:                 continue;
please do not use continue within catch..

 for () {
     try {
     } catch() {
         continue;
     }
     logic
 }

==

 for () {
     try {
         logic
     } catch() {
     }
 }

which is exceptional pattern valid without spagetti goto.

or if you really like to not nest within try, nest within if:

 for () {
     boolean f = false;
     try {
         xxx;
         f = true;
     } catch() {
     }
     if (f) {
         logic
     }
 }
Line 51:             }
Line 52: 
Line 53:             boolean supportRecursiveGroupResolution =
Line 54:                     (authzExtension.getContext().<Long> 
get(Authz.ContextKeys.CAPABILITIES, 0L) & 
Authz.Capabilities.RECURSIVE_GROUP_RESOLUTION) != 0L;


Line 53:             boolean supportRecursiveGroupResolution =
Line 54:                     (authzExtension.getContext().<Long> 
get(Authz.ContextKeys.CAPABILITIES, 0L) & 
Authz.Capabilities.RECURSIVE_GROUP_RESOLUTION) != 0L;
Line 55: 
Line 56:             Map<String, Set<String>> groupIdsToFetch = 
Collections.emptyMap();
Line 57:             Set<DirectoryGroup> groupsToFetch = new HashSet<>();
I stopped here... I truly want to see you are using PrincipalRecord and 
GroupRecord instead of using these db entities.
Line 58:             Map<String, Set<String>> usersToFetchPerNamespace = 
userIdsToFetch.get(authz);
Line 59:             for (String namespace : usersToFetchPerNamespace.keySet()) 
{
Line 60:                 List<DirectoryUser> fetchedUsers = 
AuthzUtils.findPrincipalsByIds(
Line 61:                         authzExtension,


Line 103:                 }
Line 104:                 groupIdsToFetch = getIdsFromGroups(groupsToFetch, 
fetchedGroupsCache);
Line 105:             }
Line 106:         }
Line 107:         outDirectoryGroupsByIds.putAll(fetchedGroupsCache);
I am unsure why you need both.
Line 108:     }
Line 109: 
Line 110: 
Line 111:     private void addGroupsToFetch(Set<String> activeGroupIds,


http://gerrit.ovirt.org/#/c/28561/13/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/aaa/DirectoryUtils.java
File 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/aaa/DirectoryUtils.java:

Line 59:             dbGroupsPerExternalId.put(dbGroup.getExternalId(), 
dbGroup);
Line 60:             if (dbGroup.isActive()) {
Line 61:                 activeGroupExternalIds.add(dbGroup.getExternalId());
Line 62:             }
Line 63:         }
ok, so now I am confused... why do we need to populate groups? can we read the 
result? as this is void input to our algorithm.
Line 64: 
Line 65:         Map<String, DirectoryGroup> outDirectoryGroupsByIds = new 
HashMap<>();
Line 66:         Map<String, DirectoryUser> outDirectoryUserByIds = new 
HashMap<>();
Line 67:         List<String> outNonActiveUserExternalIds = new ArrayList<>();


Line 80: 
Line 81:         for (String id : outNonActiveGroupExternalIds) {
Line 82:             dbGroupsPerExternalId.get(id).setActive(false);
Line 83:             
DbFacade.getInstance().getDbGroupDao().update(dbGroupsPerExternalId.get(id));
Line 84:         }
both of the above should be concluded by the output of the outDirectory***
Line 85: 
Line 86:         for (DbUser dbUser : dbUsers) {
Line 87:             if (dbUser.isActive()) {
Line 88:                 DirectoryUser user = 
outDirectoryUserByIds.get(dbUser.getExternalId());


Line 86:         for (DbUser dbUser : dbUsers) {
Line 87:             if (dbUser.isActive()) {
Line 88:                 DirectoryUser user = 
outDirectoryUserByIds.get(dbUser.getExternalId());
Line 89:                 Set<DirectoryGroup> accumulator = new HashSet<>();
Line 90:                 DirectoryUtils.flatGroups(accumulator, 
user.getGroups(), outDirectoryGroupsByIds);
I almost sure you have double flat here and within the aaa sync... I would like 
to believe that we do not need to flat there.

If you use PrincipalRecord and GroupRecord, you can return a full scale list of 
PrincipalRecords as:

 // input is Map<Authz, Set<ids>>
 // output is Set<PrincipalRecord>
 Set<ExtMap> fetchPrincipals(Map<String, Set<String>> principalIds) {
 }

This should be sufficient signature, why?

Each PrincipalRecord has List<GroupRecord>, each GroupRecord has 
List<GroupRecord>, so there should be no problem for you to build standard 
structure of documented entities.

Then from this List<PrincipalRecord> you can derive all:

 1. inactive users = db_users - Set<PrincipalRecord>
 2. groups for user = flat(PrincipalRecord.Groups)
Line 91:                 user.setGroups(new 
ArrayList<DirectoryGroup>(accumulator));
Line 92:                 DbUser userFromDirectory = new DbUser(user);
Line 93:                 
userFromDirectory.setGroupIds(DirectoryUtils.getGroupIdsFromUser(user, 
outDirectoryGroupsByIds));
Line 94:                 if (!userFromDirectory.equals(dbUser)) {


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

Gerrit-MessageType: comment
Gerrit-Change-Id: Id49b51517a967c7a83e8e73f52181673baa31700
Gerrit-PatchSet: 13
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Yair Zaslavsky <yzasl...@redhat.com>
Gerrit-Reviewer: Alon Bar-Lev <alo...@redhat.com>
Gerrit-Reviewer: Yair Zaslavsky <yzasl...@redhat.com>
Gerrit-Reviewer: automat...@ovirt.org
Gerrit-Reviewer: oVirt Jenkins CI Server
Gerrit-HasComments: Yes
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to