diff --git a/src/main/java/org/folio/inventory/dataimport/handlers/matching/AbstractMatchEventHandler.java b/src/main/java/org/folio/inventory/dataimport/handlers/matching/AbstractMatchEventHandler.java index 6f24c32de..af75181cc 100644 --- a/src/main/java/org/folio/inventory/dataimport/handlers/matching/AbstractMatchEventHandler.java +++ b/src/main/java/org/folio/inventory/dataimport/handlers/matching/AbstractMatchEventHandler.java @@ -126,7 +126,8 @@ private CompletableFuture matchCentralTenantIfNeeded(DataImportEventPay return MatchingManager.match(dataImportEventPayload) .thenCompose(isMatchedConsortium -> { dataImportEventPayload.setTenant(context.getTenantId()); - if (Boolean.TRUE.equals(isMatchedConsortium) && isMatchedLocal && !isShadowEntity(localMatchedInstance, dataImportEventPayload.getContext().get(getEntityType().value()))) { + if (Boolean.TRUE.equals(isMatchedConsortium) && isMatchedLocal && localMatchedInstance != null + && !isShadowEntity(localMatchedInstance, dataImportEventPayload.getContext().get(getEntityType().value()))) { LOGGER.warn("matchCentralTenantIfNeeded:: Found multiple results during matching on local tenant: {} and central tenant: {} ", context.getTenantId(), consortiumConfiguration.get().getCentralTenantId()); return CompletableFuture.failedFuture(new MatchingException(String.format(FOUND_MULTIPLE_ENTITIES, context.getTenantId(), consortiumConfiguration.get().getCentralTenantId()))); diff --git a/src/test/java/org/folio/inventory/eventhandlers/MatchInstanceEventHandlerUnitTest.java b/src/test/java/org/folio/inventory/eventhandlers/MatchInstanceEventHandlerUnitTest.java index 3eb4a0c10..a445abb2e 100644 --- a/src/test/java/org/folio/inventory/eventhandlers/MatchInstanceEventHandlerUnitTest.java +++ b/src/test/java/org/folio/inventory/eventhandlers/MatchInstanceEventHandlerUnitTest.java @@ -742,21 +742,38 @@ public void shouldMatchWithSubConditionBasedOnMultiMatchResultOnHandleEventPaylo @Test public void shouldPutMultipleMatchResultToPayloadOnHandleEventPayload(TestContext testContext) throws UnsupportedEncodingException { + // Also covers the consortium case: when central tenant has shadow copies of the same instances, + // both sides return MULTI_MATCH_IDS and no "Found multiple entities" error should be thrown. Async async = testContext.async(); + + String centralTenantId = "consortium"; + String consortiumId = "consortiumId"; List matchedInstances = List.of( new Instance(UUID.randomUUID().toString(), 1, "in1", "MARC", "Wonderful", "12334"), new Instance(UUID.randomUUID().toString(), 1, "in2", "MARC", "Wonderful", "12334")); + doAnswer(inv -> Future.succeededFuture(Optional.of(new ConsortiumConfiguration(centralTenantId, consortiumId)))) + .when(consortiumService).getConsortiumConfiguration(any()); + + // Local: unscoped query -> 2 instances -> MULTI_MATCH_IDS doAnswer(invocation -> { Consumer>> successHandler = invocation.getArgument(2); - Success> result = - new Success<>(new MultipleRecords<>(matchedInstances, 2)); - successHandler.accept(result); + successHandler.accept(new Success<>(new MultipleRecords<>(matchedInstances, 2))); return null; }).when(instanceCollection) .findByCql(eq(format("hrid == \"%s\"", INSTANCE_HRID)), any(PagingParameters.class), any(Consumer.class), any(Consumer.class)); + // Central: same instances returned for the MULTI_MATCH_IDS-scoped query (shadow copies) + doAnswer(invocation -> { + Consumer>> successHandler = invocation.getArgument(2); + successHandler.accept(new Success<>(new MultipleRecords<>(matchedInstances, 2))); + return null; + }).when(instanceCollection) + .findByCql(eq(format("hrid == \"%s\" AND id == (%s OR %s)", INSTANCE_HRID, + matchedInstances.get(0).getId(), matchedInstances.get(1).getId())), + any(PagingParameters.class), any(Consumer.class), any(Consumer.class)); + MatchProfile subMatchProfile = new MatchProfile() .withExistingRecordType(INSTANCE) .withIncomingRecordType(MARC_BIBLIOGRAPHIC);