From 7d875ee7eba6e6dfa6171cd80c5c7a3cd2dfc5c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominique=20Eifl=C3=A4nder?= Date: Wed, 22 May 2024 14:48:45 +0200 Subject: [PATCH] RED-9147: Provide events via websocket --- .../impl/controller/DossierController.java | 12 ++- .../controller/FileAttributesController.java | 5 + .../build.gradle.kts | 4 +- .../configuration/WebSocketConfiguration.java | 95 +++++++++++++++++++ .../WebSocketSecurityConfig.java | 23 +++++ .../model/websocket/AnalyseEvent.java | 32 +++++++ .../model/websocket/AnalyseStatus.java | 10 ++ .../model/websocket/DossierEvent.java | 15 +++ .../model/websocket/DossierEventType.java | 5 + .../model/websocket/DownloadEvent.java | 19 ++++ .../processor/model/websocket/FileEvent.java | 19 ++++ .../model/websocket/FileEventType.java | 5 + .../model/websocket/NotificationEvent.java | 15 +++ .../AnalysisFlagsCalculationService.java | 3 + .../v1/processor/service/DownloadService.java | 4 +- .../v1/processor/service/FileService.java | 9 ++ .../FileStatusProcessingUpdateService.java | 4 +- .../processor/service/FileStatusService.java | 52 ++++++++-- .../processor/service/WebsocketService.java | 63 ++++++++++++ .../download/DownloadCompressingService.java | 3 + .../download/DownloadDLQMessageReceiver.java | 4 + .../download/DownloadPreparationService.java | 3 + .../download/DownloadProcessorService.java | 5 +- .../DownloadStatusPersistenceService.java | 1 + .../FileStatusPersistenceService.java | 11 ++- .../NotificationPersistenceService.java | 4 + .../LayoutParsingFinishedMessageReceiver.java | 7 ++ .../queue/OCRProcessingMessageReceiver.java | 16 +++- .../peristence/v1/server/Application.java | 5 + .../src/main/resources/application.yaml | 2 +- .../service/FileTesterAndProvider.java | 4 +- .../tests/DossierTemplateStatsTest.java | 2 +- .../tests/DownloadPreparationTest.java | 2 +- .../integration/tests/DownloadTest.java | 2 +- .../v1/server/integration/tests/FileTest.java | 2 +- .../AbstractPersistenceServerServiceTest.java | 3 + 36 files changed, 447 insertions(+), 23 deletions(-) create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/configuration/WebSocketConfiguration.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/configuration/WebSocketSecurityConfig.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/AnalyseEvent.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/AnalyseStatus.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/DossierEvent.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/DossierEventType.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/DownloadEvent.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/FileEvent.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/FileEventType.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/NotificationEvent.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/WebsocketService.java diff --git a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/DossierController.java b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/DossierController.java index 0fdfed37f..5bf26c6f1 100644 --- a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/DossierController.java +++ b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/DossierController.java @@ -18,6 +18,7 @@ import java.util.Set; import java.util.TreeSet; import java.util.stream.Collectors; +import com.iqser.red.service.persistence.management.v1.processor.model.websocket.DossierEventType; import com.iqser.red.service.persistence.management.v1.processor.service.DossierCreatorService; import org.apache.commons.lang3.StringUtils; @@ -41,6 +42,7 @@ import com.iqser.red.service.persistence.management.v1.processor.roles.Applicati import com.iqser.red.service.persistence.management.v1.processor.service.AccessControlService; import com.iqser.red.service.persistence.management.v1.processor.service.DossierManagementService; import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusManagementService; +import com.iqser.red.service.persistence.management.v1.processor.service.WebsocketService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.NotificationPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.users.UserService; @@ -76,6 +78,7 @@ public class DossierController implements DossierResource { private final AccessControlService accessControlService; private final DossierACLService dossierACLService; private final DossierCreatorService dossierCreatorService; + private final WebsocketService websocketService; @Override @@ -217,6 +220,8 @@ public class DossierController implements DossierResource { .target(Map.of("dossierId", dossierRequest.getDossierId())) .build())); + websocketService.sendDossierEvent(dossierRequest.getDossierId(), DossierEventType.UPDATE); + HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setContentType(MediaType.APPLICATION_JSON); return new ResponseEntity<>(updatedDossier, httpHeaders, HttpStatus.OK); @@ -231,6 +236,7 @@ public class DossierController implements DossierResource { .message("Dossier has been created.") .build()); + websocketService.sendDossierEvent(created.getId(), DossierEventType.CREATE); HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setContentType(MediaType.APPLICATION_JSON); return new ResponseEntity<>(created, httpHeaders, HttpStatus.CREATED); @@ -387,6 +393,7 @@ public class DossierController implements DossierResource { .target(Map.of("dossierId", dossierId, "dossierName", dossier.getDossierName())) .build())); + websocketService.sendDossierEvent(dossierId, DossierEventType.SOFT_DELETE); } @@ -476,6 +483,7 @@ public class DossierController implements DossierResource { .category(AuditCategory.DOSSIER.name()) .message("Dossier archived.") .build()); + websocketService.sendDossierEvent(dossierId, DossierEventType.ARCHIVE); } } @@ -493,6 +501,7 @@ public class DossierController implements DossierResource { .category(AuditCategory.DOSSIER.name()) .message("Dossier restored from archive.") .build()); + websocketService.sendDossierEvent(dossierId, DossierEventType.UNARCHIVE); } } @@ -513,7 +522,7 @@ public class DossierController implements DossierResource { .category(AuditCategory.DOSSIER.name()) .message("Dossier permanently deleted.") .build()); - + websocketService.sendDossierEvent(dossierId, DossierEventType.HARD_DELETE); } } @@ -533,6 +542,7 @@ public class DossierController implements DossierResource { .category(AuditCategory.DOSSIER.name()) .message("Dossier restored from trash.") .build()); + websocketService.sendDossierEvent(dossierId, DossierEventType.UNDELETE); } } diff --git a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/FileAttributesController.java b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/FileAttributesController.java index 6d7c18f24..590ab81ea 100644 --- a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/FileAttributesController.java +++ b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/FileAttributesController.java @@ -13,6 +13,9 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; +import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity; +import com.iqser.red.service.persistence.management.v1.processor.model.websocket.FileEventType; +import com.iqser.red.service.persistence.management.v1.processor.service.WebsocketService; import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity; import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.FileAttributesGeneralConfigurationEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileAttributeConfigEntity; @@ -47,6 +50,7 @@ public class FileAttributesController implements FileAttributesResource { private final AuditPersistenceService auditPersistenceService; private final FileStatusService fileStatusService; private final AccessControlService accessControlService; + private final WebsocketService websocketService; @Override @@ -161,6 +165,7 @@ public class FileAttributesController implements FileAttributesResource { } accessControlService.verifyUserIsMemberOrApprover(dossierId); fileAttributesManagementService.setFileAttributes(dossierId, fileId, fileAttributes.getAttributeIdToValue()); + websocketService.sendFileEvent(dossierId, fileId, FileEventType.UPDATE); auditPersistenceService.audit(AuditRequest.builder() .userId(KeycloakSecurity.getUserId()) .objectId(fileId) diff --git a/persistence-service-v1/persistence-service-processor-v1/build.gradle.kts b/persistence-service-v1/persistence-service-processor-v1/build.gradle.kts index ced472f2b..dbf220411 100644 --- a/persistence-service-v1/persistence-service-processor-v1/build.gradle.kts +++ b/persistence-service-v1/persistence-service-processor-v1/build.gradle.kts @@ -37,7 +37,7 @@ dependencies { } api("com.knecon.fforesight:jobs-commons:0.10.0") api("com.knecon.fforesight:database-tenant-commons:0.24.0") - api("com.knecon.fforesight:keycloak-commons:0.28.0") + api("com.knecon.fforesight:keycloak-commons:0.29.0") api("com.knecon.fforesight:tracing-commons:0.5.0") api("com.knecon.fforesight:swagger-commons:0.7.0") api("com.giffing.bucket4j.spring.boot.starter:bucket4j-spring-boot-starter:0.4.0") @@ -47,6 +47,8 @@ dependencies { api("org.springframework.boot:spring-boot-starter-data-redis:${springBootStarterVersion}") api("org.springframework.boot:spring-boot-starter-amqp:${springBootStarterVersion}") api("org.springframework.boot:spring-boot-starter-web:${springBootStarterVersion}") + api("org.springframework.boot:spring-boot-starter-websocket:${springBootStarterVersion}") + api("org.springframework.security:spring-security-messaging:6.1.3") api("com.iqser.red.commons:spring-commons:2.1.0") api("com.iqser.red.commons:jackson-commons:2.1.0") api("com.iqser.red.commons:storage-commons:2.45.0") diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/configuration/WebSocketConfiguration.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/configuration/WebSocketConfiguration.java new file mode 100644 index 000000000..9462eec45 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/configuration/WebSocketConfiguration.java @@ -0,0 +1,95 @@ +package com.iqser.red.service.persistence.management.v1.processor.configuration; + +import java.util.Collections; +import java.util.Optional; + +import org.apache.tomcat.websocket.server.WsSci; +import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer; +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageChannel; +import org.springframework.messaging.simp.config.ChannelRegistration; +import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.messaging.simp.stomp.StompCommand; +import org.springframework.messaging.simp.stomp.StompHeaderAccessor; +import org.springframework.messaging.support.ChannelInterceptor; +import org.springframework.messaging.support.MessageHeaderAccessor; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; +import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; +import org.springframework.web.socket.config.annotation.StompEndpointRegistry; +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; + +import com.knecon.fforesight.keycloakcommons.security.TenantAuthenticationManagerResolver; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Configuration +@EnableWebSocketMessageBroker +@RequiredArgsConstructor +public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer { + + private final TenantAuthenticationManagerResolver tenantAuthenticationManagerResolver; + + + @Override + public void configureMessageBroker(MessageBrokerRegistry config) { + + config.enableSimpleBroker("/topic"); + config.setApplicationDestinationPrefixes("/app"); + } + + + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + + registry.addEndpoint("/redaction-gateway-v1/websocket").setAllowedOrigins("*"); + } + + + @Override + public void configureClientInboundChannel(ChannelRegistration registration) { + + // https://docs.spring.io/spring-framework/reference/web/websocket/stomp/authentication-token-based.html + registration.interceptors(new ChannelInterceptor() { + @Override + public Message preSend(Message message, MessageChannel channel) { + + StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class); + if (StompCommand.CONNECT.equals(accessor.getCommand())) { + Optional.ofNullable(accessor.getNativeHeader("Authorization")) + .ifPresent(ah -> { + String bearerToken = ah.get(0).replace("Bearer ", ""); + log.debug("Received bearer token {}", bearerToken); + AuthenticationManager authenticationManager = tenantAuthenticationManagerResolver.resolve(bearerToken); + JwtAuthenticationToken token = (JwtAuthenticationToken) authenticationManager.authenticate(new BearerTokenAuthenticationToken(bearerToken)); + accessor.setUser(token); + }); + } + return message; + } + }); + } + + + @Bean + public TomcatServletWebServerFactory tomcatContainerFactory() { + + TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(); + factory.setTomcatContextCustomizers(Collections.singletonList(tomcatContextCustomizer())); + return factory; + } + + + @Bean + public TomcatContextCustomizer tomcatContextCustomizer() { + + return context -> context.addServletContainerInitializer(new WsSci(), null); + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/configuration/WebSocketSecurityConfig.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/configuration/WebSocketSecurityConfig.java new file mode 100644 index 000000000..12f57f2d6 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/configuration/WebSocketSecurityConfig.java @@ -0,0 +1,23 @@ +//package com.iqser.red.service.persistence.management.v1.processor.configuration; +// +//import org.springframework.context.annotation.Bean; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.messaging.Message; +//import org.springframework.security.authorization.AuthorizationManager; +//import org.springframework.security.config.annotation.web.socket.EnableWebSocketSecurity; +//import org.springframework.security.messaging.access.intercept.MessageMatcherDelegatingAuthorizationManager; +// +//@Configuration +//@EnableWebSocketSecurity +//public class WebSocketSecurityConfig { +// +// @Bean +// AuthorizationManager> messageAuthorizationManager(MessageMatcherDelegatingAuthorizationManager.Builder messages) { +// +// messages +// .simpDestMatchers("/redaction-gateway-v1/websocket/**", "/redaction-gateway-v1/websocket/**/**").authenticated() +// .anyMessage().authenticated(); +// +// return messages.build(); +// } +//} \ 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/websocket/AnalyseEvent.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/AnalyseEvent.java new file mode 100644 index 000000000..3ca4d5b0d --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/AnalyseEvent.java @@ -0,0 +1,32 @@ +package com.iqser.red.service.persistence.management.v1.processor.model.websocket; + +import java.time.OffsetDateTime; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AnalyseEvent { + + private String dossierId; + private String fileId; + private AnalyseStatus analyseStatus; + private Integer analysisNumber; + private OffsetDateTime timestamp; + private int numberOfPagesToOCR; + private int numberOfOCRedPages; + + public AnalyseEvent(String dossierId, String fileId, AnalyseStatus analyseStatus, Integer analysisNumber, OffsetDateTime timestamp) { + this.dossierId = dossierId; + this.fileId = fileId; + this.analyseStatus = analyseStatus; + this.analysisNumber = analysisNumber; + this.timestamp = timestamp; + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/AnalyseStatus.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/AnalyseStatus.java new file mode 100644 index 000000000..5963f1f77 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/AnalyseStatus.java @@ -0,0 +1,10 @@ +package com.iqser.red.service.persistence.management.v1.processor.model.websocket; + +public enum AnalyseStatus { + READ_ONLY_PROCESSING, + PROCESSING, + OCR_PROCESSING, + LAYOUT_UPDATE, + FINISHED, + ERROR +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/DossierEvent.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/DossierEvent.java new file mode 100644 index 000000000..f8eefbde7 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/DossierEvent.java @@ -0,0 +1,15 @@ +package com.iqser.red.service.persistence.management.v1.processor.model.websocket; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DossierEvent { + private String dossierId; + private DossierEventType dossierEventType; +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/DossierEventType.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/DossierEventType.java new file mode 100644 index 000000000..7399e1c5a --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/DossierEventType.java @@ -0,0 +1,5 @@ +package com.iqser.red.service.persistence.management.v1.processor.model.websocket; + +public enum DossierEventType { + CREATE, UPDATE, SOFT_DELETE, HARD_DELETE, UNDELETE, ARCHIVE, UNARCHIVE +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/DownloadEvent.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/DownloadEvent.java new file mode 100644 index 000000000..9b64a898b --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/DownloadEvent.java @@ -0,0 +1,19 @@ +package com.iqser.red.service.persistence.management.v1.processor.model.websocket; + +import com.iqser.red.service.persistence.service.v1.api.shared.model.download.DownloadStatusValue; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DownloadEvent { + + private String downloadId; + private String userId; + private DownloadStatusValue status; +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/FileEvent.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/FileEvent.java new file mode 100644 index 000000000..244ca757b --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/FileEvent.java @@ -0,0 +1,19 @@ +package com.iqser.red.service.persistence.management.v1.processor.model.websocket; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FileEvent { + + private String dossierId; + private String fileId; + private FileEventType fileEventType; + + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/FileEventType.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/FileEventType.java new file mode 100644 index 000000000..c075d892a --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/FileEventType.java @@ -0,0 +1,5 @@ +package com.iqser.red.service.persistence.management.v1.processor.model.websocket; + +public enum FileEventType { + CREATE, UPDATE, SOFT_DELETE, HARD_DELETE, UNDELETE +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/NotificationEvent.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/NotificationEvent.java new file mode 100644 index 000000000..8c147a0b0 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/websocket/NotificationEvent.java @@ -0,0 +1,15 @@ +package com.iqser.red.service.persistence.management.v1.processor.model.websocket; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class NotificationEvent { + + private String userId; +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/AnalysisFlagsCalculationService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/AnalysisFlagsCalculationService.java index 3460baab1..e4c75d9b6 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/AnalysisFlagsCalculationService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/AnalysisFlagsCalculationService.java @@ -8,6 +8,7 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ViewedPageEntity; +import com.iqser.red.service.persistence.management.v1.processor.model.websocket.FileEventType; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.ViewedPagesPersistenceService; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry; @@ -35,6 +36,7 @@ public class AnalysisFlagsCalculationService { EntityLogService entityLogService; ViewedPagesPersistenceService viewedPagesPersistenceService; ObservationRegistry observationRegistry; + WebsocketService websocketService; @Timed("redactmanager_calculateFlags") @@ -137,6 +139,7 @@ public class AnalysisFlagsCalculationService { } fileStatusPersistenceService.setLastFlagCalculation(fileId, OffsetDateTime.now()); + websocketService.sendFileEvent(dossierId, fileId, FileEventType.UPDATE); } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/DownloadService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/DownloadService.java index 3a29c35ae..a60f18cd5 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/DownloadService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/DownloadService.java @@ -20,6 +20,7 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DownloadStatusPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.ReportTemplateRepository; +import com.iqser.red.service.persistence.service.v1.api.shared.model.download.DownloadStatusValue; import com.knecon.fforesight.databasetenantcommons.providers.utils.MagicConverter; import com.iqser.red.service.persistence.management.v1.processor.utils.StorageIdUtils; import com.iqser.red.service.persistence.service.v1.api.shared.model.common.JSONPrimitive; @@ -40,7 +41,7 @@ public class DownloadService { private final FileStatusPersistenceService fileStatusPersistenceService; private final DossierPersistenceService dossierPersistenceService; private final ReportTemplateRepository reportTemplateRepository; - private final ObjectMapper objectMapper; + private final WebsocketService websocketService; private final RabbitTemplate rabbitTemplate; @@ -87,6 +88,7 @@ public class DownloadService { request.getDownloadFileTypes(), request.getReportTemplateIds(), request.getRedactionPreviewColor()); + websocketService.sendDownloadEvent(storageId, request.getUserId(), DownloadStatusValue.QUEUED); addToDownloadQueue(DownloadJob.builder().storageId(storageId).userId(request.getUserId()).includeUnprocessed(request.getIncludeUnprocessed()).build(), 1); return new JSONPrimitive<>(storageId); diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileService.java index 1e19c6bd5..3ff3e3768 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileService.java @@ -15,6 +15,7 @@ import com.iqser.red.service.persistence.management.v1.processor.exception.Confl import com.iqser.red.service.persistence.management.v1.processor.exception.DossierNotFoundException; import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; import com.iqser.red.service.persistence.management.v1.processor.model.ManualChangesQueryOptions; +import com.iqser.red.service.persistence.management.v1.processor.model.websocket.FileEventType; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.ViewedPagesPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.AddRedactionPersistenceService; @@ -48,6 +49,7 @@ public class FileService { private final DossierPersistenceService dossierPersistenceService; private final DossierService dossierService; private final FileDeletionService fileDeletionService; + private final WebsocketService websocketService; public JSONPrimitive upload(AddFileRequest request, boolean keepManualRedactions, long size) { @@ -102,6 +104,7 @@ public class FileService { OffsetDateTime softDeleteTime = OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS); fileDeletionService.softDeleteFiles(List.of(fileId), softDeleteTime); fileDeletionService.reindexDeletedFiles(dossierId, List.of(fileId)); + websocketService.sendFileEvent(dossierId, fileId, FileEventType.SOFT_DELETE); } @@ -115,6 +118,9 @@ public class FileService { fileDeletionService.hardDeleteFiles(fileIds); fileDeletionService.hardDeleteFileDataAndIndexUpdates(dossierId, fileIds); + fileIds.forEach(fileId -> { + websocketService.sendFileEvent(dossierId, fileId, FileEventType.HARD_DELETE); + }); } @@ -131,6 +137,9 @@ public class FileService { fileDeletionService.undeleteFile(fileId, softDeletedTime); } fileDeletionService.reindexUndeletedFiles(dossier.getDossierTemplateId(), dossierId, fileIds); + fileIds.forEach(fileId -> { + websocketService.sendFileEvent(dossierId, fileId, FileEventType.UNDELETE); + }); } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileStatusProcessingUpdateService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileStatusProcessingUpdateService.java index 1ff6dc088..e8a48209b 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileStatusProcessingUpdateService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileStatusProcessingUpdateService.java @@ -47,7 +47,7 @@ public class FileStatusProcessingUpdateService { default: retryTemplate.execute(retryContext -> { log.info("Analysis Successful for dossier {} and file {}, Attempt to update status: {}", dossierId, fileId, retryContext.getRetryCount()); - fileStatusService.setStatusSuccessful(fileId, analyzeResult); + fileStatusService.setStatusSuccessful(dossierId, fileId, analyzeResult); return null; }); @@ -110,7 +110,7 @@ public class FileStatusProcessingUpdateService { fileId, dossierId, fileErrorInfo != null ? fileErrorInfo.getCause() : null); - fileStatusService.setStatusError(fileId, fileErrorInfo); + fileStatusService.setStatusError(dossierId, fileId, fileErrorInfo); return null; }); } 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 7f750d5b1..9818fefee 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 @@ -11,6 +11,8 @@ import java.util.stream.Collectors; import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException; import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.model.websocket.AnalyseStatus; +import com.iqser.red.service.persistence.management.v1.processor.model.websocket.FileEventType; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierTemplatePersistenceService; import org.apache.commons.lang3.StringUtils; import org.springframework.amqp.rabbit.core.RabbitTemplate; @@ -88,7 +90,7 @@ public class FileStatusService { ViewedPagesPersistenceService viewedPagesPersistenceService; FileManagementServiceSettings fileManagementServiceSettings; LayoutParsingRequestFactory layoutParsingRequestFactory; - + WebsocketService websocketService; @Transactional public List getAllRelevantStatusesForReanalysisScheduler() { @@ -173,8 +175,10 @@ public class FileStatusService { var dossier = dossierPersistenceService.getAndValidateDossier(dossierId); var fileEntity = fileStatusPersistenceService.getStatus(fileId); + if (!fileManagementStorageService.objectExists(dossierId, fileId, FileType.ORIGIN)) { addToPreprocessingQueue(dossierId, fileId, fileEntity.getFilename()); + sendReadOnlyAnalysisEvent(dossierId, fileId, fileEntity); return; } @@ -187,24 +191,28 @@ public class FileStatusService { 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); + sendReadOnlyAnalysisEvent(dossierId, fileId, fileEntity); 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); + sendReadOnlyAnalysisEvent(dossierId, fileId, fileEntity); return; } if (settings.isCvTableParsingEnabled() && !fileManagementStorageService.objectExists(dossierId, fileId, FileType.TABLES)) { log.debug("Add file: {} from dossier {} to Cv Service queue", fileId, dossierId); addToTableParsingRequestQueue(dossierId, fileId); + sendReadOnlyAnalysisEvent(dossierId, fileId, fileEntity); return; } if (settings.isImageServiceEnabled() && !fileManagementStorageService.objectExists(dossierId, fileId, FileType.IMAGE_INFO)) { log.info("Add file: {} from dossier {} to Image queue", fileId, dossierId); addToImageQueue(dossierId, fileId); + sendReadOnlyAnalysisEvent(dossierId, fileId, fileEntity); return; } @@ -215,6 +223,7 @@ public class FileStatusService { if (dossierTemplate.isOcrByDefault() && fileModel.getOcrEndTime() == null && !fileModel.isSoftOrHardDeleted()) { log.debug("Add file: {} from dossier {} to OCR queue", fileId, dossierId); setStatusOcrQueued(dossierId, fileId); + sendReadOnlyAnalysisEvent(dossierId, fileId, fileEntity); return; } @@ -222,12 +231,14 @@ public class FileStatusService { var layoutParsingRequest = layoutParsingRequestFactory.build(dossierId, fileId, priority); setStatusFullProcessing(fileId); rabbitTemplate.convertAndSend(LAYOUT_PARSING_REQUEST_QUEUE, layoutParsingRequest); + sendReadOnlyAnalysisEvent(dossierId, fileId, fileEntity); return; } if (settings.isNerServiceEnabled() && !fileManagementStorageService.objectExists(dossierId, fileId, FileType.NER_ENTITIES)) { log.debug("Add file: {} from dossier {} to NER queue", fileId, dossierId); addToNerQueue(dossierId, fileId); + sendReadOnlyAnalysisEvent(dossierId, fileId, fileEntity); return; } @@ -259,6 +270,20 @@ public class FileStatusService { } else { rabbitTemplate.convertAndSend(MessagingConfiguration.REDACTION_QUEUE, analyseRequest); } + sendAnalysisEvent(dossierId, fileId, fileEntity); + } + + + private void sendAnalysisEvent(String dossierId, String fileId, FileEntity fileEntity){ + if(fileEntity.getProcessingStatus().equals(ProcessingStatus.UNPROCESSED) || fileEntity.getProcessingStatus().equals(ProcessingStatus.ERROR) || fileEntity.getProcessingStatus().equals(ProcessingStatus.REPROCESS) || fileEntity.getProcessingStatus().equals(ProcessingStatus.PROCESSED)){ + websocketService.sendAnalysisEvent(dossierId, fileId, AnalyseStatus.PROCESSING, fileEntity.getNumberOfAnalyses() + 1); + } + } + + private void sendReadOnlyAnalysisEvent(String dossierId, String fileId, FileEntity fileEntity){ + if(fileEntity.getProcessingStatus().equals(ProcessingStatus.UNPROCESSED) || fileEntity.getProcessingStatus().equals(ProcessingStatus.ERROR) || fileEntity.getProcessingStatus().equals(ProcessingStatus.REPROCESS) || fileEntity.getProcessingStatus().equals(ProcessingStatus.PROCESSED) || fileEntity.getProcessingStatus().equals(ProcessingStatus.OCR_PROCESSING)){ + websocketService.sendAnalysisEvent(dossierId, fileId, AnalyseStatus.READ_ONLY_PROCESSING, fileEntity.getNumberOfAnalyses() + 1); + } } @@ -363,6 +388,7 @@ public class FileStatusService { updateOCRStartTime(fileId); fileStatusPersistenceService.updateProcessingStatus(fileId, ProcessingStatus.OCR_PROCESSING_QUEUED); + websocketService.sendAnalysisEvent(dossierId, fileId, AnalyseStatus.OCR_PROCESSING, fileStatus.getNumberOfAnalyses() + 1); addToOcrQueue(dossierId, fileId, 2); } @@ -480,9 +506,9 @@ public class FileStatusService { } - public void setStatusSuccessful(String fileId, AnalyzeResult analyzeResult) { + public void setStatusSuccessful(String dossierId, String fileId, AnalyzeResult analyzeResult) { - fileStatusPersistenceService.updateProcessingStatus(fileId, + fileStatusPersistenceService.updateProcessingStatus(dossierId, fileId, analyzeResult.getNumberOfPages(), analyzeResult.getDictionaryVersion(), analyzeResult.getRulesVersion(), @@ -504,6 +530,7 @@ public class FileStatusService { public void setApprovalStatusSuccessful(String dossierId, String fileId, WorkflowStatus workflowStatus) { fileStatusPersistenceService.updateWorkflowStatus(fileId, workflowStatus, true); + websocketService.sendFileEvent(dossierId, fileId, FileEventType.UPDATE); } @@ -559,13 +586,15 @@ public class FileStatusService { public void createStatus(String dossierId, String fileId, String uploader, String filename, long size) { fileStatusPersistenceService.createStatus(dossierId, fileId, filename, uploader, size); + websocketService.sendFileEvent(dossierId, fileId, FileEventType.CREATE); addToAnalysisQueue(dossierId, fileId, false, Set.of(), false); } public void setStatusIndexingSuccessful(String fileId) { - fileStatusPersistenceService.setUpdateStatusIndexingSuccessful(fileId); + FileEntity fileStatus = fileStatusPersistenceService.getStatus(fileId); + websocketService.sendFileEvent(fileStatus.getDossierId(), fileId, FileEventType.UPDATE); } @@ -575,22 +604,26 @@ public class FileStatusService { } - public void setStatusError(String fileId, FileErrorInfo fileErrorInfo) { + public void setStatusError(String dossierId, String fileId, FileErrorInfo fileErrorInfo) { fileStatusPersistenceService.updateStatusErrorInfo(fileId, fileErrorInfo); fileStatusPersistenceService.updateProcessingStatus(fileId, ProcessingStatus.ERROR); + websocketService.sendAnalysisEvent(dossierId, fileId, AnalyseStatus.ERROR, 0); } public void updateFileModificationDate(String fileId, OffsetDateTime fileManipulationDate) { - fileStatusPersistenceService.updateFileModificationDate(fileId, fileManipulationDate); + FileEntity fileStatus = fileStatusPersistenceService.getStatus(fileId); + websocketService.sendFileEvent(fileStatus.getDossierId(), fileId, FileEventType.UPDATE); } public void updateHasHighlights(String fileId, boolean hasHighlights) { fileStatusPersistenceService.updateHasHighlights(fileId, hasHighlights); + FileEntity fileStatus = fileStatusPersistenceService.getStatus(fileId); + websocketService.sendFileEvent(fileStatus.getDossierId(), fileId, FileEventType.UPDATE); } @@ -607,6 +640,7 @@ public class FileStatusService { } fileStatusPersistenceService.setAssignee(fileId, assignee, lastReviewer, lastApprover); + websocketService.sendFileEvent(fileStatus.getDossierId(), fileId, FileEventType.UPDATE); } @@ -614,6 +648,8 @@ public class FileStatusService { public void toggleExclusion(String dossierId, String fileId, boolean excluded) { fileStatusPersistenceService.toggleExclusion(fileId, excluded); + FileEntity fileStatus = fileStatusPersistenceService.getStatus(fileId); + websocketService.sendFileEvent(fileStatus.getDossierId(), fileId, FileEventType.UPDATE); if (!excluded) { setStatusFullReprocess(dossierId, fileId, false, true); @@ -648,6 +684,8 @@ public class FileStatusService { public void toggleAutomaticAnalysis(String dossierId, String fileId, boolean excludedFromAutomaticAnalysis) { fileStatusPersistenceService.toggleAutomaticAnalysis(fileId, excludedFromAutomaticAnalysis); + FileEntity fileStatus = fileStatusPersistenceService.getStatus(fileId); + websocketService.sendFileEvent(fileStatus.getDossierId(), fileId, FileEventType.UPDATE); if (!excludedFromAutomaticAnalysis) { setStatusFullReprocess(dossierId, fileId, false, true); @@ -691,6 +729,8 @@ public class FileStatusService { viewedPagesPersistenceService.deleteForFile(fileId); + FileEntity fileStatus = fileStatusPersistenceService.getStatus(fileId); + websocketService.sendFileEvent(fileStatus.getDossierId(), fileId, FileEventType.UPDATE); addToAnalysisQueue(dossierId, fileId, false, Set.of(), false); } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/WebsocketService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/WebsocketService.java new file mode 100644 index 000000000..3fd624280 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/WebsocketService.java @@ -0,0 +1,63 @@ +package com.iqser.red.service.persistence.management.v1.processor.service; + +import java.time.OffsetDateTime; +import java.time.temporal.ChronoUnit; + +import org.springframework.messaging.simp.SimpMessagingTemplate; +import org.springframework.stereotype.Service; + +import com.iqser.red.service.persistence.management.v1.processor.model.websocket.AnalyseEvent; +import com.iqser.red.service.persistence.management.v1.processor.model.websocket.AnalyseStatus; +import com.iqser.red.service.persistence.management.v1.processor.model.websocket.DossierEvent; +import com.iqser.red.service.persistence.management.v1.processor.model.websocket.DossierEventType; +import com.iqser.red.service.persistence.management.v1.processor.model.websocket.DownloadEvent; +import com.iqser.red.service.persistence.management.v1.processor.model.websocket.FileEvent; +import com.iqser.red.service.persistence.management.v1.processor.model.websocket.FileEventType; +import com.iqser.red.service.persistence.management.v1.processor.model.websocket.NotificationEvent; +import com.iqser.red.service.persistence.service.v1.api.shared.model.download.DownloadStatusValue; +import com.knecon.fforesight.tenantcommons.TenantContext; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Service +@RequiredArgsConstructor +public class WebsocketService { + + private final SimpMessagingTemplate template; + + + public void sendAnalysisEvent(String dossierId, String fileId, AnalyseStatus analyseStatus, int analysisNumber) { + + template.convertAndSend("/topic/" + TenantContext.getTenantId() + "/analysis-events", new AnalyseEvent(dossierId, fileId, analyseStatus, analysisNumber, OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS))); + } + + public void sendOcrUpdateAnalysisEvent(String dossierId, String fileId, AnalyseStatus analyseStatus, int analysisNumber, int numberOfPagesToOCR, int numberOfOCRedPages) { + + template.convertAndSend("/topic/" + TenantContext.getTenantId() + "/analysis-events", new AnalyseEvent(dossierId, fileId, analyseStatus, analysisNumber, OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS), numberOfPagesToOCR, numberOfOCRedPages)); + } + + + public void sendDownloadEvent(String downloadId, String userId, DownloadStatusValue downloadStatusValue){ + + template.convertAndSend("/topic/" + TenantContext.getTenantId() + "/download-events", new DownloadEvent(downloadId, userId, downloadStatusValue)); + } + + + public void sendFileEvent(String dossierId, String fileId, FileEventType fileEventType){ + + template.convertAndSend("/topic/" + TenantContext.getTenantId() + "/file-events", new FileEvent(dossierId, fileId, fileEventType)); + } + + + public void sendDossierEvent(String dossierId, DossierEventType dossierEventType){ + + template.convertAndSend("/topic/" + TenantContext.getTenantId() + "/dossier-events", new DossierEvent(dossierId, dossierEventType)); + } + + public void sendNotificationEvent(String userId){ + template.convertAndSend("/topic/" + TenantContext.getTenantId() + "/notification-events", new NotificationEvent(userId)); + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/download/DownloadCompressingService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/download/DownloadCompressingService.java index eaf6fcfa4..33456eea6 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/download/DownloadCompressingService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/download/DownloadCompressingService.java @@ -5,6 +5,7 @@ import org.springframework.stereotype.Service; import com.iqser.red.service.persistence.management.v1.processor.configuration.MessagingConfiguration; import com.iqser.red.service.persistence.management.v1.processor.model.DownloadJob; +import com.iqser.red.service.persistence.management.v1.processor.service.WebsocketService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DownloadStatusRepository; import com.iqser.red.service.persistence.service.v1.api.shared.model.download.DownloadStatusValue; @@ -19,6 +20,7 @@ public class DownloadCompressingService { private final DownloadPreparationService downloadPreparationService; private final DownloadStatusRepository downloadStatusRepository; private final RabbitTemplate rabbitTemplate; + private final WebsocketService websocketService; public void markDownloadForCompression(String downloadId, String userId) { @@ -26,6 +28,7 @@ public class DownloadCompressingService { var updated = downloadStatusRepository.updateStatusOnlyIfNotAlreadySet(downloadId, DownloadStatusValue.COMPRESSING); if (updated == 1) { + websocketService.sendDownloadEvent(downloadId, userId, DownloadStatusValue.COMPRESSING); rabbitTemplate.convertAndSend(MessagingConfiguration.DOWNLOAD_COMPRESSION_QUEUE, DownloadJob.builder().storageId(downloadId).userId(userId).build()); } } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/download/DownloadDLQMessageReceiver.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/download/DownloadDLQMessageReceiver.java index 1d88edbaf..44e8c9623 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/download/DownloadDLQMessageReceiver.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/download/DownloadDLQMessageReceiver.java @@ -10,6 +10,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.DownloadJob; +import com.iqser.red.service.persistence.management.v1.processor.service.WebsocketService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DownloadStatusPersistenceService; import com.iqser.red.service.persistence.service.v1.api.shared.model.download.DownloadStatusValue; import com.iqser.red.service.redaction.report.v1.api.model.ReportRequestMessage; @@ -28,6 +29,7 @@ public class DownloadDLQMessageReceiver { private final RetryTemplate retryTemplate; private final ObjectMapper objectMapper; private final static int MAX_ERROR_CAUSE_LENGTH = 1024; + private final WebsocketService websocketService; @RabbitListener(queues = MessagingConfiguration.DOWNLOAD_COMPRESSION_DLQ) @@ -85,6 +87,7 @@ public class DownloadDLQMessageReceiver { downloadStatusPersistenceService.updateStatus(downloadId, DownloadStatusValue.FAILED, "error occured in unknown queue"); return null; }); + websocketService.sendDownloadEvent(downloadId, userId, DownloadStatusValue.FAILED); } @@ -95,6 +98,7 @@ public class DownloadDLQMessageReceiver { downloadStatusPersistenceService.updateStatus(downloadId, DownloadStatusValue.FAILED, errorCause); return null; }); + websocketService.sendDownloadEvent(downloadId, userId, DownloadStatusValue.FAILED); } } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/download/DownloadPreparationService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/download/DownloadPreparationService.java index a4d3d6d8d..d7cd4ccc7 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/download/DownloadPreparationService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/download/DownloadPreparationService.java @@ -15,6 +15,7 @@ import com.iqser.red.service.persistence.management.v1.processor.entity.download import com.iqser.red.service.persistence.management.v1.processor.entity.download.DownloadStatusEntity; import com.iqser.red.service.persistence.management.v1.processor.service.ColorsService; import com.iqser.red.service.persistence.management.v1.processor.service.FileManagementStorageService; +import com.iqser.red.service.persistence.management.v1.processor.service.WebsocketService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierTemplatePersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DownloadStatusPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.NotificationPersistenceService; @@ -63,6 +64,7 @@ public class DownloadPreparationService { FileManagementServiceSettings settings; DossierTemplatePersistenceService dossierTemplatePersistenceService; DownloadRedactionFileStatusRepository downloadRedactionFileStatusRepository; + WebsocketService websocketService; @Transactional @@ -220,6 +222,7 @@ public class DownloadPreparationService { private void updateStatusToReady(DownloadStatusEntity downloadStatus, FileSystemBackedArchiver fileSystemBackedArchiver) { downloadStatusPersistenceService.updateStatus(downloadStatus, DownloadStatusValue.READY, fileSystemBackedArchiver.getContentLength()); + websocketService.sendDownloadEvent(downloadStatus.getStorageId(), downloadStatus.getUserId(), DownloadStatusValue.READY); } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/download/DownloadProcessorService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/download/DownloadProcessorService.java index d9054dbd4..8461bdbd6 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/download/DownloadProcessorService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/download/DownloadProcessorService.java @@ -14,6 +14,7 @@ import com.iqser.red.service.persistence.management.v1.processor.entity.dossier. import com.iqser.red.service.persistence.management.v1.processor.entity.download.DownloadStatusEntity; import com.iqser.red.service.persistence.management.v1.processor.model.DownloadJob; import com.iqser.red.service.persistence.management.v1.processor.service.DossierService; +import com.iqser.red.service.persistence.management.v1.processor.service.WebsocketService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DownloadStatusPersistenceService; import com.iqser.red.service.persistence.service.v1.api.shared.model.download.DownloadStatusValue; import com.iqser.red.service.redaction.report.v1.api.model.ReportRequestMessage; @@ -28,7 +29,7 @@ public class DownloadProcessorService { private final DownloadStatusPersistenceService downloadStatusPersistenceService; private final DossierService dossierService; private final RabbitTemplate rabbitTemplate; - private final ObjectMapper objectMapper; + private final WebsocketService websocketService; @Transactional @@ -36,6 +37,8 @@ public class DownloadProcessorService { DownloadStatusEntity downloadStatus = downloadStatusPersistenceService.getStatus(downloadJob.getStorageId()); downloadStatusPersistenceService.updateStatus(downloadJob.getStorageId(), DownloadStatusValue.GENERATING); + websocketService.sendDownloadEvent(downloadJob.getStorageId(), downloadJob.getUserId(), DownloadStatusValue.GENERATING); + var dossier = dossierService.getDossierById(downloadStatus.getFiles() .iterator().next().getDossierId()); diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DownloadStatusPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DownloadStatusPersistenceService.java index 4db310d0e..3d12ae614 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DownloadStatusPersistenceService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DownloadStatusPersistenceService.java @@ -58,6 +58,7 @@ public class DownloadStatusPersistenceService { downloadStatus.setDownloadFileTypes(downloadFileTypes != null ? new HashSet<>(downloadFileTypes) : new HashSet<>()); downloadStatus.setReports(reportTemplateIds != null ? reportTemplateRepository.findAllById(reportTemplateIds) : new ArrayList<>()); downloadStatus.setRedactionPreviewColor(redactionPreviewColor); + downloadStatus.setStatus(DownloadStatusValue.QUEUED); downloadStatusRepository.save(downloadStatus); } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/FileStatusPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/FileStatusPersistenceService.java index d07367561..d47301caa 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/FileStatusPersistenceService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/FileStatusPersistenceService.java @@ -18,6 +18,8 @@ import com.iqser.red.service.persistence.management.v1.processor.exception.BadRe import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; import com.iqser.red.service.persistence.management.v1.processor.model.FileIdentifier; import com.iqser.red.service.persistence.management.v1.processor.model.OCRStatusUpdateResponse; +import com.iqser.red.service.persistence.management.v1.processor.model.websocket.AnalyseStatus; +import com.iqser.red.service.persistence.management.v1.processor.service.WebsocketService; 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; @@ -39,6 +41,7 @@ public class FileStatusPersistenceService { private final FileAttributesRepository fileAttributesRepository; private final FileAttributeConfigPersistenceService fileAttributeConfigPersistenceService; private final DossierPersistenceService dossierService; + private final WebsocketService websocketService; public void createStatus(String dossierId, String fileId, String filename, String uploader, long size) { @@ -108,7 +111,8 @@ public class FileStatusPersistenceService { @Transactional - public void updateProcessingStatus(String fileId, + public void updateProcessingStatus(String dossierId, + String fileId, int numberOfPages, long dictionaryVersion, long rulesVersion, @@ -136,6 +140,8 @@ public class FileStatusPersistenceService { OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS), analysisNumber, calculateProcessingErrorCounter(fileId, ProcessingStatus.PROCESSED)); + + websocketService.sendAnalysisEvent(dossierId, fileId, AnalyseStatus.FINISHED, analysisNumber); } @@ -420,12 +426,13 @@ public class FileStatusPersistenceService { } } + public void softDeleteFiles(List fileIds, OffsetDateTime softDeletedTime) { + fileRepository.softDeleteFiles(fileIds, ProcessingStatus.PROCESSED, OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS), softDeletedTime); } - public void hardDeleteFiles(List fileIds) { var now = OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS); diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/NotificationPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/NotificationPersistenceService.java index 96572bf34..ffc38d139 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/NotificationPersistenceService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/NotificationPersistenceService.java @@ -10,6 +10,7 @@ import org.springframework.stereotype.Service; import com.iqser.red.service.persistence.management.v1.processor.entity.notification.NotificationEntity; import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; import com.iqser.red.service.persistence.management.v1.processor.service.NotificationPreferencesService; +import com.iqser.red.service.persistence.management.v1.processor.service.WebsocketService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.NotificationRepository; import com.iqser.red.service.persistence.service.v1.api.shared.model.audit.AddNotificationRequest; import com.iqser.red.service.persistence.service.v1.api.shared.model.notification.EmailNotificationType; @@ -28,6 +29,8 @@ public class NotificationPersistenceService { private final NotificationEmailService notificationEmailService; + private final WebsocketService websocketService; + public boolean hasNewNotificationsSince(String userId, OffsetDateTime since) { @@ -56,6 +59,7 @@ public class NotificationPersistenceService { } notificationRepository.save(notification); + websocketService.sendNotificationEvent(notification.getUserId()); } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/queue/LayoutParsingFinishedMessageReceiver.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/queue/LayoutParsingFinishedMessageReceiver.java index 5b6003e96..4ac94ca82 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/queue/LayoutParsingFinishedMessageReceiver.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/queue/LayoutParsingFinishedMessageReceiver.java @@ -4,8 +4,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.exc.ValueInstantiationException; import com.iqser.red.service.persistence.management.v1.processor.configuration.MessagingConfiguration; import com.iqser.red.service.persistence.management.v1.processor.migration.SaasMigrationService; +import com.iqser.red.service.persistence.management.v1.processor.model.websocket.AnalyseStatus; 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.management.v1.processor.service.WebsocketService; import com.iqser.red.service.persistence.management.v1.processor.service.layoutparsing.LayoutParsingRequestIdentifierService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.SaasMigrationStatusPersistenceService; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileErrorInfo; @@ -35,6 +37,7 @@ public class LayoutParsingFinishedMessageReceiver { private final LayoutParsingRequestIdentifierService layoutParsingRequestIdentifierService; private final SaasMigrationStatusPersistenceService saasMigrationStatusPersistenceService; private final SaasMigrationService saasMigrationService; + private final WebsocketService websocketService; @SneakyThrows @@ -47,11 +50,15 @@ public class LayoutParsingFinishedMessageReceiver { return; } + var dossierId = layoutParsingRequestIdentifierService.parseDossierId(response.identifier()); + var fileId = layoutParsingRequestIdentifierService.parseFileId(response.identifier()); + fileStatusService.setStatusAnalyse(layoutParsingRequestIdentifierService.parseDossierId(response.identifier()), layoutParsingRequestIdentifierService.parseFileId(response.identifier()), layoutParsingRequestIdentifierService.parsePriority(response.identifier())); fileStatusService.updateLayoutProcessedTime(layoutParsingRequestIdentifierService.parseFileId(response.identifier())); + websocketService.sendAnalysisEvent(dossierId, fileId, AnalyseStatus.LAYOUT_UPDATE, fileStatusService.getStatus(fileId).getNumberOfAnalyses() + 1); log.info("Received message {} in {}", response, LayoutParsingQueueNames.LAYOUT_PARSING_FINISHED_EVENT_QUEUE); } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/queue/OCRProcessingMessageReceiver.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/queue/OCRProcessingMessageReceiver.java index aae0f6861..7730046c4 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/queue/OCRProcessingMessageReceiver.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/queue/OCRProcessingMessageReceiver.java @@ -12,11 +12,14 @@ 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.OCRStatusUpdateResponse; +import com.iqser.red.service.persistence.management.v1.processor.model.websocket.AnalyseStatus; 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.management.v1.processor.service.WebsocketService; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileErrorInfo; import com.knecon.fforesight.service.ocr.v1.api.model.DocumentRequest; + import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -29,16 +32,25 @@ public class OCRProcessingMessageReceiver { private final ObjectMapper objectMapper; private final FileStatusService fileStatusService; private final FileStatusProcessingUpdateService fileStatusProcessingUpdateService; + private final WebsocketService websocketService; @SneakyThrows @RabbitListener(queues = MessagingConfiguration.OCR_STATUS_UPDATE_RESPONSE_QUEUE) public void handleOCRStatusUpdateMessage(OCRStatusUpdateResponse response) { + var fileModel = fileStatusService.getStatus(response.getFileId()); + if (response.isOcrStarted()) { fileStatusProcessingUpdateService.ocrProcessingUpdateOnly(response.getFileId()); } else { fileStatusService.updateOCRStatus(response); + websocketService.sendOcrUpdateAnalysisEvent(fileModel.getDossierId(), + fileModel.getId(), + AnalyseStatus.OCR_PROCESSING, + fileModel.getNumberOfAnalyses() + 1, + response.getNumberOfPagesToOCR(), + response.getNumberOfOCRedPages()); } log.info("Received message {} in {}", response, MessagingConfiguration.OCR_STATUS_UPDATE_RESPONSE_QUEUE); @@ -77,8 +89,8 @@ public class OCRProcessingMessageReceiver { OffsetDateTime timestamp = failedMessage.getMessageProperties().getHeader(MessagingConfiguration.X_ERROR_INFO_TIMESTAMP_HEADER); timestamp = timestamp != null ? timestamp : OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS); fileStatusProcessingUpdateService.requeueOCROrMarkFailed(ocrRequestMessage.getDossierId(), - ocrRequestMessage.getFileId(), - new FileErrorInfo(errorMessage, MessagingConfiguration.OCR_DLQ, "ocr-service", timestamp)); + ocrRequestMessage.getFileId(), + new FileErrorInfo(errorMessage, MessagingConfiguration.OCR_DLQ, "ocr-service", timestamp)); } } diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/Application.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/Application.java index acfeca435..c4f7974eb 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/Application.java +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/Application.java @@ -1,8 +1,11 @@ package com.iqser.red.service.peristence.v1.server; +import java.util.Collections; import java.util.Map; import java.util.Optional; +import org.apache.catalina.Context; +import org.apache.tomcat.websocket.server.WsSci; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; @@ -18,6 +21,8 @@ import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfigurati import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer; +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yaml b/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yaml index 79125b8b8..a6bd7209b 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yaml +++ b/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yaml @@ -135,7 +135,7 @@ bucket4j: fforesight: keycloak: - ignored-endpoints: [ '/redaction-gateway-v1','/actuator/health/**', '/redaction-gateway-v1/async/download/with-ott/**', + ignored-endpoints: [ '/redaction-gateway-v1', '/actuator/health/**',"/redaction-gateway-v1/websocket","/redaction-gateway-v1/websocket/**", '/redaction-gateway-v1/async/download/with-ott/**', '/internal-api/**', '/redaction-gateway-v1/docs/swagger-ui', '/redaction-gateway-v1/docs/**','/redaction-gateway-v1/docs', '/api', '/api/','/api/docs/**','/api/docs','/api/docs/swagger-ui' ] diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/service/FileTesterAndProvider.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/service/FileTesterAndProvider.java index d702fb1c6..92332f560 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/service/FileTesterAndProvider.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/service/FileTesterAndProvider.java @@ -103,7 +103,7 @@ public class FileTesterAndProvider { } - public void markFileAsProcessed(String fileId) { + public void markFileAsProcessed(String dossierId, String fileId) { AnalyzeResult result = new AnalyzeResult(); result.setFileId(fileId); @@ -115,7 +115,7 @@ public class FileTesterAndProvider { result.setDossierDictionaryVersion(1); result.setAnalysisNumber(1); result.setAnalysisVersion(1); - fileStatusService.setStatusSuccessful(fileId, result); + fileStatusService.setStatusSuccessful(dossierId, fileId, result); fileStatusService.setStatusProcessed(fileId); } diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DossierTemplateStatsTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DossierTemplateStatsTest.java index fb7674c77..55535290d 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DossierTemplateStatsTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DossierTemplateStatsTest.java @@ -298,7 +298,7 @@ public class DossierTemplateStatsTest extends AbstractPersistenceServerServiceTe var fileId = fileTesterAndProvider.testAndProvideFileQuick(dossier, "file: " + k); if (k == 1) { - fileStatusPersistenceService.updateProcessingStatus(fileId, k, 0L, 0L, 0L, 0L, 0L, 0L, 1, 1); + fileStatusPersistenceService.updateProcessingStatus(dossier.getId(), fileId, k, 0L, 0L, 0L, 0L, 0L, 0L, 1, 1); reanalysisClient.excludePages(dossier.getId(), fileId, new PageExclusionRequest(List.of(new PageRange(k, k)))); } if (k == 2) { diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DownloadPreparationTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DownloadPreparationTest.java index fe9391237..c6c01c5f3 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DownloadPreparationTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DownloadPreparationTest.java @@ -253,7 +253,7 @@ public class DownloadPreparationTest extends AbstractPersistenceServerServiceTes public void forwardFileToApprovedState() { - fileTesterAndProvider.markFileAsProcessed(getFileId()); + fileTesterAndProvider.markFileAsProcessed(getDossierId(), getFileId()); fileClient.setStatusApproved(getDossierId(), getFileId()); diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DownloadTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DownloadTest.java index 11be42521..0fc49111c 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DownloadTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DownloadTest.java @@ -81,7 +81,7 @@ public class DownloadTest extends AbstractPersistenceServerServiceTest { var file = fileTesterAndProvider.testAndProvideFile(dossier); var file2 = fileTesterAndProvider.testAndProvideFile(dossier, "file2"); - fileTesterAndProvider.markFileAsProcessed(file2.getFileId()); + fileTesterAndProvider.markFileAsProcessed(dossier.getId(), file2.getFileId()); fileClient.setStatusApproved(dossier.getId(), file2.getId()); var file22 = fileClient.getFileStatus(dossier.getId(), file2.getId()); diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/FileTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/FileTest.java index 053ee759c..67953922d 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/FileTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/FileTest.java @@ -291,7 +291,7 @@ public class FileTest extends AbstractPersistenceServerServiceTest { assertThat(loadedFile.getLastReviewer()).isEqualTo(userId); assertThat(loadedFile.getLastApprover()).isEqualTo(userId); - fileTesterAndProvider.markFileAsProcessed(file.getFileId()); + fileTesterAndProvider.markFileAsProcessed(dossier.getId(), file.getFileId()); fileClient.setStatusApproved(dossier.getId(), file.getId()); loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId()); assertThat(loadedFile.getWorkflowStatus()).isEqualTo(WorkflowStatus.APPROVED); diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/AbstractPersistenceServerServiceTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/AbstractPersistenceServerServiceTest.java index bd634866d..8f9d9a87b 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/AbstractPersistenceServerServiceTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/AbstractPersistenceServerServiceTest.java @@ -110,6 +110,7 @@ import com.iqser.red.storage.commons.utils.FileSystemBackedStorageService; import com.knecon.fforesight.databasetenantcommons.providers.TenantCreatedListener; import com.knecon.fforesight.databasetenantcommons.providers.events.TenantCreatedEvent; import com.knecon.fforesight.databasetenantcommons.providers.utils.MagicConverter; +import com.knecon.fforesight.keycloakcommons.security.TenantAuthenticationManagerResolver; import com.knecon.fforesight.mongo.database.commons.liquibase.MongoTenantCreatedEvent; import com.knecon.fforesight.mongo.database.commons.liquibase.MongoTenantCreatedListener; import com.knecon.fforesight.tenantcommons.EncryptionDecryptionService; @@ -251,6 +252,8 @@ public abstract class AbstractPersistenceServerServiceTest { protected CommentRepository commentRepository; @Autowired protected ResizeRedactionRepository resizeRedactionRepository; + @MockBean + protected TenantAuthenticationManagerResolver tenantAuthenticationManagerResolver; private static String[] getAllRoles() {