diff --git a/ramls/routing-lists.raml b/ramls/routing-lists.raml index 4384183a2..9675563d2 100644 --- a/ramls/routing-lists.raml +++ b/ramls/routing-lists.raml @@ -69,6 +69,13 @@ resourceTypes: body: application/json: type: error + /{id}/template: + uriParameters: + id: + description: The UUID of a Title + type: UUID + get: + description: Execute mod-template-engine to process templates with replaced token placeholders [update] /{id}: uriParameters: id: @@ -79,10 +86,3 @@ resourceTypes: collection-item: exampleItem: !include acq-models/mod-orders-storage/examples/routing_list_get.sample schema: routing-list - /{id}/template: - uriParameters: - id: - description: The UUID of a Title - type: UUID - get: - description: Execute mod-template-engine to process templates with replaced token placeholders [update] diff --git a/src/main/java/org/folio/config/ApplicationConfig.java b/src/main/java/org/folio/config/ApplicationConfig.java index 6c1a45321..4870506b7 100644 --- a/src/main/java/org/folio/config/ApplicationConfig.java +++ b/src/main/java/org/folio/config/ApplicationConfig.java @@ -112,7 +112,7 @@ import org.folio.service.pieces.flows.update.PieceUpdateFlowInventoryManager; import org.folio.service.pieces.flows.update.PieceUpdateFlowManager; import org.folio.service.pieces.flows.update.PieceUpdateFlowPoLineService; -import org.folio.service.RoutingListService; +import org.folio.service.routinglists.RoutingListService; import org.folio.service.titles.TitleValidationService; import org.folio.service.titles.TitlesService; import org.springframework.beans.factory.annotation.Qualifier; @@ -437,8 +437,8 @@ CompositeOrderDynamicDataPopulateService combinedPopulateService(CompositeOrderR } @Bean - RoutingListService routingListService(RestClient restClient, UserService userService) { - return new RoutingListService(restClient, userService); + RoutingListService routingListService(RestClient restClient, PurchaseOrderLineService purchaseOrderLineService, UserService userService) { + return new RoutingListService(restClient, purchaseOrderLineService, userService); } @Bean diff --git a/src/main/java/org/folio/orders/utils/ResourcePathResolver.java b/src/main/java/org/folio/orders/utils/ResourcePathResolver.java index 1635dc328..4e29b8e7a 100644 --- a/src/main/java/org/folio/orders/utils/ResourcePathResolver.java +++ b/src/main/java/org/folio/orders/utils/ResourcePathResolver.java @@ -22,7 +22,6 @@ private ResourcePathResolver() { public static final String ACQUISITIONS_MEMBERSHIPS = "acquisitionsMemberships"; public static final String REPORTING_CODES = "reportingCodes"; public static final String PURCHASE_ORDER_STORAGE = "purchaseOrder"; - public static final String ROUTING_LIST_STORAGE = "routingLists"; public static final String PIECES_STORAGE = "pieces"; public static final String RECEIVING_HISTORY = "receiving-history"; public static final String RECEIPT_STATUS = "receiptStatus"; @@ -67,7 +66,6 @@ private ResourcePathResolver() { apis.put(PO_LINES_BUSINESS, "/orders/order-lines"); apis.put(PO_NUMBER, "/orders-storage/po-number"); apis.put(PURCHASE_ORDER_STORAGE, "/orders-storage/purchase-orders"); - apis.put(ROUTING_LIST_STORAGE, "/orders-storage/routing-lists"); apis.put(PIECES_STORAGE, "/orders-storage/pieces"); apis.put(RECEIVING_HISTORY, "/orders-storage/receiving-history"); apis.put(PO_LINE_NUMBER, "/orders-storage/po-line-number"); diff --git a/src/main/java/org/folio/rest/impl/RoutingListsAPI.java b/src/main/java/org/folio/rest/impl/RoutingListsAPI.java index a442f4256..058245848 100644 --- a/src/main/java/org/folio/rest/impl/RoutingListsAPI.java +++ b/src/main/java/org/folio/rest/impl/RoutingListsAPI.java @@ -8,7 +8,7 @@ import org.folio.rest.core.models.RequestContext; import org.folio.rest.jaxrs.model.RoutingList; import org.folio.rest.jaxrs.resource.OrdersRoutingLists; -import org.folio.service.routinglists.RoutingListsService; +import org.folio.service.routinglists.RoutingListService; import org.folio.spring.SpringContextUtil; import org.springframework.beans.factory.annotation.Autowired; @@ -20,7 +20,7 @@ public class RoutingListsAPI extends BaseApi implements OrdersRoutingLists { @Autowired - private RoutingListService routingListsService; + private RoutingListService routingListService; public RoutingListsAPI() { SpringContextUtil.autowireDependencies(this, Vertx.currentContext()); @@ -29,7 +29,7 @@ public RoutingListsAPI() { @Override @Validate public void getOrdersRoutingLists(String query, String totalRecords, int offset, int limit, Map okapiHeaders, Handler> asyncResultHandler, Context vertxContext) { - routingListsStorageService.getRoutingLists(limit, offset, query, new RequestContext(vertxContext, okapiHeaders)) + routingListService.getRoutingLists(limit, offset, query, new RequestContext(vertxContext, okapiHeaders)) .onSuccess(lists -> asyncResultHandler.handle(succeededFuture(buildOkResponse(lists)))) .onFailure(fail -> handleErrorResponse(asyncResultHandler, fail)); } @@ -37,7 +37,7 @@ public void getOrdersRoutingLists(String query, String totalRecords, int offset, @Override @Validate public void postOrdersRoutingLists(RoutingList entity, Map okapiHeaders, Handler> asyncResultHandler, Context vertxContext) { - routingListsStorageService.createRoutingList(entity, new RequestContext(vertxContext, okapiHeaders)) + routingListService.createRoutingList(entity, new RequestContext(vertxContext, okapiHeaders)) .onSuccess(list -> asyncResultHandler.handle(succeededFuture(buildOkResponse(list)))) .onFailure(fail -> handleErrorResponse(asyncResultHandler, fail)); } @@ -45,7 +45,7 @@ public void postOrdersRoutingLists(RoutingList entity, Map okapi @Override @Validate public void getOrdersRoutingListsById(String id, Map okapiHeaders, Handler> asyncResultHandler, Context vertxContext) { - routingListsStorageService.getRoutingList(id, new RequestContext(vertxContext, okapiHeaders)) + routingListService.getRoutingList(id, new RequestContext(vertxContext, okapiHeaders)) .onSuccess(list -> asyncResultHandler.handle(succeededFuture(buildOkResponse(list)))) .onFailure(fail -> handleErrorResponse(asyncResultHandler, fail)); } @@ -53,7 +53,7 @@ public void getOrdersRoutingListsById(String id, Map okapiHeader @Override @Validate public void deleteOrdersRoutingListsById(String id, Map okapiHeaders, Handler> asyncResultHandler, Context vertxContext) { - routingListsStorageService.deleteRoutingList(id, new RequestContext(vertxContext, okapiHeaders)) + routingListService.deleteRoutingList(id, new RequestContext(vertxContext, okapiHeaders)) .onSuccess(list -> asyncResultHandler.handle(succeededFuture(buildNoContentResponse()))) .onFailure(fail -> handleErrorResponse(asyncResultHandler, fail)); @@ -62,7 +62,7 @@ public void deleteOrdersRoutingListsById(String id, Map okapiHea @Override @Validate public void putOrdersRoutingListsById(String id, RoutingList entity, Map okapiHeaders, Handler> asyncResultHandler, Context vertxContext) { - routingListsStorageService.updateRoutingList(entity, new RequestContext(vertxContext, okapiHeaders)) + routingListService.updateRoutingList(entity, new RequestContext(vertxContext, okapiHeaders)) .onSuccess(list -> asyncResultHandler.handle(succeededFuture(buildOkResponse(list)))) .onFailure(fail -> handleErrorResponse(asyncResultHandler, fail)); } diff --git a/src/main/java/org/folio/service/RoutingListService.java b/src/main/java/org/folio/service/routinglists/RoutingListService.java similarity index 58% rename from src/main/java/org/folio/service/RoutingListService.java rename to src/main/java/org/folio/service/routinglists/RoutingListService.java index 8c9b92b9e..4ba5a5e36 100644 --- a/src/main/java/org/folio/service/RoutingListService.java +++ b/src/main/java/org/folio/service/routinglists/RoutingListService.java @@ -1,16 +1,8 @@ -package org.folio.service; - -import static org.folio.orders.utils.ResourcePathResolver.ORDER_SETTINGS; -import static org.folio.orders.utils.ResourcePathResolver.ROUTING_LISTS; -import static org.folio.orders.utils.ResourcePathResolver.TEMPLATE_REQUEST; -import static org.folio.orders.utils.ResourcePathResolver.resourcesPath; - -import java.util.Collections; -import java.util.List; -import java.util.UUID; +package org.folio.service.routinglists; import io.vertx.core.Future; import io.vertx.core.json.JsonObject; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.apache.kafka.common.errors.ResourceNotFoundException; @@ -18,34 +10,102 @@ import org.apache.logging.log4j.Logger; import org.folio.models.TemplateProcessingRequest; import org.folio.models.UserCollection; +import org.folio.rest.RestConstants; import org.folio.rest.acq.model.SettingCollection; import org.folio.rest.core.RestClient; +import org.folio.rest.core.exceptions.HttpException; import org.folio.rest.core.models.RequestContext; import org.folio.rest.core.models.RequestEntry; +import org.folio.rest.jaxrs.model.Error; +import org.folio.rest.jaxrs.model.Errors; +import org.folio.rest.jaxrs.model.PoLine; import org.folio.rest.jaxrs.model.RoutingList; +import org.folio.rest.jaxrs.model.RoutingListCollection; +import org.folio.service.UserService; +import org.folio.service.orders.PurchaseOrderLineService; +import org.folio.service.routinglists.validators.RoutingListValidatorUtil; + +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import static org.folio.orders.utils.ResourcePathResolver.ORDER_SETTINGS; +import static org.folio.orders.utils.ResourcePathResolver.ROUTING_LISTS; +import static org.folio.orders.utils.ResourcePathResolver.TEMPLATE_REQUEST; +import static org.folio.orders.utils.ResourcePathResolver.resourcesPath; public class RoutingListService { + private static final Logger logger = LogManager.getLogger(RoutingListService.class); - private static final Logger log = LogManager.getLogger(); - private static final UUID TEMPLATE_REQUEST_ID = UUID.fromString("9465105a-e8a1-470c-9817-142d33bc4fcd"); - private static final String TEMPLATE_REQUEST_LANG = "en"; - private static final String TEMPLATE_REQUEST_OUTPUT = "text/html"; private static final String ROUTING_LIST_ENDPOINT = resourcesPath(ROUTING_LISTS); private static final String ORDER_SETTINGS_ENDPOINT = resourcesPath(ORDER_SETTINGS); private static final String ROUTING_USER_ADDRESS_TYPE_ID = "ROUTING_USER_ADDRESS_TYPE_ID"; private static final String ROUTING_LIST_BY_ID_ENDPOINT = ROUTING_LIST_ENDPOINT + "/{id}"; + private static final String ROUTING_LIST_BY_POL_ID = "poLineId==%s"; + private static final String TEMPLATE_REQUEST_ENDPOINT = resourcesPath(TEMPLATE_REQUEST); + private static final UUID TEMPLATE_REQUEST_ID = UUID.fromString("9465105a-e8a1-470c-9817-142d33bc4fcd"); + private static final String TEMPLATE_REQUEST_LANG = "en"; + private static final String TEMPLATE_REQUEST_OUTPUT = "text/html"; - private final RestClient restClient; + private final PurchaseOrderLineService poLineService; private final UserService userService; + private final RestClient restClient; - public RoutingListService(RestClient restClient, UserService userService) { + public RoutingListService(RestClient restClient, PurchaseOrderLineService poLineService, UserService userService) { this.restClient = restClient; + this.poLineService = poLineService; this.userService = userService; } + public Future getRoutingList(String rListId, RequestContext requestContext) { + RequestEntry requestEntry = new RequestEntry(ROUTING_LIST_BY_ID_ENDPOINT).withId(rListId); + return restClient.get(requestEntry, RoutingList.class, requestContext); + } + + public Future updateRoutingList(RoutingList routingList, RequestContext requestContext) { + validateRoutingList(routingList, requestContext); + RequestEntry requestEntry = new RequestEntry(ROUTING_LIST_BY_ID_ENDPOINT).withId(routingList.getId()); + return restClient.put(requestEntry, requestContext, requestContext); + } + + public Future deleteRoutingList(String rListId, RequestContext requestContext) { + RequestEntry requestEntry = new RequestEntry(ROUTING_LIST_BY_ID_ENDPOINT).withId(rListId); + return restClient.delete(requestEntry, requestContext); + } + + public Future createRoutingList(RoutingList routingList, RequestContext requestContext) { + validateRoutingList(routingList, requestContext); + RequestEntry requestEntry = new RequestEntry(ROUTING_LIST_ENDPOINT); + return restClient.post(requestEntry, routingList, RoutingList.class, requestContext); + } + + public Future getRoutingLists(int limit, int offset, String query, RequestContext requestContext) { + RequestEntry requestEntry = new RequestEntry(ROUTING_LIST_ENDPOINT) + .withQuery(query) + .withOffset(offset) + .withLimit(limit); + return restClient.get(requestEntry, RoutingListCollection.class, requestContext); + } + + private Future getRoutingListsByPoLineId(String poLineId, RequestContext requestContext) { + String query = String.format(ROUTING_LIST_BY_POL_ID, poLineId); + return getRoutingLists(Integer.MAX_VALUE, 0, query, requestContext); + } + + private void validateRoutingList(RoutingList routingList, RequestContext requestContext) { + RoutingListCollection routingLists = getRoutingListsByPoLineId(routingList.getPoLineId(), requestContext).result(); + PoLine poLine = poLineService.getOrderLineById(routingList.getPoLineId(), requestContext).result(); + List combinedErrors = RoutingListValidatorUtil.validateRoutingList(routingLists, poLine); + if (CollectionUtils.isNotEmpty(combinedErrors)) { + Errors errors = new Errors().withErrors(combinedErrors).withTotalRecords(combinedErrors.size()); + logger.error("Validation error: {}", JsonObject.mapFrom(errors).encodePrettily()); + throw new HttpException(RestConstants.VALIDATION_ERROR, errors); + } + } + public Future processTemplateRequest(String routingListId, RequestContext requestContext) { - log.debug("processTemplateRequest: Tying to process template request for routingListId={}", routingListId); + logger.debug("processTemplateRequest: Tying to process template request for routingListId={}", routingListId); return getRoutingListById(routingListId, requestContext) .compose(routingList -> getUsersAndCreateTemplate(routingList, requestContext)) .compose(templateProcessingRequest -> postTemplateRequest(templateProcessingRequest, requestContext)); @@ -69,7 +129,7 @@ private Future getAddressTypeId(RequestContext requestContext) { .map(settingCollection -> { var settings = settingCollection.getSettings(); if (ObjectUtils.isEmpty(settings) || StringUtils.isBlank(settings.get(0).getValue())) { - log.error("getAddressTypeId:: Setting is not found with key={}", ROUTING_USER_ADDRESS_TYPE_ID); + logger.error("getAddressTypeId:: Setting is not found with key={}", ROUTING_USER_ADDRESS_TYPE_ID); throw new ResourceNotFoundException(String.format("Setting is not found with key=%s", ROUTING_USER_ADDRESS_TYPE_ID)); } return settings.get(0).getValue(); @@ -82,7 +142,7 @@ private TemplateProcessingRequest createTemplateRequest(RoutingList routingList, .withRoutingList(fillRoutingListForContext(routingList)) .withUsers(fillUsersForContext(users, addressTypeId))); - log.info("createTemplateRequest:: TemplateProcessingRequest object created for routing list name: {}", + logger.info("createTemplateRequest:: TemplateProcessingRequest object created for routing list name: {}", templateRequest.getContext().getRoutingList().getName()); return templateRequest; } @@ -117,11 +177,11 @@ private List fillUsersForContext(UserCollection private String getUserAddress(List addressList, String addressTypeId) { for (UserCollection.User.Personal.Address address : addressList) { if (address.getAddressTypeId().equals(addressTypeId)) { - log.info("getUserAddress:: Required address with addressTypeId={} is found", addressTypeId); + logger.info("getUserAddress:: Required address with addressTypeId={} is found", addressTypeId); return address.getAddressLine1(); } } - log.warn("getUserAddress:: Required address is not found with addressTypId={}", addressTypeId); + logger.warn("getUserAddress:: Required address is not found with addressTypId={}", addressTypeId); return ""; } @@ -133,7 +193,8 @@ private RoutingList fillRoutingListForContext(RoutingList routingList) { private Future postTemplateRequest(TemplateProcessingRequest templateRequest, RequestContext requestContext) { var requestEntry = new RequestEntry(TEMPLATE_REQUEST_ENDPOINT); - log.info("postTemplateRequest:: Sending template request with routing list name={}", templateRequest.getContext().getRoutingList().getName()); + logger.info("postTemplateRequest:: Sending template request with routing list name={}", templateRequest.getContext().getRoutingList().getName()); return restClient.postJsonObject(requestEntry, JsonObject.mapFrom(templateRequest), requestContext); } + } diff --git a/src/main/java/org/folio/service/routinglists/RoutingListsStorageService.java b/src/main/java/org/folio/service/routinglists/RoutingListsStorageService.java deleted file mode 100644 index 458418841..000000000 --- a/src/main/java/org/folio/service/routinglists/RoutingListsStorageService.java +++ /dev/null @@ -1,87 +0,0 @@ -package org.folio.service.routinglists; - -import io.vertx.core.Future; -import io.vertx.core.json.JsonObject; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.folio.rest.RestConstants; -import org.folio.rest.core.RestClient; -import org.folio.rest.core.exceptions.HttpException; -import org.folio.rest.core.models.RequestContext; -import org.folio.rest.core.models.RequestEntry; -import org.folio.rest.jaxrs.model.Error; -import org.folio.rest.jaxrs.model.Errors; -import org.folio.rest.jaxrs.model.PoLine; -import org.folio.rest.jaxrs.model.RoutingList; -import org.folio.rest.jaxrs.model.RoutingListCollection; -import org.folio.service.orders.PurchaseOrderLineService; -import org.folio.service.routinglists.validators.RoutingListValidatorUtil; - -import java.util.List; - -import static org.folio.orders.utils.ResourcePathResolver.ROUTING_LIST_STORAGE; -import static org.folio.orders.utils.ResourcePathResolver.resourcesPath; - -public class RoutingListsStorageService { - private static final Logger logger = LogManager.getLogger(RoutingListsStorageService.class); - - private static final String ROUTING_LIST_STORAGE_ENDPOINT = resourcesPath(ROUTING_LIST_STORAGE); - private static final String ROUTING_LIST_STORAGE_BY_ID_ENDPOINT = ROUTING_LIST_STORAGE_ENDPOINT + "/{id}"; - private static final String ROUTING_LIST_BY_POL_ID = "poLineId==%s"; - - private final PurchaseOrderLineService poLineService; - private final RestClient restClient; - - public RoutingListsStorageService(PurchaseOrderLineService poLineService, RestClient restClient) { - this.poLineService = poLineService; - this.restClient = restClient; - } - - public Future getRoutingList(String rListId, RequestContext requestContext) { - RequestEntry requestEntry = new RequestEntry(ROUTING_LIST_STORAGE_BY_ID_ENDPOINT).withId(rListId); - return restClient.get(requestEntry, RoutingList.class, requestContext); - } - - public Future updateRoutingList(RoutingList routingList, RequestContext requestContext) { - validateRoutingList(routingList, requestContext); - RequestEntry requestEntry = new RequestEntry(ROUTING_LIST_STORAGE_BY_ID_ENDPOINT).withId(routingList.getId()); - return restClient.put(requestEntry, requestContext, requestContext); - } - - public Future deleteRoutingList(String rListId, RequestContext requestContext) { - RequestEntry requestEntry = new RequestEntry(ROUTING_LIST_STORAGE_BY_ID_ENDPOINT).withId(rListId); - return restClient.delete(requestEntry, requestContext); - } - - public Future createRoutingList(RoutingList routingList, RequestContext requestContext) { - validateRoutingList(routingList, requestContext); - RequestEntry requestEntry = new RequestEntry(ROUTING_LIST_STORAGE_ENDPOINT); - return restClient.post(requestEntry, routingList, RoutingList.class, requestContext); - } - - public Future getRoutingLists(int limit, int offset, String query, RequestContext requestContext) { - RequestEntry requestEntry = new RequestEntry(ROUTING_LIST_STORAGE_ENDPOINT) - .withQuery(query) - .withOffset(offset) - .withLimit(limit); - return restClient.get(requestEntry, RoutingListCollection.class, requestContext); - } - - private Future getRoutingListsByPoLineId(String poLineId, RequestContext requestContext) { - String query = String.format(ROUTING_LIST_BY_POL_ID, poLineId); - return getRoutingLists(Integer.MAX_VALUE, 0, query, requestContext); - } - - private void validateRoutingList(RoutingList routingList, RequestContext requestContext) { - RoutingListCollection routingLists = getRoutingListsByPoLineId(routingList.getPoLineId(), requestContext).result(); - PoLine poLine = poLineService.getOrderLineById(routingList.getPoLineId(), requestContext).result(); - List combinedErrors = RoutingListValidatorUtil.validateRoutingList(routingLists, poLine); - if (CollectionUtils.isNotEmpty(combinedErrors)) { - Errors errors = new Errors().withErrors(combinedErrors).withTotalRecords(combinedErrors.size()); - logger.error("Validation error: {}", JsonObject.mapFrom(errors).encodePrettily()); - throw new HttpException(RestConstants.VALIDATION_ERROR, errors); - } - } - -} diff --git a/src/test/java/org/folio/ApiTestSuite.java b/src/test/java/org/folio/ApiTestSuite.java index f0dac243e..145383176 100644 --- a/src/test/java/org/folio/ApiTestSuite.java +++ b/src/test/java/org/folio/ApiTestSuite.java @@ -99,7 +99,7 @@ import org.folio.service.pieces.flows.update.PieceUpdateFlowManagerTest; import org.folio.service.pieces.flows.update.PieceUpdateFlowPoLineServiceTest; import org.folio.service.pieces.validators.PieceValidatorUtilTest; -import org.folio.service.RoutingListServiceTest; +import org.folio.service.routinglists.RoutingListServiceTest; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Nested; diff --git a/src/test/java/org/folio/rest/impl/MockServer.java b/src/test/java/org/folio/rest/impl/MockServer.java index 879e975d1..4c9f28e6f 100644 --- a/src/test/java/org/folio/rest/impl/MockServer.java +++ b/src/test/java/org/folio/rest/impl/MockServer.java @@ -63,7 +63,7 @@ import static org.folio.orders.utils.ResourcePathResolver.FINANCE_EXCHANGE_RATE; import static org.folio.orders.utils.ResourcePathResolver.FUNDS; import static org.folio.orders.utils.ResourcePathResolver.LEDGERS; -import static org.folio.orders.utils.ResourcePathResolver.ROUTING_LIST_STORAGE; +import static org.folio.orders.utils.ResourcePathResolver.ROUTING_LISTS; import static org.folio.orders.utils.ResourcePathResolver.USER_TENANTS_ENDPOINT; import static org.folio.orders.utils.ResourcePathResolver.LEDGER_FY_ROLLOVERS; import static org.folio.orders.utils.ResourcePathResolver.LEDGER_FY_ROLLOVER_ERRORS; @@ -245,14 +245,13 @@ public class MockServer { private static final String HOLDINGS_SOURCE_MOCK_DATA_PATH = BASE_MOCK_DATA_PATH + "holdingsSources/"; public static final String PIECE_RECORDS_MOCK_DATA_PATH = BASE_MOCK_DATA_PATH + "pieces/"; public static final String PO_LINES_MOCK_DATA_PATH = BASE_MOCK_DATA_PATH + "lines/"; - public static final String ROUTING_LIST_MOCK_DATA_PATH = BASE_MOCK_DATA_PATH + "routingLists/"; + public static final String ROUTING_LISTS_MOCK_DATA_PATH = BASE_MOCK_DATA_PATH + "routingLists/"; public static final String USERS_MOCK_DATA_PATH = BASE_MOCK_DATA_PATH + "users/"; public static final String TITLES_MOCK_DATA_PATH = BASE_MOCK_DATA_PATH + "titles/"; private static final String ACQUISITIONS_UNITS_MOCK_DATA_PATH = BASE_MOCK_DATA_PATH + "acquisitionsUnits/units"; private static final String ORDER_TEMPLATES_MOCK_DATA_PATH = BASE_MOCK_DATA_PATH + "orderTemplates/"; private static final String RECEIVING_HISTORY_MOCK_DATA_PATH = BASE_MOCK_DATA_PATH + "receivingHistory/"; private static final String ORGANIZATIONS_MOCK_DATA_PATH = BASE_MOCK_DATA_PATH + "organizations/"; - public static final String ROUTING_LISTS_MOCK_DATA_PATH = BASE_MOCK_DATA_PATH + "routing-lists/"; public static final String POLINES_COLLECTION = PO_LINES_MOCK_DATA_PATH + "po_line_collection.json"; private static final String IDENTIFIER_TYPES_MOCK_DATA_PATH = BASE_MOCK_DATA_PATH + "identifierTypes/"; private static final String ITEM_REQUESTS_MOCK_DATA_PATH = BASE_MOCK_DATA_PATH + "itemRequests/"; @@ -551,7 +550,7 @@ private Router defineRoutes() { router.post(resourcesPath(ORDER_TEMPLATES)).handler(ctx -> handlePostGenericSubObj(ctx, ORDER_TEMPLATES)); router.post(resourcesPath(FINANCE_BATCH_TRANSACTIONS)).handler(this::handleBatchTransactions); router.post(resourcesPath(TITLES)).handler(ctx -> handlePostGenericSubObj(ctx, TITLES)); - router.post(resourcesPath(ROUTING_LIST_STORAGE)).handler(ctx -> handlePostGenericSubObj(ctx, ROUTING_LIST_STORAGE)); + router.post(resourcesPath(ROUTING_LISTS)).handler(ctx -> handlePostGenericSubObj(ctx, ROUTING_LISTS)); router.post(resourcesPath(ACQUISITIONS_UNITS)).handler(ctx -> handlePostGenericSubObj(ctx, ACQUISITIONS_UNITS)); router.post(resourcesPath(ACQUISITION_METHODS)).handler(ctx -> handlePostGenericSubObj(ctx, ACQUISITION_METHODS)); @@ -605,8 +604,8 @@ private Router defineRoutes() { router.get(resourcesPath(LEDGERS)).handler(this::handleGetLedgers); router.get(resourcesPath(TITLES)).handler(this::handleGetTitles); router.get(resourcePath(TITLES)).handler(this::handleGetOrderTitleById); - router.get(resourcesPath(ROUTING_LIST_STORAGE)).handler(this::handleGetRoutingLists); - router.get(resourcePath(ROUTING_LIST_STORAGE)).handler(this::handleGetRoutingListById); + router.get(resourcesPath(ROUTING_LISTS)).handler(this::handleGetRoutingLists); + router.get(resourcePath(ROUTING_LISTS)).handler(this::handleGetRoutingListById); router.get(resourcesPath(REASONS_FOR_CLOSURE)).handler(ctx -> handleGetGenericSubObjs(ctx, REASONS_FOR_CLOSURE)); router.get(resourcesPath(PREFIXES)).handler(ctx -> handleGetGenericSubObjs(ctx, PREFIXES)); router.get(resourcesPath(SUFFIXES)).handler(ctx -> handleGetGenericSubObjs(ctx, SUFFIXES)); @@ -641,7 +640,7 @@ private Router defineRoutes() { router.put(resourcePath(ACQUISITIONS_MEMBERSHIPS)).handler(ctx -> handlePutGenericSubObj(ctx, ACQUISITIONS_MEMBERSHIPS)); router.put(resourcePath(ORDER_TEMPLATES)).handler(ctx -> handlePutGenericSubObj(ctx, ORDER_TEMPLATES)); router.put(resourcePath(TITLES)).handler(ctx -> handlePutGenericSubObj(ctx, TITLES)); - router.put(resourcePath(ROUTING_LIST_STORAGE)).handler(ctx -> handlePutGenericSubObj(ctx, ROUTING_LIST_STORAGE)); + router.put(resourcePath(ROUTING_LISTS)).handler(ctx -> handlePutGenericSubObj(ctx, ROUTING_LISTS)); router.put(resourcePath(REASONS_FOR_CLOSURE)).handler(ctx -> handlePutGenericSubObj(ctx, REASONS_FOR_CLOSURE)); router.put(resourcePath(PREFIXES)).handler(ctx -> handlePutGenericSubObj(ctx, PREFIXES)); router.put(resourcePath(SUFFIXES)).handler(ctx -> handlePutGenericSubObj(ctx, SUFFIXES)); @@ -658,7 +657,7 @@ private Router defineRoutes() { router.delete(resourcePath(ACQUISITIONS_MEMBERSHIPS)).handler(ctx -> handleDeleteGenericSubObj(ctx, ACQUISITIONS_MEMBERSHIPS)); router.delete(resourcePath(ORDER_TEMPLATES)).handler(ctx -> handleDeleteGenericSubObj(ctx, ORDER_TEMPLATES)); router.delete(resourcePath(TITLES)).handler(ctx -> handleDeleteGenericSubObj(ctx, TITLES)); - router.delete(resourcePath(ROUTING_LIST_STORAGE)).handler(ctx -> handleDeleteGenericSubObj(ctx, ROUTING_LIST_STORAGE)); + router.delete(resourcePath(ROUTING_LISTS)).handler(ctx -> handleDeleteGenericSubObj(ctx, ROUTING_LISTS)); router.delete(resourcePath(REASONS_FOR_CLOSURE)).handler(ctx -> handleDeleteGenericSubObj(ctx, REASONS_FOR_CLOSURE)); router.delete(resourcePath(PREFIXES)).handler(ctx -> handleDeleteGenericSubObj(ctx, PREFIXES)); router.delete(resourcePath(SUFFIXES)).handler(ctx -> handleDeleteGenericSubObj(ctx, SUFFIXES)); @@ -731,7 +730,7 @@ private JsonObject getRoutingListsByPoLineId(List poLineId) { } }; - List rLists = getMockEntries(ROUTING_LIST_STORAGE, RoutingList.class).orElseGet(getFromFile); + List rLists = getMockEntries(ROUTING_LISTS, RoutingList.class).orElseGet(getFromFile); if (!poLineId.isEmpty()) { rLists.removeIf(item -> !item.getPoLineId().equals(poLineId.get(0))); @@ -1976,7 +1975,7 @@ private void handleGetRoutingListById(RoutingContext ctx) { String id = ctx.request().getParam(ID); logger.info("id: " + id); - addServerRqRsData(HttpMethod.GET, ROUTING_LIST_STORAGE, new JsonObject().put(ID, id)); + addServerRqRsData(HttpMethod.GET, ROUTING_LISTS, new JsonObject().put(ID, id)); if (ID_FOR_INTERNAL_SERVER_ERROR.equals(id)) { serverResponse(ctx, 500, APPLICATION_JSON, INTERNAL_SERVER_ERROR.getReasonPhrase()); @@ -1984,7 +1983,7 @@ private void handleGetRoutingListById(RoutingContext ctx) { try { // Attempt to find title in mock server memory - JsonObject existantTitle = getMockEntry(ROUTING_LIST_STORAGE, id).orElse(null); + JsonObject existantTitle = getMockEntry(ROUTING_LISTS, id).orElse(null); // If previous step has no result then attempt to find title in stubs if (existantTitle == null) { @@ -2001,7 +2000,7 @@ private void handleGetRoutingListById(RoutingContext ctx) { private void handleGetRoutingLists(RoutingContext ctx) { String query = StringUtils.trimToEmpty(ctx.request().getParam(QUERY)); - addServerRqQuery(ROUTING_LIST_STORAGE, query); + addServerRqQuery(ROUTING_LISTS, query); if (query.contains(ID_FOR_INTERNAL_SERVER_ERROR)) { serverResponse(ctx, 500, APPLICATION_JSON, INTERNAL_SERVER_ERROR.getReasonPhrase()); } else { @@ -2013,7 +2012,7 @@ private void handleGetRoutingLists(RoutingContext ctx) { } JsonObject collection = getRoutingListsByPoLineId(ids); - addServerRqRsData(HttpMethod.GET, ROUTING_LIST_STORAGE, collection); + addServerRqRsData(HttpMethod.GET, ROUTING_LISTS, collection); ctx.response() .setStatusCode(200) diff --git a/src/test/java/org/folio/rest/impl/RoutingListsApiTest.java b/src/test/java/org/folio/rest/impl/RoutingListsApiTest.java index cd13f87ef..a3d3cf555 100644 --- a/src/test/java/org/folio/rest/impl/RoutingListsApiTest.java +++ b/src/test/java/org/folio/rest/impl/RoutingListsApiTest.java @@ -13,6 +13,7 @@ import org.folio.rest.jaxrs.model.Errors; import org.folio.rest.jaxrs.model.PoLine; import org.folio.service.orders.PurchaseOrderLineService; +import org.folio.service.routinglists.RoutingListService; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; @@ -48,6 +49,7 @@ import static org.folio.TestConstants.EXIST_CONFIG_X_OKAPI_TENANT_LIMIT_10; import static org.folio.TestConstants.ID_BAD_FORMAT; import static org.folio.TestConstants.ID_DOES_NOT_EXIST; +import static org.folio.TestConstants.ROUTING_LIST_ID; import static org.folio.TestConstants.X_OKAPI_TOKEN; import static org.folio.TestConstants.X_OKAPI_USER_ID; import static org.folio.TestConstants.X_OKAPI_USER_ID_WITH_ACQ_UNITS; diff --git a/src/test/java/org/folio/service/RoutingListServiceTest.java b/src/test/java/org/folio/service/RoutingListServiceTest.java deleted file mode 100644 index fe9651a93..000000000 --- a/src/test/java/org/folio/service/RoutingListServiceTest.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.folio.service; - -import static io.vertx.core.Future.succeededFuture; -import static org.folio.TestConstants.ROUTING_LIST_ID; -import static org.folio.TestUtils.getMockData; -import static org.folio.rest.impl.MockServer.ROUTING_LIST_MOCK_DATA_PATH; -import static org.folio.rest.impl.MockServer.USERS_MOCK_DATA_PATH; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import io.vertx.core.Future; -import io.vertx.core.json.JsonObject; -import io.vertx.junit5.VertxExtension; -import io.vertx.junit5.VertxTestContext; -import org.folio.models.UserCollection; -import org.folio.rest.acq.model.Setting; -import org.folio.rest.acq.model.SettingCollection; -import org.folio.rest.core.RestClient; -import org.folio.rest.core.models.RequestContext; -import org.folio.rest.core.models.RequestEntry; -import org.folio.rest.jaxrs.model.RoutingList; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@ExtendWith(VertxExtension.class) -public class RoutingListServiceTest { - - @InjectMocks - RoutingListService routingListService; - @Mock - private RestClient restClient; - @Mock - private UserService userService; - @Mock - private RequestContext requestContextMock; - private AutoCloseable mockitoMocks; - - @BeforeEach - public void initMocks() throws Exception { - mockitoMocks = MockitoAnnotations.openMocks(this); - } - - @AfterEach - void afterEach() throws Exception { - mockitoMocks.close(); - } - - @Test - void processTemplate(VertxTestContext vertxTestContext) throws IOException { - var routingList = new JsonObject(getMockData(ROUTING_LIST_MOCK_DATA_PATH + ROUTING_LIST_ID + ".json")).mapTo(RoutingList.class); - var users = new JsonObject(getMockData(USERS_MOCK_DATA_PATH + "user_collection.json")).mapTo(UserCollection.class); - var expectedTemplateRequest = new JsonObject(getMockData(ROUTING_LIST_MOCK_DATA_PATH + ROUTING_LIST_ID + "-expected-template-request.json")); - var setting = new Setting().withId(UUID.randomUUID().toString()) - .withKey("routing-list") - .withValue("1c4b225f-f669-4e9b-afcd-ebc0e273a34e"); - var settingCollection = new SettingCollection().withSettings(List.of(setting)); - - doReturn(succeededFuture(routingList)).when(restClient).get(any(RequestEntry.class), eq(RoutingList.class), any()); - doReturn(succeededFuture(users)).when(userService).getUsersByIds(eq(routingList.getUserIds()), any()); - doReturn(succeededFuture(settingCollection)).when(restClient).get(any(RequestEntry.class), eq(SettingCollection.class), any()); - doReturn(succeededFuture(new JsonObject())).when(restClient).postJsonObject(any(RequestEntry.class), eq(expectedTemplateRequest), any()); - - Future future = routingListService.processTemplateRequest(ROUTING_LIST_ID, requestContextMock); - - vertxTestContext.assertComplete(future).onComplete(result -> { - assertTrue(result.succeeded()); - vertxTestContext.completeNow(); - }); - } - - @Test - void throwErrorWhenSettingNotFound(VertxTestContext vertxTestContext) throws IOException { - var routingList = new JsonObject(getMockData(ROUTING_LIST_MOCK_DATA_PATH + ROUTING_LIST_ID + ".json")).mapTo(RoutingList.class); - var users = new JsonObject(getMockData(USERS_MOCK_DATA_PATH + "user_collection.json")).mapTo(UserCollection.class); - - doReturn(succeededFuture(routingList)).when(restClient).get(any(RequestEntry.class), eq(RoutingList.class), any()); - doReturn(succeededFuture(users)).when(userService).getUsersByIds(eq(routingList.getUserIds()), any()); - doReturn(succeededFuture(new SettingCollection().withSettings(new ArrayList<>()))) - .when(restClient).get(any(RequestEntry.class), eq(SettingCollection.class), any()); - - Future future = routingListService.processTemplateRequest(ROUTING_LIST_ID, requestContextMock); - - vertxTestContext.assertFailure(future).onComplete(result -> { - assertTrue(result.failed()); - var exception = result.cause().getMessage(); - assertTrue(exception.contains("Setting is not found with key=ROUTING_USER_ADDRESS_TYPE_ID")); - vertxTestContext.completeNow(); - }); - } -} diff --git a/src/test/java/org/folio/service/routinglists/RoutingListServiceTest.java b/src/test/java/org/folio/service/routinglists/RoutingListServiceTest.java index 817b82f32..e14c8cb92 100644 --- a/src/test/java/org/folio/service/routinglists/RoutingListServiceTest.java +++ b/src/test/java/org/folio/service/routinglists/RoutingListServiceTest.java @@ -1,30 +1,47 @@ package org.folio.service.routinglists; import io.vertx.core.Future; +import io.vertx.core.json.JsonObject; import io.vertx.junit5.VertxExtension; +import io.vertx.junit5.VertxTestContext; +import org.folio.models.UserCollection; +import org.folio.rest.acq.model.Setting; +import org.folio.rest.acq.model.SettingCollection; import org.folio.rest.core.RestClient; import org.folio.rest.core.exceptions.HttpException; +import org.folio.rest.core.models.RequestContext; import org.folio.rest.core.models.RequestEntry; import org.folio.rest.jaxrs.model.PoLine; import org.folio.rest.jaxrs.model.RoutingList; import org.folio.rest.jaxrs.model.RoutingListCollection; +import org.folio.service.UserService; import org.folio.service.orders.PurchaseOrderLineService; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.UUID; +import static io.vertx.core.Future.succeededFuture; +import static org.folio.TestConstants.ROUTING_LIST_ID; import static org.folio.TestUtils.getLocationPhysicalCopies; import static org.folio.TestUtils.getMinimalContentPoLine; import static org.folio.TestUtils.getMockAsJson; +import static org.folio.TestUtils.getMockData; import static org.folio.rest.impl.MockServer.ROUTING_LISTS_MOCK_DATA_PATH; +import static org.folio.rest.impl.MockServer.USERS_MOCK_DATA_PATH; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; @ExtendWith(VertxExtension.class) public class RoutingListServiceTest { @@ -42,45 +59,98 @@ public class RoutingListServiceTest { @Mock private PurchaseOrderLineService poLineService; - private RoutingListsStorageService routingListService; + @Mock + private UserService userService; + + @Mock + private RequestContext requestContextMock; + + @InjectMocks + private RoutingListService routingListService; + + private AutoCloseable mockitoMocks; @BeforeEach void before() { + mockitoMocks = MockitoAnnotations.openMocks(this); sampleRoutingList = getMockAsJson(ROUTING_LIST_SAMPLE).mapTo(RoutingList.class); samplePoLine = getMinimalContentPoLine() .withId(PO_LINE_UUID) .withOrderFormat(PoLine.OrderFormat.PHYSICAL_RESOURCE) .withLocations(getLocationPhysicalCopies(1)); + } - routingListService = spy(new RoutingListsStorageService(poLineService, restClient)); + @AfterEach + void afterEach() throws Exception { + mockitoMocks.close(); } @Test void testCreateRoutingList() { - doReturn(getRoutingListCollection(1)).when(restClient).get(any(RequestEntry.class), RoutingList.class, any()); - doReturn(Future.succeededFuture(samplePoLine)).when(poLineService).getOrderLineById(any(), any()); - doReturn(Future.succeededFuture(List.of())).when(routingListService).getRoutingLists(any(), any(), any(), any()); + doReturn(succeededFuture(getRoutingListCollection(0))).when(restClient).get(any(RequestEntry.class), eq(RoutingListCollection.class), any()); + doReturn(succeededFuture(samplePoLine)).when(poLineService).getOrderLineById(any(), any()); - routingListService.createRoutingList(sampleRoutingList, null); + routingListService.createRoutingList(sampleRoutingList, requestContextMock); } @Test void testCreateRoutingListWithPOLineLimitReached() { - doReturn(getRoutingListCollection(1)).when(restClient).get(any(RequestEntry.class), RoutingList.class, any()); - doReturn(Future.succeededFuture(samplePoLine)).when(poLineService).getOrderLineById(any(), any()); - doReturn(Future.succeededFuture(List.of(sampleRoutingList))).when(routingListService).getRoutingLists(any(), any(), any(), any()); + doReturn(succeededFuture(getRoutingListCollection(1))).when(restClient).get(any(RequestEntry.class), eq(RoutingListCollection.class), any()); + doReturn(succeededFuture(samplePoLine)).when(poLineService).getOrderLineById(any(), any()); - assertThrows(HttpException.class, () -> routingListService.createRoutingList(sampleRoutingList, null)); + assertThrows(HttpException.class, () -> routingListService.createRoutingList(sampleRoutingList, requestContextMock)); } @Test void testCreateRoutingListWithPOLineInvalidOrderFormat() { samplePoLine.setOrderFormat(PoLine.OrderFormat.ELECTRONIC_RESOURCE); - doReturn(getRoutingListCollection(0)).when(restClient).get(any(RequestEntry.class), RoutingList.class, any()); - doReturn(Future.succeededFuture(samplePoLine)).when(poLineService).getOrderLineById(any(), any()); - doReturn(Future.succeededFuture(List.of())).when(routingListService).getRoutingLists(any(), any(), any(), any()); + doReturn(succeededFuture(getRoutingListCollection(0))).when(restClient).get(any(RequestEntry.class), eq(RoutingListCollection.class), any()); + doReturn(succeededFuture(samplePoLine)).when(poLineService).getOrderLineById(any(), any()); - assertThrows(HttpException.class, () -> routingListService.createRoutingList(sampleRoutingList, null)); + assertThrows(HttpException.class, () -> routingListService.createRoutingList(sampleRoutingList, requestContextMock)); + } + + @Test + void processTemplate(VertxTestContext vertxTestContext) throws IOException { + var routingList = new JsonObject(getMockData(ROUTING_LISTS_MOCK_DATA_PATH + ROUTING_LIST_ID + ".json")).mapTo(RoutingList.class); + var users = new JsonObject(getMockData(USERS_MOCK_DATA_PATH + "user_collection.json")).mapTo(UserCollection.class); + var expectedTemplateRequest = new JsonObject(getMockData(ROUTING_LISTS_MOCK_DATA_PATH + ROUTING_LIST_ID + "-expected-template-request.json")); + var setting = new Setting().withId(UUID.randomUUID().toString()) + .withKey("routing-list") + .withValue("1c4b225f-f669-4e9b-afcd-ebc0e273a34e"); + var settingCollection = new SettingCollection().withSettings(List.of(setting)); + + doReturn(succeededFuture(routingList)).when(restClient).get(any(RequestEntry.class), eq(RoutingList.class), any()); + doReturn(succeededFuture(users)).when(userService).getUsersByIds(eq(routingList.getUserIds()), any()); + doReturn(succeededFuture(settingCollection)).when(restClient).get(any(RequestEntry.class), eq(SettingCollection.class), any()); + doReturn(succeededFuture(new JsonObject())).when(restClient).postJsonObject(any(RequestEntry.class), eq(expectedTemplateRequest), any()); + + Future future = routingListService.processTemplateRequest(ROUTING_LIST_ID, requestContextMock); + + vertxTestContext.assertComplete(future).onComplete(result -> { + assertTrue(result.succeeded()); + vertxTestContext.completeNow(); + }); + } + + @Test + void throwErrorWhenSettingNotFound(VertxTestContext vertxTestContext) throws IOException { + var routingList = new JsonObject(getMockData(ROUTING_LISTS_MOCK_DATA_PATH + ROUTING_LIST_ID + ".json")).mapTo(RoutingList.class); + var users = new JsonObject(getMockData(USERS_MOCK_DATA_PATH + "user_collection.json")).mapTo(UserCollection.class); + + doReturn(succeededFuture(routingList)).when(restClient).get(any(RequestEntry.class), eq(RoutingList.class), any()); + doReturn(succeededFuture(users)).when(userService).getUsersByIds(eq(routingList.getUserIds()), any()); + doReturn(succeededFuture(new SettingCollection().withSettings(new ArrayList<>()))) + .when(restClient).get(any(RequestEntry.class), eq(SettingCollection.class), any()); + + Future future = routingListService.processTemplateRequest(ROUTING_LIST_ID, requestContextMock); + + vertxTestContext.assertFailure(future).onComplete(result -> { + assertTrue(result.failed()); + var exception = result.cause().getMessage(); + assertTrue(exception.contains("Setting is not found with key=ROUTING_USER_ADDRESS_TYPE_ID")); + vertxTestContext.completeNow(); + }); } private RoutingListCollection getRoutingListCollection(int n) { diff --git a/src/test/resources/mockdata/routing-lists/c0d13648-347b-4ac9-8c2f-5bc47248b87e.json b/src/test/resources/mockdata/routingLists/c0d13648-347b-4ac9-8c2f-5bc47248b87e.json similarity index 100% rename from src/test/resources/mockdata/routing-lists/c0d13648-347b-4ac9-8c2f-5bc47248b87e.json rename to src/test/resources/mockdata/routingLists/c0d13648-347b-4ac9-8c2f-5bc47248b87e.json diff --git a/src/test/resources/mockdata/routing-lists/routing-list.json b/src/test/resources/mockdata/routingLists/routing-list.json similarity index 100% rename from src/test/resources/mockdata/routing-lists/routing-list.json rename to src/test/resources/mockdata/routingLists/routing-list.json diff --git a/src/test/resources/mockdata/routing-lists/routing-lists.json b/src/test/resources/mockdata/routingLists/routing-lists.json similarity index 100% rename from src/test/resources/mockdata/routing-lists/routing-lists.json rename to src/test/resources/mockdata/routingLists/routing-lists.json