From a60ac4cfb4138dfa49a0bcc086c1e427f35dde02 Mon Sep 17 00:00:00 2001 From: Viacheslav Kolesnyk <94473337+viacheslavkol@users.noreply.github.com> Date: Mon, 23 Dec 2024 12:00:07 +0100 Subject: [PATCH] feat(reindex): Extend range tables with the status column (#717) * feat(reindex): Extend range tables with the status column - add status, failCause columns to merge/upload range tables - implement status population logic Closes: MSEARCH-870 --- NEWS.md | 1 + .../model/reindex/MergeRangeEntity.java | 5 ++ .../model/reindex/UploadRangeEntity.java | 5 ++ .../model/types/ReindexRangeStatus.java | 28 ++++++++ .../ReindexMergeRangeIndexService.java | 7 +- .../reindex/ReindexOrchestrationService.java | 8 ++- .../ReindexUploadRangeIndexService.java | 5 +- .../reindex/jdbc/MergeRangeRepository.java | 5 +- .../reindex/jdbc/ReindexJdbcRepository.java | 13 ++-- .../reindex/jdbc/UploadRangeRepository.java | 9 ++- .../resources/changelog/changelog-master.xml | 1 + .../v4.0/add-reindex-range-statuses.xml | 40 +++++++++++ .../folio/InventoryServiceTest.java | 4 +- .../ReindexMergeRangeIndexServiceTest.java | 9 ++- .../ReindexOrchestrationServiceTest.java | 10 ++- .../service/reindex/ReindexServiceTest.java | 4 +- .../jdbc/MergeRangeRepositoriesIT.java | 9 +-- .../jdbc/ReindexJdbcRepositoriesIT.java | 20 ++++-- .../jdbc/UploadRangeRepositoriesIT.java | 67 +++++++++++++++++++ src/test/resources/sql/populate-instances.sql | 8 +++ 20 files changed, 222 insertions(+), 36 deletions(-) create mode 100644 src/main/java/org/folio/search/model/types/ReindexRangeStatus.java create mode 100644 src/main/resources/changelog/changes/v4.0/add-reindex-range-statuses.xml create mode 100644 src/test/java/org/folio/search/service/reindex/jdbc/UploadRangeRepositoriesIT.java create mode 100644 src/test/resources/sql/populate-instances.sql diff --git a/NEWS.md b/NEWS.md index 951a7bfda..31d7af3fe 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,6 +9,7 @@ ### Features * Move Instance sub-entities population from database trigger to code ([MSEARCH-887](https://folio-org.atlassian.net/browse/MSEARCH-887)) * Update reindex merge failed status only for failed entity type ([MSEARCH-909](https://folio-org.atlassian.net/browse/MSEARCH-909)) +* Extend reindex range tables with status, fail_cause columns ([MSEARCH-870](https://folio-org.atlassian.net/browse/MSEARCH-870)) ### Bug fixes * Remove shelving order calculation for local call-number types diff --git a/src/main/java/org/folio/search/model/reindex/MergeRangeEntity.java b/src/main/java/org/folio/search/model/reindex/MergeRangeEntity.java index 856aad1b5..d095ce687 100644 --- a/src/main/java/org/folio/search/model/reindex/MergeRangeEntity.java +++ b/src/main/java/org/folio/search/model/reindex/MergeRangeEntity.java @@ -4,6 +4,7 @@ import java.util.UUID; import lombok.Data; import org.folio.search.model.types.ReindexEntityType; +import org.folio.search.model.types.ReindexRangeStatus; @Data public class MergeRangeEntity { @@ -15,6 +16,8 @@ public class MergeRangeEntity { public static final String RANGE_UPPER_COLUMN = "upper"; public static final String CREATED_AT_COLUMN = "created_at"; public static final String FINISHED_AT_COLUMN = "finished_at"; + public static final String STATUS_COLUMN = "status"; + public static final String FAIL_CAUSE_COLUMN = "fail_cause"; private final UUID id; private final ReindexEntityType entityType; @@ -23,5 +26,7 @@ public class MergeRangeEntity { private final String upperId; private final Timestamp createdAt; private Timestamp finishedAt; + private final ReindexRangeStatus status; + private final String failCause; } diff --git a/src/main/java/org/folio/search/model/reindex/UploadRangeEntity.java b/src/main/java/org/folio/search/model/reindex/UploadRangeEntity.java index df264ee4b..7fcaef797 100644 --- a/src/main/java/org/folio/search/model/reindex/UploadRangeEntity.java +++ b/src/main/java/org/folio/search/model/reindex/UploadRangeEntity.java @@ -4,6 +4,7 @@ import java.util.UUID; import lombok.Data; import org.folio.search.model.types.ReindexEntityType; +import org.folio.search.model.types.ReindexRangeStatus; @Data public class UploadRangeEntity { @@ -14,6 +15,8 @@ public class UploadRangeEntity { public static final String UPPER_BOUND_COLUMN = "upper"; public static final String CREATED_AT_COLUMN = "created_at"; public static final String FINISHED_AT_COLUMN = "finished_at"; + public static final String STATUS_COLUMN = "status"; + public static final String FAIL_CAUSE_COLUMN = "fail_cause"; private final UUID id; private final ReindexEntityType entityType; @@ -21,5 +24,7 @@ public class UploadRangeEntity { private final String upper; private final Timestamp createdAt; private Timestamp finishedAt; + private final ReindexRangeStatus status; + private final String failCause; } diff --git a/src/main/java/org/folio/search/model/types/ReindexRangeStatus.java b/src/main/java/org/folio/search/model/types/ReindexRangeStatus.java new file mode 100644 index 000000000..1f9279ad9 --- /dev/null +++ b/src/main/java/org/folio/search/model/types/ReindexRangeStatus.java @@ -0,0 +1,28 @@ +package org.folio.search.model.types; + +import lombok.Getter; + +@Getter +public enum ReindexRangeStatus { + SUCCESS("Success"), + FAIL("Fail"); + + private final String value; + + ReindexRangeStatus(String value) { + this.value = value; + } + + public static ReindexRangeStatus valueOfNullable(String value) { + if (value == null) { + return null; + } + + for (ReindexRangeStatus b : ReindexRangeStatus.values()) { + if (b.name().equalsIgnoreCase(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} diff --git a/src/main/java/org/folio/search/service/reindex/ReindexMergeRangeIndexService.java b/src/main/java/org/folio/search/service/reindex/ReindexMergeRangeIndexService.java index 5d239f473..dfd60172f 100644 --- a/src/main/java/org/folio/search/service/reindex/ReindexMergeRangeIndexService.java +++ b/src/main/java/org/folio/search/service/reindex/ReindexMergeRangeIndexService.java @@ -16,6 +16,7 @@ import org.folio.search.model.reindex.MergeRangeEntity; import org.folio.search.model.types.InventoryRecordType; import org.folio.search.model.types.ReindexEntityType; +import org.folio.search.model.types.ReindexRangeStatus; import org.folio.search.service.InstanceChildrenResourceService; import org.folio.search.service.reindex.jdbc.MergeRangeRepository; import org.springframework.stereotype.Service; @@ -67,9 +68,9 @@ public List fetchMergeRanges(ReindexEntityType entityType) { return repositories.get(entityType).getMergeRanges(); } - public void updateFinishDate(ReindexEntityType entityType, String rangeId) { + public void updateStatus(ReindexEntityType entityType, String rangeId, ReindexRangeStatus status, String failCause) { var repository = repositories.get(entityType); - repository.setIndexRangeFinishDate(UUID.fromString(rangeId), Timestamp.from(Instant.now())); + repository.updateRangeStatus(UUID.fromString(rangeId), Timestamp.from(Instant.now()), status, failCause); } @SuppressWarnings("unchecked") @@ -110,7 +111,7 @@ private MergeRangeEntity mergeEntity(InventoryRecordType recordType, String tena private MergeRangeEntity mergeEntity(UUID id, InventoryRecordType recordType, String tenantId, String lowerId, String upperId, Timestamp createdAt) { - return new MergeRangeEntity(id, asEntityType(recordType), tenantId, lowerId, upperId, createdAt); + return new MergeRangeEntity(id, asEntityType(recordType), tenantId, lowerId, upperId, createdAt, null, null); } private ReindexEntityType asEntityType(InventoryRecordType recordType) { diff --git a/src/main/java/org/folio/search/service/reindex/ReindexOrchestrationService.java b/src/main/java/org/folio/search/service/reindex/ReindexOrchestrationService.java index d055d9f23..3b8d7552b 100644 --- a/src/main/java/org/folio/search/service/reindex/ReindexOrchestrationService.java +++ b/src/main/java/org/folio/search/service/reindex/ReindexOrchestrationService.java @@ -9,6 +9,7 @@ import org.folio.search.model.event.ReindexRangeIndexEvent; import org.folio.search.model.event.ReindexRecordsEvent; import org.folio.search.model.types.ReindexEntityType; +import org.folio.search.model.types.ReindexRangeStatus; import org.folio.search.repository.PrimaryResourceRepository; import org.folio.search.service.converter.MultiTenantSearchDocumentConverter; import org.folio.spring.FolioExecutionContext; @@ -34,13 +35,14 @@ public boolean process(ReindexRangeIndexEvent event) { var resourceEvents = uploadRangeService.fetchRecordRange(event); var documents = documentConverter.convert(resourceEvents).values().stream().flatMap(Collection::stream).toList(); var folioIndexOperationResponse = elasticRepository.indexResources(documents); - uploadRangeService.updateFinishDate(event); if (folioIndexOperationResponse.getStatus() == FolioIndexOperationResponse.StatusEnum.ERROR) { log.warn("process:: ReindexRangeIndexEvent indexing error [id: {}, error: {}]", event.getId(), folioIndexOperationResponse.getErrorMessage()); + uploadRangeService.updateStatus(event, ReindexRangeStatus.FAIL, folioIndexOperationResponse.getErrorMessage()); reindexStatusService.updateReindexUploadFailed(event.getEntityType()); throw new ReindexException(folioIndexOperationResponse.getErrorMessage()); } + uploadRangeService.updateStatus(event, ReindexRangeStatus.SUCCESS, null); log.info("process:: ReindexRangeIndexEvent processed [id: {}]", event.getId()); reindexStatusService.addProcessedUploadRanges(event.getEntityType(), 1); @@ -55,7 +57,7 @@ public boolean process(ReindexRecordsEvent event) { try { mergeRangeService.saveEntities(event); reindexStatusService.addProcessedMergeRanges(entityType, 1); - mergeRangeService.updateFinishDate(entityType, event.getRangeId()); + mergeRangeService.updateStatus(entityType, event.getRangeId(), ReindexRangeStatus.SUCCESS, null); log.info("process:: ReindexRecordsEvent processed [rangeId: {}, recordType: {}]", event.getRangeId(), event.getRecordType()); if (reindexStatusService.isMergeCompleted()) { @@ -69,7 +71,7 @@ public boolean process(ReindexRecordsEvent event) { log.error(new FormattedMessage("process:: ReindexRecordsEvent indexing error [rangeId: {}, error: {}]", event.getRangeId(), ex.getMessage()), ex); reindexStatusService.updateReindexMergeFailed(entityType); - mergeRangeService.updateFinishDate(entityType, event.getRangeId()); + mergeRangeService.updateStatus(entityType, event.getRangeId(), ReindexRangeStatus.FAIL, ex.getMessage()); } return true; diff --git a/src/main/java/org/folio/search/service/reindex/ReindexUploadRangeIndexService.java b/src/main/java/org/folio/search/service/reindex/ReindexUploadRangeIndexService.java index d4fc5551d..77fdfc392 100644 --- a/src/main/java/org/folio/search/service/reindex/ReindexUploadRangeIndexService.java +++ b/src/main/java/org/folio/search/service/reindex/ReindexUploadRangeIndexService.java @@ -15,6 +15,7 @@ import org.folio.search.model.event.ReindexRangeIndexEvent; import org.folio.search.model.reindex.UploadRangeEntity; import org.folio.search.model.types.ReindexEntityType; +import org.folio.search.model.types.ReindexRangeStatus; import org.folio.search.service.reindex.jdbc.UploadRangeRepository; import org.folio.spring.tools.kafka.FolioMessageProducer; import org.springframework.stereotype.Service; @@ -56,9 +57,9 @@ public Collection fetchRecordRange(ReindexRangeIndexEvent rangeIn .toList(); } - public void updateFinishDate(ReindexRangeIndexEvent event) { + public void updateStatus(ReindexRangeIndexEvent event, ReindexRangeStatus status, String failCause) { var repository = repositories.get(event.getEntityType()); - repository.setIndexRangeFinishDate(event.getId(), Timestamp.from(Instant.now())); + repository.updateRangeStatus(event.getId(), Timestamp.from(Instant.now()), status, failCause); } private List prepareEvents(List uploadRanges) { diff --git a/src/main/java/org/folio/search/service/reindex/jdbc/MergeRangeRepository.java b/src/main/java/org/folio/search/service/reindex/jdbc/MergeRangeRepository.java index 5e6b010c2..150ac6a95 100644 --- a/src/main/java/org/folio/search/service/reindex/jdbc/MergeRangeRepository.java +++ b/src/main/java/org/folio/search/service/reindex/jdbc/MergeRangeRepository.java @@ -11,6 +11,7 @@ import java.util.UUID; import org.folio.search.model.reindex.MergeRangeEntity; import org.folio.search.model.types.ReindexEntityType; +import org.folio.search.model.types.ReindexRangeStatus; import org.folio.search.utils.JdbcUtils; import org.folio.search.utils.JsonConverter; import org.folio.spring.FolioExecutionContext; @@ -102,7 +103,9 @@ private RowMapper mergeRangeEntityRowMapper() { rs.getString(MergeRangeEntity.TENANT_ID_COLUMN), rs.getString(MergeRangeEntity.RANGE_LOWER_COLUMN), rs.getString(MergeRangeEntity.RANGE_UPPER_COLUMN), - rs.getTimestamp(MergeRangeEntity.CREATED_AT_COLUMN) + rs.getTimestamp(MergeRangeEntity.CREATED_AT_COLUMN), + ReindexRangeStatus.valueOfNullable(rs.getString(MergeRangeEntity.STATUS_COLUMN)), + rs.getString(MergeRangeEntity.FAIL_CAUSE_COLUMN) ); mergeRange.setFinishedAt(rs.getTimestamp(MergeRangeEntity.FINISHED_AT_COLUMN)); return mergeRange; diff --git a/src/main/java/org/folio/search/service/reindex/jdbc/ReindexJdbcRepository.java b/src/main/java/org/folio/search/service/reindex/jdbc/ReindexJdbcRepository.java index c67a2bad3..f6f9ef118 100644 --- a/src/main/java/org/folio/search/service/reindex/jdbc/ReindexJdbcRepository.java +++ b/src/main/java/org/folio/search/service/reindex/jdbc/ReindexJdbcRepository.java @@ -6,6 +6,7 @@ import java.util.Optional; import java.util.UUID; import org.folio.search.model.types.ReindexEntityType; +import org.folio.search.model.types.ReindexRangeStatus; import org.folio.search.utils.JdbcUtils; import org.folio.search.utils.JsonConverter; import org.folio.spring.FolioExecutionContext; @@ -15,7 +16,11 @@ public abstract class ReindexJdbcRepository { protected static final int BATCH_OPERATION_SIZE = 100; private static final String COUNT_SQL = "SELECT COUNT(*) FROM %s;"; - private static final String UPDATE_FINISHED_AT_RANGE_SQL = "UPDATE %s SET finished_at = ? WHERE id = ?;"; + private static final String UPDATE_STATUS_SQL = """ + UPDATE %s + SET finished_at = ?, status = ?, fail_cause = ? + WHERE id = ?; + """; protected final JsonConverter jsonConverter; protected final FolioExecutionContext context; @@ -40,9 +45,9 @@ public void truncate() { JdbcUtils.truncateTable(entityTable(), jdbcTemplate, context); } - public void setIndexRangeFinishDate(UUID id, Timestamp timestamp) { - var sql = UPDATE_FINISHED_AT_RANGE_SQL.formatted(getFullTableName(context, rangeTable())); - jdbcTemplate.update(sql, timestamp, id); + public void updateRangeStatus(UUID id, Timestamp timestamp, ReindexRangeStatus status, String failCause) { + var sql = UPDATE_STATUS_SQL.formatted(getFullTableName(context, rangeTable())); + jdbcTemplate.update(sql, timestamp, status.name(), failCause, id); } public abstract ReindexEntityType entityType(); diff --git a/src/main/java/org/folio/search/service/reindex/jdbc/UploadRangeRepository.java b/src/main/java/org/folio/search/service/reindex/jdbc/UploadRangeRepository.java index 950d6ae83..20c616ce1 100644 --- a/src/main/java/org/folio/search/service/reindex/jdbc/UploadRangeRepository.java +++ b/src/main/java/org/folio/search/service/reindex/jdbc/UploadRangeRepository.java @@ -2,9 +2,11 @@ import static org.folio.search.model.reindex.UploadRangeEntity.CREATED_AT_COLUMN; import static org.folio.search.model.reindex.UploadRangeEntity.ENTITY_TYPE_COLUMN; +import static org.folio.search.model.reindex.UploadRangeEntity.FAIL_CAUSE_COLUMN; import static org.folio.search.model.reindex.UploadRangeEntity.FINISHED_AT_COLUMN; import static org.folio.search.model.reindex.UploadRangeEntity.ID_COLUMN; import static org.folio.search.model.reindex.UploadRangeEntity.LOWER_BOUND_COLUMN; +import static org.folio.search.model.reindex.UploadRangeEntity.STATUS_COLUMN; import static org.folio.search.model.reindex.UploadRangeEntity.UPPER_BOUND_COLUMN; import static org.folio.search.service.reindex.ReindexConstants.UPLOAD_RANGE_TABLE; import static org.folio.search.utils.JdbcUtils.getFullTableName; @@ -21,6 +23,7 @@ import org.folio.search.model.index.InstanceSubResource; import org.folio.search.model.reindex.UploadRangeEntity; import org.folio.search.model.types.ReindexEntityType; +import org.folio.search.model.types.ReindexRangeStatus; import org.folio.search.service.reindex.RangeGenerator; import org.folio.search.utils.JsonConverter; import org.folio.spring.FolioExecutionContext; @@ -92,7 +95,9 @@ private RowMapper uploadRangeRowMapper() { ReindexEntityType.fromValue(rs.getString(ENTITY_TYPE_COLUMN)), rs.getString(LOWER_BOUND_COLUMN), rs.getString(UPPER_BOUND_COLUMN), - rs.getTimestamp(CREATED_AT_COLUMN) + rs.getTimestamp(CREATED_AT_COLUMN), + ReindexRangeStatus.valueOfNullable(rs.getString(STATUS_COLUMN)), + rs.getString(FAIL_CAUSE_COLUMN) ); uploadRange.setFinishedAt(rs.getTimestamp(FINISHED_AT_COLUMN)); return uploadRange; @@ -103,7 +108,7 @@ private List prepareAndSaveUploadRanges() { var ranges = createRanges() .stream() .map(range -> new UploadRangeEntity(UUID.randomUUID(), entityType(), range.lowerBound(), range.upperBound(), - Timestamp.from(Instant.now()))) + Timestamp.from(Instant.now()), null, null)) .toList(); upsertUploadRanges(ranges); diff --git a/src/main/resources/changelog/changelog-master.xml b/src/main/resources/changelog/changelog-master.xml index 59f169d8c..9f479a318 100644 --- a/src/main/resources/changelog/changelog-master.xml +++ b/src/main/resources/changelog/changelog-master.xml @@ -11,5 +11,6 @@ + diff --git a/src/main/resources/changelog/changes/v4.0/add-reindex-range-statuses.xml b/src/main/resources/changelog/changes/v4.0/add-reindex-range-statuses.xml new file mode 100644 index 000000000..2e184a496 --- /dev/null +++ b/src/main/resources/changelog/changes/v4.0/add-reindex-range-statuses.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/java/org/folio/search/integration/folio/InventoryServiceTest.java b/src/test/java/org/folio/search/integration/folio/InventoryServiceTest.java index 712dca937..a96441c29 100644 --- a/src/test/java/org/folio/search/integration/folio/InventoryServiceTest.java +++ b/src/test/java/org/folio/search/integration/folio/InventoryServiceTest.java @@ -80,7 +80,7 @@ void publishReindexRecordsRange_ShouldIgnoreInvalidInput() { void publishReindexRecordsRange_ValidExecutionPath() { var id = UUID.randomUUID(); var validRange = new MergeRangeEntity(id, INSTANCE, TENANT_ID, "low", "high", Timestamp.from( - Instant.now())); + Instant.now()), null, null); var request = constructRequest(id.toString(), INSTANCE.getType(), "low", "high"); doNothing().when(reindexRecordsClient).publishReindexRecords(request); @@ -92,7 +92,7 @@ void publishReindexRecordsRange_ValidExecutionPath() { void publishReindexRecordsRange_ShouldRetryOnFailure() { var id = UUID.randomUUID(); var validRange = new MergeRangeEntity(id, INSTANCE, TENANT_ID, "low", "high", Timestamp.from( - Instant.now())); + Instant.now()), null, null); var request = constructRequest(id.toString(), INSTANCE.getType(), "low", "high"); doThrow(new RuntimeException("API failure")).when(reindexRecordsClient).publishReindexRecords(request); diff --git a/src/test/java/org/folio/search/service/reindex/ReindexMergeRangeIndexServiceTest.java b/src/test/java/org/folio/search/service/reindex/ReindexMergeRangeIndexServiceTest.java index 8023d2b64..0febc507a 100644 --- a/src/test/java/org/folio/search/service/reindex/ReindexMergeRangeIndexServiceTest.java +++ b/src/test/java/org/folio/search/service/reindex/ReindexMergeRangeIndexServiceTest.java @@ -27,6 +27,7 @@ import org.folio.search.model.reindex.MergeRangeEntity; import org.folio.search.model.types.InventoryRecordType; import org.folio.search.model.types.ReindexEntityType; +import org.folio.search.model.types.ReindexRangeStatus; import org.folio.search.service.InstanceChildrenResourceService; import org.folio.search.service.reindex.jdbc.HoldingRepository; import org.folio.search.service.reindex.jdbc.ItemRepository; @@ -99,14 +100,16 @@ void createMergeRanges_positive() { } @Test - void updateFinishDate() { + void updateStatus() { var testStartTime = Timestamp.from(Instant.now()); var rangeId = UUID.randomUUID(); var captor = ArgumentCaptor.captor(); + var failCause = "fail cause"; - service.updateFinishDate(ReindexEntityType.INSTANCE, rangeId.toString()); + service.updateStatus(ReindexEntityType.INSTANCE, rangeId.toString(), ReindexRangeStatus.FAIL, failCause); - verify(instanceRepository).setIndexRangeFinishDate(eq(rangeId), captor.capture()); + verify(instanceRepository) + .updateRangeStatus(eq(rangeId), captor.capture(), eq(ReindexRangeStatus.FAIL), eq(failCause)); var timestamp = captor.getValue(); assertThat(timestamp).isAfterOrEqualTo(testStartTime); diff --git a/src/test/java/org/folio/search/service/reindex/ReindexOrchestrationServiceTest.java b/src/test/java/org/folio/search/service/reindex/ReindexOrchestrationServiceTest.java index a803454e4..6b1227b98 100644 --- a/src/test/java/org/folio/search/service/reindex/ReindexOrchestrationServiceTest.java +++ b/src/test/java/org/folio/search/service/reindex/ReindexOrchestrationServiceTest.java @@ -21,6 +21,7 @@ import org.folio.search.model.types.IndexActionType; import org.folio.search.model.types.IndexingDataFormat; import org.folio.search.model.types.ReindexEntityType; +import org.folio.search.model.types.ReindexRangeStatus; import org.folio.search.repository.PrimaryResourceRepository; import org.folio.search.service.converter.MultiTenantSearchDocumentConverter; import org.folio.spring.testing.type.UnitTest; @@ -107,7 +108,8 @@ void process_positive_reindexRecordsEvent() { verify(mergeRangeIndexService).saveEntities(event); verify(reindexStatusService).addProcessedMergeRanges(ReindexEntityType.INSTANCE, 1); - verify(mergeRangeIndexService).updateFinishDate(ReindexEntityType.INSTANCE, event.getRangeId()); + verify(mergeRangeIndexService) + .updateStatus(ReindexEntityType.INSTANCE, event.getRangeId(), ReindexRangeStatus.SUCCESS, null); } @Test @@ -116,12 +118,14 @@ void process_negative_reindexRecordsEvent_shouldFailMergeOnException() { event.setRangeId(UUID.randomUUID().toString()); event.setRecordType(ReindexRecordsEvent.ReindexRecordType.INSTANCE); event.setRecords(emptyList()); - doThrow(new RuntimeException()).when(mergeRangeIndexService).saveEntities(event); + var failCause = "exception occurred"; + doThrow(new RuntimeException(failCause)).when(mergeRangeIndexService).saveEntities(event); service.process(event); verify(reindexStatusService).updateReindexMergeFailed(ReindexEntityType.INSTANCE); - verify(mergeRangeIndexService).updateFinishDate(ReindexEntityType.INSTANCE, event.getRangeId()); + verify(mergeRangeIndexService) + .updateStatus(ReindexEntityType.INSTANCE, event.getRangeId(), ReindexRangeStatus.FAIL, failCause); verifyNoMoreInteractions(reindexStatusService); } diff --git a/src/test/java/org/folio/search/service/reindex/ReindexServiceTest.java b/src/test/java/org/folio/search/service/reindex/ReindexServiceTest.java index bad12fb62..a79c03466 100644 --- a/src/test/java/org/folio/search/service/reindex/ReindexServiceTest.java +++ b/src/test/java/org/folio/search/service/reindex/ReindexServiceTest.java @@ -85,7 +85,7 @@ void submitFullReindex_positive() throws InterruptedException { var id = UUID.randomUUID(); var bound = UUID.randomUUID().toString(); var rangeEntity = - new MergeRangeEntity(id, INSTANCE, tenant, bound, bound, Timestamp.from(Instant.now())); + new MergeRangeEntity(id, INSTANCE, tenant, bound, bound, Timestamp.from(Instant.now()), null, null); when(consortiumService.getCentralTenant(tenant)).thenReturn(Optional.of(tenant)); when(mergeRangeService.createMergeRanges(tenant)).thenReturn(List.of(rangeEntity)); @@ -124,7 +124,7 @@ void submitFullReindex_negative_abortMergeAndSetFailedStatusWhenPublishingRanges var id = UUID.randomUUID(); var bound = UUID.randomUUID().toString(); var rangeEntity = - new MergeRangeEntity(id, INSTANCE, tenant, bound, bound, Timestamp.from(Instant.now())); + new MergeRangeEntity(id, INSTANCE, tenant, bound, bound, Timestamp.from(Instant.now()), null, null); when(consortiumService.getCentralTenant(tenant)).thenReturn(Optional.of(tenant)); when(consortiumService.getConsortiumTenants(tenant)).thenReturn(List.of(member)); diff --git a/src/test/java/org/folio/search/service/reindex/jdbc/MergeRangeRepositoriesIT.java b/src/test/java/org/folio/search/service/reindex/jdbc/MergeRangeRepositoriesIT.java index 7205a0021..02ada1612 100644 --- a/src/test/java/org/folio/search/service/reindex/jdbc/MergeRangeRepositoriesIT.java +++ b/src/test/java/org/folio/search/service/reindex/jdbc/MergeRangeRepositoriesIT.java @@ -17,6 +17,7 @@ import org.folio.search.configuration.properties.ReindexConfigurationProperties; import org.folio.search.model.reindex.MergeRangeEntity; import org.folio.search.model.types.ReindexEntityType; +import org.folio.search.model.types.ReindexRangeStatus; import org.folio.search.service.consortium.ConsortiumTenantProvider; import org.folio.search.utils.JsonConverter; import org.folio.spring.FolioExecutionContext; @@ -120,9 +121,9 @@ void saveMergeRanges_savesRanges_whenProvidedListOfMergeRangeEntities() { var bound2 = id2.toString().replace("-", ""); var instanceRanges = List.of( new MergeRangeEntity(id1, ReindexEntityType.INSTANCE, "member", bound1, bound1, - Timestamp.from(Instant.now())), + Timestamp.from(Instant.now()), ReindexRangeStatus.SUCCESS, null), new MergeRangeEntity(id2, ReindexEntityType.INSTANCE, "member", bound2, bound2, - Timestamp.from(Instant.now())) + Timestamp.from(Instant.now()), ReindexRangeStatus.FAIL, "fail cause") ); // act @@ -132,7 +133,8 @@ void saveMergeRanges_savesRanges_whenProvidedListOfMergeRangeEntities() { var ranges = instanceRepository.getMergeRanges(); assertThat(ranges) - .usingRecursiveFieldByFieldElementComparatorIgnoringFields("createdAt") + .allMatch(range -> range.getStatus() == null && range.getFailCause() == null) + .usingRecursiveFieldByFieldElementComparatorIgnoringFields("createdAt", "status", "failCause") .isEqualTo(instanceRanges); } @@ -181,7 +183,6 @@ void saveEntities() { } @Test - @SuppressWarnings("unchecked") void deleteEntities() { // given var instanceId = UUID.randomUUID(); diff --git a/src/test/java/org/folio/search/service/reindex/jdbc/ReindexJdbcRepositoriesIT.java b/src/test/java/org/folio/search/service/reindex/jdbc/ReindexJdbcRepositoriesIT.java index 4604c9705..eaa88a852 100644 --- a/src/test/java/org/folio/search/service/reindex/jdbc/ReindexJdbcRepositoriesIT.java +++ b/src/test/java/org/folio/search/service/reindex/jdbc/ReindexJdbcRepositoriesIT.java @@ -10,6 +10,7 @@ import java.util.UUID; import org.folio.search.configuration.properties.ReindexConfigurationProperties; import org.folio.search.model.types.ReindexEntityType; +import org.folio.search.model.types.ReindexRangeStatus; import org.folio.search.service.consortium.ConsortiumTenantProvider; import org.folio.search.utils.JsonConverter; import org.folio.spring.FolioExecutionContext; @@ -61,15 +62,16 @@ public String getDBSchemaName(String tenantId) { @Test @Sql({"/sql/populate-merge-ranges.sql", "/sql/populate-upload-ranges.sql"}) - void setIndexRangeFinishDate() { + void updateRangeStatus() { // arrange var timestamp = Timestamp.from(Instant.now()); + var failCause = "fail cause"; // act - mergeRepository.setIndexRangeFinishDate( - UUID.fromString("9f8febd1-e96c-46c4-a5f4-84a45cc499a2"), timestamp); - uploadRepository.setIndexRangeFinishDate( - UUID.fromString("9f8febd1-e96c-46c4-a5f4-84a45cc499a3"), timestamp); + mergeRepository.updateRangeStatus( + UUID.fromString("9f8febd1-e96c-46c4-a5f4-84a45cc499a2"), timestamp, ReindexRangeStatus.SUCCESS, failCause); + uploadRepository.updateRangeStatus( + UUID.fromString("9f8febd1-e96c-46c4-a5f4-84a45cc499a3"), timestamp, ReindexRangeStatus.FAIL, failCause); // assert var mergeRange = mergeRepository.getMergeRanges().stream() @@ -79,7 +81,11 @@ void setIndexRangeFinishDate() { .filter(range -> range.getEntityType().equals(ReindexEntityType.INSTANCE)) .findFirst(); - assertThat(mergeRange).isPresent().get().matches(range -> timestamp.getTime() == range.getFinishedAt().getTime()); - assertThat(uploadRange).isPresent().get().matches(range -> timestamp.getTime() == range.getFinishedAt().getTime()); + assertThat(mergeRange).isPresent().get() + .matches(range -> timestamp.getTime() == range.getFinishedAt().getTime() + && ReindexRangeStatus.SUCCESS == range.getStatus() && failCause.equals(range.getFailCause())); + assertThat(uploadRange).isPresent().get() + .matches(range -> timestamp.getTime() == range.getFinishedAt().getTime() + && ReindexRangeStatus.FAIL == range.getStatus() && failCause.equals(range.getFailCause())); } } diff --git a/src/test/java/org/folio/search/service/reindex/jdbc/UploadRangeRepositoriesIT.java b/src/test/java/org/folio/search/service/reindex/jdbc/UploadRangeRepositoriesIT.java new file mode 100644 index 000000000..a323216bb --- /dev/null +++ b/src/test/java/org/folio/search/service/reindex/jdbc/UploadRangeRepositoriesIT.java @@ -0,0 +1,67 @@ +package org.folio.search.service.reindex.jdbc; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.folio.search.utils.TestConstants.TENANT_ID; +import static org.mockito.Mockito.when; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.folio.search.configuration.properties.ReindexConfigurationProperties; +import org.folio.search.utils.JsonConverter; +import org.folio.spring.FolioExecutionContext; +import org.folio.spring.FolioModuleMetadata; +import org.folio.spring.testing.extension.EnablePostgres; +import org.folio.spring.testing.type.IntegrationTest; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.boot.test.autoconfigure.json.AutoConfigureJson; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.context.jdbc.Sql; + +@IntegrationTest +@JdbcTest +@EnablePostgres +@AutoConfigureJson +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +class UploadRangeRepositoriesIT { + + private @Autowired JdbcTemplate jdbcTemplate; + private @MockBean FolioExecutionContext context; + private @MockBean ReindexConfigurationProperties reindexConfig; + private UploadInstanceRepository uploadRepository; + + @BeforeEach + void setUp() { + var jsonConverter = new JsonConverter(new ObjectMapper()); + uploadRepository = new UploadInstanceRepository(jdbcTemplate, jsonConverter, context, reindexConfig); + when(context.getFolioModuleMetadata()).thenReturn(new FolioModuleMetadata() { + @Override + public String getModuleName() { + return null; + } + + @Override + public String getDBSchemaName(String tenantId) { + return "public"; + } + }); + when(context.getTenantId()).thenReturn(TENANT_ID); + when(reindexConfig.getUploadRangeSize()).thenReturn(1); + } + + @Test + @Sql({"/sql/populate-instances.sql"}) + void getUploadRanges_shouldNotPopulateStatus() { + // act + var uploadRanges = uploadRepository.getUploadRanges(true); + System.out.println(uploadRanges.size()); + + // assert + assertThat(uploadRanges) + .hasSize(1) + .allMatch(range -> range.getStatus() == null && range.getFailCause() == null); + } +} diff --git a/src/test/resources/sql/populate-instances.sql b/src/test/resources/sql/populate-instances.sql new file mode 100644 index 000000000..663424b27 --- /dev/null +++ b/src/test/resources/sql/populate-instances.sql @@ -0,0 +1,8 @@ +INSERT INTO instance (id, tenant_id, shared, is_bound_with, json) +VALUES ( + '9f8febd1-e96c-46c4-a5f4-84a45cc499a2', + 'tenant_123', + false, + false, + '{"title": "Random Instance", "author": "Random Author"}'::jsonb +); \ No newline at end of file