From 97d2ecd7d18188a75da8ea019665818ba067c2ae Mon Sep 17 00:00:00 2001 From: flyue <17125663@cumt.edu.cn> Date: Sun, 10 Dec 2023 22:05:54 +0800 Subject: [PATCH] [SYNCOPE-1716] fixed membership hashmap multi-threaded problem with concurrent pull (#571) --- .../pushpull/LDAPMembershipPullActions.java | 23 ++++++++----------- .../LDAPMembershipPullActionsTest.java | 6 ++--- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java index 4db705e3f42..509ab4c9f6f 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java @@ -19,12 +19,13 @@ package org.apache.syncope.core.provisioning.java.pushpull; import java.util.ArrayList; -import java.util.HashMap; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import org.apache.syncope.common.lib.request.AnyUR; import org.apache.syncope.common.lib.request.MembershipUR; import org.apache.syncope.common.lib.request.UserUR; @@ -78,9 +79,9 @@ public class LDAPMembershipPullActions implements PullActions { @Autowired protected UserProvisioningManager userProvisioningManager; - protected final Map> membershipsBefore = new HashMap<>(); + protected final Map> membershipsBefore = new ConcurrentHashMap<>(); - protected final Map> membershipsAfter = new HashMap<>(); + protected final Map> membershipsAfter = new ConcurrentHashMap<>(); /** * Allows easy subclassing for the ConnId AD connector bundle. @@ -153,11 +154,9 @@ public void beforeUpdate( } groupDAO.findUMemberships(groupDAO.find(entity.getKey())).forEach(uMembership -> { - Set memb = membershipsBefore.get(uMembership.getLeftEnd().getKey()); - if (memb == null) { - memb = new HashSet<>(); - membershipsBefore.put(uMembership.getLeftEnd().getKey(), memb); - } + Set memb = membershipsBefore.computeIfAbsent( + uMembership.getLeftEnd().getKey(), + k -> Collections.synchronizedSet(new HashSet<>())); memb.add(entity.getKey()); }); } @@ -192,11 +191,9 @@ public void after( profile.getTask().getResource(), profile.getConnector()); if (match.isPresent()) { - Set memb = membershipsAfter.get(match.get().getAny().getKey()); - if (memb == null) { - memb = new HashSet<>(); - membershipsAfter.put(match.get().getAny().getKey(), memb); - } + Set memb = membershipsAfter.computeIfAbsent( + match.get().getAny().getKey(), + k -> Collections.synchronizedSet(new HashSet<>())); memb.add(entity.getKey()); } else { LOG.warn("Could not find matching user for {}", membValue); diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActionsTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActionsTest.java index 26339123e92..f89210118a9 100644 --- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActionsTest.java +++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActionsTest.java @@ -25,7 +25,6 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.HashMap; @@ -98,7 +97,6 @@ public class LDAPMembershipPullActionsTest extends AbstractTest { @Mock private ProvisioningReport result; - @Mock private Map> membershipsAfter; @Mock @@ -139,6 +137,7 @@ public void initTest() { anyReq = new UserUR(); membershipsBefore = new HashMap<>(); + membershipsAfter = new HashMap<>(); ReflectionTestUtils.setField(ldapMembershipPullActions, "membershipsBefore", membershipsBefore); ReflectionTestUtils.setField(ldapMembershipPullActions, "membershipsAfter", membershipsAfter); @@ -208,8 +207,7 @@ public void after() throws JobExecutionException { ldapMembershipPullActions.after(profile, syncDelta, entity, result); - verify(membershipsAfter).get(anyString()); - verify(membershipsAfter).put(anyString(), any()); + assertEquals(1, membershipsAfter.get(user.getKey()).size()); assertEquals(expected, attribute.getValue()); } }