From 7a5fd749dc8a62d4ff633bd54e92e637b6f47c1b Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Fri, 13 Dec 2024 16:40:32 +0530 Subject: [PATCH 01/15] CIRCSTORE-540: ItemUpdateProcessorForRequest update item's location and SP --- ramls/locations/location.json | 75 +++++++++++++++++++ ramls/locations/locations.json | 24 ++++++ ramls/request-storage.raml | 2 + .../rest/client/InventoryStorageClient.java | 8 ++ .../event/handler/ItemUpdateEventHandler.java | 3 +- .../ItemUpdateProcessorForRequest.java | 69 ++++++++++++++++- .../support/builders/LocationBuilder.java | 30 ++++++++ 7 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 ramls/locations/location.json create mode 100644 ramls/locations/locations.json create mode 100644 src/test/java/org/folio/rest/support/builders/LocationBuilder.java diff --git a/ramls/locations/location.json b/ramls/locations/location.json new file mode 100644 index 000000000..6f0ac1da0 --- /dev/null +++ b/ramls/locations/location.json @@ -0,0 +1,75 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "A (shelf) location, the forth-level location unit below institution, campus, and library.", + "javaType": "org.folio.rest.jaxrs.model.Location", + "type": "object", + "properties": { + "id": { + "description": "id of this (shelf) location record as UUID.", + "type": "string" + }, + "name": { + "description": "Name of the (shelf) location", + "type": "string" + }, + "code": { + "description": "Code of the (shelf) location, usually an abbreviation of the name.", + "type": "string" + }, + "description": { + "description": "Description of the (shelf) location.", + "type": "string" + }, + "discoveryDisplayName": { + "description": "Name of the (shelf) location to be shown in the discovery.", + "type": "string" + }, + "isActive": { + "description": "Whether this (shelf) location is active. Inactive (shelf) locations can no longer been used.", + "type": "boolean" + }, + "institutionId": { + "description": "The UUID of the institution, the first-level location unit, this (shelf) location belongs to.", + "type": "string" + }, + "campusId": { + "description": "The UUID of the campus, the second-level location unit, this (shelf) location belongs to.", + "type": "string" + }, + "libraryId": { + "description": "The UUID of the library, the third-level location unit, this (shelf) location belongs to.", + "type": "string" + }, + "primaryServicePoint": { + "description": "The UUID of the primary service point of this (shelf) location.", + "format": "uuid", + "type": "string" + }, + "servicePointIds": { + "description": "All service points that this (shelf) location has.", + "type": "array", + "items": { + "description": "The UUID of a service point that belongs to this (shelf) location.", + "type": "string", + "format": "uuid", + "not": { + "type": "null" + } + } + }, + "metadata": { + "type": "object", + "$ref": "../raml-util/schemas/metadata.schema", + "readonly": true + } + }, + "additionalProperties": false, + "required": [ + "name", + "code", + "institutionId", + "campusId", + "libraryId", + "primaryServicePoint" + ] +} diff --git a/ramls/locations/locations.json b/ramls/locations/locations.json new file mode 100644 index 000000000..df6bdad1d --- /dev/null +++ b/ramls/locations/locations.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "List of (shelf) locations.", + "type": "object", + "properties": { + "locations": { + "id": "locations", + "description": "List of (shelf) locations.", + "type": "array", + "items": { + "type": "object", + "$ref": "location.json" + } + }, + "totalRecords": { + "description": "Estimated or exact total number of records", + "type": "integer" + } + }, + "required": [ + "locations", + "totalRecords" + ] +} diff --git a/ramls/request-storage.raml b/ramls/request-storage.raml index cf32c0fc7..29f93e5f4 100644 --- a/ramls/request-storage.raml +++ b/ramls/request-storage.raml @@ -13,6 +13,8 @@ types: requests: !include requests.json errors: !include raml-util/schemas/errors.schema parameters: !include raml-util/schemas/parameters.schema + location: !include locations/location.json + locations: !include locations/locations.json traits: pageable: !include raml-util/traits/pageable.raml diff --git a/src/main/java/org/folio/rest/client/InventoryStorageClient.java b/src/main/java/org/folio/rest/client/InventoryStorageClient.java index b9a830755..2d607c470 100644 --- a/src/main/java/org/folio/rest/client/InventoryStorageClient.java +++ b/src/main/java/org/folio/rest/client/InventoryStorageClient.java @@ -3,6 +3,7 @@ import java.util.Collection; import java.util.Map; +import org.folio.rest.jaxrs.model.Location; import org.folio.rest.jaxrs.model.Servicepoint; import io.vertx.core.Future; @@ -12,6 +13,9 @@ public class InventoryStorageClient extends OkapiClient { private static final String SERVICE_POINTS_URL = "/service-points"; private static final String SERVICE_POINTS_COLLECTION_NAME = "servicepoints"; + private static final String LOCATION_URL = "/locations"; + private static final String LOCATION_COLLECTION_NAME = "locations"; + public InventoryStorageClient(Vertx vertx, Map okapiHeaders) { super(vertx, okapiHeaders); } @@ -20,4 +24,8 @@ public Future> getServicePoints(Collection ids) return get(SERVICE_POINTS_URL, ids, SERVICE_POINTS_COLLECTION_NAME, Servicepoint.class); } + public Future> getLocations(Collection ids) { + return get(LOCATION_URL, ids, LOCATION_COLLECTION_NAME, Location.class); + } + } diff --git a/src/main/java/org/folio/service/event/handler/ItemUpdateEventHandler.java b/src/main/java/org/folio/service/event/handler/ItemUpdateEventHandler.java index c27bc6d96..561b7cf2b 100644 --- a/src/main/java/org/folio/service/event/handler/ItemUpdateEventHandler.java +++ b/src/main/java/org/folio/service/event/handler/ItemUpdateEventHandler.java @@ -5,6 +5,7 @@ import org.apache.commons.collections4.map.CaseInsensitiveMap; import org.folio.kafka.AsyncRecordHandler; import org.folio.persist.RequestRepository; +import org.folio.rest.client.InventoryStorageClient; import org.folio.service.event.handler.processor.ItemUpdateProcessorForRequest; import io.vertx.core.Context; @@ -26,7 +27,7 @@ public Future handle(KafkaConsumerRecord kafkaConsumerRe new CaseInsensitiveMap<>(kafkaHeadersToMap(kafkaConsumerRecord.headers())); ItemUpdateProcessorForRequest itemUpdateProcessorForRequest = - new ItemUpdateProcessorForRequest(new RequestRepository(context, headers)); + new ItemUpdateProcessorForRequest(new RequestRepository(context, headers), new InventoryStorageClient(context.owner(), headers)); return itemUpdateProcessorForRequest.run(kafkaConsumerRecord.key(), payload); } diff --git a/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java b/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java index 26266f056..18d816418 100644 --- a/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java +++ b/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java @@ -1,16 +1,26 @@ package org.folio.service.event.handler.processor; +import static io.vertx.core.Future.succeededFuture; import static org.apache.commons.lang3.ObjectUtils.notEqual; import static org.folio.service.event.InventoryEventType.INVENTORY_ITEM_UPDATED; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.List; +import java.util.Objects; +import io.vertx.core.Future; +import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.folio.persist.RequestRepository; +import org.folio.rest.client.InventoryStorageClient; import org.folio.rest.jaxrs.model.CallNumberComponents; +import org.folio.rest.jaxrs.model.Item; +import org.folio.rest.jaxrs.model.Location; import org.folio.rest.jaxrs.model.Request; +import org.folio.rest.jaxrs.model.Servicepoint; import org.folio.rest.persist.Criteria.Criteria; import org.folio.rest.persist.Criteria.Criterion; @@ -24,9 +34,11 @@ public class ItemUpdateProcessorForRequest extends UpdateEventProcessor private static final String CALL_NUMBER_KEY = "callNumber"; private static final String CALL_NUMBER_PREFIX_KEY = "prefix"; private static final String CALL_NUMBER_SUFFIX_KEY = "suffix"; + private final InventoryStorageClient inventoryStorageClient; - public ItemUpdateProcessorForRequest(RequestRepository repository) { + public ItemUpdateProcessorForRequest(RequestRepository repository, InventoryStorageClient inventoryStorageClient) { super(INVENTORY_ITEM_UPDATED, repository); + this.inventoryStorageClient = inventoryStorageClient; } protected List> collectRelevantChanges(JsonObject payload) { @@ -50,9 +62,64 @@ protected List> collectRelevantChanges(JsonObject payload) { changes.add(new Change<>(request -> request.getSearchIndex().setShelvingOrder(newShelvingOrder))); } + updateItemAndServicePoint(newObject, changes); + + return changes; } + private void updateItemAndServicePoint(JsonObject newObject, + List> changes) { + String effectiveLocationId = newObject.getString("effectiveLocationId"); + log.info("ItemUpdateProcessorForRequest :: updateItemAndServicePoint(): " + + "effectiveLocationId: {}", effectiveLocationId); + changes.add(new Change<>(request -> { + if (request.getItem() == null) { + request.setItem(new Item()); + } + request.getItem().setItemEffectiveLocationId(effectiveLocationId); + inventoryStorageClient.getLocations(Collections.singletonList(effectiveLocationId)) + .compose(locations -> setEffectiveLocationName(request, locations, + effectiveLocationId)) + .compose(primaryServicePoint -> { + if (!StringUtils.isBlank(primaryServicePoint)) { + request.getItem().setRetrievalServicePointId(primaryServicePoint); + inventoryStorageClient.getServicePoints(Collections.singletonList(effectiveLocationId)) + .compose(servicePoints -> setServicePoint(request, servicePoints, + primaryServicePoint)); + } + return succeededFuture(); + }); + })); + } + + private Future setEffectiveLocationName(Request request, + Collection locations, String effectiveLocationId) { + Location effectiveLocation = locations.stream() + .filter(l -> l.getId().equals(effectiveLocationId)) + .findFirst().orElse(null); + log.info("ItemUpdateProcessorForRequest :: setEffectiveLocationName(): " + + "locationsName: {}", effectiveLocation.getName()); + if(Objects.nonNull(effectiveLocation)) { + request.getItem().setItemEffectiveLocationName(effectiveLocation.getName()); + return succeededFuture(effectiveLocation.getPrimaryServicePoint().toString()); + } + return succeededFuture(); + } + + private Future setServicePoint(Request request, + Collection servicePoints, String primaryServicePoint) { + Servicepoint retrievalServicePoint = servicePoints.stream() + .filter(sp -> sp.getId().equals(primaryServicePoint)) + .findFirst().orElse(null); + log.info("ItemUpdateProcessorForRequest :: setServicePoint(): " + + "servicePointName: {}", retrievalServicePoint.getName()); + if(Objects.nonNull(retrievalServicePoint)) { + request.getItem().setRetrievalServicePointName(retrievalServicePoint.getName()); + } + return succeededFuture(); + } + @Override protected Criterion criterionForObjectsToBeUpdated(String oldObjectId) { log.info("criteriaForObjectsToBeUpdated:: oldObjectId: {}", oldObjectId); diff --git a/src/test/java/org/folio/rest/support/builders/LocationBuilder.java b/src/test/java/org/folio/rest/support/builders/LocationBuilder.java new file mode 100644 index 000000000..fe50b6c72 --- /dev/null +++ b/src/test/java/org/folio/rest/support/builders/LocationBuilder.java @@ -0,0 +1,30 @@ +package org.folio.rest.support.builders; + +import io.vertx.core.json.JsonObject; +import lombok.AllArgsConstructor; +import lombok.With; + +import java.util.UUID; + +@With +@AllArgsConstructor +public class LocationBuilder extends JsonBuilder implements Builder { + private final String id; + private final String name; + private final String code; + private final String primaryServicePoint; + + public LocationBuilder(String name) { + this(UUID.randomUUID().toString(), name, null, null); + } + + @Override + public JsonObject create() { + JsonObject location = new JsonObject(); + put(location, "id", this.id); + put(location, "name", this.name); + put(location, "code", this.code); + put(location, "primaryServicePoint", this.primaryServicePoint); + return location; + } +} From 78f28d05d335debc41db06a1909a1c4e7137e610 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Fri, 13 Dec 2024 16:50:03 +0530 Subject: [PATCH 02/15] CIRCSTORE-540: added log for debugging --- .../service/event/handler/ItemUpdateEventHandler.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/folio/service/event/handler/ItemUpdateEventHandler.java b/src/main/java/org/folio/service/event/handler/ItemUpdateEventHandler.java index 561b7cf2b..75295905e 100644 --- a/src/main/java/org/folio/service/event/handler/ItemUpdateEventHandler.java +++ b/src/main/java/org/folio/service/event/handler/ItemUpdateEventHandler.java @@ -1,11 +1,14 @@ package org.folio.service.event.handler; +import static org.apache.logging.log4j.LogManager.getLogger; import static org.folio.kafka.KafkaHeaderUtils.kafkaHeadersToMap; import org.apache.commons.collections4.map.CaseInsensitiveMap; +import org.apache.logging.log4j.Logger; import org.folio.kafka.AsyncRecordHandler; import org.folio.persist.RequestRepository; import org.folio.rest.client.InventoryStorageClient; +import org.folio.service.event.EntityChangedEventPublisher; import org.folio.service.event.handler.processor.ItemUpdateProcessorForRequest; import io.vertx.core.Context; @@ -15,7 +18,7 @@ public class ItemUpdateEventHandler implements AsyncRecordHandler { private final Context context; - + private static final Logger log = getLogger(ItemUpdateEventHandler.class); public ItemUpdateEventHandler(Context context) { this.context = context; } @@ -25,7 +28,7 @@ public Future handle(KafkaConsumerRecord kafkaConsumerRe JsonObject payload = new JsonObject(kafkaConsumerRecord.value()); CaseInsensitiveMap headers = new CaseInsensitiveMap<>(kafkaHeadersToMap(kafkaConsumerRecord.headers())); - + log.info("ItemUpdateEventHandler :: handle() :: kafkaHeaders: {}", headers); ItemUpdateProcessorForRequest itemUpdateProcessorForRequest = new ItemUpdateProcessorForRequest(new RequestRepository(context, headers), new InventoryStorageClient(context.owner(), headers)); From a0341dd698730f380281623f62a3651aaf992c0a Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Fri, 13 Dec 2024 17:41:24 +0530 Subject: [PATCH 03/15] CIRCSTORE-540: added log for debugging --- .../handler/processor/ItemUpdateProcessorForRequest.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java b/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java index 18d816418..4b234e548 100644 --- a/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java +++ b/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java @@ -11,6 +11,7 @@ import java.util.Objects; import io.vertx.core.Future; +import io.vertx.core.Handler; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -86,9 +87,15 @@ private void updateItemAndServicePoint(JsonObject newObject, request.getItem().setRetrievalServicePointId(primaryServicePoint); inventoryStorageClient.getServicePoints(Collections.singletonList(effectiveLocationId)) .compose(servicePoints -> setServicePoint(request, servicePoints, - primaryServicePoint)); + primaryServicePoint)).onFailure(throwable -> { + log.info("ItemUpdateProcessorForRequest :: Error while " + + "fetching ServicePoint: {}", throwable.toString()); + });; } return succeededFuture(); + }).onFailure(throwable -> { + log.info("ItemUpdateProcessorForRequest :: Error while fetching " + + "gLocations: {}", throwable.toString()); }); })); } From d3653a56652f2ef87de26d1a630b87d40d4e3556 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Fri, 13 Dec 2024 18:11:06 +0530 Subject: [PATCH 04/15] CIRCSTORE-540: set additionalProperties true inside location.json --- ramls/locations/location.json | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/ramls/locations/location.json b/ramls/locations/location.json index 6f0ac1da0..31a13886a 100644 --- a/ramls/locations/location.json +++ b/ramls/locations/location.json @@ -63,13 +63,5 @@ "readonly": true } }, - "additionalProperties": false, - "required": [ - "name", - "code", - "institutionId", - "campusId", - "libraryId", - "primaryServicePoint" - ] + "additionalProperties": true } From 32c8464c1893610ed52f174fa4eb7e689992dea7 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Fri, 13 Dec 2024 19:10:02 +0530 Subject: [PATCH 05/15] CIRCSTORE-540: fix exception issue --- .../event/handler/processor/ItemUpdateProcessorForRequest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java b/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java index 4b234e548..01db291fd 100644 --- a/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java +++ b/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java @@ -85,7 +85,7 @@ private void updateItemAndServicePoint(JsonObject newObject, .compose(primaryServicePoint -> { if (!StringUtils.isBlank(primaryServicePoint)) { request.getItem().setRetrievalServicePointId(primaryServicePoint); - inventoryStorageClient.getServicePoints(Collections.singletonList(effectiveLocationId)) + inventoryStorageClient.getServicePoints(Collections.singletonList(primaryServicePoint)) .compose(servicePoints -> setServicePoint(request, servicePoints, primaryServicePoint)).onFailure(throwable -> { log.info("ItemUpdateProcessorForRequest :: Error while " + From 73c1ad5d7ad1b454280173a2544913624d05976e Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Fri, 13 Dec 2024 19:11:45 +0530 Subject: [PATCH 06/15] CIRCSTORE-540: fix exception issue --- .../event/handler/processor/ItemUpdateProcessorForRequest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java b/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java index 01db291fd..bf25daa6a 100644 --- a/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java +++ b/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java @@ -12,6 +12,7 @@ import io.vertx.core.Future; import io.vertx.core.Handler; +import io.vertx.core.json.Json; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -124,6 +125,8 @@ private Future setServicePoint(Request request, if(Objects.nonNull(retrievalServicePoint)) { request.getItem().setRetrievalServicePointName(retrievalServicePoint.getName()); } + log.info("ItemUpdateProcessorForRequest :: setServicePoint() :: request" + + ".item: {}", Json.encode(request.getItem())); return succeededFuture(); } From 15344f55079d26efe10517f0ce50fa04963db25b Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Mon, 16 Dec 2024 19:28:04 +0530 Subject: [PATCH 07/15] CIRCSTORE-540: 1) added async mechanism in EventProcessor class to execute and support non-blocking api calls. 2) Added test case. --- .../handler/processor/EventProcessor.java | 20 ++-- .../ItemUpdateProcessorForRequest.java | 112 ++++++++++-------- ...ePointDeleteProcessorForRequestPolicy.java | 5 +- ...ServicePointUpdateProcessorForRequest.java | 5 +- ...ePointUpdateProcessorForRequestPolicy.java | 5 +- .../rest/api/EventConsumerVerticleTest.java | 93 ++++++++++++++- 6 files changed, 174 insertions(+), 66 deletions(-) diff --git a/src/main/java/org/folio/service/event/handler/processor/EventProcessor.java b/src/main/java/org/folio/service/event/handler/processor/EventProcessor.java index 111d91524..d3b1fad83 100644 --- a/src/main/java/org/folio/service/event/handler/processor/EventProcessor.java +++ b/src/main/java/org/folio/service/event/handler/processor/EventProcessor.java @@ -49,20 +49,24 @@ private Future> processEvent(JsonObject payload) { return succeededFuture(); } - List> relevantChanges = collectRelevantChanges(payload); + Future>> relevantChangesFuture = + collectRelevantChanges(payload); - if (relevantChanges.isEmpty()) { - log.info("processEvent:: no relevant changes detected"); - return succeededFuture(); - } + return relevantChangesFuture.compose(relevantChanges -> { + + if (relevantChanges.isEmpty()) { + log.info("processEvent:: no relevant changes detected"); + return succeededFuture(); + } - log.info("processEvent:: {} relevant changes detected, applying", relevantChanges::size); - return applyChanges(relevantChanges, payload); + log.info("processEvent:: {} relevant changes detected, applying", relevantChanges::size); + return applyChanges(relevantChanges, payload); + }); } protected abstract boolean validatePayload(JsonObject payload); - protected abstract List> collectRelevantChanges(JsonObject payload); + protected abstract Future>> collectRelevantChanges(JsonObject payload); private Future> applyChanges(List> changes, JsonObject payload) { log.debug("applyChanges:: payload: {}", payload); diff --git a/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java b/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java index bf25daa6a..75c41e1e2 100644 --- a/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java +++ b/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java @@ -7,12 +7,12 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import io.vertx.core.Future; -import io.vertx.core.Handler; -import io.vertx.core.json.Json; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -31,19 +31,26 @@ public class ItemUpdateProcessorForRequest extends UpdateEventProcessor { private static final Logger log = LogManager.getLogger(ItemUpdateProcessorForRequest.class); + private final InventoryStorageClient inventoryStorageClient; + private static final String EFFECTIVE_SHELVING_ORDER_KEY = "effectiveShelvingOrder"; private static final String EFFECTIVE_CALL_NUMBER_COMPONENTS_KEY = "effectiveCallNumberComponents"; private static final String CALL_NUMBER_KEY = "callNumber"; private static final String CALL_NUMBER_PREFIX_KEY = "prefix"; private static final String CALL_NUMBER_SUFFIX_KEY = "suffix"; - private final InventoryStorageClient inventoryStorageClient; + + public static final String ITEM_EFFECTIVE_LOCATION_ID = "itemEffectiveLocationId"; + public static final String ITEM_EFFECTIVE_LOCATION_NAME = "itemEffectiveLocationName"; + public static final String RETRIEVAL_SERVICE_POINT_ID = "retrievalServicePointId"; + public static final String RETRIEVAL_SERVICE_POINT_NAME = "retrievalServicePointName"; public ItemUpdateProcessorForRequest(RequestRepository repository, InventoryStorageClient inventoryStorageClient) { super(INVENTORY_ITEM_UPDATED, repository); this.inventoryStorageClient = inventoryStorageClient; } - protected List> collectRelevantChanges(JsonObject payload) { + @Override + protected Future>> collectRelevantChanges(JsonObject payload) { JsonObject oldObject = payload.getJsonObject("old"); JsonObject newObject = payload.getJsonObject("new"); @@ -64,72 +71,75 @@ protected List> collectRelevantChanges(JsonObject payload) { changes.add(new Change<>(request -> request.getSearchIndex().setShelvingOrder(newShelvingOrder))); } - updateItemAndServicePoint(newObject, changes); - - - return changes; + Future> fetchLocationAndServicePoint = updateItemAndServicePoint(newObject, changes); + return fetchLocationAndServicePoint + .compose(locationAndSpData -> addLocationAndServicePointChanges(locationAndSpData, changes)) + .compose(res -> Future.succeededFuture(changes)); } - private void updateItemAndServicePoint(JsonObject newObject, - List> changes) { - String effectiveLocationId = newObject.getString("effectiveLocationId"); - log.info("ItemUpdateProcessorForRequest :: updateItemAndServicePoint(): " + - "effectiveLocationId: {}", effectiveLocationId); + private static Future>> addLocationAndServicePointChanges(Map locationAndSpData, List> changes) { changes.add(new Change<>(request -> { if (request.getItem() == null) { request.setItem(new Item()); } - request.getItem().setItemEffectiveLocationId(effectiveLocationId); - inventoryStorageClient.getLocations(Collections.singletonList(effectiveLocationId)) - .compose(locations -> setEffectiveLocationName(request, locations, - effectiveLocationId)) - .compose(primaryServicePoint -> { - if (!StringUtils.isBlank(primaryServicePoint)) { - request.getItem().setRetrievalServicePointId(primaryServicePoint); - inventoryStorageClient.getServicePoints(Collections.singletonList(primaryServicePoint)) - .compose(servicePoints -> setServicePoint(request, servicePoints, - primaryServicePoint)).onFailure(throwable -> { - log.info("ItemUpdateProcessorForRequest :: Error while " + - "fetching ServicePoint: {}", throwable.toString()); - });; - } - return succeededFuture(); - }).onFailure(throwable -> { - log.info("ItemUpdateProcessorForRequest :: Error while fetching " + - "gLocations: {}", throwable.toString()); - }); + request.getItem().setItemEffectiveLocationId(locationAndSpData.get("itemEffectiveLocationId")); + request.getItem().setItemEffectiveLocationName(locationAndSpData.get("itemEffectiveLocationName")); + request.getItem().setRetrievalServicePointId(locationAndSpData.get("retrievalServicePointId")); + request.getItem().setRetrievalServicePointName(locationAndSpData.get("retrievalServicePointName")); })); + return Future.succeededFuture(changes); + } + + private Future> updateItemAndServicePoint(JsonObject newObject, List> changes) { + String effectiveLocationId = newObject.getString("effectiveLocationId"); + Map locationAndSpData = new HashMap<>(); + locationAndSpData.put(ITEM_EFFECTIVE_LOCATION_ID, effectiveLocationId); + return inventoryStorageClient.getLocations(Collections.singletonList(effectiveLocationId)) + .compose(locations -> setEffectiveLocationData(locations, effectiveLocationId, locationAndSpData)) + .compose(primaryServicePoint -> setRetrievalServicePointData(primaryServicePoint, locationAndSpData)) + .compose(e -> Future.succeededFuture(locationAndSpData)) + .onFailure(throwable -> { + log.info("ItemUpdateProcessorForRequest :: Error while fetching Locations: {}", throwable.toString()); + }); } - private Future setEffectiveLocationName(Request request, - Collection locations, String effectiveLocationId) { + private static Future setEffectiveLocationData(Collection locations, String effectiveLocationId, + Map locationAndSpData) { Location effectiveLocation = locations.stream() - .filter(l -> l.getId().equals(effectiveLocationId)) - .findFirst().orElse(null); - log.info("ItemUpdateProcessorForRequest :: setEffectiveLocationName(): " + - "locationsName: {}", effectiveLocation.getName()); - if(Objects.nonNull(effectiveLocation)) { - request.getItem().setItemEffectiveLocationName(effectiveLocation.getName()); + .filter(l -> l.getId().equals(effectiveLocationId)) + .findFirst().orElse(null); + log.info("ItemUpdateProcessorForRequest :: setEffectiveLocationName(): locationsName: {}", + JsonObject.mapFrom(effectiveLocation).encode()); + if (Objects.nonNull(effectiveLocation)) { + locationAndSpData.put(ITEM_EFFECTIVE_LOCATION_NAME, effectiveLocation.getName()); return succeededFuture(effectiveLocation.getPrimaryServicePoint().toString()); } return succeededFuture(); } - private Future setServicePoint(Request request, - Collection servicePoints, String primaryServicePoint) { - Servicepoint retrievalServicePoint = servicePoints.stream() - .filter(sp -> sp.getId().equals(primaryServicePoint)) - .findFirst().orElse(null); - log.info("ItemUpdateProcessorForRequest :: setServicePoint(): " + - "servicePointName: {}", retrievalServicePoint.getName()); - if(Objects.nonNull(retrievalServicePoint)) { - request.getItem().setRetrievalServicePointName(retrievalServicePoint.getName()); + private Future setRetrievalServicePointData(String primaryServicePoint, Map locationAndSpData) { + if (!StringUtils.isBlank(primaryServicePoint)) { + locationAndSpData.put(RETRIEVAL_SERVICE_POINT_ID, primaryServicePoint); + return inventoryStorageClient.getServicePoints(Collections.singletonList(primaryServicePoint)) + .compose(servicePoints -> { + Servicepoint retrievalServicePoint = servicePoints.stream() + .filter(sp -> sp.getId().equals(primaryServicePoint)) + .findFirst().orElse(null); + log.info("ItemUpdateProcessorForRequest :: setServicePoint(): {}", + JsonObject.mapFrom(retrievalServicePoint).encode()); + if (Objects.nonNull(retrievalServicePoint)) { + locationAndSpData.put(RETRIEVAL_SERVICE_POINT_NAME, retrievalServicePoint.getName()); + } + return succeededFuture(); + }).onFailure(throwable -> { + log.info("ItemUpdateProcessorForRequest :: Error while fetching ServicePoint: {}", + throwable.toString()); + }); } - log.info("ItemUpdateProcessorForRequest :: setServicePoint() :: request" + - ".item: {}", Json.encode(request.getItem())); return succeededFuture(); } + @Override protected Criterion criterionForObjectsToBeUpdated(String oldObjectId) { log.info("criteriaForObjectsToBeUpdated:: oldObjectId: {}", oldObjectId); diff --git a/src/main/java/org/folio/service/event/handler/processor/ServicePointDeleteProcessorForRequestPolicy.java b/src/main/java/org/folio/service/event/handler/processor/ServicePointDeleteProcessorForRequestPolicy.java index 9ab5d3576..9ae792ce4 100644 --- a/src/main/java/org/folio/service/event/handler/processor/ServicePointDeleteProcessorForRequestPolicy.java +++ b/src/main/java/org/folio/service/event/handler/processor/ServicePointDeleteProcessorForRequestPolicy.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.List; +import io.vertx.core.Future; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.folio.persist.RequestPolicyRepository; @@ -27,7 +28,7 @@ public ServicePointDeleteProcessorForRequestPolicy( } @Override - protected List> collectRelevantChanges(JsonObject payload) { + protected Future>> collectRelevantChanges(JsonObject payload) { log.debug("collectRelevantChanges:: payload: {}", payload); JsonObject oldObject = payload.getJsonObject("old"); @@ -38,7 +39,7 @@ protected List> collectRelevantChanges(JsonObject payload) changes.add(new Change<>(requestPolicy -> removeServicePointFromRequestPolicy(requestPolicy, deletedServicePointId))); - return changes; + return Future.succeededFuture(changes); } @Override diff --git a/src/main/java/org/folio/service/event/handler/processor/ServicePointUpdateProcessorForRequest.java b/src/main/java/org/folio/service/event/handler/processor/ServicePointUpdateProcessorForRequest.java index 34e30bf64..4054d6b4b 100644 --- a/src/main/java/org/folio/service/event/handler/processor/ServicePointUpdateProcessorForRequest.java +++ b/src/main/java/org/folio/service/event/handler/processor/ServicePointUpdateProcessorForRequest.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.List; +import io.vertx.core.Future; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.folio.persist.RequestRepository; @@ -24,7 +25,7 @@ public ServicePointUpdateProcessorForRequest(RequestRepository requestRepository } @Override - protected List> collectRelevantChanges(JsonObject payload) { + protected Future>> collectRelevantChanges(JsonObject payload) { JsonObject oldObject = payload.getJsonObject("old"); JsonObject newObject = payload.getJsonObject("new"); @@ -40,7 +41,7 @@ protected List> collectRelevantChanges(JsonObject payload) { .setPickupServicePointName(newServicePointName))); } - return changes; + return Future.succeededFuture(changes); } @Override diff --git a/src/main/java/org/folio/service/event/handler/processor/ServicePointUpdateProcessorForRequestPolicy.java b/src/main/java/org/folio/service/event/handler/processor/ServicePointUpdateProcessorForRequestPolicy.java index e6cb8aad9..33a3db946 100644 --- a/src/main/java/org/folio/service/event/handler/processor/ServicePointUpdateProcessorForRequestPolicy.java +++ b/src/main/java/org/folio/service/event/handler/processor/ServicePointUpdateProcessorForRequestPolicy.java @@ -9,6 +9,7 @@ import java.util.ArrayList; import java.util.List; +import io.vertx.core.Future; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.folio.persist.RequestPolicyRepository; @@ -28,7 +29,7 @@ public ServicePointUpdateProcessorForRequestPolicy( } @Override - protected List> collectRelevantChanges(JsonObject payload) { + protected Future>> collectRelevantChanges(JsonObject payload) { JsonObject oldObject = payload.getJsonObject("old"); JsonObject newObject = payload.getJsonObject("new"); List> changes = new ArrayList<>(); @@ -44,7 +45,7 @@ protected List> collectRelevantChanges(JsonObject payload) updatedServicePointId))); } - return changes; + return Future.succeededFuture(changes); } @Override diff --git a/src/test/java/org/folio/rest/api/EventConsumerVerticleTest.java b/src/test/java/org/folio/rest/api/EventConsumerVerticleTest.java index 81dd93644..4c16376d1 100644 --- a/src/test/java/org/folio/rest/api/EventConsumerVerticleTest.java +++ b/src/test/java/org/folio/rest/api/EventConsumerVerticleTest.java @@ -11,14 +11,22 @@ import static org.folio.kafka.services.KafkaEnvironmentProperties.environment; import static org.folio.kafka.services.KafkaEnvironmentProperties.host; import static org.folio.kafka.services.KafkaEnvironmentProperties.port; +import static org.folio.rest.RestVerticle.OKAPI_HEADER_TOKEN; +import static org.folio.rest.api.StorageTestSuite.PROXY_PORT; import static org.folio.rest.api.StorageTestSuite.TENANT_ID; import static org.folio.rest.api.StorageTestSuite.getVertx; import static org.folio.rest.support.builders.RequestRequestBuilder.OPEN_NOT_YET_FILLED; import static org.folio.rest.tools.utils.ModuleName.getModuleName; import static org.folio.rest.tools.utils.ModuleName.getModuleVersion; +import static org.folio.rest.util.OkapiConnectionParams.OKAPI_TENANT_HEADER; +import static org.folio.rest.util.OkapiConnectionParams.OKAPI_URL_HEADER; import static org.folio.service.event.InventoryEventType.INVENTORY_ITEM_UPDATED; import static org.folio.service.event.InventoryEventType.INVENTORY_SERVICE_POINT_DELETED; import static org.folio.service.event.InventoryEventType.INVENTORY_SERVICE_POINT_UPDATED; +import static org.folio.service.event.handler.processor.ItemUpdateProcessorForRequest.ITEM_EFFECTIVE_LOCATION_ID; +import static org.folio.service.event.handler.processor.ItemUpdateProcessorForRequest.ITEM_EFFECTIVE_LOCATION_NAME; +import static org.folio.service.event.handler.processor.ItemUpdateProcessorForRequest.RETRIEVAL_SERVICE_POINT_ID; +import static org.folio.service.event.handler.processor.ItemUpdateProcessorForRequest.RETRIEVAL_SERVICE_POINT_NAME; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.hasItem; import static org.hamcrest.CoreMatchers.hasItems; @@ -27,6 +35,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import java.net.URL; +import java.util.Base64; import java.util.List; import java.util.Map; import java.util.Optional; @@ -43,6 +52,7 @@ import org.folio.rest.support.ApiTests; import org.folio.rest.support.builders.ItemBuilder; import org.folio.rest.support.builders.ItemBuilder.ItemCallNumberComponents; +import org.folio.rest.support.builders.LocationBuilder; import org.folio.rest.support.builders.RequestItemSummary; import org.folio.rest.support.builders.RequestPolicyBuilder; import org.folio.rest.support.builders.RequestRequestBuilder; @@ -169,6 +179,38 @@ public void requestSearchIndexIsNotUpdatedWhenEventContainsNoRelevantChanges() { verifyRequestSearchIndex(REQUEST_ID, searchIndex); } + @Test + public void requestItemLocationAndSpIsSetWhenItemEffectiveLocationChange() { + JsonObject oldItem = buildItem(DEFAULT_CALL_NUMBER_PREFIX, DEFAULT_CALL_NUMBER, + DEFAULT_CALL_NUMBER_SUFFIX, DEFAULT_SHELVING_ORDER); + JsonObject newItem = oldItem.copy(); + + //Creating and mocking ServicePoint + String servicePointId = UUID.randomUUID().toString(); + JsonObject servicePoint = buildServicePoint(servicePointId, "ServicePoint-1"); + createStubForServicePoints(List.of(servicePoint)); + + //Creating and mocking Location + String locationId = UUID.randomUUID().toString(); + JsonObject location = buildLocation(locationId, "Location-1", servicePointId); + createStubForLocations(List.of(location)); + newItem.put("effectiveLocationId", locationId); + + // Expected item + JsonObject expectedItem = new JsonObject(); + expectedItem.put(ITEM_EFFECTIVE_LOCATION_ID, locationId); + expectedItem.put(ITEM_EFFECTIVE_LOCATION_NAME, location.getString("name")); + expectedItem.put(RETRIEVAL_SERVICE_POINT_ID, servicePointId); + expectedItem.put(RETRIEVAL_SERVICE_POINT_NAME, servicePoint.getString("name")); + + createRequest(buildRequest(REQUEST_ID, oldItem)); + + int initialOffset = getOffsetForItemUpdateEvents(); + publishItemUpdateEvent(oldItem, newItem); + waitUntilValueIsIncreased(initialOffset, EventConsumerVerticleTest::getOffsetForItemUpdateEvents); + verifyRequestItem(REQUEST_ID, expectedItem); + } + @Test public void requestSearchIndexIsNotUpdatedWhenRequestAndEventAreForDifferentItems() { JsonObject oldItem = buildItem(DEFAULT_CALL_NUMBER_PREFIX, DEFAULT_CALL_NUMBER, @@ -486,6 +528,18 @@ private static JsonObject buildItem(String prefix, String callNumber, String suf .create(); } + private static JsonObject buildLocation(String id, String name, String primaryServicePoint) { + return buildLocation(id, name, "code", primaryServicePoint); + } + + private static JsonObject buildLocation(String id, String name, String code, String primaryServicePoint) { + return new LocationBuilder(name) + .withId(id) + .withCode(code) + .withPrimaryServicePoint(primaryServicePoint) + .create(); + } + private static JsonObject buildServicePoint(String id, String name) { return buildServicePoint(id, name, "code"); } @@ -592,10 +646,23 @@ private void publishInvalidServicePointDeleteEvent(JsonObject servicePoint) { private void publishEvent(String topic, JsonObject eventPayload) { var record = KafkaProducerRecord.create(topic, "test-key", eventPayload); - record.addHeader("X-Okapi-Tenant", TENANT_ID); + record.addHeader(OKAPI_TENANT_HEADER, TENANT_ID); + record.addHeader(OKAPI_URL_HEADER, "http://localhost:" + PROXY_PORT); + record.addHeader(OKAPI_HEADER_TOKEN, "123"); waitFor(producer.write(record)); } + private static String generateToken() { + final String payload = new JsonObject() + .put("user_id", randomId()) + .put("tenant", TENANT_ID) + .put("sub", "admin") + .toString(); + + return format("1.%s.3", Base64.getEncoder() + .encodeToString(payload.getBytes())); + } + private static JsonObject buildUpdateEvent(JsonObject oldVersion, JsonObject newVersion) { return new JsonObject() .put("tenant", TENANT_ID) @@ -638,6 +705,19 @@ private JsonObject verifyRequestSearchIndex(String requestId, SearchIndex search .until(() -> getRequestSearchIndex(requestId), equalTo(mapFrom(searchIndex))); } + private JsonObject verifyRequestItem(String requestId, JsonObject itemObject) { + return waitAtMost(60, SECONDS) + .until(() -> { + JsonObject requestItem = getRequestItem(requestId); + JsonObject actualItem = new JsonObject(); + actualItem.put(ITEM_EFFECTIVE_LOCATION_ID, requestItem.getString(ITEM_EFFECTIVE_LOCATION_ID)); + actualItem.put(ITEM_EFFECTIVE_LOCATION_NAME, requestItem.getString(ITEM_EFFECTIVE_LOCATION_NAME)); + actualItem.put(RETRIEVAL_SERVICE_POINT_ID, requestItem.getString(RETRIEVAL_SERVICE_POINT_ID)); + actualItem.put(RETRIEVAL_SERVICE_POINT_NAME, requestItem.getString(RETRIEVAL_SERVICE_POINT_NAME)); + return actualItem; + }, equalTo(itemObject)); + } + private JsonObject verifyPickupServicePointName(String requestId, SearchIndex searchIndex) { return waitAtMost(60, SECONDS) .until(() -> getRequestSearchIndex(requestId), equalTo(mapFrom(searchIndex))); @@ -668,6 +748,10 @@ private JsonObject getRequestSearchIndex(String requestId) { return getRequest(requestId).getJsonObject("searchIndex"); } + private JsonObject getRequestItem(String requestId) { + return getRequest(requestId).getJsonObject("item"); + } + private static JsonObject buildRequestPolicy(String requestPolicyId, List requestTypes, AllowedServicePoints allowedServicePoints) { @@ -763,6 +847,13 @@ private void createStubForServicePoints(List servicePoints) { .encodePrettily()))); } + private void createStubForLocations(List locations) { + StorageTestSuite.getWireMockServer() + .stubFor(WireMock.get(urlPathMatching("/locations.*")) + .willReturn(ok().withBody(new JsonObject().put("locations", new JsonArray(locations)) + .encodePrettily()))); + } + private JsonObject buildRequestPolicy(List allowedServicePointIds, RequestType... requestTypes) { From c70e263676034e497ae879d85751f311d75063e2 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Mon, 16 Dec 2024 19:35:21 +0530 Subject: [PATCH 08/15] CIRCSTORE-540: removed unnecessary log and code --- .../event/handler/ItemUpdateEventHandler.java | 2 -- .../folio/rest/api/EventConsumerVerticleTest.java | 13 +------------ 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/src/main/java/org/folio/service/event/handler/ItemUpdateEventHandler.java b/src/main/java/org/folio/service/event/handler/ItemUpdateEventHandler.java index 75295905e..a6e59c14c 100644 --- a/src/main/java/org/folio/service/event/handler/ItemUpdateEventHandler.java +++ b/src/main/java/org/folio/service/event/handler/ItemUpdateEventHandler.java @@ -18,7 +18,6 @@ public class ItemUpdateEventHandler implements AsyncRecordHandler { private final Context context; - private static final Logger log = getLogger(ItemUpdateEventHandler.class); public ItemUpdateEventHandler(Context context) { this.context = context; } @@ -28,7 +27,6 @@ public Future handle(KafkaConsumerRecord kafkaConsumerRe JsonObject payload = new JsonObject(kafkaConsumerRecord.value()); CaseInsensitiveMap headers = new CaseInsensitiveMap<>(kafkaHeadersToMap(kafkaConsumerRecord.headers())); - log.info("ItemUpdateEventHandler :: handle() :: kafkaHeaders: {}", headers); ItemUpdateProcessorForRequest itemUpdateProcessorForRequest = new ItemUpdateProcessorForRequest(new RequestRepository(context, headers), new InventoryStorageClient(context.owner(), headers)); diff --git a/src/test/java/org/folio/rest/api/EventConsumerVerticleTest.java b/src/test/java/org/folio/rest/api/EventConsumerVerticleTest.java index 4c16376d1..e91a8c9fd 100644 --- a/src/test/java/org/folio/rest/api/EventConsumerVerticleTest.java +++ b/src/test/java/org/folio/rest/api/EventConsumerVerticleTest.java @@ -648,21 +648,10 @@ private void publishEvent(String topic, JsonObject eventPayload) { var record = KafkaProducerRecord.create(topic, "test-key", eventPayload); record.addHeader(OKAPI_TENANT_HEADER, TENANT_ID); record.addHeader(OKAPI_URL_HEADER, "http://localhost:" + PROXY_PORT); - record.addHeader(OKAPI_HEADER_TOKEN, "123"); + record.addHeader(OKAPI_HEADER_TOKEN, "RANDOM_TOKEN"); waitFor(producer.write(record)); } - private static String generateToken() { - final String payload = new JsonObject() - .put("user_id", randomId()) - .put("tenant", TENANT_ID) - .put("sub", "admin") - .toString(); - - return format("1.%s.3", Base64.getEncoder() - .encodeToString(payload.getBytes())); - } - private static JsonObject buildUpdateEvent(JsonObject oldVersion, JsonObject newVersion) { return new JsonObject() .put("tenant", TENANT_ID) From b25ccacd6821e1e290e3347a9e3b8d326ab0afe1 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Mon, 16 Dec 2024 19:49:10 +0530 Subject: [PATCH 09/15] CIRCSTORE-540: using location and SP constants --- .../handler/processor/ItemUpdateProcessorForRequest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java b/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java index 75c41e1e2..1a1c2f3d2 100644 --- a/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java +++ b/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java @@ -82,10 +82,10 @@ private static Future>> addLocationAndServicePointChanges(M if (request.getItem() == null) { request.setItem(new Item()); } - request.getItem().setItemEffectiveLocationId(locationAndSpData.get("itemEffectiveLocationId")); - request.getItem().setItemEffectiveLocationName(locationAndSpData.get("itemEffectiveLocationName")); - request.getItem().setRetrievalServicePointId(locationAndSpData.get("retrievalServicePointId")); - request.getItem().setRetrievalServicePointName(locationAndSpData.get("retrievalServicePointName")); + request.getItem().setItemEffectiveLocationId(locationAndSpData.get(ITEM_EFFECTIVE_LOCATION_ID)); + request.getItem().setItemEffectiveLocationName(locationAndSpData.get(ITEM_EFFECTIVE_LOCATION_NAME)); + request.getItem().setRetrievalServicePointId(locationAndSpData.get(RETRIEVAL_SERVICE_POINT_ID)); + request.getItem().setRetrievalServicePointName(locationAndSpData.get(RETRIEVAL_SERVICE_POINT_NAME)); })); return Future.succeededFuture(changes); } From 0d592b336289d8692314f170fddf0c8ba16406e3 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Tue, 17 Dec 2024 14:53:42 +0530 Subject: [PATCH 10/15] CIRCSTORE-540: fix NLP due to logging of null object --- .../processor/ItemUpdateProcessorForRequest.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java b/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java index 1a1c2f3d2..4600c4aca 100644 --- a/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java +++ b/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java @@ -71,13 +71,15 @@ protected Future>> collectRelevantChanges(JsonObject payloa changes.add(new Change<>(request -> request.getSearchIndex().setShelvingOrder(newShelvingOrder))); } - Future> fetchLocationAndServicePoint = updateItemAndServicePoint(newObject, changes); + Future> fetchLocationAndServicePoint = updateItemAndServicePoint(newObject); return fetchLocationAndServicePoint .compose(locationAndSpData -> addLocationAndServicePointChanges(locationAndSpData, changes)) - .compose(res -> Future.succeededFuture(changes)); + .compose(r -> Future.succeededFuture(changes)) + .recover(throwable -> Future.succeededFuture(changes)); } private static Future>> addLocationAndServicePointChanges(Map locationAndSpData, List> changes) { + log.info("ItemUpdateProcessorForRequest :: locationAndSpData: {}", locationAndSpData); changes.add(new Change<>(request -> { if (request.getItem() == null) { request.setItem(new Item()); @@ -90,7 +92,7 @@ private static Future>> addLocationAndServicePointChanges(M return Future.succeededFuture(changes); } - private Future> updateItemAndServicePoint(JsonObject newObject, List> changes) { + private Future> updateItemAndServicePoint(JsonObject newObject) { String effectiveLocationId = newObject.getString("effectiveLocationId"); Map locationAndSpData = new HashMap<>(); locationAndSpData.put(ITEM_EFFECTIVE_LOCATION_ID, effectiveLocationId); @@ -108,8 +110,6 @@ private static Future setEffectiveLocationData(Collection loca Location effectiveLocation = locations.stream() .filter(l -> l.getId().equals(effectiveLocationId)) .findFirst().orElse(null); - log.info("ItemUpdateProcessorForRequest :: setEffectiveLocationName(): locationsName: {}", - JsonObject.mapFrom(effectiveLocation).encode()); if (Objects.nonNull(effectiveLocation)) { locationAndSpData.put(ITEM_EFFECTIVE_LOCATION_NAME, effectiveLocation.getName()); return succeededFuture(effectiveLocation.getPrimaryServicePoint().toString()); @@ -125,8 +125,6 @@ private Future setRetrievalServicePointData(String primaryServicePoint, Servicepoint retrievalServicePoint = servicePoints.stream() .filter(sp -> sp.getId().equals(primaryServicePoint)) .findFirst().orElse(null); - log.info("ItemUpdateProcessorForRequest :: setServicePoint(): {}", - JsonObject.mapFrom(retrievalServicePoint).encode()); if (Objects.nonNull(retrievalServicePoint)) { locationAndSpData.put(RETRIEVAL_SERVICE_POINT_NAME, retrievalServicePoint.getName()); } From 29b77fbaf5c4b4c77d922e1c14212bcf8bc8b13f Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Tue, 17 Dec 2024 16:55:57 +0530 Subject: [PATCH 11/15] CIRCSTORE-540: fixed sonar issues --- .../service/event/handler/ItemUpdateEventHandler.java | 3 --- .../processor/ItemUpdateProcessorForRequest.java | 10 +++------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/folio/service/event/handler/ItemUpdateEventHandler.java b/src/main/java/org/folio/service/event/handler/ItemUpdateEventHandler.java index a6e59c14c..3535af48e 100644 --- a/src/main/java/org/folio/service/event/handler/ItemUpdateEventHandler.java +++ b/src/main/java/org/folio/service/event/handler/ItemUpdateEventHandler.java @@ -1,14 +1,11 @@ package org.folio.service.event.handler; -import static org.apache.logging.log4j.LogManager.getLogger; import static org.folio.kafka.KafkaHeaderUtils.kafkaHeadersToMap; import org.apache.commons.collections4.map.CaseInsensitiveMap; -import org.apache.logging.log4j.Logger; import org.folio.kafka.AsyncRecordHandler; import org.folio.persist.RequestRepository; import org.folio.rest.client.InventoryStorageClient; -import org.folio.service.event.EntityChangedEventPublisher; import org.folio.service.event.handler.processor.ItemUpdateProcessorForRequest; import io.vertx.core.Context; diff --git a/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java b/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java index 4600c4aca..1fd662c0a 100644 --- a/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java +++ b/src/main/java/org/folio/service/event/handler/processor/ItemUpdateProcessorForRequest.java @@ -100,9 +100,7 @@ private Future> updateItemAndServicePoint(JsonObject newObje .compose(locations -> setEffectiveLocationData(locations, effectiveLocationId, locationAndSpData)) .compose(primaryServicePoint -> setRetrievalServicePointData(primaryServicePoint, locationAndSpData)) .compose(e -> Future.succeededFuture(locationAndSpData)) - .onFailure(throwable -> { - log.info("ItemUpdateProcessorForRequest :: Error while fetching Locations: {}", throwable.toString()); - }); + .onFailure(throwable -> log.info("ItemUpdateProcessorForRequest :: Error while fetching Locations: {}", throwable.toString())); } private static Future setEffectiveLocationData(Collection locations, String effectiveLocationId, @@ -129,10 +127,8 @@ private Future setRetrievalServicePointData(String primaryServicePoint, locationAndSpData.put(RETRIEVAL_SERVICE_POINT_NAME, retrievalServicePoint.getName()); } return succeededFuture(); - }).onFailure(throwable -> { - log.info("ItemUpdateProcessorForRequest :: Error while fetching ServicePoint: {}", - throwable.toString()); - }); + }).onFailure(throwable -> log.info("ItemUpdateProcessorForRequest :: Error while fetching ServicePoint: {}", + throwable.toString())); } return succeededFuture(); } From f00ec578c6b7e3e2ce6caf505ea9ec499b0e1937 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Thu, 19 Dec 2024 17:13:08 +0530 Subject: [PATCH 12/15] CIRCSTORE-541: added ItemRetrievalServicePointUpdateProcessorForRequest for retrival SP for request --- .../ServicePointUpdateEventHandler.java | 5 +- ...ServicePointUpdateProcessorForRequest.java | 59 +++++++++++++++++++ .../rest/api/EventConsumerVerticleTest.java | 49 ++++++++++++++- 3 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/folio/service/event/handler/processor/ItemRetrievalServicePointUpdateProcessorForRequest.java diff --git a/src/main/java/org/folio/service/event/handler/ServicePointUpdateEventHandler.java b/src/main/java/org/folio/service/event/handler/ServicePointUpdateEventHandler.java index 27c4ff909..2f5fe316d 100644 --- a/src/main/java/org/folio/service/event/handler/ServicePointUpdateEventHandler.java +++ b/src/main/java/org/folio/service/event/handler/ServicePointUpdateEventHandler.java @@ -6,6 +6,7 @@ import org.folio.kafka.AsyncRecordHandler; import org.folio.persist.RequestPolicyRepository; import org.folio.persist.RequestRepository; +import org.folio.service.event.handler.processor.ItemRetrievalServicePointUpdateProcessorForRequest; import org.folio.service.event.handler.processor.ServicePointUpdateProcessorForRequest; import org.folio.service.event.handler.processor.ServicePointUpdateProcessorForRequestPolicy; @@ -31,6 +32,8 @@ public Future handle(KafkaConsumerRecord kafkaConsumerRe return new ServicePointUpdateProcessorForRequest(requestRepository) .run(kafkaConsumerRecord.key(), payload) .compose(notUsed -> new ServicePointUpdateProcessorForRequestPolicy(requestPolicyRepository) - .run(kafkaConsumerRecord.key(), payload)); + .run(kafkaConsumerRecord.key(), payload)) + .compose(notUsed -> new ItemRetrievalServicePointUpdateProcessorForRequest(requestRepository) + .run(kafkaConsumerRecord.key(), payload)); } } diff --git a/src/main/java/org/folio/service/event/handler/processor/ItemRetrievalServicePointUpdateProcessorForRequest.java b/src/main/java/org/folio/service/event/handler/processor/ItemRetrievalServicePointUpdateProcessorForRequest.java new file mode 100644 index 000000000..ad1940b88 --- /dev/null +++ b/src/main/java/org/folio/service/event/handler/processor/ItemRetrievalServicePointUpdateProcessorForRequest.java @@ -0,0 +1,59 @@ +package org.folio.service.event.handler.processor; + +import io.vertx.core.Future; +import io.vertx.core.json.JsonObject; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.folio.persist.RequestRepository; +import org.folio.rest.jaxrs.model.Request; +import org.folio.rest.persist.Criteria.Criteria; +import org.folio.rest.persist.Criteria.Criterion; + +import java.util.ArrayList; +import java.util.List; + +import static org.apache.commons.lang3.ObjectUtils.notEqual; +import static org.folio.service.event.InventoryEventType.INVENTORY_SERVICE_POINT_UPDATED; +import static org.folio.service.event.handler.processor.ItemUpdateProcessorForRequest.RETRIEVAL_SERVICE_POINT_ID; + +public class ItemRetrievalServicePointUpdateProcessorForRequest extends UpdateEventProcessor { + private static final Logger log = LogManager.getLogger(ItemRetrievalServicePointUpdateProcessorForRequest.class); + private static final String SERVICE_POINT_NAME_KEY = "name"; + + public ItemRetrievalServicePointUpdateProcessorForRequest(RequestRepository requestRepository) { + super(INVENTORY_SERVICE_POINT_UPDATED, requestRepository); + } + + @Override + protected Future>> collectRelevantChanges(JsonObject payload) { + JsonObject oldObject = payload.getJsonObject("old"); + JsonObject newObject = payload.getJsonObject("new"); + + List> changes = new ArrayList<>(); + + // compare service point names + String oldServicePointName = oldObject.getString(SERVICE_POINT_NAME_KEY); + String newServicePointName = newObject.getString(SERVICE_POINT_NAME_KEY); + if (notEqual(oldServicePointName, newServicePointName)) { + log.info("ItemRetrievalServicePointUpdateProcessorForRequest :: collectRelevantChanges:: changing item.retrievalServicePointName from {} to {}", + oldServicePointName, newServicePointName); + changes.add(new Change<>(request -> request.getItem() + .setRetrievalServicePointName(newServicePointName))); + } + + return Future.succeededFuture(changes); + } + + @Override + protected Criterion criterionForObjectsToBeUpdated(String oldObjectId) { + log.info("ItemRetrievalServicePointUpdateProcessorForRequest :: criterionForObjectsToBeUpdated:: oldObjectId: {}", + oldObjectId); + + return new Criterion( + new Criteria() + .addField("'item'") + .addField(String.format("'%s'", RETRIEVAL_SERVICE_POINT_ID)) + .setOperation("=") + .setVal(oldObjectId)); + } +} diff --git a/src/test/java/org/folio/rest/api/EventConsumerVerticleTest.java b/src/test/java/org/folio/rest/api/EventConsumerVerticleTest.java index e91a8c9fd..f319fd12f 100644 --- a/src/test/java/org/folio/rest/api/EventConsumerVerticleTest.java +++ b/src/test/java/org/folio/rest/api/EventConsumerVerticleTest.java @@ -35,7 +35,6 @@ import static org.hamcrest.MatcherAssert.assertThat; import java.net.URL; -import java.util.Base64; import java.util.List; import java.util.Map; import java.util.Optional; @@ -211,6 +210,43 @@ public void requestItemLocationAndSpIsSetWhenItemEffectiveLocationChange() { verifyRequestItem(REQUEST_ID, expectedItem); } + @Test + public void requestItemSpIsSetWhenItemEffectiveLocationPrimarySpChange() { + //Creating and mocking ServicePoint + String servicePointId = UUID.randomUUID().toString(); + JsonObject servicePoint = buildServicePoint(servicePointId, "ServicePoint-1"); + createStubForServicePoints(List.of(servicePoint)); + + //Creating and mocking Location + String locationId = UUID.randomUUID().toString(); + JsonObject location = buildLocation(locationId, "Location-1", servicePointId); + createStubForLocations(List.of(location)); + + //Creating request with retrieval service-point in item object + JsonObject item = buildItem(); + JsonObject request = buildRequest(REQUEST_ID, item); + JsonObject requestItem = request.getJsonObject("item"); + requestItem.put(RETRIEVAL_SERVICE_POINT_ID, servicePointId); + requestItem.put(RETRIEVAL_SERVICE_POINT_NAME, servicePoint.getString("name")); + createRequest(request); + + int initialOffset = getOffsetForServicePointUpdateEvents(); + + //Change ServicePoint Name in stub and publish SP update event + JsonObject servicePointNew = servicePoint.copy(); + servicePointNew.put("name", "ServicePoint-2-Changed"); + createStubForServicePoints(List.of(servicePoint)); + publishServicePointUpdateEvent(servicePoint, servicePointNew); + + // Expected RETRIEVAL_SERVICE_POINT in item + JsonObject expectedItemRetrivalServicePoint = new JsonObject(); + expectedItemRetrivalServicePoint.put(RETRIEVAL_SERVICE_POINT_ID, servicePointId); + expectedItemRetrivalServicePoint.put(RETRIEVAL_SERVICE_POINT_NAME, servicePointNew.getString("name")); + + waitUntilValueIsIncreased(initialOffset, EventConsumerVerticleTest::getOffsetForServicePointUpdateEvents); + verifyRequestItemRetrievalServicePoint(REQUEST_ID, expectedItemRetrivalServicePoint); + } + @Test public void requestSearchIndexIsNotUpdatedWhenRequestAndEventAreForDifferentItems() { JsonObject oldItem = buildItem(DEFAULT_CALL_NUMBER_PREFIX, DEFAULT_CALL_NUMBER, @@ -707,6 +743,17 @@ private JsonObject verifyRequestItem(String requestId, JsonObject itemObject) { }, equalTo(itemObject)); } + private JsonObject verifyRequestItemRetrievalServicePoint(String requestId, JsonObject itemObject) { + return waitAtMost(60, SECONDS) + .until(() -> { + JsonObject requestItem = getRequestItem(requestId); + JsonObject actualItem = new JsonObject(); + actualItem.put(RETRIEVAL_SERVICE_POINT_ID, requestItem.getString(RETRIEVAL_SERVICE_POINT_ID)); + actualItem.put(RETRIEVAL_SERVICE_POINT_NAME, requestItem.getString(RETRIEVAL_SERVICE_POINT_NAME)); + return actualItem; + }, equalTo(itemObject)); + } + private JsonObject verifyPickupServicePointName(String requestId, SearchIndex searchIndex) { return waitAtMost(60, SECONDS) .until(() -> getRequestSearchIndex(requestId), equalTo(mapFrom(searchIndex))); From 35addbe0f68cce882ef98f70135b697c9208481c Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Thu, 19 Dec 2024 18:27:34 +0530 Subject: [PATCH 13/15] CIRCSTORE-541: fix duplicate code line sonar issue --- ...RetrievalServicePointUpdateProcessorForRequest.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/folio/service/event/handler/processor/ItemRetrievalServicePointUpdateProcessorForRequest.java b/src/main/java/org/folio/service/event/handler/processor/ItemRetrievalServicePointUpdateProcessorForRequest.java index ad1940b88..faea6b366 100644 --- a/src/main/java/org/folio/service/event/handler/processor/ItemRetrievalServicePointUpdateProcessorForRequest.java +++ b/src/main/java/org/folio/service/event/handler/processor/ItemRetrievalServicePointUpdateProcessorForRequest.java @@ -26,21 +26,18 @@ public ItemRetrievalServicePointUpdateProcessorForRequest(RequestRepository requ @Override protected Future>> collectRelevantChanges(JsonObject payload) { - JsonObject oldObject = payload.getJsonObject("old"); JsonObject newObject = payload.getJsonObject("new"); - + JsonObject oldObject = payload.getJsonObject("old"); List> changes = new ArrayList<>(); // compare service point names - String oldServicePointName = oldObject.getString(SERVICE_POINT_NAME_KEY); String newServicePointName = newObject.getString(SERVICE_POINT_NAME_KEY); + String oldServicePointName = oldObject.getString(SERVICE_POINT_NAME_KEY); if (notEqual(oldServicePointName, newServicePointName)) { log.info("ItemRetrievalServicePointUpdateProcessorForRequest :: collectRelevantChanges:: changing item.retrievalServicePointName from {} to {}", oldServicePointName, newServicePointName); - changes.add(new Change<>(request -> request.getItem() - .setRetrievalServicePointName(newServicePointName))); + changes.add(new Change<>(request -> request.getItem().setRetrievalServicePointName(newServicePointName))); } - return Future.succeededFuture(changes); } @@ -48,7 +45,6 @@ protected Future>> collectRelevantChanges(JsonObject payloa protected Criterion criterionForObjectsToBeUpdated(String oldObjectId) { log.info("ItemRetrievalServicePointUpdateProcessorForRequest :: criterionForObjectsToBeUpdated:: oldObjectId: {}", oldObjectId); - return new Criterion( new Criteria() .addField("'item'") From 1f3d6195125a184e54f69f1f6f04fdaeb39d9953 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Fri, 20 Dec 2024 17:53:44 +0530 Subject: [PATCH 14/15] CIRCSTORE-540: added interface dependency for location and service-point api --- descriptors/ModuleDescriptor-template.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/descriptors/ModuleDescriptor-template.json b/descriptors/ModuleDescriptor-template.json index 4ce7a918e..69bce0105 100644 --- a/descriptors/ModuleDescriptor-template.json +++ b/descriptors/ModuleDescriptor-template.json @@ -29,6 +29,14 @@ { "id": "configuration", "version": "2.0" + }, + { + "id": "locations", + "version": "3.1" + }, + { + "id": "service-points", + "version": "3.4" } ], "provides": [ From 2ee8bff14d8d25120ca4bcc8dde7e00d2531247f Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Mon, 23 Dec 2024 14:34:14 +0530 Subject: [PATCH 15/15] CIRCSTORE-541: resolved merge conflict --- .../rest/api/EventConsumerVerticleTest.java | 93 +++++++++---------- 1 file changed, 46 insertions(+), 47 deletions(-) diff --git a/src/test/java/org/folio/rest/api/EventConsumerVerticleTest.java b/src/test/java/org/folio/rest/api/EventConsumerVerticleTest.java index 56f3a9fdd..f319fd12f 100644 --- a/src/test/java/org/folio/rest/api/EventConsumerVerticleTest.java +++ b/src/test/java/org/folio/rest/api/EventConsumerVerticleTest.java @@ -35,7 +35,6 @@ import static org.hamcrest.MatcherAssert.assertThat; import java.net.URL; -import java.util.Base64; import java.util.List; import java.util.Map; import java.util.Optional; @@ -211,42 +210,42 @@ public void requestItemLocationAndSpIsSetWhenItemEffectiveLocationChange() { verifyRequestItem(REQUEST_ID, expectedItem); } - @Test - public void requestItemSpIsSetWhenItemEffectiveLocationPrimarySpChange() { - //Creating and mocking ServicePoint - String servicePointId = UUID.randomUUID().toString(); - JsonObject servicePoint = buildServicePoint(servicePointId, "ServicePoint-1"); - createStubForServicePoints(List.of(servicePoint)); - - //Creating and mocking Location - String locationId = UUID.randomUUID().toString(); - JsonObject location = buildLocation(locationId, "Location-1", servicePointId); - createStubForLocations(List.of(location)); - - //Creating request with retrieval service-point in item object - JsonObject item = buildItem(); - JsonObject request = buildRequest(REQUEST_ID, item); - JsonObject requestItem = request.getJsonObject("item"); - requestItem.put(RETRIEVAL_SERVICE_POINT_ID, servicePointId); - requestItem.put(RETRIEVAL_SERVICE_POINT_NAME, servicePoint.getString("name")); - createRequest(request); - - int initialOffset = getOffsetForServicePointUpdateEvents(); - - //Change ServicePoint Name in stub and publish SP update event - JsonObject servicePointNew = servicePoint.copy(); - servicePointNew.put("name", "ServicePoint-2-Changed"); - createStubForServicePoints(List.of(servicePoint)); - publishServicePointUpdateEvent(servicePoint, servicePointNew); - - // Expected RETRIEVAL_SERVICE_POINT in item - JsonObject expectedItemRetrivalServicePoint = new JsonObject(); - expectedItemRetrivalServicePoint.put(RETRIEVAL_SERVICE_POINT_ID, servicePointId); - expectedItemRetrivalServicePoint.put(RETRIEVAL_SERVICE_POINT_NAME, servicePointNew.getString("name")); - - waitUntilValueIsIncreased(initialOffset, EventConsumerVerticleTest::getOffsetForServicePointUpdateEvents); - verifyRequestItemRetrievalServicePoint(REQUEST_ID, expectedItemRetrivalServicePoint); - } + @Test + public void requestItemSpIsSetWhenItemEffectiveLocationPrimarySpChange() { + //Creating and mocking ServicePoint + String servicePointId = UUID.randomUUID().toString(); + JsonObject servicePoint = buildServicePoint(servicePointId, "ServicePoint-1"); + createStubForServicePoints(List.of(servicePoint)); + + //Creating and mocking Location + String locationId = UUID.randomUUID().toString(); + JsonObject location = buildLocation(locationId, "Location-1", servicePointId); + createStubForLocations(List.of(location)); + + //Creating request with retrieval service-point in item object + JsonObject item = buildItem(); + JsonObject request = buildRequest(REQUEST_ID, item); + JsonObject requestItem = request.getJsonObject("item"); + requestItem.put(RETRIEVAL_SERVICE_POINT_ID, servicePointId); + requestItem.put(RETRIEVAL_SERVICE_POINT_NAME, servicePoint.getString("name")); + createRequest(request); + + int initialOffset = getOffsetForServicePointUpdateEvents(); + + //Change ServicePoint Name in stub and publish SP update event + JsonObject servicePointNew = servicePoint.copy(); + servicePointNew.put("name", "ServicePoint-2-Changed"); + createStubForServicePoints(List.of(servicePoint)); + publishServicePointUpdateEvent(servicePoint, servicePointNew); + + // Expected RETRIEVAL_SERVICE_POINT in item + JsonObject expectedItemRetrivalServicePoint = new JsonObject(); + expectedItemRetrivalServicePoint.put(RETRIEVAL_SERVICE_POINT_ID, servicePointId); + expectedItemRetrivalServicePoint.put(RETRIEVAL_SERVICE_POINT_NAME, servicePointNew.getString("name")); + + waitUntilValueIsIncreased(initialOffset, EventConsumerVerticleTest::getOffsetForServicePointUpdateEvents); + verifyRequestItemRetrievalServicePoint(REQUEST_ID, expectedItemRetrivalServicePoint); + } @Test public void requestSearchIndexIsNotUpdatedWhenRequestAndEventAreForDifferentItems() { @@ -744,16 +743,16 @@ private JsonObject verifyRequestItem(String requestId, JsonObject itemObject) { }, equalTo(itemObject)); } - private JsonObject verifyRequestItemRetrievalServicePoint(String requestId, JsonObject itemObject) { - return waitAtMost(60, SECONDS) - .until(() -> { - JsonObject requestItem = getRequestItem(requestId); - JsonObject actualItem = new JsonObject(); - actualItem.put(RETRIEVAL_SERVICE_POINT_ID, requestItem.getString(RETRIEVAL_SERVICE_POINT_ID)); - actualItem.put(RETRIEVAL_SERVICE_POINT_NAME, requestItem.getString(RETRIEVAL_SERVICE_POINT_NAME)); - return actualItem; - }, equalTo(itemObject)); - } + private JsonObject verifyRequestItemRetrievalServicePoint(String requestId, JsonObject itemObject) { + return waitAtMost(60, SECONDS) + .until(() -> { + JsonObject requestItem = getRequestItem(requestId); + JsonObject actualItem = new JsonObject(); + actualItem.put(RETRIEVAL_SERVICE_POINT_ID, requestItem.getString(RETRIEVAL_SERVICE_POINT_ID)); + actualItem.put(RETRIEVAL_SERVICE_POINT_NAME, requestItem.getString(RETRIEVAL_SERVICE_POINT_NAME)); + return actualItem; + }, equalTo(itemObject)); + } private JsonObject verifyPickupServicePointName(String requestId, SearchIndex searchIndex) { return waitAtMost(60, SECONDS)