diff --git a/NEWS.md b/NEWS.md index 069118385..7169f3bfb 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,6 @@ ## 20.2.7 2024-06-26 * [MODDATAIMP-1046](https://folio-org.atlassian.net/browse/MODDATAIMP-1046) Reorder only 00X fields while preserving system order for all other +* [MODINV-1071](https://folio-org.atlassian.net/browse/MODINV-1071) Extend Authority with Additional fields ## 20.2.6 2024-05-29 * [MODDATAIMP-1052](https://folio-org.atlassian.net/browse/MODDATAIMP-1052) Fix editing shared Instance via quickMARC from Member tenant diff --git a/README.MD b/README.MD index 71fa0e31b..3cca808c7 100644 --- a/README.MD +++ b/README.MD @@ -129,6 +129,19 @@ 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) +* saft*Trunc for every saft* field with "i" and numeric subfields excluded + +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/pom.xml b/pom.xml index 7bac3c06e..b26ef60d3 100644 --- a/pom.xml +++ b/pom.xml @@ -321,7 +321,7 @@ 4.9.1 3.1.0 4.13.2 - 4.2.0 + 4.2.5-LOC-SNAPSHOT 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 ed807c71c..8fcbe808d 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,9 +55,11 @@ 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; + public static boolean isAuthorityExtended = isAuthorityExtendedMode(); protected AbstractAuthorityEventHandler(Storage storage, MappingMetadataCache mappingMetadataCache) { this.storage = storage; @@ -161,7 +164,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 +220,21 @@ 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; + } + public static boolean getIsAuthorityExtended() { + return isAuthorityExtended; + } } diff --git a/src/main/java/org/folio/inventory/dataimport/handlers/actions/AuthorityUpdateDelegate.java b/src/main/java/org/folio/inventory/dataimport/handlers/actions/AuthorityUpdateDelegate.java index 418ad7083..1358ae93a 100644 --- a/src/main/java/org/folio/inventory/dataimport/handlers/actions/AuthorityUpdateDelegate.java +++ b/src/main/java/org/folio/inventory/dataimport/handlers/actions/AuthorityUpdateDelegate.java @@ -6,6 +6,7 @@ import org.apache.http.HttpStatus; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.folio.ActionProfile.FolioRecord; import org.folio.Authority; import org.folio.inventory.common.Context; import org.folio.inventory.dataimport.exceptions.DataImportException; @@ -21,6 +22,7 @@ import java.util.Map; import static java.lang.String.format; +import static org.folio.inventory.dataimport.handlers.actions.AbstractAuthorityEventHandler.getIsAuthorityExtended; import static org.folio.inventory.dataimport.util.LoggerUtil.logParametersUpdateDelegate; public class AuthorityUpdateDelegate { @@ -48,7 +50,9 @@ public Future handle(Map eventPayload, Record marcRec JsonObject parsedRecord = retrieveParsedContent(marcRecord.getParsedRecord()); String authorityId = marcRecord.getExternalIdsHolder().getAuthorityId(); LOGGER.info("Authority update with authorityId: {}", authorityId); - RecordMapper recordMapper = RecordMapperBuilder.buildMapper(MARC_FORMAT); + RecordMapper recordMapper = getIsAuthorityExtended() + ? RecordMapperBuilder.buildMapper(FolioRecord.MARC_AUTHORITY_EXTENDED.value()) + : RecordMapperBuilder.buildMapper(MARC_FORMAT); var mappedAuthority = recordMapper.mapRecord(parsedRecord, mappingParameters, mappingRules); AuthorityRecordCollection authorityRecordCollection = storage.getAuthorityRecordCollection(context); 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 8a32d72c2..0a2f6b568 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 diff --git a/src/test/java/org/folio/inventory/eventhandlers/UpdateAuthorityQuickMarcEventHandlerTest.java b/src/test/java/org/folio/inventory/eventhandlers/UpdateAuthorityQuickMarcEventHandlerTest.java index 75c8e1a8b..d32446c2b 100644 --- a/src/test/java/org/folio/inventory/eventhandlers/UpdateAuthorityQuickMarcEventHandlerTest.java +++ b/src/test/java/org/folio/inventory/eventhandlers/UpdateAuthorityQuickMarcEventHandlerTest.java @@ -12,15 +12,19 @@ import io.vertx.core.Future; import io.vertx.core.json.JsonObject; +import junitparams.JUnitParamsRunner; +import junitparams.Parameters; import org.folio.inventory.dataimport.exceptions.OptimisticLockingException; +import org.folio.inventory.dataimport.handlers.actions.AbstractAuthorityEventHandler; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnit; import org.folio.Authority; import org.folio.inventory.TestUtil; @@ -31,8 +35,9 @@ import org.folio.inventory.dataimport.handlers.quickmarc.UpdateAuthorityQuickMarcEventHandler; import org.folio.inventory.domain.AuthorityRecordCollection; import org.folio.inventory.storage.Storage; +import org.mockito.junit.MockitoRule; -@RunWith(MockitoJUnitRunner.class) +@RunWith(JUnitParamsRunner.class) public class UpdateAuthorityQuickMarcEventHandlerTest { private static final String MAPPING_RULES_PATH = "src/test/resources/handlers/authority-rules.json"; @@ -54,6 +59,9 @@ public class UpdateAuthorityQuickMarcEventHandlerTest { private JsonObject record; private Authority existingAuthority; + @Rule + public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Before public void setUp() throws IOException { existingAuthority = new JsonObject(TestUtil.readFileFromPath(AUTHORITY_PATH)).mapTo(Authority.class); @@ -83,7 +91,9 @@ record = new JsonObject(TestUtil.readFileFromPath(RECORD_PATH)); } @Test - public void shouldProcessEvent() { + @Parameters({"true", "false"}) + public void shouldProcessEvent(String isAuthorityExtendedMode) { + AbstractAuthorityEventHandler.setAuthorityExtendedMode(Boolean.parseBoolean(isAuthorityExtendedMode)); HashMap eventPayload = new HashMap<>(); eventPayload.put("RECORD_TYPE", "MARC_AUTHORITY"); eventPayload.put("MARC_AUTHORITY", record.encode()); @@ -107,6 +117,7 @@ public void shouldProcessEvent() { Assert.assertEquals("token", argument.getValue().getToken()); Assert.assertEquals("dummy", argument.getValue().getTenantId()); Assert.assertEquals("http://localhost", argument.getValue().getOkapiLocation()); + AbstractAuthorityEventHandler.setAuthorityExtendedMode(false); } @Test