Search in sources :

Example 1 with MappingContext

use of org.folio.processing.mapping.mapper.MappingContext in project mod-inventory by folio-org.

the class CreateHoldingEventHandler method handle.

@Override
public CompletableFuture<DataImportEventPayload> handle(DataImportEventPayload dataImportEventPayload) {
    CompletableFuture<DataImportEventPayload> future = new CompletableFuture<>();
    try {
        dataImportEventPayload.setEventType(DI_INVENTORY_HOLDING_CREATED.value());
        HashMap<String, String> payloadContext = dataImportEventPayload.getContext();
        if (payloadContext == null || payloadContext.isEmpty() || StringUtils.isEmpty(payloadContext.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));
        }
        Context context = constructContext(dataImportEventPayload.getTenant(), dataImportEventPayload.getToken(), dataImportEventPayload.getOkapiUrl());
        String jobExecutionId = dataImportEventPayload.getJobExecutionId();
        String recordId = payloadContext.get(RECORD_ID_HEADER);
        String chunkId = payloadContext.get(CHUNK_ID_HEADER);
        Future<RecordToEntity> recordToHoldingsFuture = idStorageService.store(recordId, UUID.randomUUID().toString(), dataImportEventPayload.getTenant());
        recordToHoldingsFuture.onSuccess(res -> {
            String holdingsId = res.getEntityId();
            mappingMetadataCache.get(jobExecutionId, context).map(parametersOptional -> parametersOptional.orElseThrow(() -> new EventProcessingException(format(MAPPING_METADATA_NOT_FOUND_MSG, jobExecutionId, recordId, chunkId)))).map(mappingMetadataDto -> {
                prepareEvent(dataImportEventPayload);
                MappingParameters mappingParameters = Json.decodeValue(mappingMetadataDto.getMappingParams(), MappingParameters.class);
                MappingManager.map(dataImportEventPayload, new MappingContext().withMappingParameters(mappingParameters));
                JsonObject holdingAsJson = new JsonObject(payloadContext.get(HOLDINGS.value()));
                if (holdingAsJson.getJsonObject(HOLDINGS_PATH_FIELD) != null) {
                    holdingAsJson = holdingAsJson.getJsonObject(HOLDINGS_PATH_FIELD);
                }
                holdingAsJson.put("id", holdingsId);
                holdingAsJson.put("sourceId", FOLIO_SOURCE_ID);
                fillInstanceIdIfNeeded(dataImportEventPayload, holdingAsJson);
                checkIfPermanentLocationIdExists(holdingAsJson);
                return Json.decodeValue(payloadContext.get(HOLDINGS.value()), HoldingsRecord.class);
            }).compose(holdingToCreate -> addHoldings(holdingToCreate, context)).onSuccess(createdHoldings -> {
                LOGGER.info("Created Holding record by jobExecutionId: '{}' and recordId: '{}' and chunkId: '{}'", jobExecutionId, recordId, chunkId);
                payloadContext.put(HOLDINGS.value(), Json.encodePrettily(createdHoldings));
                future.complete(dataImportEventPayload);
            }).onFailure(e -> {
                if (!(e instanceof DuplicateEventException)) {
                    LOGGER.error("Error creating inventory Holding record by jobExecutionId: '{}' and recordId: '{}' and chunkId: '{}' ", jobExecutionId, recordId, chunkId, e);
                }
                future.completeExceptionally(e);
            });
        }).onFailure(failure -> {
            LOGGER.error("Error creating inventory recordId and holdingsId relationship by jobExecutionId: '{}' and recordId: '{}' and chunkId: '{}' ", jobExecutionId, recordId, chunkId, failure);
            future.completeExceptionally(failure);
        });
    } catch (Exception e) {
        LOGGER.error(CREATE_HOLDING_ERROR_MESSAGE, 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) ParsedRecordUtil(org.folio.inventory.dataimport.util.ParsedRecordUtil) Json(io.vertx.core.json.Json) Context(org.folio.inventory.common.Context) EventHandler(org.folio.processing.events.services.handler.EventHandler) DI_INVENTORY_HOLDING_CREATED(org.folio.DataImportEventTypes.DI_INVENTORY_HOLDING_CREATED) MappingManager(org.folio.processing.mapping.MappingManager) 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) UNIQUE_ID_ERROR_MESSAGE(org.folio.inventory.dataimport.util.DataImportConstants.UNIQUE_ID_ERROR_MESSAGE) EntityType(org.folio.rest.jaxrs.model.EntityType) JsonObject(io.vertx.core.json.JsonObject) IdStorageService(org.folio.inventory.services.IdStorageService) ActionProfile(org.folio.ActionProfile) RecordToEntity(org.folio.inventory.domain.relationship.RecordToEntity) 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) DuplicateEventException(org.folio.kafka.exception.DuplicateEventException) Record(org.folio.rest.jaxrs.model.Record) Promise(io.vertx.core.Promise) DataImportEventPayload(org.folio.DataImportEventPayload) UUID(java.util.UUID) Future(io.vertx.core.Future) HoldingsRecord(org.folio.HoldingsRecord) String.format(java.lang.String.format) StringUtils.isNotBlank(org.apache.commons.lang.StringUtils.isNotBlank) Storage(org.folio.inventory.storage.Storage) Logger(org.apache.logging.log4j.Logger) EventProcessingException(org.folio.processing.exceptions.EventProcessingException) StringUtils.isBlank(org.apache.commons.lang3.StringUtils.isBlank) Strings.isNotEmpty(org.apache.logging.log4j.util.Strings.isNotEmpty) LogManager(org.apache.logging.log4j.LogManager) MappingMetadataCache(org.folio.inventory.dataimport.cache.MappingMetadataCache) DuplicateEventException(org.folio.kafka.exception.DuplicateEventException) JsonObject(io.vertx.core.json.JsonObject) RecordToEntity(org.folio.inventory.domain.relationship.RecordToEntity) DuplicateEventException(org.folio.kafka.exception.DuplicateEventException) EventProcessingException(org.folio.processing.exceptions.EventProcessingException) DataImportEventPayload(org.folio.DataImportEventPayload) MappingContext(org.folio.processing.mapping.mapper.MappingContext) CompletableFuture(java.util.concurrent.CompletableFuture) MappingParameters(org.folio.processing.mapping.defaultmapper.processor.parameters.MappingParameters) EventProcessingException(org.folio.processing.exceptions.EventProcessingException)

Example 2 with MappingContext

use of org.folio.processing.mapping.mapper.MappingContext 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 3 with MappingContext

use of org.folio.processing.mapping.mapper.MappingContext in project mod-source-record-manager by folio-org.

the class EdifactDiErrorPayloadBuilder method mapPayloadWithPopulatingInvoiceDetails.

private DataImportEventPayload mapPayloadWithPopulatingInvoiceDetails(DataImportEventPayload dataImportEventPayload) {
    DataImportEventPayload mappedPayload = MappingManager.map(dataImportEventPayload, new MappingContext());
    mappedPayload.setEventType(DI_ERROR.value());
    JsonObject mappingResult = new JsonObject(mappedPayload.getContext().get(INVOICE.value()));
    JsonObject invoiceJson = mappingResult.getJsonObject(INVOICE_FIELD);
    JsonObject invoiceLineCollection = new JsonObject().put(INVOICE_LINES_FIELD, new JsonArray(invoiceJson.remove(INVOICE_LINES_FIELD).toString()));
    mappedPayload.getContext().put(INVOICE_LINES_KEY, Json.encode(invoiceLineCollection));
    mappedPayload.getContext().put(INVOICE.value(), invoiceJson.encode());
    return mappedPayload;
}
Also used : MappingContext(org.folio.processing.mapping.mapper.MappingContext) JsonArray(io.vertx.core.json.JsonArray) JsonObject(io.vertx.core.json.JsonObject) DataImportEventPayload(org.folio.DataImportEventPayload)

Example 4 with MappingContext

use of org.folio.processing.mapping.mapper.MappingContext in project mod-invoice by folio-org.

the class CreateInvoiceEventHandler method handle.

@Override
public CompletableFuture<DataImportEventPayload> handle(DataImportEventPayload dataImportEventPayload) {
    CompletableFuture<DataImportEventPayload> future = new CompletableFuture<>();
    dataImportEventPayload.setEventType(DI_INVOICE_CREATED.value());
    try {
        HashMap<String, String> payloadContext = dataImportEventPayload.getContext();
        if (payloadContext == null || isBlank(payloadContext.get(EDIFACT_INVOICE.value()))) {
            logger.error(PAYLOAD_HAS_NO_DATA_MSG);
            return CompletableFuture.failedFuture(new EventProcessingException(PAYLOAD_HAS_NO_DATA_MSG));
        }
        Map<String, String> okapiHeaders = DataImportUtils.getOkapiHeaders(dataImportEventPayload);
        CompletableFuture<Map<Integer, PoLine>> poLinesFuture = getAssociatedPoLines(dataImportEventPayload, okapiHeaders);
        poLinesFuture.thenAccept(invLineNoToPoLine -> ensureAdditionalData(dataImportEventPayload, invLineNoToPoLine)).thenAccept(v -> prepareEventPayloadForMapping(dataImportEventPayload)).thenAccept(v -> MappingManager.map(dataImportEventPayload, new MappingContext())).thenAccept(v -> prepareMappingResult(dataImportEventPayload)).thenCompose(v -> saveInvoice(dataImportEventPayload, okapiHeaders)).thenApply(savedInvoice -> prepareInvoiceLinesToSave(savedInvoice.getId(), dataImportEventPayload, poLinesFuture.join())).thenCompose(preparedInvoiceLines -> saveInvoiceLines(preparedInvoiceLines, okapiHeaders)).whenComplete((savedInvoiceLines, throwable) -> {
            makeLightweightReturnPayload(dataImportEventPayload);
            if (throwable == null) {
                List<InvoiceLine> invoiceLines = savedInvoiceLines.stream().map(Pair::getLeft).collect(Collectors.toList());
                InvoiceLineCollection invoiceLineCollection = new InvoiceLineCollection().withInvoiceLines(invoiceLines).withTotalRecords(invoiceLines.size());
                dataImportEventPayload.getContext().put(INVOICE_LINES_KEY, Json.encode(invoiceLineCollection));
                Map<Integer, String> invoiceLinesErrors = prepareInvoiceLinesErrors(savedInvoiceLines);
                if (!invoiceLinesErrors.isEmpty()) {
                    dataImportEventPayload.getContext().put(INVOICE_LINES_ERRORS_KEY, Json.encode(invoiceLinesErrors));
                    future.completeExceptionally(new EventProcessingException("Error during invoice lines creation"));
                    return;
                }
                future.complete(dataImportEventPayload);
            } else {
                preparePayloadWithMappedInvoiceLines(dataImportEventPayload);
                logger.error("Error during invoice creation", throwable);
                future.completeExceptionally(throwable);
            }
        });
    } catch (Exception e) {
        logger.error("Error during creation invoice and invoice lines", e);
        future.completeExceptionally(e);
    }
    return future;
}
Also used : ORDER_LINES(org.folio.invoices.utils.ResourcePathResolver.ORDER_LINES) CREATE(org.folio.ActionProfile.Action.CREATE) EventHandler(org.folio.processing.events.services.handler.EventHandler) CompletableFuture.completedFuture(java.util.concurrent.CompletableFuture.completedFuture) PoLine(org.folio.rest.acq.model.orders.PoLine) ACTION_PROFILE(org.folio.rest.jaxrs.model.ProfileSnapshotWrapper.ContentType.ACTION_PROFILE) StreamEx.ofSubLists(one.util.streamex.StreamEx.ofSubLists) Pair(org.apache.commons.lang3.tuple.Pair) Map(java.util.Map) JsonObject(io.vertx.core.json.JsonObject) OPEN(org.folio.rest.jaxrs.model.InvoiceLine.InvoiceLineStatus.OPEN) HelperUtils.collectResultsOnSuccess(org.folio.invoices.utils.HelperUtils.collectResultsOnSuccess) MappingProfile(org.folio.MappingProfile) InvoiceLine(org.folio.rest.jaxrs.model.InvoiceLine) DataImportEventPayload(org.folio.DataImportEventPayload) EdifactParsedContent(org.folio.EdifactParsedContent) Collectors(java.util.stream.Collectors) String.format(java.lang.String.format) Objects(java.util.Objects) List(java.util.List) CollectionUtils.isNotEmpty(org.apache.commons.collections4.CollectionUtils.isNotEmpty) Logger(org.apache.logging.log4j.Logger) DI_INVOICE_CREATED(org.folio.DataImportEventTypes.DI_INVOICE_CREATED) Optional(java.util.Optional) ParsedRecord(org.folio.ParsedRecord) Pattern(java.util.regex.Pattern) Invoice(org.folio.rest.jaxrs.model.Invoice) RestClient(org.folio.rest.core.RestClient) FundDistribution(org.folio.rest.acq.model.orders.FundDistribution) Json(io.vertx.core.json.Json) INVOICE(org.folio.ActionProfile.FolioRecord.INVOICE) Record(org.folio.Record) MappingManager(org.folio.processing.mapping.MappingManager) PoLineCollection(org.folio.rest.acq.model.orders.PoLineCollection) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) EDIFACT_INVOICE(org.folio.rest.jaxrs.model.EntityType.EDIFACT_INVOICE) ArrayList(java.util.ArrayList) InvoiceLineHelper(org.folio.rest.impl.InvoiceLineHelper) InvoiceLineCollection(org.folio.rest.jaxrs.model.InvoiceLineCollection) RequestContext(org.folio.rest.core.models.RequestContext) ActionProfile(org.folio.ActionProfile) ResourcePathResolver.resourcesPath(org.folio.invoices.utils.ResourcePathResolver.resourcesPath) MappingContext(org.folio.processing.mapping.mapper.MappingContext) DataImportUtils(org.folio.dataimport.utils.DataImportUtils) Vertx(io.vertx.core.Vertx) RequestEntry(org.folio.rest.core.models.RequestEntry) InvoiceHelper(org.folio.rest.impl.InvoiceHelper) JsonArray(io.vertx.core.json.JsonArray) EventProcessingException(org.folio.processing.exceptions.EventProcessingException) StringUtils.isBlank(org.apache.commons.lang3.StringUtils.isBlank) EdifactRecordReader(org.folio.processing.mapping.mapper.reader.record.edifact.EdifactRecordReader) Collections(java.util.Collections) LogManager(org.apache.logging.log4j.LogManager) InvoiceLine(org.folio.rest.jaxrs.model.InvoiceLine) EventProcessingException(org.folio.processing.exceptions.EventProcessingException) DataImportEventPayload(org.folio.DataImportEventPayload) MappingContext(org.folio.processing.mapping.mapper.MappingContext) CompletableFuture(java.util.concurrent.CompletableFuture) InvoiceLineCollection(org.folio.rest.jaxrs.model.InvoiceLineCollection) Map(java.util.Map) HashMap(java.util.HashMap) EventProcessingException(org.folio.processing.exceptions.EventProcessingException)

Example 5 with MappingContext

use of org.folio.processing.mapping.mapper.MappingContext in project mod-inventory by folio-org.

the class CreateItemEventHandler method handle.

@Override
public CompletableFuture<DataImportEventPayload> handle(DataImportEventPayload dataImportEventPayload) {
    CompletableFuture<DataImportEventPayload> future = new CompletableFuture<>();
    try {
        dataImportEventPayload.setEventType(DI_INVENTORY_ITEM_CREATED.value());
        HashMap<String, String> payloadContext = dataImportEventPayload.getContext();
        if (payloadContext == null || isBlank(payloadContext.get(EntityType.MARC_BIBLIOGRAPHIC.value()))) {
            LOG.error(PAYLOAD_HAS_NO_DATA_MSG);
            return CompletableFuture.failedFuture(new EventProcessingException(PAYLOAD_HAS_NO_DATA_MSG));
        }
        if (dataImportEventPayload.getCurrentNode().getChildSnapshotWrappers().isEmpty()) {
            LOG.error(ACTION_HAS_NO_MAPPING_MSG);
            return CompletableFuture.failedFuture(new EventProcessingException(ACTION_HAS_NO_MAPPING_MSG));
        }
        dataImportEventPayload.getEventsChain().add(dataImportEventPayload.getEventType());
        dataImportEventPayload.setCurrentNode(dataImportEventPayload.getCurrentNode().getChildSnapshotWrappers().get(0));
        dataImportEventPayload.getContext().put(ITEM.value(), new JsonObject().encode());
        String jobExecutionId = dataImportEventPayload.getJobExecutionId();
        String recordId = dataImportEventPayload.getContext().get(RECORD_ID_HEADER);
        String chunkId = dataImportEventPayload.getContext().get(CHUNK_ID_HEADER);
        Future<RecordToEntity> recordToItemFuture = idStorageService.store(recordId, UUID.randomUUID().toString(), dataImportEventPayload.getTenant());
        recordToItemFuture.onSuccess(res -> {
            String itemId = res.getEntityId();
            Context context = EventHandlingUtil.constructContext(dataImportEventPayload.getTenant(), dataImportEventPayload.getToken(), dataImportEventPayload.getOkapiUrl());
            ItemCollection itemCollection = storage.getItemCollection(context);
            mappingMetadataCache.get(jobExecutionId, context).map(parametersOptional -> parametersOptional.orElseThrow(() -> new EventProcessingException(format(MAPPING_METADATA_NOT_FOUND_MSG, jobExecutionId, recordId, chunkId)))).map(mappingMetadataDto -> {
                MappingParameters mappingParameters = Json.decodeValue(mappingMetadataDto.getMappingParams(), MappingParameters.class);
                MappingManager.map(dataImportEventPayload, new MappingContext().withMappingParameters(mappingParameters));
                return processMappingResult(dataImportEventPayload, itemId);
            }).compose(mappedItemJson -> {
                List<String> errors = validateItem(mappedItemJson, requiredFields);
                if (!errors.isEmpty()) {
                    String msg = format("Mapped Item is invalid: %s, by jobExecutionId: '%s' and recordId: '%s' and chunkId: '%s' ", errors, jobExecutionId, recordId, chunkId);
                    LOG.error(msg);
                    return Future.failedFuture(msg);
                }
                Item mappedItem = ItemUtil.jsonToItem(mappedItemJson);
                return isItemBarcodeUnique(mappedItemJson.getString("barcode"), itemCollection).compose(isUnique -> isUnique ? addItem(mappedItem, itemCollection) : Future.failedFuture(format("Barcode must be unique, %s is already assigned to another item", mappedItemJson.getString("barcode"))));
            }).onComplete(ar -> {
                if (ar.succeeded()) {
                    dataImportEventPayload.getContext().put(ITEM.value(), Json.encode(ar.result()));
                    future.complete(dataImportEventPayload);
                } else {
                    if (!(ar.cause() instanceof DuplicateEventException)) {
                        LOG.error("Error creating inventory Item by jobExecutionId: '{}' and recordId: '{}' and chunkId: '{}' ", jobExecutionId, recordId, chunkId, ar.cause());
                    }
                    future.completeExceptionally(ar.cause());
                }
            });
        }).onFailure(failure -> {
            LOG.error("Error creating inventory recordId and itemId relationship by jobExecutionId: '{}' and recordId: '{}' and chunkId: '{}' ", jobExecutionId, recordId, chunkId, failure);
            future.completeExceptionally(failure);
        });
    } catch (Exception e) {
        LOG.error("Error creating inventory Item", e);
        future.completeExceptionally(e);
    }
    return future;
}
Also used : ParsedRecordUtil(org.folio.inventory.dataimport.util.ParsedRecordUtil) CREATE(org.folio.ActionProfile.Action.CREATE) Arrays(java.util.Arrays) EventHandler(org.folio.processing.events.services.handler.EventHandler) ItemUtil(org.folio.inventory.support.ItemUtil) JsonHelper(org.folio.inventory.support.JsonHelper) ZonedDateTime(java.time.ZonedDateTime) Item(org.folio.inventory.domain.items.Item) ACTION_PROFILE(org.folio.rest.jaxrs.model.ProfileSnapshotWrapper.ContentType.ACTION_PROFILE) StringUtils(org.apache.commons.lang3.StringUtils) CirculationNote(org.folio.inventory.domain.items.CirculationNote) UNIQUE_ID_ERROR_MESSAGE(org.folio.inventory.dataimport.util.DataImportConstants.UNIQUE_ID_ERROR_MESSAGE) JsonObject(io.vertx.core.json.JsonObject) ItemCollection(org.folio.inventory.domain.items.ItemCollection) ZoneOffset(java.time.ZoneOffset) RecordToEntity(org.folio.inventory.domain.relationship.RecordToEntity) StringUtils.isEmpty(org.apache.commons.lang3.StringUtils.isEmpty) DuplicateEventException(org.folio.kafka.exception.DuplicateEventException) DataImportEventPayload(org.folio.DataImportEventPayload) UUID(java.util.UUID) Future(io.vertx.core.Future) Collectors(java.util.stream.Collectors) String.format(java.lang.String.format) Storage(org.folio.inventory.storage.Storage) List(java.util.List) Logger(org.apache.logging.log4j.Logger) EventHandlingUtil(org.folio.inventory.dataimport.handlers.matching.util.EventHandlingUtil) ITEM(org.folio.ActionProfile.FolioRecord.ITEM) PagingParameters(org.folio.inventory.common.api.request.PagingParameters) UnsupportedEncodingException(java.io.UnsupportedEncodingException) Json(io.vertx.core.json.Json) Context(org.folio.inventory.common.Context) MappingManager(org.folio.processing.mapping.MappingManager) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) DI_INVENTORY_ITEM_CREATED(org.folio.DataImportEventTypes.DI_INVENTORY_ITEM_CREATED) EntityType(org.folio.rest.jaxrs.model.EntityType) IdStorageService(org.folio.inventory.services.IdStorageService) ActionProfile(org.folio.ActionProfile) MappingParameters(org.folio.processing.mapping.defaultmapper.processor.parameters.MappingParameters) MappingContext(org.folio.processing.mapping.mapper.MappingContext) ItemStatusName(org.folio.inventory.domain.items.ItemStatusName) Record(org.folio.rest.jaxrs.model.Record) Promise(io.vertx.core.Promise) CqlHelper(org.folio.inventory.support.CqlHelper) StringUtils.isNotBlank(org.apache.commons.lang.StringUtils.isNotBlank) EventProcessingException(org.folio.processing.exceptions.EventProcessingException) StringUtils.isBlank(org.apache.commons.lang3.StringUtils.isBlank) DateTimeFormatter(java.time.format.DateTimeFormatter) LogManager(org.apache.logging.log4j.LogManager) MappingMetadataCache(org.folio.inventory.dataimport.cache.MappingMetadataCache) Context(org.folio.inventory.common.Context) MappingContext(org.folio.processing.mapping.mapper.MappingContext) DuplicateEventException(org.folio.kafka.exception.DuplicateEventException) JsonObject(io.vertx.core.json.JsonObject) ItemCollection(org.folio.inventory.domain.items.ItemCollection) RecordToEntity(org.folio.inventory.domain.relationship.RecordToEntity) DuplicateEventException(org.folio.kafka.exception.DuplicateEventException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) EventProcessingException(org.folio.processing.exceptions.EventProcessingException) DataImportEventPayload(org.folio.DataImportEventPayload) MappingContext(org.folio.processing.mapping.mapper.MappingContext) Item(org.folio.inventory.domain.items.Item) CompletableFuture(java.util.concurrent.CompletableFuture) MappingParameters(org.folio.processing.mapping.defaultmapper.processor.parameters.MappingParameters) EventProcessingException(org.folio.processing.exceptions.EventProcessingException)

Aggregations

JsonObject (io.vertx.core.json.JsonObject)7 MappingContext (org.folio.processing.mapping.mapper.MappingContext)7 DataImportEventPayload (org.folio.DataImportEventPayload)5 EventProcessingException (org.folio.processing.exceptions.EventProcessingException)5 Json (io.vertx.core.json.Json)4 String.format (java.lang.String.format)4 HashMap (java.util.HashMap)4 CompletableFuture (java.util.concurrent.CompletableFuture)4 LogManager (org.apache.logging.log4j.LogManager)4 Logger (org.apache.logging.log4j.Logger)4 ActionProfile (org.folio.ActionProfile)4 EventHandler (org.folio.processing.events.services.handler.EventHandler)4 MappingManager (org.folio.processing.mapping.MappingManager)4 MappingParameters (org.folio.processing.mapping.defaultmapper.processor.parameters.MappingParameters)4 ACTION_PROFILE (org.folio.rest.jaxrs.model.ProfileSnapshotWrapper.ContentType.ACTION_PROFILE)4 StringUtils.isBlank (org.apache.commons.lang3.StringUtils.isBlank)3 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)2 Future (io.vertx.core.Future)2 Promise (io.vertx.core.Promise)2 JsonArray (io.vertx.core.json.JsonArray)2