forked from folio-org/mod-circulation
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CIRC-2099 POST Api implementation (folio-org#1481)
* CIRC-2099 POST Api implementation of print event logs
- Loading branch information
1 parent
e7e2682
commit 4b4301b
Showing
12 changed files
with
402 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"requestIds": [ | ||
"059e54bb-53e5-4039-a2fb-b34358e88b0a", | ||
"e70dcbae-30c6-47ac-94f8-4ffefd44a935" | ||
], | ||
"requesterId": "d51470ea-5daa-480b-a4aa-09c8c6d9940e", | ||
"requesterName": "requester", | ||
"printEventDate": "2024-06-25T20:00:00+05:30" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
src/main/java/org/folio/circulation/domain/PrintEventRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package org.folio.circulation.domain; | ||
|
||
import io.vertx.core.json.JsonObject; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.ToString; | ||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
|
||
import java.lang.invoke.MethodHandles; | ||
import java.util.List; | ||
import java.util.Set; | ||
|
||
import static lombok.AccessLevel.PRIVATE; | ||
import static org.folio.circulation.support.json.JsonPropertyFetcher.getArrayProperty; | ||
import static org.folio.circulation.support.json.JsonPropertyFetcher.getProperty; | ||
|
||
@AllArgsConstructor(access = PRIVATE) | ||
@ToString(onlyExplicitlyIncluded = true) | ||
public class PrintEventRequest { | ||
private static final Logger log = LogManager.getLogger(MethodHandles.lookup().lookupClass()); | ||
public static final String REQUEST_IDS_FIELD = "requestIds"; | ||
public static final String REQUESTER_ID_FIELD = "requesterId"; | ||
public static final String REQUESTER_NAME_FIELD = "requesterName"; | ||
public static final String PRINT_DATE_FIELD = "printEventDate"; | ||
|
||
@ToString.Include | ||
@Getter | ||
private final JsonObject representation; | ||
|
||
@Getter | ||
private final List<String> requestIds; | ||
@Getter | ||
private final String requesterId; | ||
@Getter | ||
private final String requesterName; | ||
@Getter | ||
private final String printEventDate; | ||
|
||
public static PrintEventRequest from(JsonObject representation) { | ||
final var requestIds = getArrayProperty(representation, REQUEST_IDS_FIELD).stream() | ||
.map(String.class::cast) | ||
.toList(); | ||
final var requesterId = getProperty(representation, REQUESTER_ID_FIELD); | ||
final var requesterName = getProperty(representation, REQUESTER_NAME_FIELD); | ||
final var printEventDate = getProperty(representation, PRINT_DATE_FIELD); | ||
|
||
if (requestIds.isEmpty() || null == requesterId || null == requesterName || null == printEventDate || !containsOnlyKnownFields(representation)) { | ||
log.info("from:: Print Event Request JSON is invalid: {},{},{},{},{}", representation, requestIds, requesterName, requesterId, printEventDate); | ||
return null; | ||
} | ||
return new PrintEventRequest(representation, requestIds, requesterId, requesterName, printEventDate); | ||
} | ||
|
||
private static boolean containsOnlyKnownFields(JsonObject representation) { | ||
return Set.of(REQUEST_IDS_FIELD, REQUESTER_ID_FIELD, REQUESTER_NAME_FIELD, PRINT_DATE_FIELD) | ||
.containsAll(representation.fieldNames()); | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
src/main/java/org/folio/circulation/infrastructure/storage/PrintEventsRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package org.folio.circulation.infrastructure.storage; | ||
|
||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
import org.folio.circulation.domain.PrintEventRequest; | ||
import org.folio.circulation.support.Clients; | ||
import org.folio.circulation.support.CollectionResourceClient; | ||
import org.folio.circulation.support.http.client.ResponseInterpreter; | ||
import org.folio.circulation.support.results.Result; | ||
|
||
import java.lang.invoke.MethodHandles; | ||
import java.util.concurrent.CompletableFuture; | ||
|
||
import static org.folio.circulation.support.http.ResponseMapping.forwardOnFailure; | ||
import static org.folio.circulation.support.results.Result.succeeded; | ||
|
||
public class PrintEventsRepository { | ||
private static final Logger log = LogManager.getLogger(MethodHandles.lookup().lookupClass()); | ||
|
||
private final CollectionResourceClient printEventsStorageClient; | ||
|
||
public PrintEventsRepository(Clients clients) { | ||
printEventsStorageClient = clients.printEventsStorageClient(); | ||
} | ||
|
||
public CompletableFuture<Result<Void>> create(PrintEventRequest printEventRequest) { | ||
log.info("create:: parameters printEvent: {}", printEventRequest); | ||
final var storagePrintEventRequest = printEventRequest.getRepresentation(); | ||
final ResponseInterpreter<Void> interpreter = new ResponseInterpreter<Void>() | ||
.on(201, succeeded(null)) | ||
.otherwise(forwardOnFailure()); | ||
return printEventsStorageClient.post(storagePrintEventRequest).thenApply(interpreter::flatMap); | ||
} | ||
|
||
} |
111 changes: 111 additions & 0 deletions
111
src/main/java/org/folio/circulation/resources/PrintEventsResource.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package org.folio.circulation.resources; | ||
|
||
import io.vertx.core.http.HttpClient; | ||
import io.vertx.ext.web.Router; | ||
import io.vertx.ext.web.RoutingContext; | ||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
import org.folio.circulation.domain.CirculationSetting; | ||
import org.folio.circulation.domain.MultipleRecords; | ||
import org.folio.circulation.domain.PrintEventRequest; | ||
import org.folio.circulation.infrastructure.storage.CirculationSettingsRepository; | ||
import org.folio.circulation.infrastructure.storage.PrintEventsRepository; | ||
import org.folio.circulation.infrastructure.storage.requests.RequestRepository; | ||
import org.folio.circulation.support.Clients; | ||
import org.folio.circulation.support.RouteRegistration; | ||
import org.folio.circulation.support.http.server.JsonHttpResponse; | ||
import org.folio.circulation.support.http.server.WebContext; | ||
import org.folio.circulation.support.results.Result; | ||
|
||
import java.lang.invoke.MethodHandles; | ||
import java.util.Collection; | ||
import java.util.concurrent.CompletableFuture; | ||
import java.util.function.Function; | ||
|
||
import static org.folio.circulation.support.ValidationErrorFailure.singleValidationError; | ||
import static org.folio.circulation.support.json.JsonPropertyFetcher.getProperty; | ||
import static org.folio.circulation.support.results.Result.ofAsync; | ||
import static org.folio.circulation.support.results.Result.succeeded; | ||
|
||
public class PrintEventsResource extends Resource { | ||
private static final Logger log = LogManager.getLogger(MethodHandles.lookup().lookupClass()); | ||
private static final String PRINT_EVENT_FLAG_QUERY = "query=name=printEventLogFeature"; | ||
private static final String PRINT_EVENT_FEATURE_DISABLED_ERROR = "print event feature is disabled for this tenant"; | ||
private static final String NO_CONFIG_FOUND_ERROR = "No configuration found for print event feature"; | ||
private static final String MULTIPLE_CONFIGS_ERROR = "Multiple configurations found for print event feature"; | ||
private static final String PRINT_EVENT_FLAG_PROPERTY_NAME = "enablePrintLog"; | ||
|
||
public PrintEventsResource(HttpClient client) { | ||
super(client); | ||
} | ||
|
||
@Override | ||
public void register(Router router) { | ||
new RouteRegistration("/circulation/print-events-entry", router) | ||
.create(this::create); | ||
} | ||
|
||
void create(RoutingContext routingContext) { | ||
final var context = new WebContext(routingContext); | ||
final var clients = Clients.create(context, client); | ||
final var printEventsRepository = new PrintEventsRepository(clients); | ||
final var circulationSettingsRepository = new CirculationSettingsRepository(clients); | ||
final var requestRepository = new RequestRepository(clients); | ||
final var incomingRepresentation = routingContext.body().asJsonObject(); | ||
final var printEventRequest = PrintEventRequest.from(incomingRepresentation); | ||
|
||
log.info("create:: Creating print event: {}", printEventRequest); | ||
|
||
ofAsync(printEventRequest) | ||
.thenApply(refuseWhenPrintEventRequestIsInvalid()) | ||
.thenCompose(r -> r.after(validatePrintEventFeatureFlag(circulationSettingsRepository))) | ||
.thenCompose(r -> r.after(validateRequests(requestRepository))) | ||
.thenCompose(r -> r.after(printEventsRepository::create)) | ||
.thenApply(r -> r.map(response -> JsonHttpResponse.created(null, null))) | ||
.thenAccept(context::writeResultToHttpResponse); | ||
} | ||
|
||
private static Function<PrintEventRequest, CompletableFuture<Result<PrintEventRequest>>> | ||
validateRequests(RequestRepository requestRepository) { | ||
return printRequest -> requestRepository.fetchRequests(printRequest.getRequestIds()) | ||
.thenApply(printRequestList -> printRequestList.map(Collection::size)).thenApply(size -> { | ||
if (size.value() != printRequest.getRequestIds().size()) { | ||
return Result.failed(singleValidationError("invalid request found", "", "")); | ||
} | ||
return succeeded(printRequest); | ||
}); | ||
} | ||
|
||
private static Function<Result<PrintEventRequest>, Result<PrintEventRequest>> | ||
refuseWhenPrintEventRequestIsInvalid() { | ||
return r -> r.failWhen(printEventRequest -> succeeded(printEventRequest == null), | ||
circulationSetting -> singleValidationError("Print Event Request JSON is invalid", "", "")); | ||
} | ||
|
||
private static Function<PrintEventRequest, CompletableFuture<Result<PrintEventRequest>>> validatePrintEventFeatureFlag( | ||
CirculationSettingsRepository circulationSettingsRepository) { | ||
return printEventRequest -> circulationSettingsRepository.findBy(PRINT_EVENT_FLAG_QUERY) | ||
.thenApply(result -> | ||
handleCirculationSettingResult(result.map(MultipleRecords::getRecords), printEventRequest) | ||
); | ||
} | ||
|
||
private static Result<PrintEventRequest> handleCirculationSettingResult(Result<Collection<CirculationSetting>> result, | ||
PrintEventRequest printEventRequest) { | ||
|
||
int size = result.value().size(); | ||
if (size == 0) { | ||
return Result.failed(singleValidationError(NO_CONFIG_FOUND_ERROR, "", "")); | ||
} else if (size > 1) { | ||
return Result.failed(singleValidationError(MULTIPLE_CONFIGS_ERROR, "", "")); | ||
} | ||
boolean isEnabled = result.value().stream() | ||
.map(x -> Boolean.valueOf(getProperty(x.getValue(), PRINT_EVENT_FLAG_PROPERTY_NAME))).findFirst().orElse(true); | ||
|
||
if (!isEnabled) { | ||
return Result.failed(singleValidationError(PRINT_EVENT_FEATURE_DISABLED_ERROR, "", "")); | ||
} | ||
return succeeded(printEventRequest); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.