Pull request #694: RED-6072

Merge in RED/persistence-service from RED-6072 to master

* commit 'eff8eeaf03f76c12ca700ff4bb4f7688c291fab6':
  RED-6072 - As Operation I want to see why files are in an ERROR state - update junit tests
  RED-6072 - As Operation I want to see why files are in an ERROR state - add @Transactional for the update
  RED-6072 - As Operation I want to see why files are in an ERROR state - update the new endpoints with different path than the original endpoints
  RED-6072 - As Operation I want to see why files are in an ERROR state - set back the initial endpoints for backward compatibility
  RED-6072 - As Operation I want to see why files are in an ERROR state - update junit test
  RED-6072 - As Operation I want to see why files are in an ERROR state - add to file entity and models information about the error state - update endpoints with the error information in case of failure
This commit is contained in:
Corina Olariu 2023-05-25 09:12:35 +02:00
commit 9a44ba7658
18 changed files with 180 additions and 30 deletions

View File

@ -486,6 +486,7 @@ public class StatusController implements StatusResource {
.hasHighlights(status.isHasHighlights())
.lastIndexed(status.getLastIndexed())
.fileSize(status.getFileSize())
.fileErrorInfo(status.getFileErrorInfo())
.build();
}

View File

@ -2,12 +2,15 @@ package com.iqser.red.service.persistence.v1.internal.api.controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.iqser.red.service.persistence.management.v1.processor.configuration.MessagingConfiguration;
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusProcessingUpdateService;
import com.iqser.red.service.persistence.service.v1.api.internal.resources.FileStatusProcessingUpdateResource;
import com.iqser.red.service.persistence.service.v1.api.shared.model.AnalyzeResult;
import com.iqser.red.service.persistence.service.v1.api.shared.model.UntouchedDocumentResponse;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileErrorInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -30,7 +33,15 @@ public class FileStatusProcessingUpdateInternalController implements FileStatusP
public void preprocessingFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId) {
fileStatusProcessingUpdateService.preprocessingFailed(dossierId, fileId);
fileStatusProcessingUpdateService.preprocessingFailed(dossierId, fileId, new FileErrorInfo("preprocessing failed",
MessagingConfiguration.PRE_PROCESSING_DLQ, "pdftron-service"));
}
public void preprocessingFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId,
@RequestBody FileErrorInfo fileErrorInfo) {
fileStatusProcessingUpdateService.preprocessingFailed(dossierId, fileId, fileErrorInfo);
}
@ -48,7 +59,14 @@ public class FileStatusProcessingUpdateInternalController implements FileStatusP
public void analysisFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId) {
fileStatusProcessingUpdateService.analysisFailed(dossierId, fileId);
fileStatusProcessingUpdateService.analysisFailed(dossierId, fileId, new FileErrorInfo());
}
public void analysisFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId,
@RequestBody FileErrorInfo fileErrorInfo) {
fileStatusProcessingUpdateService.analysisFailed(dossierId, fileId, fileErrorInfo);
}
@ -66,7 +84,15 @@ public class FileStatusProcessingUpdateInternalController implements FileStatusP
public void ocrFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId) {
fileStatusProcessingUpdateService.ocrFailed(dossierId, fileId);
fileStatusProcessingUpdateService.ocrFailed(dossierId, fileId, new FileErrorInfo("ocr failed",
MessagingConfiguration.OCR_DLQ, "ocr-service"));
}
public void ocrFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId,
@RequestBody FileErrorInfo fileErrorInfo) {
fileStatusProcessingUpdateService.ocrFailed(dossierId, fileId, fileErrorInfo);
}
@ -84,7 +110,14 @@ public class FileStatusProcessingUpdateInternalController implements FileStatusP
public void indexingFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId) {
fileStatusProcessingUpdateService.indexingFailed(dossierId, fileId);
fileStatusProcessingUpdateService.indexingFailed(dossierId, fileId, new FileErrorInfo("indexing failed",
MessagingConfiguration.INDEXING_DQL, "search-service"));
}
public void indexingFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId,
@RequestBody FileErrorInfo fileErrorInfo) {
fileStatusProcessingUpdateService.indexingFailed(dossierId, fileId, fileErrorInfo);
}
}

View File

@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
import com.iqser.red.service.persistence.service.v1.api.shared.model.AnalyzeResult;
import com.iqser.red.service.persistence.service.v1.api.shared.model.UntouchedDocumentResponse;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileErrorInfo;
public interface FileStatusProcessingUpdateResource {
@ -26,11 +27,16 @@ public interface FileStatusProcessingUpdateResource {
@PathVariable(FILE_ID) String fileId,
@RequestBody UntouchedDocumentResponse untouchedDocumentResponse);
@Deprecated
@ResponseStatus(value = HttpStatus.OK)
@PostMapping(value = InternalApi.BASE_PATH + STATUS_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + "/preprocessing-failed")
void preprocessingFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId);
@ResponseStatus(value = HttpStatus.OK)
@PostMapping(value = InternalApi.BASE_PATH + STATUS_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + "/preprocessing-failed-error")
void preprocessingFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId,
@RequestBody FileErrorInfo fileErrorInfo);
@ResponseStatus(value = HttpStatus.OK)
@PostMapping(value = InternalApi.BASE_PATH + STATUS_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + "/analysis-successful", consumes = MediaType.APPLICATION_JSON_VALUE)
@ -42,11 +48,18 @@ public interface FileStatusProcessingUpdateResource {
void ocrSuccessful(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId);
@Deprecated
@ResponseStatus(value = HttpStatus.OK)
@PostMapping(value = InternalApi.BASE_PATH + STATUS_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + "/analysis-failed")
void analysisFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId);
@ResponseStatus(value = HttpStatus.OK)
@PostMapping(value = InternalApi.BASE_PATH + STATUS_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + "/analysis-failed-error")
void analysisFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId,
@RequestBody FileErrorInfo fileErrorInfo);
@ResponseStatus(value = HttpStatus.OK)
@PostMapping(value = InternalApi.BASE_PATH + STATUS_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + "/pre-processing")
void preProcessing(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId);
@ -57,11 +70,18 @@ public interface FileStatusProcessingUpdateResource {
void ocrProcessing(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId);
@Deprecated
@ResponseStatus(value = HttpStatus.OK)
@PostMapping(value = InternalApi.BASE_PATH + STATUS_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + "/ocr-failed")
void ocrFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId);
@ResponseStatus(value = HttpStatus.OK)
@PostMapping(value = InternalApi.BASE_PATH + STATUS_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + "/ocr-failed-error")
void ocrFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId,
@RequestBody FileErrorInfo fileErrorInfo);
@ResponseStatus(value = HttpStatus.OK)
@PostMapping(value = InternalApi.BASE_PATH + STATUS_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + "/indexing")
void indexing(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId);
@ -72,8 +92,15 @@ public interface FileStatusProcessingUpdateResource {
void indexingSuccessful(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId);
@Deprecated
@ResponseStatus(value = HttpStatus.OK)
@PostMapping(value = InternalApi.BASE_PATH + STATUS_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + "/indexing-failed")
void indexingFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId);
@ResponseStatus(value = HttpStatus.OK)
@PostMapping(value = InternalApi.BASE_PATH + STATUS_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + "/indexing-failed-error")
void indexingFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId,
@RequestBody FileErrorInfo fileErrorInfo);
}

View File

@ -180,6 +180,12 @@ public class FileEntity {
@Column
private Integer processingErrorCounter;
@Column
private String errorCause;
@Column
private String errorQueue;
@Column
private String errorService;
public OffsetDateTime getLastOCRTime() {

View File

@ -7,6 +7,7 @@ import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.iqser.red.service.persistence.management.v1.processor.configuration.MessagingConfiguration;
import com.iqser.red.service.persistence.management.v1.processor.model.CvAnalysisServiceResponse;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileErrorInfo;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
@ -40,9 +41,10 @@ public class CvAnalysisMessageReceiver {
var response = objectMapper.readValue(failedMessage.getBody(), CvAnalysisServiceResponse.class);
fileStatusProcessingUpdateService.analysisFailed(response.getDossierId(), response.getFileId());
log.warn("Received message from {} for dossierId {} and fileId {}", MessagingConfiguration.IMAGE_SERVICE_DLQ, response.getDossierId(), response.getFileId());
fileStatusProcessingUpdateService.analysisFailed(response.getDossierId(), response.getFileId(), new FileErrorInfo("cv analysis failed", MessagingConfiguration.IMAGE_SERVICE_DLQ, "cv-analysis-service-v1"));
}
}

View File

@ -2,6 +2,7 @@ package com.iqser.red.service.persistence.management.v1.processor.service;
import javax.transaction.Transactional;
import org.apache.commons.lang3.StringUtils;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.web.bind.annotation.RestController;
@ -11,6 +12,7 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist
import com.iqser.red.service.persistence.management.v1.processor.settings.FileManagementServiceSettings;
import com.iqser.red.service.persistence.service.v1.api.shared.model.AnalyzeResult;
import com.iqser.red.service.persistence.service.v1.api.shared.model.UntouchedDocumentResponse;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileErrorInfo;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.ProcessingStatus;
import com.iqser.red.service.search.v1.model.IndexMessageType;
@ -101,17 +103,19 @@ public class FileStatusProcessingUpdateService {
}
public void preprocessingFailed(String dossierId, String fileId) {
setStatusError(dossierId, fileId, "preprocessingFailed");
public void preprocessingFailed(String dossierId, String fileId, FileErrorInfo fileErrorInfo) {
if (fileErrorInfo != null && StringUtils.isEmpty(fileErrorInfo.getCause())) {
fileErrorInfo.setCause("preprocessingFailed");
}
setStatusError(dossierId, fileId, fileErrorInfo);
}
private void setStatusError(String dossierId, String fileId, String reason) {
private void setStatusError(String dossierId, String fileId, FileErrorInfo fileErrorInfo) {
retryTemplate.execute(retryContext -> {
log.warn("Retrying {} time to set ERROR status for file {} in dossier {} with reason {} ", retryContext.getRetryCount(), fileId, dossierId, reason);
fileStatusService.setStatusError(fileId);
log.warn("Retrying {} time to set ERROR status for file {} in dossier {} with reason {} ", retryContext.getRetryCount(), fileId, dossierId, fileErrorInfo != null ? fileErrorInfo.getCause() : null);
fileStatusService.setStatusError(fileId, fileErrorInfo);
return null;
});
}
@ -150,15 +154,21 @@ public class FileStatusProcessingUpdateService {
}
public void analysisFailed(String dossierId, String fileId) {
public void analysisFailed(String dossierId, String fileId, FileErrorInfo fileErrorInfo) {
setStatusError(dossierId, fileId, "analysisFailed");
if (fileErrorInfo != null && StringUtils.isEmpty(fileErrorInfo.getCause())) {
fileErrorInfo.setCause("analysisFailed");
}
setStatusError(dossierId, fileId, fileErrorInfo);
}
public void ocrFailed(String dossierId, String fileId) {
public void ocrFailed(String dossierId, String fileId, FileErrorInfo fileErrorInfo) {
setStatusError(dossierId, fileId, "ocrFailed");
if (fileErrorInfo != null && StringUtils.isEmpty(fileErrorInfo.getCause())) {
fileErrorInfo.setCause("ocrFailed");
}
setStatusError(dossierId, fileId, fileErrorInfo);
}
@ -182,9 +192,12 @@ public class FileStatusProcessingUpdateService {
}
public void indexingFailed(String dossierId, String fileId) {
public void indexingFailed(String dossierId, String fileId, FileErrorInfo fileErrorInfo) {
setStatusError(dossierId, fileId, "indexingFailed");
if (fileErrorInfo != null && StringUtils.isEmpty(fileErrorInfo.getCause())) {
fileErrorInfo.setCause("indexingFailed");
}
setStatusError(dossierId, fileId, fileErrorInfo);
}
}

View File

@ -43,6 +43,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.AnalyzeRequ
import com.iqser.red.service.persistence.service.v1.api.shared.model.AnalyzeResult;
import com.iqser.red.service.persistence.service.v1.api.shared.model.FileAttribute;
import com.iqser.red.service.persistence.service.v1.api.shared.model.MessageType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileErrorInfo;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileModel;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.ProcessingStatus;
@ -546,8 +547,9 @@ public class FileStatusService {
}
public void setStatusError(String fileId) {
public void setStatusError(String fileId, FileErrorInfo fileErrorInfo) {
fileStatusPersistenceService.updateStatusErrorInfo(fileId, fileErrorInfo);
fileStatusPersistenceService.updateProcessingStatus(fileId, ProcessingStatus.ERROR);
}

View File

@ -12,6 +12,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.iqser.red.service.persistence.management.v1.processor.configuration.MessagingConfiguration;
import com.iqser.red.service.persistence.management.v1.processor.settings.FileManagementServiceSettings;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileErrorInfo;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType;
import lombok.RequiredArgsConstructor;
@ -51,9 +52,9 @@ public class ImageMessageReceiver {
String dossierId = (String) imageResponse.get("dossierId");
String fileId = (String) imageResponse.get("fileId");
fileStatusProcessingUpdateService.analysisFailed(dossierId, fileId);
log.warn("Received message from {} for dossierId {} and fileId {}", MessagingConfiguration.IMAGE_SERVICE_DLQ, dossierId, fileId);
fileStatusProcessingUpdateService.analysisFailed(dossierId, fileId, new FileErrorInfo("image analysis failed", MessagingConfiguration.IMAGE_SERVICE_DLQ, "image-service-v3"));
}
}

View File

@ -10,6 +10,7 @@ import org.springframework.stereotype.Service;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.iqser.red.service.persistence.management.v1.processor.configuration.MessagingConfiguration;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileErrorInfo;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
@ -49,7 +50,8 @@ public class NerMessageReceiver {
String fileId = (String) entityResponse.get("fileId");
log.warn("Received message {} for dossierId {} and fileId {}", MessagingConfiguration.NER_SERVICE_DLQ, dossierId, fileId);
fileStatusProcessingUpdateService.analysisFailed(dossierId, fileId);
fileStatusProcessingUpdateService.analysisFailed(dossierId, fileId,
new FileErrorInfo("ner service failed", MessagingConfiguration.NER_SERVICE_DLQ, "entity-recognition-service-v3"));
}
}

View File

@ -22,6 +22,7 @@ import com.iqser.red.service.persistence.management.v1.processor.model.OCRStatus
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.FileAttributesRepository;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.FileRepository;
import com.iqser.red.service.persistence.service.v1.api.shared.model.FileAttribute;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileErrorInfo;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.ProcessingStatus;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.WorkflowStatus;
@ -163,6 +164,16 @@ public class FileStatusPersistenceService {
}
@Transactional
public void updateStatusErrorInfo(String fileId, FileErrorInfo fileErrorInfo) {
if (fileErrorInfo == null) {
fileRepository.updateStatusErrorInfo(fileId, null, null, null);
} else {
fileRepository.updateStatusErrorInfo(fileId, fileErrorInfo.getCause(), fileErrorInfo.getQueue(), fileErrorInfo.getService());
}
}
@Transactional
public void updateProcessingStatus(String fileId, ProcessingStatus processingStatus) {
@ -170,6 +181,8 @@ public class FileStatusPersistenceService {
return;
}
if (processingStatus == ProcessingStatus.PROCESSED) {
// reset the error info
fileRepository.updateStatusErrorInfo(fileId, null, null, null);
// In case the file is updated to "processed", "lastProcessed" date should be updated to "now"
fileRepository.updateProcessingStatus(fileId,
processingStatus,

View File

@ -81,6 +81,10 @@ public interface FileRepository extends JpaRepository<FileEntity, String> {
@Query("update FileEntity f set f.processingStatus = :processingStatus, f.lastUpdated = :lastUpdated, f.processingErrorCounter = :processingErrorCounter " + "where f.id = :fileId")
void updateProcessingStatus(String fileId, ProcessingStatus processingStatus, OffsetDateTime lastUpdated, int processingErrorCounter);
@Modifying
@Query("update FileEntity f set f.errorCause = :cause, f.errorQueue = :queue, f.errorService = :service where f.id = :fileId")
void updateStatusErrorInfo(String fileId, String cause, String queue, String service);
@Modifying(clearAutomatically = true, flushAutomatically = true)
@Query("update FileEntity f set f.processingStatus = :processingStatus, f.lastUpdated = :lastUpdated, f.lastProcessed = :lastProcessed, f.processingErrorCounter = :processingErrorCounter " + "where f.id = :fileId")

View File

@ -3,6 +3,7 @@ package com.iqser.red.service.persistence.management.v1.processor.utils;
import java.util.function.BiConsumer;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileErrorInfo;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileModel;
public class FileModelMapper implements BiConsumer<FileEntity, FileModel> {
@ -11,7 +12,7 @@ public class FileModelMapper implements BiConsumer<FileEntity, FileModel> {
public void accept(FileEntity fileEntity, FileModel fileModel) {
fileEntity.getFileAttributes().forEach(fa -> fileModel.getFileAttributes().put(fa.getFileAttributeId().getFileAttributeConfigId(), fa.getValue()));
fileModel.setFileErrorInfo(new FileErrorInfo(fileEntity.getErrorCause(), fileEntity.getErrorQueue(), fileEntity.getErrorService()));
}
}

View File

@ -132,4 +132,6 @@ databaseChangeLog:
- include:
file: db/changelog/tenant/48-add-watermark-text-alignment.yaml
- include:
file: db/changelog/tenant/sql/49-add-keep_overlapping_objects.sql
file: db/changelog/tenant/sql/49-add-keep_overlapping_objects.sql
- include:
file: db/changelog/tenant/50-add-file-status-error-info.yaml

View File

@ -0,0 +1,17 @@
databaseChangeLog:
- changeSet:
id: add-file-status-error-info
author: corinaolariu
changes:
- addColumn:
columns:
- column:
name: error_cause
type: VARCHAR(255)
- column:
name: error_queue
type: VARCHAR(255)
- column:
name: error_service
type: VARCHAR(255)
tableName: file

View File

@ -19,6 +19,7 @@ import com.iqser.red.service.peristence.v1.server.integration.utils.AbstractPers
import com.iqser.red.service.persistence.service.v1.api.shared.model.AnalyzeResult;
import com.iqser.red.service.persistence.service.v1.api.shared.model.MessageType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualRedactions;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileErrorInfo;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.ProcessingStatus;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.WorkflowStatus;
@ -57,7 +58,7 @@ public class FileProcessingTest extends AbstractPersistenceServerServiceTest {
assertThat(file.getOcrStartTime()).isNull();
fileProcessingClient.analysisFailed(dossier.getId(), file.getId());
fileProcessingClient.analysisFailed(dossier.getId(), file.getId(), new FileErrorInfo());
var loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.ERROR);
@ -68,7 +69,7 @@ public class FileProcessingTest extends AbstractPersistenceServerServiceTest {
assertThat(loadedFile.getWorkflowStatus()).isEqualTo(WorkflowStatus.NEW);
assertThat(loadedFile.getAnalysisVersion()).isEqualTo(0);
fileProcessingClient.ocrFailed(dossier.getId(), file.getId());
fileProcessingClient.ocrFailed(dossier.getId(), file.getId(), new FileErrorInfo());
loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.ERROR);
@ -81,7 +82,7 @@ public class FileProcessingTest extends AbstractPersistenceServerServiceTest {
assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.INDEXING);
assertThat(loadedFile.getLastIndexed()).isNull();
fileProcessingClient.indexingFailed(dossier.getId(), file.getId());
fileProcessingClient.indexingFailed(dossier.getId(), file.getId(), new FileErrorInfo());
loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.ERROR);
@ -102,9 +103,11 @@ public class FileProcessingTest extends AbstractPersistenceServerServiceTest {
assertThat(file.getOcrStartTime()).isNull();
fileProcessingClient.analysisFailed(dossier.getId(), file.getId());
var queue = "queue1";
fileProcessingClient.analysisFailed(dossier.getId(), file.getId(), new FileErrorInfo("something failed", queue, "service"));
var loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.ERROR);
assertThat(loadedFile.getFileErrorInfo().getQueue()).isEqualTo(queue);
fileProcessingClient.analysisSuccessful(dossier.getId(),
file.getId(),
@ -129,7 +132,7 @@ public class FileProcessingTest extends AbstractPersistenceServerServiceTest {
// assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.DELETED);
assertThat(loadedFile.getSoftDeletedTime()).isNotNull();
fileProcessingClient.indexingFailed(dossier.getId(), file.getId());
fileProcessingClient.indexingFailed(dossier.getId(), file.getId(), new FileErrorInfo());
loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
// assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.DELETED);
assertThat(loadedFile.getSoftDeletedTime()).isNotNull();
@ -202,9 +205,11 @@ public class FileProcessingTest extends AbstractPersistenceServerServiceTest {
var file = fileTesterAndProvider.testAndProvideFile(dossier);
fileProcessingClient.analysisFailed(dossier.getId(), file.getId());
fileProcessingClient.analysisFailed(dossier.getId(), file.getId(), new FileErrorInfo());
var loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
assertThat(loadedFile.getProcessingStatus()).isEqualTo(ProcessingStatus.ERROR);
assertThat(loadedFile.getFileErrorInfo()).isNotNull();
assertThat(loadedFile.getFileErrorInfo().getCause()).isEqualTo("analysisFailed");
reanalysisClient.reanalyzeFilesForDossier(dossier.getId(), List.of(loadedFile.getId()), true);
loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());

View File

@ -3,6 +3,7 @@ package com.iqser.red.service.persistence.service.v1.api.shared.model;
import java.time.OffsetDateTime;
import java.util.Set;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileErrorInfo;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.ProcessingStatus;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.WorkflowStatus;
@ -138,6 +139,8 @@ public class FileStatus {
private int analysisVersion;
@Schema(description = "Last time the file was indexed in ES.")
private OffsetDateTime lastIndexed;
@Schema(description = "The error information for the error state of the file")
private FileErrorInfo fileErrorInfo;
@Schema(description = "Shows if this file has been OCRed by us. Last Time of OCR.")
public OffsetDateTime getLastOCRTime() {

View File

@ -0,0 +1,17 @@
package com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class FileErrorInfo {
private String cause;
private String queue;
private String service;
}

View File

@ -70,6 +70,7 @@ public class FileModel {
private OffsetDateTime redactionModificationDate;
private OffsetDateTime fileManipulationDate;
private boolean hasHighlights;
private FileErrorInfo fileErrorInfo;
public boolean isAnalysisRequired() {