Skip to content

Commit

Permalink
MODTLR-11 Save secondary request info to DB
Browse files Browse the repository at this point in the history
  • Loading branch information
OleksandrVidinieiev committed Feb 6, 2024
1 parent b9ec34c commit 1976d49
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 63 deletions.
2 changes: 2 additions & 0 deletions src/main/java/org/folio/domain/entity/EcsTlrEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@ public class EcsTlrEntity {
private String fulfillmentPreference;
private UUID pickupServicePointId;
private UUID itemId;
private UUID secondaryRequestId;
private String secondaryRequestTenantId;
}
28 changes: 15 additions & 13 deletions src/main/java/org/folio/service/impl/EcsTlrServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@ public Optional<EcsTlr> get(UUID id) {
@Override
public EcsTlr create(EcsTlr ecsTlr) {
log.debug("create:: parameters ecsTlr: {}", () -> ecsTlr);
createRemoteRequest(ecsTlr);
final String instanceId = ecsTlr.getInstanceId();

return requestsMapper.mapEntityToDto(ecsTlrRepository.save(
requestsMapper.mapDtoToEntity(ecsTlr)));
return tenantPickingStrategy.pickTenant(instanceId)
.map(tenantId -> createRequest(ecsTlr, tenantId))
.orElseThrow(() -> new TenantPickingException("Failed to pick tenant for instance " + instanceId));
}

@Override
Expand All @@ -67,22 +68,23 @@ public boolean delete(UUID requestId) {
return false;
}

private Request createRemoteRequest(EcsTlr ecsTlr) {
log.info("createRemoteRequest:: creating remote request for ECS TLR {}", ecsTlr.getId());
String instanceId = ecsTlr.getInstanceId();
private EcsTlr createRequest(EcsTlr ecsTlr, String tenantId) {
log.info("createRemoteRequest:: creating request for ECS TLR {}", ecsTlr.getId());

return tenantPickingStrategy.pickTenant(instanceId)
.map(tenantId -> createRemoteRequest(ecsTlr, tenantId))
.orElseThrow(() -> new TenantPickingException("Failed to pick tenant for instance " + instanceId));
}

private Request createRemoteRequest(EcsTlr ecsTlr, String tenantId) {
Request mappedRequest = requestsMapper.mapDtoToRequest(ecsTlr);
Request createdRequest = tenantScopedExecutionService.execute(tenantId,
() -> circulationClient.createInstanceRequest(mappedRequest));

log.info("createRemoteRequest:: request created: {}", createdRequest.getId());
log.debug("createRemoteRequest:: request: {}", () -> createdRequest);

return createdRequest;
ecsTlr.secondaryRequestTenantId(tenantId)
.secondaryRequestId(createdRequest.getId())
.itemId(createdRequest.getItemId());

log.debug("createRequest:: updating ECS TLR: {}", ecsTlr);

return requestsMapper.mapEntityToDto(ecsTlrRepository.save(
requestsMapper.mapDtoToEntity(ecsTlr)));
}
}
2 changes: 2 additions & 0 deletions src/main/resources/db/changelog/changes/initial_schema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
</column>
<column name="instance_id" type="uuid"/>
<column name="requester_id" type="uuid"/>
<column name="secondary_request_id" type="uuid"/>
<column name="secondary_request_tenant_id" type="varchar(255)"/>
<column name="request_type" type="varchar(255)"/>
<column name="request_level" type="varchar(255)"/>
<column name="request_date" type="timestamp with time zone"/>
Expand Down
26 changes: 6 additions & 20 deletions src/main/resources/swagger.api/schemas/EcsTlr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,26 +40,12 @@ EcsTlr:
itemId:
description: "ID of the item being requested"
$ref: "uuid.yaml"
secondaryRequest:
description: "Secondary request"
type: object
properties:
id:
description: "ID of the secondary request"
$ref: "uuid.yaml"
tenantId:
description: "ID of the tenant secondary request was created in"
$ref: "uuid.yaml"
item:
description: "Requested item"
type: object
properties:
id:
description: "ID of the requested item"
$ref: "uuid.yaml"
status:
description: "Status of the requested item"
type: string
secondaryRequestId:
description: "Secondary request ID"
$ref: "uuid.yaml"
secondaryRequestTenantId:
description: "ID of the tenant secondary request was created in"
type: string

required:
- instanceId
Expand Down
15 changes: 11 additions & 4 deletions src/test/java/org/folio/api/BaseIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ public class BaseIT {
protected MockMvc mockMvc;
protected static WireMockServer wireMockServer;
protected static final String TOKEN = "test_token";
protected static final String TENANT = "diku";
protected static final String TENANT_ID_DIKU = "diku";
protected static final String TENANT_ID_UNIVERSITY = "university";
protected static final String TENANT_ID_COLLEGE = "college";
private static final PostgreSQLContainer<?> postgresDBContainer = new PostgreSQLContainer<>("postgres:12-alpine");
private static final int WIRE_MOCK_PORT = TestSocketUtils.findAvailableTcpPort();
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL)
protected static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
Expand Down Expand Up @@ -89,7 +91,7 @@ public static HttpHeaders defaultHeaders() {
final HttpHeaders httpHeaders = new HttpHeaders();

httpHeaders.setContentType(APPLICATION_JSON);
httpHeaders.put(XOkapiHeaders.TENANT, List.of(TENANT));
httpHeaders.put(XOkapiHeaders.TENANT, List.of(TENANT_ID_DIKU));
httpHeaders.add(XOkapiHeaders.URL, wireMockServer.baseUrl());
httpHeaders.add(XOkapiHeaders.TOKEN, TOKEN);
httpHeaders.add(XOkapiHeaders.USER_ID, "08d51c7a-0f36-4f3d-9e35-d285612a23df");
Expand All @@ -102,6 +104,11 @@ public static String asJsonString(Object value) {
return OBJECT_MAPPER.writeValueAsString(value);
}

@SneakyThrows
public static <T> T fromJsonString(String json, Class<T> objectType) {
return OBJECT_MAPPER.readValue(json, objectType);
}

public static class DockerPostgresDataSourceInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(@NotNull ConfigurableApplicationContext applicationContext) {
Expand All @@ -125,7 +132,7 @@ protected WebTestClient.RequestBodySpec buildRequest(HttpMethod method, String u
.uri(uri)
.accept(APPLICATION_JSON)
.contentType(APPLICATION_JSON)
.header(XOkapiHeaders.TENANT, TENANT)
.header(XOkapiHeaders.TENANT, TENANT_ID_DIKU)
.header(XOkapiHeaders.URL, wireMockServer.baseUrl())
.header(XOkapiHeaders.TOKEN, TOKEN)
.header(XOkapiHeaders.USER_ID, randomId());
Expand Down
57 changes: 31 additions & 26 deletions src/test/java/org/folio/api/EcsTlrApiTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.folio.domain.dto.Instance;
import org.folio.domain.dto.Item;
import org.folio.domain.dto.ItemStatus;
import org.folio.domain.dto.Request;
import org.folio.domain.dto.SearchInstancesResponse;
import org.folio.spring.FolioExecutionContext;
import org.folio.spring.FolioModuleMetadata;
Expand All @@ -31,7 +32,6 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.MediaType;

import com.github.tomakehurst.wiremock.client.WireMock;
Expand All @@ -48,8 +48,6 @@ class EcsTlrApiTest extends BaseIT {
private FolioExecutionContext context;
@Autowired
private FolioModuleMetadata moduleMetadata;
@Autowired
private TestRestTemplate restTemplate;
private FolioExecutionContextSetter contextSetter;

@BeforeEach
Expand All @@ -73,45 +71,55 @@ void getByIdNotFound() throws Exception {

@Test
void titleLevelRequestIsCreatedForDifferentTenant() {
String instanceRequestId = randomId();
String availableItemId = randomId();
EcsTlr ecsTlr = buildEcsTlr(INSTANCE_ID);
String ecsTlrJson = asJsonString(ecsTlr);

SearchInstancesResponse mockSearchInstancesResponse = new SearchInstancesResponse()
.totalRecords(2)
.instances(List.of(
new Instance().id(INSTANCE_ID)
.tenantId("college")
.tenantId(TENANT_ID_UNIVERSITY)
.items(List.of(
buildItem("Available"),
buildItem("Checked out"),
buildItem("In transit"),
buildItem("Paged"))),
buildItem(randomId(), "Checked out"),
buildItem(randomId(), "In transit"))),
new Instance().id(INSTANCE_ID)
.tenantId("university")
.tenantId(TENANT_ID_COLLEGE)
.items(List.of(
buildItem("Available"),
buildItem("Checked out"),
buildItem("Available"),
buildItem("In transit")))
buildItem(randomId(), "Checked out"),
buildItem(availableItemId, "Available")))
));

Request mockInstanceRequestResponse = new Request()
.id(instanceRequestId)
.requestLevel(Request.RequestLevelEnum.TITLE)
.requestType(Request.RequestTypeEnum.PAGE)
.instanceId(INSTANCE_ID)
.itemId(availableItemId);

wireMockServer.stubFor(WireMock.get(urlMatching(".*" + SEARCH_INSTANCES_URL))
.willReturn(jsonResponse(mockSearchInstancesResponse, HttpStatus.SC_OK)));

wireMockServer.stubFor(WireMock.post(urlMatching(".*" + INSTANCE_REQUESTS_URL))
.willReturn(jsonResponse(ecsTlrJson, HttpStatus.SC_CREATED)));
.willReturn(jsonResponse(asJsonString(mockInstanceRequestResponse), HttpStatus.SC_CREATED)));

assertEquals(TENANT, getCurrentTenantId());
EcsTlr expectedPostEcsTlrResponse = fromJsonString(ecsTlrJson, EcsTlr.class)
.secondaryRequestId(instanceRequestId)
.secondaryRequestTenantId(TENANT_ID_COLLEGE)
.itemId(availableItemId);

assertEquals(TENANT_ID_DIKU, getCurrentTenantId());
doPost(TLR_URL, ecsTlr)
.expectStatus().isCreated()
.expectBody().json(ecsTlrJson);
assertEquals(TENANT, getCurrentTenantId());
.expectBody().json(asJsonString(expectedPostEcsTlrResponse), true);
assertEquals(TENANT_ID_DIKU, getCurrentTenantId());

wireMockServer.verify(getRequestedFor(urlMatching(".*" + SEARCH_INSTANCES_URL))
.withHeader(TENANT_HEADER, equalTo(TENANT)));
.withHeader(TENANT_HEADER, equalTo(TENANT_ID_DIKU)));

wireMockServer.verify(postRequestedFor(urlMatching(".*" + INSTANCE_REQUESTS_URL))
.withHeader(TENANT_HEADER, equalTo("university")) // because it has most available items
.withHeader(TENANT_HEADER, equalTo(TENANT_ID_COLLEGE)) // because this tenant has available item
.withRequestBody(equalToJson(ecsTlrJson)));
}

Expand All @@ -129,7 +137,7 @@ void canNotCreateEcsTlrWhenFailedToPickTenant() {
.expectStatus().isEqualTo(500);

wireMockServer.verify(getRequestedFor(urlMatching(".*" + SEARCH_INSTANCES_URL))
.withHeader(TENANT_HEADER, equalTo(TENANT)));
.withHeader(TENANT_HEADER, equalTo(TENANT_ID_DIKU)));
}

private String getCurrentTenantId() {
Expand All @@ -149,20 +157,17 @@ private FolioExecutionContextSetter initContext() {
private static EcsTlr buildEcsTlr(String instanceId) {
return new EcsTlr()
.id(randomId())
.itemId(randomId())
.instanceId(instanceId)
.requesterId(randomId())
.pickupServicePointId(randomId())
.fulfillmentPreference(EcsTlr.FulfillmentPreferenceEnum.DELIVERY)
.patronComments("random comment")
.requestExpirationDate(new Date())
.requestType(EcsTlr.RequestTypeEnum.PAGE)
.requestLevel(EcsTlr.RequestLevelEnum.TITLE);
.requestExpirationDate(new Date());
}

private static Item buildItem(String status) {
private static Item buildItem(String id, String status) {
return new Item()
.id(randomId())
.id(id)
.status(new ItemStatus().name(status));
}

Expand Down

0 comments on commit 1976d49

Please sign in to comment.