From 4d0f91155d862de6550c7141d22c2b7d645ea755 Mon Sep 17 00:00:00 2001 From: Serhii_Nosko Date: Fri, 27 Dec 2024 10:18:29 +0200 Subject: [PATCH 1/2] MODCONSKC-58. Skip creating shadow system users for Eureka --- .../folio/consortia/domain/dto/UserType.java | 12 ++++++++++- .../SyncPrimaryAffiliationServiceImpl.java | 2 +- .../service/impl/UserServiceImpl.java | 9 +++++++++ .../consortia/service/UserServiceTest.java | 20 +++++++++++++++++++ ...SyncPrimaryAffiliationServiceImplTest.java | 13 +++++++----- 5 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/folio/consortia/domain/dto/UserType.java b/src/main/java/org/folio/consortia/domain/dto/UserType.java index db9b5701..75104b8a 100644 --- a/src/main/java/org/folio/consortia/domain/dto/UserType.java +++ b/src/main/java/org/folio/consortia/domain/dto/UserType.java @@ -7,11 +7,21 @@ public enum UserType { PATRON("patron"), STAFF("staff"), SHADOW("shadow"), - SYSTEM("system"); + SYSTEM("system"), + DCB("dcb"); UserType(String name) { this.name = name; } private final String name; + + public static UserType fromName(String name) { + for (UserType userType : values()) { + if (userType.name.equals(name)) { + return userType; + } + } + return null; + } } diff --git a/src/main/java/org/folio/consortia/service/impl/SyncPrimaryAffiliationServiceImpl.java b/src/main/java/org/folio/consortia/service/impl/SyncPrimaryAffiliationServiceImpl.java index cb0a3d36..30276227 100644 --- a/src/main/java/org/folio/consortia/service/impl/SyncPrimaryAffiliationServiceImpl.java +++ b/src/main/java/org/folio/consortia/service/impl/SyncPrimaryAffiliationServiceImpl.java @@ -44,7 +44,7 @@ public void syncPrimaryAffiliations(UUID consortiumId, String tenantId, String c log.info("Start syncing user primary affiliations for tenant {}", tenantId); List users = new ArrayList<>(); try { - users = userService.getUsersByQuery("(cql.allRecords=1 NOT type=\"patron\" NOT type=\"dcb\" NOT type=\"shadow\")", 0, Integer.MAX_VALUE); + users = userService.getUsersByQuery("(cql.allRecords=1 NOT type=\"patron\" NOT type=\"dcb\" NOT type=\"shadow\" NOT type=\"system\")", 0, Integer.MAX_VALUE); } catch (Exception e) { log.error("syncPrimaryAffiliations:: failed to retrieve '{}' users", tenantId, e); tenantService.updateTenantSetupStatus(tenantId, centralTenantId, SetupStatusEnum.FAILED); diff --git a/src/main/java/org/folio/consortia/service/impl/UserServiceImpl.java b/src/main/java/org/folio/consortia/service/impl/UserServiceImpl.java index 87ba286d..4dee3c0f 100644 --- a/src/main/java/org/folio/consortia/service/impl/UserServiceImpl.java +++ b/src/main/java/org/folio/consortia/service/impl/UserServiceImpl.java @@ -3,11 +3,14 @@ import static org.folio.consortia.utils.TenantContextUtils.prepareContextForTenant; import feign.FeignException; + +import java.util.EnumSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.UUID; + import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; import org.folio.consortia.client.UsersClient; @@ -29,6 +32,7 @@ @RequiredArgsConstructor public class UserServiceImpl implements UserService { private static final String USER_ID = "userId"; + public static final EnumSet NOT_APPLICABLE_USER_TYPES = EnumSet.of(UserType.PATRON, UserType.DCB, UserType.SHADOW, UserType.SYSTEM); private final UsersKeycloakClient usersKeycloakClient; private final UsersClient usersClient; @@ -92,6 +96,11 @@ public User prepareShadowUser(UUID userId, String tenantId) { log.warn("Could not find real user with id: {} in his home tenant: {}", userId.toString(), tenantId); throw new ResourceNotFoundException(USER_ID, userId.toString()); } + UserType userType = Optional.ofNullable(realUser.getType()).map(UserType::fromName).orElse(null); + if (NOT_APPLICABLE_USER_TYPES.contains(userType)) { + log.warn("User with id: {} has type: {} which is not applicable for shadow user creation", userId.toString(), realUser.getType()); + throw new IllegalStateException("User type is not applicable for shadow user creation"); + } var shadowUser = new User(); shadowUser.setId(userId.toString()); diff --git a/src/test/java/org/folio/consortia/service/UserServiceTest.java b/src/test/java/org/folio/consortia/service/UserServiceTest.java index 704f22cc..0a2a1e16 100644 --- a/src/test/java/org/folio/consortia/service/UserServiceTest.java +++ b/src/test/java/org/folio/consortia/service/UserServiceTest.java @@ -21,6 +21,8 @@ import org.folio.spring.FolioModuleMetadata; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; @@ -89,6 +91,24 @@ void shouldPrepareShadowUser() { assertNull(shadow.getBarcode()); } + @ParameterizedTest + @EnumSource(value = UserType.class, names = {"PATRON", "DCB", "SHADOW", "SYSTEM"}) + void shouldThrowIllegalStateExceptionForNotApplicableUserType(UserType userType) { + String tenantId = "diku"; + when(folioExecutionContext.getTenantId()).thenReturn(tenantId); + Map> okapiHeaders = createOkapiHeaders(); + when(folioExecutionContext.getOkapiHeaders()).thenReturn(okapiHeaders); + + UUID userId = UUID.randomUUID(); + User realUser = createUserEntity(true); + realUser.setType(userType.getName()); + + when(usersKeycloakClient.getUsersByUserId(userId.toString())).thenReturn(realUser); + + IllegalStateException exception = assertThrows(IllegalStateException.class, () -> userService.prepareShadowUser(userId, tenantId)); + assertEquals("User type is not applicable for shadow user creation", exception.getMessage()); + } + private void mockOkapiHeaders() { when(folioExecutionContext.getTenantId()).thenReturn("diku"); Map> okapiHeaders = createOkapiHeaders(); diff --git a/src/test/java/org/folio/consortia/service/impl/SyncPrimaryAffiliationServiceImplTest.java b/src/test/java/org/folio/consortia/service/impl/SyncPrimaryAffiliationServiceImplTest.java index 5a7bf0a5..9762b8dd 100644 --- a/src/test/java/org/folio/consortia/service/impl/SyncPrimaryAffiliationServiceImplTest.java +++ b/src/test/java/org/folio/consortia/service/impl/SyncPrimaryAffiliationServiceImplTest.java @@ -6,6 +6,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; @@ -51,6 +52,8 @@ @EnableAutoConfiguration(exclude = BatchAutoConfiguration.class) @EntityScan(basePackageClasses = UserTenantEntity.class) class SyncPrimaryAffiliationServiceImplTest { + private static final String CQL_GET_USERS = "(cql.allRecords=1 NOT type=\"patron\" NOT type=\"dcb\" NOT type=\"shadow\" NOT type=\"system\")"; + @InjectMocks SyncPrimaryAffiliationServiceImpl syncPrimaryAffiliationService; @Mock @@ -96,7 +99,7 @@ void createPrimaryUserAffiliationsWhenCentralTenantSaving() throws JsonProcessin when(tenantService.getByTenantId(anyString())).thenReturn(tenantEntity1); when(userTenantRepository.findAnyByUserId(any(), any())).thenReturn(new PageImpl<>(Collections.emptyList())); when(tenantRepository.findById(anyString())).thenReturn(Optional.of(tenantEntity1)); - when(userService.getUsersByQuery(anyString(), anyInt(), anyInt())).thenReturn(userCollection); + when(userService.getUsersByQuery(eq(CQL_GET_USERS), anyInt(), anyInt())).thenReturn(userCollection); when(consortiaConfigurationService.getCentralTenantId(anyString())).thenReturn(tenantId); syncPrimaryAffiliationService.createPrimaryUserAffiliations(consortiumId, centralTenantId, spab); @@ -127,7 +130,7 @@ void createPrimaryUserAffiliationsWhenLocalTenantSaving() throws JsonProcessingE when(tenantService.getByTenantId(anyString())).thenReturn(tenantEntity1); when(userTenantRepository.findAnyByUserId(any(), any())).thenReturn(new PageImpl<>(Collections.emptyList())); when(tenantRepository.findById(anyString())).thenReturn(Optional.of(tenantEntity1)); - when(userService.getUsersByQuery(anyString(), anyInt(), anyInt())).thenReturn(userCollection); + when(userService.getUsersByQuery(eq(CQL_GET_USERS), anyInt(), anyInt())).thenReturn(userCollection); when(consortiaConfigurationService.getCentralTenantId(anyString())).thenReturn(centralTenantId); syncPrimaryAffiliationService.createPrimaryUserAffiliations(consortiumId, centralTenantId, spab); @@ -151,7 +154,7 @@ void syncPrimaryUserAffiliationsWhenTenantSaving() throws JsonProcessingExceptio var spab = getSyncBody(tenantId); // stub collection of 2 users - when(userService.getUsersByQuery(anyString(), anyInt(), anyInt())).thenReturn(userCollection); + when(userService.getUsersByQuery(eq(CQL_GET_USERS), anyInt(), anyInt())).thenReturn(userCollection); syncPrimaryAffiliationService.syncPrimaryAffiliations(consortiumId, tenantId, centralTenantId); @@ -171,7 +174,7 @@ void syncPrimaryAffiliationsException() throws JsonProcessingException { var spab = getSyncBody(tenantId); // stub collection of 2 users - when(userService.getUsersByQuery(anyString(), anyInt(), anyInt())).thenReturn(userCollection); + when(userService.getUsersByQuery(eq(CQL_GET_USERS), anyInt(), anyInt())).thenReturn(userCollection); when(syncClient.savePrimaryAffiliations(spab, String.valueOf(consortiumId), tenantId, centralTenantId)) .thenThrow(FeignException.FeignClientException.class); @@ -189,7 +192,7 @@ void syncPrimaryAffiliationsGetUsersException() { var tenantId = "ABC1"; var centralTenantId = "diku"; - when(userService.getUsersByQuery(anyString(), anyInt(), anyInt())) + when(userService.getUsersByQuery(eq(CQL_GET_USERS), anyInt(), anyInt())) .thenThrow(FeignException.FeignClientException.class); syncPrimaryAffiliationService.syncPrimaryAffiliations(consortiumId, tenantId, centralTenantId); From f321d833c16af89259d958f02d8dc736f0d1423a Mon Sep 17 00:00:00 2001 From: Serhii_Nosko Date: Fri, 27 Dec 2024 11:52:58 +0200 Subject: [PATCH 2/2] MODCONSKC-58. Fix sonar --- .../java/org/folio/consortia/service/impl/UserServiceImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/folio/consortia/service/impl/UserServiceImpl.java b/src/main/java/org/folio/consortia/service/impl/UserServiceImpl.java index 4dee3c0f..da3a6565 100644 --- a/src/main/java/org/folio/consortia/service/impl/UserServiceImpl.java +++ b/src/main/java/org/folio/consortia/service/impl/UserServiceImpl.java @@ -9,6 +9,7 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.Set; import java.util.UUID; import lombok.RequiredArgsConstructor; @@ -32,7 +33,7 @@ @RequiredArgsConstructor public class UserServiceImpl implements UserService { private static final String USER_ID = "userId"; - public static final EnumSet NOT_APPLICABLE_USER_TYPES = EnumSet.of(UserType.PATRON, UserType.DCB, UserType.SHADOW, UserType.SYSTEM); + private static final Set NOT_APPLICABLE_USER_TYPES = EnumSet.of(UserType.PATRON, UserType.DCB, UserType.SHADOW, UserType.SYSTEM); private final UsersKeycloakClient usersKeycloakClient; private final UsersClient usersClient;