Skip to content

Commit

Permalink
CIRCSTORE- 514 Implement Post API to fetch print Event Details (#471)
Browse files Browse the repository at this point in the history
* CIRCSTORE-514 Adding a plain index for requestId field of jsonb column

* CIRCSTORE-514 Adding a new endpoint to fetch request print details

* CIRCSTORE-514 Adding new endpoint in module descriptor

* CIRCSTORE-514 Adding test cases, example json files

* CIRCSTORE-514 Adding try catch and loggers
  • Loading branch information
Vignesh-kalyanasundaram authored Jul 22, 2024
1 parent 2ade190 commit 117f2c3
Show file tree
Hide file tree
Showing 12 changed files with 363 additions and 3 deletions.
17 changes: 16 additions & 1 deletion descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,15 @@
"permissionsRequired": [
"print-events-storage.print-events-entry.item.post"
]
},
{
"methods": [
"POST"
],
"pathPattern": "/print-events-storage/print-events-status",
"permissionsRequired": [
"print-events-storage.print-events-status.item.post"
]
}
]
},
Expand Down Expand Up @@ -697,6 +706,11 @@
"displayName": "print events storage - save print event logs",
"description": "save print event log in storage"
},
{
"permissionName": "print-events-storage.print-events-status.item.post",
"displayName": "print-events-storage - Fetch print event status",
"description": "Fetch print event details for a batch of request Ids"
},
{
"permissionName": "check-in-storage.check-ins.collection.get",
"displayName": "Check-in storage - get check-ins collection",
Expand Down Expand Up @@ -1154,7 +1168,8 @@
"circulation-storage.circulation-settings.item.post",
"circulation-storage.circulation-settings.item.put",
"circulation-storage.circulation-settings.item.delete",
"print-events-storage.print-events-entry.item.post"
"print-events-storage.print-events-entry.item.post",
"print-events-storage.print-events-status.item.post"
]
},
{
Expand Down
6 changes: 6 additions & 0 deletions ramls/examples/print-events-status-request.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"requestIds" : [
"fbbbe691-d6c6-4f40-b9dd-7364ccb1518a",
"fd831be3-f05f-4b6f-b68f-1a976ea1ab0f"
]
}
7 changes: 7 additions & 0 deletions ramls/examples/print-events-status-response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"requestId": "fbbbe691-d6c6-4f40-b9dd-7364ccb1518a",
"requesterId": "44642483-f4d4-4a29-a2ba-8eefcf53de16",
"requesterName": "vignesh",
"count": 2,
"printEventDate": "2024-07-04T07:07:00.000+00:00"
}
19 changes: 19 additions & 0 deletions ramls/examples/print-events-status-responses.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"printEventsStatusResponses": [
{
"requestId": "fbbbe691-d6c6-4f40-b9dd-7364ccb1518a",
"requesterId": "44642483-f4d4-4a29-a2ba-8eefcf53de16",
"requesterName": "vignesh",
"count": 2,
"printEventDate": "2024-07-04T07:07:00.000+00:00"
},
{
"requestId": "fd831be3-f05f-4b6f-b68f-1a976ea1ab0f",
"requesterId": "44642483-f4d4-4a29-a2ba-8eefcf53de17",
"requesterName": "siddhu",
"count": 5,
"printEventDate": "2024-07-05T07:07:00.000+00:00"
}
],
"totalRecords": 2
}
17 changes: 17 additions & 0 deletions ramls/print-events-status-request.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Print Events Request",
"type": "object",
"properties": {
"requestIds": {
"description": "List of request IDs",
"type": "array",
"minItems": 1,
"items": {
"type": "string",
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[1-5][a-fA-F0-9]{3}-[89abAB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$"
}
}
}
}

28 changes: 28 additions & 0 deletions ramls/print-events-status-response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Print events details",
"type": "object",
"properties": {
"requestId": {
"description": "ID of the request",
"type": "string"
},
"requesterId": {
"description": "ID of the requester",
"type": "string"
},
"requesterName": {
"description": "Name of the requester",
"type": "string"
},
"count": {
"description": "No of times the request is printed",
"type": "integer"
},
"printEventDate": {
"description": "Date and time when the print command is executed",
"type": "string",
"format": "date-time"
}
}
}
23 changes: 23 additions & 0 deletions ramls/print-events-status-responses.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Collection of print events details",
"type": "object",
"properties": {
"printEventsStatusResponses": {
"description": "List of print events details",
"id": "printEvents",
"type": "array",
"items": {
"type": "object",
"$ref": "print-events-status-response.json"
}
},
"totalRecords": {
"type": "integer"
}
},
"required": [
"printEventsStatusResponses",
"totalRecords"
]
}
25 changes: 25 additions & 0 deletions ramls/print-events-storage.raml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ documentation:

types:
print-events-request: !include print-events-request.json
print-events-status-request: !include print-events-status-request.json
print-events-status-responses: !include print-events-status-responses.json
errors: !include raml-util/schemas/errors.schema

traits:
Expand Down Expand Up @@ -46,3 +48,26 @@ traits:
body:
text/plain:
example: "Internal server error"
/print-events-status:
post:
is: [validate]
description: Fetch batch of print event details
body:
application/json:
type: print-events-status-request
responses:
200:
description: "Requests print event details are successfully retreived"
body:
application/json:
type: print-events-status-responses
422:
description: "Unprocessable entity"
body:
application/json:
type: errors
500:
description: "Internal server error"
body:
text/plain:
example: "Internal server error"
9 changes: 9 additions & 0 deletions src/main/java/org/folio/rest/impl/PrintEventsApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io.vertx.core.Context;
import io.vertx.core.Handler;
import org.folio.rest.jaxrs.model.PrintEventsRequest;
import org.folio.rest.jaxrs.model.PrintEventsStatusRequest;
import org.folio.rest.jaxrs.resource.PrintEventsStorage;
import org.folio.service.PrintEventsService;
import org.slf4j.Logger;
Expand All @@ -25,4 +26,12 @@ public void postPrintEventsStoragePrintEventsEntry(PrintEventsRequest printEvent
.onSuccess(response -> asyncResultHandler.handle(succeededFuture(response)))
.onFailure(throwable -> asyncResultHandler.handle(succeededFuture(PostPrintEventsStoragePrintEventsEntryResponse.respond500WithTextPlain(throwable.getMessage()))));
}

@Override
public void postPrintEventsStoragePrintEventsStatus(PrintEventsStatusRequest entity, Map<String, String> okapiHeaders, Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {
LOG.info("postPrintEventsStoragePrintEventsStatus:: Fetching print event details for requestIds {}",
entity.getRequestIds());
new PrintEventsService(vertxContext, okapiHeaders)
.getPrintEventRequestDetails(entity.getRequestIds(), asyncResultHandler);
}
}
81 changes: 81 additions & 0 deletions src/main/java/org/folio/service/PrintEventsService.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
package org.folio.service;

import io.vertx.core.AsyncResult;
import io.vertx.core.Context;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.sqlclient.Row;
import io.vertx.sqlclient.RowSet;
import org.folio.rest.RestVerticle;
import org.folio.rest.jaxrs.model.PrintEventsRequest;
import org.folio.rest.jaxrs.model.PrintEventsStatusResponse;
import org.folio.rest.jaxrs.model.PrintEventsStatusResponses;
import org.folio.rest.jaxrs.resource.PrintEventsStorage;
import org.folio.rest.model.PrintEvent;
import org.folio.rest.persist.PgUtil;
import org.folio.rest.persist.PostgresClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ws.rs.core.Response;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static io.vertx.core.Future.succeededFuture;
import static org.folio.rest.persist.PgUtil.postgresClient;
import static org.folio.rest.persist.PostgresClient.convertToPsqlStandard;
import static org.folio.support.ModuleConstants.PRINT_EVENTS_TABLE;

public class PrintEventsService {
Expand All @@ -22,6 +37,23 @@ public class PrintEventsService {
private final Context vertxContext;
private final Map<String, String> okapiHeaders;

private static final String PRINT_EVENT_FETCH_QUERY = """
WITH cte AS (
SELECT id, jsonb->>'requestId' AS request_id, jsonb->>'printEventDate' AS last_updated_date,
jsonb->>'requesterName' AS requester_name, jsonb->>'requesterId' AS requester_id,
COUNT(*) OVER (PARTITION BY jsonb->>'requestId') AS request_count,
ROW_NUMBER() OVER (PARTITION BY jsonb->>'requestId'
ORDER BY (jsonb->>'printEventDate')::timestamptz DESC) AS rank
FROM %s.%s
where jsonb->>'requestId' in (%s)
)
SELECT request_id, requester_name, requester_id, request_count, (last_updated_date)::timestamptz
FROM cte
WHERE
rank = 1;
""";



public PrintEventsService(Context vertxContext, Map<String, String> okapiHeaders) {
this.vertxContext = vertxContext;
Expand All @@ -41,4 +73,53 @@ public Future<Response> create(PrintEventsRequest printEventRequest) {
return PgUtil.postSync(PRINT_EVENTS_TABLE, printEvents, MAX_ENTITIES, false, okapiHeaders, vertxContext,
PrintEventsStorage.PostPrintEventsStoragePrintEventsEntryResponse.class);
}

public void getPrintEventRequestDetails(List<String> requestIds, Handler<AsyncResult<Response>> asyncResultHandler) {
LOG.debug("getPrintEventRequestDetails:: Fetching print event details for requestIds {}", requestIds);
String tenantId = okapiHeaders.get(RestVerticle.OKAPI_HEADER_TENANT);
PostgresClient postgresClient = postgresClient(vertxContext, okapiHeaders);
postgresClient.execute(formatQuery(tenantId, requestIds), handler -> {
try {
if (handler.succeeded()) {
asyncResultHandler.handle(
succeededFuture(PrintEventsStorage.PostPrintEventsStoragePrintEventsStatusResponse
.respond200WithApplicationJson(mapRowSetToResponse(handler.result()))));
} else {
LOG.warn("getPrintEventRequestDetails:: Error while executing query", handler.cause());
asyncResultHandler.handle(succeededFuture(PrintEventsStorage.PostPrintEventsStoragePrintEventsStatusResponse
.respond500WithTextPlain(handler.cause())));
}
} catch (Exception ex) {
LOG.warn("getPrintEventRequestDetails:: Error while fetching print details", ex);
asyncResultHandler.handle(succeededFuture(PrintEventsStorage.PostPrintEventsStoragePrintEventsEntryResponse
.respond500WithTextPlain(ex.getMessage())));
}
});
}

private String formatQuery(String tenantId, List<String> requestIds) {
String formattedRequestIds = requestIds
.stream()
.map(requestId -> "'" + requestId + "'")
.collect(Collectors.joining(", "));
return String.format(PRINT_EVENT_FETCH_QUERY, convertToPsqlStandard(tenantId), PRINT_EVENTS_TABLE, formattedRequestIds);
}

private PrintEventsStatusResponses mapRowSetToResponse(RowSet<Row> rowSet) {
PrintEventsStatusResponses printEventsStatusResponses = new PrintEventsStatusResponses();
List<PrintEventsStatusResponse> responseList = new ArrayList<>();
rowSet.forEach(row -> {
var response = new PrintEventsStatusResponse();
response.setRequestId(row.getString("request_id"));
response.setRequesterName(row.getString("requester_name"));
response.setRequesterId(row.getString("requester_id"));
response.setCount(row.getInteger("request_count"));
response.setPrintEventDate(Date.from(row.getLocalDateTime("last_updated_date")
.atZone(ZoneOffset.UTC).toInstant()));
responseList.add(response);
});
printEventsStatusResponses.setPrintEventsStatusResponses(responseList);
printEventsStatusResponses.setTotalRecords(rowSet.size());
return printEventsStatusResponses;
}
}
12 changes: 11 additions & 1 deletion src/main/resources/templates/db_scripts/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,17 @@
{
"tableName": "print_events",
"withMetadata": true,
"withAuditing": false
"withAuditing": false,
"index": [
{
"fieldName": "requestId",
"tOps": "ADD",
"caseSensitive": true,
"removeAccents": false,
"sqlExpression": "(jsonb->>'requestId')",
"sqlExpressionQuery": "$"
}
]
}
],
"scripts": [
Expand Down
Loading

0 comments on commit 117f2c3

Please sign in to comment.