d8055cffe8552aad69ebe896f100bde855631690
java/com.sap.sailing.server.test/src/com/sap/sailing/server/test/LeagueEventHierarchyOwnershipChangeTest.java
| ... | ... | @@ -2,6 +2,7 @@ package com.sap.sailing.server.test; |
| 2 | 2 | |
| 3 | 3 | import static org.junit.jupiter.api.Assertions.assertNull; |
| 4 | 4 | import static org.junit.jupiter.api.Assertions.assertSame; |
| 5 | +import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; |
|
| 5 | 6 | |
| 6 | 7 | import java.util.Collections; |
| 7 | 8 | import java.util.Locale; |
| ... | ... | @@ -142,6 +143,37 @@ public class LeagueEventHierarchyOwnershipChangeTest { |
| 142 | 143 | final OwnershipAnnotation eventOwnership = securityService.getOwnership(event.getIdentifier()); |
| 143 | 144 | assertSame(eventOwnership.getAnnotation().getTenantOwner(), lg2Ownership.getAnnotation().getTenantOwner()); |
| 144 | 145 | } |
| 146 | + |
|
| 147 | + @Test |
|
| 148 | + public void testCyclicLeagueHierarchyOwnershipChangeStartingAtEventTerminates() { |
|
| 149 | + final Event otherEvent = service.addEvent("Test2", "Test Event 2", TimePoint.now(), TimePoint.now().plus(Duration.ONE_WEEK), "There", |
|
| 150 | + /* isPublic */ true, UUID.randomUUID()); |
|
| 151 | + otherEvent.getVenue().addCourseArea(defaultCourseArea); |
|
| 152 | + try { |
|
| 153 | + final LeaderboardGroup sharedLeaderboardGroup = new LeaderboardGroupImpl("LG-shared", "LGDesc-shared", |
|
| 154 | + "The shared LG", /* displayGroupsInReverseOrder */ false, Collections.emptyList()); |
|
| 155 | + final Leaderboard sharedOverallLeaderboard = new LeaderboardGroupMetaLeaderboard(sharedLeaderboardGroup, new LowPoint(), |
|
| 156 | + new ThresholdBasedResultDiscardingRuleImpl(new int[0])); |
|
| 157 | + sharedLeaderboardGroup.setOverallLeaderboard(sharedOverallLeaderboard); |
|
| 158 | + sharedLeaderboardGroup.addLeaderboard(new FlexibleLeaderboardImpl("SharedFlexibleLeaderboard", |
|
| 159 | + new ThresholdBasedResultDiscardingRuleImpl(new int[0]), new LowPoint(), defaultCourseArea)); |
|
| 160 | + event.addLeaderboardGroup(sharedLeaderboardGroup); |
|
| 161 | + otherEvent.addLeaderboardGroup(sharedLeaderboardGroup); |
|
| 162 | + |
|
| 163 | + assertTimeoutPreemptively(java.time.Duration.ofSeconds(5), () -> SailingHierarchyOwnershipUpdater |
|
| 164 | + .createOwnershipUpdater(/* createNewGroup */ true, /* existingGroupIdOrNull */ null, |
|
| 165 | + THE_NEW_OWNING_GROUP_NAME, /* migrateCompetitors */ true, /* migrateBoats */ true, |
|
| 166 | + /* copyMembersAndRoles */ true, service) |
|
| 167 | + .updateGroupOwnershipForEventHierarchy(event)); |
|
| 168 | + |
|
| 169 | + final OwnershipAnnotation eventOwnership = securityService.getOwnership(event.getIdentifier()); |
|
| 170 | + final OwnershipAnnotation otherEventOwnership = securityService.getOwnership(otherEvent.getIdentifier()); |
|
| 171 | + assertSame(eventOwnership.getAnnotation().getTenantOwner(), |
|
| 172 | + otherEventOwnership.getAnnotation().getTenantOwner()); |
|
| 173 | + } finally { |
|
| 174 | + service.removeEvent(otherEvent.getId()); |
|
| 175 | + } |
|
| 176 | + } |
|
| 145 | 177 | |
| 146 | 178 | @AfterEach |
| 147 | 179 | public void tearDown() { |
java/com.sap.sailing.server/src/com/sap/sailing/server/hierarchy/SailingHierarchyOwnershipUpdater.java
| ... | ... | @@ -65,6 +65,9 @@ public class SailingHierarchyOwnershipUpdater { |
| 65 | 65 | private final boolean updateCompetitors; |
| 66 | 66 | private final boolean updateBoats; |
| 67 | 67 | private final Set<QualifiedObjectIdentifier> objectsToUpdateOwnershipsFor; |
| 68 | + private final Set<QualifiedObjectIdentifier> visitedEvents; |
|
| 69 | + private final Set<QualifiedObjectIdentifier> visitedLeaderboardGroups; |
|
| 70 | + private final Set<QualifiedObjectIdentifier> visitedLeaderboards; |
|
| 68 | 71 | |
| 69 | 72 | private SailingHierarchyOwnershipUpdater(final RacingEventService service, SecurityService securityService, |
| 70 | 73 | final GroupOwnerUpdateStrategy updateStrategy, final boolean updateCompetitors, final boolean updateBoats) { |
| ... | ... | @@ -74,6 +77,9 @@ public class SailingHierarchyOwnershipUpdater { |
| 74 | 77 | this.updateCompetitors = updateCompetitors; |
| 75 | 78 | this.updateBoats = updateBoats; |
| 76 | 79 | objectsToUpdateOwnershipsFor = new HashSet<>(); |
| 80 | + visitedEvents = new HashSet<>(); |
|
| 81 | + visitedLeaderboardGroups = new HashSet<>(); |
|
| 82 | + visitedLeaderboards = new HashSet<>(); |
|
| 77 | 83 | } |
| 78 | 84 | |
| 79 | 85 | public void updateGroupOwnershipForEventHierarchy(Event event) { |
| ... | ... | @@ -82,6 +88,9 @@ public class SailingHierarchyOwnershipUpdater { |
| 82 | 88 | } |
| 83 | 89 | |
| 84 | 90 | private void updateGroupOwnershipForEventHierarchyInternal(Event event) { |
| 91 | + if (!visitedEvents.add(event.getIdentifier())) { |
|
| 92 | + return; |
|
| 93 | + } |
|
| 85 | 94 | updateGroupOwner(event.getIdentifier()); |
| 86 | 95 | SailingHierarchyWalker.walkFromEvent(event, /* includeLeaderboardGroupsWithOverallLeaderboard */ false, |
| 87 | 96 | new EventHierarchyVisitor() { |
| ... | ... | @@ -106,6 +115,9 @@ public class SailingHierarchyOwnershipUpdater { |
| 106 | 115 | } |
| 107 | 116 | |
| 108 | 117 | private void updateGroupOwnershipForLeaderboardGroupHierarchyInternal(LeaderboardGroup leaderboardGroup, Event eventToExclude) { |
| 118 | + if (!visitedLeaderboardGroups.add(leaderboardGroup.getIdentifier())) { |
|
| 119 | + return; |
|
| 120 | + } |
|
| 109 | 121 | updateGroupOwner(leaderboardGroup.getIdentifier()); |
| 110 | 122 | SailingHierarchyWalker.walkFromLeaderboardGroup(service, leaderboardGroup, |
| 111 | 123 | /* includeEventsIfLeaderboardGroupHasOverallLeaderboard */ true, |
| ... | ... | @@ -132,6 +144,9 @@ public class SailingHierarchyOwnershipUpdater { |
| 132 | 144 | } |
| 133 | 145 | |
| 134 | 146 | private void updateGroupOwnershipForLeaderboardHierarchyInternal(Leaderboard leaderboard) { |
| 147 | + if (!visitedLeaderboards.add(leaderboard.getIdentifier())) { |
|
| 148 | + return; |
|
| 149 | + } |
|
| 135 | 150 | updateGroupOwner(leaderboard.getIdentifier()); |
| 136 | 151 | if (leaderboard instanceof RegattaLeaderboard) { |
| 137 | 152 | RegattaLeaderboard regattaLeaderboard = (RegattaLeaderboard) leaderboard; |