use of org.folio.inventory.domain.relationship.RecordToEntity 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;
}
use of org.folio.inventory.domain.relationship.RecordToEntity in project mod-inventory by folio-org.
the class CreateInstanceEventHandler method handle.
@Override
public CompletableFuture<DataImportEventPayload> handle(DataImportEventPayload dataImportEventPayload) {
CompletableFuture<DataImportEventPayload> future = new CompletableFuture<>();
try {
dataImportEventPayload.setEventType(DI_INVENTORY_INSTANCE_CREATED.value());
HashMap<String, String> payloadContext = dataImportEventPayload.getContext();
if (payloadContext == null || payloadContext.isEmpty() || isEmpty(dataImportEventPayload.getContext().get(MARC_BIBLIOGRAPHIC.value()))) {
LOGGER.error(PAYLOAD_HAS_NO_DATA_MSG);
return CompletableFuture.failedFuture(new EventProcessingException(PAYLOAD_HAS_NO_DATA_MSG));
}
String jobExecutionId = dataImportEventPayload.getJobExecutionId();
String recordId = dataImportEventPayload.getContext().get(RECORD_ID_HEADER);
if (dataImportEventPayload.getCurrentNode().getChildSnapshotWrappers().isEmpty()) {
LOGGER.error(ACTION_HAS_NO_MAPPING_MSG);
return CompletableFuture.failedFuture(new EventProcessingException(format(ACTION_HAS_NO_MAPPING_MSG, jobExecutionId, recordId)));
}
Context context = EventHandlingUtil.constructContext(dataImportEventPayload.getTenant(), dataImportEventPayload.getToken(), dataImportEventPayload.getOkapiUrl());
Record targetRecord = Json.decodeValue(payloadContext.get(EntityType.MARC_BIBLIOGRAPHIC.value()), Record.class);
String chunkId = dataImportEventPayload.getContext().get(CHUNK_ID_HEADER);
Future<RecordToEntity> recordToInstanceFuture = idStorageService.store(targetRecord.getId(), UUID.randomUUID().toString(), dataImportEventPayload.getTenant());
recordToInstanceFuture.onSuccess(res -> {
String instanceId = res.getEntityId();
mappingMetadataCache.get(jobExecutionId, context).compose(parametersOptional -> parametersOptional.map(mappingMetadata -> prepareAndExecuteMapping(dataImportEventPayload, new JsonObject(mappingMetadata.getMappingRules()), Json.decodeValue(mappingMetadata.getMappingParams(), MappingParameters.class))).orElseGet(() -> Future.failedFuture(format(MAPPING_PARAMETERS_NOT_FOUND_MSG, jobExecutionId, recordId, chunkId)))).compose(v -> {
InstanceCollection instanceCollection = storage.getInstanceCollection(context);
JsonObject instanceAsJson = prepareInstance(dataImportEventPayload, instanceId, jobExecutionId);
List<String> errors = EventHandlingUtil.validateJsonByRequiredFields(instanceAsJson, 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);
LOGGER.warn(msg);
return Future.failedFuture(msg);
}
Instance mappedInstance = Instance.fromJson(instanceAsJson);
return addInstance(mappedInstance, instanceCollection).compose(createdInstance -> precedingSucceedingTitlesHelper.createPrecedingSucceedingTitles(mappedInstance, context).map(createdInstance));
}).onSuccess(ar -> {
dataImportEventPayload.getContext().put(INSTANCE.value(), Json.encode(ar));
future.complete(dataImportEventPayload);
}).onFailure(e -> {
if (!(e instanceof DuplicateEventException)) {
LOGGER.error("Error creating inventory Instance by jobExecutionId: '{}' and recordId: '{}' and chunkId: '{}' ", jobExecutionId, recordId, chunkId, e);
}
future.completeExceptionally(e);
});
}).onFailure(failure -> {
LOGGER.error("Error creating inventory recordId and instanceId relationship by jobExecutionId: '{}' and recordId: '{}' and chunkId: '{}' ", jobExecutionId, recordId, chunkId, failure);
future.completeExceptionally(failure);
});
} catch (Exception e) {
LOGGER.error("Error creating inventory Instance", e);
future.completeExceptionally(e);
}
return future;
}
use of org.folio.inventory.domain.relationship.RecordToEntity in project mod-inventory by folio-org.
the class CreateMarcHoldingsEventHandler 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_HOLDINGS.value()))) {
return CompletableFuture.failedFuture(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());
Record targetRecord = new JsonObject(payloadContext.get(EntityType.MARC_HOLDINGS.value())).mapTo(Record.class);
prepareEvent(dataImportEventPayload);
String jobExecutionId = dataImportEventPayload.getJobExecutionId();
String recordId = payloadContext.get(RECORD_ID_HEADER);
String chunkId = payloadContext.get(CHUNK_ID_HEADER);
Future<RecordToEntity> recordToHoldingsFuture = idStorageService.store(targetRecord.getId(), 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)))).onSuccess(mappingMetadata -> defaultMapRecordToHoldings(dataImportEventPayload, mappingMetadata)).map(v -> processMappingResult(dataImportEventPayload, holdingsId)).compose(holdingJson -> findInstanceIdByHrid(dataImportEventPayload, holdingJson, context).compose(instanceId -> {
fillInstanceId(dataImportEventPayload, holdingJson, instanceId);
var holdingsRecords = storage.getHoldingsRecordCollection(context);
HoldingsRecord holding = Json.decodeValue(payloadContext.get(HOLDINGS.value()), HoldingsRecord.class);
return addHoldings(holding, holdingsRecords);
})).onSuccess(createdHoldings -> {
LOGGER.info("Created Holding record by jobExecutionId: '{}' and recordId: '{}' and chunkId: '{}' ", jobExecutionId, recordId, chunkId);
dataImportEventPayload.getContext().put(HOLDINGS.value(), Json.encodePrettily(createdHoldings));
future.complete(dataImportEventPayload);
}).onFailure(e -> {
if (!(e instanceof DuplicateEventException)) {
LOGGER.error("Error creating Holding by jobExecutionId: '{}' and recordId: '{}' and chunkId: '{}' ", jobExecutionId, recordId, chunkId, e);
}
future.completeExceptionally(e);
});
}).onFailure(failure -> {
LOGGER.error(format(CREATING_INVENTORY_RELATIONSHIP_ERROR_MESSAGE, jobExecutionId, recordId, chunkId), failure);
future.completeExceptionally(failure);
});
} catch (Exception e) {
LOGGER.error("Failed to create Holdings", e);
future.completeExceptionally(e);
}
return future;
}
use of org.folio.inventory.domain.relationship.RecordToEntity in project mod-inventory by folio-org.
the class AuthorityIdStorageService method store.
@Override
public Future<RecordToEntity> store(String recordId, String authorityId, String tenantId) {
RecordToEntity recordToAuthority = RecordToEntity.builder().table(EntityTable.AUTHORITY).recordId(recordId).entityId(authorityId).build();
LOGGER.info("Saving RecordToAuthority relationship: {}", recordToAuthority);
return entityIdStorageDao.saveRecordToEntityRelationship(recordToAuthority, tenantId);
}
use of org.folio.inventory.domain.relationship.RecordToEntity in project mod-inventory by folio-org.
the class InstanceIdStorageService method store.
@Override
public Future<RecordToEntity> store(String recordId, String instanceId, String tenantId) {
RecordToEntity recordToInstance = RecordToEntity.builder().table(EntityTable.INSTANCE).recordId(recordId).entityId(instanceId).build();
LOGGER.info("Saving RecordToInstance relationship: {}", recordToInstance);
return entityIdStorageDao.saveRecordToEntityRelationship(recordToInstance, tenantId);
}
Aggregations