use of org.folio.ActionProfile.Action.UPDATE 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;
}
use of org.folio.ActionProfile.Action.UPDATE in project mod-inventory by folio-org.
the class UpdateHoldingEventHandler method processOLError.
private void processOLError(DataImportEventPayload dataImportEventPayload, CompletableFuture<DataImportEventPayload> future, HoldingsRecordCollection holdingsRecords, HoldingsRecord holding, Failure failure) {
int currentRetryNumber = dataImportEventPayload.getContext().get(CURRENT_RETRY_NUMBER) == null ? 0 : Integer.parseInt(dataImportEventPayload.getContext().get(CURRENT_RETRY_NUMBER));
if (currentRetryNumber < MAX_RETRIES_COUNT) {
dataImportEventPayload.getContext().put(CURRENT_RETRY_NUMBER, String.valueOf(currentRetryNumber + 1));
LOGGER.warn("Error updating Holding by id '{}' - '{}', status code '{}'. Retry UpdateHoldingEventHandler handler...", holding.getId(), failure.getReason(), failure.getStatusCode());
holdingsRecords.findById(holding.getId()).thenAccept(actualInstance -> prepareDataAndReInvokeCurrentHandler(dataImportEventPayload, future, actualInstance)).exceptionally(e -> {
dataImportEventPayload.getContext().remove(CURRENT_RETRY_NUMBER);
String errMessage = format("Cannot get actual Holding by id: '%s' for jobExecutionId '%s'. Error: %s ", holding.getId(), dataImportEventPayload.getJobExecutionId(), e.getCause());
LOGGER.error(errMessage);
future.completeExceptionally(new EventProcessingException(errMessage));
return null;
});
} else {
dataImportEventPayload.getContext().remove(CURRENT_RETRY_NUMBER);
String errMessage = format("Current retry number %s exceeded or equal given number %s for the Holding update for jobExecutionId '%s' ", MAX_RETRIES_COUNT, currentRetryNumber, dataImportEventPayload.getJobExecutionId());
LOGGER.error(errMessage);
future.completeExceptionally(new EventProcessingException(errMessage));
}
}
use of org.folio.ActionProfile.Action.UPDATE in project mod-inventory by folio-org.
the class UpdateItemEventHandler method handle.
@Override
public CompletableFuture<DataImportEventPayload> handle(DataImportEventPayload dataImportEventPayload) {
CompletableFuture<DataImportEventPayload> future = new CompletableFuture<>();
try {
dataImportEventPayload.setEventType(DI_INVENTORY_ITEM_UPDATED.value());
HashMap<String, String> payloadContext = dataImportEventPayload.getContext();
if (isNull(payloadContext) || isBlank(payloadContext.get(MARC_BIBLIOGRAPHIC.value())) || isBlank(payloadContext.get(ITEM.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));
}
LOG.info("Processing UpdateItemEventHandler starting with jobExecutionId: {}.", dataImportEventPayload.getJobExecutionId());
AtomicBoolean isProtectedStatusChanged = new AtomicBoolean();
Context context = EventHandlingUtil.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_MSG, jobExecutionId, recordId, chunkId)))).compose(mappingMetadataDto -> {
String oldItemStatus = preparePayloadAndGetStatus(dataImportEventPayload, payloadContext, mappingMetadataDto);
JsonObject mappedItemAsJson = new JsonObject(payloadContext.get(ITEM.value()));
mappedItemAsJson = mappedItemAsJson.containsKey(ITEM_PATH_FIELD) ? mappedItemAsJson.getJsonObject(ITEM_PATH_FIELD) : mappedItemAsJson;
List<String> errors = validateItem(mappedItemAsJson, requiredFields);
if (!errors.isEmpty()) {
String msg = format("Mapped Instance is invalid: %s, by jobExecutionId: '%s' and recordId: '%s' and chunkId: '%s' ", errors, jobExecutionId, recordId, chunkId);
LOG.error(msg);
return Future.failedFuture(msg);
}
String newItemStatus = mappedItemAsJson.getJsonObject(STATUS_KEY).getString("name");
isProtectedStatusChanged.set(isProtectedStatusChanged(oldItemStatus, newItemStatus));
if (isProtectedStatusChanged.get()) {
mappedItemAsJson.getJsonObject(STATUS_KEY).put("name", oldItemStatus);
}
ItemCollection itemCollection = storage.getItemCollection(context);
Item itemToUpdate = ItemUtil.jsonToItem(mappedItemAsJson);
return verifyItemBarcodeUniqueness(itemToUpdate, itemCollection).compose(v -> updateItemAndRetryIfOLExists(itemToUpdate, itemCollection, dataImportEventPayload)).onSuccess(updatedItem -> {
if (isProtectedStatusChanged.get()) {
String msg = String.format(STATUS_UPDATE_ERROR_MSG, oldItemStatus, newItemStatus);
LOG.warn(msg);
dataImportEventPayload.getContext().put(ITEM.value(), ItemUtil.mapToJson(updatedItem).encode());
future.completeExceptionally(new EventProcessingException(msg));
} else {
addHoldingToPayloadIfNeeded(dataImportEventPayload, context, updatedItem).onComplete(item -> {
dataImportEventPayload.getContext().put(ITEM.value(), ItemUtil.mapToJson(updatedItem).encode());
future.complete(dataImportEventPayload);
});
}
});
}).onFailure(e -> {
LOG.error("Failed to update inventory Item by jobExecutionId: '{}' and recordId: '{}' and chunkId: '{}' ", jobExecutionId, recordId, chunkId, e);
future.completeExceptionally(e);
});
} catch (Exception e) {
LOG.error("Error updating inventory Item", e);
future.completeExceptionally(e);
}
return future;
}
Aggregations