Search in sources :

Example 1 with Failure

use of org.folio.inventory.common.domain.Failure in project mod-inventory by folio-org.

the class UpdateHoldingEventHandler method handle.

@Override
public CompletableFuture<DataImportEventPayload> handle(DataImportEventPayload dataImportEventPayload) {
    CompletableFuture<DataImportEventPayload> future = new CompletableFuture<>();
    try {
        dataImportEventPayload.setEventType(DI_INVENTORY_HOLDING_UPDATED.value());
        if (dataImportEventPayload.getContext() == null || isEmpty(dataImportEventPayload.getContext().get(HOLDINGS.value())) || isEmpty(dataImportEventPayload.getContext().get(MARC_BIBLIOGRAPHIC.value()))) {
            throw new EventProcessingException(CONTEXT_EMPTY_ERROR_MESSAGE);
        }
        if (dataImportEventPayload.getCurrentNode().getChildSnapshotWrappers().isEmpty()) {
            LOGGER.error(ACTION_HAS_NO_MAPPING_MSG);
            return CompletableFuture.failedFuture(new EventProcessingException(ACTION_HAS_NO_MAPPING_MSG));
        }
        LOGGER.info("Processing UpdateHoldingEventHandler starting with jobExecutionId: {}.", dataImportEventPayload.getJobExecutionId());
        HoldingsRecord tmpHoldingsRecord = retrieveHolding(dataImportEventPayload.getContext());
        String holdingId = tmpHoldingsRecord.getId();
        String hrid = tmpHoldingsRecord.getHrid();
        String instanceId = tmpHoldingsRecord.getInstanceId();
        String permanentLocationId = tmpHoldingsRecord.getPermanentLocationId();
        if (StringUtils.isAnyBlank(hrid, instanceId, permanentLocationId, holdingId)) {
            throw new EventProcessingException(EMPTY_REQUIRED_FIELDS_ERROR_MESSAGE);
        }
        Context context = constructContext(dataImportEventPayload.getTenant(), dataImportEventPayload.getToken(), dataImportEventPayload.getOkapiUrl());
        String jobExecutionId = dataImportEventPayload.getJobExecutionId();
        String recordId = dataImportEventPayload.getContext().get(RECORD_ID_HEADER);
        String chunkId = dataImportEventPayload.getContext().get(CHUNK_ID_HEADER);
        mappingMetadataCache.get(jobExecutionId, context).map(parametersOptional -> parametersOptional.orElseThrow(() -> new EventProcessingException(format(MAPPING_METADATA_NOT_FOUND_MESSAGE, jobExecutionId, recordId, chunkId)))).onSuccess(mappingMetadataDto -> {
            prepareEvent(dataImportEventPayload);
            MappingParameters mappingParameters = Json.decodeValue(mappingMetadataDto.getMappingParams(), MappingParameters.class);
            MappingManager.map(dataImportEventPayload, new MappingContext().withMappingParameters(mappingParameters));
            HoldingsRecordCollection holdingsRecords = storage.getHoldingsRecordCollection(context);
            HoldingsRecord holding = retrieveHolding(dataImportEventPayload.getContext());
            holdingsRecords.update(holding, holdingSuccess -> constructDataImportEventPayload(future, dataImportEventPayload, holding), failure -> {
                if (failure.getStatusCode() == HttpStatus.SC_CONFLICT) {
                    processOLError(dataImportEventPayload, future, holdingsRecords, holding, failure);
                } else {
                    dataImportEventPayload.getContext().remove(CURRENT_RETRY_NUMBER);
                    LOGGER.error(format(CANNOT_UPDATE_HOLDING_ERROR_MESSAGE, holding.getId(), jobExecutionId, recordId, chunkId, failure.getReason(), failure.getStatusCode()));
                    future.completeExceptionally(new EventProcessingException(format(UPDATE_HOLDING_ERROR_MESSAGE, jobExecutionId, recordId, chunkId)));
                }
            });
        }).onFailure(e -> {
            LOGGER.error("Error updating inventory Holdings by jobExecutionId: '{}'", jobExecutionId, e);
            future.completeExceptionally(e);
        });
    } catch (Exception e) {
        LOGGER.error("Failed to update Holdings", e);
        future.completeExceptionally(e);
    }
    return future;
}
Also used : Context(org.folio.inventory.common.Context) EventHandlingUtil.constructContext(org.folio.inventory.dataimport.handlers.matching.util.EventHandlingUtil.constructContext) MappingContext(org.folio.processing.mapping.mapper.MappingContext) Json(io.vertx.core.json.Json) Context(org.folio.inventory.common.Context) EventHandler(org.folio.processing.events.services.handler.EventHandler) MappingManager(org.folio.processing.mapping.MappingManager) HttpStatus(org.apache.http.HttpStatus) Failure(org.folio.inventory.common.domain.Failure) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) ACTION_PROFILE(org.folio.rest.jaxrs.model.ProfileSnapshotWrapper.ContentType.ACTION_PROFILE) StringUtils(org.apache.commons.lang3.StringUtils) EventHandlingUtil.constructContext(org.folio.inventory.dataimport.handlers.matching.util.EventHandlingUtil.constructContext) HOLDINGS(org.folio.ActionProfile.FolioRecord.HOLDINGS) HoldingsRecordCollection(org.folio.inventory.domain.HoldingsRecordCollection) ProfileSnapshotWrapper(org.folio.rest.jaxrs.model.ProfileSnapshotWrapper) ObjectMapperTool(org.folio.dbschema.ObjectMapperTool) JsonObject(io.vertx.core.json.JsonObject) Objects.isNull(java.util.Objects.isNull) ActionProfile(org.folio.ActionProfile) StringUtils.isEmpty(org.apache.commons.lang3.StringUtils.isEmpty) MappingParameters(org.folio.processing.mapping.defaultmapper.processor.parameters.MappingParameters) MARC_BIBLIOGRAPHIC(org.folio.ActionProfile.FolioRecord.MARC_BIBLIOGRAPHIC) MappingContext(org.folio.processing.mapping.mapper.MappingContext) DataImportEventPayload(org.folio.DataImportEventPayload) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) HoldingsRecord(org.folio.HoldingsRecord) String.format(java.lang.String.format) DI_INVENTORY_HOLDING_UPDATED(org.folio.DataImportEventTypes.DI_INVENTORY_HOLDING_UPDATED) Storage(org.folio.inventory.storage.Storage) UPDATE(org.folio.ActionProfile.Action.UPDATE) Logger(org.apache.logging.log4j.Logger) EventProcessingException(org.folio.processing.exceptions.EventProcessingException) LogManager(org.apache.logging.log4j.LogManager) MappingMetadataCache(org.folio.inventory.dataimport.cache.MappingMetadataCache) MappingContext(org.folio.processing.mapping.mapper.MappingContext) HoldingsRecord(org.folio.HoldingsRecord) CompletableFuture(java.util.concurrent.CompletableFuture) HoldingsRecordCollection(org.folio.inventory.domain.HoldingsRecordCollection) MappingParameters(org.folio.processing.mapping.defaultmapper.processor.parameters.MappingParameters) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) EventProcessingException(org.folio.processing.exceptions.EventProcessingException) DataImportEventPayload(org.folio.DataImportEventPayload) EventProcessingException(org.folio.processing.exceptions.EventProcessingException)

Example 2 with Failure

use of org.folio.inventory.common.domain.Failure in project mod-inventory by folio-org.

the class ExternalStorageModuleCollection method findById.

public void findById(String id, Consumer<Success<T>> resultCallback, Consumer<Failure> failureCallback) {
    final var futureResponse = new CompletableFuture<AsyncResult<HttpResponse<Buffer>>>();
    final HttpRequest<Buffer> request = withStandardHeaders(webClient.getAbs(individualRecordLocation(id)));
    request.send(futureResponse::complete);
    futureResponse.thenCompose(this::mapAsyncResultToCompletionStage).thenAccept(response -> {
        switch(response.getStatusCode()) {
            case 200:
                JsonObject instanceFromServer = response.getJson();
                try {
                    T found = mapFromJson(instanceFromServer);
                    resultCallback.accept(new Success<>(found));
                    break;
                } catch (Exception e) {
                    LOGGER.error(e);
                    failureCallback.accept(new Failure(e.getMessage(), 500));
                    break;
                }
            case 404:
                resultCallback.accept(new Success<>(null));
                break;
            default:
                failureCallback.accept(new Failure(response.getBody(), response.getStatusCode()));
        }
    });
}
Also used : Buffer(io.vertx.core.buffer.Buffer) CompletableFuture(java.util.concurrent.CompletableFuture) ACCEPT(org.apache.http.HttpHeaders.ACCEPT) HttpResponse(io.vertx.ext.web.client.HttpResponse) JsonObject(io.vertx.core.json.JsonObject) Failure(org.folio.inventory.common.domain.Failure)

Example 3 with Failure

use of org.folio.inventory.common.domain.Failure in project mod-inventory by folio-org.

the class MatchInstanceEventHandlerUnitTest method shouldFailOnHandleEventPayloadIfFailedCallToInventoryStorage.

@Test
public void shouldFailOnHandleEventPayloadIfFailedCallToInventoryStorage(TestContext testContext) throws UnsupportedEncodingException {
    Async async = testContext.async();
    doAnswer(ans -> {
        Consumer<Failure> callback = ans.getArgument(3);
        Failure result = new Failure("Internal Server Error", 500);
        callback.accept(result);
        return null;
    }).when(instanceCollection).findByCql(anyString(), any(PagingParameters.class), any(Consumer.class), any(Consumer.class));
    EventHandler eventHandler = new MatchInstanceEventHandler(mappingMetadataCache);
    DataImportEventPayload eventPayload = createEventPayload();
    eventHandler.handle(eventPayload).whenComplete((updatedEventPayload, throwable) -> {
        testContext.assertNotNull(throwable);
        async.complete();
    });
}
Also used : PagingParameters(org.folio.inventory.common.api.request.PagingParameters) Consumer(java.util.function.Consumer) Async(io.vertx.ext.unit.Async) MatchInstanceEventHandler(org.folio.inventory.dataimport.handlers.matching.MatchInstanceEventHandler) EventHandler(org.folio.processing.events.services.handler.EventHandler) MatchInstanceEventHandler(org.folio.inventory.dataimport.handlers.matching.MatchInstanceEventHandler) Failure(org.folio.inventory.common.domain.Failure) DataImportEventPayload(org.folio.DataImportEventPayload) Test(org.junit.Test)

Example 4 with Failure

use of org.folio.inventory.common.domain.Failure in project mod-inventory by folio-org.

the class CreateItemEventHandlerTest method shouldReturnFailedFutureIfInventoryStorageErrorExists.

@Test(expected = ExecutionException.class)
public void shouldReturnFailedFutureIfInventoryStorageErrorExists() throws InterruptedException, ExecutionException, TimeoutException, UnsupportedEncodingException {
    // given
    RecordToEntity recordToItem = RecordToEntity.builder().recordId(RECORD_ID).entityId(ITEM_ID).build();
    when(itemIdStorageService.store(any(), any(), any())).thenReturn(Future.succeededFuture(recordToItem));
    Mockito.doAnswer(invocationOnMock -> {
        MultipleRecords<Item> result = new MultipleRecords<>(new ArrayList<>(), 0);
        Consumer<Success<MultipleRecords<Item>>> successHandler = invocationOnMock.getArgument(2);
        successHandler.accept(new Success<>(result));
        return null;
    }).when(mockedItemCollection).findByCql(anyString(), any(PagingParameters.class), any(Consumer.class), any(Consumer.class));
    doAnswer(invocationOnMock -> {
        Consumer<Failure> failureHandler = invocationOnMock.getArgument(2);
        failureHandler.accept(new Failure("Smth error", 400));
        return null;
    }).when(mockedItemCollection).add(any(), any(), any());
    MappingManager.registerReaderFactory(fakeReaderFactory);
    MappingManager.registerWriterFactory(new ItemWriterFactory());
    String expectedHoldingId = UUID.randomUUID().toString();
    JsonObject holdingAsJson = new JsonObject().put("id", expectedHoldingId);
    HashMap<String, String> payloadContext = new HashMap<>();
    payloadContext.put(EntityType.MARC_BIBLIOGRAPHIC.value(), Json.encode(new Record()));
    payloadContext.put(EntityType.HOLDINGS.value(), holdingAsJson.encode());
    DataImportEventPayload dataImportEventPayload = new DataImportEventPayload().withEventType(DI_SRS_MARC_BIB_RECORD_CREATED.value()).withJobExecutionId(UUID.randomUUID().toString()).withContext(payloadContext).withCurrentNode(profileSnapshotWrapper.getChildSnapshotWrappers().get(0));
    // when
    CompletableFuture<DataImportEventPayload> future = createItemHandler.handle(dataImportEventPayload);
    future.get(5, TimeUnit.SECONDS);
}
Also used : PagingParameters(org.folio.inventory.common.api.request.PagingParameters) HashMap(java.util.HashMap) JsonObject(io.vertx.core.json.JsonObject) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) ItemWriterFactory(org.folio.inventory.dataimport.ItemWriterFactory) RecordToEntity(org.folio.inventory.domain.relationship.RecordToEntity) Success(org.folio.inventory.common.domain.Success) DataImportEventPayload(org.folio.DataImportEventPayload) Item(org.folio.inventory.domain.items.Item) Consumer(java.util.function.Consumer) MultipleRecords(org.folio.inventory.common.domain.MultipleRecords) ParsedRecord(org.folio.rest.jaxrs.model.ParsedRecord) Record(org.folio.rest.jaxrs.model.Record) Failure(org.folio.inventory.common.domain.Failure) Test(org.junit.Test)

Example 5 with Failure

use of org.folio.inventory.common.domain.Failure in project mod-inventory by folio-org.

the class MatchAuthorityEventHandlerUnitTest method shouldFailOnHandleEventPayloadIfFailedCallToInventoryStorage.

@Test
public void shouldFailOnHandleEventPayloadIfFailedCallToInventoryStorage(TestContext testContext) throws UnsupportedEncodingException {
    Async async = testContext.async();
    MatchDetail personalNameMatchDetail = new MatchDetail().withMatchCriterion(EXACTLY_MATCHES).withExistingMatchExpression(new MatchExpression().withDataValueType(VALUE_FROM_RECORD).withFields(singletonList(new Field().withLabel("personalName").withValue("authority.personalName"))));
    DataImportEventPayload eventPayload = createEventPayload(personalNameMatchDetail);
    doAnswer(ans -> {
        Consumer<Failure> callback = ans.getArgument(3);
        Failure result = new Failure("Internal Server Error", 500);
        callback.accept(result);
        return null;
    }).when(collection).findByCql(anyString(), any(PagingParameters.class), any(Consumer.class), any(Consumer.class));
    EventHandler eventHandler = new MatchAuthorityEventHandler(mappingMetadataCache);
    eventHandler.handle(eventPayload).whenComplete((updatedEventPayload, throwable) -> {
        testContext.assertNotNull(throwable);
        async.complete();
    });
}
Also used : Field(org.folio.rest.jaxrs.model.Field) PagingParameters(org.folio.inventory.common.api.request.PagingParameters) Consumer(java.util.function.Consumer) Async(io.vertx.ext.unit.Async) MatchAuthorityEventHandler(org.folio.inventory.dataimport.handlers.matching.MatchAuthorityEventHandler) EventHandler(org.folio.processing.events.services.handler.EventHandler) MatchAuthorityEventHandler(org.folio.inventory.dataimport.handlers.matching.MatchAuthorityEventHandler) MatchDetail(org.folio.MatchDetail) MatchExpression(org.folio.rest.jaxrs.model.MatchExpression) Failure(org.folio.inventory.common.domain.Failure) DataImportEventPayload(org.folio.DataImportEventPayload) Test(org.junit.Test)

Aggregations

Failure (org.folio.inventory.common.domain.Failure)50 Test (org.junit.Test)44 CompletableFuture (java.util.concurrent.CompletableFuture)26 HashMap (java.util.HashMap)21 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)18 DataImportEventPayload (org.folio.DataImportEventPayload)17 JsonObject (io.vertx.core.json.JsonObject)16 PagingParameters (org.folio.inventory.common.api.request.PagingParameters)10 Record (org.folio.rest.jaxrs.model.Record)10 ParsedRecord (org.folio.rest.jaxrs.model.ParsedRecord)9 Async (io.vertx.ext.unit.Async)8 Consumer (java.util.function.Consumer)7 HoldingsRecord (org.folio.HoldingsRecord)7 AuthorityRecordCollection (org.folio.inventory.domain.AuthorityRecordCollection)7 InstanceCollection (org.folio.inventory.domain.instances.InstanceCollection)7 ItemCollection (org.folio.inventory.domain.items.ItemCollection)6 EventHandler (org.folio.processing.events.services.handler.EventHandler)6 MultipleRecords (org.folio.inventory.common.domain.MultipleRecords)4 Instance (org.folio.inventory.domain.instances.Instance)4 Reader (org.folio.processing.mapping.mapper.reader.Reader)4