Skip to content

Commit

Permalink
MCBFF-44 Create external ECS TLR
Browse files Browse the repository at this point in the history
  • Loading branch information
OleksandrVidinieiev committed Jan 27, 2025
1 parent 250b6b1 commit a6e39db
Show file tree
Hide file tree
Showing 19 changed files with 355 additions and 73 deletions.
9 changes: 7 additions & 2 deletions descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"provides": [
{
"id": "circulation-bff-ecs-request-external",
"version": "1.1",
"version": "1.2",
"handlers": [
{
"methods": ["POST"],
Expand All @@ -14,7 +14,12 @@
"tlr.ecs-request-external.post",
"user-tenants.collection.get",
"circulation.requests.item.get",
"circulation.requests.collection.get"
"circulation.requests.collection.get",
"tlr.settings.get",
"circulation.settings.item.get",
"circulation.settings.collection.get",
"consortium-search.items.collection.get",
"consortium-search.items.item.get"
]
}
]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package org.folio.circulationbff.client.feign;

import org.folio.circulationbff.domain.dto.ConsortiumItem;
import org.folio.circulationbff.domain.dto.SearchInstances;
import org.folio.spring.config.FeignClientConfiguration;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(name = "search", url = "search", configuration = FeignClientConfiguration.class)
public interface SearchClient {

@GetMapping("/instances")
SearchInstances findInstances(@RequestParam String query, @RequestParam boolean expandAll);

@GetMapping("/consortium/item/{itemId}")
ConsortiumItem searchItem(@PathVariable("itemId") String itemId);
}
21 changes: 21 additions & 0 deletions src/main/java/org/folio/circulationbff/config/TenantConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.folio.circulationbff.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import jakarta.annotation.PostConstruct;
import lombok.Data;

@Configuration
@Data
@ConfigurationProperties("folio.tenant")
public class TenantConfig {
private String secureTenantId;

@PostConstruct
private void postConstruct() {
if ("${SECURE_TENANT_ID}".equals(secureTenantId)) {
secureTenantId = null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.folio.circulationbff.domain;

public record EcsTenantConfiguration(boolean isConsortiaEnabled, String currentTenantId,
String centralTenantId, String secureTenantId) {

public boolean isCurrentTenantCentral() {
return isConsortiaEnabled && currentTenantId != null && currentTenantId.equals(centralTenantId);
}

public boolean isCurrentTenantSecure() {
return isConsortiaEnabled && currentTenantId != null && currentTenantId.equals(secureTenantId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.folio.circulationbff.service;

import org.folio.circulationbff.domain.EcsTenantConfiguration;

public interface EcsTenantConfigurationService {
EcsTenantConfiguration getTenantConfiguration();
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import java.util.Collection;

import org.folio.circulationbff.domain.dto.BffSearchInstance;
import org.folio.circulationbff.domain.dto.ConsortiumItem;

public interface SearchService {
Collection<BffSearchInstance> findInstances(String query);
ConsortiumItem findConsortiumItem(String itemId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
public interface SettingsService {
boolean isEcsTlrFeatureEnabled();
boolean isEcsTlrFeatureEnabled(String tenantId);
boolean isEcsTlrFeatureEnabled(boolean isCentralTenant);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package org.folio.circulationbff.service;

import org.folio.circulationbff.domain.dto.UserTenant;

public interface UserTenantsService {
String getCentralTenant();
boolean isCentralTenant();
UserTenant getFirstUserTenant();
boolean isCentralTenant(String tenantId);
boolean isCentralTenant(UserTenant userTenant);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
package org.folio.circulationbff.service.impl;

import static org.folio.circulationbff.domain.dto.EcsRequestExternal.RequestLevelEnum.ITEM;
import static org.folio.circulationbff.domain.dto.EcsRequestExternal.RequestLevelEnum.TITLE;

import org.folio.circulationbff.client.feign.CirculationClient;
import org.folio.circulationbff.client.feign.EcsTlrClient;
import org.folio.circulationbff.domain.EcsTenantConfiguration;
import org.folio.circulationbff.domain.dto.ConsortiumItem;
import org.folio.circulationbff.domain.dto.EcsRequestExternal;
import org.folio.circulationbff.domain.dto.EcsRequestExternal.RequestLevelEnum;
import org.folio.circulationbff.domain.dto.EcsTlr;
import org.folio.circulationbff.domain.dto.Request;
import org.folio.circulationbff.service.EcsTenantConfigurationService;
import org.folio.circulationbff.service.EcsRequestExternalService;
import org.folio.circulationbff.service.UserTenantsService;
import org.folio.circulationbff.service.SearchService;
import org.folio.circulationbff.service.SettingsService;
import org.folio.spring.service.SystemUserScopedExecutionService;
import org.springframework.stereotype.Service;

Expand All @@ -21,18 +29,79 @@ public class EcsRequestExternalServiceImpl implements EcsRequestExternalService
private final SystemUserScopedExecutionService systemUserScopedExecutionService;
private final EcsTlrClient ecsTlrClient;
private final CirculationClient circulationClient;
private final UserTenantsService userTenantsService;

private final SettingsService settingsService;
private final SearchService searchService;
private final EcsTenantConfigurationService ecsTenantConfigurationService;

@Override
public Request createEcsRequestExternal(EcsRequestExternal ecsRequestExternal) {
String centralTenantId = userTenantsService.getCentralTenant();
log.info("createEcsRequestExternal:: centralTenantId={}", centralTenantId);
public Request createEcsRequestExternal(EcsRequestExternal request) {
log.info("createEcsRequestExternal:: creating external request");
fetchMissingRequestProperties(request);
EcsTenantConfiguration tenantConfiguration = ecsTenantConfigurationService.getTenantConfiguration();

return settingsService.isEcsTlrFeatureEnabled(tenantConfiguration.isCurrentTenantCentral())
? createEcsRequest(request, tenantConfiguration)
: createCirculationRequest(request);
}

private Request createEcsRequest(EcsRequestExternal ecsRequestExternal,
EcsTenantConfiguration tenantConfiguration) {

log.info("createEcsRequest:: creating ECS request");
return tenantConfiguration.isCurrentTenantSecure()
? createMediatedRequest(ecsRequestExternal)
: createExternalEcsTlr(ecsRequestExternal, tenantConfiguration);
}

private Request createCirculationRequest(EcsRequestExternal ecsRequestExternal) {
log.info("createCirculationRequest:: creating circulation request");
return ecsRequestExternal.getRequestLevel() == TITLE
? createTitleLevelRequest(ecsRequestExternal)
: createItemLevelRequest(ecsRequestExternal);
}

private Request createExternalEcsTlr(EcsRequestExternal ecsRequestExternal,
EcsTenantConfiguration tenantConfiguration) {

EcsTlr ecsTlr = systemUserScopedExecutionService.executeSystemUserScoped(centralTenantId,
log.info("createExternalEcsTlr:: creating ECS TLR");
EcsTlr ecsTlr = systemUserScopedExecutionService.executeSystemUserScoped(
tenantConfiguration.centralTenantId(),
() -> ecsTlrClient.createEcsExternalRequest(ecsRequestExternal));
log.info("createEcsRequestExternal:: ecsTlr: {}", ecsTlr);
log.info("createExternalEcsTlr:: ECS TLR created: {}", ecsTlr::getId);
log.debug("createExternalEcsTlr:: ecsTlr: {}", ecsTlr);

log.info("createExternalEcsTlr:: fetching primary request");
return circulationClient.getRequestById(ecsTlr.getPrimaryRequestId());
}

private Request createMediatedRequest(EcsRequestExternal ecsRequestExternal) {
log.info("createMediatedRequest:: creating mediated request");
// POST /requests-mediated/mediated-requests
return new Request();
}

private Request createItemLevelRequest(EcsRequestExternal ecsRequestExternal) {
log.info("createItemLevelRequest:: creating item level request");
// POST /circulation/requests
return new Request();
}

private Request createTitleLevelRequest(EcsRequestExternal ecsRequestExternal) {
log.info("createTitleLevelRequest:: creating title level request");
// POST /circulation/requests/instances
return new Request();
}

private void fetchMissingRequestProperties(EcsRequestExternal request) {
String itemId = request.getItemId();
RequestLevelEnum requestLevel = request.getRequestLevel();
log.info("fetchMissingRequestProperties:: requestLevel={}, itemId={}", requestLevel, itemId);
if (requestLevel == ITEM && itemId != null) {
log.info("fetchMissingRequestProperties:: fetching item for item level request");
ConsortiumItem item = searchService.findConsortiumItem(itemId);
request.instanceId(item.getInstanceId())
.holdingsRecordId(item.getHoldingsRecordId());
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.folio.circulationbff.service.impl;

import org.folio.circulationbff.config.TenantConfig;
import org.folio.circulationbff.domain.EcsTenantConfiguration;
import org.folio.circulationbff.domain.dto.UserTenant;
import org.folio.circulationbff.service.EcsTenantConfigurationService;
import org.folio.circulationbff.service.UserTenantsService;
import org.springframework.stereotype.Service;

import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;

@Service
@RequiredArgsConstructor
@Log4j2
public class EcsTenantConfigurationServiceImpl
implements EcsTenantConfigurationService {

private final UserTenantsService userTenantsService;
private final TenantConfig tenantConfig;

@Override
public EcsTenantConfiguration getTenantConfiguration() {
UserTenant userTenant = userTenantsService.getFirstUserTenant();

EcsTenantConfiguration tenantConfiguration = userTenant == null
? new EcsTenantConfiguration(false, null, null, null)
: new EcsTenantConfiguration(true, userTenant.getTenantId(), userTenant.getCentralTenantId(),
tenantConfig.getSecureTenantId());

log.info("getTenantConfiguration:: {}", tenantConfiguration);
return tenantConfiguration;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.folio.circulationbff.domain.dto.BffSearchItemLocation;
import org.folio.circulationbff.domain.dto.BffSearchItemMaterialType;
import org.folio.circulationbff.domain.dto.BffSearchItemStatus;
import org.folio.circulationbff.domain.dto.ConsortiumItem;
import org.folio.circulationbff.domain.dto.Contributor;
import org.folio.circulationbff.domain.dto.HoldingsRecord;
import org.folio.circulationbff.domain.dto.HoldingsRecords;
Expand Down Expand Up @@ -71,6 +72,12 @@ public class SearchServiceImpl implements SearchService {
private final BulkFetchingService fetchingService;
private final SearchInstanceMapper searchInstanceMapper;

@Override
public ConsortiumItem findConsortiumItem(String itemId) {
log.info("findConsortiumItem:: looking for item {}", itemId);
return searchClient.searchItem(itemId);
}

@Override
public Collection<BffSearchInstance> findInstances(String query) {
log.info("findInstances:: searching instances by query: {}", query);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,19 @@ public class SettingsServiceImpl implements SettingsService {

@Override
public boolean isEcsTlrFeatureEnabled() {
if (userTenantsService.isCentralTenant()) {
return ecsTlrClient.getTlrSettings().getEcsTlrFeatureEnabled();
}
return isTlrEnabledInCirculationSettings();
return isEcsTlrFeatureEnabled(userTenantsService.isCentralTenant());
}

@Override
public boolean isEcsTlrFeatureEnabled(String tenantId) {
if (userTenantsService.isCentralTenant(tenantId)) {
return ecsTlrClient.getTlrSettings().getEcsTlrFeatureEnabled();
}
return isTlrEnabledInCirculationSettings();
return isEcsTlrFeatureEnabled(userTenantsService.isCentralTenant(tenantId));
}

@Override
public boolean isEcsTlrFeatureEnabled(boolean isCentralTenant) {
return isCentralTenant
? isEcsTlrFeatureEnabledInCentralTenant()
: isTlrEnabledInCirculationSettings();
}

private boolean isTlrEnabledInCirculationSettings() {
Expand All @@ -50,4 +51,10 @@ private boolean isTlrEnabledInCirculationSettings() {
}
return false;
}

private boolean isEcsTlrFeatureEnabledInCentralTenant() {
Boolean ecsTlrFeatureEnabled = ecsTlrClient.getTlrSettings().getEcsTlrFeatureEnabled();
log.info("isEcsTlrFeatureEnabled:: {}", ecsTlrFeatureEnabled);
return ecsTlrFeatureEnabled;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,11 @@ public String getCentralTenant() {

@Override
public boolean isCentralTenant() {
UserTenant firstUserTenant = getFirstUserTenant();
if (firstUserTenant == null) {
log.info("isCentralTenant:: failed to fetch user tenants");
return false;
}
String centralTenantId = firstUserTenant.getCentralTenantId();
String tenantId = firstUserTenant.getTenantId();
log.info("isCentralTenant:: centralTenantId={}, tenantId={}", centralTenantId,
tenantId);

return centralTenantId.equals(tenantId);
return isCentralTenant(getFirstUserTenant());
}

private UserTenant getFirstUserTenant() {
@Override
public UserTenant getFirstUserTenant() {
UserTenant firstUserTenant = findFirstUserTenant();
if (firstUserTenant == null) {
log.info("processUserGroupEvent: Failed to get user-tenants info");
Expand All @@ -67,20 +58,34 @@ public boolean isCentralTenant(String tenantId) {
return false;
}

@Override
public boolean isCentralTenant(UserTenant userTenant) {
if (userTenant == null) {
log.info("isCentralTenant:: failed to fetch user tenants");
return false;
}
String centralTenantId = userTenant.getCentralTenantId();
String tenantId = userTenant.getTenantId();
log.info("isCentralTenant:: centralTenantId={}, tenantId={}", centralTenantId,
tenantId);

return centralTenantId.equals(tenantId);
}

private UserTenant findFirstUserTenant() {
log.info("findFirstUserTenant:: finding first userTenant");
UserTenant firstUserTenant = null;
UserTenantCollection userTenantCollection = userTenantsClient.getUserTenants(1);
log.info("findFirstUserTenant:: userTenantCollection: {}", () -> userTenantCollection);
log.debug("findFirstUserTenant:: userTenantCollection: {}", () -> userTenantCollection);
if (userTenantCollection != null) {
log.info("findFirstUserTenant:: userTenantCollection: {}", () -> userTenantCollection);
log.debug("findFirstUserTenant:: userTenantCollection: {}", () -> userTenantCollection);
List<UserTenant> userTenants = userTenantCollection.getUserTenants();
if (!userTenants.isEmpty()) {
firstUserTenant = userTenants.get(0);
log.info("findFirstUserTenant:: found userTenant: {}", firstUserTenant);
log.debug("findFirstUserTenant:: found userTenant: {}", firstUserTenant);
}
}
log.info("findFirstUserTenant:: result: {}", firstUserTenant);
log.debug("findFirstUserTenant:: result: {}", firstUserTenant);
return firstUserTenant;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ spring:
enabled: true
folio:
tenant:
secure-tenant-id: ${SECURE_TENANT_ID}
validation:
enabled: true
environment: ${ENV:folio}
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/swagger.api/circulation-bff.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,5 @@ components:
$ref: 'schemas/dto/request/BffRequest.yaml#/BffRequest'
ecs-tlr:
$ref: 'schemas/dto/ecs-tlr/EcsTlr.yaml#/EcsTlr'
consortium-item:
$ref: 'schemas/dto/search/consortiumItem.yaml'
Loading

0 comments on commit a6e39db

Please sign in to comment.