Skip to content

Commit

Permalink
[MODORSERS-1026] - Implement API to execute mod-template-engine request
Browse files Browse the repository at this point in the history
  • Loading branch information
azizbekxm committed Mar 28, 2024
1 parent c73fa3e commit 47ef021
Show file tree
Hide file tree
Showing 12 changed files with 355 additions and 15 deletions.
13 changes: 13 additions & 0 deletions descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -1003,6 +1003,19 @@
}
]
},
{
"id": "orders.routing-list",
"version": "1.0",
"handlers": [
{
"methods": ["POST"],
"pathPattern": "/orders/routing-lists/{id}/process-template",
"permissionsRequired": [
"orders.routing-list.item.post"
]
}
]
},
{
"id": "_jsonSchemas",
"version": "1.0",
Expand Down
12 changes: 4 additions & 8 deletions ramls/routing-lists.raml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ documentation:
content: <b>CRUD API to manage routing lists.</b>

types:
title: !include acq-models/mod-orders-storage/schemas/routing_list.json
title_collection: !include acq-models/mod-orders-storage/schemas/routing_list_collection.json
routing_list: !include acq-models/mod-orders-storage/schemas/routing_list.json
routing_list_collection: !include acq-models/mod-orders-storage/schemas/routing_list_collection.json
UUID:
type: string
pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
Expand All @@ -19,8 +19,8 @@ traits:
searchable: !include raml-util/traits/searchable.raml

resourceTypes:
collection: !include raml-util/rtypes/collection.raml
collection-item: !include raml-util/rtypes/item-collection.raml
collection: !include rtypes/collection-with-json-response.raml
collection-item: !include rtypes/item-collection-with-json-response.raml

/orders/routing-lists:
type:
Expand All @@ -40,9 +40,5 @@ resourceTypes:
id:
description: The UUID of a Title
type: UUID
type:
collection-item:
exampleItem: !include acq-models/mod-orders-storage/examples/routing_list_get.sample
schema: routing_list
post:
description: Execute mod-template-engine to process templates with replaced token placeholders [update]
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package org.folio.models.template;

import java.util.List;
import java.util.UUID;

import lombok.Getter;

@Getter
public class TemplateProcessingRequest {
private UUID templateId;
private String lang;
private String outputFormat;
private Context context;

public TemplateProcessingRequest withTemplateId(UUID templateId) {
this.templateId = templateId;
return this;
}

public TemplateProcessingRequest withLang(String lang) {
this.lang = lang;
return this;
}

public TemplateProcessingRequest withOutputFormat(String outputFormat) {
this.outputFormat = outputFormat;
return this;
}

public TemplateProcessingRequest withContext(Context context) {
this.context = context;
return this;
}

@Getter
public static class Context {
private List<User> users;
private List<Item> items;

public Context withUsers(List<User> users) {
this.users = users;
return this;
}

}

@Getter
public static class User {
private String name;
public User withName(String name) {
this.name = name;
return this;
}
}

@Getter
public static class Item {
private String name;

public Item setName(String name) {
this.name = name;
return this;
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ private ResourcePathResolver() {
public static final String PAYMENT_STATUS = "paymentStatus";
public static final String ORDER_TEMPLATES = "orderTemplates";
public static final String TITLES = "titles";
public static final String ROUTING_LISTS = "routing-lists";
public static final String TEMPLATE_REQUEST = "template-request";
public static final String USERS = "users";
public static final String FUNDS = "finance.funds";
public static final String BUDGETS = "finance.budgets";
public static final String LEDGERS = "finance.ledgers";
Expand Down Expand Up @@ -66,6 +69,8 @@ private ResourcePathResolver() {
apis.put(RECEIVING_HISTORY, "/orders-storage/receiving-history");
apis.put(PO_LINE_NUMBER, "/orders-storage/po-line-number");
apis.put(ORDER_TEMPLATES, "/orders-storage/order-templates");
apis.put(ROUTING_LISTS, "/orders-storage/routing-lists");
apis.put(TEMPLATE_REQUEST, "/template-request");
apis.put(FUNDS, "/finance/funds");
apis.put(BUDGETS, "/finance/budgets");
apis.put(LEDGERS, "/finance-storage/ledgers");
Expand All @@ -86,6 +91,7 @@ private ResourcePathResolver() {
apis.put(ORDER_INVOICE_RELATIONSHIP, "/orders-storage/order-invoice-relns");
apis.put(EXPORT_HISTORY, "/orders-storage/export-history");
apis.put(TAGS, "/tags");
apis.put(USERS, "/users");

SUB_OBJECT_COLLECTION_APIS = Collections.unmodifiableMap(apis);
SUB_OBJECT_ITEM_APIS = Collections.unmodifiableMap(
Expand Down
13 changes: 6 additions & 7 deletions src/main/java/org/folio/rest/core/RestClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,6 @@

import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.folio.okapi.common.WebClientFactory;
import org.folio.rest.core.exceptions.HttpException;
import org.folio.rest.core.models.RequestContext;
import org.folio.rest.core.models.RequestEntry;

import io.vertx.core.Context;
import io.vertx.core.Future;
import io.vertx.core.MultiMap;
Expand All @@ -29,6 +22,12 @@
import io.vertx.ext.web.client.WebClientOptions;
import io.vertx.ext.web.client.predicate.ErrorConverter;
import io.vertx.ext.web.client.predicate.ResponsePredicate;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.folio.okapi.common.WebClientFactory;
import org.folio.rest.core.exceptions.HttpException;
import org.folio.rest.core.models.RequestContext;
import org.folio.rest.core.models.RequestEntry;

public class RestClient {

Expand Down
39 changes: 39 additions & 0 deletions src/main/java/org/folio/rest/impl/RoutingListAPI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.folio.rest.impl;

import javax.ws.rs.core.Response;
import java.util.Map;

import io.vertx.core.AsyncResult;
import io.vertx.core.Context;
import io.vertx.core.Handler;
import org.apache.commons.lang.NotImplementedException;
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.routinglist.RoutingListService;
import org.springframework.beans.factory.annotation.Autowired;

public class RoutingListAPI extends BaseApi implements OrdersRoutingLists {

@Autowired
private RoutingListService routingListService;

@Override
public void getOrdersRoutingLists(String query, String totalRecords, int offset, int limit, Map<String, String> okapiHeaders,
Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {
throw new NotImplementedException();
}

@Override
public void postOrdersRoutingLists(RoutingList entity, Map<String, String> okapiHeaders,
Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {
throw new NotImplementedException();
}

@Override
public void postOrdersRoutingListsProcessTemplateById(String id, Map<String, String> okapiHeaders,
Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {
routingListService.processTemplateEngine(id, new RequestContext(vertxContext, okapiHeaders))
.onFailure(t -> handleErrorResponse(asyncResultHandler, t));
}
}
25 changes: 25 additions & 0 deletions src/main/java/org/folio/service/UserService.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,37 @@
package org.folio.service;

import static org.folio.orders.utils.HelperUtils.convertIdsToCqlQuery;
import static org.folio.orders.utils.ResourcePathResolver.USERS;
import static org.folio.orders.utils.ResourcePathResolver.resourcesPath;
import static org.folio.rest.RestVerticle.OKAPI_USERID_HEADER;

import java.util.List;
import java.util.Map;

import io.vertx.core.Future;
import io.vertx.core.json.JsonObject;
import org.folio.rest.core.RestClient;
import org.folio.rest.core.models.RequestContext;
import org.folio.rest.core.models.RequestEntry;

public class UserService {
private static final String ENDPOINT = resourcesPath(USERS);
private final RestClient restClient;

public UserService(RestClient restClient) {
this.restClient = restClient;
}

public static String getCurrentUserId(Map<String, String> okapiHeaders) {
return okapiHeaders.get(OKAPI_USERID_HEADER);
}

public Future<JsonObject> getUsersByIds(List<String> userIds, RequestContext requestContext) {
var requestEntry = new RequestEntry(USERS)
.withOffset(0)
.withLimit(Integer.MAX_VALUE)
.withQuery(convertIdsToCqlQuery(userIds, "sourceInvoiceId"));

return restClient.get(requestEntry, JsonObject.class, requestContext);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package org.folio.service.routinglist;

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.List;
import java.util.UUID;

import io.vertx.core.Future;
import io.vertx.core.json.JsonObject;
import lombok.extern.log4j.Log4j2;
import org.folio.models.template.TemplateProcessingRequest;
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.folio.service.UserService;

@Log4j2
public class RoutingListService {

private static final String ENDPOINT = resourcesPath(ROUTING_LISTS);
private static final String BY_ID_ENDPOINT = ENDPOINT + "/{id}";
private final RestClient restClient;
private final UserService userService;

public RoutingListService(RestClient restClient, UserService userService) {
this.restClient = restClient;
this.userService = userService;
}

public Future<JsonObject> processTemplateEngine(String id, RequestContext requestContext) {
return getRoutingListById(id, requestContext)
.compose(routingList -> fetchUsersAndCreateTemplate(routingList, requestContext))
.compose(templateProcessingRequest -> postTemplateRequest(templateProcessingRequest, requestContext));
}

public Future<RoutingList> getRoutingListById(String routingListId, RequestContext requestContext) {
var requestEntry = new RequestEntry(BY_ID_ENDPOINT).withId(routingListId);
return restClient.get(requestEntry, RoutingList.class, requestContext);
}

private Future<TemplateProcessingRequest> fetchUsersAndCreateTemplate(RoutingList routingList, RequestContext requestContext) {
return userService.getUsersByIds(routingList.getUserIds(), requestContext)
.map(users -> createTemplateRequest(routingList, users));
}

private TemplateProcessingRequest createTemplateRequest(RoutingList routingList, JsonObject users) {
var templateRequest =createBaseTemplateRequest();
var userListForContext = createUserListForContext(users);
var context = new TemplateProcessingRequest.Context().withUsers(userListForContext);
templateRequest.withContext(context);
return templateRequest;
}

private TemplateProcessingRequest createBaseTemplateRequest() {
return new TemplateProcessingRequest()
.withTemplateId(UUID.randomUUID())
.withLang("en")
.withOutputFormat("text/plain");
}

private List<TemplateProcessingRequest.User> createUserListForContext(JsonObject users) {
return users.getJsonArray("users").stream()
.map(JsonObject.class::cast)
.map(user -> new TemplateProcessingRequest.User()
.withName(user.getJsonObject("personal").getString("firstName"))
)
.toList();
}

private Future<JsonObject> postTemplateRequest(TemplateProcessingRequest templateProcessingRequest, RequestContext requestContext) {
return restClient.post(TEMPLATE_REQUEST, JsonObject.mapFrom(templateProcessingRequest), JsonObject.class, requestContext);
}
}
2 changes: 2 additions & 0 deletions src/test/java/org/folio/rest/impl/MockServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ 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 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/";
Expand Down
Loading

0 comments on commit 47ef021

Please sign in to comment.