Skip to content

Commit

Permalink
CIRC-2167 Search slips: address high memory consumption [Q] (#1533)
Browse files Browse the repository at this point in the history
* CIRC-2167 Address high memory consumption in mod-circulation for Quesnelia triggered by search-slips endpoint calls

* CIRC-2167 Address high memory consumption in mod-circulation for Quesnelia triggered by search-slips endpoint calls

* CIRC-2167 Address high memory consumption in mod-circulation for Quesnelia triggered by search-slips endpoint calls

* CIRC-2167 Address high memory consumption in mod-circulation for Quesnelia triggered by search-slips endpoint calls

* CIRC-2167 Address high memory consumption in mod-circulation for Quesnelia triggered by search-slips endpoint calls

* CIRC-2167 Address high memory consumption in mod-circulation for Quesnelia triggered by search-slips endpoint calls

* CIRC-2167 Address high memory consumption in mod-circulation for Quesnelia triggered by search-slips endpoint calls

* CIRC-2167 Address high memory consumption in mod-circulation for Quesnelia triggered by search-slips endpoint calls

* CIRC-2167 Address high memory consumption in mod-circulation for Quesnelia triggered by search-slips endpoint calls

* CIRC-2167 Address high memory consumption in mod-circulation for Quesnelia triggered by search-slips endpoint calls

* CIRC-2167 Address high memory consumption in mod-circulation for Quesnelia triggered by search-slips endpoint calls

* CIRC-2167 Address high memory consumption in mod-circulation for Quesnelia triggered by search-slips endpoint calls

* CIRC-2167 Address high memory consumption in mod-circulation for Quesnelia triggered by search-slips endpoint calls

* CIRC-2167 Address high memory consumption in mod-circulation for Quesnelia triggered by search-slips endpoint calls

* CIRC-2167 Address high memory consumption in mod-circulation for Quesnelia triggered by search-slips endpoint calls

* CIRC-2167 Address high memory consumption in mod-circulation for Quesnelia triggered by search-slips endpoint calls

* CIRC-2167 Address high memory consumption in mod-circulation for Quesnelia triggered by search-slips endpoint calls

(cherry picked from commit e227033)
MagzhanArtykov authored and roman-barannyk committed Jan 18, 2025
1 parent 4858ade commit 66e1ae7
Showing 10 changed files with 139 additions and 1 deletion.
5 changes: 4 additions & 1 deletion descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
@@ -66,7 +66,10 @@
],
"pathPattern": "/circulation/search-slips/{servicePointId}",
"permissionsRequired": [
"circulation.search-slips.get"
"circulation.search-slips.get",
"mod-settings.entries.item.get",
"mod-settings.entries.collection.get",
"mod-settings.global.read.circulation"
],
"modulePermissions": [
"modperms.circulation.search-slips.get"
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.folio.circulation.domain.configuration;

import io.vertx.core.json.JsonObject;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;

import static org.folio.circulation.support.json.JsonPropertyFetcher.getBooleanProperty;

@AllArgsConstructor
@Getter
@ToString(onlyExplicitlyIncluded = true)
public class PrintHoldRequestsConfiguration {

@ToString.Include
private final boolean printHoldRequestsEnabled;

public static PrintHoldRequestsConfiguration from(JsonObject jsonObject) {
return new PrintHoldRequestsConfiguration(getBooleanProperty(jsonObject,
"printHoldRequestsEnabled"));
}
}
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@
import org.folio.circulation.domain.ConfigurationService;
import org.folio.circulation.domain.MultipleRecords;
import org.folio.circulation.domain.anonymization.config.LoanAnonymizationConfiguration;
import org.folio.circulation.domain.configuration.PrintHoldRequestsConfiguration;
import org.folio.circulation.domain.configuration.TlrSettingsConfiguration;
import org.folio.circulation.support.Clients;
import org.folio.circulation.support.GetManyRecordsClient;
@@ -59,6 +60,13 @@ public CompletableFuture<Result<TlrSettingsConfiguration>> lookupTlrSettings() {
return findAndMapFirstConfiguration(queryResult, TlrSettingsConfiguration::from);
}

public CompletableFuture<Result<PrintHoldRequestsConfiguration>> lookupPrintHoldRequestsEnabled() {
log.info("lookupPrintHoldRequestsEnabled:: fetching PrintHoldRequest configuration");

return findAndMapFirstConfiguration(defineModuleNameAndConfigNameFilter(
"SETTINGS", "PRINT_HOLD_REQUESTS"), PrintHoldRequestsConfiguration::from);
}

/**
* Gets loan history tenant configuration - settings for loan anonymization
*
24 changes: 24 additions & 0 deletions src/main/java/org/folio/circulation/resources/SlipsResource.java
Original file line number Diff line number Diff line change
@@ -41,7 +41,9 @@
import org.folio.circulation.domain.RequestStatus;
import org.folio.circulation.domain.RequestType;
import org.folio.circulation.domain.ServicePoint;
import org.folio.circulation.domain.configuration.PrintHoldRequestsConfiguration;
import org.folio.circulation.domain.notice.TemplateContextUtil;
import org.folio.circulation.infrastructure.storage.ConfigurationRepository;
import org.folio.circulation.infrastructure.storage.ServicePointRepository;
import org.folio.circulation.infrastructure.storage.inventory.HoldingsRepository;
import org.folio.circulation.infrastructure.storage.inventory.InstanceRepository;
@@ -63,6 +65,7 @@

import io.vertx.core.http.HttpClient;
import io.vertx.core.json.JsonObject;
import io.vertx.core.json.JsonArray;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;

@@ -77,6 +80,7 @@ public abstract class SlipsResource extends Resource {
private static final String REQUEST_TYPE_KEY = "requestType";
private static final String REQUEST_LEVEL_KEY = "requestLevel";
private static final String TOTAL_RECORDS_KEY = "totalRecords";
private static final String SEARCH_SLIPS_KEY = "searchSlips";
private static final String SERVICE_POINT_ID_PARAM = "servicePointId";
private static final String EFFECTIVE_LOCATION_ID_KEY = "effectiveLocationId";
private static final String PRIMARY_SERVICE_POINT_KEY = "primaryServicePoint";
@@ -118,9 +122,15 @@ private void getMany(RoutingContext routingContext) {
final var servicePointRepository = new ServicePointRepository(clients);
final var patronGroupRepository = new PatronGroupRepository(clients);
final var departmentRepository = new DepartmentRepository(clients);
final var configurationRepository = new ConfigurationRepository(clients);
final UUID servicePointId = UUID.fromString(
routingContext.request().getParam(SERVICE_POINT_ID_PARAM));

if (SEARCH_SLIPS_KEY.equals(collectionName) && requestType == RequestType.HOLD) {
configurationRepository.lookupPrintHoldRequestsEnabled()
.thenAccept(r -> r.next(config -> returnNoRecordsIfSearchSlipsDisabled(config, context)));
}

fetchLocationsForServicePoint(servicePointId, clients)
.thenComposeAsync(r -> r.after(ctx -> fetchItemsForLocations(ctx,
itemRepository, LocationRepository.using(clients, servicePointRepository))))
@@ -138,6 +148,20 @@ private void getMany(RoutingContext routingContext) {
.thenAccept(context::writeResultToHttpResponse);
}

private Result<Object> returnNoRecordsIfSearchSlipsDisabled(PrintHoldRequestsConfiguration config,
WebContext context) {

if (config == null || !config.isPrintHoldRequestsEnabled()) {
log.info("returnNoRecordsIfSearchSlipsDisabled:: Print hold requests configuration is disabled");
context.writeResultToHttpResponse(succeeded(JsonHttpResponse.ok(
new io.vertx.core.json.JsonObject()
.put(SEARCH_SLIPS_KEY, new JsonArray())
.put(TOTAL_RECORDS_KEY, 0)
)));
}
return succeeded(null);
}

private CompletableFuture<Result<StaffSlipsContext>> fetchTitleLevelRequests(
StaffSlipsContext staffSlipsContext, Clients clients) {

9 changes: 9 additions & 0 deletions src/test/java/api/requests/SearchSlipsTests.java
Original file line number Diff line number Diff line change
@@ -19,6 +19,15 @@ class SearchSlipsTests extends APITests {

@Test
void responseShouldHaveEmptyListOfSearchSlipsRecords() {
configurationsFixture.configurePrintHoldRequests(true);
Response response = ResourceClient.forSearchSlips().getById(UUID.randomUUID());
assertThat(response.getStatusCode(), is(HTTP_OK));
assertResponseHasItems(response, 0);
}

@Test
void responseShouldHaveNoSearchSlipsRecords() {
configurationsFixture.configurePrintHoldRequests(false);
Response response = ResourceClient.forSearchSlips().getById(UUID.randomUUID());
assertThat(response.getStatusCode(), is(HTTP_OK));
assertResponseHasItems(response, 0);
13 changes: 13 additions & 0 deletions src/test/java/api/requests/StaffSlipsTests.java
Original file line number Diff line number Diff line change
@@ -71,6 +71,7 @@ class StaffSlipsTests extends APITests {
@ParameterizedTest
@EnumSource(value = SlipsType.class)
void responseContainsNoSlipsForNonExistentServicePointId(SlipsType slipsType) {
configurationsFixture.configurePrintHoldRequests(true);
UUID servicePointId = servicePointsFixture.cd1().getId();
ItemResource item = itemsFixture.basedUponSmallAngryPlanet();

@@ -89,6 +90,7 @@ void responseContainsNoSlipsForNonExistentServicePointId(SlipsType slipsType) {
@ParameterizedTest
@EnumSource(value = SlipsType.class)
void responseContainsNoSlipsForWrongServicePointId(SlipsType slipsType) {
configurationsFixture.configurePrintHoldRequests(true);
UUID servicePointId = servicePointsFixture.cd1().getId();
ItemResource item = itemsFixture.basedUponSmallAngryPlanet();

@@ -109,6 +111,7 @@ void responseContainsNoSlipsForWrongServicePointId(SlipsType slipsType) {
@ParameterizedTest
@EnumSource(value = SlipsType.class)
void responseContainsNoSlipsWhenThereAreNoItems(SlipsType slipsType) {
configurationsFixture.configurePrintHoldRequests(true);
UUID servicePointId = servicePointsFixture.cd1().getId();
Response response = slipsType.get(servicePointId);

@@ -119,6 +122,7 @@ void responseContainsNoSlipsWhenThereAreNoItems(SlipsType slipsType) {
@ParameterizedTest
@EnumSource(value = SlipsType.class)
void responseContainsNoPickSlipsWhenItemHasOpenRequestWithWrongStatus(SlipsType slipsType) {
configurationsFixture.configurePrintHoldRequests(true);
UUID servicePointId = servicePointsFixture.cd1().getId();
ItemResource item = itemsFixture.basedUponSmallAngryPlanet();

@@ -142,6 +146,7 @@ void responseContainsNoPickSlipsWhenItemHasOpenRequestWithWrongStatus(SlipsType
@ParameterizedTest
@MethodSource(value = "getAllowedStatusesForHoldRequest")
void responseContainsSearchSlipsForItemWithAllowedStatus(ItemStatus itemStatus) {
configurationsFixture.configurePrintHoldRequests(true);
UUID servicePointId = servicePointsFixture.cd1().getId();
ItemResource item = itemsFixture.basedUponNod(b -> b.withStatus(itemStatus.getValue()));

@@ -182,6 +187,7 @@ private static Collection<ItemStatus> getAllowedStatusesForHoldRequest() {
})
void responseContainsSlipWithAllAvailableTokens(String countryCode, String primaryAddress,
String slipsTypeName) {
configurationsFixture.configurePrintHoldRequests(true);
SlipsType slipsType = SlipsType.valueOf(slipsTypeName);
IndividualResource servicePoint = servicePointsFixture.cd1();
UUID servicePointId = servicePoint.getId();
@@ -324,6 +330,7 @@ void responseContainsSlipWithAllAvailableTokens(String countryCode, String prima

@Test
void responseContainsPickSlipsForRequestsOfTypePageOnly() {
configurationsFixture.configurePrintHoldRequests(true);
UUID servicePointId = servicePointsFixture.cd1().getId();
val item = itemsFixture.basedUponSmallAngryPlanet();
val james = usersFixture.james();
@@ -354,6 +361,7 @@ void responseContainsPickSlipsForRequestsOfTypePageOnly() {

@Test
void responseContainsSearchSlipsForRequestsOfTypeHoldOnly() {
configurationsFixture.configurePrintHoldRequests(true);
UUID servicePointId = servicePointsFixture.cd1().getId();
val item = itemsFixture.basedUponSmallAngryPlanet();
UserResource steve = usersFixture.steve();
@@ -385,6 +393,7 @@ void responseContainsSearchSlipsForRequestsOfTypeHoldOnly() {
@ParameterizedTest
@EnumSource(value = SlipsType.class)
void responseIncludesItemsFromDifferentLocationsForSameServicePoint(SlipsType slipsType) {
configurationsFixture.configurePrintHoldRequests(true);
UUID circDesk1 = servicePointsFixture.cd1().getId();

// Circ desk 1: Second floor
@@ -440,6 +449,7 @@ void responseIncludesItemsFromDifferentLocationsForSameServicePoint(SlipsType sl
@ParameterizedTest
@EnumSource(value = SlipsType.class)
void responseDoesNotIncludeSlipsFromDifferentServicePoint(SlipsType slipsType) {
configurationsFixture.configurePrintHoldRequests(true);
UUID circDesk1 = servicePointsFixture.cd1().getId();
UUID circDesk4 = servicePointsFixture.cd4().getId();

@@ -503,6 +513,7 @@ void responseDoesNotIncludeSlipsFromDifferentServicePoint(SlipsType slipsType) {
@ParameterizedTest
@EnumSource(value = SlipsType.class)
void responseContainsSlipsWhenServicePointHasManyLocations(SlipsType slipsType) {
configurationsFixture.configurePrintHoldRequests(true);
final UUID servicePointId = servicePointsFixture.cd1().getId();
final int numberOfLocations = 100;

@@ -546,6 +557,7 @@ void responseContainsSlipsWhenServicePointHasManyLocations(SlipsType slipsType)

@Test
void responseContainsSearchSlipsForTLR() {
configurationsFixture.configurePrintHoldRequests(true);
settingsFixture.enableTlrFeature();
var servicePointId = servicePointsFixture.cd1().getId();
var steve = usersFixture.steve();
@@ -574,6 +586,7 @@ void responseContainsSearchSlipsForTLR() {

@Test
void responseContainsSearchSlipsForQueueTLRs() {
configurationsFixture.configurePrintHoldRequests(true);
settingsFixture.enableTlrFeature();
var servicePointId = servicePointsFixture.cd1().getId();
var steve = usersFixture.steve();
2 changes: 2 additions & 0 deletions src/test/java/api/support/APITests.java
Original file line number Diff line number Diff line change
@@ -47,6 +47,7 @@
import api.support.fixtures.CirculationItemsFixture;
import api.support.fixtures.CirculationRulesFixture;
import api.support.fixtures.ClaimItemReturnedFixture;
import api.support.fixtures.ConfigurationsFixture;
import api.support.fixtures.DeclareLostFixtures;
import api.support.fixtures.DepartmentFixture;
import api.support.fixtures.EndPatronSessionClient;
@@ -303,6 +304,7 @@ public abstract class APITests {
protected final DepartmentFixture departmentFixture = new DepartmentFixture();
protected final CheckOutLockFixture checkOutLockFixture = new CheckOutLockFixture();
protected final SettingsFixture settingsFixture = new SettingsFixture();
protected final ConfigurationsFixture configurationsFixture = new ConfigurationsFixture(configClient);
protected final SearchInstanceFixture searchFixture = new SearchInstanceFixture();

protected APITests() {
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package api.support.builders;

import io.vertx.core.json.JsonObject;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.With;

@With
@AllArgsConstructor
@NoArgsConstructor(force = true)
public class PrintHoldRequestConfigurationBuilder extends JsonBuilder implements Builder {

private final boolean printHoldRequestsEnabled;

@Override
public JsonObject create() {
JsonObject request = new JsonObject();
request.put("printHoldRequestsEnabled", printHoldRequestsEnabled);
return request;
}
}
9 changes: 9 additions & 0 deletions src/test/java/api/support/fixtures/ConfigurationExample.java
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
import static org.folio.circulation.support.json.JsonPropertyWriter.write;

import api.support.builders.ConfigRecordBuilder;
import api.support.builders.PrintHoldRequestConfigurationBuilder;
import io.vertx.core.json.JsonObject;

public class ConfigurationExample {
@@ -37,6 +38,14 @@ public static ConfigRecordBuilder schedulerNoticesLimitConfiguration(String limi
DEFAULT_NOTIFICATION_SCHEDULER_CONFIG_NAME, limit);
}

public static ConfigRecordBuilder setPrintHoldRequestsEnabled(boolean enabled) {
return new ConfigRecordBuilder("SETTINGS", "PRINT_HOLD_REQUESTS",
new PrintHoldRequestConfigurationBuilder()
.withPrintHoldRequestsEnabled(enabled)
.create()
.encodePrettily());
}

private static JsonObject combinedTimeZoneConfig(String timezone) {
final JsonObject encodedValue = new JsonObject();
write(encodedValue, "locale", US_LOCALE);
27 changes: 27 additions & 0 deletions src/test/java/api/support/fixtures/ConfigurationsFixture.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package api.support.fixtures;

import api.support.http.ResourceClient;

import java.util.UUID;

public class ConfigurationsFixture {
private final ResourceClient client;
private UUID printHoldRequestConfigurationEntryId = null;

public ConfigurationsFixture(ResourceClient client) {
this.client = client;
}

public void configurePrintHoldRequests(boolean printHoldRequestsEnabled) {
deletePrintHoldRequestConfig();
printHoldRequestConfigurationEntryId = client.create(
ConfigurationExample.setPrintHoldRequestsEnabled(printHoldRequestsEnabled)).getId();
}

public void deletePrintHoldRequestConfig() {
if (printHoldRequestConfigurationEntryId != null) {
client.delete(printHoldRequestConfigurationEntryId);
printHoldRequestConfigurationEntryId = null;
}
}
}

0 comments on commit 66e1ae7

Please sign in to comment.