Skip to content

Commit

Permalink
Merge branch 'master' of github.com:folio-org/mod-circulation into CI…
Browse files Browse the repository at this point in the history
…RC-1809-fix

� Conflicts:
�	src/main/java/org/folio/circulation/rules/Drools.java
  • Loading branch information
roman-barannyk committed Sep 20, 2023
2 parents 474496e + 194a208 commit dffb7a8
Show file tree
Hide file tree
Showing 14 changed files with 446 additions and 152 deletions.
2 changes: 1 addition & 1 deletion descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@
},
{
"id": "allowed-service-points",
"version": "0.1",
"version": "1.0",
"handlers": [
{
"methods": [
Expand Down
17 changes: 13 additions & 4 deletions ramls/circulation.raml
Original file line number Diff line number Diff line change
Expand Up @@ -322,15 +322,24 @@ resourceTypes:
minProperties: 2
maxProperties: 2
properties:
requester:
operation:
description: "Operation (create, replace or move)"
type: string
enum: [create, replace, move]
required: false
requestId:
description: "Request ID"
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}$"
required: false
requesterId:
description: "Requester ID"
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}$"
required: true
item:
required: false
itemId:
description: "Item ID"
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}$"
required: false
instance:
instanceId:
description: "Instance ID"
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}$"
required: false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package org.folio.circulation.domain;

import java.lang.invoke.MethodHandles;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;
Expand All @@ -8,7 +13,32 @@
@Getter
@ToString
public class AllowedServicePointsRequest {
private static final Logger log = LogManager.getLogger(MethodHandles.lookup().lookupClass());

private Request.Operation operation;
private String requesterId;
private String instanceId;
private String itemId;
private String requestId;

public void updateWithRequestInformation(Request request) {
log.debug("updateWithRequestInformation:: parameters request: {}", request);

if (request != null) {
log.info("updateWithRequestInformation:: request in not null");
this.requesterId = request.getRequesterId();

if (request.isItemLevel()) {
this.itemId = request.getItemId();
}

if (request.isTitleLevel()) {
this.instanceId = request.getInstanceId();
}
}
}

public boolean isImplyingItemStatusIgnore() {
return operation == Request.Operation.REPLACE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ public RequestRepository(org.folio.circulation.support.Clients clients,
loanRepository, servicePointRepository, patronGroupRepository, new InstanceRepository(clients));
}

/**
* Simplified constructor for fetching request records only, ignoring related records
*/
public RequestRepository(org.folio.circulation.support.Clients clients) {
this(clients, null, null, null, null, null);
}

private RequestRepository(Clients clients, ItemRepository itemRepository,
UserRepository userRepository, LoanRepository loanRepository,
ServicePointRepository servicePointRepository,
Expand Down Expand Up @@ -173,7 +180,10 @@ private CompletableFuture<Result<Boolean>> exists(String id) {
public CompletableFuture<Result<Request>> getById(String id) {
return fetchRequest(id)
.thenCompose(r -> r.after(this::fetchRelatedRecords));
}

public CompletableFuture<Result<Request>> getByIdIgnoringRelatedRecords(String id) {
return fetchRequest(id);
}

public CompletableFuture<Result<Request>> fetchRelatedRecords(Request request) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.apache.logging.log4j.Logger;
import org.folio.circulation.domain.AllowedServicePoint;
import org.folio.circulation.domain.AllowedServicePointsRequest;
import org.folio.circulation.domain.Request;
import org.folio.circulation.domain.RequestType;
import org.folio.circulation.services.AllowedServicePointsService;
import org.folio.circulation.support.BadRequestFailure;
Expand Down Expand Up @@ -60,32 +61,35 @@ private void get(RoutingContext routingContext) {

private static Result<AllowedServicePointsRequest> buildRequest(RoutingContext routingContext) {
MultiMap queryParams = routingContext.queryParams();
AllowedServicePointsRequest request = new AllowedServicePointsRequest(
queryParams.get("requester"),
queryParams.get("instance"),
queryParams.get("item"));

return validateRequest(request);
Request.Operation operation = queryParams.get("operation") == null ? null
: Request.Operation.valueOf(queryParams.get("operation").toUpperCase());

AllowedServicePointsRequest request = new AllowedServicePointsRequest(operation,
queryParams.get("requesterId"), queryParams.get("instanceId"), queryParams.get("itemId"),
queryParams.get("requestId"));

return validateAllowedServicePointsRequest(request);
}

private static Result<AllowedServicePointsRequest> validateRequest(
AllowedServicePointsRequest request) {
private static Result<AllowedServicePointsRequest> validateAllowedServicePointsRequest(
AllowedServicePointsRequest allowedServicePointsRequest) {

log.debug("validateAllowedServicePointsRequest:: parameters allowedServicePointsRequest: {}",
allowedServicePointsRequest);

log.debug("validateRequest:: parameters: request={}", request);
Request.Operation operation = allowedServicePointsRequest.getOperation();
String requesterId = allowedServicePointsRequest.getRequesterId();
String instanceId = allowedServicePointsRequest.getInstanceId();
String itemId = allowedServicePointsRequest.getItemId();
String requestId = allowedServicePointsRequest.getRequestId();

List<String> errors = new ArrayList<>();
String requesterId = request.getRequesterId();
String instanceId = request.getInstanceId();
String itemId = request.getItemId();

if (requesterId == null) {
errors.add("Request query parameters must contain 'requester'.");
} else if (!isUuid(requesterId)) {
errors.add(String.format("Requester ID is not a valid UUID: %s.", requesterId));
}
// Checking UUID validity

if (instanceId == null ^ itemId != null) {
errors.add("Request query parameters must contain either 'instance' or 'item'.");
if (requesterId != null && !isUuid(requesterId)) {
errors.add(String.format("Requester ID is not a valid UUID: %s.", requesterId));
}

if (instanceId != null && !isUuid(instanceId)) {
Expand All @@ -96,13 +100,54 @@ private static Result<AllowedServicePointsRequest> validateRequest(
errors.add(String.format("Item ID is not a valid UUID: %s.", itemId));
}

if (requestId != null && !isUuid(requestId)) {
errors.add(String.format("Request ID is not a valid UUID: %s.", requestId));
}

// Checking parameter combinations

boolean allowedCombinationOfParametersDetected = false;

if (operation == Request.Operation.CREATE && requesterId != null && instanceId != null &&
itemId == null && requestId == null) {

log.info("validateAllowedServicePointsRequest:: TLR request creation case");
allowedCombinationOfParametersDetected = true;
}

if (operation == Request.Operation.CREATE && requesterId != null && instanceId == null &&
itemId != null && requestId == null) {

log.info("validateAllowedServicePointsRequest:: ILR request creation case");
allowedCombinationOfParametersDetected = true;
}

if (operation == Request.Operation.REPLACE && requesterId == null && instanceId == null &&
itemId == null && requestId != null) {

log.info("validateAllowedServicePointsRequest:: request replacement case");
allowedCombinationOfParametersDetected = true;
}

if (operation == Request.Operation.MOVE && requesterId == null && instanceId == null &&
itemId == null && requestId != null) {

log.info("validateAllowedServicePointsRequest:: request movement case");
allowedCombinationOfParametersDetected = true;
}

if (!allowedCombinationOfParametersDetected) {
String errorMessage = "Invalid combination of query parameters";
errors.add(errorMessage);
}

if (!errors.isEmpty()) {
String errorMessage = String.join(" ", errors);
log.error("validateRequest:: allowed service points request failed: {}", errorMessage);
return failed(new BadRequestFailure(errorMessage));
}

return succeeded(request);
return succeeded(allowedServicePointsRequest);
}

private static JsonObject toJson(Map<RequestType, Set<AllowedServicePoint>> allowedServicePoints) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class AppliedRuleConditions {
boolean isPatronGroupPresent;

public AppliedRuleConditions(boolean isItemTypePresent,
boolean isLoanTypePresent, boolean isPatronGroupPresent) {
boolean isLoanTypePresent, boolean isPatronGroupPresent) {

this.isItemTypePresent = isItemTypePresent;
this.isLoanTypePresent = isLoanTypePresent;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public class CirculationRuleMatch {
private final AppliedRuleConditions appliedRuleConditions;

public CirculationRuleMatch(String policyId,
AppliedRuleConditions appliedRuleConditions) {
AppliedRuleConditions appliedRuleConditions) {

this.policyId = policyId;
this.appliedRuleConditions = appliedRuleConditions;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,54 +38,74 @@ public CirculationRulesProcessor(String tenantId, CollectionResourceClient circu
public CompletableFuture<Result<CirculationRuleMatch>> getLoanPolicyAndMatch(
RulesExecutionParameters params) {

log.debug("getLoanPolicyAndMatch:: parameters params: {}", params);

return executeRules(params, ExecutableRules::determineLoanPolicy);
}

public CompletableFuture<Result<JsonArray>> getLoanPolicies(RulesExecutionParameters params) {
log.debug("getLoanPolicies:: parameters params: {}", params);

return triggerRules(params,
(drools, newParams) -> drools.loanPolicies(newParams.toMap(), newParams.getLocation()));
}

public CompletableFuture<Result<CirculationRuleMatch>> getLostItemPolicyAndMatch(
RulesExecutionParameters params) {

log.debug("getLostItemPolicyAndMatch:: parameters params: {}", params);

return executeRules(params, ExecutableRules::determineLostItemPolicy);
}

public CompletableFuture<Result<JsonArray>> getLostItemPolicies(RulesExecutionParameters params) {
log.debug("getLostItemPolicies:: parameters params: {}", params);

return triggerRules(params,
(drools, newParams) -> drools.lostItemPolicies(newParams.toMap(), newParams.getLocation()));
}

public CompletableFuture<Result<CirculationRuleMatch>> getNoticePolicyAndMatch(
RulesExecutionParameters params) {

log.debug("getNoticePolicyAndMatch:: parameters params: {}", params);

return executeRules(params, ExecutableRules::determineNoticePolicy);
}

public CompletableFuture<Result<JsonArray>> getNoticePolicies(RulesExecutionParameters params) {
log.debug("getNoticePolicies:: parameters params: {}", params);

return triggerRules(params,
(drools, newParams) -> drools.noticePolicies(newParams.toMap(), newParams.getLocation()));
}

public CompletableFuture<Result<CirculationRuleMatch>> getOverduePolicyAndMatch(
RulesExecutionParameters params) {

log.debug("getOverduePolicyAndMatch:: parameters params: {}", params);

return executeRules(params, ExecutableRules::determineOverduePolicy);
}

public CompletableFuture<Result<JsonArray>> getOverduePolicies(RulesExecutionParameters params) {
log.debug("getOverduePolicies:: parameters params: {}", params);

return triggerRules(params,
(drools, newParams) -> drools.overduePolicies(newParams.toMap(), newParams.getLocation()));
}

public CompletableFuture<Result<CirculationRuleMatch>> getRequestPolicyAndMatch(
RulesExecutionParameters params) {

log.debug("getRequestPolicyAndMatch:: parameters params: {}", params);

return executeRules(params, ExecutableRules::determineRequestPolicy);
}

public CompletableFuture<Result<JsonArray>> getRequestPolicies(RulesExecutionParameters params) {
log.debug("getRequestPolicies:: parameters params: {}", params);

return triggerRules(params,
(drools, newParams) -> drools.requestPolicies(newParams.toMap(), newParams.getLocation()));
}
Expand Down Expand Up @@ -114,8 +134,13 @@ private <T> CompletableFuture<Result<T>> executeRules(RulesExecutionParameters p
rulesExecutor.apply(rules, parametersWithLocation)));
}

private CompletableFuture<Result<RulesExecutionParameters>> fetchLocation(RulesExecutionParameters params) {
private CompletableFuture<Result<RulesExecutionParameters>> fetchLocation(
RulesExecutionParameters params) {

log.debug("fetchLocation:: parameters params: {}", params);

if (params.getLocation() != null) {
log.info("fetchLocation:: location is not null");
return ofAsync(() -> params);
}

Expand Down
Loading

0 comments on commit dffb7a8

Please sign in to comment.