From e450f3f6d64e585ba641039f3aba82b287e0da34 Mon Sep 17 00:00:00 2001 From: Saba-Zedginidze-EPAM <148070844+Saba-Zedginidze-EPAM@users.noreply.github.com> Date: Thu, 29 Aug 2024 18:41:29 +0400 Subject: [PATCH 1/7] [MODINV-1070] Modify TenantItems response schema (#759) * [MODINV-1070] Modify TenantItems response schema * [MODINV-1070] Fix failing test * [MODINV-1070] Remove unused import * [MODINV-1070] Remove unused import --- pom.xml | 1 + ramls/tenantItemResponse.json | 20 ++++++++++++ .../inventory/resources/TenantItems.java | 32 +++++++++---------- .../java/api/items/TenantItemApiTests.java | 10 +++--- 4 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 ramls/tenantItemResponse.json 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/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/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/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; From 8e019f94811b1af87d2e5475d12b9a050d105d0b Mon Sep 17 00:00:00 2001 From: SvitlanaKovalova1 Date: Fri, 30 Aug 2024 13:43:39 +0300 Subject: [PATCH 2/7] feat(instance-date-type-fields): add new date type fields to Instance schema (#758) --- NEWS.md | 1 + descriptors/ModuleDescriptor-template.json | 4 +- ramls/instance.json | 21 ++++++ .../config/InventoryConfigurationImpl.java | 3 +- .../inventory/domain/instances/Dates.java | 42 +++++++++++ .../inventory/domain/instances/Instance.java | 20 ++++- src/test/java/api/InstancesApiExamples.java | 24 +++++- .../inventory/domain/instances/DatesTest.java | 74 +++++++++++++++++++ 8 files changed, 182 insertions(+), 7 deletions(-) create mode 100644 src/main/java/org/folio/inventory/domain/instances/Dates.java create mode 100644 src/test/java/org/folio/inventory/domain/instances/DatesTest.java diff --git a/NEWS.md b/NEWS.md index 27a7f4fb7..bf365f805 100644 --- a/NEWS.md +++ b/NEWS.md @@ -20,6 +20,7 @@ * 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) ## 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/descriptors/ModuleDescriptor-template.json b/descriptors/ModuleDescriptor-template.json index 5bc3ee80b..cea866adc 100644 --- a/descriptors/ModuleDescriptor-template.json +++ b/descriptors/ModuleDescriptor-template.json @@ -4,7 +4,7 @@ "provides": [ { "id": "inventory", - "version": "13.1", + "version": "13.2", "handlers": [ { "methods": ["GET"], @@ -602,7 +602,7 @@ }, { "id": "instance-storage", - "version": "10.0" + "version": "10.2" }, { "id": "instance-storage-batch", 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/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/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/test/java/api/InstancesApiExamples.java b/src/test/java/api/InstancesApiExamples.java index c33a7bb76..a9c25c8de 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,6 +45,7 @@ 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.titles.PrecedingSucceedingTitle; import org.folio.inventory.support.JsonArrayHelper; @@ -63,6 +69,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 +102,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 +171,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 @@ -392,6 +407,7 @@ public void canUpdateAnExistingInstance() 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,6 +415,7 @@ 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())); @@ -434,6 +451,11 @@ 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)); } @Test @@ -612,7 +634,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/org/folio/inventory/domain/instances/DatesTest.java b/src/test/java/org/folio/inventory/domain/instances/DatesTest.java new file mode 100644 index 000000000..770ea1b40 --- /dev/null +++ b/src/test/java/org/folio/inventory/domain/instances/DatesTest.java @@ -0,0 +1,74 @@ +package org.folio.inventory.domain.instances; + +import io.vertx.core.json.JsonObject; +import junitparams.JUnitParamsRunner; +import junitparams.Parameters; +import junitparams.converters.Nullable; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.folio.inventory.domain.instances.Dates.datesFromJson; +import static org.folio.inventory.domain.instances.Dates.datesToJson; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; + +@RunWith(JUnitParamsRunner.class) +public class DatesTest { + + @Parameters({ + "1, 1990, 2002", + "1, 1990, null", + "1, null, 2022", + "null, 1990, 2002", + "null, 1990, null", + }) + @Test + public void shouldCreateDatesFromJson(@Nullable String dateTypeId, @Nullable String date1, @Nullable String date2) { + var dates = datesFromJson(datesJson(dateTypeId, date1, date2)); + + assertThat(dates.getDateTypeId(), is(dateTypeId)); + assertThat(dates.getDate1(), is(date1)); + assertThat(dates.getDate2(), is(date2)); + } + + @Test + public void shouldNotCreateDatesFromJsonWhenJsonIsNull() { + assertThat(datesFromJson(null), nullValue()); + } + + @Test + public void shouldNotCreateDatesFromJsonWhenAllFieldsAreNull() { + assertThat(datesFromJson(datesJson(null, null, null)), nullValue()); + } + + @Parameters({ + "1, 1990, 2002", + "1, 1990, null", + "1, null, 2022", + "null, 1990, 2002", + "null, 1990, null", + }) + @Test + public void shouldConvertDatesToJson(@Nullable String dateTypeId, @Nullable String date1, @Nullable String date2) { + var json = datesToJson(new Dates(dateTypeId, date1, date2)); + + assertThat(json.getString("dateTypeId"), is(dateTypeId)); + assertThat(json.getString("date1"), is(date1)); + assertThat(json.getString("date2"), is(date2)); + } + + @Test + public void shouldNotConvertDatesToJsonWhenItIsNull() { + assertThat(datesToJson(null), nullValue()); + } + + @Test + public void shouldNotConvertDatesToJsonWhenAllFieldsAreNull() { + assertThat(datesToJson(new Dates(null, null, null)), nullValue()); + } + + private JsonObject datesJson(String dateTypeId, String date1, String date2) { + return new JsonObject().put("dateTypeId", dateTypeId).put("date1", date1).put("date2", date2); + } +} From 6a37749c98d060e09f5489fefab243f7f4286c19 Mon Sep 17 00:00:00 2001 From: Javokhir Abdullaev <101543142+JavokhirAbdullayev@users.noreply.github.com> Date: Tue, 3 Sep 2024 16:42:45 +0500 Subject: [PATCH 3/7] MODINV-1069 Fix DataImportConsumerVerticleTest in mod-inventory and Fix NPE in HoldingsItemMatcher (#757) * Fix DataImportConsumerVerticleTest in mod-inventory and Fix NPE in HoldingsItemMatcher * Fix DataImportConsumerVerticleTest in mod-inventory and Fix NPE in HoldingsItemMatcher * small fix * small fix --- .../handlers/matching/loaders/HoldingLoader.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) 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); } From 890d389941d3158f0d45b178e755bdb4ad4baa16 Mon Sep 17 00:00:00 2001 From: Pavel Bobylev <131748689+PBobylev@users.noreply.github.com> Date: Thu, 5 Sep 2024 12:31:23 +0500 Subject: [PATCH 4/7] MODINV-1066: Update mapping for "sourceRecordIdentifier" property in "instance_ingress" event (#754) --- .../handler/InstanceIngressEventHandler.java | 9 +++++++-- ...reateInstanceIngressEventHandlerUnitTest.java | 16 ++++++++-------- ...pdateInstanceIngressEventHandlerUnitTest.java | 15 ++++++++------- 3 files changed, 23 insertions(+), 17 deletions(-) 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/test/java/org/folio/inventory/instanceingress/handler/CreateInstanceIngressEventHandlerUnitTest.java b/src/test/java/org/folio/inventory/instanceingress/handler/CreateInstanceIngressEventHandlerUnitTest.java index 01dbce3ea..701f1350e 100644 --- a/src/test/java/org/folio/inventory/instanceingress/handler/CreateInstanceIngressEventHandlerUnitTest.java +++ b/src/test/java/org/folio/inventory/instanceingress/handler/CreateInstanceIngressEventHandlerUnitTest.java @@ -330,14 +330,16 @@ public void shouldReturnFailedFuture_ifItsFailedToCreateMarcRecordInSrs() throws @Test public void shouldReturnSucceededFuture_ifProcessFinishedCorrectly() throws IOException, ExecutionException, InterruptedException { // given - var linkedDataIdId = "someLinkedDataIdId"; + var linkedDataId = "someLinkedDataId"; + var instanceId = "someInstanceId"; var event = new InstanceIngressEvent() .withId(UUID.randomUUID().toString()) .withEventPayload(new InstanceIngressPayload() .withSourceRecordObject(TestUtil.readFileFromPath(BIB_RECORD_PATH)) .withSourceType(LINKED_DATA) .withSourceRecordIdentifier(UUID.randomUUID().toString()) - .withAdditionalProperty("linkedDataId", linkedDataIdId) + .withAdditionalProperty("linkedDataId", linkedDataId) + .withAdditionalProperty("instanceId", instanceId) ); doReturn(succeededFuture(null)).when(idStorageService).store(anyString(), anyString(), anyString()); var mappingRules = new JsonObject(TestUtil.readFileFromPath(MAPPING_RULES_PATH)); @@ -365,18 +367,16 @@ public void shouldReturnSucceededFuture_ifProcessFinishedCorrectly() throws IOEx assertThat(future.isDone()).isTrue(); var instance = future.get(); - assertThat(instance.getId()).isEqualTo(event.getEventPayload().getSourceRecordIdentifier()); + assertThat(instance.getId()).isEqualTo(instanceId); assertThat(instance.getSource()).isEqualTo("LINKED_DATA"); - assertThat(instance.getIdentifiers().stream().anyMatch(i -> i.value.equals("(ld) " + linkedDataIdId))).isTrue(); + assertThat(instance.getIdentifiers().stream().anyMatch(i -> i.value.equals("(ld) " + linkedDataId))).isTrue(); var recordCaptor = ArgumentCaptor.forClass(Record.class); verify(sourceStorageClient).postSourceStorageRecords(recordCaptor.capture()); var recordSentToSRS = recordCaptor.getValue(); - assertThat(recordSentToSRS.getId()).isNotNull(); - assertThat(recordSentToSRS.getId()).isNotEqualTo(event.getEventPayload().getSourceRecordIdentifier()); - assertThat(recordSentToSRS.getId()).doesNotContain(linkedDataIdId); + assertThat(recordSentToSRS.getId()).isEqualTo(event.getEventPayload().getSourceRecordIdentifier()); assertThat(recordSentToSRS.getRecordType()).isEqualTo(Record.RecordType.MARC_BIB); assertThat(AdditionalFieldsUtil.getValue(recordSentToSRS, TAG_999, SUBFIELD_I)).hasValue(instance.getId()); - assertThat(AdditionalFieldsUtil.getValue(recordSentToSRS, TAG_999, SUBFIELD_L)).hasValue(linkedDataIdId); + assertThat(AdditionalFieldsUtil.getValue(recordSentToSRS, TAG_999, SUBFIELD_L)).hasValue(linkedDataId); } } diff --git a/src/test/java/org/folio/inventory/instanceingress/handler/UpdateInstanceIngressEventHandlerUnitTest.java b/src/test/java/org/folio/inventory/instanceingress/handler/UpdateInstanceIngressEventHandlerUnitTest.java index 51a4c80c7..0c9afb4be 100644 --- a/src/test/java/org/folio/inventory/instanceingress/handler/UpdateInstanceIngressEventHandlerUnitTest.java +++ b/src/test/java/org/folio/inventory/instanceingress/handler/UpdateInstanceIngressEventHandlerUnitTest.java @@ -490,14 +490,16 @@ public void shouldReturnFailedFuture_ifCreatePrecedingSucceedingTitlesFailed() t @Test public void shouldReturnSucceededFuture_ifProcessFinishedCorrectly() throws IOException, ExecutionException, InterruptedException { // given - var linkedDataIdId = "someLinkedDataIdId"; + var linkedDataId = "someLinkedDataId"; + var instanceId = "instanceId"; var event = new InstanceIngressEvent() .withId(UUID.randomUUID().toString()) .withEventPayload(new InstanceIngressPayload() .withSourceRecordObject(TestUtil.readFileFromPath(BIB_RECORD_PATH)) .withSourceType(LINKED_DATA) .withSourceRecordIdentifier(UUID.randomUUID().toString()) - .withAdditionalProperty("linkedDataId", linkedDataIdId) + .withAdditionalProperty("linkedDataId", linkedDataId) + .withAdditionalProperty("instanceId", instanceId) ); var mappingRules = new JsonObject(TestUtil.readFileFromPath(MAPPING_RULES_PATH)); doReturn(succeededFuture(Optional.of(new MappingMetadataDto() @@ -537,10 +539,10 @@ public void shouldReturnSucceededFuture_ifProcessFinishedCorrectly() throws IOEx assertThat(future.isDone()).isTrue(); var instance = future.get(); - assertThat(instance.getId()).isEqualTo(event.getEventPayload().getSourceRecordIdentifier()); + assertThat(instance.getId()).isEqualTo(instanceId); assertThat(instance.getHrid()).isEqualTo(existedInstance.getHrid()); assertThat(instance.getSource()).isEqualTo("LINKED_DATA"); - assertThat(instance.getIdentifiers().stream().anyMatch(i -> i.value.equals("(ld) " + linkedDataIdId))).isTrue(); + assertThat(instance.getIdentifiers().stream().anyMatch(i -> i.value.equals("(ld) " + linkedDataId))).isTrue(); var recordCaptor = ArgumentCaptor.forClass(Record.class); verify(sourceStorageClient).putSourceStorageRecordsGenerationById(eq(previousSrsId), recordCaptor.capture()); @@ -548,11 +550,10 @@ public void shouldReturnSucceededFuture_ifProcessFinishedCorrectly() throws IOEx assertThat(recordSentToSRS.getId()).isNotNull(); assertThat(recordSentToSRS.getId()).isNotEqualTo(previousSrsId); assertThat(recordSentToSRS.getMatchedId()).isEqualTo(previousSrsId); - assertThat(recordSentToSRS.getId()).isNotEqualTo(event.getEventPayload().getSourceRecordIdentifier()); - assertThat(recordSentToSRS.getId()).doesNotContain(linkedDataIdId); + assertThat(recordSentToSRS.getId()).isEqualTo(event.getEventPayload().getSourceRecordIdentifier()); assertThat(recordSentToSRS.getRecordType()).isEqualTo(Record.RecordType.MARC_BIB); assertThat(AdditionalFieldsUtil.getValue(recordSentToSRS, TAG_999, SUBFIELD_I)).hasValue(instance.getId()); - assertThat(AdditionalFieldsUtil.getValue(recordSentToSRS, TAG_999, SUBFIELD_L)).hasValue(linkedDataIdId); + assertThat(AdditionalFieldsUtil.getValue(recordSentToSRS, TAG_999, SUBFIELD_L)).hasValue(linkedDataId); } } From 271d4e88dc96b4ce80de2469166c2ee0d87a120f Mon Sep 17 00:00:00 2001 From: RomanChernetskyi <111740564+RomanChernetskyi@users.noreply.github.com> Date: Mon, 9 Sep 2024 14:06:06 +0300 Subject: [PATCH 5/7] [MODINVSTOR-1253] Add user-tenants.collection.get to all ECS APIs (#763) --- descriptors/ModuleDescriptor-template.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/descriptors/ModuleDescriptor-template.json b/descriptors/ModuleDescriptor-template.json index cea866adc..a062e86ac 100644 --- a/descriptors/ModuleDescriptor-template.json +++ b/descriptors/ModuleDescriptor-template.json @@ -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" ] } ] From 41a10ffb4e6c4930d3c1e9f65e1c48914196acfc Mon Sep 17 00:00:00 2001 From: Dmytro Krutii Date: Mon, 9 Sep 2024 14:37:27 +0300 Subject: [PATCH 6/7] MODINVSTOR-1205 Add subjectTypeId and subjectSourceId to instance --- descriptors/ModuleDescriptor-template.json | 4 +-- .../inventory/domain/instances/Subject.java | 27 ++++++++++++++++--- src/test/java/api/InstancesApiExamples.java | 14 +++++++++- 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/descriptors/ModuleDescriptor-template.json b/descriptors/ModuleDescriptor-template.json index a062e86ac..8ca1eef80 100644 --- a/descriptors/ModuleDescriptor-template.json +++ b/descriptors/ModuleDescriptor-template.json @@ -4,7 +4,7 @@ "provides": [ { "id": "inventory", - "version": "13.2", + "version": "13.3", "handlers": [ { "methods": ["GET"], @@ -604,7 +604,7 @@ }, { "id": "instance-storage", - "version": "10.2" + "version": "10.3" }, { "id": "instance-storage-batch", 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/test/java/api/InstancesApiExamples.java b/src/test/java/api/InstancesApiExamples.java index a9c25c8de..fd41b36ea 100644 --- a/src/test/java/api/InstancesApiExamples.java +++ b/src/test/java/api/InstancesApiExamples.java @@ -47,6 +47,7 @@ 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; @@ -402,6 +403,8 @@ public void canUpdateAnExistingInstance() ExecutionException { UUID id = UUID.randomUUID(); + final var sourceId = "sourceId"; + final var typeId = "typeId"; JsonObject smallAngryPlanet = smallAngryPlanet(id); smallAngryPlanet.put("natureOfContentTermIds", @@ -417,7 +420,10 @@ public void canUpdateAnExistingInstance() .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"))); @@ -456,6 +462,12 @@ public void canUpdateAnExistingInstance() 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 From 39ad7d188213a78bce5ab2f2db5bb0d7f0529d8e Mon Sep 17 00:00:00 2001 From: elena-shmygaliova Date: Thu, 12 Sep 2024 12:22:40 +0300 Subject: [PATCH 7/7] MODDINV-1071: Extended Authority Mapping (#762) * MODDINV-1071: Extended Authority Mapping * MODDINV-1071: Extended Authority Mapping * MODDINV-1071: Extended Authority Mapping * MODDINV-1071: Extended Authority Mapping * MODDINV-1071: Extended Authority Mapping --------- Co-authored-by: ElenaShm --- NEWS.md | 1 + README.MD | 12 ++++++++++ .../AbstractAuthorityEventHandler.java | 22 +++++++++++++++++- .../UpdateAuthorityEventHandlerTest.java | 23 +++++++++++++++++++ 4 files changed, 57 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index bf365f805..ebb154b4a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -21,6 +21,7 @@ * 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/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/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 data() { + return Arrays.asList(new Object[][]{{true}, {false}}); + } + @Before public void setUp() throws IOException { MockitoAnnotations.openMocks(this); @@ -130,6 +146,13 @@ public void setUp() throws IOException { .willReturn(WireMock.ok().withBody(Json.encode(new MappingMetadataDto() .withMappingParams(Json.encode(new MappingParameters())) .withMappingRules(mappingRules.encode()))))); + + AbstractAuthorityEventHandler.setAuthorityExtendedMode(isAuthorityExtended); + } + + @After + public void tearDown() { + AbstractAuthorityEventHandler.setAuthorityExtendedMode(false); } @Test