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": [ diff --git a/ramls/locations/location.json b/ramls/locations/location.json new file mode 100644 index 000000000..31a13886a --- /dev/null +++ b/ramls/locations/location.json @@ -0,0 +1,67 @@ +{ + "$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": true +} 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..3535af48e 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; @@ -14,7 +15,6 @@ public class ItemUpdateEventHandler implements AsyncRecordHandler { private final Context context; - public ItemUpdateEventHandler(Context context) { this.context = context; } @@ -24,9 +24,8 @@ public Future handle(KafkaConsumerRecord kafkaConsumerRe JsonObject payload = new JsonObject(kafkaConsumerRecord.value()); CaseInsensitiveMap headers = 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/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 26266f056..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 @@ -1,16 +1,28 @@ 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.HashMap; import java.util.List; +import java.util.Map; +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; @@ -19,17 +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"; - public ItemUpdateProcessorForRequest(RequestRepository repository) { + 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"); @@ -50,9 +71,69 @@ protected List> collectRelevantChanges(JsonObject payload) { changes.add(new Change<>(request -> request.getSearchIndex().setShelvingOrder(newShelvingOrder))); } - return changes; + Future> fetchLocationAndServicePoint = updateItemAndServicePoint(newObject); + return fetchLocationAndServicePoint + .compose(locationAndSpData -> addLocationAndServicePointChanges(locationAndSpData, 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()); + } + 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); + } + + private Future> updateItemAndServicePoint(JsonObject newObject) { + 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 static Future setEffectiveLocationData(Collection locations, String effectiveLocationId, + Map locationAndSpData) { + Location effectiveLocation = locations.stream() + .filter(l -> l.getId().equals(effectiveLocationId)) + .findFirst().orElse(null); + if (Objects.nonNull(effectiveLocation)) { + locationAndSpData.put(ITEM_EFFECTIVE_LOCATION_NAME, effectiveLocation.getName()); + return succeededFuture(effectiveLocation.getPrimaryServicePoint().toString()); + } + return succeededFuture(); + } + + 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); + 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())); + } + 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..e91a8c9fd 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,7 +646,9 @@ 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, "RANDOM_TOKEN"); waitFor(producer.write(record)); } @@ -638,6 +694,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 +737,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 +836,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) { 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; + } +}