Skip to content

Commit

Permalink
MODSOURMAN-1063: Implementation finished.
Browse files Browse the repository at this point in the history
  • Loading branch information
VRohach committed Jan 2, 2024
1 parent 4ddb0b2 commit f3f972f
Show file tree
Hide file tree
Showing 10 changed files with 802 additions and 138 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* [MODSOURMAN-1021](https://issues.folio.org/browse/MODSOURMAN-1021) Provide endpoint for getting parsed content for DI log
* [MODSOURMAN-1022](https://issues.folio.org/browse/MODSOURMAN-1022) Remove step of initial saving of incoming records to SRS
* [MODSOURMAN-1070](https://issues.folio.org/browse/MODSOURMAN-1070) Fill in Journal Records for created MARC when INSTANCE_CREATED event received
* [MODSOURMAN-1063](https://issues.folio.org/browse/MODSOURMAN-1063) Update RecordProcessingLogDto to contain incoming record id

## 2023-10-13 v3.7.0
* [MODSOURMAN-1045](https://issues.folio.org/browse/MODSOURMAN-1045) Allow create action with non-matches for instance without match profile
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import io.vertx.sqlclient.Row;
import io.vertx.sqlclient.RowSet;
import org.folio.rest.jaxrs.model.JobExecutionSummaryDto;
import org.folio.rest.jaxrs.model.JobLogEntryDtoCollection;
import org.folio.rest.jaxrs.model.JournalRecord;
import org.folio.rest.jaxrs.model.RecordProcessingLogDto;
import org.folio.rest.jaxrs.model.RecordProcessingLogDtoCollection;

import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -55,7 +55,7 @@ public interface JournalRecordDao {
Future<Boolean> deleteByJobExecutionId(String jobExecutionId, String tenantId);

/**
* Searches for JobLogEntryDto entities by jobExecutionId and sorts them using specified sort criteria and direction
* Searches for RecordProcessingLogDtoCollection by jobExecutionId and sorts them using specified sort criteria and direction
*
* @param jobExecutionId job execution id
* @param sortBy sorting criteria
Expand All @@ -67,7 +67,7 @@ public interface JournalRecordDao {
* @param tenantId tenantId
* @return future with JobLogEntryDto collection
*/
Future<JobLogEntryDtoCollection> getJobLogEntryDtoCollection(String jobExecutionId, String sortBy, String order, boolean errorsOnly, String entityType, int limit, int offset, String tenantId);
Future<RecordProcessingLogDtoCollection> getRecordProcessingLogDtoCollection(String jobExecutionId, String sortBy, String order, boolean errorsOnly, String entityType, int limit, int offset, String tenantId);

/**
* Searches for RecordProcessingLogDto entities by jobExecutionId and recordId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,12 @@
import io.vertx.sqlclient.RowSet;
import io.vertx.sqlclient.SqlResult;
import io.vertx.sqlclient.Tuple;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.folio.dao.util.JournalRecordsColumns;
import org.folio.dao.util.PostgresClientFactory;
import org.folio.rest.jaxrs.model.EntityProcessingSummary;
import org.folio.rest.jaxrs.model.JobExecutionSummaryDto;
import org.folio.rest.jaxrs.model.JobLogEntryDto;
import org.folio.rest.jaxrs.model.JobLogEntryDtoCollection;
import org.folio.rest.jaxrs.model.JournalRecord;
import org.folio.rest.jaxrs.model.JournalRecord.ActionStatus;
import org.folio.rest.jaxrs.model.JournalRecord.ActionType;
Expand All @@ -22,6 +20,7 @@
import org.folio.rest.jaxrs.model.ProcessedHoldingsInfo;
import org.folio.rest.jaxrs.model.ProcessedItemInfo;
import org.folio.rest.jaxrs.model.RecordProcessingLogDto;
import org.folio.rest.jaxrs.model.RecordProcessingLogDtoCollection;
import org.folio.rest.jaxrs.model.RelatedInvoiceLineInfo;
import org.folio.rest.jaxrs.model.RelatedPoLineInfo;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -78,13 +77,17 @@
import static org.folio.dao.util.JournalRecordsColumns.INVOICE_LINE_ENTITY_ERROR;
import static org.folio.dao.util.JournalRecordsColumns.INVOICE_LINE_ENTITY_HRID;
import static org.folio.dao.util.JournalRecordsColumns.INVOICE_LINE_ENTITY_ID;
import static org.folio.dao.util.JournalRecordsColumns.INVOICE_LINE_JOURNAL_RECORD_ID;
import static org.folio.dao.util.JournalRecordsColumns.INVOICE_LINE_NUMBER;
import static org.folio.dao.util.JournalRecordsColumns.ITEM_ACTION_STATUS;
import static org.folio.dao.util.JournalRecordsColumns.ITEM_ENTITY_ERROR;
import static org.folio.dao.util.JournalRecordsColumns.ITEM_ENTITY_HRID;
import static org.folio.dao.util.JournalRecordsColumns.ITEM_ENTITY_ID;
import static org.folio.dao.util.JournalRecordsColumns.JOB_EXECUTION_ID;
import static org.folio.dao.util.JournalRecordsColumns.ORDER_ID;
import static org.folio.dao.util.JournalRecordsColumns.PO_LINE_ACTION_STATUS;
import static org.folio.dao.util.JournalRecordsColumns.PO_LINE_ENTITY_ERROR;
import static org.folio.dao.util.JournalRecordsColumns.PO_LINE_ENTITY_HRID;
import static org.folio.dao.util.JournalRecordsColumns.PO_LINE_ENTITY_ID;
import static org.folio.dao.util.JournalRecordsColumns.SOURCE_ENTITY_ERROR;
import static org.folio.dao.util.JournalRecordsColumns.SOURCE_ID;
import static org.folio.dao.util.JournalRecordsColumns.SOURCE_RECORD_ACTION_STATUS;
Expand Down Expand Up @@ -122,13 +125,7 @@
import static org.folio.dao.util.JournalRecordsColumns.TOTAL_UPDATED_ITEMS;
import static org.folio.dao.util.JournalRecordsColumns.TOTAL_UPDATED_ORDERS;
import static org.folio.dao.util.JournalRecordsColumns.TOTAL_UPDATED_SOURCE_RECORDS;
import static org.folio.dao.util.JournalRecordsColumns.ORDER_ID;
import static org.folio.dao.util.JournalRecordsColumns.PO_LINE_ACTION_STATUS;
import static org.folio.dao.util.JournalRecordsColumns.PO_LINE_ENTITY_ID;
import static org.folio.dao.util.JournalRecordsColumns.PO_LINE_ENTITY_HRID;
import static org.folio.dao.util.JournalRecordsColumns.PO_LINE_ENTITY_ERROR;
import static org.folio.rest.jaxrs.model.ActionStatus.UPDATED;
import static org.folio.rest.jaxrs.model.JobLogEntryDto.SourceRecordType.MARC_HOLDINGS;
import static org.folio.rest.persist.PostgresClient.convertToPsqlStandard;

@Repository
Expand All @@ -137,6 +134,9 @@ public class JournalRecordDaoImpl implements JournalRecordDao {
private static final Logger LOGGER = LogManager.getLogger();
public static final String SOURCE_RECORD_ENTITY_TYPE = "source_record_entity_type";
public static final String ORDER_ENTITY_ID = "order_entity_id";
public static final String SOURCE_ENTITY_ERROR = "source_entity_error";
public static final String INCOMING_RECORD_ID = "incoming_record_id";
public static final String HOLDINGS_ENTITY_HRID = "holdings_entity_hrid";
private final Set<String> sortableFields = Set.of("source_record_order", "action_type", "error");
private final Set<String> jobLogEntrySortableFields = Set.of("source_record_order", "title", "source_record_action_status",
"instance_action_status", "holdings_action_status", "item_action_status", "order_action_status", "invoice_action_status", "error");
Expand Down Expand Up @@ -239,7 +239,7 @@ public Future<Boolean> deleteByJobExecutionId(String jobExecutionId, String tena
}

@Override
public Future<JobLogEntryDtoCollection> getJobLogEntryDtoCollection(String jobExecutionId, String sortBy, String order, boolean errorsOnly, String entityType, int limit, int offset, String tenantId) {
public Future<RecordProcessingLogDtoCollection> getRecordProcessingLogDtoCollection(String jobExecutionId, String sortBy, String order, boolean errorsOnly, String entityType, int limit, int offset, String tenantId) {
LOGGER.trace("getJobLogEntryDtoCollection:: Trying to get JobLogEntryDtoCollection entity by jobExecutionId = {}", jobExecutionId);
if (!jobLogEntrySortableFields.contains(sortBy)) {
return Future.failedFuture(new BadRequestException(format("The specified field for sorting job log entries is invalid: '%s'", sortBy)));
Expand All @@ -248,7 +248,7 @@ public Future<JobLogEntryDtoCollection> getJobLogEntryDtoCollection(String jobEx
String query = format(GET_JOB_LOG_ENTRIES_BY_JOB_EXECUTION_ID_QUERY, jobExecutionId, sortBy, order, limit, offset, errorsOnly, entityType);
LOGGER.trace("JournalRecordDaoImpl::getJobLogEntryDtoCollection query = {};", query);
pgClientFactory.createInstance(tenantId).select(query, promise);
return promise.future().map(this::mapRowSetToJobLogDtoCollection);
return promise.future().map(this::mapRowSetToRecordProcessingLogDtoCollection);
}

@Override
Expand Down Expand Up @@ -316,48 +316,73 @@ private String prepareSortingClause(String sortBy, String order) {
return format(ORDER_BY_PATTERN, sortBy, order);
}

private JobLogEntryDtoCollection mapRowSetToJobLogDtoCollection(RowSet<Row> rowSet) {
var jobLogEntryDtoCollection = new JobLogEntryDtoCollection()
private RecordProcessingLogDtoCollection mapRowSetToRecordProcessingLogDtoCollection(RowSet<Row> rowSet) {
var recordProcessingLogDto = new RecordProcessingLogDtoCollection()
.withTotalRecords(0);

rowSet.forEach(row ->
jobLogEntryDtoCollection
recordProcessingLogDto
.withTotalRecords(row.getInteger(TOTAL_COUNT))
.getEntries().add(mapJobLogEntryRow(row))
);
return jobLogEntryDtoCollection;
return recordProcessingLogDto;
}

private JobLogEntryDto mapJobLogEntryRow(Row row) {
final var entityType = mapToEntityType(row.getString(SOURCE_RECORD_ENTITY_TYPE));
final var entityHrid = row.getArrayOfStrings(HOLDINGS_ENTITY_HRID);
private RecordProcessingLogDto mapJobLogEntryRow(Row row) {
RecordProcessingLogDto recordProcessingLogSummary = new RecordProcessingLogDto();

List<ProcessedHoldingsInfo> processedHoldingsInfo = new LinkedList<>();
List<ProcessedItemInfo> processedItemInfo = new LinkedList<>();

final var entityType = mapToRecordProcessingEntityType(row.getString(SOURCE_RECORD_ENTITY_TYPE));
final var holdingsEntityHrid = row.getString(HOLDINGS_ENTITY_HRID);
final var holdingsActionStatus = mapNameToEntityActionStatus(row.getString(HOLDINGS_ACTION_STATUS));
return new JobLogEntryDto()
recordProcessingLogSummary
.withSourceRecordType(entityType)
.withJobExecutionId(row.getValue(JOB_EXECUTION_ID).toString())
.withIncomingRecordId(row.getValue(INCOMING_RECORD_ID).toString())
.withSourceRecordId(row.getValue(SOURCE_ID).toString())
.withSourceRecordOrder(isEmpty(row.getString(INVOICE_ACTION_STATUS))
? row.getInteger(SOURCE_RECORD_ORDER).toString()
: row.getString(INVOICE_LINE_NUMBER))
.withSourceRecordTitle(getJobLogEntryTitle(row.getString(TITLE), entityType, entityHrid, holdingsActionStatus))
.withSourceRecordType(entityType)
.withHoldingsRecordHridList(ArrayUtils.isEmpty(entityHrid) ? Collections.emptyList() : Arrays.asList(entityHrid))
.withSourceRecordTitle(getJobLogEntryTitle(row.getString(TITLE), entityType, holdingsEntityHrid, holdingsActionStatus))
.withSourceRecordActionStatus(mapNameToEntityActionStatus(row.getString(SOURCE_RECORD_ACTION_STATUS)))
.withInstanceActionStatus(mapNameToEntityActionStatus(row.getString(INSTANCE_ACTION_STATUS)))
.withHoldingsActionStatus(holdingsActionStatus)
.withItemActionStatus(mapNameToEntityActionStatus(row.getString(ITEM_ACTION_STATUS)))
.withAuthorityActionStatus(mapNameToEntityActionStatus(row.getString(AUTHORITY_ACTION_STATUS)))
.withPoLineActionStatus(mapNameToEntityActionStatus(row.getString(PO_LINE_ACTION_STATUS)))
.withInvoiceActionStatus(mapNameToEntityActionStatus(row.getString(INVOICE_ACTION_STATUS)))
.withInvoiceLineJournalRecordId(Objects.isNull(row.getValue(INVOICE_LINE_JOURNAL_RECORD_ID))
? null : row.getValue(INVOICE_LINE_JOURNAL_RECORD_ID).toString())
.withError(row.getString(ERROR));
.withError(row.getString(SOURCE_ENTITY_ERROR))
.withRelatedInstanceInfo(constructInstanceProcessingInfo(row))
.withRelatedAuthorityInfo(constructProcessedEntityWithSingleIdInfoBasedOnEntityType(row,
AUTHORITY_ACTION_STATUS, AUTHORITY_ENTITY_ID, null, AUTHORITY_ENTITY_ERROR))
.withRelatedPoLineInfo(new RelatedPoLineInfo()
.withActionStatus(mapNameToEntityActionStatus(row.getString(PO_LINE_ACTION_STATUS)))
.withIdList(constructSingletonListFromColumn(row, PO_LINE_ENTITY_ID))
.withHridList(constructSingletonListFromColumn(row, PO_LINE_ENTITY_HRID))
.withError(row.getString(PO_LINE_ENTITY_ERROR))
.withOrderId(row.getString(ORDER_ENTITY_ID)))
.withRelatedInvoiceInfo(constructProcessedEntityInfoBasedOnEntityType(row,
INVOICE_ACTION_STATUS, INVOICE_ENTITY_ID, INVOICE_ENTITY_HRID, INVOICE_ENTITY_ERROR))
.withRelatedInvoiceLineInfo(constructInvoiceLineInfo(row))
.withSourceRecordTenantId(row.getString(SOURCE_RECORD_TENANT_ID));

ProcessedHoldingsInfo processedHoldings = constructProcessedHoldingsInfoBasedOnEntityType(row, HOLDINGS_ACTION_STATUS, HOLDINGS_ENTITY_ID, JournalRecordsColumns.HOLDINGS_ENTITY_HRID, HOLDINGS_PERMANENT_LOCATION_ID, HOLDINGS_ENTITY_ERROR);
ProcessedItemInfo processedItem = constructProcessedItemInfoBasedOnEntityType(row, ITEM_ACTION_STATUS, ITEM_ENTITY_ID, ITEM_ENTITY_HRID, HOLDINGS_ENTITY_ID, ITEM_ENTITY_ERROR);
if (Objects.nonNull(processedHoldings.getActionStatus()) || processedItem.getActionStatus() == UPDATED) {
processedHoldingsInfo.add(processedHoldings);
}
if (Objects.nonNull(processedItem.getActionStatus())) {
processedItemInfo.add(processedItem);
}

recordProcessingLogSummary.
withRelatedItemInfo(processedItemInfo.stream().distinct().toList())
.withRelatedHoldingsInfo(processedHoldingsInfo.stream().distinct().toList());

return recordProcessingLogSummary;
}

private String getJobLogEntryTitle(String title, JobLogEntryDto.SourceRecordType entityType, String[] entityHrid,
private String getJobLogEntryTitle(String title, RecordProcessingLogDto.SourceRecordType entityType, String entityHrid,
org.folio.rest.jaxrs.model.ActionStatus holdingsActionStatus) {
return MARC_HOLDINGS.equals(entityType)
return RecordProcessingLogDto.SourceRecordType.MARC_HOLDINGS.equals(entityType)
&& isActionStatusUpdatedOrCreated(holdingsActionStatus)
? "Holdings " + entityHrid[0]
? "Holdings " + entityHrid
: title;
}

Expand All @@ -378,10 +403,10 @@ private RecordProcessingLogDto mapRowSetToRecordProcessingLogDto(RowSet<Row> res
recordProcessingLogSummary
.withJobExecutionId(row.getValue(JOB_EXECUTION_ID).toString())
.withSourceRecordId(row.getValue(SOURCE_ID).toString())
.withSourceRecordOrder(row.getInteger(SOURCE_RECORD_ORDER))
.withSourceRecordOrder(row.getInteger(SOURCE_RECORD_ORDER).toString())
.withSourceRecordTitle(row.getString(TITLE))
.withSourceRecordActionStatus(mapNameToEntityActionStatus(row.getString(SOURCE_RECORD_ACTION_STATUS)))
.withError(row.getString(SOURCE_ENTITY_ERROR))
.withError(row.getString(JournalRecordsColumns.SOURCE_ENTITY_ERROR))
.withSourceRecordTenantId(row.getString(SOURCE_RECORD_TENANT_ID))
.withRelatedInstanceInfo(constructInstanceProcessingInfo(row))
.withRelatedAuthorityInfo(constructProcessedEntityWithSingleIdInfoBasedOnEntityType(row,
Expand All @@ -398,7 +423,7 @@ private RecordProcessingLogDto mapRowSetToRecordProcessingLogDto(RowSet<Row> res
}

resultSet.forEach(r -> {
ProcessedHoldingsInfo processedHoldings = constructProcessedHoldingsInfoBasedOnEntityType(r, HOLDINGS_ACTION_STATUS, HOLDINGS_ENTITY_ID, HOLDINGS_ENTITY_HRID, HOLDINGS_PERMANENT_LOCATION_ID, HOLDINGS_ENTITY_ERROR);
ProcessedHoldingsInfo processedHoldings = constructProcessedHoldingsInfoBasedOnEntityType(r, HOLDINGS_ACTION_STATUS, HOLDINGS_ENTITY_ID, JournalRecordsColumns.HOLDINGS_ENTITY_HRID, HOLDINGS_PERMANENT_LOCATION_ID, HOLDINGS_ENTITY_ERROR);
ProcessedItemInfo processedItem = constructProcessedItemInfoBasedOnEntityType(r, ITEM_ACTION_STATUS, ITEM_ENTITY_ID, ITEM_ENTITY_HRID, HOLDINGS_ENTITY_ID, ITEM_ENTITY_ERROR);
if (Objects.nonNull(processedHoldings.getActionStatus()) || processedItem.getActionStatus() == UPDATED) {
processedHoldingsInfo.add(processedHoldings);
Expand Down Expand Up @@ -474,8 +499,8 @@ private org.folio.rest.jaxrs.model.ActionStatus mapNameToEntityActionStatus(Stri
return name == null ? null : org.folio.rest.jaxrs.model.ActionStatus.fromValue(name);
}

private JobLogEntryDto.SourceRecordType mapToEntityType(String entityType) {
return entityType == null ? null : JobLogEntryDto.SourceRecordType.fromValue(entityType);
private RecordProcessingLogDto.SourceRecordType mapToRecordProcessingEntityType(String entityType) {
return entityType == null ? null : RecordProcessingLogDto.SourceRecordType.fromValue(entityType);
}

private JobExecutionSummaryDto mapRowToJobExecutionSummaryDto(Row row) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public void getMetadataProviderJobLogEntriesByJobExecutionId(String jobExecution
try {
LOGGER.debug("getMetadataProviderJobLogEntriesByJobExecutionId:: jobExecutionId {}, sortBy {}, errorsOnly {}, entityType {}",
jobExecutionId, sortBy, errorsOnly, entityType.name());
journalRecordService.getJobLogEntryDtoCollection(jobExecutionId, sortBy, order.name(), errorsOnly, entityType.name(), limit, offset, tenantId)
journalRecordService.getRecordProcessingLogDtoCollection(jobExecutionId, sortBy, order.name(), errorsOnly, entityType.name(), limit, offset, tenantId)
.map(GetMetadataProviderJobLogEntriesByJobExecutionIdResponse::respond200WithApplicationJson)
.map(Response.class::cast)
.otherwise(ExceptionHelper::mapExceptionToResponse)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import io.vertx.core.Future;
import org.folio.rest.jaxrs.model.JobExecutionSummaryDto;
import org.folio.rest.jaxrs.model.JournalRecord;
import org.folio.rest.jaxrs.model.JobLogEntryDtoCollection;
import org.folio.rest.jaxrs.model.JournalRecordCollection;
import org.folio.rest.jaxrs.model.RecordProcessingLogDto;
import org.folio.rest.jaxrs.model.RecordProcessingLogDtoCollection;

import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -42,13 +42,13 @@ public interface JournalRecordService {
* @param sortBy sorting criteria
* @param order sorting direction
* @param errorsOnly filtering by error field
* @param errorsOnly filtering by entity type
* @param entityType filtering by entity type
* @param limit limit
* @param offset offset
* @param tenantId tenantId
* @return future with JobLogEntryDto collection
*/
Future<JobLogEntryDtoCollection> getJobLogEntryDtoCollection(String jobExecutionId, String sortBy, String order, boolean errorsOnly, String entityType, int limit, int offset, String tenantId);
Future<RecordProcessingLogDtoCollection> getRecordProcessingLogDtoCollection(String jobExecutionId, String sortBy, String order, boolean errorsOnly, String entityType, int limit, int offset, String tenantId);

/**
* Searches for RecordProcessingLogDto entity by jobExecutionId and recordId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import org.folio.dao.JournalRecordDao;
import org.folio.rest.jaxrs.model.JobExecutionSummaryDto;
import org.folio.rest.jaxrs.model.JournalRecord;
import org.folio.rest.jaxrs.model.JobLogEntryDtoCollection;
import org.folio.rest.jaxrs.model.JournalRecordCollection;
import org.folio.rest.jaxrs.model.RecordProcessingLogDto;
import org.folio.rest.jaxrs.model.RecordProcessingLogDtoCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

Expand Down Expand Up @@ -38,8 +38,8 @@ public Future<JournalRecordCollection> getJobExecutionJournalRecords(String jobE
}

@Override
public Future<JobLogEntryDtoCollection> getJobLogEntryDtoCollection(String jobExecutionId, String sortBy, String order, boolean errorsOnly, String entityType, int limit, int offset, String tenantId) {
return journalRecordDao.getJobLogEntryDtoCollection(jobExecutionId, sortBy, order, errorsOnly, entityType, limit, offset, tenantId);
public Future<RecordProcessingLogDtoCollection> getRecordProcessingLogDtoCollection(String jobExecutionId, String sortBy, String order, boolean errorsOnly, String entityType, int limit, int offset, String tenantId) {
return journalRecordDao.getRecordProcessingLogDtoCollection(jobExecutionId, sortBy, order, errorsOnly, entityType, limit, offset, tenantId);
}

@Override
Expand Down
Loading

0 comments on commit f3f972f

Please sign in to comment.