Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/master' into MODINV…
Browse files Browse the repository at this point in the history
…-943

# Conflicts:
#	NEWS.md
  • Loading branch information
dmytrokrutii committed Jun 5, 2024
2 parents b2478bf + c3699f8 commit c42d60d
Show file tree
Hide file tree
Showing 30 changed files with 944 additions and 67 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
* Replace GET with POST request for fetching instances and holdings on /items endpoint to omit 414 error [MODINV-943](https://folio-org.atlassian.net/browse/MODINV-943)

## 20.2.0 2023-03-20
Expand Down
45 changes: 44 additions & 1 deletion descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,37 @@
}
]
},
{
"id": "inventory-update-ownership",
"version": "1.0",
"handlers": [
{
"methods": ["POST"],
"pathPattern": "/inventory/items/update-ownership",
"permissionsRequired": ["inventory.items.update-ownership.item.post"],
"modulePermissions": [
"inventory-storage.items.item.post",
"inventory-storage.items.item.delete",
"inventory-storage.items.collection.get",
"inventory-storage.holdings.item.get"
]
},
{
"methods": ["POST"],
"pathPattern": "/inventory/holdings/update-ownership",
"permissionsRequired": ["inventory.holdings.update-ownership.item.post"],
"modulePermissions": [
"inventory-storage.holdings.item.post",
"inventory-storage.holdings.item.delete",
"inventory-storage.holdings.collection.get",
"inventory-storage.items.item.post",
"inventory-storage.items.item.delete",
"inventory-storage.items.collection.get",
"inventory-storage.instances.item.get"
]
}
]
},
{
"id": "_tenant",
"version": "1.2",
Expand Down Expand Up @@ -706,6 +737,11 @@
"displayName": "Inventory - mark an item as unknown",
"description": "Mark an item as unknown"
},
{
"permissionName": "inventory.items.update-ownership.item.post",
"displayName": "Inventory - update an item ownership",
"description": "Update an item ownership"
},

{
"permissionName": "inventory.holdings.move.item.post",
Expand Down Expand Up @@ -742,6 +778,11 @@
"displayName": "Inventory - modify holdings",
"description": "Modify individual instance"
},
{
"permissionName": "inventory.holdings.update-ownership.item.post",
"displayName": "Inventory - update holdings ownership",
"description": "Update holdings record ownership"
},
{
"permissionName": "inventory.instances.item.get",
"displayName": "Inventory - get individual instance",
Expand Down Expand Up @@ -803,7 +844,9 @@
"inventory.items.item.mark-in-process-non-requestable.post",
"inventory.items.item.mark-missing.post",
"inventory.items.move.item.post",
"inventory.holdings.move.item.post"
"inventory.holdings.move.item.post",
"inventory.items.update-ownership.item.post",
"inventory.holdings.update-ownership.item.post"
]
},
{
Expand Down
28 changes: 28 additions & 0 deletions ramls/holdings_update_ownership.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Ids holder for updating ownership of the holdings records",
"type": "object",
"properties": {
"toInstanceId": {
"description": "Id of the shared Instance, ownership of Holdings linked to this Instance will be changed.",
"$ref": "uuid.json"
},
"holdingsRecordIds": {
"description": "Ids of the holdings to update ownership.",
"type": "array",
"items": {
"$ref": "uuid.json"
}
},
"targetTenantId": {
"description": "Target tenant Id, where selected Holdings will be created.",
"type": "string"
}
},
"additionalProperties": false,
"required": [
"toInstanceId",
"holdingsRecordIds",
"targetTenantId"
]
}
66 changes: 66 additions & 0 deletions ramls/inventory-update-ownership.raml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#%RAML 1.0
title: Inventory Update Ownership API
version: v0.1
protocols: [ HTTP, HTTPS ]
baseUri: http://localhost

documentation:
- title: "Inventory Update Ownership API"
content: <b>API for updating ownership of holdings records and items between ECS tenants</b>

types:
errors: !include raml-util/schemas/errors.schema
items_update_ownership: !include items_update_ownership.json
holdings_update_ownership: !include holdings_update_ownership.json
move_response: !include move_response.json

traits:
language: !include raml-util/traits/language.raml
validate: !include raml-util/traits/validation.raml

/inventory/items/update-ownership:
displayName: Items Update Ownership
post:
is: [validate]
body:
application/json:
type: items_update_ownership
responses:
200:
description: "Items ownership updated to another tenant"
body:
application/json:
type: move_response
422:
description: "Validation error"
body:
application/json:
type: errors
500:
description: "Internal server error"
body:
text/plain:
example: "Internal server error"
/inventory/holdings/update-ownership:
displayName: Holdings Record Update Ownership
post:
is: [validate]
body:
application/json:
type: holdings_update_ownership
responses:
200:
description: "Holdings record ownership updated to another tenant"
body:
application/json:
type: move_response
422:
description: "Validation error"
body:
application/json:
type: errors
500:
description: "Internal server error"
body:
text/plain:
example: "Internal server error"
28 changes: 28 additions & 0 deletions ramls/items_update_ownership.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Ids holder for updating ownership of the items",
"type": "object",
"properties": {
"toHoldingsRecordId": {
"description": "Id of the Holdings Record, ownership of Items linked to this Holdings Record will be changed.",
"$ref": "uuid.json"
},
"itemIds": {
"description": "Ids of the items to update ownership.",
"type": "array",
"items": {
"$ref": "uuid.json"
}
},
"targetTenantId": {
"description": "Target tenant Id, where selected Items will be created.",
"type": "string"
}
},
"additionalProperties": false,
"required": [
"toHoldingsRecordId",
"itemIds",
"targetTenantId"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,10 @@ public void start(Promise<Void> 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);

Expand Down
2 changes: 2 additions & 0 deletions src/main/java/org/folio/inventory/InventoryVerticle.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.folio.inventory.resources.ItemsByHoldingsRecordId;
import org.folio.inventory.resources.MoveApi;
import org.folio.inventory.resources.TenantApi;
import org.folio.inventory.resources.UpdateOwnershipApi;
import org.folio.inventory.storage.Storage;

import io.vertx.core.AbstractVerticle;
Expand Down Expand Up @@ -69,6 +70,7 @@ public void start(Promise<Void> started) {
new ItemsByHoldingsRecordId(storage, client).register(router);
new InventoryConfigApi().register(router);
new TenantApi().register(router);
new UpdateOwnershipApi(storage, client).register(router);

Handler<AsyncResult<HttpServer>> onHttpServerStart = result -> {
if (result.succeeded()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ public void start(Promise<Void> 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);
Expand Down Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ public void start(Promise<Void> 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);
Expand Down Expand Up @@ -101,12 +100,4 @@ private KafkaConsumerWrapper<String, String> 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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -29,9 +31,11 @@
public class MappingMetadataCache {

private static final Logger LOGGER = LogManager.getLogger();

private static MappingMetadataCache instance = null;
private final AsyncCache<String, Optional<MappingMetadataDto>> 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;
Expand Down Expand Up @@ -107,4 +111,18 @@ private CompletableFuture<Optional<MappingMetadataDto>> 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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.folio.inventory.resources;

import io.vertx.core.http.HttpClient;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import org.folio.inventory.storage.Storage;

public class UpdateOwnershipApi extends AbstractInventoryResource {
public UpdateOwnershipApi(Storage storage, HttpClient client) {
super(storage, client);
}

@Override
public void register(Router router) {
router.post("/inventory/items/update-ownership")
.handler(this::updateItemsOwnership);
router.post("/inventory/holdings/update-ownership")
.handler(this::updateHoldingsOwnership);
}

private void updateHoldingsOwnership(RoutingContext routingContext) {
// should be implemented in MODINV-1031
}

private void updateItemsOwnership(RoutingContext routingContext) {
// should be implemented in MODINV-1031
}
}
Loading

0 comments on commit c42d60d

Please sign in to comment.