diff --git a/NEWS.md b/NEWS.md
index 27a7f4fb7..ebb154b4a 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -20,6 +20,8 @@
* Disallow updating holdings ownership with related boundwith [MODINV-1051](https://folio-org.atlassian.net/browse/MODINV-1051)
* Disallow updating ownership of boundwith item [MODINV-1052](https://folio-org.atlassian.net/browse/MODINV-1052)
* InstanceIngress update events consumption [MODINV-1008](https://folio-org.atlassian.net/browse/MODINV-1008)
+* Apply new date type fields to instance schema [MODINV-1067](https://folio-org.atlassian.net/browse/MODINV-1067)
+* Extend Authority with Additional fields [MODINV-1071](https://folio-org.atlassian.net/browse/MODINV-1071)
## 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/README.MD b/README.MD
index 71fa0e31b..ca9d74c41 100644
--- a/README.MD
+++ b/README.MD
@@ -129,6 +129,18 @@ After setup, it is good to check logs in all related modules for errors.
* DI_SRS_MARC_BIB_RECORD_MODIFIED_PARTITIONS
Default value for all partitions is 1
+## Properties
+
+`AUTHORITY_EXTENDED` environment variable enables extended mapping for Authority to support advanced references classification in 5xx fields:
+* broader terms (`$wg` tag)
+* narrower terms (`$wh` tag)
+* earlier headings (`$wa` tag)
+* later headings (`$wb` tag)
+
+Default value for `AUTHORITY_EXTENDED` is `false`.
+The mapping itself is implemented in [data-import-processing-core](https://github.com/folio-org/data-import-processing-core).
+
+
# Making Requests
These modules provide HTTP based APIs rather than any UI themselves.
diff --git a/descriptors/ModuleDescriptor-template.json b/descriptors/ModuleDescriptor-template.json
index 5bc3ee80b..8ca1eef80 100644
--- a/descriptors/ModuleDescriptor-template.json
+++ b/descriptors/ModuleDescriptor-template.json
@@ -4,7 +4,7 @@
"provides": [
{
"id": "inventory",
- "version": "13.1",
+ "version": "13.3",
"handlers": [
{
"methods": ["GET"],
@@ -559,7 +559,8 @@
"inventory-storage.holdings.item.get",
"inventory-storage.holdings.collection.get",
"inventory-storage.instances.item.get",
- "inventory-storage.bound-with-parts.collection.get"
+ "inventory-storage.bound-with-parts.collection.get",
+ "user-tenants.collection.get"
]
},
{
@@ -574,7 +575,8 @@
"inventory-storage.items.item.delete",
"inventory-storage.items.collection.get",
"inventory-storage.instances.item.get",
- "inventory-storage.bound-with-parts.collection.get"
+ "inventory-storage.bound-with-parts.collection.get",
+ "user-tenants.collection.get"
]
}
]
@@ -602,7 +604,7 @@
},
{
"id": "instance-storage",
- "version": "10.0"
+ "version": "10.3"
},
{
"id": "instance-storage-batch",
diff --git a/pom.xml b/pom.xml
index 49b91ca8a..705f4f467 100644
--- a/pom.xml
+++ b/pom.xml
@@ -451,6 +451,7 @@
${basedir}/ramls/instance-ingress-event.json
${basedir}/ramls/tenantItemPair.json
${basedir}/ramls/tenantItemPairCollection.json
+ ${basedir}/ramls/tenantItemResponse.json
org.folio
true
diff --git a/ramls/instance.json b/ramls/instance.json
index d27ab0f00..ee7703fee 100644
--- a/ramls/instance.json
+++ b/ramls/instance.json
@@ -335,6 +335,27 @@
]
}
},
+ "dates": {
+ "type": "object",
+ "description": "Instance Dates",
+ "properties": {
+ "dateTypeId": {
+ "type": "string",
+ "description": "Date type ID",
+ "$ref": "uuid.json"
+ },
+ "date1": {
+ "type": "string",
+ "description": "Date 1",
+ "maxLength": 4
+ },
+ "date2": {
+ "type": "string",
+ "description": "Date 2",
+ "maxLength": 4
+ }
+ }
+ },
"instanceTypeId": {
"type": "string",
"description": "The unique term for the resource type whether it's from the RDA content term list of locally defined"
diff --git a/ramls/tenantItemResponse.json b/ramls/tenantItemResponse.json
new file mode 100644
index 000000000..8bdf521e3
--- /dev/null
+++ b/ramls/tenantItemResponse.json
@@ -0,0 +1,20 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "description": "Collection of pairs of item and tenant IDs",
+ "type": "object",
+ "properties": {
+ "tenantItems": {
+ "type": "array",
+ "description": "Items with corresponding tenantIds",
+ "items": {
+ "type": "object",
+ "additionalProperties": true
+ }
+ },
+ "totalRecords": {
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["item", "totalRecords"]
+}
diff --git a/src/main/java/org/folio/inventory/config/InventoryConfigurationImpl.java b/src/main/java/org/folio/inventory/config/InventoryConfigurationImpl.java
index 6fbd93eb0..b750fb5ff 100644
--- a/src/main/java/org/folio/inventory/config/InventoryConfigurationImpl.java
+++ b/src/main/java/org/folio/inventory/config/InventoryConfigurationImpl.java
@@ -32,7 +32,8 @@ public class InventoryConfigurationImpl implements InventoryConfiguration {
Instance.INSTANCE_TYPE_ID_KEY,
Instance.MODE_OF_ISSUANCE_ID_KEY,
Instance.PRECEDING_TITLES_KEY,
- Instance.SUCCEEDING_TITLES_KEY
+ Instance.SUCCEEDING_TITLES_KEY,
+ Instance.DATES_KEY
);
private static final Set HOLDINGS_BLOCKED_FIELDS = Sets.newHashSet(
diff --git a/src/main/java/org/folio/inventory/dataimport/handlers/actions/AbstractAuthorityEventHandler.java b/src/main/java/org/folio/inventory/dataimport/handlers/actions/AbstractAuthorityEventHandler.java
index 12be75fd7..2f052bf36 100644
--- a/src/main/java/org/folio/inventory/dataimport/handlers/actions/AbstractAuthorityEventHandler.java
+++ b/src/main/java/org/folio/inventory/dataimport/handlers/actions/AbstractAuthorityEventHandler.java
@@ -21,6 +21,7 @@
import org.apache.logging.log4j.Logger;
import org.folio.ActionProfile;
+import org.folio.ActionProfile.FolioRecord;
import org.folio.Authority;
import org.folio.DataImportEventPayload;
import org.folio.MappingMetadataDto;
@@ -54,10 +55,13 @@ public abstract class AbstractAuthorityEventHandler implements EventHandler {
private static final String RECORD_ID_HEADER = "recordId";
private static final String CHUNK_ID_HEADER = "chunkId";
+ public static final String AUTHORITY_EXTENDED = "AUTHORITY_EXTENDED";
private final Storage storage;
private final MappingMetadataCache mappingMetadataCache;
+ private static boolean isAuthorityExtended = isAuthorityExtendedMode();
+
protected AbstractAuthorityEventHandler(Storage storage, MappingMetadataCache mappingMetadataCache) {
this.storage = storage;
this.mappingMetadataCache = mappingMetadataCache;
@@ -161,7 +165,9 @@ private Future mapAuthority(DataImportEventPayload payload, MappingMe
var mappingParameters = Json.decodeValue(mappingMetadata.getMappingParams(), MappingParameters.class);
var parsedRecord = new JsonObject((String) new JsonObject(payload.getContext().get(sourceRecordType().value()))
.mapTo(Record.class).getParsedRecord().getContent());
- RecordMapper recordMapper = RecordMapperBuilder.buildMapper(sourceRecordType().value());
+ RecordMapper recordMapper = isAuthorityExtended
+ ? RecordMapperBuilder.buildMapper(FolioRecord.MARC_AUTHORITY_EXTENDED.value())
+ : RecordMapperBuilder.buildMapper(sourceRecordType().value());
var authority = recordMapper.mapRecord(parsedRecord, mappingParameters, mappingRules);
authority.setSource(Authority.Source.MARC);
return Future.succeededFuture(authority);
@@ -215,4 +221,18 @@ private String constructMetaInfoMsg(DataImportEventPayload payload) {
getChunkIdHeader(payload)
);
}
+
+ private static boolean isAuthorityExtendedMode() {
+ return Boolean.parseBoolean(
+ System.getenv().getOrDefault(AUTHORITY_EXTENDED, "false"));
+ }
+
+ /**
+ * For test usage only.
+ *
+ * @param newIsAuthoritiesExtended New value for the env to set.
+ */
+ public static void setAuthorityExtendedMode(boolean newIsAuthoritiesExtended) {
+ isAuthorityExtended = newIsAuthoritiesExtended;
+ }
}
diff --git a/src/main/java/org/folio/inventory/dataimport/handlers/matching/loaders/HoldingLoader.java b/src/main/java/org/folio/inventory/dataimport/handlers/matching/loaders/HoldingLoader.java
index d3acb0e5f..44a8364bb 100644
--- a/src/main/java/org/folio/inventory/dataimport/handlers/matching/loaders/HoldingLoader.java
+++ b/src/main/java/org/folio/inventory/dataimport/handlers/matching/loaders/HoldingLoader.java
@@ -4,13 +4,11 @@
import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
+import io.vertx.core.json.Json;
+import io.vertx.core.json.JsonObject;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
-
-import io.vertx.core.json.Json;
-import io.vertx.core.json.JsonObject;
-
import org.folio.DataImportEventPayload;
import org.folio.HoldingsRecord;
import org.folio.inventory.common.Context;
@@ -26,6 +24,7 @@ public class HoldingLoader extends AbstractLoader {
private static final String HOLDINGS_FIELD = "holdings";
private static final String INSTANCE_ID_FIELD = "instanceId";
private static final String INSTANCES_IDS_KEY = "INSTANCES_IDS";
+ private static final String EMPTY_ARRAY = "[]";
private Storage storage;
private AbstractPreloader preloader;
@@ -59,7 +58,7 @@ protected String addCqlSubMatchCondition(DataImportEventPayload eventPayload) {
cqlSubMatch = getConditionByMultiMatchResult(eventPayload);
} else if (isNotEmpty(eventPayload.getContext().get(INSTANCES_IDS_KEY))) {
cqlSubMatch = getConditionByMultipleMarcBibMatchResult(eventPayload);
- } else if (isNotEmpty(eventPayload.getContext().get(EntityType.HOLDINGS.value()))) {
+ } else if (isNotNullOrEmpty(eventPayload.getContext().get(EntityType.HOLDINGS.value()))) {
JsonObject holdingAsJson = new JsonObject(eventPayload.getContext().get(EntityType.HOLDINGS.value()));
if (holdingAsJson.getJsonObject(HOLDINGS_FIELD) != null) {
holdingAsJson = holdingAsJson.getJsonObject(HOLDINGS_FIELD);
@@ -73,6 +72,12 @@ protected String addCqlSubMatchCondition(DataImportEventPayload eventPayload) {
return cqlSubMatch;
}
+ private static boolean isNotNullOrEmpty(String value) {
+ if (value == null || value.equals(EMPTY_ARRAY))
+ return false;
+ return isNotEmpty(value);
+ }
+
private String getConditionByMultipleMarcBibMatchResult(DataImportEventPayload eventPayload) {
return getConditionByMultipleValues(INSTANCE_ID_FIELD, eventPayload, INSTANCES_IDS_KEY);
}
diff --git a/src/main/java/org/folio/inventory/domain/instances/Dates.java b/src/main/java/org/folio/inventory/domain/instances/Dates.java
new file mode 100644
index 000000000..58ee18458
--- /dev/null
+++ b/src/main/java/org/folio/inventory/domain/instances/Dates.java
@@ -0,0 +1,42 @@
+package org.folio.inventory.domain.instances;
+
+import io.vertx.core.json.JsonObject;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import static org.apache.commons.lang3.ObjectUtils.anyNotNull;
+import static org.folio.inventory.support.JsonHelper.includeIfPresent;
+
+@Getter
+@AllArgsConstructor
+public class Dates {
+ // JSON property names
+ public static final String DATE_TYPE_ID_KEY = "dateTypeId";
+ public static final String DATE1_KEY = "date1";
+ public static final String DATE2_KEY = "date2";
+
+ public final String dateTypeId;
+ public final String date1;
+ public final String date2;
+
+ public static JsonObject datesToJson(Dates dates) {
+ if (dates == null || (dates.getDate1() == null && dates.getDate2() == null && dates.getDateTypeId() == null)) {
+ return null;
+ }
+ var json = new JsonObject();
+ includeIfPresent(json, DATE_TYPE_ID_KEY, dates.getDateTypeId());
+ includeIfPresent(json, DATE1_KEY, dates.getDate1());
+ includeIfPresent(json, DATE2_KEY, dates.getDate2());
+ return json;
+ }
+
+ public static Dates datesFromJson(JsonObject datesJson) {
+ if (datesJson == null) {
+ return null;
+ }
+ var dateTypeId = datesJson.getString(DATE_TYPE_ID_KEY);
+ var date1 = datesJson.getString(DATE1_KEY);
+ var date2 = datesJson.getString(DATE2_KEY);
+ return anyNotNull(dateTypeId, date1, date2) ? new Dates(dateTypeId, date1, date2) : null;
+ }
+}
diff --git a/src/main/java/org/folio/inventory/domain/instances/Instance.java b/src/main/java/org/folio/inventory/domain/instances/Instance.java
index bd92b3508..3efeba9df 100644
--- a/src/main/java/org/folio/inventory/domain/instances/Instance.java
+++ b/src/main/java/org/folio/inventory/domain/instances/Instance.java
@@ -1,5 +1,7 @@
package org.folio.inventory.domain.instances;
+import static org.folio.inventory.domain.instances.Dates.datesFromJson;
+import static org.folio.inventory.domain.instances.Dates.datesToJson;
import static org.folio.inventory.domain.instances.PublicationPeriod.publicationPeriodFromJson;
import static org.folio.inventory.domain.instances.PublicationPeriod.publicationPeriodToJson;
import static org.folio.inventory.support.JsonArrayHelper.toListOfStrings;
@@ -73,6 +75,7 @@ public class Instance {
public static final String TAG_LIST_KEY = "tagList";
public static final String NATURE_OF_CONTENT_TERM_IDS_KEY = "natureOfContentTermIds";
public static final String PUBLICATION_PERIOD_KEY = "publicationPeriod";
+ public static final String DATES_KEY = "dates";
private final String id;
@JsonProperty("_version")
@@ -117,6 +120,7 @@ public class Instance {
private List tags;
private List natureOfContentTermIds = new ArrayList<>();
private PublicationPeriod publicationPeriod;
+ private Dates dates;
protected static final String INVENTORY_PATH = "/inventory";
protected static final String INSTANCES_PATH = INVENTORY_PATH + "/instances";
@@ -188,7 +192,8 @@ public static Instance fromJson(JsonObject instanceJson) {
.setStatusUpdatedDate(instanceJson.getString(STATUS_UPDATED_DATE_KEY))
.setTags(getTags(instanceJson))
.setNatureOfContentTermIds(toListOfStrings(instanceJson.getJsonArray(NATURE_OF_CONTENT_TERM_IDS_KEY)))
- .setPublicationPeriod(publicationPeriodFromJson(instanceJson.getJsonObject(PUBLICATION_PERIOD_KEY)));
+ .setPublicationPeriod(publicationPeriodFromJson(instanceJson.getJsonObject(PUBLICATION_PERIOD_KEY)))
+ .setDates(datesFromJson(instanceJson.getJsonObject(DATES_KEY)));
}
/**
@@ -237,6 +242,7 @@ public JsonObject getJsonForStorage() {
json.put(TAGS_KEY, new JsonObject().put(TAG_LIST_KEY, new JsonArray(getTags() == null ? Collections.emptyList() : getTags())));
json.put(NATURE_OF_CONTENT_TERM_IDS_KEY, natureOfContentTermIds);
putIfNotNull(json, PUBLICATION_PERIOD_KEY, publicationPeriodToJson(publicationPeriod));
+ putIfNotNull(json, DATES_KEY, datesToJson(dates));
return json;
}
@@ -290,6 +296,7 @@ public JsonObject getJsonForResponse(WebContext context) {
putIfNotNull(json, TAGS_KEY, new JsonObject().put(TAG_LIST_KEY, new JsonArray(getTags())));
putIfNotNull(json, NATURE_OF_CONTENT_TERM_IDS_KEY, getNatureOfContentTermIds());
putIfNotNull(json, PUBLICATION_PERIOD_KEY, publicationPeriodToJson(publicationPeriod));
+ putIfNotNull(json, DATES_KEY, datesToJson(dates));
if (precedingTitles != null) {
JsonArray precedingTitlesJsonArray = new JsonArray();
@@ -461,6 +468,11 @@ public Instance setElectronicAccess (JsonArray array) {
return this;
}
+ public Instance setDates(Dates dates) {
+ this.dates = dates;
+ return this;
+ }
+
public Instance setInstanceFormatIds(List instanceFormatIds) {
this.instanceFormatIds = instanceFormatIds;
return this;
@@ -747,7 +759,8 @@ public Instance copyWithNewId(String newId) {
.setMetadata(metadata)
.setTags(tags)
.setNatureOfContentTermIds(natureOfContentTermIds)
- .setPublicationPeriod(publicationPeriod);
+ .setPublicationPeriod(publicationPeriod)
+ .setDates(dates);
}
public Instance copyInstance() {
@@ -781,7 +794,8 @@ public Instance copyInstance() {
.setMetadata(metadata)
.setTags(tags)
.setNatureOfContentTermIds(natureOfContentTermIds)
- .setPublicationPeriod(publicationPeriod);
+ .setPublicationPeriod(publicationPeriod)
+ .setDates(dates);
}
public Instance addIdentifier(Identifier identifier) {
diff --git a/src/main/java/org/folio/inventory/domain/instances/Subject.java b/src/main/java/org/folio/inventory/domain/instances/Subject.java
index 27950f639..051c3ca11 100644
--- a/src/main/java/org/folio/inventory/domain/instances/Subject.java
+++ b/src/main/java/org/folio/inventory/domain/instances/Subject.java
@@ -4,17 +4,30 @@
public class Subject extends Authorized {
// JSON property names
- public static final String VALUE_KEY = "value";
+ private static final String VALUE_KEY = "value";
+ private static final String SOURCE_KEY = "sourceId";
+ private static final String TYPE_KEY = "typeId";
private final String value;
- public Subject(String value, String authorityId) {
+ private final String sourceId;
+
+ private final String typeId;
+
+ public Subject(String value, String authorityId, String sourceId, String typeId) {
super(authorityId);
this.value = value;
+ this.sourceId = sourceId;
+ this.typeId = typeId;
}
public Subject(JsonObject json) {
- this(json.getString(VALUE_KEY), json.getString(AUTHORITY_ID_KEY));
+ this(
+ json.getString(VALUE_KEY),
+ json.getString(AUTHORITY_ID_KEY),
+ json.getString(SOURCE_KEY),
+ json.getString(TYPE_KEY)
+ );
}
public String getAuthorityId() {
@@ -24,4 +37,12 @@ public String getAuthorityId() {
public String getValue() {
return value;
}
+
+ public String getSourceId() {
+ return sourceId;
+ }
+
+ public String getTypeId() {
+ return typeId;
+ }
}
diff --git a/src/main/java/org/folio/inventory/instanceingress/handler/InstanceIngressEventHandler.java b/src/main/java/org/folio/inventory/instanceingress/handler/InstanceIngressEventHandler.java
index 74bdfc146..18320b5bf 100644
--- a/src/main/java/org/folio/inventory/instanceingress/handler/InstanceIngressEventHandler.java
+++ b/src/main/java/org/folio/inventory/instanceingress/handler/InstanceIngressEventHandler.java
@@ -46,6 +46,7 @@
public interface InstanceIngressEventHandler {
String LINKED_DATA_ID = "linkedDataId";
+ String INSTANCE_ID = "instanceId";
String FAILURE = "Failed to process InstanceIngressEvent with id {}";
CompletableFuture handle(InstanceIngressEvent instanceIngressEvent);
@@ -57,11 +58,15 @@ default boolean eventContainsNoData(InstanceIngressEvent event) {
}
default Optional getInstanceId(InstanceIngressEvent event) {
- return ofNullable(event.getEventPayload().getSourceRecordIdentifier());
+ return ofNullable(event.getEventPayload())
+ .map(InstanceIngressPayload::getAdditionalProperties)
+ .map(ap -> ap.get(INSTANCE_ID))
+ .map(o -> (String) o);
}
default Record constructMarcBibRecord(InstanceIngressPayload eventPayload) {
- var recordId = UUID.randomUUID().toString();
+ var recordId = ofNullable(eventPayload.getSourceRecordIdentifier())
+ .orElseGet(() -> UUID.randomUUID().toString());
var marcBibRecord = new org.folio.rest.jaxrs.model.Record()
.withId(recordId)
.withRecordType(MARC_BIB)
diff --git a/src/main/java/org/folio/inventory/resources/TenantItems.java b/src/main/java/org/folio/inventory/resources/TenantItems.java
index c6079b6f4..c02ac570d 100644
--- a/src/main/java/org/folio/inventory/resources/TenantItems.java
+++ b/src/main/java/org/folio/inventory/resources/TenantItems.java
@@ -17,8 +17,10 @@
import org.apache.http.HttpStatus;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.folio.TenantItem;
import org.folio.TenantItemPair;
import org.folio.TenantItemPairCollection;
+import org.folio.TenantItemResponse;
import org.folio.inventory.common.WebContext;
import org.folio.inventory.storage.external.CollectionResourceClient;
import org.folio.inventory.support.JsonArrayHelper;
@@ -28,7 +30,6 @@
import org.folio.inventory.support.http.server.ServerErrorResponse;
import io.vertx.core.http.HttpClient;
-import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
@@ -45,6 +46,7 @@ public class TenantItems {
private static final String TENANT_ITEMS_PATH = "/inventory/tenant-items";
public static final String ITEMS_FIELD = "items";
+ public static final String ITEM_FIELD = "item";
public static final String TOTAL_RECORDS_FIELD = "totalRecords";
public static final String TENANT_ID_FIELD = "tenantId";
@@ -77,11 +79,11 @@ private void getItemsFromTenants(RoutingContext routingContext) {
.map(CompletableFuture::join)
.flatMap(List::stream)
.toList())
- .thenApply(this::constructResponse)
- .thenAccept(jsonObject -> JsonResponse.success(routingContext.response(), jsonObject));
+ .thenApply(items -> new TenantItemResponse().withTenantItems(items).withTotalRecords(items.size()))
+ .thenAccept(response -> JsonResponse.success(routingContext.response(), JsonObject.mapFrom(response)));
}
- private CompletableFuture> getItemsWithTenantId(String tenantId, List itemIds, RoutingContext routingContext) {
+ private CompletableFuture> getItemsWithTenantId(String tenantId, List itemIds, RoutingContext routingContext) {
LOG.info("getItemsWithTenantId:: Fetching items - {} from tenant - {}", itemIds, tenantId);
var context = new WebContext(routingContext);
CollectionResourceClient itemsStorageClient;
@@ -98,24 +100,20 @@ private CompletableFuture> getItemsWithTenantId(String tenantId
var itemsFetched = new CompletableFuture();
itemsStorageClient.getAll(getByIdsQuery, itemsFetched::complete);
- return itemsFetched.thenApplyAsync(response ->
- getItemsWithTenantId(tenantId, response));
+ return itemsFetched
+ .thenApply(this::getItems)
+ .thenApply(items -> items.stream()
+ .map(item -> new TenantItem()
+ .withAdditionalProperty(ITEM_FIELD, item)
+ .withAdditionalProperty(TENANT_ID_FIELD, tenantId))
+ .toList());
}
- private List getItemsWithTenantId(String tenantId, Response response) {
+ private List getItems(Response response) {
if (response.getStatusCode() != HttpStatus.SC_OK || !response.hasBody()) {
return List.of();
}
- return JsonArrayHelper.toList(response.getJson(), ITEMS_FIELD).stream()
- .map(item -> item.put(TENANT_ID_FIELD, tenantId))
- .toList();
- }
-
- private JsonObject constructResponse(List items) {
- return JsonObject.of(
- ITEMS_FIELD, JsonArray.of(items.toArray()),
- TOTAL_RECORDS_FIELD, items.size()
- );
+ return JsonArrayHelper.toList(response.getJson(), ITEMS_FIELD);
}
private CollectionResourceClient createItemsStorageClient(OkapiHttpClient client, WebContext context) throws MalformedURLException {
diff --git a/src/test/java/api/InstancesApiExamples.java b/src/test/java/api/InstancesApiExamples.java
index c33a7bb76..fd41b36ea 100644
--- a/src/test/java/api/InstancesApiExamples.java
+++ b/src/test/java/api/InstancesApiExamples.java
@@ -12,6 +12,11 @@
import static io.vertx.core.http.HttpMethod.PUT;
import static java.util.Arrays.asList;
import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.folio.inventory.domain.instances.Dates.DATE_TYPE_ID_KEY;
+import static org.folio.inventory.domain.instances.Dates.DATE1_KEY;
+import static org.folio.inventory.domain.instances.Dates.DATE2_KEY;
+import static org.folio.inventory.domain.instances.Dates.datesToJson;
+import static org.folio.inventory.domain.instances.Instance.DATES_KEY;
import static org.folio.inventory.domain.instances.Instance.PRECEDING_TITLES_KEY;
import static org.folio.inventory.domain.instances.Instance.PUBLICATION_PERIOD_KEY;
import static org.folio.inventory.domain.instances.Instance.TAGS_KEY;
@@ -40,7 +45,9 @@
import org.folio.HttpStatus;
import org.folio.inventory.config.InventoryConfiguration;
import org.folio.inventory.config.InventoryConfigurationImpl;
+import org.folio.inventory.domain.instances.Dates;
import org.folio.inventory.domain.instances.PublicationPeriod;
+import org.folio.inventory.domain.instances.Subject;
import org.folio.inventory.domain.instances.titles.PrecedingSucceedingTitle;
import org.folio.inventory.support.JsonArrayHelper;
import org.folio.inventory.support.http.ContentType;
@@ -63,6 +70,9 @@ public class InstancesApiExamples extends ApiTests {
private static final InventoryConfiguration config = new InventoryConfigurationImpl();
private final String tagNameOne = "important";
private final String tagNameTwo = "very important";
+ private final String dateTypeId = "0750f52b-3bfc-458d-9307-e9afc8bcdffa";
+ private final String date1 = "2014";
+ private final String date2 = "2016";
@After
public void disableFailureEmulation() throws Exception {
@@ -93,6 +103,7 @@ public void canCreateInstanceWithoutAnIDAndHRID()
.put("instanceTypeId", ApiTestSuite.getTextInstanceType())
.put(TAGS_KEY, new JsonObject().put(TAG_LIST_KEY, new JsonArray().add(tagNameOne)))
.put(PUBLICATION_PERIOD_KEY, publicationPeriodToJson(new PublicationPeriod(1000, 2000)))
+ .put(DATES_KEY, datesToJson(new Dates(dateTypeId, date1, date2)))
.put("natureOfContentTermIds",
new JsonArray(asList(
ApiTestSuite.getAudiobookNatureOfContentTermId(),
@@ -161,6 +172,11 @@ public void canCreateInstanceWithoutAnIDAndHRID()
var publicationPeriod = createdInstance.getJsonObject(PUBLICATION_PERIOD_KEY);
assertThat(publicationPeriod.getInteger("start"), is(1000));
assertThat(publicationPeriod.getInteger("end"), is(2000));
+
+ var dates = createdInstance.getJsonObject(DATES_KEY);
+ assertThat(dates.getString(DATE_TYPE_ID_KEY), is(dateTypeId));
+ assertThat(dates.getString(DATE1_KEY), is(date1));
+ assertThat(dates.getString(DATE2_KEY), is(date2));
}
@Test
@@ -387,11 +403,14 @@ public void canUpdateAnExistingInstance()
ExecutionException {
UUID id = UUID.randomUUID();
+ final var sourceId = "sourceId";
+ final var typeId = "typeId";
JsonObject smallAngryPlanet = smallAngryPlanet(id);
smallAngryPlanet.put("natureOfContentTermIds",
new JsonArray().add(ApiTestSuite.getBibliographyNatureOfContentTermId()));
smallAngryPlanet.put(PUBLICATION_PERIOD_KEY, publicationPeriodToJson(new PublicationPeriod(1000, 2000)));
+ smallAngryPlanet.put(DATES_KEY, datesToJson(new Dates(null, date1, date2)));
JsonObject newInstance = createInstance(smallAngryPlanet);
@@ -399,8 +418,12 @@ public void canUpdateAnExistingInstance()
.put("title", "The Long Way to a Small, Angry Planet")
.put(TAGS_KEY, new JsonObject().put(TAG_LIST_KEY, new JsonArray().add(tagNameTwo)))
.put(PUBLICATION_PERIOD_KEY, publicationPeriodToJson(new PublicationPeriod(2000, 2012)))
+ .put(DATES_KEY, datesToJson(new Dates(dateTypeId, date1, date2)))
.put("natureOfContentTermIds",
- new JsonArray().add(ApiTestSuite.getAudiobookNatureOfContentTermId()));
+ new JsonArray().add(ApiTestSuite.getAudiobookNatureOfContentTermId()))
+ .put("subjects", new JsonArray().add(
+ new Subject(null, null, sourceId, typeId)
+ ));
URL instanceLocation = new URL(String.format("%s/%s", ApiRoot.instances(),
newInstance.getString("id")));
@@ -434,6 +457,17 @@ public void canUpdateAnExistingInstance()
var publicationPeriod = updatedInstance.getJsonObject(PUBLICATION_PERIOD_KEY);
assertThat(publicationPeriod.getInteger("start"), is(2000));
assertThat(publicationPeriod.getInteger("end"), is(2012));
+
+ var dates = updatedInstance.getJsonObject(DATES_KEY);
+ assertThat(dates.getString(DATE_TYPE_ID_KEY), is(dateTypeId));
+ assertThat(dates.getString(DATE1_KEY), is(date1));
+ assertThat(dates.getString(DATE2_KEY), is(date2));
+
+ var subjects = updatedInstance.getJsonArray("subjects");
+ var subject = subjects.getJsonObject(0);
+ assertThat(subjects.size(), is(1));
+ assertThat(subject.getString(sourceId), is(sourceId));
+ assertThat(subject.getString(typeId), is(typeId));
}
@Test
@@ -612,7 +646,7 @@ public void canNotUpdateAnExistingMARCInstanceIfBlockedFieldsAreChangedToNulls()
assertThat(errors.size(), is(1));
assertThat(errors.getJsonObject(0).getString("message"), is(
"Instance is controlled by MARC record, these fields are blocked and can not be updated: " +
- "physicalDescriptions,notes,languages,precedingTitles,identifiers,instanceTypeId,modeOfIssuanceId,subjects," +
+ "physicalDescriptions,notes,languages,precedingTitles,identifiers,instanceTypeId,modeOfIssuanceId,subjects,dates," +
"source,title,indexTitle,publicationFrequency,electronicAccess,publicationRange," +
"classifications,succeedingTitles,editions,hrid,series,instanceFormatIds,publication,contributors," +
"alternativeTitles"));
diff --git a/src/test/java/api/items/TenantItemApiTests.java b/src/test/java/api/items/TenantItemApiTests.java
index 4b0095bcd..5471bda7a 100644
--- a/src/test/java/api/items/TenantItemApiTests.java
+++ b/src/test/java/api/items/TenantItemApiTests.java
@@ -6,7 +6,7 @@
import static api.ApiTestSuite.getCanCirculateLoanType;
import static api.support.InstanceSamples.smallAngryPlanet;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.folio.inventory.resources.TenantItems.ITEMS_FIELD;
+import static org.folio.inventory.resources.TenantItems.ITEM_FIELD;
import static org.folio.inventory.resources.TenantItems.TENANT_ID_FIELD;
import static org.folio.inventory.resources.TenantItems.TOTAL_RECORDS_FIELD;
import static org.folio.inventory.support.ItemUtil.ID;
@@ -38,6 +38,8 @@
@RunWith(JUnitParamsRunner.class)
public class TenantItemApiTests extends ApiTests {
+ private static final String TENANT_ITEMS_FIELD = "tenantItems";
+
@Test
public void testTenantItemsGetFromDifferentTenants() throws MalformedURLException,
ExecutionException, InterruptedException, TimeoutException {
@@ -59,8 +61,8 @@ public void testTenantItemsGetFromDifferentTenants() throws MalformedURLExceptio
.toCompletableFuture().get(5, TimeUnit.SECONDS);
assertThat(response.getStatusCode()).isEqualTo(200);
- consortiumItem.put(TENANT_ID_FIELD, CONSORTIA_TENANT_ID);
- collegeItem.put(TENANT_ID_FIELD, COLLEGE_TENANT_ID);
+ consortiumItem = JsonObject.of(ITEM_FIELD, consortiumItem, TENANT_ID_FIELD, CONSORTIA_TENANT_ID);
+ collegeItem = JsonObject.of(ITEM_FIELD, collegeItem, TENANT_ID_FIELD, COLLEGE_TENANT_ID);
var items = extractItems(response, 2);
assertThat(items).contains(consortiumItem, collegeItem);
}
@@ -91,7 +93,7 @@ private UUID createInstanceHoldingItem(ResourceClient itemsStorageClient, Resour
private List extractItems(Response itemsResponse, int expected) {
var itemsCollection = itemsResponse.getJson();
- var items = JsonArrayHelper.toList(itemsCollection.getJsonArray(ITEMS_FIELD));
+ var items = JsonArrayHelper.toList(itemsCollection.getJsonArray(TENANT_ITEMS_FIELD));
assertThat(items).hasSize(expected);
assertThat(itemsCollection.getInteger(TOTAL_RECORDS_FIELD)).isEqualTo(expected);
return items;
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 5cea2d3c4..b4961c753 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
@@ -9,6 +9,8 @@
import io.vertx.core.Vertx;
import io.vertx.core.json.Json;
import io.vertx.core.json.JsonObject;
+import java.util.Arrays;
+import java.util.Collection;
import org.folio.ActionProfile;
import org.folio.Authority;
import org.folio.DataImportEventPayload;
@@ -28,9 +30,12 @@
import org.folio.rest.jaxrs.model.ParsedRecord;
import org.folio.rest.jaxrs.model.ProfileSnapshotWrapper;
import org.folio.rest.jaxrs.model.Record;
+import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -70,11 +75,13 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+@RunWith(Parameterized.class)
public class UpdateAuthorityEventHandlerTest {
private static final String MAPPING_RULES_PATH = "src/test/resources/handlers/marc-authority-rules.json";
private static final String PARSED_AUTHORITY_RECORD = "src/test/resources/marc/authority/parsed-authority-record.json";
private static final String MAPPING_METADATA_URL = "/mapping-metadata";
+ private final boolean isAuthorityExtended;
private final Vertx vertx = Vertx.vertx();
@Rule
@@ -112,6 +119,15 @@ public class UpdateAuthorityEventHandlerTest {
private UpdateAuthorityEventHandler eventHandler;
+ public UpdateAuthorityEventHandlerTest(boolean isAuthorityExtended) {
+ this.isAuthorityExtended = isAuthorityExtended;
+ }
+
+ @Parameterized.Parameters
+ public static Collection