diff --git a/NEWS.md b/NEWS.md index 012eb24c4..4ba4ba6f5 100644 --- a/NEWS.md +++ b/NEWS.md @@ -7,6 +7,7 @@ * Remove null values from electronicAccess object before returning item and instance [MODINV-1006](https://folio-org.atlassian.net/browse/MODINV-1006) * 422 Unprocessable Content Error while updating Instances and Items with electronic access without URI field populated. [MODINV-1024](https://folio-org.atlassian.net/browse/MODINV-1024) * Error appears when edit via quickMARC MARC Instance shared from Member tenant [MODDATAIMP-1052](https://folio-org.atlassian.net/browse/MODDATAIMP-1052) +* Fix mod-inventory OOM issue [MODINV-1023](https://folio-org.atlassian.net/browse/MODINV-1023) ## 20.2.0 2023-03-20 * Inventory cannot process Holdings with virtual fields ([MODINV-941](https://issues.folio.org/browse/MODINV-941)) diff --git a/src/main/java/org/folio/inventory/DataImportConsumerVerticle.java b/src/main/java/org/folio/inventory/DataImportConsumerVerticle.java index ecb65db09..f98349069 100644 --- a/src/main/java/org/folio/inventory/DataImportConsumerVerticle.java +++ b/src/main/java/org/folio/inventory/DataImportConsumerVerticle.java @@ -119,12 +119,10 @@ public void start(Promise startPromise) { Storage storage = Storage.basedUpon(config, client); String profileSnapshotExpirationTime = getCacheEnvVariable(config, "inventory.profile-snapshot-cache.expiration.time.seconds"); - String mappingMetadataExpirationTime = getCacheEnvVariable(config, "inventory.mapping-metadata-cache.expiration.time.seconds"); ProfileSnapshotCache profileSnapshotCache = new ProfileSnapshotCache(vertx, client, Long.parseLong(profileSnapshotExpirationTime)); - MappingMetadataCache mappingMetadataCache = new MappingMetadataCache(vertx, client, Long.parseLong(mappingMetadataExpirationTime)); ConsortiumDataCache consortiumDataCache = new ConsortiumDataCache(vertx, client); - + MappingMetadataCache mappingMetadataCache = MappingMetadataCache.getInstance(vertx, client); DataImportKafkaHandler dataImportKafkaHandler = new DataImportKafkaHandler( vertx, storage, client, profileSnapshotCache, kafkaConfig, mappingMetadataCache, consortiumDataCache); diff --git a/src/main/java/org/folio/inventory/MarcBibUpdateConsumerVerticle.java b/src/main/java/org/folio/inventory/MarcBibUpdateConsumerVerticle.java index 44aa43ad3..7754f1036 100644 --- a/src/main/java/org/folio/inventory/MarcBibUpdateConsumerVerticle.java +++ b/src/main/java/org/folio/inventory/MarcBibUpdateConsumerVerticle.java @@ -40,8 +40,7 @@ public void start(Promise startPromise) { Storage storage = Storage.basedUpon(config, client); InstanceUpdateDelegate instanceUpdateDelegate = new InstanceUpdateDelegate(storage); - var mappingMetadataExpirationTime = getCacheEnvVariable(config, METADATA_EXPIRATION_TIME); - MappingMetadataCache mappingMetadataCache = new MappingMetadataCache(vertx, client, Long.parseLong(mappingMetadataExpirationTime)); + MappingMetadataCache mappingMetadataCache = MappingMetadataCache.getInstance(vertx, client); MarcBibUpdateKafkaHandler marcBibUpdateKafkaHandler = new MarcBibUpdateKafkaHandler(vertx, getMaxDistributionNumber(), kafkaConfig, instanceUpdateDelegate, mappingMetadataCache); @@ -95,14 +94,6 @@ private KafkaConfig getKafkaConfig(JsonObject config) { return kafkaConfig; } - private String getCacheEnvVariable(JsonObject config, String variableName) { - String cacheExpirationTime = config.getString(variableName); - if (StringUtils.isBlank(cacheExpirationTime)) { - cacheExpirationTime = "3600"; - } - return cacheExpirationTime; - } - public static String formatSubscriptionPattern(String env, String eventType) { return String.join("\\.", env, "\\w{1,}", eventType); } diff --git a/src/main/java/org/folio/inventory/MarcHridSetConsumerVerticle.java b/src/main/java/org/folio/inventory/MarcHridSetConsumerVerticle.java index 1bbaeea06..12af1cbac 100644 --- a/src/main/java/org/folio/inventory/MarcHridSetConsumerVerticle.java +++ b/src/main/java/org/folio/inventory/MarcHridSetConsumerVerticle.java @@ -63,8 +63,7 @@ public void start(Promise startPromise) { InstanceUpdateDelegate instanceUpdateDelegate = new InstanceUpdateDelegate(storage); HoldingsUpdateDelegate holdingsRecordUpdateDelegate = new HoldingsUpdateDelegate(storage, holdingsCollectionService); - String mappingMetadataExpirationTime = getCacheEnvVariable(config, "inventory.mapping-metadata-cache.expiration.time.seconds"); - MappingMetadataCache mappingMetadataCache = new MappingMetadataCache(vertx, client, Long.parseLong(mappingMetadataExpirationTime)); + MappingMetadataCache mappingMetadataCache = MappingMetadataCache.getInstance(vertx, client); MarcBibInstanceHridSetKafkaHandler marcBibInstanceHridSetKafkaHandler = new MarcBibInstanceHridSetKafkaHandler(instanceUpdateDelegate, mappingMetadataCache); MarcHoldingsRecordHridSetKafkaHandler marcHoldingsRecordHridSetKafkaHandler = new MarcHoldingsRecordHridSetKafkaHandler(holdingsRecordUpdateDelegate, mappingMetadataCache); @@ -101,12 +100,4 @@ private KafkaConsumerWrapper createConsumerByEvent(KafkaConfig k .subscriptionDefinition(subscriptionDefinition) .build(); } - - private String getCacheEnvVariable(JsonObject config, String variableName) { - String cacheExpirationTime = config.getString(variableName); - if (StringUtils.isBlank(cacheExpirationTime)) { - cacheExpirationTime = "3600"; - } - return cacheExpirationTime; - } } diff --git a/src/main/java/org/folio/inventory/dataimport/cache/MappingMetadataCache.java b/src/main/java/org/folio/inventory/dataimport/cache/MappingMetadataCache.java index fe910b31e..209386659 100644 --- a/src/main/java/org/folio/inventory/dataimport/cache/MappingMetadataCache.java +++ b/src/main/java/org/folio/inventory/dataimport/cache/MappingMetadataCache.java @@ -6,8 +6,10 @@ import java.util.concurrent.TimeUnit; import io.vertx.core.json.Json; +import io.vertx.core.json.JsonObject; import io.vertx.ext.web.client.WebClient; import lombok.SneakyThrows; +import org.apache.commons.lang.StringUtils; import org.apache.http.HttpStatus; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -29,9 +31,11 @@ public class MappingMetadataCache { private static final Logger LOGGER = LogManager.getLogger(); - + private static MappingMetadataCache instance = null; private final AsyncCache> cache; private final HttpClient httpClient; + private static final String METADATA_EXPIRATION_TIME = "inventory.mapping-metadata-cache.expiration.time.seconds"; + public MappingMetadataCache(Vertx vertx, HttpClient httpClient, long cacheExpirationTime) { this.httpClient = httpClient; @@ -107,4 +111,18 @@ private CompletableFuture> loadMappingMetadata(Stri }); } + public static synchronized MappingMetadataCache getInstance(Vertx vertx, HttpClient httpClient) { + if (instance == null) { + instance = new MappingMetadataCache(vertx, httpClient, Long.parseLong(getCacheEnvVariable(vertx.getOrCreateContext().config(), METADATA_EXPIRATION_TIME))); + } + return instance; + } + + private static String getCacheEnvVariable(JsonObject config, String variableName) { + String cacheExpirationTime = config.getString(variableName); + if (StringUtils.isBlank(cacheExpirationTime)) { + cacheExpirationTime = "3600"; + } + return cacheExpirationTime; + } } diff --git a/src/test/java/org/folio/inventory/dataimport/cache/MappingMetadataCacheTest.java b/src/test/java/org/folio/inventory/dataimport/cache/MappingMetadataCacheTest.java index 6ca70cd8b..dc7175889 100644 --- a/src/test/java/org/folio/inventory/dataimport/cache/MappingMetadataCacheTest.java +++ b/src/test/java/org/folio/inventory/dataimport/cache/MappingMetadataCacheTest.java @@ -5,6 +5,7 @@ import java.util.Optional; import java.util.UUID; +import io.vertx.core.json.JsonObject; import org.folio.inventory.common.Context; import org.folio.inventory.dataimport.handlers.matching.util.EventHandlingUtil; import org.folio.MappingMetadataDto; @@ -35,8 +36,9 @@ public class MappingMetadataCacheTest { private static final String MARC_BIB_RECORD_TYPE = "marc-bib"; private final Vertx vertx = Vertx.vertx(); - private final MappingMetadataCache mappingMetadataCache = new MappingMetadataCache(vertx, - vertx.createHttpClient(), 3600); + + private final MappingMetadataCache mappingMetadataCache = MappingMetadataCache.getInstance(vertx, + vertx.createHttpClient()); @Rule public WireMockRule mockServer = new WireMockRule( diff --git a/src/test/java/org/folio/inventory/dataimport/consumers/DataImportKafkaHandlerTest.java b/src/test/java/org/folio/inventory/dataimport/consumers/DataImportKafkaHandlerTest.java index 3529b870e..89c30d69c 100644 --- a/src/test/java/org/folio/inventory/dataimport/consumers/DataImportKafkaHandlerTest.java +++ b/src/test/java/org/folio/inventory/dataimport/consumers/DataImportKafkaHandlerTest.java @@ -153,7 +153,8 @@ public void setUp() { HttpClient client = vertx.createHttpClient(); dataImportKafkaHandler = new DataImportKafkaHandler(vertx, mockedStorage, client, new ProfileSnapshotCache(vertx, client, 3600), - kafkaConfig, new MappingMetadataCache(vertx, client, 3600), + kafkaConfig, + MappingMetadataCache.getInstance(vertx, client), new ConsortiumDataCache(vertx, client)); EventManager.clearEventHandlers(); diff --git a/src/test/java/org/folio/inventory/dataimport/consumers/MarcHoldingsRecordHridSetKafkaHandlerTest.java b/src/test/java/org/folio/inventory/dataimport/consumers/MarcHoldingsRecordHridSetKafkaHandlerTest.java index 5163b1d27..ef668148e 100644 --- a/src/test/java/org/folio/inventory/dataimport/consumers/MarcHoldingsRecordHridSetKafkaHandlerTest.java +++ b/src/test/java/org/folio/inventory/dataimport/consumers/MarcHoldingsRecordHridSetKafkaHandlerTest.java @@ -129,7 +129,7 @@ record = Json.decodeValue(TestUtil.readFileFromPath(RECORD_PATH), Record.class); .withMappingParams(Json.encode(mappingParameters)) .withMappingRules(mappingRules.encode()))))); - MappingMetadataCache mappingMetadataCache = new MappingMetadataCache(vertx, vertx.createHttpClient(), 3600); + MappingMetadataCache mappingMetadataCache = MappingMetadataCache.getInstance(vertx, vertx.createHttpClient()); marcHoldingsRecordHridSetKafkaHandler = new MarcHoldingsRecordHridSetKafkaHandler(new HoldingsUpdateDelegate(mockedStorage, holdingsCollectionService), mappingMetadataCache); diff --git a/src/test/java/org/folio/inventory/dataimport/handlers/actions/CreateAuthorityEventHandlerTest.java b/src/test/java/org/folio/inventory/dataimport/handlers/actions/CreateAuthorityEventHandlerTest.java index aa048a8b7..161df352e 100644 --- a/src/test/java/org/folio/inventory/dataimport/handlers/actions/CreateAuthorityEventHandlerTest.java +++ b/src/test/java/org/folio/inventory/dataimport/handlers/actions/CreateAuthorityEventHandlerTest.java @@ -144,7 +144,7 @@ public class CreateAuthorityEventHandlerTest { public void setUp() throws IOException { MockitoAnnotations.openMocks(this); MappingManager.clearReaderFactories(); - MappingMetadataCache mappingMetadataCache = new MappingMetadataCache(vertx, vertx.createHttpClient(), 3600); + MappingMetadataCache mappingMetadataCache = MappingMetadataCache.getInstance(vertx, vertx.createHttpClient()); createMarcAuthoritiesEventHandler = new CreateAuthorityEventHandler(storage, mappingMetadataCache, authorityIdStorageService); JsonObject mappingRules = new JsonObject(TestUtil.readFileFromPath(MAPPING_RULES_PATH)); diff --git a/src/test/java/org/folio/inventory/dataimport/handlers/actions/CreateInstanceEventHandlerTest.java b/src/test/java/org/folio/inventory/dataimport/handlers/actions/CreateInstanceEventHandlerTest.java index 32ea6894b..88b50d70b 100644 --- a/src/test/java/org/folio/inventory/dataimport/handlers/actions/CreateInstanceEventHandlerTest.java +++ b/src/test/java/org/folio/inventory/dataimport/handlers/actions/CreateInstanceEventHandlerTest.java @@ -229,8 +229,8 @@ public void setUp() throws IOException { Vertx vertx = Vertx.vertx(); HttpClient httpClient = vertx.createHttpClient(); createInstanceEventHandler = spy(new CreateInstanceEventHandler(storage, - new PrecedingSucceedingTitlesHelper(context -> mockedClient), new MappingMetadataCache(vertx, - httpClient, 3600), instanceIdStorageService, orderHelperService, httpClient)); + new PrecedingSucceedingTitlesHelper(context -> mockedClient), MappingMetadataCache.getInstance(vertx, + httpClient), instanceIdStorageService, orderHelperService, httpClient)); doReturn(sourceStorageClient).when(createInstanceEventHandler).getSourceStorageRecordsClient(any(), any()); doAnswer(invocationOnMock -> { diff --git a/src/test/java/org/folio/inventory/dataimport/handlers/actions/CreateMarcHoldingsEventHandlerTest.java b/src/test/java/org/folio/inventory/dataimport/handlers/actions/CreateMarcHoldingsEventHandlerTest.java index 479a987b1..ccd631933 100644 --- a/src/test/java/org/folio/inventory/dataimport/handlers/actions/CreateMarcHoldingsEventHandlerTest.java +++ b/src/test/java/org/folio/inventory/dataimport/handlers/actions/CreateMarcHoldingsEventHandlerTest.java @@ -155,7 +155,7 @@ public class CreateMarcHoldingsEventHandlerTest { public void setUp() throws IOException { MockitoAnnotations.openMocks(this); MappingManager.clearReaderFactories(); - MappingMetadataCache mappingMetadataCache = new MappingMetadataCache(vertx, vertx.createHttpClient(), 3600); + MappingMetadataCache mappingMetadataCache = MappingMetadataCache.getInstance(vertx, vertx.createHttpClient()); createMarcHoldingsEventHandler = new CreateMarcHoldingsEventHandler(storage, mappingMetadataCache, holdingsIdStorageService, holdingsCollectionService); mappingRules = new JsonObject(TestUtil.readFileFromPath(MAPPING_RULES_PATH)); instanceId = String.valueOf(UUID.randomUUID()); diff --git a/src/test/java/org/folio/inventory/dataimport/handlers/actions/ReplaceInstanceEventHandlerTest.java b/src/test/java/org/folio/inventory/dataimport/handlers/actions/ReplaceInstanceEventHandlerTest.java index 01eca0f72..d2d5abdaa 100644 --- a/src/test/java/org/folio/inventory/dataimport/handlers/actions/ReplaceInstanceEventHandlerTest.java +++ b/src/test/java/org/folio/inventory/dataimport/handlers/actions/ReplaceInstanceEventHandlerTest.java @@ -255,8 +255,8 @@ public void setUp() throws IOException { precedingSucceedingTitlesHelper = spy(new PrecedingSucceedingTitlesHelper(ctxt -> mockedClient)); Vertx vertx = Vertx.vertx(); - replaceInstanceEventHandler = spy(new ReplaceInstanceEventHandler(storage, precedingSucceedingTitlesHelper, new MappingMetadataCache(vertx, - vertx.createHttpClient(), 3600), vertx.createHttpClient(), consortiumServiceImpl)); + replaceInstanceEventHandler = spy(new ReplaceInstanceEventHandler(storage, precedingSucceedingTitlesHelper, MappingMetadataCache.getInstance(vertx, + vertx.createHttpClient()), vertx.createHttpClient(), consortiumServiceImpl)); var recordUUID = UUID.randomUUID().toString(); HttpResponse recordHttpResponse = buildHttpResponseWithBuffer(BufferImpl.buffer(String.format(EXISTING_SRS_CONTENT, recordUUID, recordUUID, 0)), HttpStatus.SC_OK); diff --git a/src/test/java/org/folio/inventory/dataimport/handlers/actions/UpdateAuthorityEventHandlerTest.java b/src/test/java/org/folio/inventory/dataimport/handlers/actions/UpdateAuthorityEventHandlerTest.java index ff73de23d..ab4fd325e 100644 --- a/src/test/java/org/folio/inventory/dataimport/handlers/actions/UpdateAuthorityEventHandlerTest.java +++ b/src/test/java/org/folio/inventory/dataimport/handlers/actions/UpdateAuthorityEventHandlerTest.java @@ -116,7 +116,7 @@ public class UpdateAuthorityEventHandlerTest { public void setUp() throws IOException { MockitoAnnotations.openMocks(this); MappingManager.clearReaderFactories(); - MappingMetadataCache mappingMetadataCache = new MappingMetadataCache(vertx, vertx.createHttpClient(), 3600); + MappingMetadataCache mappingMetadataCache = MappingMetadataCache.getInstance(vertx, vertx.createHttpClient()); eventHandler = new UpdateAuthorityEventHandler(storage, mappingMetadataCache, publisher); JsonObject mappingRules = new JsonObject(TestUtil.readFileFromPath(MAPPING_RULES_PATH)); diff --git a/src/test/java/org/folio/inventory/dataimport/handlers/actions/UpdateMarcHoldingsEventHandlerTest.java b/src/test/java/org/folio/inventory/dataimport/handlers/actions/UpdateMarcHoldingsEventHandlerTest.java index 08ef02840..e37c0c2f3 100644 --- a/src/test/java/org/folio/inventory/dataimport/handlers/actions/UpdateMarcHoldingsEventHandlerTest.java +++ b/src/test/java/org/folio/inventory/dataimport/handlers/actions/UpdateMarcHoldingsEventHandlerTest.java @@ -138,7 +138,7 @@ public class UpdateMarcHoldingsEventHandlerTest { public void setUp() throws IOException { MockitoAnnotations.openMocks(this); MappingManager.clearReaderFactories(); - MappingMetadataCache mappingMetadataCache = new MappingMetadataCache(vertx, vertx.createHttpClient(), 3600); + MappingMetadataCache mappingMetadataCache = MappingMetadataCache.getInstance(vertx, vertx.createHttpClient()); eventHandler = new UpdateMarcHoldingsEventHandler(storage, mappingMetadataCache, publisher); mappingRules = new JsonObject(TestUtil.readFileFromPath(MAPPING_RULES_PATH));