Skip to content

Commit

Permalink
Merge branch 'master' into MODCONSKC-57-3
Browse files Browse the repository at this point in the history
  • Loading branch information
azizbekxm authored Jan 20, 2025
2 parents 896e09d + f1f280f commit 09d2b8c
Show file tree
Hide file tree
Showing 18 changed files with 666 additions and 453 deletions.
4 changes: 2 additions & 2 deletions descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,12 @@
"consortia.tenants.item.post"
],
"modulePermissions": [
"consortia.consortia-configuration.item.post",
"perms.users.item.put",
"perms.users.item.post",
"perms.users.assign.immutable",
"perms.users.assign.mutable",
"users.collection.get"
"users.collection.get",
"user-tenants.collection.get"
]
},
{
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
package org.folio.consortia.client;

import org.folio.consortia.domain.dto.UserTenant;
import org.folio.consortia.domain.dto.UserTenantCollection;
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.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

@FeignClient(name = "user-tenants" , configuration = FeignClientConfiguration.class)
public interface UserTenantsClient {

@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
UserTenantCollection getUserTenants();

@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
void postUserTenant(@RequestBody UserTenant userTenant);

Expand Down
33 changes: 13 additions & 20 deletions src/main/java/org/folio/consortia/controller/TenantController.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package org.folio.consortia.controller;

import static org.folio.spring.scope.FolioExecutionScopeExecutionContextManager.getRunnableWithCurrentFolioContext;
import static org.folio.spring.scope.FolioExecutionScopeExecutionContextManager.getRunnableWithFolioContext;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.NO_CONTENT;

Expand All @@ -14,11 +12,9 @@
import org.folio.consortia.domain.dto.TenantDetails.SetupStatusEnum;
import org.folio.consortia.rest.resource.TenantsApi;
import org.folio.consortia.service.SyncPrimaryAffiliationService;
import org.folio.consortia.service.TenantManager;
import org.folio.consortia.service.TenantService;
import org.folio.consortia.utils.TenantContextUtils;
import org.folio.spring.FolioExecutionContext;
import org.jetbrains.annotations.NotNull;
import org.springframework.core.task.TaskExecutor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
Expand All @@ -34,45 +30,44 @@
@RequiredArgsConstructor
public class TenantController implements TenantsApi {

private final TenantService service;
private final TaskExecutor asyncTaskExecutor;
private final TenantService tenantService;
private final TenantManager tenantManager;
private final SyncPrimaryAffiliationService syncPrimaryAffiliationService;
private final FolioExecutionContext folioExecutionContext;

@Override
public ResponseEntity<TenantCollection> getTenants(UUID consortiumId, Integer offset, Integer limit) {
return ResponseEntity.ok(service.get(consortiumId, offset, limit));
return ResponseEntity.ok(tenantManager.get(consortiumId, offset, limit));
}

@Override
public ResponseEntity<Tenant> saveTenant(UUID consortiumId, @Validated Tenant tenant, UUID adminUserId) {
return ResponseEntity.status(CREATED).body(service.save(consortiumId, adminUserId, tenant));
return ResponseEntity.status(CREATED).body(tenantManager.save(consortiumId, adminUserId, tenant));
}

@Override
public ResponseEntity<Tenant> updateTenant(UUID consortiumId, String tenantId, @Validated Tenant tenant) {
return ResponseEntity.ok(service.update(consortiumId, tenantId, tenant));
return ResponseEntity.ok(tenantManager.update(consortiumId, tenantId, tenant));
}

@Override
public ResponseEntity<Void> deleteTenantById(UUID consortiumId, String tenantId) {
service.delete(consortiumId, tenantId);
tenantManager.delete(consortiumId, tenantId);
return ResponseEntity.status(NO_CONTENT).build();
}

@Override
public ResponseEntity<TenantDetails> getTenantDetailsById(UUID consortiumId, String tenantId) {
return ResponseEntity.ok(service.getTenantDetailsById(consortiumId, tenantId));
return ResponseEntity.ok(tenantService.getTenantDetailsById(consortiumId, tenantId));
}

@Override
public ResponseEntity<Void> syncPrimaryAffiliations(UUID consortiumId, String tenantId, @NotNull String centralTenantId) {
try {
asyncTaskExecutor.execute(getRunnableWithCurrentFolioContext(
() -> syncPrimaryAffiliationService.syncPrimaryAffiliations(consortiumId, tenantId, centralTenantId)));
syncPrimaryAffiliationService.syncPrimaryAffiliations(consortiumId, tenantId, centralTenantId);
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
} catch (Exception e) {
log.error("syncPrimaryAffiliations:: error syncing user primary affiliations", e);
service.updateTenantSetupStatus(tenantId, centralTenantId, SetupStatusEnum.FAILED);
tenantService.updateTenantSetupStatus(tenantId, centralTenantId, SetupStatusEnum.FAILED);
throw e;
}
}
Expand All @@ -81,13 +76,11 @@ public ResponseEntity<Void> syncPrimaryAffiliations(UUID consortiumId, String te
public ResponseEntity<Void> createPrimaryAffiliations(UUID consortiumId, String tenantId, @NotNull String centralTenantId,
SyncPrimaryAffiliationBody syncPrimaryAffiliationBody) {
try {
var context = TenantContextUtils.prepareContextForTenant(centralTenantId, folioExecutionContext.getFolioModuleMetadata(), folioExecutionContext);
asyncTaskExecutor.execute(getRunnableWithFolioContext(context,
() -> syncPrimaryAffiliationService.createPrimaryUserAffiliations(consortiumId, centralTenantId, syncPrimaryAffiliationBody)));
syncPrimaryAffiliationService.createPrimaryUserAffiliations(consortiumId, centralTenantId, syncPrimaryAffiliationBody);
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
} catch (Exception e) {
log.error("createPrimaryAffiliations:: error creating user primary affiliations", e);
service.updateTenantSetupStatus(tenantId, centralTenantId, SetupStatusEnum.FAILED);
tenantService.updateTenantSetupStatus(tenantId, centralTenantId, SetupStatusEnum.FAILED);
throw e;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public interface TenantRepository extends JpaRepository<TenantEntity, String> {
Optional<TenantEntity> findCentralTenant();

boolean existsByIsCentralTrue();

@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);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.folio.consortia.service;

import org.folio.consortia.domain.dto.ConsortiaConfiguration;
import org.folio.consortia.exception.ResourceAlreadyExistException;

public interface ConsortiaConfigurationService {
/**
Expand All @@ -24,12 +25,16 @@ public interface ConsortiaConfigurationService {
* This configuration will be stored in requested tenant schema
*
* @param centralTenantId id of central tenant for requested tenant
* @throws ResourceAlreadyExistException if configuration already exists
*/
ConsortiaConfiguration createConfiguration(String centralTenantId);
ConsortiaConfiguration createConfiguration(String centralTenantId) throws ResourceAlreadyExistException;

/**
* Check if there is any central tenant
* @return boolean value based one whether central tenant configuration exists or not
* Check if there exists a central tenant configuration;
* if not then save new configuration with central tenant id as value.
* This configuration will be stored in requested tenant schema
*
* @param centralTenantId id of central tenant for requested tenant
*/
boolean isCentralTenantConfigurationExists();
void createConfigurationIfNeeded(String centralTenantId);
}
51 changes: 51 additions & 0 deletions src/main/java/org/folio/consortia/service/TenantManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.folio.consortia.service;

import java.util.UUID;

import org.folio.consortia.domain.dto.Tenant;
import org.folio.consortia.domain.dto.TenantCollection;

public interface TenantManager {

/**
* Gets tenant collection based on consortiumId.
*
* @param consortiumId the consortiumId
* @param limit the limit
* @param offset the offset
* @return tenant collection
*/
TenantCollection get(UUID consortiumId, Integer offset, Integer limit);

/**
* 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
* @param adminUserId the id of admin_user
* @return tenantDto
*/
Tenant save(UUID consortiumId, UUID adminUserId, Tenant tenantDto);

/**
* Updates single tenant based on consortiumId.
*
* @param consortiumId the consortiumId
* @param tenantId the tenantId
* @param tenantDto the tenantDto
* @return tenantDto
*/
Tenant update(UUID consortiumId, String tenantId, Tenant tenantDto);

/**
* Deletes single tenant based on consortiumId.
* @param consortiumId the consortiumId
* @param tenantId the tenantId
*/
void delete(UUID consortiumId, String tenantId);

}
53 changes: 36 additions & 17 deletions src/main/java/org/folio/consortia/service/TenantService.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.folio.consortia.service;

import org.folio.consortia.domain.dto.User;
import org.folio.consortia.exception.ResourceAlreadyExistException;
import org.folio.consortia.exception.ResourceNotFoundException;
import java.util.List;
import java.util.UUID;
Expand Down Expand Up @@ -30,28 +32,40 @@ public interface TenantService {
TenantCollection getAll(UUID consortiumId);

/**
* 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.
* Inserts single tenant
*
* @param tenantEntity the tenant entity
* @return tenantDto
*/
Tenant saveTenant(TenantEntity tenantEntity);

/**
* Inserts single tenant based on consortiumId
*
* @param consortiumId the consortiumId
* @param tenantDto the tenantDto
* @param adminUserId the id of admin_user
* @return tenantDto
*/
Tenant save(UUID consortiumId, UUID adminUserId, Tenant tenantDto);
Tenant saveTenant(UUID consortiumId, Tenant tenantDto);

/**
* Updates single tenant based on consortiumId.
* Inserts single tenant based on consortiumId and setup status
*
* @param consortiumId the consortiumId
* @param tenantId the tenantId
* @param tenantDto the tenantDto
* @param setupStatus the setup status
* @return tenantDto
*/
Tenant update(UUID consortiumId, String tenantId, Tenant tenantDto);
Tenant saveTenantDetails(UUID consortiumId, Tenant tenantDto, TenantDetails.SetupStatusEnum setupStatus);

/**
* Inserts single user tenant based on consortiumId
*
* @param consortiumId the consortiumId
* @param user the user
* @param tenantDto the tenantDto
*/
void saveUserTenant(UUID consortiumId, User user, Tenant tenantDto);

/**
* Updates tenant's setup status.
Expand All @@ -62,13 +76,6 @@ public interface TenantService {
*/
void updateTenantSetupStatus(String tenantId, String centralTenantId, SetupStatusEnum setupStatus);

/**
* Deletes single tenant based on consortiumId.
* @param consortiumId the consortiumId
* @param tenantId the tenantId
*/
void delete(UUID consortiumId, String tenantId);

/**
* Gets tenant entity based on tenantId.
*
Expand All @@ -92,6 +99,18 @@ public interface TenantService {
*/
String getCentralTenantId();

/**
* Checks if central tenant exists
* @return true if central tenant exists, false otherwise
*/
boolean centralTenantExists();

/**
* Checks if tenant with given name exists
* @throws ResourceAlreadyExistException in case if tenant with given name or code already exists
*/
void checkTenantUniqueNameAndCodeOrThrow(Tenant tenant);

/**
* Check for tenant existence in consortia
* @throws ResourceNotFoundException in case if tenants absence in consortia
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.folio.consortia.service.impl;

import java.util.List;
import java.util.function.Supplier;

import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.folio.consortia.domain.dto.ConsortiaConfiguration;
Expand Down Expand Up @@ -37,8 +39,22 @@ public String getCentralTenantId(String requestTenantId) {
}

@Override
public ConsortiaConfiguration createConfiguration(String centralTenantId) {
checkAnyConsortiaConfigurationNotExistsOrThrow();
public ConsortiaConfiguration createConfiguration(String centralTenantId) throws ResourceAlreadyExistException {
return createConfiguration(centralTenantId, () -> {
throw new ResourceAlreadyExistException(CONSORTIA_CONFIGURATION_EXIST_MSG_TEMPLATE);
});
}

@Override
public void createConfigurationIfNeeded(String centralTenantId) {
createConfiguration(centralTenantId, this::getConsortiaConfiguration);
}

private ConsortiaConfiguration createConfiguration(String centralTenantId, Supplier<ConsortiaConfiguration> supplierIfConfigExists) {
if (configurationRepository.count() > 0) {
log.info("createConfiguration:: Configuration already exists for central tenant: '{}'", centralTenantId);
return supplierIfConfigExists.get();
}
ConsortiaConfigurationEntity configuration = new ConsortiaConfigurationEntity();
configuration.setCentralTenantId(centralTenantId);
return converter.convert(configurationRepository.save(configuration), ConsortiaConfiguration.class);
Expand All @@ -53,14 +69,4 @@ 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);
}
}

}
Loading

0 comments on commit 09d2b8c

Please sign in to comment.