Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MCBFF-21 Request types - failsafe approach for ECS requesting #31

Merged
merged 50 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from 47 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
728a4f7
MCBFF-12: staff slips endpoints.
AntonAntonich Nov 15, 2024
4704967
MCBFF-12: ModuleDescriptor-template.json
AntonAntonich Nov 15, 2024
69300c1
MCBFF-12: sonar issues
AntonAntonich Nov 16, 2024
a003689
MCBFF-12: removed "staff"
AntonAntonich Nov 17, 2024
e3f1196
MCBFF-12: add "staff" in Unit Tests
AntonAntonich Nov 18, 2024
d9223b3
MCBFF-12: add "staff" when it necessary
AntonAntonich Nov 18, 2024
b0a8a24
MCBFF-12: deleted staffSlipsCommon.yaml
AntonAntonich Nov 18, 2024
6e23ef2
MCBFF-12: added dependencies to mod-tlr and mod-circulation interface…
AntonAntonich Nov 19, 2024
fd171db
MCBFF-12: removed quotes
AntonAntonich Nov 19, 2024
17815e7
MCBFF-12: add logic for checking is tenantId central
AntonAntonich Nov 19, 2024
284dc25
MCBFF-12: UT refactored
AntonAntonich Nov 20, 2024
b6f9287
MCBFF-12: add coverage
AntonAntonich Nov 20, 2024
b8901e0
Merge branch 'refs/heads/master' into MCBFF-12
AntonAntonich Nov 20, 2024
a23e0f1
MCBFF-12: add coverage
AntonAntonich Nov 20, 2024
0df7143
MCBFF-12: refactored
AntonAntonich Nov 20, 2024
ea77e59
MCBFF-12: refactored
AntonAntonich Nov 20, 2024
03dd9ae
MCBFF-12: refactored
AntonAntonich Nov 20, 2024
6c80bf1
MCBFF-12: staff slips split into search and pick
AntonAntonich Nov 21, 2024
1d14b44
Merge remote-tracking branch 'refs/remotes/origin/master' into MCBFF-12
AntonAntonich Nov 21, 2024
d7bc7bb
MCBFF-12: staff slips split into search and pick
AntonAntonich Nov 21, 2024
b755f58
MCBFF-12: urls. arrays naming
AntonAntonich Nov 21, 2024
c4fb064
MCBFF-12: test data provider methods naming
AntonAntonich Nov 22, 2024
0399a5e
MCBFF-12: increased openapi-generator version to 7.9.0
AntonAntonich Nov 22, 2024
6421c81
MCBFF-12: added necessary permissions
AntonAntonich Nov 22, 2024
6264709
MCBFF-12: added necessary permissions
AntonAntonich Nov 22, 2024
f29687c
MCBFF-12: user-tenants dependency as required
AntonAntonich Nov 22, 2024
acff7cf
MCBFF-12: decreased openapi codegen version to previous. removed prox…
AntonAntonich Nov 22, 2024
6b9f853
MCBFF-12: refactored empty lines
AntonAntonich Nov 22, 2024
076ad67
MCBFF-12: changed logic with routing
AntonAntonich Nov 23, 2024
acdb4c0
MCBFF-12: UT refactored
AntonAntonich Nov 23, 2024
a34d583
MCBFF-12: removed unnecessary logic
AntonAntonich Nov 23, 2024
d1b0b86
MCBFF-12: removed unnecessary permissions
AntonAntonich Nov 23, 2024
c19aa99
MCBFF-12 Refactor
alexanderkurash Nov 23, 2024
973fe2f
MCBFF-12: refactored
AntonAntonich Nov 23, 2024
96e32f4
MCBFF-12: refactored unit tests naming
AntonAntonich Nov 25, 2024
ced0f14
MCBFF-21: ModuleDescriptor-template.json
AntonAntonich Nov 25, 2024
48b5085
MCBFF-21: structure
AntonAntonich Nov 25, 2024
d7072ed
Merge branch 'refs/heads/MCBFF-12' into MCBFF-21
AntonAntonich Nov 25, 2024
b0f33ab
MCBFF-21: implementation
AntonAntonich Nov 25, 2024
5163af0
MCBFF-21: UT
AntonAntonich Nov 26, 2024
499e9a0
Merge branch 'refs/heads/master' into MCBFF-21
AntonAntonich Nov 26, 2024
b073269
MCBFF-21: resolved conflicts
AntonAntonich Nov 26, 2024
62663fa
MCBFF-21: refactored after review
AntonAntonich Nov 27, 2024
de97d98
MCBFF-21: refactored tabulation
AntonAntonich Nov 27, 2024
c63b942
MCBFF-21: refactored
AntonAntonich Nov 27, 2024
5cdac06
MCBFF-21: refactored
AntonAntonich Nov 27, 2024
aa406ab
Merge branch 'refs/heads/master' into MCBFF-21
AntonAntonich Nov 27, 2024
5ff24d3
MCBFF-21: refactored
AntonAntonich Nov 27, 2024
dad6483
MCBFF-21: refactored permission naming
AntonAntonich Nov 27, 2024
c74a3f3
Merge branch 'master' of github.com:folio-org/mod-circulation-bff int…
roman-barannyk Dec 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions 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.post"],
"modulePermissions": [
"tlr.ecs-request-external.post",
"user-tenants.collection.get"
]
}
]
},
{
"id": "circulation-bff-pick-slips",
"version": "1.0",
Expand Down Expand Up @@ -151,6 +166,11 @@
}
],
"permissionSets" : [
{
"permissionName": "circulation-bff.ecs-request-external.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 @@ -188,6 +208,10 @@
}
],
"requires": [
{
"id": "ecs-request-external",
"version": "1.0"
},
{
"id": "pick-slips",
"version": "0.4"
Expand All @@ -212,6 +236,10 @@
"id": "users",
"version": "16.0"
},
{
"id": "user-tenants",
"version": "1.0"
},
roman-barannyk marked this conversation as resolved.
Show resolved Hide resolved
{
"id": "login",
"version": "7.3"
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();
roman-barannyk marked this conversation as resolved.
Show resolved Hide resolved
log.info("createEcsRequestExternal:: centralTenantId={}", centralTenantId);

return systemUserScopedExecutionService.executeSystemUserScoped(centralTenantId,
() -> ecsTlrClient.createEcsExternalRequest(ecsRequestExternal));
}
}
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
@@ -0,0 +1,82 @@
package org.folio.circulationbff.api;

import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson;
import static com.github.tomakehurst.wiremock.client.WireMock.jsonResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.matching;
import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching;
import static org.apache.http.HttpStatus.SC_CREATED;
import static org.apache.http.HttpStatus.SC_OK;

import java.time.LocalDate;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.folio.circulationbff.domain.dto.EcsRequestExternal;
import org.folio.circulationbff.domain.dto.EcsTlr;
import org.folio.circulationbff.domain.dto.UserTenant;
import org.folio.circulationbff.domain.dto.UserTenantCollection;
import org.folio.spring.integration.XOkapiHeaders;
import org.junit.jupiter.api.Test;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;

import com.github.tomakehurst.wiremock.client.WireMock;

import lombok.SneakyThrows;

class EcsExternalRequestApiTest extends BaseIT {
private static final String TLR_CREATE_ECS_EXTERNAL_REQUEST_URL =
"/tlr/create-ecs-request-external";
private static final String CIRCULATION_BFF_CREATE_ECS_EXTERNAL_REQUEST_URL =
"/circulation-bff/create-ecs-request-external";
private static final String TEST_CENTRAL_TENANT_ID = "testCentralTenantId";

@Test
@SneakyThrows
void postEcsRequestExternalTest() {
EcsRequestExternal requestExternal = buildEcsRequestExternal();
mockEcsTlrExternalRequestCreating(requestExternal);
mockUserTenants();
mockPerform(requestExternal);

wireMockServer.verify(1, postRequestedFor(urlPathMatching(TLR_CREATE_ECS_EXTERNAL_REQUEST_URL))
.withHeader(XOkapiHeaders.TENANT, equalTo(TEST_CENTRAL_TENANT_ID)));
}

private static void mockUserTenants() {
UserTenant userTenant = new UserTenant();
userTenant.setCentralTenantId(TEST_CENTRAL_TENANT_ID);
UserTenantCollection userTenants = new UserTenantCollection(List.of(userTenant), 1);

wireMockServer.stubFor(WireMock.get(urlPathEqualTo(USER_TENANTS_URL))
.withQueryParam("limit", matching("\\d*"))
.withHeader(HEADER_TENANT, equalTo(TENANT_ID_CONSORTIUM))
.willReturn(jsonResponse(asJsonString(userTenants), SC_OK)));
}

private static EcsRequestExternal buildEcsRequestExternal() {
return new EcsRequestExternal(
UUID.randomUUID().toString(),
UUID.randomUUID().toString(),
EcsRequestExternal.RequestLevelEnum.ITEM,
new Date(LocalDate.of(2000, 1, 1).toEpochDay()),
EcsRequestExternal.FulfillmentPreferenceEnum.HOLD_SHELF
);
}

private void mockPerform(EcsRequestExternal requestExternal) throws Exception {
mockMvc.perform(buildRequest(MockMvcRequestBuilders.post(
CIRCULATION_BFF_CREATE_ECS_EXTERNAL_REQUEST_URL), requestExternal)
.header(XOkapiHeaders.TENANT, TENANT_ID_CONSORTIUM));
}

private static void mockEcsTlrExternalRequestCreating(EcsRequestExternal requestExternal) {
wireMockServer.stubFor(WireMock.post(urlMatching(TLR_CREATE_ECS_EXTERNAL_REQUEST_URL))
.withRequestBody(equalToJson(asJsonString(requestExternal)))
.willReturn(jsonResponse(asJsonString(new EcsTlr()), SC_CREATED)));
}
}
Loading