diff --git a/pom.xml b/pom.xml
index e217be5f..0e7b3c6c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -68,11 +68,11 @@
1.4.0
- 2.27.2
- 1.19.7
+ 3.0.1
+ 1.19.3
2.2
- 1.19.7
- 3.2.0
+ 1.19.3
+ 3.3.1
diff --git a/src/main/java/org/folio/consortia/client/UserTenantsClient.java b/src/main/java/org/folio/consortia/client/UserTenantsClient.java
index fb9b8a47..badc7665 100644
--- a/src/main/java/org/folio/consortia/client/UserTenantsClient.java
+++ b/src/main/java/org/folio/consortia/client/UserTenantsClient.java
@@ -4,6 +4,7 @@
import org.folio.spring.config.FeignClientConfiguration;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@@ -12,4 +13,7 @@ public interface UserTenantsClient {
@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
void postUserTenant(@RequestBody UserTenant userTenant);
+
+ @DeleteMapping
+ void deleteUserTenants();
}
diff --git a/src/main/java/org/folio/consortia/config/AppConfig.java b/src/main/java/org/folio/consortia/config/AppConfig.java
index 50cfd289..5065df48 100644
--- a/src/main/java/org/folio/consortia/config/AppConfig.java
+++ b/src/main/java/org/folio/consortia/config/AppConfig.java
@@ -48,7 +48,7 @@ public ObjectMapper objectMapper() {
objectMapper.findAndRegisterModules()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
- .setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
+ .setSerializationInclusion(JsonInclude.Include.NON_NULL);
return objectMapper;
}
diff --git a/src/main/java/org/folio/consortia/domain/converter/TenantDetailsEntityToTenantConverter.java b/src/main/java/org/folio/consortia/domain/converter/TenantDetailsEntityToTenantConverter.java
index 1738bff6..4a207caf 100644
--- a/src/main/java/org/folio/consortia/domain/converter/TenantDetailsEntityToTenantConverter.java
+++ b/src/main/java/org/folio/consortia/domain/converter/TenantDetailsEntityToTenantConverter.java
@@ -14,6 +14,7 @@ public Tenant convert(TenantDetailsEntity source) {
tenant.setCode(source.getCode());
tenant.setName(source.getName());
tenant.setIsCentral(source.getIsCentral());
+ tenant.setIsDeleted(source.getIsDeleted());
return tenant;
}
}
diff --git a/src/main/java/org/folio/consortia/domain/converter/TenantDetailsEntityToTenantDetailsConverter.java b/src/main/java/org/folio/consortia/domain/converter/TenantDetailsEntityToTenantDetailsConverter.java
index 243de6ed..3c8c3b10 100644
--- a/src/main/java/org/folio/consortia/domain/converter/TenantDetailsEntityToTenantDetailsConverter.java
+++ b/src/main/java/org/folio/consortia/domain/converter/TenantDetailsEntityToTenantDetailsConverter.java
@@ -14,6 +14,7 @@ public TenantDetails convert(TenantDetailsEntity source) {
.code(source.getCode())
.name(source.getName())
.isCentral(source.getIsCentral())
+ .isDeleted(source.getIsDeleted())
.setupStatus(source.getSetupStatus());
}
}
diff --git a/src/main/java/org/folio/consortia/domain/converter/TenantEntityToTenantConverter.java b/src/main/java/org/folio/consortia/domain/converter/TenantEntityToTenantConverter.java
index a1f6dc1e..8bc238ae 100644
--- a/src/main/java/org/folio/consortia/domain/converter/TenantEntityToTenantConverter.java
+++ b/src/main/java/org/folio/consortia/domain/converter/TenantEntityToTenantConverter.java
@@ -15,6 +15,7 @@ public Tenant convert(TenantEntity source) {
tenant.setCode(source.getCode());
tenant.setName(source.getName());
tenant.setIsCentral(source.getIsCentral());
+ tenant.setIsDeleted(source.getIsDeleted());
return tenant;
}
}
diff --git a/src/main/java/org/folio/consortia/domain/entity/AbstractTenantEntity.java b/src/main/java/org/folio/consortia/domain/entity/AbstractTenantEntity.java
index 0383473d..06502e3c 100644
--- a/src/main/java/org/folio/consortia/domain/entity/AbstractTenantEntity.java
+++ b/src/main/java/org/folio/consortia/domain/entity/AbstractTenantEntity.java
@@ -23,16 +23,19 @@ public abstract class AbstractTenantEntity extends AuditableEntity {
private String name;
private UUID consortiumId;
private Boolean isCentral;
+ private Boolean isDeleted;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof AbstractTenantEntity that)) return false;
- return Objects.equals(id, that.id) && Objects.equals(code, that.code) && Objects.equals(name, that.name) && Objects.equals(consortiumId, that.consortiumId) && Objects.equals(isCentral, that.isCentral);
+ return Objects.equals(id, that.id) && Objects.equals(code, that.code) &&
+ Objects.equals(name, that.name) && Objects.equals(consortiumId, that.consortiumId) &&
+ Objects.equals(isCentral, that.isCentral) && Objects.equals(isDeleted, that.isDeleted);
}
@Override
public int hashCode() {
- return Objects.hash(id, code, name, consortiumId, isCentral);
+ return Objects.hash(id, code, name, consortiumId, isCentral, isDeleted);
}
}
diff --git a/src/main/java/org/folio/consortia/repository/SharingInstanceRepository.java b/src/main/java/org/folio/consortia/repository/SharingInstanceRepository.java
index 42682a09..7a8b7264 100644
--- a/src/main/java/org/folio/consortia/repository/SharingInstanceRepository.java
+++ b/src/main/java/org/folio/consortia/repository/SharingInstanceRepository.java
@@ -2,6 +2,7 @@
import java.util.ArrayList;
import java.util.Objects;
+import java.util.Optional;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
@@ -10,11 +11,15 @@
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
@Repository
public interface SharingInstanceRepository extends JpaRepository, JpaSpecificationExecutor {
+ @Query("SELECT si FROM SharingInstanceEntity si WHERE si.instanceId = ?1 AND si.sourceTenantId= ?2 AND si.targetTenantId= ?3")
+ Optional findByInstanceAndTenantIds(UUID instanceIdentifier, String sourceTenantId, String targetTenantId);
+
interface Specifications {
static Specification constructSpecification(UUID instanceIdentifier, String sourceTenantId,
String targetTenantId, Status status) {
diff --git a/src/main/java/org/folio/consortia/repository/TenantRepository.java b/src/main/java/org/folio/consortia/repository/TenantRepository.java
index 819f5c72..69be4a3e 100644
--- a/src/main/java/org/folio/consortia/repository/TenantRepository.java
+++ b/src/main/java/org/folio/consortia/repository/TenantRepository.java
@@ -14,13 +14,21 @@
@Repository
public interface TenantRepository extends JpaRepository {
+ @Query("SELECT t FROM TenantEntity t WHERE t.consortiumId = ?1 and t.isDeleted = FALSE")
Page findByConsortiumId(UUID consortiumId, Pageable pageable);
+
+ @Query("SELECT t FROM TenantEntity t WHERE t.consortiumId = ?1 and t.isDeleted = FALSE")
List findByConsortiumId(UUID consortiumId);
- @Query("SELECT t FROM TenantEntity t where t.isCentral = true")
+ @Query("SELECT t FROM TenantEntity t WHERE t.isCentral = true")
Optional findCentralTenant();
boolean existsByIsCentralTrue();
- boolean existsByCode(String code);
- boolean existsByName(String name);
+ @Query("SELECT CASE WHEN COUNT(t) > 0 THEN TRUE ELSE FALSE END FROM TenantEntity t " +
+ "WHERE t.code = ?1 AND t.id != ?2")
+ boolean existsByCodeForOtherTenant(String name, String tenantId);
+
+ @Query("SELECT CASE WHEN COUNT(t) > 0 THEN TRUE ELSE FALSE END FROM TenantEntity t " +
+ "WHERE t.name = ?1 AND t.id != ?2")
+ boolean existsByNameForOtherTenant(String name, String tenantId);
}
diff --git a/src/main/java/org/folio/consortia/repository/UserTenantRepository.java b/src/main/java/org/folio/consortia/repository/UserTenantRepository.java
index 29f7bb6d..85918d5d 100644
--- a/src/main/java/org/folio/consortia/repository/UserTenantRepository.java
+++ b/src/main/java/org/folio/consortia/repository/UserTenantRepository.java
@@ -14,16 +14,22 @@
@Repository
public interface UserTenantRepository extends JpaRepository {
+
+ @Query("SELECT ut FROM UserTenantEntity ut WHERE ut.tenant.isDeleted= FALSE")
+ Page getAll(Pageable pageable);
+
+ @Query("SELECT ut FROM UserTenantEntity ut WHERE ut.userId= ?1 AND ut.tenant.isDeleted= FALSE")
Page findByUserId(UUID userId, Pageable pageable);
- @Query("SELECT ut FROM UserTenantEntity ut WHERE ut.username= ?1 AND ut.tenant.id= ?2")
+ @Query("SELECT ut FROM UserTenantEntity ut WHERE ut.userId= ?1")
+ Page findAnyByUserId(UUID userId, Pageable pageable);
+
+ @Query("SELECT ut FROM UserTenantEntity ut WHERE ut.username= ?1 AND ut.tenant.id= ?2 AND ut.tenant.isDeleted= FALSE")
Optional findByUsernameAndTenantId(String username, String tenantId);
@Query("SELECT ut FROM UserTenantEntity ut WHERE ut.userId= ?1 AND ut.tenant.id= ?2")
Optional findByUserIdAndTenantId(UUID userId, String tenantId);
- boolean existsByTenantId(String tenantId);
-
@Query("SELECT ut FROM UserTenantEntity ut WHERE ut.userId= ?1 AND ut.isPrimary= true")
Optional findByUserIdAndIsPrimaryTrue(UUID userId);
diff --git a/src/main/java/org/folio/consortia/service/ConsortiaConfigurationService.java b/src/main/java/org/folio/consortia/service/ConsortiaConfigurationService.java
index 1e42130d..ff8aefae 100644
--- a/src/main/java/org/folio/consortia/service/ConsortiaConfigurationService.java
+++ b/src/main/java/org/folio/consortia/service/ConsortiaConfigurationService.java
@@ -27,4 +27,9 @@ public interface ConsortiaConfigurationService {
*/
ConsortiaConfiguration createConfiguration(String centralTenantId);
+ /**
+ * Check if there is any central tenant
+ * @return boolean value based one whether central tenant configuration exists or not
+ */
+ boolean isCentralTenantConfigurationExists();
}
diff --git a/src/main/java/org/folio/consortia/service/TenantService.java b/src/main/java/org/folio/consortia/service/TenantService.java
index fc106510..4a8c8ca4 100644
--- a/src/main/java/org/folio/consortia/service/TenantService.java
+++ b/src/main/java/org/folio/consortia/service/TenantService.java
@@ -31,6 +31,10 @@ public interface TenantService {
/**
* Inserts single tenant based on consortiumId.
+ * Method checks whether requesting tenant is soft deleted or new tenant.
+ * For re-adding soft deleted tenant,
+ * tenant is_deleted flag will be changed to false and dummy user will be created in mod_users.user-tenants table
+ * For new tenant, all necessary actions will be done.
*
* @param consortiumId the consortiumId
* @param tenantDto the tenantDto
diff --git a/src/main/java/org/folio/consortia/service/impl/ConsortiaConfigurationServiceImpl.java b/src/main/java/org/folio/consortia/service/impl/ConsortiaConfigurationServiceImpl.java
index bad638a7..b78e85f8 100644
--- a/src/main/java/org/folio/consortia/service/impl/ConsortiaConfigurationServiceImpl.java
+++ b/src/main/java/org/folio/consortia/service/impl/ConsortiaConfigurationServiceImpl.java
@@ -1,20 +1,19 @@
package org.folio.consortia.service.impl;
-import org.folio.consortia.exception.ResourceAlreadyExistException;
-import org.folio.consortia.exception.ResourceNotFoundException;
-import org.folio.consortia.repository.ConsortiaConfigurationRepository;
+import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.folio.consortia.domain.dto.ConsortiaConfiguration;
import org.folio.consortia.domain.entity.ConsortiaConfigurationEntity;
+import org.folio.consortia.exception.ResourceAlreadyExistException;
+import org.folio.consortia.exception.ResourceNotFoundException;
+import org.folio.consortia.repository.ConsortiaConfigurationRepository;
import org.folio.consortia.service.ConsortiaConfigurationService;
import org.folio.consortia.utils.TenantContextUtils;
import org.folio.spring.FolioExecutionContext;
import org.springframework.core.convert.ConversionService;
import org.springframework.stereotype.Service;
-import java.util.List;
-
@Log4j2
@Service
@RequiredArgsConstructor
@@ -54,6 +53,10 @@ private ConsortiaConfigurationEntity getConfiguration(String requestTenantId) {
return configList.get(0);
}
+ public boolean isCentralTenantConfigurationExists() {
+ return configurationRepository.count() > 0;
+ }
+
private void checkAnyConsortiaConfigurationNotExistsOrThrow() {
if (configurationRepository.count() > 0) {
throw new ResourceAlreadyExistException(CONSORTIA_CONFIGURATION_EXIST_MSG_TEMPLATE);
diff --git a/src/main/java/org/folio/consortia/service/impl/ConsortiumServiceImpl.java b/src/main/java/org/folio/consortia/service/impl/ConsortiumServiceImpl.java
index e07b7e17..bb1e4ac0 100644
--- a/src/main/java/org/folio/consortia/service/impl/ConsortiumServiceImpl.java
+++ b/src/main/java/org/folio/consortia/service/impl/ConsortiumServiceImpl.java
@@ -1,22 +1,21 @@
package org.folio.consortia.service.impl;
-import org.folio.consortia.exception.ResourceAlreadyExistException;
-import org.folio.consortia.exception.ResourceNotFoundException;
-import org.folio.consortia.repository.ConsortiumRepository;
+import java.util.UUID;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.folio.consortia.domain.dto.Consortium;
import org.folio.consortia.domain.dto.ConsortiumCollection;
import org.folio.consortia.domain.entity.ConsortiumEntity;
+import org.folio.consortia.exception.ResourceAlreadyExistException;
+import org.folio.consortia.exception.ResourceNotFoundException;
+import org.folio.consortia.repository.ConsortiumRepository;
import org.folio.consortia.service.ConsortiumService;
import org.folio.consortia.utils.HelperUtils;
+import org.folio.spring.data.OffsetRequest;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
-import java.util.UUID;
-
@Service
@Log4j2
@RequiredArgsConstructor
@@ -57,7 +56,7 @@ public Consortium update(UUID consortiumId, Consortium consortiumDto) {
public ConsortiumCollection getAll() {
var result = new ConsortiumCollection();
- Page consortiaPage = repository.findAll(PageRequest.of(0, 1));
+ Page consortiaPage = repository.findAll(OffsetRequest.of(0, 1));
result.setConsortia(consortiaPage.stream().map(o -> converter.convert(o, Consortium.class)).toList());
result.setTotalRecords((int) consortiaPage.getTotalElements());
return result;
diff --git a/src/main/java/org/folio/consortia/service/impl/PublicationServiceImpl.java b/src/main/java/org/folio/consortia/service/impl/PublicationServiceImpl.java
index 837cf843..b25aadd4 100644
--- a/src/main/java/org/folio/consortia/service/impl/PublicationServiceImpl.java
+++ b/src/main/java/org/folio/consortia/service/impl/PublicationServiceImpl.java
@@ -41,11 +41,11 @@
import org.folio.consortia.utils.TenantContextUtils;
import org.folio.spring.FolioExecutionContext;
import org.folio.spring.FolioModuleMetadata;
+import org.folio.spring.data.OffsetRequest;
import org.folio.spring.scope.FolioExecutionContextSetter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.task.TaskExecutor;
import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
@@ -95,7 +95,7 @@ public PublicationDetailsResponse getPublicationDetails(UUID consortiumId, UUID
var publicationStatusEntity = publicationStatusRepository.findById(publicationId)
.orElseThrow(() -> new ResourceNotFoundException(PUBLICATION_ID_FIELD, String.valueOf(publicationId)));
- var ptrEntities = publicationTenantRequestRepository.findByPcStateId(publicationId, PageRequest.of(0, Integer.MAX_VALUE));
+ var ptrEntities = publicationTenantRequestRepository.findByPcStateId(publicationId, OffsetRequest.of(0, Integer.MAX_VALUE));
log.info("getPublicationDetails:: Found {} of {} expected tenant request records", ptrEntities.getTotalElements(), publicationStatusEntity.getTotalRecords());
var errorList = buildErrorListFromPublicationTenantRequestEntities(ptrEntities);
@@ -312,7 +312,7 @@ public PublicationResultCollection getPublicationResults(UUID consortiumId, UUID
var publicationStatusEntity = publicationStatusRepository.findById(publicationId)
.orElseThrow(() -> new ResourceNotFoundException(PUBLICATION_ID_FIELD, String.valueOf(publicationId)));
- var ptrEntities = publicationTenantRequestRepository.findByPcStateId(publicationId, PageRequest.of(0, Integer.MAX_VALUE));
+ var ptrEntities = publicationTenantRequestRepository.findByPcStateId(publicationId, OffsetRequest.of(0, Integer.MAX_VALUE));
log.info("getPublicationResults:: Found {} of {} expected tenant request records for publication {}", ptrEntities.getTotalElements(), publicationStatusEntity.getTotalRecords(), publicationId);
var resultList = ptrEntities.stream()
diff --git a/src/main/java/org/folio/consortia/service/impl/SharingInstanceServiceImpl.java b/src/main/java/org/folio/consortia/service/impl/SharingInstanceServiceImpl.java
index e85d77b7..5828869f 100644
--- a/src/main/java/org/folio/consortia/service/impl/SharingInstanceServiceImpl.java
+++ b/src/main/java/org/folio/consortia/service/impl/SharingInstanceServiceImpl.java
@@ -1,11 +1,15 @@
package org.folio.consortia.service.impl;
-import org.folio.consortia.exception.ResourceNotFoundException;
-import org.folio.consortia.repository.SharingInstanceRepository;
-import org.folio.consortia.repository.SharingInstanceRepository.Specifications;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.fasterxml.jackson.databind.node.TextNode;
+import jakarta.transaction.Transactional;
import java.util.Objects;
import java.util.UUID;
-
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.ObjectUtils;
import org.folio.consortia.client.InventoryClient;
import org.folio.consortia.config.kafka.KafkaService;
@@ -13,6 +17,9 @@
import org.folio.consortia.domain.dto.SharingInstanceCollection;
import org.folio.consortia.domain.dto.Status;
import org.folio.consortia.domain.entity.SharingInstanceEntity;
+import org.folio.consortia.exception.ResourceNotFoundException;
+import org.folio.consortia.repository.SharingInstanceRepository;
+import org.folio.consortia.repository.SharingInstanceRepository.Specifications;
import org.folio.consortia.service.ConsortiumService;
import org.folio.consortia.service.InventoryService;
import org.folio.consortia.service.SharingInstanceService;
@@ -21,21 +28,11 @@
import org.folio.consortia.utils.TenantContextUtils;
import org.folio.spring.FolioExecutionContext;
import org.folio.spring.FolioModuleMetadata;
+import org.folio.spring.data.OffsetRequest;
import org.folio.spring.scope.FolioExecutionContextSetter;
import org.springframework.core.convert.ConversionService;
-import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fasterxml.jackson.databind.node.TextNode;
-
-import jakarta.transaction.Transactional;
-import lombok.RequiredArgsConstructor;
-import lombok.SneakyThrows;
-import lombok.extern.log4j.Log4j2;
-
@Service
@Log4j2
@RequiredArgsConstructor
@@ -76,7 +73,7 @@ public SharingInstance start(UUID consortiumId, SharingInstance sharingInstance)
if (Objects.equals(centralTenantId, sourceTenantId)) {
JsonNode inventoryInstance;
- try (var context = new FolioExecutionContextSetter(
+ try (var ignored = new FolioExecutionContextSetter(
TenantContextUtils.prepareContextForTenant(sourceTenantId, folioModuleMetadata, folioExecutionContext))) {
inventoryInstance = inventoryService.getById(sharingInstance.getInstanceIdentifier());
} catch (Exception ex) {
@@ -84,7 +81,7 @@ public SharingInstance start(UUID consortiumId, SharingInstance sharingInstance)
return updateFieldsAndSaveInCaseOfException(sharingInstance, GET_INSTANCE_EXCEPTION_MSG, ex);
}
- try (var context = new FolioExecutionContextSetter(
+ try (var ignored = new FolioExecutionContextSetter(
TenantContextUtils.prepareContextForTenant(targetTenantId, folioModuleMetadata, folioExecutionContext))) {
String source = switch (inventoryInstance.get("source").asText().toLowerCase()) {
case "folio" -> HelperUtils.CONSORTIUM_FOLIO_INSTANCE_SOURCE;
@@ -105,21 +102,47 @@ public SharingInstance start(UUID consortiumId, SharingInstance sharingInstance)
sharingInstance.setStatus(Status.IN_PROGRESS);
}
- SharingInstanceEntity savedSharingInstance = sharingInstanceRepository.save(toEntity(sharingInstance));
+
+ SharingInstanceEntity savedSharingInstance = saveSharingInstance(sharingInstance);
log.info("start:: sharingInstance with id: {}, instanceId: {}, sourceTenantId: {}, targetTenantId: {} has been saved with status: {}",
savedSharingInstance.getId(), savedSharingInstance.getInstanceId(), sourceTenantId, targetTenantId, savedSharingInstance.getStatus());
return converter.convert(savedSharingInstance, SharingInstance.class);
}
+ /**
+ * This method save sharing instance record to database.
+ * Before to save sharing instance to db, previous attempt will be checked.
+ * If a matching previous attempt is found, the method updates it with the new attempt's error and status information.
+ * Otherwise, new record will be created.
+ *
+ * @param sharingInstance sharingInstanceDto
+ * @return saved sharing instance entity
+ */
+ private SharingInstanceEntity saveSharingInstance(SharingInstance sharingInstance) {
+ var existingSharingInstanceOptional = sharingInstanceRepository.findByInstanceAndTenantIds(
+ sharingInstance.getInstanceIdentifier(), sharingInstance.getSourceTenantId(), sharingInstance.getTargetTenantId());
+
+ if (existingSharingInstanceOptional.isEmpty()) {
+ log.info("saveSharingInstance:: There is no existing record, so creating new record");
+ return sharingInstanceRepository.save(toEntity(sharingInstance));
+ }
+
+ log.info("saveSharingInstance:: Existed sharingInstance is being updated with new attempt with status={}", sharingInstance.getStatus());
+ var existingSharingInstance = existingSharingInstanceOptional.get();
+ existingSharingInstance.setError(sharingInstance.getError());
+ existingSharingInstance.setStatus(sharingInstance.getStatus());
+ return sharingInstanceRepository.save(existingSharingInstance);
+ }
+
@Override
public SharingInstanceCollection getSharingInstances(UUID consortiumId, UUID instanceIdentifier, String sourceTenantId,
- String targetTenantId, Status status, Integer offset, Integer limit) {
+ String targetTenantId, Status status, Integer offset, Integer limit) {
log.debug("getSharingInstances:: parameters consortiumId: {}, instanceIdentifier: {}, sourceTenantId: {}, targetTenantId: {}, status: {}.",
consortiumId, instanceIdentifier, sourceTenantId, targetTenantId, status);
consortiumService.checkConsortiumExistsOrThrow(consortiumId);
var specification = Specifications.constructSpecification(instanceIdentifier, sourceTenantId, targetTenantId, status);
- var sharingInstancePage = sharingInstanceRepository.findAll(specification, PageRequest.of(offset, limit));
+ var sharingInstancePage = sharingInstanceRepository.findAll(specification, OffsetRequest.of(offset, limit));
var result = new SharingInstanceCollection();
result.setSharingInstances(sharingInstancePage.stream().map(o -> converter.convert(o, SharingInstance.class)).toList());
result.setTotalRecords((int) sharingInstancePage.getTotalElements());
@@ -182,6 +205,13 @@ private void checkTenantsExistAndContainCentralTenantOrThrow(String sourceTenant
throw new IllegalArgumentException("Both 'sourceTenantId' and 'targetTenantId' cannot be member tenants.");
}
+ private SharingInstance updateFieldsAndSaveInCaseOfException(SharingInstance sharingInstance, String message, Exception ex) {
+ sharingInstance.setStatus(Status.ERROR);
+ sharingInstance.setError(String.format(message, InventoryClient.getReason(ex)));
+ var savedSharingInstance = saveSharingInstance(sharingInstance);
+ return converter.convert(savedSharingInstance, SharingInstance.class);
+ }
+
private SharingInstanceEntity toEntity(SharingInstance dto) {
SharingInstanceEntity entity = new SharingInstanceEntity();
entity.setId(UUID.randomUUID());
@@ -192,11 +222,4 @@ private SharingInstanceEntity toEntity(SharingInstance dto) {
entity.setError(dto.getError());
return entity;
}
-
- private SharingInstance updateFieldsAndSaveInCaseOfException(SharingInstance sharingInstance, String message, Exception ex) {
- sharingInstance.setStatus(Status.ERROR);
- sharingInstance.setError(String.format(message, InventoryClient.getReason(ex)));
- var savedSharingInstance = sharingInstanceRepository.save(toEntity(sharingInstance));
- return converter.convert(savedSharingInstance, SharingInstance.class);
- }
}
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 e86dfc37..cb0a3d36 100644
--- a/src/main/java/org/folio/consortia/service/impl/SyncPrimaryAffiliationServiceImpl.java
+++ b/src/main/java/org/folio/consortia/service/impl/SyncPrimaryAffiliationServiceImpl.java
@@ -1,11 +1,11 @@
package org.folio.consortia.service.impl;
-import org.folio.consortia.repository.UserTenantRepository;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
-
+import lombok.RequiredArgsConstructor;
+import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.folio.consortia.client.SyncPrimaryAffiliationClient;
@@ -17,19 +17,17 @@
import org.folio.consortia.domain.dto.User;
import org.folio.consortia.domain.entity.TenantEntity;
import org.folio.consortia.domain.entity.UserTenantEntity;
+import org.folio.consortia.repository.UserTenantRepository;
import org.folio.consortia.service.LockService;
import org.folio.consortia.service.PrimaryAffiliationService;
import org.folio.consortia.service.SyncPrimaryAffiliationService;
import org.folio.consortia.service.TenantService;
import org.folio.consortia.service.UserService;
+import org.folio.spring.data.OffsetRequest;
import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.log4j.Log4j2;
-
@Service
@Log4j2
@RequiredArgsConstructor
@@ -118,7 +116,7 @@ private void createPrimaryUserAffiliations(UUID consortiumId, String centralTena
var user = userList.get(idx);
try {
log.info("createPrimaryUserAffiliations:: Processing users: {} of {}", idx + 1, userList.size());
- Page userTenantPage = userTenantRepository.findByUserId(UUID.fromString(user.getId()), PageRequest.of(0, 1));
+ Page userTenantPage = userTenantRepository.findAnyByUserId(UUID.fromString(user.getId()), OffsetRequest.of(0, 1));
if (userTenantPage.getTotalElements() > 0) {
log.info("createPrimaryUserAffiliations:: Primary affiliation already exists for tenant/user: {}/{}",
diff --git a/src/main/java/org/folio/consortia/service/impl/TenantServiceImpl.java b/src/main/java/org/folio/consortia/service/impl/TenantServiceImpl.java
index 8015c68f..24aa5815 100644
--- a/src/main/java/org/folio/consortia/service/impl/TenantServiceImpl.java
+++ b/src/main/java/org/folio/consortia/service/impl/TenantServiceImpl.java
@@ -1,5 +1,7 @@
package org.folio.consortia.service.impl;
+import static org.folio.consortia.utils.HelperUtils.checkIdenticalOrThrow;
+
import java.util.List;
import java.util.Objects;
import java.util.UUID;
@@ -7,6 +9,7 @@
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.map.CaseInsensitiveMap;
+import org.apache.commons.lang3.ObjectUtils;
import org.folio.consortia.client.ConsortiaConfigurationClient;
import org.folio.consortia.client.SyncPrimaryAffiliationClient;
import org.folio.consortia.client.UserTenantsClient;
@@ -31,15 +34,14 @@
import org.folio.consortia.service.PermissionUserService;
import org.folio.consortia.service.TenantService;
import org.folio.consortia.service.UserService;
-import org.folio.consortia.utils.HelperUtils;
import org.folio.consortia.utils.TenantContextUtils;
import org.folio.spring.FolioExecutionContext;
+import org.folio.spring.context.ExecutionContextBuilder;
+import org.folio.spring.data.OffsetRequest;
import org.folio.spring.scope.FolioExecutionContextSetter;
-import org.folio.spring.service.SystemUserScopedExecutionService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@@ -52,8 +54,7 @@ public class TenantServiceImpl implements TenantService {
private static final String SHADOW_ADMIN_PERMISSION_FILE_PATH = "permissions/admin-user-permissions.csv";
private static final String SHADOW_SYSTEM_USER_PERMISSION_FILE_PATH = "permissions/system-user-permissions.csv";
private static final String TENANTS_IDS_NOT_MATCHED_ERROR_MSG = "Request body tenantId and path param tenantId should be identical";
- private static final String TENANT_HAS_ACTIVE_USER_ASSOCIATIONS_ERROR_MSG = "Cannot delete tenant with ID {tenantId} because it has an association with a user. "
- + "Please remove the user association before attempting to delete the tenant.";
+
private static final String DUMMY_USERNAME = "dummy_user";
@Value("${folio.system-user.username}")
private String systemUserUsername;
@@ -67,7 +68,7 @@ public class TenantServiceImpl implements TenantService {
private final ConsortiaConfigurationClient configurationClient;
private final PermissionUserService permissionUserService;
private final UserService userService;
- private final SystemUserScopedExecutionService systemUserScopedExecutionService;
+ private final ExecutionContextBuilder contextBuilder;
private final UserTenantsClient userTenantsClient;
private final SyncPrimaryAffiliationClient syncPrimaryAffiliationClient;
private final CleanupService cleanupService;
@@ -77,7 +78,7 @@ public class TenantServiceImpl implements TenantService {
public TenantCollection get(UUID consortiumId, Integer offset, Integer limit) {
TenantCollection result = new TenantCollection();
consortiumService.checkConsortiumExistsOrThrow(consortiumId);
- Page page = tenantRepository.findByConsortiumId(consortiumId, PageRequest.of(offset, limit));
+ Page page = tenantRepository.findByConsortiumId(consortiumId, OffsetRequest.of(offset, limit));
result.setTenants(page.map(o -> converter.convert(o, Tenant.class)).getContent());
result.setTotalRecords((int) page.getTotalElements());
return result;
@@ -87,8 +88,7 @@ public TenantCollection get(UUID consortiumId, Integer offset, Integer limit) {
public TenantCollection getAll(UUID consortiumId) {
TenantCollection result = new TenantCollection();
List list = tenantRepository.findByConsortiumId(consortiumId)
- .stream()
- .map(o -> converter.convert(o, Tenant.class)).toList();
+ .stream().map(o -> converter.convert(o, Tenant.class)).toList();
result.setTenants(list);
result.setTotalRecords(list.size());
return result;
@@ -118,18 +118,42 @@ public TenantEntity getByTenantId(String tenantId) {
@Override
@Transactional
public Tenant save(UUID consortiumId, UUID adminUserId, Tenant tenantDto) {
- log.info("save:: Trying to save a tenant by consortiumId '{}', tenant object with id '{}' and isCentral={}", consortiumId,
- tenantDto.getId(), tenantDto.getIsCentral());
+ log.info("save:: Trying to save a tenant with id={}, consortiumId={} and isCentral={}", tenantDto.getId(),
+ consortiumId, tenantDto.getIsCentral());
+ validateConsortiumAndTenantForSaveOperation(consortiumId, tenantDto);
+ validateCodeAndNameUniqueness(tenantDto);
- // validation part
- checkTenantNotExistsAndConsortiumExistsOrThrow(consortiumId, tenantDto.getId());
- checkCodeAndNameUniqueness(tenantDto);
- if (tenantDto.getIsCentral()) {
- checkCentralTenantExistsOrThrow();
+ var existingTenant = tenantRepository.findById(tenantDto.getId());
+
+ // checked whether tenant exists or not.
+ return existingTenant.isPresent() ? reAddSoftDeletedTenant(consortiumId, existingTenant.get(), tenantDto)
+ : addNewTenant(consortiumId, tenantDto, adminUserId);
+ }
+
+ private Tenant reAddSoftDeletedTenant(UUID consortiumId, TenantEntity existingTenant, Tenant tenantDto) {
+ log.info("reAddSoftDeletedTenant:: Re-adding soft deleted tenant with id={}", tenantDto.getId());
+ validateExistingTenant(existingTenant);
+
+ tenantDto.setIsDeleted(false);
+ var savedTenant = saveTenant(consortiumId, tenantDto, SetupStatusEnum.COMPLETED);
+
+ String centralTenantId = getCentralTenantId();
+ try (var ignored = new FolioExecutionContextSetter(contextBuilder.buildContext(tenantDto.getId()))) {
+ createUserTenantWithDummyUser(tenantDto.getId(), centralTenantId, consortiumId);
+ log.info("reAddSoftDeletedTenant:: Dummy user re-created in user-tenants table");
+ } catch (Exception e) {
+ log.error("Failed to create dummy user with centralTenantId: {}, tenant: {}" +
+ " and error message: {}", centralTenantId, tenantDto.getId(), e.getMessage(), e);
}
+ return savedTenant;
+ }
+
+ private Tenant addNewTenant(UUID consortiumId, Tenant tenantDto, UUID adminUserId) {
+ log.info("addNewTenant:: Creating new tenant with id={}, consortiumId={}, and adminUserId={}",
+ tenantDto.getId(), consortiumId, adminUserId);
- // save tenant to db
lockService.lockTenantSetupWithinTransaction();
+ tenantDto.setIsDeleted(false);
Tenant savedTenant = saveTenant(consortiumId, tenantDto, SetupStatusEnum.IN_PROGRESS);
// save admin user tenant association for non-central tenant
@@ -145,7 +169,7 @@ public Tenant save(UUID consortiumId, UUID adminUserId, Tenant tenantDto) {
userTenantRepository.save(createUserTenantEntity(consortiumId, shadowAdminUser, tenantDto));
// creating shadow user of consortia system user of central tenant with same permissions.
var centralSystemUser = userService.getByUsername(systemUserUsername)
- .orElseThrow(() -> new ResourceNotFoundException("systemUserUsername", systemUserUsername));
+ .orElseThrow(() -> new ResourceNotFoundException("systemUserUsername", systemUserUsername));
shadowSystemUser = userService.prepareShadowUser(UUID.fromString(centralSystemUser.getId()), folioExecutionContext.getTenantId());
userTenantRepository.save(createUserTenantEntity(consortiumId, shadowSystemUser, tenantDto));
}
@@ -156,7 +180,7 @@ public Tenant save(UUID consortiumId, UUID adminUserId, Tenant tenantDto) {
var allHeaders = new CaseInsensitiveMap<>(folioExecutionContext.getOkapiHeaders());
allHeaders.put("x-okapi-tenant", List.of(tenantDto.getId()));
- try (var fex = new FolioExecutionContextSetter(folioExecutionContext.getFolioModuleMetadata(), allHeaders)) {
+ try (var ignored = new FolioExecutionContextSetter(folioExecutionContext.getFolioModuleMetadata(), allHeaders)) {
configurationClient.saveConfiguration(createConsortiaConfigurationBody(centralTenantId));
if (!tenantDto.getIsCentral()) {
createUserTenantWithDummyUser(tenantDto.getId(), centralTenantId, consortiumId);
@@ -174,16 +198,20 @@ public Tenant save(UUID consortiumId, UUID adminUserId, Tenant tenantDto) {
@Override
@Transactional
public Tenant update(UUID consortiumId, String tenantId, Tenant tenantDto) {
- consortiumService.checkConsortiumExistsOrThrow(consortiumId);
- checkTenantExistsOrThrow(tenantId);
- HelperUtils.checkIdenticalOrThrow(tenantId, tenantDto.getId(), TENANTS_IDS_NOT_MATCHED_ERROR_MSG);
+ log.debug("update:: Trying to update tenant '{}' in consortium '{}'", tenantId, consortiumId);
+ var existedTenant = tenantRepository.findById(tenantId)
+ .orElseThrow(() -> new ResourceNotFoundException("id", tenantId));
+
+ validateTenantForUpdateOperation(consortiumId, tenantId, tenantDto, existedTenant);
+ // isDeleted flag cannot be changed by put request
+ tenantDto.setIsDeleted(existedTenant.getIsDeleted());
return updateTenant(consortiumId, tenantDto);
}
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateTenantSetupStatus(String tenantId, String centralTenantId, SetupStatusEnum setupStatus) {
- try (var ctx = new FolioExecutionContextSetter(TenantContextUtils.prepareContextForTenant(centralTenantId,
+ try (var ignored = new FolioExecutionContextSetter(TenantContextUtils.prepareContextForTenant(centralTenantId,
folioExecutionContext.getFolioModuleMetadata(), folioExecutionContext))) {
tenantDetailsRepository.setSetupStatusByTenantId(setupStatus, tenantId);
log.info("updateTenantSetupStatus:: tenant id={} status updated to {}", tenantId, setupStatus);
@@ -194,13 +222,23 @@ public void updateTenantSetupStatus(String tenantId, String centralTenantId, Set
@Transactional
public void delete(UUID consortiumId, String tenantId) {
consortiumService.checkConsortiumExistsOrThrow(consortiumId);
- checkTenantExistsOrThrow(tenantId);
- if (userTenantRepository.existsByTenantId(tenantId)) {
- throw new IllegalArgumentException(TENANT_HAS_ACTIVE_USER_ASSOCIATIONS_ERROR_MSG);
+ var tenant = tenantRepository.findById(tenantId);
+
+ if (tenant.isEmpty()) {
+ throw new ResourceNotFoundException("id", tenantId);
}
+
+ validateTenantForDeleteOperation(tenant.get());
+
+ var softDeletedTenant = tenant.get();
+ softDeletedTenant.setIsDeleted(true);
// clean publish coordinator tables first, because after tenant removal it will be ignored by cleanup service
cleanupService.clearPublicationTables();
- tenantRepository.deleteById(tenantId);
+ tenantRepository.save(softDeletedTenant);
+
+ try (var ignored = new FolioExecutionContextSetter(contextBuilder.buildContext(tenantId))) {
+ userTenantsClient.deleteUserTenants();
+ }
}
private Tenant saveTenant(UUID consortiumId, Tenant tenantDto, SetupStatusEnum setupStatus) {
@@ -213,22 +251,21 @@ private Tenant saveTenant(UUID consortiumId, Tenant tenantDto, SetupStatusEnum s
}
private Tenant updateTenant(UUID consortiumId, Tenant tenantDto) {
- log.debug("updateTenant:: Trying to update tenant with consoritumId={} and tenant with id={}", consortiumId, tenantDto);
TenantEntity entity = toTenantEntity(consortiumId, tenantDto);
TenantEntity updatedTenant = tenantRepository.save(entity);
log.info("updateTenant:: Tenant '{}' successfully updated", updatedTenant.getId());
return converter.convert(updatedTenant, Tenant.class);
}
- /*
- Dummy user will be used to support cross-tenant requests checking in mod-authtoken,
- if user-tenant table contains some record in institutional tenant - it means mod-consortia enabled for
- this tenant and will allow cross-tenant request.
-
- @param tenantId tenant id
- @param centralTenantId central tenant id
- @param consortiumId consortium id
- */
+ /**
+ * Dummy user will be used to support cross-tenant requests checking in mod-authtoken,
+ * if user-tenant table contains some record in institutional tenant - it means mod-consortia enabled for
+ * this tenant and will allow cross-tenant request.
+ *
+ * @param tenantId tenant id
+ * @param centralTenantId central tenant id
+ * @param consortiumId consortium id
+ */
private void createUserTenantWithDummyUser(String tenantId, String centralTenantId, UUID consortiumId) {
UserTenant userTenant = new UserTenant();
userTenant.setId(UUID.randomUUID());
@@ -242,22 +279,6 @@ private void createUserTenantWithDummyUser(String tenantId, String centralTenant
userTenantsClient.postUserTenant(userTenant);
}
- private void checkTenantNotExistsAndConsortiumExistsOrThrow(UUID consortiumId, String tenantId) {
- consortiumService.checkConsortiumExistsOrThrow(consortiumId);
- if (tenantRepository.existsById(tenantId)) {
- throw new ResourceAlreadyExistException("id", tenantId);
- }
- }
-
- private void checkCodeAndNameUniqueness(Tenant tenant) {
- if (tenantRepository.existsByName(tenant.getName())) {
- throw new ResourceAlreadyExistException("name", tenant.getName());
- }
- if (tenantRepository.existsByCode(tenant.getCode())) {
- throw new ResourceAlreadyExistException("code", tenant.getCode());
- }
- }
-
@Override
public void checkTenantExistsOrThrow(String tenantId) {
if (!tenantRepository.existsById(tenantId)) {
@@ -281,12 +302,45 @@ public void checkTenantsAndConsortiumExistsOrThrow(UUID consortiumId, List
@@ -64,8 +63,8 @@ public class UserTenantServiceImpl implements UserTenantService {
public UserTenantCollection get(UUID consortiumId, Integer offset, Integer limit) {
consortiumService.checkConsortiumExistsOrThrow(consortiumId);
var result = new UserTenantCollection();
- Page userTenantPage = userTenantRepository.findAll(PageRequest.of(offset, limit));
- result.setUserTenants(userTenantPage.stream().map(o -> converter.convert(o, UserTenant.class)).toList());
+ Page userTenantPage = userTenantRepository.getAll(OffsetRequest.of(offset, limit));
+ result.setUserTenants(userTenantPage.map(o -> converter.convert(o, UserTenant.class)).getContent());
result.setTotalRecords((int) userTenantPage.getTotalElements());
return result;
}
@@ -95,7 +94,7 @@ public UserTenantCollection getByUsernameAndTenantId(UUID consortiumId, String u
public UserTenantCollection getByUserId(UUID consortiumId, UUID userId, Integer offset, Integer limit) {
consortiumService.checkConsortiumExistsOrThrow(consortiumId);
var result = new UserTenantCollection();
- Page userTenantPage = userTenantRepository.findByUserId(userId, PageRequest.of(offset, limit));
+ Page userTenantPage = userTenantRepository.findByUserId(userId, OffsetRequest.of(offset, limit));
if (userTenantPage.getContent().isEmpty()) {
throw new ResourceNotFoundException(USER_ID, String.valueOf(userId));
diff --git a/src/main/resources/db/changelog/changes/create-tenant-table.xml b/src/main/resources/db/changelog/changes/create-tenant-table.xml
index 3fef6a75..08644d80 100644
--- a/src/main/resources/db/changelog/changes/create-tenant-table.xml
+++ b/src/main/resources/db/changelog/changes/create-tenant-table.xml
@@ -55,4 +55,12 @@
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/log4j2-json.properties b/src/main/resources/log4j2-json.properties
index a8c80275..7d4a507d 100644
--- a/src/main/resources/log4j2-json.properties
+++ b/src/main/resources/log4j2-json.properties
@@ -31,3 +31,7 @@ appender.console.layout.moduleId.value = $${folio:moduleid:-}
rootLogger.level = info
rootLogger.appenderRefs = info
rootLogger.appenderRef.stdout.ref = STDOUT
+
+logger.kafka_consumer_config.name = org.apache.kafka.clients.consumer.ConsumerConfig
+logger.kafka_consumer_config.level = error
+logger.kafka_consumer_config.appenderRef.stdout.ref = STDOUT
diff --git a/src/main/resources/log4j2.properties b/src/main/resources/log4j2.properties
index 4996d068..c41432bc 100644
--- a/src/main/resources/log4j2.properties
+++ b/src/main/resources/log4j2.properties
@@ -13,3 +13,7 @@ appender.console.layout.pattern = %d{HH:mm:ss} %t [$${folio:requestid:-}] [$${fo
rootLogger.level = info
rootLogger.appenderRefs = info
rootLogger.appenderRef.stdout.ref = STDOUT
+
+logger.kafka_consumer_config.name = org.apache.kafka.clients.consumer.ConsumerConfig
+logger.kafka_consumer_config.level = error
+logger.kafka_consumer_config.appenderRef.stdout.ref = STDOUT
diff --git a/src/main/resources/permissions/system-user-permissions.csv b/src/main/resources/permissions/system-user-permissions.csv
index 4a2d8d35..8d992b54 100644
--- a/src/main/resources/permissions/system-user-permissions.csv
+++ b/src/main/resources/permissions/system-user-permissions.csv
@@ -11,6 +11,7 @@ perms.users.assign.immutable
perms.users.assign.mutable
perms.users.get
user-tenants.item.post
+user-tenants.item.delete
consortia.sync-primary-affiliations.item.post
consortia.create-primary-affiliations.item.post
departments.item.post
@@ -34,6 +35,9 @@ inventory-storage.call-number-types.item.delete
inventory-storage.classification-types.item.post
inventory-storage.classification-types.item.put
inventory-storage.classification-types.item.delete
+inventory-storage.contributor-name-types.item.post
+inventory-storage.contributor-name-types.item.put
+inventory-storage.contributor-name-types.item.delete
inventory-storage.electronic-access-relationships.item.post
inventory-storage.electronic-access-relationships.item.put
inventory-storage.electronic-access-relationships.item.delete
@@ -43,6 +47,9 @@ inventory-storage.holdings-note-types.item.delete
inventory-storage.holdings-types.item.post
inventory-storage.holdings-types.item.put
inventory-storage.holdings-types.item.delete
+inventory-storage.holdings-sources.item.post
+inventory-storage.holdings-sources.item.put
+inventory-storage.holdings-sources.item.delete
inventory-storage.statistical-codes.item.post
inventory-storage.statistical-codes.item.put
inventory-storage.statistical-codes.item.delete
diff --git a/src/main/resources/swagger.api/schemas/tenant.yaml b/src/main/resources/swagger.api/schemas/tenant.yaml
index 8d3bbaef..b2044a42 100644
--- a/src/main/resources/swagger.api/schemas/tenant.yaml
+++ b/src/main/resources/swagger.api/schemas/tenant.yaml
@@ -14,6 +14,8 @@ Tenant:
maxLength: 150
isCentral:
type: boolean
+ isDeleted:
+ type: boolean
additionalProperties: false
required:
- id
diff --git a/src/main/resources/swagger.api/schemas/user.yaml b/src/main/resources/swagger.api/schemas/user.yaml
index 428626a3..cdbe65e5 100644
--- a/src/main/resources/swagger.api/schemas/user.yaml
+++ b/src/main/resources/swagger.api/schemas/user.yaml
@@ -64,7 +64,7 @@ User:
description: Object that contains custom field
type: object
additionalProperties: true
- additionalProperties: false
+ additionalProperties: true
Personal:
type: object
@@ -103,7 +103,11 @@ Personal:
preferredContactTypeId:
description: Id of user's preferred contact type
type: string
- additionalProperties: false
+ profilePictureLink:
+ description: Link to the profile picture
+ type: string
+ format: uri
+ additionalProperties: true
required:
- lastName
diff --git a/src/test/java/org/folio/consortia/FolioConsortiaApplicationTest.java b/src/test/java/org/folio/consortia/FolioConsortiaApplicationTest.java
index e4b3e55b..3f8082ac 100644
--- a/src/test/java/org/folio/consortia/FolioConsortiaApplicationTest.java
+++ b/src/test/java/org/folio/consortia/FolioConsortiaApplicationTest.java
@@ -30,7 +30,7 @@ public ResponseEntity deleteTenant(String operationId) {
}
@Override
- public ResponseEntity postTenant(@Valid TenantAttributes tenantAttributes) {
+ public ResponseEntity postTenant(TenantAttributes tenantAttributes) {
return ResponseEntity.status(HttpStatus.CREATED).build();
}
}
diff --git a/src/test/java/org/folio/consortia/base/BaseIT.java b/src/test/java/org/folio/consortia/base/BaseIT.java
index 4171dc10..4de321b3 100644
--- a/src/test/java/org/folio/consortia/base/BaseIT.java
+++ b/src/test/java/org/folio/consortia/base/BaseIT.java
@@ -5,9 +5,16 @@
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-import java.util.List;
-
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.tomakehurst.wiremock.WireMockServer;
+import com.github.tomakehurst.wiremock.common.ClasspathFileSource;
import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer;
+import com.github.tomakehurst.wiremock.extension.responsetemplating.TemplateEngine;
+import java.util.ArrayList;
+import java.util.List;
+import lombok.SneakyThrows;
import org.folio.consortia.support.extension.EnableKafkaExtension;
import org.folio.spring.integration.XOkapiHeaders;
import org.folio.tenant.domain.dto.TenantAttributes;
@@ -32,13 +39,6 @@
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Testcontainers;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.github.tomakehurst.wiremock.WireMockServer;
-
-import lombok.SneakyThrows;
-
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ContextConfiguration(initializers = BaseIT.DockerPostgresDataSourceInitializer.class)
@@ -69,7 +69,7 @@ public abstract class BaseIT {
static void beforeAll(@Autowired MockMvc mockMvc) {
wireMockServer = new WireMockServer(wireMockConfig()
.port(WIRE_MOCK_PORT)
- .extensions(new ResponseTemplateTransformer(true)));
+ .extensions(new ResponseTemplateTransformer(TemplateEngine.defaultTemplateEngine(), true, new ClasspathFileSource("/"), new ArrayList<>())));
wireMockServer.start();
diff --git a/src/test/java/org/folio/consortia/controller/ConsortiumControllerTest.java b/src/test/java/org/folio/consortia/controller/ConsortiumControllerTest.java
index 25c569ac..eb6676dd 100644
--- a/src/test/java/org/folio/consortia/controller/ConsortiumControllerTest.java
+++ b/src/test/java/org/folio/consortia/controller/ConsortiumControllerTest.java
@@ -10,20 +10,19 @@
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-import org.folio.consortia.domain.entity.ConsortiumEntity;
-import org.folio.consortia.exception.ResourceAlreadyExistException;
-import org.folio.consortia.repository.ConsortiumRepository;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
-
import org.folio.consortia.base.BaseIT;
+import org.folio.consortia.domain.entity.ConsortiumEntity;
+import org.folio.consortia.exception.ResourceAlreadyExistException;
+import org.folio.consortia.repository.ConsortiumRepository;
+import org.folio.spring.data.OffsetRequest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.PageRequest;
class ConsortiumControllerTest extends BaseIT {
private static final String CONSORTIUM_RESOURCE_EXIST_MSG_TEMPLATE = "System can not have more than one consortium record";
@@ -161,8 +160,8 @@ void shouldGetConsortiumCollection() throws Exception {
List consortiumEntityList = new ArrayList<>();
consortiumEntityList.add(consortiumEntity);
- when(consortiumRepository.findAll(PageRequest.of(0, 1)))
- .thenReturn(new PageImpl<>(consortiumEntityList, PageRequest.of(0, 1), consortiumEntityList.size()));
+ when(consortiumRepository.findAll(OffsetRequest.of(0, 1)))
+ .thenReturn(new PageImpl<>(consortiumEntityList, OffsetRequest.of(0, 1), consortiumEntityList.size()));
this.mockMvc.perform(
get("/consortia")
diff --git a/src/test/java/org/folio/consortia/controller/TenantControllerTest.java b/src/test/java/org/folio/consortia/controller/TenantControllerTest.java
index 6b9fcfba..da01187d 100644
--- a/src/test/java/org/folio/consortia/controller/TenantControllerTest.java
+++ b/src/test/java/org/folio/consortia/controller/TenantControllerTest.java
@@ -35,12 +35,14 @@
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
+import org.folio.consortia.base.BaseIT;
import org.folio.consortia.client.CapabilitiesClient;
import org.folio.consortia.client.ConsortiaConfigurationClient;
import org.folio.consortia.client.SyncPrimaryAffiliationClient;
import org.folio.consortia.client.UserCapabilitiesClient;
import org.folio.consortia.client.UserPermissionsClient;
import org.folio.consortia.client.UserTenantsClient;
+import org.folio.consortia.client.UsersClient;
import org.folio.consortia.client.UsersKeycloakClient;
import org.folio.consortia.config.kafka.KafkaService;
import org.folio.consortia.domain.dto.Capabilities;
@@ -63,9 +65,10 @@
import org.folio.consortia.service.UserService;
import org.folio.consortia.service.UserTenantService;
import org.folio.consortia.service.impl.ConsortiaConfigurationServiceImpl;
-import org.folio.consortia.base.BaseIT;
import org.folio.spring.FolioExecutionContext;
import org.folio.spring.FolioModuleMetadata;
+import org.folio.spring.context.ExecutionContextBuilder;
+import org.folio.spring.data.OffsetRequest;
import org.folio.spring.integration.XOkapiHeaders;
import org.folio.spring.service.PrepareSystemUserService;
import org.folio.spring.service.SystemUserScopedExecutionService;
@@ -77,7 +80,6 @@
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.PageRequest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
@@ -86,6 +88,7 @@ class TenantControllerTest extends BaseIT {
private static final String TENANT_REQUEST_BODY =
"{\"id\":\"diku1234\",\"code\":\"TST\",\"name\":\"diku_tenant_name1234\", \"isCentral\":false}";
private static final String CONSORTIUM_ID = "7698e46-c3e3-11ed-afa1-0242ac120002";
+ private static final String CENTRAL_TENANT_REQUEST_BODY = "{\"id\":\"diku1234\",\"code\":\"TST\",\"name\":\"diku_tenant_name1234\", \"isCentral\":true}";
private static final String CENTRAL_TENANT_ID = "diku";
public static final String SYNC_PRIMARY_AFFILIATIONS_URL =
"/consortia/%s/tenants/%s/sync-primary-affiliations?centralTenantId=%s";
@@ -130,6 +133,10 @@ class TenantControllerTest extends BaseIT {
SyncPrimaryAffiliationClient syncPrimaryAffiliationClient;
@MockBean
UsersKeycloakClient usersKeycloakClient;
+ @MockBean
+ UsersClient usersClient;
+ @MockBean
+ ExecutionContextBuilder executionContextBuilder;
/* Success cases */
@Test
@@ -141,13 +148,12 @@ void getTenants() throws Exception {
tenantEntityList.add(tenantEntity1);
tenantEntityList.add(tenantEntity2);
- when(tenantRepository.findByConsortiumId(any(), any(PageRequest.of(0, 2)
- .getClass()))).thenReturn(new PageImpl<>(tenantEntityList, PageRequest.of(0, 2), tenantEntityList.size()));
+ when(tenantRepository.findByConsortiumId(any(), any(OffsetRequest.of(1, 2).getClass())))
+ .thenReturn(new PageImpl<>(tenantEntityList, OffsetRequest.of(2, 2), tenantEntityList.size()));
when(consortiumRepository.existsById(consortiumId)).thenReturn(true);
var headers = defaultHeaders();
- this.mockMvc.perform(
- get("/consortia/7698e46-c3e3-11ed-afa1-0242ac120002/tenants?limit=2&offset=1").headers(headers))
+ this.mockMvc.perform(get("/consortia/7698e46-c3e3-11ed-afa1-0242ac120002/tenants?limit=2&offset=2").headers(headers))
.andExpectAll(status().isOk(), content().contentType(MediaType.APPLICATION_JSON_VALUE));
}
@@ -198,13 +204,40 @@ void shouldSaveTenant(String contentString) throws Exception {
@ParameterizedTest
@ValueSource(strings = {TENANT_REQUEST_BODY})
- void shouldUpdateTenant(String contentString) throws Exception {
- TenantEntity tenant = createTenantEntity();
+ void shouldReAddSoftDeletedTenant(String contentString) throws Exception {
+ var headers = defaultHeaders();
+ String adminUser = UUID.randomUUID().toString();
+ TenantEntity centralTenant = createTenantEntity(CENTRAL_TENANT_ID, CENTRAL_TENANT_ID, "AAA", true);
+ var existedTenant = createTenantEntity("diku1234", "diku_tenant_name1234");
+ existedTenant.setIsDeleted(true);
+ var tenantDetailsEntity = new TenantDetailsEntity();
+ tenantDetailsEntity.setConsortiumId(centralTenant.getConsortiumId());
+ tenantDetailsEntity.setId("diku1234");
+
+ doNothing().when(userTenantsClient).postUserTenant(any());
+ when(consortiumRepository.existsById(any())).thenReturn(true);
+ when(tenantRepository.findById("diku1234")).thenReturn(Optional.of(existedTenant));
+ when(tenantDetailsRepository.save(any(TenantDetailsEntity.class))).thenReturn(tenantDetailsEntity);
+ when(tenantRepository.findCentralTenant()).thenReturn(Optional.of(centralTenant));
+ doReturn(folioExecutionContext).when(executionContextBuilder).buildContext(anyString());
+
+ this.mockMvc.perform(
+ post("/consortia/7698e46-c3e3-11ed-afa1-0242ac120002/tenants?adminUserId=" + adminUser)
+ .headers(headers).content(contentString))
+ .andExpect(status().isCreated());
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {TENANT_REQUEST_BODY})
+ void shouldUpdateTenant(String contentString) throws Exception {
+ var existingTenant = createTenantEntity();
+ var updatedTenant = createTenantEntity();
var headers = defaultHeaders();
- when(tenantRepository.existsById(any())).thenReturn(true);
+
+ when(tenantRepository.findById(anyString())).thenReturn(Optional.of(existingTenant));
when(consortiumRepository.existsById(any())).thenReturn(true);
- when(tenantRepository.save(any())).thenReturn(tenant);
+ when(tenantRepository.save(any())).thenReturn(updatedTenant);
this.mockMvc.perform(
put("/consortia/7698e46-c3e3-11ed-afa1-0242ac120002/tenants/diku1234")
@@ -240,7 +273,7 @@ void getBadRequest() throws Exception {
andExpectAll(
status().is4xxClientError(),
content().contentType(MediaType.APPLICATION_JSON_VALUE),
- jsonPath("$.errors[0].message", is("Page size must not be less than one")));
+ jsonPath("$.errors[0].message", is("Limit cannot be negative or zero: 0")));
}
@Test
@@ -330,20 +363,38 @@ void shouldThrownMethodArgumentNotValidException(String contentString) throws Ex
@ParameterizedTest
- @ValueSource(strings = {TENANT_REQUEST_BODY})
- void shouldGet4xxErrorWhileSavingDuplicateName(String contentString) throws Exception {
+ @ValueSource(strings = {CENTRAL_TENANT_REQUEST_BODY})
+ void shouldGet4xxErrorWhileSavingDuplicateCentralTenant(String contentString) throws Exception {
var headers = defaultHeaders();
UUID consortiumId = UUID.fromString(CONSORTIUM_ID);
TenantEntity centralTenant = createTenantEntity(CENTRAL_TENANT_ID, CENTRAL_TENANT_ID, "TTA", true);
- PermissionUser permissionUser = new PermissionUser();
- PermissionUserCollection permissionUserCollection = new PermissionUserCollection();
- permissionUserCollection.setPermissionUsers(List.of(permissionUser));
doReturn(new User()).when(usersKeycloakClient).getUsersByUserId(any());
when(consortiumRepository.existsById(consortiumId)).thenReturn(true);
when(tenantRepository.existsById(any(String.class))).thenReturn(true);
+ when(tenantRepository.existsByIsCentralTrue()).thenReturn(true);
when(tenantRepository.findCentralTenant()).thenReturn(Optional.of(centralTenant));
- doNothing().when(configurationClient).saveConfiguration(createConsortiaConfiguration(CENTRAL_TENANT_ID));
+
+ this.mockMvc.perform(
+ post("/consortia/7698e46-c3e3-11ed-afa1-0242ac120002/tenants?adminUserId=111841e3-e6fb-4191-9fd8-5674a5107c34")
+ .headers(headers).content(contentString))
+ .andExpectAll(
+ status().is4xxClientError(),
+ jsonPath("$.errors[0].message", is("Object with isCentral [true] is already presented in the system")),
+ jsonPath("$.errors[0].code", is("DUPLICATE_ERROR")));
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {TENANT_REQUEST_BODY})
+ void shouldGet4xxErrorWhileSavingExistingTenant(String contentString) throws Exception {
+ var headers = defaultHeaders();
+ UUID consortiumId = UUID.fromString(CONSORTIUM_ID);
+ var existedTenant = createTenantEntity("diku1234", "diku_tenant_name1234");
+ existedTenant.setIsDeleted(false);
+
+ when(consortiumRepository.existsById(consortiumId)).thenReturn(true);
+ when(tenantRepository.existsById(any(String.class))).thenReturn(true);
+ when(tenantRepository.findById(anyString())).thenReturn(Optional.of(existedTenant));
this.mockMvc.perform(
post("/consortia/7698e46-c3e3-11ed-afa1-0242ac120002/tenants?adminUserId=111841e3-e6fb-4191-9fd8-5674a5107c34")
@@ -358,10 +409,10 @@ void shouldGet4xxErrorWhileSavingDuplicateName(String contentString) throws Exce
@ValueSource(strings = {TENANT_REQUEST_BODY})
void shouldThrowValidationErrorWhileUpdateTenant(String contentString) throws Exception {
var headers = defaultHeaders();
+ var existingTenant = createTenantEntity();
- when(tenantRepository.existsById(any())).thenReturn(true);
+ when(tenantRepository.findById(any())).thenReturn(Optional.of(existingTenant));
when(consortiumRepository.existsById(any())).thenReturn(true);
- when(tenantRepository.save(any(TenantEntity.class))).thenReturn(TenantEntity.class.newInstance());
this.mockMvc.perform(
put("/consortia/7698e46-c3e3-11ed-afa1-0242ac120002/tenants/TestID")
@@ -390,20 +441,23 @@ void shouldThrowNotFoundErrorWhileUpdateTenant(String contentString) throws Exce
jsonPath("$.errors[0].code", is("NOT_FOUND_ERROR")));
}
- @ParameterizedTest
- @ValueSource(strings = {TENANT_REQUEST_BODY})
- void shouldThrownHasActiveAffiliationExceptionWhileDeletingTenant(String contentString) throws Exception {
+ @Test
+ void shouldThrownExceptionWhenDeletingCentralTenant() throws Exception {
var headers = defaultHeaders();
- when(tenantRepository.existsById(any())).thenReturn(true);
+ String tenantId = "diku";
+ var centralTenant = createTenantEntity(tenantId);
+ centralTenant.setIsCentral(true);
+
+ when(tenantRepository.findById(any())).thenReturn(Optional.of(centralTenant));
when(consortiumRepository.existsById(any())).thenReturn(true);
- when(userTenantRepository.existsByTenantId("diku1234")).thenReturn(true);
this.mockMvc.perform(
- delete("/consortia/7698e46-c3e3-11ed-afa1-0242ac120002/tenants/diku1234")
- .headers(headers).content(contentString))
+ delete("/consortia/7698e46-c3e3-11ed-afa1-0242ac120002/tenants/diku")
+ .headers(headers))
.andExpectAll(
status().is4xxClientError(),
- jsonPath("$.errors[0].code", is("VALIDATION_ERROR")));
+ jsonPath("$.errors[0].code", is("VALIDATION_ERROR")),
+ jsonPath("$.errors[0].message", is("Central tenant [diku] cannot be deleted.")));
}
@Test
diff --git a/src/test/java/org/folio/consortia/controller/UserTenantControllerTest.java b/src/test/java/org/folio/consortia/controller/UserTenantControllerTest.java
index 2fff53f8..950b123b 100644
--- a/src/test/java/org/folio/consortia/controller/UserTenantControllerTest.java
+++ b/src/test/java/org/folio/consortia/controller/UserTenantControllerTest.java
@@ -1,8 +1,8 @@
package org.folio.consortia.controller;
-import static org.folio.consortia.support.TestConstants.CENTRAL_TENANT_ID;
import static org.folio.consortia.support.EntityUtils.createUserTenant;
import static org.folio.consortia.support.EntityUtils.createUserTenantEntity;
+import static org.folio.consortia.support.TestConstants.CENTRAL_TENANT_ID;
import static org.hamcrest.Matchers.is;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
@@ -15,22 +15,26 @@
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-import org.folio.consortia.client.UsersKeycloakClient;
-import org.folio.consortia.domain.entity.UserTenantEntity;
-import org.folio.consortia.exception.ResourceNotFoundException;
-import org.folio.consortia.repository.ConsortiumRepository;
-import org.folio.consortia.repository.UserTenantRepository;
-import org.folio.consortia.service.TenantService;
-import org.folio.consortia.service.UserTenantService;
+import feign.FeignException;
+import feign.Request;
+import feign.RequestTemplate;
+import feign.Response;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
-
+import org.folio.consortia.base.BaseIT;
+import org.folio.consortia.client.UsersKeycloakClient;
import org.folio.consortia.domain.dto.UserTenant;
import org.folio.consortia.domain.dto.UserTenantCollection;
-import org.folio.consortia.base.BaseIT;
+import org.folio.consortia.domain.entity.UserTenantEntity;
+import org.folio.consortia.exception.ResourceNotFoundException;
+import org.folio.consortia.repository.ConsortiumRepository;
+import org.folio.consortia.repository.UserTenantRepository;
+import org.folio.consortia.service.TenantService;
+import org.folio.consortia.service.UserTenantService;
+import org.folio.spring.data.OffsetRequest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
@@ -42,23 +46,18 @@
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.PageRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
-import feign.FeignException;
-import feign.Request;
-import feign.RequestTemplate;
-import feign.Response;
-
@EntityScan(basePackageClasses = UserTenantEntity.class)
class UserTenantControllerTest extends BaseIT {
private static final String CONSORTIUM_ID = "7698e46-c3e3-11ed-afa1-0242ac120002";
private static final String PERMISSION_EXCEPTION_MSG = "[403 Forbidden] during [GET] to " +
- "[http://users/8c54ff1e-5954-4227-8402-9a5dd061a350] [UsersClient#getUsersByUserId(String)]: " +
+ "[http://users/8c54ff1e-5954-4227-8402-9a5dd061a350] [UsersClient#getUserById(String)]: " +
"[Access for user 'ss_admin' (b82b46b6-9a6e-46f0-b986-5c643d9ba036) requires permission: users.item.get]";
+
@Mock
private UserTenantService userTenantService;
@InjectMocks
@@ -122,7 +121,7 @@ void shouldGetUserTenantList() throws Exception {
Page userTenantPage = new PageImpl<>(List.of(createUserTenantEntity(consortiumId)));
when(consortiumRepository.existsById(consortiumId)).thenReturn(true);
- when(userTenantRepository.findAll(PageRequest.of(1, 2))).thenReturn(userTenantPage);
+ when(userTenantRepository.getAll(OffsetRequest.of(1, 2))).thenReturn(userTenantPage);
this.mockMvc.perform(
get("/consortia/7698e46-c3e3-11ed-afa1-0242ac120002/user-tenants?limit=2&offset=1")
@@ -223,6 +222,7 @@ private Response createForbiddenResponse(String message) {
.request(request)
.build();
}
+
private Response createUnknownResponse(String message) {
Request request = Request.create(Request.HttpMethod.GET, "", Map.of(), null, Charset.defaultCharset(),
new RequestTemplate());
diff --git a/src/test/java/org/folio/consortia/service/ConsortiumServiceTest.java b/src/test/java/org/folio/consortia/service/ConsortiumServiceTest.java
index 21cddfa3..f3d9670a 100644
--- a/src/test/java/org/folio/consortia/service/ConsortiumServiceTest.java
+++ b/src/test/java/org/folio/consortia/service/ConsortiumServiceTest.java
@@ -6,6 +6,7 @@
import org.folio.consortia.repository.ConsortiumRepository;
import org.folio.consortia.service.impl.ConsortiumServiceImpl;
import org.folio.consortia.domain.dto.Consortium;
+import org.folio.spring.data.OffsetRequest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
@@ -15,7 +16,6 @@
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.PageRequest;
import java.util.ArrayList;
import java.util.List;
@@ -44,8 +44,8 @@ void shouldGetConsortiumList() {
List consortiumEntityList = new ArrayList<>();
consortiumEntityList.add(consortiumEntity);
- when(consortiumRepository.findAll(PageRequest.of(0, 1)))
- .thenReturn(new PageImpl<>(consortiumEntityList, PageRequest.of(0, 1), consortiumEntityList.size()));
+ when(consortiumRepository.findAll(OffsetRequest.of(0, 1)))
+ .thenReturn(new PageImpl<>(consortiumEntityList, OffsetRequest.of(0, 1), consortiumEntityList.size()));
var consortiumCollection = consortiumService.getAll();
Assertions.assertEquals(1, consortiumCollection.getTotalRecords());
diff --git a/src/test/java/org/folio/consortia/service/SharingInstanceServiceTest.java b/src/test/java/org/folio/consortia/service/SharingInstanceServiceTest.java
index ec6a9809..527369f8 100644
--- a/src/test/java/org/folio/consortia/service/SharingInstanceServiceTest.java
+++ b/src/test/java/org/folio/consortia/service/SharingInstanceServiceTest.java
@@ -205,6 +205,47 @@ void shouldSaveSharingInstanceWhenSourceTenantEqualsCentralTenantAndAllRequestsS
verify(sharingInstanceRepository, times(1)).save(any());
}
+ @Test
+ void shouldUpdatePreviousSharingInstanceWhenAfterSuccessfulUpdate() throws JsonProcessingException {
+ String sourceTenantId = "mobius";
+ String targetTenantId = "college";
+ SharingInstance sharingInstance = createSharingInstance(instanceIdentifier, sourceTenantId, targetTenantId);
+ SharingInstanceEntity sharingInstanceEntity = new SharingInstanceEntity();
+ SharingInstanceEntity existingSharingInstanceEntity = createSharingInstanceEntity(sharingInstance.getId(), instanceIdentifier, sourceTenantId, targetTenantId);
+ SharingInstanceEntity updatingSharingInstanceEntity = createSharingInstanceEntity(sharingInstance.getId(), instanceIdentifier, sourceTenantId, targetTenantId);
+ updatingSharingInstanceEntity.setStatus(Status.COMPLETE);
+
+ // skip validation part
+ when(consortiumRepository.existsById(any())).thenReturn(true);
+ doNothing().when(tenantService).checkTenantExistsOrThrow(anyString());
+ when(folioExecutionContext.getOkapiHeaders()).thenReturn(headers);
+
+ when(tenantService.getCentralTenantId()).thenReturn("mobius");
+ when(conversionService.convert(any(), eq(SharingInstance.class))).thenReturn(toDto(sharingInstanceEntity));
+ when(sharingInstanceRepository.findByInstanceAndTenantIds(instanceIdentifier, sourceTenantId, targetTenantId))
+ .thenReturn(Optional.of(existingSharingInstanceEntity));
+
+ // existing object should be updated, not created new one
+ when(sharingInstanceRepository.save(updatingSharingInstanceEntity)).thenReturn(updatingSharingInstanceEntity);
+
+ // return instance as JsonNode when getting
+ ObjectMapper objectMapper = new ObjectMapper();
+ JsonNode inventoryInstance = objectMapper.readTree("{ \"source\" : \"folio\" } ");
+
+ when(inventoryService.getById(any())).thenReturn(inventoryInstance);
+
+ // do nothing when posting inventory instance
+ doNothing().when(inventoryService).saveInstance(anyString());
+
+ // verify status field gets updated and save() method gets called
+ sharingInstanceService.start(UUID.randomUUID(), sharingInstance);
+
+ assertThat(sharingInstance.getError()).isNull();
+ assertThat(sharingInstance.getStatus()).isEqualTo(Status.COMPLETE);
+ verify(sharingInstanceRepository, times(1)).save(any());
+ verify(sharingInstanceRepository, times(1)).findByInstanceAndTenantIds(any(), anyString(), anyString());
+ }
+
@Test
void shouldPromoteSharingInstanceWithCompleteStatus() throws JsonProcessingException {
SharingInstance sharingInstance = createSharingInstance(instanceIdentifier, "college", "mobius");
diff --git a/src/test/java/org/folio/consortia/service/TenantServiceTest.java b/src/test/java/org/folio/consortia/service/TenantServiceTest.java
index 4c20844e..c05e4c0a 100644
--- a/src/test/java/org/folio/consortia/service/TenantServiceTest.java
+++ b/src/test/java/org/folio/consortia/service/TenantServiceTest.java
@@ -1,6 +1,8 @@
package org.folio.consortia.service;
+import static org.folio.consortia.support.EntityUtils.TENANT_ID;
import static org.folio.consortia.support.EntityUtils.createConsortiaConfiguration;
+import static org.folio.consortia.support.EntityUtils.createOkapiHeaders;
import static org.folio.consortia.support.EntityUtils.createTenant;
import static org.folio.consortia.support.EntityUtils.createTenantDetailsEntity;
import static org.folio.consortia.support.EntityUtils.createTenantEntity;
@@ -19,8 +21,18 @@
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
import org.folio.consortia.client.ConsortiaConfigurationClient;
import org.folio.consortia.client.PermissionsClient;
import org.folio.consortia.client.SyncPrimaryAffiliationClient;
@@ -30,6 +42,10 @@
import org.folio.consortia.config.kafka.KafkaService;
import org.folio.consortia.domain.dto.PermissionUser;
import org.folio.consortia.domain.dto.PermissionUserCollection;
+import org.folio.consortia.domain.dto.Tenant;
+import org.folio.consortia.domain.dto.TenantDetails;
+import org.folio.consortia.domain.dto.User;
+import org.folio.consortia.domain.dto.UserCollection;
import org.folio.consortia.domain.entity.TenantDetailsEntity;
import org.folio.consortia.domain.entity.TenantEntity;
import org.folio.consortia.exception.ResourceAlreadyExistException;
@@ -39,27 +55,16 @@
import org.folio.consortia.repository.TenantRepository;
import org.folio.consortia.repository.UserTenantRepository;
import org.folio.consortia.service.impl.TenantServiceImpl;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.UUID;
-
-import org.folio.consortia.domain.dto.Tenant;
-import org.folio.consortia.domain.dto.TenantDetails;
-import org.folio.consortia.domain.dto.User;
-import org.folio.consortia.domain.dto.UserCollection;
import org.folio.spring.FolioExecutionContext;
import org.folio.spring.FolioModuleMetadata;
+import org.folio.spring.context.ExecutionContextBuilder;
+import org.folio.spring.data.OffsetRequest;
import org.folio.spring.integration.XOkapiHeaders;
import org.folio.spring.service.SystemUserScopedExecutionService;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration;
@@ -67,10 +72,6 @@
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.PageRequest;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
@SpringBootTest
@EnableAutoConfiguration(exclude = BatchAutoConfiguration.class)
@@ -78,7 +79,7 @@
class TenantServiceTest {
private final static String CONSORTIUM_ID = "7698e46-c3e3-11ed-afa1-0242ac120002";
- private static final String CENTRAL_TENANT_ID = "diku";
+
@InjectMocks
private TenantServiceImpl tenantService;
@Mock
@@ -96,7 +97,8 @@ class TenantServiceTest {
@Mock
private ConsortiumService consortiumService;
@Mock
- private FolioExecutionContext folioExecutionContext = new FolioExecutionContext() {};
+ private FolioExecutionContext folioExecutionContext = new FolioExecutionContext() {
+ };
@Mock
private ConsortiaConfigurationClient configurationClient;
@Mock
@@ -127,6 +129,8 @@ class TenantServiceTest {
private SystemUserScopedExecutionService systemUserScopedExecutionService;
@Mock
private LockService lockService;
+ @Mock
+ private ExecutionContextBuilder executionContextBuilder;
@Test
void shouldGetTenantList() {
@@ -141,11 +145,11 @@ void shouldGetTenantList() {
when(consortiumRepository.existsById(consortiumId)).thenReturn(true);
when(tenantRepository.existsById(any())).thenReturn(true);
- when(tenantRepository.findByConsortiumId(any(), any(PageRequest.of(offset, limit).getClass())))
- .thenReturn(new PageImpl<>(tenantEntityList, PageRequest.of(offset, limit), tenantEntityList.size()));
+ when(tenantRepository.findByConsortiumId(any(), any(OffsetRequest.of(offset, limit).getClass())))
+ .thenReturn(new PageImpl<>(tenantEntityList, OffsetRequest.of(offset, limit), tenantEntityList.size()));
var tenantCollection = tenantService.get(consortiumId, 0, 10);
- Assertions.assertEquals(2, tenantCollection.getTotalRecords());
+ assertEquals(2, tenantCollection.getTotalRecords());
}
@Test
@@ -162,7 +166,7 @@ void shouldGetAllTenantList() {
when(tenantRepository.findByConsortiumId(consortiumId)).thenReturn(tenantEntityList);
var allTenants = tenantService.getAll(consortiumId);
- Assertions.assertEquals(2, allTenants.getTotalRecords());
+ assertEquals(2, allTenants.getTotalRecords());
}
@Test
@@ -188,12 +192,12 @@ void shouldSaveNotCentralTenantWithNewUserAndPermissions() {
when(tenantRepository.existsById(any())).thenReturn(false);
when(tenantRepository.findCentralTenant()).thenReturn(Optional.of(centralTenant));
when(tenantDetailsRepository.save(any(TenantDetailsEntity.class))).thenReturn(localTenantDetailsEntity);
- doNothing().when(configurationClient).saveConfiguration(createConsortiaConfiguration(CENTRAL_TENANT_ID));
+ doNothing().when(configurationClient).saveConfiguration(createConsortiaConfiguration(TENANT_ID));
doNothing().when(userTenantsClient).postUserTenant(any());
when(conversionService.convert(localTenantDetailsEntity, Tenant.class)).thenReturn(tenant);
doAnswer(TenantServiceTest::runSecondArgument)
.when(systemUserScopedExecutionService).executeAsyncSystemUserScoped(anyString(), any());
- when(folioExecutionContext.getTenantId()).thenReturn("diku");
+ when(folioExecutionContext.getTenantId()).thenReturn(TENANT_ID);
var tenant1 = tenantService.save(consortiumId, UUID.fromString(adminUser.getId()), tenant);
@@ -206,7 +210,7 @@ void shouldSaveNotCentralTenantWithNewUserAndPermissions() {
verify(userService, times(1)).getByUsername(any());
verify(lockService).lockTenantSetupWithinTransaction();
- Assertions.assertEquals(tenant, tenant1);
+ assertEquals(tenant, tenant1);
}
@Test
@@ -214,7 +218,7 @@ void shouldSaveCentralTenantWithExistingAndPermissions() throws JsonProcessingEx
UUID consortiumId = UUID.fromString(CONSORTIUM_ID);
TenantDetailsEntity tenantDetailsEntity = createTenantDetailsEntity("ABC1", "TestName1");
Tenant tenant = createTenant("TestID", "Test", true);
- TenantEntity centralTenant = createTenantEntity("diku", "diku");
+ TenantEntity centralTenant = createTenantEntity(TENANT_ID);
PermissionUser permissionUser = new PermissionUser();
permissionUser.setPermissions(List.of("users.collection.get"));
PermissionUserCollection permissionUserCollection = new PermissionUserCollection();
@@ -231,7 +235,7 @@ void shouldSaveCentralTenantWithExistingAndPermissions() throws JsonProcessingEx
when(tenantRepository.existsById(any())).thenReturn(false);
when(tenantRepository.findCentralTenant()).thenReturn(Optional.of(centralTenant));
when(tenantDetailsRepository.save(any(TenantDetailsEntity.class))).thenReturn(tenantDetailsEntity);
- doNothing().when(configurationClient).saveConfiguration(createConsortiaConfiguration(CENTRAL_TENANT_ID));
+ doNothing().when(configurationClient).saveConfiguration(createConsortiaConfiguration(TENANT_ID));
doNothing().when(userTenantsClient).postUserTenant(any());
when(conversionService.convert(tenantDetailsEntity, Tenant.class)).thenReturn(tenant);
doAnswer(TenantServiceTest::runSecondArgument)
@@ -241,6 +245,8 @@ void shouldSaveCentralTenantWithExistingAndPermissions() throws JsonProcessingEx
okapiHeaders.put(XOkapiHeaders.TENANT, List.of("diku"));
when(folioExecutionContext.getOkapiHeaders()).thenReturn(okapiHeaders);
when(usersClient.getUserCollection(anyString(), anyInt(), anyInt())).thenReturn(userCollection);
+ doReturn(folioExecutionContext).when(executionContextBuilder).buildContext(anyString());
+ mockOkapiHeaders();
var tenant1 = tenantService.save(consortiumId, UUID.randomUUID(), tenant);
@@ -253,24 +259,54 @@ void shouldSaveCentralTenantWithExistingAndPermissions() throws JsonProcessingEx
verify(userService, never()).createUser(any());
verify(permissionUserService, never()).createWithPermissionsFromFile(any(), any());
- Assertions.assertEquals(tenant, tenant1);
+ assertEquals(tenant, tenant1);
}
+ @Test
+ void shouldReAddSoftDeletedTenant() {
+ UUID consortiumId = UUID.fromString(CONSORTIUM_ID);
+ Tenant newTenant = createTenant("TestID", "Test", false);
+ TenantEntity existedTenant = createTenantEntity("TestID");
+ existedTenant.setIsDeleted(true);
+ TenantDetailsEntity savedTenantDetailsEntity = createTenantDetailsEntity("ABC1", "TestName1");
+
+ TenantEntity centralTenant = createTenantEntity(TENANT_ID);
+ when(consortiumRepository.existsById(consortiumId)).thenReturn(true);
+ when(tenantRepository.findById(newTenant.getId())).thenReturn(Optional.of(existedTenant));
+ when(tenantRepository.findCentralTenant()).thenReturn(Optional.of(centralTenant));
+ when(tenantDetailsRepository.save(any(TenantDetailsEntity.class))).thenReturn(savedTenantDetailsEntity);
+ doNothing().when(tenantDetailsRepository).setSetupStatusByTenantId(TenantDetails.SetupStatusEnum.COMPLETED, newTenant.getId());
+ doNothing().when(userTenantsClient).postUserTenant(any());
+ doNothing().when(userTenantsClient).postUserTenant(any());
+ when(conversionService.convert(savedTenantDetailsEntity, Tenant.class)).thenReturn(newTenant);
+ doReturn(folioExecutionContext).when(executionContextBuilder).buildContext(anyString());
+ mockOkapiHeaders();
+
+ var actualTenant = tenantService.save(consortiumId, UUID.randomUUID(), newTenant);
+
+ verifyNoInteractions(configurationClient);
+ verifyNoInteractions(lockService);
+
+ verifyNoInteractions(userService);
+ verifyNoInteractions(userTenantRepository);
+ verify(userTenantsClient).postUserTenant(any());
+ verifyNoInteractions(userService);
+ verifyNoInteractions(permissionUserService);
+
+ assertEquals(newTenant, actualTenant);
+ }
@Test
void shouldUpdateTenant() {
UUID consortiumId = UUID.randomUUID();
- TenantEntity tenantEntity1 = createTenantEntity("TestID", "TestName1");
+ TenantEntity existingTenant = createTenantEntity("TestID", "TestName1");
Tenant tenant = createTenant("TestID", "TestName2");
- Map> okapiHeaders = new HashMap<>();
- okapiHeaders.put(XOkapiHeaders.TENANT, List.of("diku"));
- when(folioExecutionContext.getOkapiHeaders()).thenReturn(okapiHeaders);
-
when(consortiumRepository.existsById(consortiumId)).thenReturn(true);
- when(tenantRepository.existsById(any())).thenReturn(true);
- when(tenantRepository.save(any(TenantEntity.class))).thenReturn(tenantEntity1);
- when(conversionService.convert(tenantEntity1, Tenant.class)).thenReturn(tenant);
+ when(tenantRepository.findById(any())).thenReturn(Optional.of(existingTenant));
+ when(tenantRepository.save(any(TenantEntity.class))).thenReturn(existingTenant);
+ when(conversionService.convert(existingTenant, Tenant.class)).thenReturn(tenant);
+ mockOkapiHeaders();
var tenant1 = tenantService.update(UUID.fromString(CONSORTIUM_ID), tenant.getId(), tenant);
Assertions.assertEquals(tenant.getId(), tenant1.getId());
@@ -280,48 +316,62 @@ void shouldUpdateTenant() {
@Test
void shouldDeleteTenant() {
UUID consortiumId = UUID.randomUUID();
- String tenantId = "diku";
+ var tenant = createTenantEntity(TENANT_ID);
+ var deletingTenant = createTenantEntity(TENANT_ID);
+ deletingTenant.setIsDeleted(true);
doNothing().when(consortiumService).checkConsortiumExistsOrThrow(consortiumId);
- when(tenantRepository.existsById(any())).thenReturn(true);
doNothing().when(cleanupService).clearPublicationTables();
- doNothing().when(tenantRepository).deleteById(tenantId);
+ doReturn(deletingTenant).when(tenantRepository).save(deletingTenant);
+ when(tenantRepository.findById(tenant.getId())).thenReturn(Optional.of(tenant));
+ doReturn(folioExecutionContext).when(executionContextBuilder).buildContext(anyString());
+ mockOkapiHeaders();
- tenantService.delete(consortiumId, tenantId);
+ tenantService.delete(consortiumId, TENANT_ID);
// Assert
- Mockito.verify(consortiumService).checkConsortiumExistsOrThrow(consortiumId);
- Mockito.verify(tenantRepository).existsById(tenantId);
- Mockito.verify(tenantRepository).deleteById(tenantId);
+ verify(consortiumService).checkConsortiumExistsOrThrow(consortiumId);
+ verify(tenantRepository).findById(TENANT_ID);
+ verify(tenantRepository).save(deletingTenant);
+ verify(cleanupService).clearPublicationTables();
+ verify(userTenantsClient).deleteUserTenants();
}
- @Test()
- void testDeleteWithAssociation() {
+ @Test
+ void testDeleteNonexistentTenant() {
UUID consortiumId = UUID.randomUUID();
String tenantId = "123";
// Mock repository method calls
- Mockito.when(tenantRepository.existsById(tenantId)).thenReturn(true);
- Mockito.when(userTenantRepository.existsByTenantId(tenantId)).thenReturn(true);
+ when(tenantRepository.existsById(tenantId)).thenReturn(false);
// Call the method
- assertThrows(IllegalArgumentException.class, () ->
+ assertThrows(ResourceNotFoundException.class, () ->
tenantService.delete(consortiumId, tenantId));
}
@Test
- void testDeleteNonexistentTenant() {
+ void shouldThrowErrorWhenDeletingCentralTenant() {
UUID consortiumId = UUID.randomUUID();
- String tenantId = "123";
+ var tenant = createTenantEntity(TENANT_ID);
+ tenant.setIsCentral(true);
+ var deletingTenant = createTenantEntity(TENANT_ID);
+ deletingTenant.setIsDeleted(true);
- // Mock repository method calls
- when(tenantRepository.existsById(tenantId)).thenReturn(false);
+ doNothing().when(consortiumService).checkConsortiumExistsOrThrow(consortiumId);
+ when(tenantRepository.findById(tenant.getId())).thenReturn(Optional.of(tenant));
- // Call the method
- assertThrows(ResourceNotFoundException.class, () ->
- tenantService.delete(consortiumId, tenantId));
+ // Assert
+ assertThrows(java.lang.IllegalArgumentException.class, () ->
+ tenantService.delete(consortiumId, TENANT_ID));
+
+ verify(consortiumService).checkConsortiumExistsOrThrow(consortiumId);
+ verify(tenantRepository).findById(TENANT_ID);
+ verifyNoInteractions(cleanupService);
+ verifyNoInteractions(userTenantsClient);
}
+
@Test
void shouldThrowExceptionWhileSavingLocalTenantWithoutAdminUserId() {
TenantDetailsEntity tenantDetailsEntity = createTenantDetailsEntity("TestID", "TestName1");
@@ -344,7 +394,7 @@ void shouldThrowExceptionWhileSavingWithDuplicateCodeOrName() {
when(consortiumRepository.existsById(any())).thenReturn(true);
when(tenantRepository.existsById(any())).thenReturn(false);
when(tenantRepository.save(any(TenantEntity.class))).thenReturn(tenantEntity1);
- when(tenantRepository.existsByCode(any())).thenReturn(true);
+ when(tenantRepository.existsByCodeForOtherTenant(anyString(), anyString())).thenReturn(true);
when(conversionService.convert(tenantEntity1, Tenant.class)).thenReturn(tenant);
assertThrows(ResourceAlreadyExistException.class, () ->
@@ -353,13 +403,11 @@ void shouldThrowExceptionWhileSavingWithDuplicateCodeOrName() {
@Test
void shouldThrowExceptionWhileUpdateTenant() {
- TenantEntity tenantEntity1 = createTenantEntity("TestID", "TestName1");
- Tenant tenant = createTenant("TestID", "TestName2");
+ var existingTenant = createTenantEntity("TestID", "TestName1");
+ var tenant = createTenant("TestID", "TestName2");
when(consortiumRepository.existsById(any())).thenReturn(true);
- when(tenantRepository.existsById(any())).thenReturn(true);
- when(tenantRepository.save(any(TenantEntity.class))).thenReturn(tenantEntity1);
- when(conversionService.convert(tenantEntity1, Tenant.class)).thenReturn(tenant);
+ when(tenantRepository.findById(tenant.getId() + "1234")).thenReturn(Optional.of(existingTenant));
assertThrows(java.lang.IllegalArgumentException.class, () ->
tenantService.update(UUID.fromString(CONSORTIUM_ID), tenant.getId() + "1234", tenant));
@@ -371,7 +419,6 @@ void shouldThrowNotFoundExceptionWhileUpdateTenant() {
Tenant tenant = createTenant("TestID", "TestName2");
when(consortiumRepository.existsById(any())).thenReturn(true);
- when(tenantRepository.save(any(TenantEntity.class))).thenReturn(tenantEntity1);
when(conversionService.convert(tenantEntity1, Tenant.class)).thenReturn(tenant);
assertThrows(ResourceNotFoundException.class, () ->
@@ -379,31 +426,25 @@ void shouldThrowNotFoundExceptionWhileUpdateTenant() {
}
@Test
- void shouldThrowResourceAlreadyExistExceptionWhileSavingCentralTenant() {
+ void shouldNotSaveExistingTenant() {
UUID consortiumId = UUID.fromString(CONSORTIUM_ID);
- Tenant tenant = createTenant("TestID", "Test", true);
+ Tenant tenant = createTenant("TestID", "Test");
+ TenantEntity existedTenant = createTenantEntity("TestId");
when(consortiumRepository.existsById(consortiumId)).thenReturn(true);
- when(tenantRepository.existsById(any())).thenReturn(false);
- when(tenantRepository.existsByIsCentralTrue()).thenReturn(true);
+ when(tenantRepository.findById(tenant.getId())).thenReturn(Optional.of(existedTenant));
assertThrows(ResourceAlreadyExistException.class,
() -> tenantService.save(UUID.fromString(CONSORTIUM_ID), null, tenant));
}
@Test
- void shouldNotSaveTenantForDuplicateId() {
- TenantEntity tenantEntity1 = createTenantEntity("TestID", "Test");
+ void shouldNotSaveDuplicateCentralTenant() {
Tenant tenant = createTenant("TestID", "Testq", true);
- TenantEntity centralTenant = createTenantEntity("diku", "diku");
- when(tenantRepository.existsById(any())).thenReturn(true);
- when(conversionService.convert(tenantEntity1, Tenant.class)).thenReturn(tenant);
- when(tenantRepository.findCentralTenant()).thenReturn(Optional.of(centralTenant));
- when(folioExecutionContext.getTenantId()).thenReturn("diku");
- Map> okapiHeaders = new HashMap<>();
- okapiHeaders.put(XOkapiHeaders.TENANT, List.of("diku"));
- when(folioExecutionContext.getOkapiHeaders()).thenReturn(okapiHeaders);
+ when(consortiumRepository.existsById(UUID.fromString(CONSORTIUM_ID))).thenReturn(true);
+ when(tenantRepository.existsByIsCentralTrue()).thenReturn(true);
+ mockOkapiHeaders();
assertThrows(ResourceAlreadyExistException.class, () ->
tenantService.save(UUID.fromString(CONSORTIUM_ID), null, tenant));
@@ -426,29 +467,33 @@ void shouldNotRetrieveEntityByTenantId() {
@Test
void shouldGetTenantDetails() {
UUID consortiumId = UUID.randomUUID();
- String tenantId = "diku";
var tenantDetailsEntity = new TenantDetailsEntity();
var tenantDetailsExpected = new TenantDetails();
when(consortiumRepository.existsById(consortiumId)).thenReturn(true);
- when(tenantDetailsRepository.findById(tenantId)).thenReturn(Optional.of(tenantDetailsEntity));
+ when(tenantDetailsRepository.findById(TENANT_ID)).thenReturn(Optional.of(tenantDetailsEntity));
when(conversionService.convert(tenantDetailsEntity, TenantDetails.class)).thenReturn(tenantDetailsExpected);
- var tenantDetails = tenantService.getTenantDetailsById(consortiumId, tenantId);
+ var tenantDetails = tenantService.getTenantDetailsById(consortiumId, TENANT_ID);
assertEquals(tenantDetailsExpected, tenantDetails);
}
@Test
void testGetTenantDetailsNonExistingTenant() {
UUID consortiumId = UUID.randomUUID();
- String tenantId = "123";
when(consortiumRepository.existsById(consortiumId)).thenReturn(true);
- when(tenantDetailsRepository.findById(tenantId)).thenReturn(Optional.empty());
+ when(tenantDetailsRepository.findById(TENANT_ID)).thenReturn(Optional.empty());
assertThrows(ResourceNotFoundException.class, () ->
- tenantService.getTenantDetailsById(consortiumId, tenantId));
+ tenantService.getTenantDetailsById(consortiumId, TENANT_ID));
+ }
+
+ private void mockOkapiHeaders() {
+ when(folioExecutionContext.getTenantId()).thenReturn("diku");
+ Map> okapiHeaders = createOkapiHeaders();
+ when(folioExecutionContext.getOkapiHeaders()).thenReturn(okapiHeaders);
}
private static Object runSecondArgument(InvocationOnMock invocation) {
diff --git a/src/test/java/org/folio/consortia/service/UserAffiliationServiceTest.java b/src/test/java/org/folio/consortia/service/UserAffiliationServiceTest.java
index e3c39726..72f29cfc 100644
--- a/src/test/java/org/folio/consortia/service/UserAffiliationServiceTest.java
+++ b/src/test/java/org/folio/consortia/service/UserAffiliationServiceTest.java
@@ -1,9 +1,9 @@
package org.folio.consortia.service;
+import static org.folio.consortia.support.EntityUtils.createOkapiHeaders;
import static org.folio.consortia.support.EntityUtils.createTenantEntity;
import static org.folio.consortia.utils.InputOutputTestUtils.getMockDataAsString;
import static org.folio.spring.integration.XOkapiHeaders.TENANT;
-import static org.folio.spring.integration.XOkapiHeaders.TOKEN;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
@@ -15,20 +15,14 @@
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
+import java.util.UUID;
import org.folio.consortia.config.kafka.KafkaService;
+import org.folio.consortia.domain.dto.PrimaryAffiliationEvent;
import org.folio.consortia.domain.entity.UserTenantEntity;
import org.folio.consortia.repository.TenantRepository;
import org.folio.consortia.service.impl.UserAffiliationServiceImpl;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import org.folio.consortia.domain.dto.PrimaryAffiliationEvent;
import org.folio.spring.FolioExecutionContext;
import org.folio.spring.FolioModuleMetadata;
-import org.folio.spring.integration.XOkapiHeaders;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -259,15 +253,6 @@ void deletePrimaryAffiliationNotParsed() {
private void mockOkapiHeaders() {
when(folioExecutionContext.getTenantId()).thenReturn("diku");
- Map> okapiHeaders = createOkapiHeaders();
- when(folioExecutionContext.getOkapiHeaders()).thenReturn(okapiHeaders);
- }
-
- private Map> createOkapiHeaders() {
- Map> map = new HashMap<>();
- map.put(TENANT, List.of(TENANT));
- map.put(TOKEN, List.of(TOKEN));
- map.put(XOkapiHeaders.USER_ID, List.of(UUID.randomUUID().toString()));
- return map;
+ when(folioExecutionContext.getOkapiHeaders()).thenReturn(createOkapiHeaders());
}
}
diff --git a/src/test/java/org/folio/consortia/service/UserServiceTest.java b/src/test/java/org/folio/consortia/service/UserServiceTest.java
index f28916bd..704f22cc 100644
--- a/src/test/java/org/folio/consortia/service/UserServiceTest.java
+++ b/src/test/java/org/folio/consortia/service/UserServiceTest.java
@@ -1,23 +1,24 @@
package org.folio.consortia.service;
+import static org.folio.consortia.support.EntityUtils.createOkapiHeaders;
import static org.folio.consortia.support.EntityUtils.createUserEntity;
+import static org.junit.Assert.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
-import org.folio.consortia.client.UsersKeycloakClient;
-import org.folio.consortia.domain.dto.UserType;
-import org.folio.consortia.exception.ResourceNotFoundException;
-import org.folio.consortia.service.impl.UserServiceImpl;
import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.UUID;
-
+import org.folio.consortia.client.UsersKeycloakClient;
import org.folio.consortia.domain.dto.User;
+import org.folio.consortia.domain.dto.UserType;
+import org.folio.consortia.service.impl.UserServiceImpl;
import org.folio.spring.FolioExecutionContext;
import org.folio.spring.FolioModuleMetadata;
-import org.folio.spring.integration.XOkapiHeaders;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
@@ -45,39 +46,52 @@ void shouldCreateUser() {
User user = createUserEntity(false);
Mockito.doNothing().when(usersKeycloakClient).saveUser(user);
User createdUser = userService.createUser(user);
- Assertions.assertEquals(user, createdUser);
+ assertEquals(user, createdUser);
}
@Test
void shouldUpdateUser() {
User user = createUserEntity(false);
- Mockito.doNothing().when(usersKeycloakClient).updateUser(user.getId(), user);
- Assertions.assertDoesNotThrow(() -> userService.updateUser(user));
+ doNothing().when(usersKeycloakClient).updateUser(user.getId(), user);
+ assertDoesNotThrow(() -> userService.updateUser(user));
}
@Test
void shouldDeleteUser() {
User user = createUserEntity(false);
- Mockito.doNothing().when(usersKeycloakClient).deleteUser(user.getId());
- Assertions.assertDoesNotThrow(() -> userService.deleteById(user.getId()));
+ doNothing().when(usersKeycloakClient).deleteUser(user.getId());
+ assertDoesNotThrow(() -> userService.deleteById(user.getId()));
}
@Test
void shouldThrowNotFoundWhilePrepareShadowUser() {
- when(folioExecutionContext.getTenantId()).thenReturn("diku");
- Map> okapiHeaders = new HashMap<>();
- okapiHeaders.put(XOkapiHeaders.TENANT, List.of("diku"));
- when(folioExecutionContext.getOkapiHeaders()).thenReturn(okapiHeaders);
- Mockito.when(usersKeycloakClient.getUsersByUserId(any())).thenReturn(new User());
- Assertions.assertThrows(ResourceNotFoundException.class, () -> userService.prepareShadowUser(UUID.randomUUID(), ""));
+ mockOkapiHeaders();
+ when(usersKeycloakClient.getUsersByUserId(any())).thenReturn(new User());
+
+ assertThrows(org.folio.consortia.exception.ResourceNotFoundException.class,
+ () -> userService.prepareShadowUser(UUID.randomUUID(), ""));
}
@Test
void shouldPrepareShadowUser() {
+ when(usersKeycloakClient.getUsersByUserId(any())).thenReturn(createUserEntity(true));
+ mockOkapiHeaders();
+
+ User shadow = userService.prepareShadowUser(UUID.randomUUID(), "diku");
+
+ assertEquals(UserType.SHADOW.getName(), shadow.getType());
+ assertEquals("diku", shadow.getCustomFields().get("originaltenantid"));
+ assertEquals(true, shadow.getActive());
+ assertEquals("testFirst", shadow.getPersonal().getFirstName());
+ assertEquals("testLast", shadow.getPersonal().getLastName());
+ assertEquals("Test@mail.com", shadow.getPersonal().getEmail());
+ assertEquals("email", shadow.getPersonal().getPreferredContactTypeId());
+ assertNull(shadow.getBarcode());
+ }
+
+ private void mockOkapiHeaders() {
when(folioExecutionContext.getTenantId()).thenReturn("diku");
- when(folioExecutionContext.getFolioModuleMetadata()).thenReturn(folioModuleMetadata);
- Map> okapiHeaders = new HashMap<>();
- okapiHeaders.put(XOkapiHeaders.TENANT, List.of("diku"));
+ Map> okapiHeaders = createOkapiHeaders();
when(folioExecutionContext.getOkapiHeaders()).thenReturn(okapiHeaders);
Mockito.when(usersKeycloakClient.getUsersByUserId(any())).thenReturn(createUserEntity(true));
User user = userService.prepareShadowUser(UUID.randomUUID(), "diku");
@@ -87,5 +101,4 @@ void shouldPrepareShadowUser() {
Assertions.assertEquals("testFirst", user.getPersonal().getFirstName());
Assertions.assertEquals("testLast", user.getPersonal().getLastName());
}
-
}
diff --git a/src/test/java/org/folio/consortia/service/UserTenantServiceTest.java b/src/test/java/org/folio/consortia/service/UserTenantServiceTest.java
index ab7b4527..b6ec59be 100644
--- a/src/test/java/org/folio/consortia/service/UserTenantServiceTest.java
+++ b/src/test/java/org/folio/consortia/service/UserTenantServiceTest.java
@@ -45,6 +45,7 @@
import org.folio.consortia.service.impl.UserTenantServiceImpl;
import org.folio.spring.FolioExecutionContext;
import org.folio.spring.FolioModuleMetadata;
+import org.folio.spring.data.OffsetRequest;
import org.folio.spring.integration.XOkapiHeaders;
import org.folio.spring.service.SystemUserScopedExecutionService;
import org.junit.jupiter.api.Assertions;
@@ -62,7 +63,6 @@
import org.springframework.core.convert.ConversionService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.PageRequest;
@SpringBootTest
@EnableAutoConfiguration(exclude = BatchAutoConfiguration.class)
@@ -103,10 +103,10 @@ class UserTenantServiceTest {
void shouldGetUserTenantList() {
// given
List userTenantEntities = List.of(new UserTenantEntity(), new UserTenantEntity());
- Page userTenantPage = new PageImpl<>(userTenantEntities, PageRequest.of(0, 10), userTenantEntities.size());
+ Page userTenantPage = new PageImpl<>(userTenantEntities, OffsetRequest.of(0, 10), userTenantEntities.size());
when(consortiumRepository.findById(UUID.fromString(CONSORTIUM_ID))).thenReturn(Optional.of(createConsortiumEntity()));
- when(userTenantRepository.findAll(PageRequest.of(0, 10))).thenReturn(userTenantPage);
+ when(userTenantRepository.getAll(OffsetRequest.of(0, 10))).thenReturn(userTenantPage);
// when
var result = userTenantService.get(UUID.fromString(CONSORTIUM_ID), 0, 10);
@@ -151,7 +151,8 @@ void shouldGetUserTenantListByUserId() {
when(consortiumRepository.findById(UUID.fromString(CONSORTIUM_ID))).thenReturn(Optional.of(createConsortiumEntity()));
when(conversionService.convert(userTenant, UserTenant.class)).thenReturn(toDto(userTenant));
when(conversionService.convert(userTenant2, UserTenant.class)).thenReturn(toDto(userTenant2));
- when(userTenantRepository.findByUserId(userId, PageRequest.of(0, 10))).thenReturn(new PageImpl<>(userTenantEntities, PageRequest.of(0, 10), userTenantEntities.size()));
+ when(userTenantRepository.findByUserId(userId, OffsetRequest.of(0, 10)))
+ .thenReturn(new PageImpl<>(userTenantEntities, OffsetRequest.of(0, 10), userTenantEntities.size()));
// when
UserTenantCollection result = userTenantService.getByUserId(UUID.fromString(CONSORTIUM_ID), userId, 0, 10);
@@ -443,7 +444,7 @@ void shouldReturn404UserIdNotFoundException() {
UUID userId = UUID.randomUUID();
when(consortiumRepository.findById(UUID.fromString(CONSORTIUM_ID))).thenReturn(Optional.of(createConsortiumEntity()));
- when(userTenantRepository.findByUserId(userId, PageRequest.of(0, 10))).thenReturn(new PageImpl<>(new ArrayList<>()));
+ when(userTenantRepository.findByUserId(userId, OffsetRequest.of(0, 10))).thenReturn(new PageImpl<>(new ArrayList<>()));
UUID id = UUID.fromString(CONSORTIUM_ID);
// throw exception
@@ -575,7 +576,8 @@ void shouldThrowIllegalStateExceptionFromUserClient(String username) {
when(userService.getById(any())).thenThrow(java.lang.IllegalStateException.class);
mockOkapiHeaders();
- assertThrows(java.lang.IllegalStateException.class, () -> userTenantService.save(UUID.fromString(CONSORTIUM_ID), tenant, false));
+ assertThrows(java.lang.IllegalStateException.class,
+ () -> userTenantService.save(UUID.fromString(CONSORTIUM_ID), tenant, false));
}
@Test
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 270d556f..5a7bf0a5 100644
--- a/src/test/java/org/folio/consortia/service/impl/SyncPrimaryAffiliationServiceImplTest.java
+++ b/src/test/java/org/folio/consortia/service/impl/SyncPrimaryAffiliationServiceImplTest.java
@@ -94,7 +94,7 @@ void createPrimaryUserAffiliationsWhenCentralTenantSaving() throws JsonProcessin
// stub collection of 2 users
when(tenantService.getByTenantId(anyString())).thenReturn(tenantEntity1);
- when(userTenantRepository.findByUserId(any(), any())).thenReturn(new PageImpl<>(Collections.emptyList()));
+ 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(consortiaConfigurationService.getCentralTenantId(anyString())).thenReturn(tenantId);
@@ -125,7 +125,7 @@ void createPrimaryUserAffiliationsWhenLocalTenantSaving() throws JsonProcessingE
// stub collection of 2 users
when(tenantService.getByTenantId(anyString())).thenReturn(tenantEntity1);
- when(userTenantRepository.findByUserId(any(), any())).thenReturn(new PageImpl<>(Collections.emptyList()));
+ 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(consortiaConfigurationService.getCentralTenantId(anyString())).thenReturn(centralTenantId);
@@ -222,7 +222,7 @@ void createPrimaryAffiliationsException() {
}
@Test
- void createPrimaryAffiliationsPartialFailure() throws JsonProcessingException {
+ void createPrimaryAffiliationsPartialFailure() {
var consortiumId = UUID.randomUUID();
var tenantId = "ABC1";
var centralTenantId = "diku";
diff --git a/src/test/java/org/folio/consortia/support/EntityUtils.java b/src/test/java/org/folio/consortia/support/EntityUtils.java
index bd25f793..2839f834 100644
--- a/src/test/java/org/folio/consortia/support/EntityUtils.java
+++ b/src/test/java/org/folio/consortia/support/EntityUtils.java
@@ -1,10 +1,14 @@
package org.folio.consortia.support;
+import static org.folio.spring.integration.XOkapiHeaders.TENANT;
+import static org.folio.spring.integration.XOkapiHeaders.TOKEN;
+
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.time.LocalDateTime;
+import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -36,10 +40,15 @@
import org.folio.consortia.domain.entity.TenantDetailsEntity;
import org.folio.consortia.domain.entity.TenantEntity;
import org.folio.consortia.domain.entity.UserTenantEntity;
+import org.folio.spring.integration.XOkapiHeaders;
import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils;
@UtilityClass
public class EntityUtils {
+ public static final UUID ACTION_ID = UUID.fromString("dcfc317b-0d7c-4334-8656-596105fa6c99");
+ public static final UUID INSTANCE_ID = UUID.fromString("111841e3-e6fb-4191-8fd8-5674a5107c33");
+ public static final String CENTRAL_TENANT_ID = "consortium";
+ public static final String TENANT_ID = "diku";
public static ConsortiumEntity createConsortiumEntity(String id, String name) {
ConsortiumEntity consortiumEntity = new ConsortiumEntity();
@@ -62,6 +71,7 @@ public static TenantEntity createTenantEntity(String id, String name, String cod
tenantEntity.setName(name);
tenantEntity.setIsCentral(isCentral);
tenantEntity.setConsortiumId(UUID.randomUUID());
+ tenantEntity.setIsDeleted(false);
return tenantEntity;
}
@@ -72,6 +82,7 @@ public static TenantEntity createTenantEntity() {
tenantEntity.setName("testtenant1");
tenantEntity.setIsCentral(false);
tenantEntity.setConsortiumId(UUID.randomUUID());
+ tenantEntity.setIsDeleted(false);
return tenantEntity;
}
@@ -81,6 +92,17 @@ public static TenantEntity createTenantEntity(String id, String name) {
tenantEntity.setCode("ABC");
tenantEntity.setName(name);
tenantEntity.setIsCentral(false);
+ tenantEntity.setIsDeleted(false);
+ return tenantEntity;
+ }
+
+ public static TenantEntity createTenantEntity(String id) {
+ TenantEntity tenantEntity = new TenantEntity();
+ tenantEntity.setId(id);
+ tenantEntity.setCode("ABC");
+ tenantEntity.setName(id);
+ tenantEntity.setIsCentral(false);
+ tenantEntity.setIsDeleted(false);
return tenantEntity;
}
@@ -90,6 +112,7 @@ public static TenantDetailsEntity createTenantDetailsEntity() {
tenantDetailsEntity.setCode("ABC");
tenantDetailsEntity.setName("testtenant1");
tenantDetailsEntity.setIsCentral(false);
+ tenantDetailsEntity.setIsDeleted(false);
tenantDetailsEntity.setConsortiumId(UUID.randomUUID());
tenantDetailsEntity.setSetupStatus(SetupStatusEnum.COMPLETED);
return tenantDetailsEntity;
@@ -101,6 +124,7 @@ public static TenantDetailsEntity createTenantDetailsEntity(String id, String na
tenantDetailsEntity.setCode("ABC");
tenantDetailsEntity.setName(name);
tenantDetailsEntity.setIsCentral(false);
+ tenantDetailsEntity.setIsDeleted(false);
tenantDetailsEntity.setSetupStatus(SetupStatusEnum.IN_PROGRESS);
return tenantDetailsEntity;
}
@@ -111,6 +135,7 @@ public static Tenant createTenant(String id, String name) {
tenant.setName(name);
tenant.setIsCentral(false);
tenant.setCode("ABC");
+ tenant.setIsDeleted(false);
return tenant;
}
@@ -119,6 +144,7 @@ public static Tenant createTenant(String id, String name, boolean isCentral) {
tenant.setId(id);
tenant.setName(name);
tenant.setIsCentral(isCentral);
+ tenant.setIsDeleted(false);
tenant.setCode("ABC");
return tenant;
}
@@ -297,6 +323,10 @@ public static User createUser(String username) {
return new User().id(UUID.randomUUID().toString()).username(username);
}
+ public static User createUser(UUID id, String username) {
+ return new User().id(id.toString()).username(username);
+ }
+
public static User createUserEntity(Boolean updateble) {
User user = new User();
Personal personal = new Personal();
@@ -309,6 +339,7 @@ public static User createUserEntity(Boolean updateble) {
user.setUsername("xyz");
user.setPersonal(personal);
user.setActive(Boolean.FALSE.equals(updateble));
+ user.setBarcode("0420690");
return user;
}
@@ -326,4 +357,12 @@ public static User createUserEntity(UUID userId) {
user.setActive(true);
return user;
}
+
+ public static Map> createOkapiHeaders() {
+ Map> map = new HashMap<>();
+ map.put(TENANT, List.of("diku"));
+ map.put(TOKEN, List.of(TOKEN));
+ map.put(XOkapiHeaders.USER_ID, List.of(UUID.randomUUID().toString()));
+ return map;
+ }
}
diff --git a/src/test/java/org/folio/consortia/support/extension/impl/OkapiExtension.java b/src/test/java/org/folio/consortia/support/extension/impl/OkapiExtension.java
index 9c45a64d..0ed1747f 100644
--- a/src/test/java/org/folio/consortia/support/extension/impl/OkapiExtension.java
+++ b/src/test/java/org/folio/consortia/support/extension/impl/OkapiExtension.java
@@ -8,10 +8,13 @@
import java.io.IOException;
import java.net.ServerSocket;
+import java.util.ArrayList;
import java.util.PrimitiveIterator;
import java.util.concurrent.ThreadLocalRandom;
+import com.github.tomakehurst.wiremock.common.ClasspathFileSource;
import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer;
+import com.github.tomakehurst.wiremock.extension.responsetemplating.TemplateEngine;
import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
@@ -24,7 +27,7 @@ public class OkapiExtension implements BeforeAllCallback, AfterAllCallback {
private static final WireMockServer WIRE_MOCK = new WireMockServer(
wireMockConfig()
.port(nextFreePort())
- .extensions(new ResponseTemplateTransformer(true))
+ .extensions(new ResponseTemplateTransformer(TemplateEngine.defaultTemplateEngine(), true, new ClasspathFileSource("/"), new ArrayList<>()))
);
private static int nextFreePort() {