diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/configuration/MessagingConfiguration.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/configuration/MessagingConfiguration.java index 73b8d6276..f4cdc196f 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/configuration/MessagingConfiguration.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/configuration/MessagingConfiguration.java @@ -64,6 +64,9 @@ public class MessagingConfiguration { public static final String CV_ANALYSIS_RESPONSE_QUEUE = "cv_analysis_response_queue"; public static final String CV_ANALYSIS_DLQ = "cv_analysis_dead_letter_queue"; + public static final String VISUAL_LAYOUT_PARSING_QUEUE = "visual_layout_parsing_service_queue"; + public static final String VISUAL_LAYOUT_RESPONSE_QUEUE = "visual_layout_parsing_service_response_queue"; + public static final String VISUAL_LAYOUT_DLQ = "visual_layout_parsing_service_dead_letter_queue"; public static final String ANALYSIS_FLAG_CALCULATION_QUEUE = "analysis_flag_calculation_queue"; public static final String OCR_STATUS_UPDATE_RESPONSE_QUEUE = "ocr_status_update_response_queue"; @@ -163,6 +166,28 @@ public class MessagingConfiguration { return QueueBuilder.durable(CV_ANALYSIS_DLQ).build(); } + @Bean + public Queue visualLayoutParsingRequestQueue() { + + return QueueBuilder.durable(VISUAL_LAYOUT_PARSING_QUEUE).withArgument("x-dead-letter-exchange", "").withArgument("x-dead-letter-routing-key", VISUAL_LAYOUT_DLQ).build(); + } + + + @Bean + public Queue visualLayoutParsingResponseQueue() { + + return QueueBuilder.durable(VISUAL_LAYOUT_RESPONSE_QUEUE) + .withArgument("x-dead-letter-exchange", "") + .withArgument("x-dead-letter-routing-key", VISUAL_LAYOUT_DLQ) + .build(); + } + + + @Bean + public Queue visualLayoutParsingDLQ() { + + return QueueBuilder.durable(VISUAL_LAYOUT_DLQ).build(); + } @Bean public Queue ocrStatusUpdateResponseQueue() { diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/VisualLayoutParsingServiceRequest.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/VisualLayoutParsingServiceRequest.java new file mode 100644 index 000000000..e0a0eb0d8 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/VisualLayoutParsingServiceRequest.java @@ -0,0 +1,24 @@ +package com.iqser.red.service.persistence.management.v1.processor.model; + +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class VisualLayoutParsingServiceRequest { + public static final String VISUAL_LAYOUT_PARSING_FILE_EXTENSION= FileType.VISUAL_LAYOUT.name() + FileType.VISUAL_LAYOUT.getExtension() + ".gz"; + + public static final String TARGET_FILE_EXTENSION = "ORIGIN.pdf.gz"; + + private String dossierId; + private String fileId; + private String targetFileExtension; + private String responseFileExtension; + +} \ No newline at end of file diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/image/VisualLayoutParsingServiceResponse.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/image/VisualLayoutParsingServiceResponse.java new file mode 100644 index 000000000..b7a1af9e6 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/image/VisualLayoutParsingServiceResponse.java @@ -0,0 +1,16 @@ +package com.iqser.red.service.persistence.management.v1.processor.model.image; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class VisualLayoutParsingServiceResponse { + + private String dossierId; + private String fileId; +} \ No newline at end of file diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileStatusService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileStatusService.java index 56c35812e..f85ad37b5 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileStatusService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileStatusService.java @@ -24,6 +24,7 @@ import com.iqser.red.service.persistence.management.v1.processor.model.CvAnalysi import com.iqser.red.service.persistence.management.v1.processor.model.FileIdentifier; import com.iqser.red.service.persistence.management.v1.processor.model.NerServiceRequest; import com.iqser.red.service.persistence.management.v1.processor.model.OCRStatusUpdateResponse; +import com.iqser.red.service.persistence.management.v1.processor.model.VisualLayoutParsingServiceRequest; import com.iqser.red.service.persistence.management.v1.processor.model.image.ImageServiceRequest; import com.iqser.red.service.persistence.management.v1.processor.service.layoutparsing.LayoutParsingRequestFactory; import com.iqser.red.service.persistence.management.v1.processor.service.manualredactions.ManualRedactionProviderService; @@ -176,6 +177,12 @@ public class FileStatusService { return; } + if (settings.isVisualLayoutParsingEnabled() && !fileManagementStorageService.objectExists(dossierId, fileId, FileType.VISUAL_LAYOUT)) { + log.info("Add file: {} from dossier {} to Visual Layout Parsing queue", fileId, dossierId); + addToVisualLayoutParsingQueue(dossierId, fileId); + return; + } + if (settings.isFigureDetectionEnabled() && !fileManagementStorageService.objectExists(dossierId, fileId, FileType.FIGURE)) { log.debug("Add file: {} from dossier {} to Figure Detection queue", fileId, dossierId); addToFigureDetectionRequestQueue(dossierId, fileId); @@ -247,6 +254,21 @@ public class FileStatusService { } } + private void addToVisualLayoutParsingQueue(String dossierId, String fileId) { + fileStatusPersistenceService.updateProcessingStatus(fileId, ProcessingStatus.VISUAL_LAYOUT_PARSING_ANALYZING); + rabbitTemplate.convertAndSend(MessagingConfiguration.VISUAL_LAYOUT_PARSING_QUEUE, + VisualLayoutParsingServiceRequest.builder() + .dossierId(dossierId) + .fileId(fileId) + .targetFileExtension(VisualLayoutParsingServiceRequest.TARGET_FILE_EXTENSION) + .responseFileExtension(VisualLayoutParsingServiceRequest.VISUAL_LAYOUT_PARSING_FILE_EXTENSION) + .build(), + message -> { + message.getMessageProperties().setPriority(1); + log.info("answer from visual layout parsing: "+message); + return message; + }); + } @SneakyThrows public void addToPreprocessingQueue(String dossierId, String fileId, String filename) { diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/layoutparsing/LayoutParsingRequestFactory.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/layoutparsing/LayoutParsingRequestFactory.java index 796db6f24..e65424e9a 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/layoutparsing/LayoutParsingRequestFactory.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/layoutparsing/LayoutParsingRequestFactory.java @@ -39,12 +39,16 @@ public class LayoutParsingRequestFactory { Optional optionalTableFileId = fileManagementStorageService.objectExists(dossierId, fileId, FileType.TABLES) // ? Optional.of(StorageIdUtils.getStorageId(dossierId, fileId, FileType.TABLES)) : Optional.empty(); + Optional optionalVisualLayoutParsingFileId = fileManagementStorageService.objectExists(dossierId, fileId, FileType.VISUAL_LAYOUT) // + ? Optional.of(StorageIdUtils.getStorageId(dossierId, fileId, FileType.VISUAL_LAYOUT)) : Optional.empty(); + return LayoutParsingRequest.builder() .layoutParsingType(type) .identifier(layoutParsingRequestIdentifierService.buildIdentifier(dossierId, fileId, priority)) .originFileStorageId(StorageIdUtils.getStorageId(dossierId, fileId, FileType.ORIGIN)) .imagesFileStorageId(optionalImageFileId) .tablesFileStorageId(optionalTableFileId) + .visualLayoutParsingFileId(optionalVisualLayoutParsingFileId) .pageFileStorageId(StorageIdUtils.getStorageId(dossierId, fileId, FileType.DOCUMENT_PAGES)) .structureFileStorageId(StorageIdUtils.getStorageId(dossierId, fileId, FileType.DOCUMENT_STRUCTURE)) .textBlockFileStorageId(StorageIdUtils.getStorageId(dossierId, fileId, FileType.DOCUMENT_TEXT)) diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/queue/VisualLayoutParsingMessageReceiver.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/queue/VisualLayoutParsingMessageReceiver.java new file mode 100644 index 000000000..48eb30e9b --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/queue/VisualLayoutParsingMessageReceiver.java @@ -0,0 +1,54 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.queue; + +import java.time.OffsetDateTime; +import java.time.temporal.ChronoUnit; + +import org.springframework.amqp.core.Message; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +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.image.VisualLayoutParsingServiceResponse; +import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusProcessingUpdateService; +import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusService; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileErrorInfo; + +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Service +@RequiredArgsConstructor +public class VisualLayoutParsingMessageReceiver { + + private final ObjectMapper objectMapper; + private final FileStatusService fileStatusService; + private final FileStatusProcessingUpdateService fileStatusProcessingUpdateService; + + + @SneakyThrows + @RabbitListener(queues = MessagingConfiguration.VISUAL_LAYOUT_RESPONSE_QUEUE) + public void receive(VisualLayoutParsingServiceResponse response) { + + fileStatusService.setStatusAnalyse(response.getDossierId(), response.getFileId(), false); + + log.info("Received message in {} for dossierId {} and fileId {}", MessagingConfiguration.VISUAL_LAYOUT_RESPONSE_QUEUE, response.getDossierId(), response.getFileId()); + } + + + @SneakyThrows + @RabbitListener(queues = MessagingConfiguration.VISUAL_LAYOUT_DLQ) + public void handleDLQMessage(Message failedMessage) { + + var response = objectMapper.readValue(failedMessage.getBody(), VisualLayoutParsingServiceResponse.class); + + log.warn("Received message from {} for dossierId {} and fileId {}", MessagingConfiguration.VISUAL_LAYOUT_DLQ, response.getDossierId(), response.getFileId()); + fileStatusProcessingUpdateService.analysisFailed(response.getDossierId(), + response.getFileId(), + new FileErrorInfo("table extractor failed", MessagingConfiguration.VISUAL_LAYOUT_DLQ, "table-extractor", OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS))); + + } + +} \ No newline at end of file diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/settings/FileManagementServiceSettings.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/settings/FileManagementServiceSettings.java index 93e2ba057..c7fdcce6c 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/settings/FileManagementServiceSettings.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/settings/FileManagementServiceSettings.java @@ -24,6 +24,7 @@ public class FileManagementServiceSettings { private boolean imageServiceEnabled = true; private boolean nerServiceEnabled = true; + private boolean visualLayoutParsingEnabled = false; private boolean storeImageFile = true; diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/resources/application-dev.yaml b/persistence-service-v1/persistence-service-server-v1/src/main/resources/application-dev.yaml index 451cedd61..369f33352 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/main/resources/application-dev.yaml +++ b/persistence-service-v1/persistence-service-server-v1/src/main/resources/application-dev.yaml @@ -30,6 +30,7 @@ cors.enabled: true persistence-service: imageServiceEnabled: false + visualLayoutParsingEnabled: true nerServiceEnabled: false storeImageFile: false applicationName: RedactManager diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/dossier/file/FileType.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/dossier/file/FileType.java index 7e67f33ac..ca4ac41f7 100644 --- a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/dossier/file/FileType.java +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/dossier/file/FileType.java @@ -16,6 +16,8 @@ public enum FileType { TEXT_HIGHLIGHTS(".json"), FIGURE(".json"), TABLES(".json"), + + VISUAL_LAYOUT(".json"), COMPONENTS(".json"), // document is split into 4 files, all should be overridden/deleted at the same time DOCUMENT_TEXT(".json"), diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/dossier/file/ProcessingStatus.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/dossier/file/ProcessingStatus.java index f65ceabe1..a2125b0c2 100644 --- a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/dossier/file/ProcessingStatus.java +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/dossier/file/ProcessingStatus.java @@ -18,5 +18,7 @@ public enum ProcessingStatus { PRE_PROCESSING, PRE_PROCESSED, FIGURE_DETECTION_ANALYZING, - TABLE_PARSING_ANALYZING + TABLE_PARSING_ANALYZING, + + VISUAL_LAYOUT_PARSING_ANALYZING }