Skip to content

Commit

Permalink
Merge pull request #38 from folio-org/bugfix-release-b1.0.2
Browse files Browse the repository at this point in the history
MCBFF-31: Bugfix release b1.0.2
  • Loading branch information
OleksandrVidinieiev authored Dec 9, 2024
2 parents 081efd2 + d9ba653 commit bee0d52
Show file tree
Hide file tree
Showing 19 changed files with 457 additions and 150 deletions.
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.0.2 2024-12-09
* Failsafe approach to ECS requesting (MCBFF-21)
* Add editions to instance search results (MCBFF-17)

## 1.0.1 2024-11-30

* Fix staff slip token name (MCBFF-27)
Expand Down
32 changes: 31 additions & 1 deletion descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@
"id": "@artifactId@-@version@",
"name": "Folio mod-circulation-bff module",
"provides": [
{
"id": "circulation-bff-ecs-request-external",
"version": "1.0",
"handlers": [
{
"methods": ["POST"],
"pathPattern": "/circulation-bff/create-ecs-request-external",
"permissionsRequired": ["circulation-bff.ecs-request-external.item.post"],
"modulePermissions": [
"tlr.ecs-request-external.post",
"user-tenants.collection.get"
]
}
]
},
{
"id": "circulation-bff-pick-slips",
"version": "1.0",
Expand Down Expand Up @@ -152,6 +167,11 @@
}
],
"permissionSets" : [
{
"permissionName": "circulation-bff.ecs-request-external.item.post",
"displayName": "circulation BFF - create ecs external request",
"description": "create ecs external request"
},
{
"permissionName": "circulation-bff.pick-slips.collection.get",
"displayName": "circulation BFF - get pick slips by service point id",
Expand Down Expand Up @@ -209,6 +229,10 @@
"id": "users",
"version": "16.0"
},
{
"id": "user-tenants",
"version": "1.0"
},
{
"id": "login",
"version": "7.3"
Expand Down Expand Up @@ -250,6 +274,10 @@
{
"id": "requests-mediated",
"version": "2.0"
},
{
"id": "ecs-request-external",
"version": "1.0"
}
],
"metadata": {
Expand All @@ -267,7 +295,9 @@
"inventory-storage.service-points.item.get",
"inventory-storage.service-points.collection.get",
"inventory-storage.material-types.item.get",
"inventory-storage.material-types.collection.get"
"inventory-storage.material-types.collection.get",
"inventory-storage.instances.item.get",
"inventory-storage.instances.collection.get"
]
}
},
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<groupId>org.folio</groupId>
<artifactId>mod-circulation-bff</artifactId>
<name>mod-circulation-bff</name>
<version>1.0.2-SNAPSHOT</version>
<version>1.0.3-SNAPSHOT</version>
<description>FOLIO mod-circulation-bff module</description>
<packaging>jar</packaging>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.folio.circulationbff.domain.dto.AllowedServicePointParams;
import org.folio.circulationbff.domain.dto.AllowedServicePoints;
import org.folio.circulationbff.domain.dto.BffRequest;
import org.folio.circulationbff.domain.dto.EcsRequestExternal;
import org.folio.circulationbff.domain.dto.EcsTlr;
import org.folio.circulationbff.domain.dto.PickSlipCollection;
import org.folio.circulationbff.domain.dto.SearchSlipCollection;
Expand Down Expand Up @@ -32,4 +33,7 @@ public interface EcsTlrClient {

@GetMapping("/staff-slips/search-slips/{servicePointId}")
SearchSlipCollection getSearchSlips(@PathVariable ("servicePointId") String servicePointId);

@PostMapping("/create-ecs-request-external")
EcsTlr createEcsExternalRequest(@RequestBody EcsRequestExternal request);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import org.folio.circulationbff.domain.dto.AllowedServicePoints;
import org.folio.circulationbff.domain.dto.BffRequest;
import org.folio.circulationbff.domain.dto.BffSearchInstance;
import org.folio.circulationbff.domain.dto.EcsRequestExternal;
import org.folio.circulationbff.domain.dto.EcsTlr;
import org.folio.circulationbff.domain.dto.EmptyBffSearchInstance;
import org.folio.circulationbff.domain.dto.MediatedRequest;
import org.folio.circulationbff.domain.dto.PickSlipCollection;
Expand All @@ -18,6 +20,7 @@
import org.folio.circulationbff.domain.dto.UserCollection;
import org.folio.circulationbff.rest.resource.CirculationBffApi;
import org.folio.circulationbff.service.CirculationBffService;
import org.folio.circulationbff.service.EcsRequestExternalService;
import org.folio.circulationbff.service.MediatedRequestsService;
import org.folio.circulationbff.service.SearchService;
import org.folio.circulationbff.service.UserService;
Expand All @@ -37,6 +40,13 @@ public class CirculationBffController implements CirculationBffApi {
private final SearchService searchService;
private final MediatedRequestsService mediatedRequestsService;
private final UserService userService;
private final EcsRequestExternalService ecsRequestExternalService;

@Override
public ResponseEntity<EcsTlr> postEcsRequestExternal(EcsRequestExternal ecsRequestExternal) {
return ResponseEntity.status(HttpStatus.OK)
.body(ecsRequestExternalService.createEcsRequestExternal(ecsRequestExternal));
}

@Override
public ResponseEntity<PickSlipCollection> getPickSlips(String servicePointId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.folio.circulationbff.service;

import org.folio.circulationbff.domain.dto.EcsRequestExternal;
import org.folio.circulationbff.domain.dto.EcsTlr;

public interface EcsRequestExternalService {
EcsTlr createEcsRequestExternal(EcsRequestExternal ecsRequestExternal);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.folio.circulationbff.service.impl;

import org.folio.circulationbff.client.feign.EcsTlrClient;
import org.folio.circulationbff.domain.dto.EcsRequestExternal;
import org.folio.circulationbff.domain.dto.EcsTlr;
import org.folio.circulationbff.service.EcsRequestExternalService;
import org.folio.circulationbff.service.UserTenantsService;
import org.folio.spring.service.SystemUserScopedExecutionService;
import org.springframework.stereotype.Service;

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

@Service
@RequiredArgsConstructor
@Log4j2
public class EcsRequestExternalServiceImpl implements EcsRequestExternalService {

private final SystemUserScopedExecutionService systemUserScopedExecutionService;
private final EcsTlrClient ecsTlrClient;
private final UserTenantsService userTenantsService;


@Override
public EcsTlr createEcsRequestExternal(EcsRequestExternal ecsRequestExternal) {
String centralTenantId = userTenantsService.getCentralTenant();
log.info("createEcsRequestExternal:: centralTenantId={}", centralTenantId);

return systemUserScopedExecutionService.executeSystemUserScoped(centralTenantId,
() -> ecsTlrClient.createEcsExternalRequest(ecsRequestExternal));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
import java.util.Set;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.folio.circulationbff.client.feign.HoldingsStorageClient;
import org.folio.circulationbff.client.feign.InstanceStorageClient;
import org.folio.circulationbff.client.feign.ItemStorageClient;
import org.folio.circulationbff.client.feign.LocationClient;
import org.folio.circulationbff.client.feign.MaterialTypeClient;
Expand All @@ -30,6 +32,8 @@
import org.folio.circulationbff.domain.dto.Contributor;
import org.folio.circulationbff.domain.dto.HoldingsRecord;
import org.folio.circulationbff.domain.dto.HoldingsRecords;
import org.folio.circulationbff.domain.dto.Instance;
import org.folio.circulationbff.domain.dto.Instances;
import org.folio.circulationbff.domain.dto.Item;
import org.folio.circulationbff.domain.dto.ItemEffectiveCallNumberComponents;
import org.folio.circulationbff.domain.dto.Items;
Expand Down Expand Up @@ -62,6 +66,7 @@ public class SearchServiceImpl implements SearchService {
private final MaterialTypeClient materialTypeClient;
private final ServicePointClient servicePointClient;
private final SearchClient searchClient;
private final InstanceStorageClient instanceStorageClient;
private final SystemUserScopedExecutionService executionService;
private final BulkFetchingService fetchingService;
private final SearchInstanceMapper searchInstanceMapper;
Expand All @@ -78,7 +83,8 @@ public Collection<BffSearchInstance> findInstances(String query) {
}
log.info("findInstances:: {} instances found", searchInstances::size);

Collection<BffSearchInstance> bffSearchInstances = buildBffSearchInstances(searchInstances);
Collection<BffSearchInstance> bffSearchInstances =
fetchEditions(buildBffSearchInstances(searchInstances));
log.info("findInstances:: successfully built {} instances", bffSearchInstances::size);

return bffSearchInstances;
Expand Down Expand Up @@ -111,6 +117,45 @@ private Collection<ItemContext> fetchItemDetails(String tenantId, Collection<Sea
return executionService.executeSystemUserScoped(tenantId, () -> buildItemContexts(items));
}

private Collection<BffSearchInstance> fetchEditions(Collection<BffSearchInstance> bffSearchInstances) {
return bffSearchInstances.stream()
.collect(Collectors.groupingBy(BffSearchInstance::getTenantId))
.entrySet()
.stream()
.flatMap(entry -> fetchEditions(entry.getKey(), entry.getValue()).stream())
.toList();
}

private Collection<BffSearchInstance> fetchEditions(String tenantId,
Collection<BffSearchInstance> searchInstances) {
log.info("fetchItemDetails:: fetching details for {} items in tenant {}", searchInstances.size(), tenantId);
return executionService.executeSystemUserScoped(tenantId,
() -> updateSearchInstanceEditions(searchInstances));
}

private Collection<BffSearchInstance> updateSearchInstanceEditions(Collection<BffSearchInstance> searchInstances) {
Map<String, Instance> instanceMap = fetchInstances(
searchInstances.stream()
.map(BffSearchInstance::getId)
.collect(Collectors.toSet())
).stream()
.collect(Collectors.toMap(Instance::getId, Function.identity()));

searchInstances.forEach(searchInstance -> {
Instance instance = instanceMap.get(searchInstance.getId());
if (instance != null) {
searchInstance.setEditions(instance.getEditions());
}
});

return searchInstances;
}

private Collection<Instance> fetchInstances(Collection<String> ids) {
log.info("fetchInstances: fetching {} instances", ids::size);
return fetchingService.fetch(instanceStorageClient, ids, Instances::getInstances);
}

private Collection<ItemContext> buildItemContexts(Collection<SearchItem> searchItems) {
Set<String> itemIds = searchItems.stream()
.map(SearchItem::getId)
Expand Down
6 changes: 5 additions & 1 deletion src/main/resources/permissions/mod-circulation-bff.csv
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ inventory-storage.service-points.item.get
inventory-storage.service-points.collection.get
inventory-storage.material-types.item.get
inventory-storage.material-types.collection.get
tlr.ecs-tlr-allowed-service-points.get
inventory-storage.instances.item.get
inventory-storage.instances.collection.get
tlr.ecs-tlr-allowed-service-points.get
tlr.ecs-request-external.post
user-tenants.collection.get
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 @@ -17,6 +17,8 @@ paths:
$ref: 'paths/staffSlips/pickSlips.yaml'
/circulation-bff/search-slips/{servicePointId}:
$ref: 'paths/staffSlips/searchSlips.yaml'
/circulation-bff/create-ecs-request-external:
$ref: 'paths/ecsRequestExternal/ecsRequestExternal.yaml'

components:
schemas:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
post:
description: Create ECS request external
operationId: postEcsRequestExternal
tags:
- ecsRequestExternal
requestBody:
content:
application/json:
schema:
$ref: '../../schemas/dto/ecsRequestExternal/ecsRequestExternal.yaml'
required: true
responses:
'201':
description: Ecs external request has been created
content:
application/json:
schema:
$ref: '../../schemas/dto/ecs-tlr/EcsTlr.yaml#/EcsTlr'
'400':
$ref: '../../responses/badRequestResponse.yaml'
'500':
$ref: '../../responses/internalServerErrorResponse.yaml'
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
description: ECS Request External - title level requests in a multi-tenant environment with Сonsortia support enabled
type: object
properties:
id:
description: ID of the ECS TLR
$ref: '../common/uuid.yaml'
instanceId:
description: ID of the instance being requested
$ref: '../common/uuid.yaml'
requesterId:
description: ID of the requesting patron (user)
$ref: '../common/uuid.yaml'
requestLevel:
description: Level of the request - Item or Title
type: string
enum: [ "Item", "Title" ]
requestExpirationDate:
description: Date when the request expires
type: string
format: date-time
requestDate:
description: Date when the request was placed
type: string
format: date-time
patronComments:
description: Comments made by the patron
type: string
fulfillmentPreference:
description: How should the request be fulfilled (whether the item should be kept on the hold shelf for collection or delivered to the requester)
type: string
enum: ["Hold Shelf", "Delivery"]
pickupServicePointId:
description: The ID of the Service Point where this request can be picked up
$ref: '../common/uuid.yaml'
itemId:
description: ID of the item being requested
$ref: '../common/uuid.yaml'
holdingsRecordId:
description: ID of the holdings record being requested
$ref: '../common/uuid.yaml'
primaryRequestId:
description: Primary request ID
$ref: '../common/uuid.yaml'
primaryRequestDcbTransactionId:
description: ID of DCB transaction created for primary request
$ref: '../common/uuid.yaml'
primaryRequestTenantId:
description: ID of the tenant primary request was created in
type: string
secondaryRequestId:
description: "Secondary request ID"
$ref: '../common/uuid.yaml'
secondaryRequestDcbTransactionId:
description: ID of DCB transaction created for secondary request
$ref: '../common/uuid.yaml'
secondaryRequestTenantId:
description: ID of the tenant secondary request was created in
type: string

required:
- instanceId
- requesterId
- requestLevel
- fulfillmentPreference
- requestDate
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,11 @@ properties:
type: array
items:
$ref: "bffSearchItem.yaml"
editions:
description: "The edition statement, imprint and other publication source information"
type: array
uniqueItems: true
items:
type: string
required:
- items
Loading

0 comments on commit bee0d52

Please sign in to comment.