Merge branch 'RED-7834' into 'master'
RED-7834: fix migration issues Closes RED-7834 See merge request redactmanager/persistence-service!261
This commit is contained in:
commit
3b8b397fe5
@ -1,10 +1,19 @@
|
|||||||
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
|
package com.iqser.red.persistence.service.v1.external.api.impl.controller;
|
||||||
|
|
||||||
|
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.migration.SaasMigrationService;
|
||||||
|
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusService;
|
||||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.SaasMigrationStatusPersistenceService;
|
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.SaasMigrationStatusPersistenceService;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.external.resource.MigrationStatusResource;
|
import com.iqser.red.service.persistence.service.v1.api.external.resource.MigrationStatusResource;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.SaasMigrationStatus;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.SaasMigrationStatus;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.saas.migration.MigrationStatusResponse;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.saas.migration.MigrationStatusResponse;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -13,12 +22,19 @@ import java.util.Map;
|
|||||||
import static com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.SaasMigrationStatus.*;
|
import static com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.SaasMigrationStatus.*;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
|
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class MigrationStatusController implements MigrationStatusResource {
|
public class MigrationStatusController implements MigrationStatusResource {
|
||||||
|
|
||||||
private final SaasMigrationStatusPersistenceService saasMigrationStatusPersistenceService;
|
SaasMigrationService saasMigrationService;
|
||||||
|
|
||||||
|
SaasMigrationStatusPersistenceService saasMigrationStatusPersistenceService;
|
||||||
|
|
||||||
|
FileStatusService fileStatusService;
|
||||||
|
|
||||||
|
|
||||||
public MigrationStatusResponse migrationStatus() {
|
public MigrationStatusResponse migrationStatus() {
|
||||||
|
|
||||||
int numberOfFilesToMigrate = saasMigrationStatusPersistenceService.countAll();
|
int numberOfFilesToMigrate = saasMigrationStatusPersistenceService.countAll();
|
||||||
|
|
||||||
Map<SaasMigrationStatus, Integer> filesInStatus = new HashMap<>();
|
Map<SaasMigrationStatus, Integer> filesInStatus = new HashMap<>();
|
||||||
@ -36,10 +52,40 @@ public class MigrationStatusController implements MigrationStatusResource {
|
|||||||
errorCauses.put(errorFile.getFileId(), errorFile.getErrorCause());
|
errorCauses.put(errorFile.getFileId(), errorFile.getErrorCause());
|
||||||
});
|
});
|
||||||
|
|
||||||
return MigrationStatusResponse.builder()
|
return MigrationStatusResponse.builder().numberOfFilesToMigrate(numberOfFilesToMigrate).filesInStatus(filesInStatus).errorCauses(errorCauses).build();
|
||||||
.numberOfFilesToMigrate(numberOfFilesToMigrate)
|
|
||||||
.filesInStatus(filesInStatus)
|
|
||||||
.errorCauses(errorCauses)
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<?> startMigrationForFile(String dossierId, String fileId) {
|
||||||
|
|
||||||
|
if (!fileStatusService.fileExists(fileId)) {
|
||||||
|
throw new NotFoundException(String.format("File with id %s does not exist", fileId));
|
||||||
|
}
|
||||||
|
|
||||||
|
saasMigrationService.startMigrationForFile(dossierId, fileId);
|
||||||
|
|
||||||
|
return ResponseEntity.ok().build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<?> requeueErrorFiles() {
|
||||||
|
|
||||||
|
MigrationStatusResponse migrationStatus = migrationStatus();
|
||||||
|
if (!migrationIsFinished(migrationStatus)) {
|
||||||
|
throw new BadRequestException("There are still files processing, please wait until migration has finished to retry!");
|
||||||
|
}
|
||||||
|
|
||||||
|
saasMigrationService.requeueErrorFiles();
|
||||||
|
|
||||||
|
return ResponseEntity.ok().build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static boolean migrationIsFinished(MigrationStatusResponse migrationStatus) {
|
||||||
|
|
||||||
|
return migrationStatus.getFilesInStatus().entrySet().stream().filter(e -> e.getValue() > 0).allMatch(e -> e.getKey().equals(FINISHED) || e.getKey().equals(ERROR));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ plugins {
|
|||||||
dependencies {
|
dependencies {
|
||||||
api(project(":persistence-service-internal-api-v1"))
|
api(project(":persistence-service-internal-api-v1"))
|
||||||
api("com.iqser.red.service:pdftron-redaction-service-api-v1:4.38.0")
|
api("com.iqser.red.service:pdftron-redaction-service-api-v1:4.38.0")
|
||||||
api("com.iqser.red.service:redaction-service-api-v1:4.177.0")
|
api("com.iqser.red.service:redaction-service-api-v1:4.196.0")
|
||||||
api("com.iqser.red.service:redaction-report-service-api-v1:4.36.0")
|
api("com.iqser.red.service:redaction-report-service-api-v1:4.36.0")
|
||||||
api("com.iqser.red.service:search-service-api-v1:2.71.0")
|
api("com.iqser.red.service:search-service-api-v1:2.71.0")
|
||||||
api("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.13.4")
|
api("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.13.4")
|
||||||
|
|||||||
@ -5,13 +5,22 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
public interface MigrationStatusResource {
|
public interface MigrationStatusResource {
|
||||||
|
|
||||||
String MIGRATION_STATUS_REST_PATH = ExternalApi.BASE_PATH + "/migration-status";
|
String MIGRATION_STATUS_REST_PATH = ExternalApi.BASE_PATH + "/migration-status";
|
||||||
|
String START_MIGRATION_REST_PATH = ExternalApi.BASE_PATH + "/start_migration";
|
||||||
|
String RETRY_MIGRATION_REST_PATH = ExternalApi.BASE_PATH + "/retry_migration";
|
||||||
|
|
||||||
|
String FILE_ID = "fileId";
|
||||||
|
String FILE_ID_PATH_VARIABLE = "/{" + FILE_ID + "}";
|
||||||
|
|
||||||
|
String DOSSIER_ID = "dossierId";
|
||||||
|
String DOSSIER_ID_PATH_VARIABLE = "/{" + DOSSIER_ID + "}";
|
||||||
|
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@PostMapping(value = MIGRATION_STATUS_REST_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
|
@PostMapping(value = MIGRATION_STATUS_REST_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
@ -19,5 +28,19 @@ public interface MigrationStatusResource {
|
|||||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Success.")})
|
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Success.")})
|
||||||
MigrationStatusResponse migrationStatus();
|
MigrationStatusResponse migrationStatus();
|
||||||
|
|
||||||
|
@ResponseBody
|
||||||
|
@PostMapping(value = START_MIGRATION_REST_PATH + FILE_ID_PATH_VARIABLE + DOSSIER_ID_PATH_VARIABLE)
|
||||||
|
@Operation(summary = "Start SAAS migration for specific file", description = "None")
|
||||||
|
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Success.")})
|
||||||
|
ResponseEntity<?> startMigrationForFile(@RequestParam(value = DOSSIER_ID) String dossierId, @RequestParam(value = FILE_ID) String fileId);
|
||||||
|
|
||||||
|
@ResponseBody
|
||||||
|
@PostMapping(value = RETRY_MIGRATION_REST_PATH)
|
||||||
|
@Operation(summary = "Restart SAAS migration for all files in error state", description = "None")
|
||||||
|
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Success.")})
|
||||||
|
ResponseEntity<?> requeueErrorFiles();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ dependencies {
|
|||||||
api(project(":persistence-service-external-api-v1"))
|
api(project(":persistence-service-external-api-v1"))
|
||||||
api(project(":persistence-service-internal-api-v1"))
|
api(project(":persistence-service-internal-api-v1"))
|
||||||
api("com.iqser.red.service:pdftron-redaction-service-api-v1:4.38.0")
|
api("com.iqser.red.service:pdftron-redaction-service-api-v1:4.38.0")
|
||||||
api("com.iqser.red.service:redaction-service-api-v1:4.177.0")
|
api("com.iqser.red.service:redaction-service-api-v1:4.196.0")
|
||||||
api("com.iqser.red.service:redaction-report-service-api-v1:4.36.0")
|
api("com.iqser.red.service:redaction-report-service-api-v1:4.36.0")
|
||||||
api("com.iqser.red.service:search-service-api-v1:2.71.0")
|
api("com.iqser.red.service:search-service-api-v1:2.71.0")
|
||||||
api("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.16.0")
|
api("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.16.0")
|
||||||
|
|||||||
@ -13,7 +13,7 @@ dependencies {
|
|||||||
api("com.knecon.fforesight:keycloak-commons:0.22.0")
|
api("com.knecon.fforesight:keycloak-commons:0.22.0")
|
||||||
api("com.knecon.fforesight:swagger-commons:0.5.0")
|
api("com.knecon.fforesight:swagger-commons:0.5.0")
|
||||||
api("com.iqser.red.service:pdftron-redaction-service-api-v1:4.38.0")
|
api("com.iqser.red.service:pdftron-redaction-service-api-v1:4.38.0")
|
||||||
api("com.iqser.red.service:redaction-service-api-v1:4.177.0")
|
api("com.iqser.red.service:redaction-service-api-v1:4.196.0")
|
||||||
api("com.iqser.red.service:redaction-report-service-api-v1:4.36.0")
|
api("com.iqser.red.service:redaction-report-service-api-v1:4.36.0")
|
||||||
api("com.knecon.fforesight:layoutparser-service-internal-api:0.74.0")
|
api("com.knecon.fforesight:layoutparser-service-internal-api:0.74.0")
|
||||||
api("com.iqser.red.service:search-service-api-v1:2.71.0")
|
api("com.iqser.red.service:search-service-api-v1:2.71.0")
|
||||||
|
|||||||
@ -368,8 +368,7 @@ public class MessagingConfiguration {
|
|||||||
@Bean
|
@Bean
|
||||||
public Queue layoutparsingResponseQueue() {
|
public Queue layoutparsingResponseQueue() {
|
||||||
|
|
||||||
return QueueBuilder.durable(LAYOUT_PARSING_FINISHED_EVENT_QUEUE)//
|
return QueueBuilder.durable(LAYOUT_PARSING_FINISHED_EVENT_QUEUE).build();
|
||||||
.withArgument("x-dead-letter-exchange", "").withArgument("x-dead-letter-routing-key", LAYOUT_PARSING_DLQ).build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,8 @@ import com.iqser.red.service.persistence.management.v1.processor.exception.NotFo
|
|||||||
import com.iqser.red.service.persistence.management.v1.processor.service.DossierService;
|
import com.iqser.red.service.persistence.management.v1.processor.service.DossierService;
|
||||||
import com.iqser.red.service.persistence.management.v1.processor.service.job.AutomaticAnalysisJob;
|
import com.iqser.red.service.persistence.management.v1.processor.service.job.AutomaticAnalysisJob;
|
||||||
import com.iqser.red.service.persistence.management.v1.processor.service.layoutparsing.LayoutParsingRequestFactory;
|
import com.iqser.red.service.persistence.management.v1.processor.service.layoutparsing.LayoutParsingRequestFactory;
|
||||||
|
import com.iqser.red.service.persistence.management.v1.processor.service.manualredactions.ManualRedactionProviderService;
|
||||||
|
import com.iqser.red.service.persistence.management.v1.processor.service.manualredactions.ManualRedactionService;
|
||||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService;
|
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService;
|
||||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.SaasMigrationStatusPersistenceService;
|
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.SaasMigrationStatusPersistenceService;
|
||||||
import com.iqser.red.service.persistence.management.v1.processor.settings.FileManagementServiceSettings;
|
import com.iqser.red.service.persistence.management.v1.processor.settings.FileManagementServiceSettings;
|
||||||
@ -19,8 +21,12 @@ import com.iqser.red.storage.commons.service.StorageService;
|
|||||||
import com.knecon.fforesight.databasetenantcommons.providers.TenantSyncService;
|
import com.knecon.fforesight.databasetenantcommons.providers.TenantSyncService;
|
||||||
import com.knecon.fforesight.databasetenantcommons.providers.events.TenantSyncEvent;
|
import com.knecon.fforesight.databasetenantcommons.providers.events.TenantSyncEvent;
|
||||||
import com.knecon.fforesight.tenantcommons.TenantContext;
|
import com.knecon.fforesight.tenantcommons.TenantContext;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@ -32,22 +38,23 @@ import static com.knecon.fforesight.service.layoutparser.internal.api.queue.Layo
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
|
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
|
||||||
public class SaasMigrationService implements TenantSyncService {
|
public class SaasMigrationService implements TenantSyncService {
|
||||||
|
|
||||||
private final AutomaticAnalysisJob automaticAnalysisJob;
|
AutomaticAnalysisJob automaticAnalysisJob;
|
||||||
private final FileStatusPersistenceService fileStatusPersistenceService;
|
FileStatusPersistenceService fileStatusPersistenceService;
|
||||||
private final SaasMigrationStatusPersistenceService saasMigrationStatusPersistenceService;
|
SaasMigrationStatusPersistenceService saasMigrationStatusPersistenceService;
|
||||||
private final DossierService dossierService;
|
DossierService dossierService;
|
||||||
|
ManualRedactionProviderService manualRedactionProviderService;
|
||||||
|
|
||||||
private final LayoutParsingRequestFactory layoutParsingRequestFactory;
|
LayoutParsingRequestFactory layoutParsingRequestFactory;
|
||||||
private final RabbitTemplate rabbitTemplate;
|
RabbitTemplate rabbitTemplate;
|
||||||
private final FileManagementServiceSettings settings;
|
FileManagementServiceSettings settings;
|
||||||
private final StorageService storageService;
|
StorageService storageService;
|
||||||
|
|
||||||
|
SaasAnnotationIdMigrationService saasAnnotationIdMigrationService;
|
||||||
|
|
||||||
private final SaasAnnotationIdMigrationService saasAnnotationIdMigrationService;
|
UncompressedFilesMigrationService uncompressedFilesMigrationService;
|
||||||
|
|
||||||
private final UncompressedFilesMigrationService uncompressedFilesMigrationService;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -58,6 +65,7 @@ public class SaasMigrationService implements TenantSyncService {
|
|||||||
|
|
||||||
// Persistence-Service needs to be scaled to 1.
|
// Persistence-Service needs to be scaled to 1.
|
||||||
|
|
||||||
|
|
||||||
public void startMigrationForTenant(String tenantId) {
|
public void startMigrationForTenant(String tenantId) {
|
||||||
|
|
||||||
// TODO migrate rules.
|
// TODO migrate rules.
|
||||||
@ -79,22 +87,71 @@ public class SaasMigrationService implements TenantSyncService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("Added {} for tenant {} to Layout-Parsing queue for saas migration", numberOfFiles, TenantContext.getTenantId());
|
log.info("Added {} documents for tenant {} to Layout-Parsing queue for saas migration", numberOfFiles, TenantContext.getTenantId());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void startMigrationForFile(String dossierId, String fileId) {
|
||||||
|
|
||||||
|
log.info("Starting Migration for dossierId {} and fileId {}", dossierId, fileId);
|
||||||
|
saasMigrationStatusPersistenceService.createMigrationRequiredStatus(dossierId, fileId);
|
||||||
|
var layoutParsingRequest = layoutParsingRequestFactory.build(dossierId, fileId, false);
|
||||||
|
rabbitTemplate.convertAndSend(LAYOUT_PARSING_REQUEST_QUEUE, layoutParsingRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void requeueErrorFiles() {
|
||||||
|
|
||||||
|
automaticAnalysisJob.stopForTenant(TenantContext.getTenantId());
|
||||||
|
saasMigrationStatusPersistenceService.findAllByStatus(SaasMigrationStatus.ERROR)
|
||||||
|
.forEach(migrationStatus -> startMigrationForFile(migrationStatus.getDossierId(), migrationStatus.getFileId()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void handleLayoutParsingFinished(String dossierId, String fileId) {
|
public void handleLayoutParsingFinished(String dossierId, String fileId) {
|
||||||
saasMigrationStatusPersistenceService.updateStatus(fileId, SaasMigrationStatus.DOCUMENT_FILES_MIGRATED);
|
|
||||||
rabbitTemplate.convertAndSend(MIGRATION_QUEUE, MigrationRequest.builder()
|
|
||||||
.dossierId(dossierId)
|
|
||||||
.fileId(fileId)
|
|
||||||
.build());
|
|
||||||
|
|
||||||
log.info("Layout Parsing finished for saas migration for tenant {} dossier {} and file {}", TenantContext.getTenantId(), dossierId, fileId);
|
if (!layoutParsingFilesExist(dossierId, fileId)) {
|
||||||
|
saasMigrationStatusPersistenceService.updateErrorStatus(fileId, "Layout parsing files not written!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
saasMigrationStatusPersistenceService.updateStatus(fileId, SaasMigrationStatus.DOCUMENT_FILES_MIGRATED);
|
||||||
|
try {
|
||||||
|
String dossierTemplateId = dossierService.getDossierById(dossierId).getDossierTemplateId();
|
||||||
|
rabbitTemplate.convertAndSend(MIGRATION_QUEUE,
|
||||||
|
MigrationRequest.builder()
|
||||||
|
.dossierTemplateId(dossierTemplateId)
|
||||||
|
.dossierId(dossierId)
|
||||||
|
.fileId(fileId)
|
||||||
|
.manualRedactions(manualRedactionProviderService.getManualRedactions(fileId))
|
||||||
|
.build());
|
||||||
|
log.info("Layout Parsing finished for saas migration for tenant {} dossier {} and file {}", TenantContext.getTenantId(), dossierId, fileId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Queuing of entityLog migration failed with {}", e.getMessage());
|
||||||
|
saasMigrationStatusPersistenceService.updateErrorStatus(fileId, String.format("Queuing of entityLog migration failed with %s", e.getMessage()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean layoutParsingFilesExist(String dossierId, String fileId) {
|
||||||
|
|
||||||
|
return storageService.objectExists(TenantContext.getTenantId(), StorageIdUtils.getStorageId(dossierId, fileId, FileType.DOCUMENT_STRUCTURE)) && storageService.objectExists(
|
||||||
|
TenantContext.getTenantId(),
|
||||||
|
StorageIdUtils.getStorageId(dossierId, fileId, FileType.DOCUMENT_TEXT)) && storageService.objectExists(TenantContext.getTenantId(),
|
||||||
|
StorageIdUtils.getStorageId(dossierId, fileId, FileType.DOCUMENT_PAGES)) && storageService.objectExists(TenantContext.getTenantId(),
|
||||||
|
StorageIdUtils.getStorageId(dossierId, fileId, FileType.DOCUMENT_POSITION));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void handleEntityLogMigrationFinished(String dossierId, String fileId) {
|
public void handleEntityLogMigrationFinished(String dossierId, String fileId) {
|
||||||
|
|
||||||
|
if (!entityLogMigrationFilesExist(dossierId, fileId)) {
|
||||||
|
saasMigrationStatusPersistenceService.updateErrorStatus(fileId, "Migration Files not written!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
saasMigrationStatusPersistenceService.updateStatus(fileId, SaasMigrationStatus.REDACTION_LOGS_MIGRATED);
|
saasMigrationStatusPersistenceService.updateStatus(fileId, SaasMigrationStatus.REDACTION_LOGS_MIGRATED);
|
||||||
|
|
||||||
log.info("EntityLog migration finished for saas migration for tenant {} dossier {} and file {}", TenantContext.getTenantId(), dossierId, fileId);
|
log.info("EntityLog migration finished for saas migration for tenant {} dossier {} and file {}", TenantContext.getTenantId(), dossierId, fileId);
|
||||||
@ -102,15 +159,21 @@ public class SaasMigrationService implements TenantSyncService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean entityLogMigrationFilesExist(String dossierId, String fileId) {
|
||||||
|
|
||||||
|
return storageService.objectExists(TenantContext.getTenantId(), StorageIdUtils.getStorageId(dossierId, fileId, FileType.ENTITY_LOG)) && storageService.objectExists(
|
||||||
|
TenantContext.getTenantId(),
|
||||||
|
StorageIdUtils.getStorageId(dossierId, fileId, FileType.MIGRATED_IDS));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void handleError(String dossierId, String fileId, String errorCause, String retryQueue) {
|
public void handleError(String dossierId, String fileId, String errorCause, String retryQueue) {
|
||||||
|
|
||||||
var migrationEntry = saasMigrationStatusPersistenceService.findById(fileId);
|
var migrationEntry = saasMigrationStatusPersistenceService.findById(fileId);
|
||||||
Integer numErrors = migrationEntry.getProcessingErrorCounter();
|
Integer numErrors = migrationEntry.getProcessingErrorCounter();
|
||||||
if (numErrors !=null && numErrors <= settings.getMaxErrorRetries()) {
|
if (numErrors != null && numErrors <= settings.getMaxErrorRetries()) {
|
||||||
saasMigrationStatusPersistenceService.updateErrorCounter(fileId, numErrors + 1, errorCause);
|
saasMigrationStatusPersistenceService.updateErrorCounter(fileId, numErrors + 1, errorCause);
|
||||||
rabbitTemplate.convertAndSend(retryQueue, MigrationRequest.builder()
|
rabbitTemplate.convertAndSend(retryQueue, MigrationRequest.builder().dossierId(dossierId).fileId(fileId).build());
|
||||||
.dossierId(dossierId)
|
|
||||||
.fileId(fileId)
|
|
||||||
.build());
|
|
||||||
log.error("Retrying error during saas migration for tenant {} dossier {} and file {}, cause {}", TenantContext.getTenantId(), dossierId, fileId, errorCause);
|
log.error("Retrying error during saas migration for tenant {} dossier {} and file {}, cause {}", TenantContext.getTenantId(), dossierId, fileId, errorCause);
|
||||||
} else {
|
} else {
|
||||||
saasMigrationStatusPersistenceService.updateErrorStatus(fileId, errorCause);
|
saasMigrationStatusPersistenceService.updateErrorStatus(fileId, errorCause);
|
||||||
@ -127,7 +190,7 @@ public class SaasMigrationService implements TenantSyncService {
|
|||||||
saasAnnotationIdMigrationService.updateAnnotationIds(fileId, oldToNewMapping);
|
saasAnnotationIdMigrationService.updateAnnotationIds(fileId, oldToNewMapping);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
saasMigrationStatusPersistenceService.updateErrorStatus(fileId, e.getMessage());
|
saasMigrationStatusPersistenceService.updateErrorStatus(fileId, e.getMessage());
|
||||||
log.error("Error during saas migration for tenant {} dossier {} and file {}, cause {}", TenantContext.getTenantId(), dossierId, fileId, e.getMessage());
|
log.error("Error during annotation id migration for tenant {} dossier {} and file {}, cause {}", TenantContext.getTenantId(), dossierId, fileId, e.getMessage());
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
saasMigrationStatusPersistenceService.updateStatus(fileId, SaasMigrationStatus.FINISHED);
|
saasMigrationStatusPersistenceService.updateStatus(fileId, SaasMigrationStatus.FINISHED);
|
||||||
@ -151,7 +214,4 @@ public class SaasMigrationService implements TenantSyncService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -96,7 +96,7 @@ public class EntityLogMergeService {
|
|||||||
|
|
||||||
boolean isHint = isHint(manualRedactionEntry.getType(), dossier);
|
boolean isHint = isHint(manualRedactionEntry.getType(), dossier);
|
||||||
|
|
||||||
if (manualRedactionEntry.getDictionaryEntryType().equals(DictionaryEntryType.FALSE_POSITIVE)) {
|
if (isFalsePositive(manualRedactionEntry)) {
|
||||||
var matchingEntities = entityLog.getEntityLogEntry().stream()
|
var matchingEntities = entityLog.getEntityLogEntry().stream()
|
||||||
.filter(entityLogEntry -> equalPosition(manualRedactionEntry.getPositions().get(0), entityLogEntry.getPositions().get(0)))
|
.filter(entityLogEntry -> equalPosition(manualRedactionEntry.getPositions().get(0), entityLogEntry.getPositions().get(0)))
|
||||||
.toList();
|
.toList();
|
||||||
@ -146,6 +146,12 @@ public class EntityLogMergeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static boolean isFalsePositive(ManualRedactionEntry manualRedactionEntry) {
|
||||||
|
|
||||||
|
return manualRedactionEntry.getDictionaryEntryType() != null && manualRedactionEntry.getDictionaryEntryType().equals(DictionaryEntryType.FALSE_POSITIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void mergeFalsePositive(EntityLog entityLog, EntityLogEntry existingEntry) {
|
private void mergeFalsePositive(EntityLog entityLog, EntityLogEntry existingEntry) {
|
||||||
|
|
||||||
existingEntry.setState(EntryState.REMOVED);
|
existingEntry.setState(EntryState.REMOVED);
|
||||||
|
|||||||
@ -130,6 +130,11 @@ public class FileStatusService {
|
|||||||
return reanalysisRequiredStatusService.enhanceFileStatusWithAnalysisRequirements(converted);
|
return reanalysisRequiredStatusService.enhanceFileStatusWithAnalysisRequirements(converted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean fileExists(String fileId) {
|
||||||
|
|
||||||
|
return fileStatusPersistenceService.statusExists(fileId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void updateProcessingStatusPreprocessed(String dossierId, String fileId, boolean hasHighlights, long fileSize) {
|
public void updateProcessingStatusPreprocessed(String dossierId, String fileId, boolean hasHighlights, long fileSize) {
|
||||||
|
|||||||
@ -560,4 +560,10 @@ public class FileStatusPersistenceService {
|
|||||||
return fileRepository.getFilenameById(fileId).orElseThrow();
|
return fileRepository.getFilenameById(fileId).orElseThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean statusExists(String fileId) {
|
||||||
|
|
||||||
|
return fileRepository.existsById(fileId);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package com.iqser.red.service.persistence.management.v1.processor.service.queue;
|
package com.iqser.red.service.persistence.management.v1.processor.service.queue;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
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.configuration.MessagingConfiguration;
|
||||||
import com.iqser.red.service.persistence.management.v1.processor.migration.SaasMigrationService;
|
import com.iqser.red.service.persistence.management.v1.processor.migration.SaasMigrationService;
|
||||||
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusProcessingUpdateService;
|
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusProcessingUpdateService;
|
||||||
@ -11,9 +12,11 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemp
|
|||||||
import com.knecon.fforesight.service.layoutparser.internal.api.queue.LayoutParsingFinishedEvent;
|
import com.knecon.fforesight.service.layoutparser.internal.api.queue.LayoutParsingFinishedEvent;
|
||||||
import com.knecon.fforesight.service.layoutparser.internal.api.queue.LayoutParsingQueueNames;
|
import com.knecon.fforesight.service.layoutparser.internal.api.queue.LayoutParsingQueueNames;
|
||||||
import com.knecon.fforesight.service.layoutparser.internal.api.queue.LayoutParsingRequest;
|
import com.knecon.fforesight.service.layoutparser.internal.api.queue.LayoutParsingRequest;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import org.springframework.amqp.core.Message;
|
import org.springframework.amqp.core.Message;
|
||||||
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -58,13 +61,15 @@ public class LayoutParsingFinishedMessageReceiver {
|
|||||||
@RabbitListener(queues = LayoutParsingQueueNames.LAYOUT_PARSING_DLQ)
|
@RabbitListener(queues = LayoutParsingQueueNames.LAYOUT_PARSING_DLQ)
|
||||||
public void handleDLQMessage(Message failedMessage) {
|
public void handleDLQMessage(Message failedMessage) {
|
||||||
|
|
||||||
var analyzeRequest = objectMapper.readValue(failedMessage.getBody(), LayoutParsingRequest.class);
|
LayoutParsingRequest analyzeRequest = objectMapper.readValue(failedMessage.getBody(), LayoutParsingRequest.class);
|
||||||
log.info("Failed to process analyze request: {}", analyzeRequest);
|
log.info("Failed to process analyze request: {}", analyzeRequest);
|
||||||
String errorCause = failedMessage.getMessageProperties().getHeader(MessagingConfiguration.X_ERROR_INFO_HEADER);
|
String errorCause = failedMessage.getMessageProperties().getHeader(MessagingConfiguration.X_ERROR_INFO_HEADER);
|
||||||
|
|
||||||
if (saasMigrationStatusPersistenceService.isMigrating(layoutParsingRequestIdentifierService.parseFileId(analyzeRequest.identifier()))) {
|
if (saasMigrationStatusPersistenceService.isMigrating(layoutParsingRequestIdentifierService.parseFileId(analyzeRequest.identifier()))) {
|
||||||
saasMigrationService.handleError(layoutParsingRequestIdentifierService.parseDossierId(analyzeRequest.identifier()),
|
saasMigrationService.handleError(layoutParsingRequestIdentifierService.parseDossierId(analyzeRequest.identifier()),
|
||||||
layoutParsingRequestIdentifierService.parseFileId(analyzeRequest.identifier()), errorCause, LayoutParsingQueueNames.LAYOUT_PARSING_REQUEST_QUEUE);
|
layoutParsingRequestIdentifierService.parseFileId(analyzeRequest.identifier()),
|
||||||
|
errorCause,
|
||||||
|
LayoutParsingQueueNames.LAYOUT_PARSING_REQUEST_QUEUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -168,4 +168,6 @@ databaseChangeLog:
|
|||||||
- include:
|
- include:
|
||||||
file: db/changelog/tenant/114-add-download-redaction-file-status-table.yaml
|
file: db/changelog/tenant/114-add-download-redaction-file-status-table.yaml
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/tenant/115-add-saas-migration-status-table.yaml
|
file: db/changelog/tenant/115-add-saas-migration-status-table.yaml
|
||||||
|
- include:
|
||||||
|
file: db/changelog/tenant/116-fix-null-fields-in-manual-redaction-table.yaml
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
databaseChangeLog:
|
||||||
|
- changeSet:
|
||||||
|
id: makeFieldsNonNullable
|
||||||
|
author: your_author_name
|
||||||
|
changes:
|
||||||
|
- addNotNullConstraint:
|
||||||
|
columnName: add_to_dictionary
|
||||||
|
tableName: manual_redaction
|
||||||
|
defaultNullValue: 'false'
|
||||||
|
- addNotNullConstraint:
|
||||||
|
columnName: add_to_all_dossiers
|
||||||
|
tableName: manual_redaction
|
||||||
|
defaultNullValue: 'true'
|
||||||
|
- addNotNullConstraint:
|
||||||
|
columnName: add_to_dictionary
|
||||||
|
tableName: manual_recategorization
|
||||||
|
defaultNullValue: 'false'
|
||||||
|
- addNotNullConstraint:
|
||||||
|
columnName: add_to_all_dossiers
|
||||||
|
tableName: manual_recategorization
|
||||||
|
defaultNullValue: 'true'
|
||||||
|
- addNotNullConstraint:
|
||||||
|
columnName: update_dictionary
|
||||||
|
tableName: manual_resize_redaction
|
||||||
|
defaultNullValue: 'false'
|
||||||
|
- addNotNullConstraint:
|
||||||
|
columnName: add_to_all_dossiers
|
||||||
|
tableName: manual_resize_redaction
|
||||||
|
defaultNullValue: 'true'
|
||||||
|
- addNotNullConstraint:
|
||||||
|
columnName: remove_from_dictionary
|
||||||
|
tableName: id_removal
|
||||||
|
defaultNullValue: 'false'
|
||||||
|
- addNotNullConstraint:
|
||||||
|
columnName: remove_from_all_dossiers
|
||||||
|
tableName: id_removal
|
||||||
|
defaultNullValue: 'true'
|
||||||
@ -35,7 +35,7 @@ persistence-service:
|
|||||||
applicationName: RedactManager
|
applicationName: RedactManager
|
||||||
fforesight:
|
fforesight:
|
||||||
springdoc:
|
springdoc:
|
||||||
auth-server-url: 'http://localhost:8080/auth'
|
auth-server-url: 'http://localhost:8080'
|
||||||
jobs:
|
jobs:
|
||||||
enabled: true
|
enabled: true
|
||||||
datasource:
|
datasource:
|
||||||
|
|||||||
@ -36,8 +36,6 @@ public class EntityLogEntry {
|
|||||||
String closestHeadline;
|
String closestHeadline;
|
||||||
String section;
|
String section;
|
||||||
|
|
||||||
float[] color;
|
|
||||||
|
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
List<Position> positions = new ArrayList<>();
|
List<Position> positions = new ArrayList<>();
|
||||||
|
|
||||||
|
|||||||
@ -11,5 +11,5 @@ commit_hash=$(git rev-parse --short=5 HEAD)
|
|||||||
# Combine branch and commit hash
|
# Combine branch and commit hash
|
||||||
buildName="${USER}-${branch}-${commit_hash}"
|
buildName="${USER}-${branch}-${commit_hash}"
|
||||||
|
|
||||||
gradle bootBuildImage --cleanCache --publishImage -PbuildbootDockerHostNetwork=true -Pversion=$buildName
|
gradle bootBuildImage --publishImage -PbuildbootDockerHostNetwork=true -Pversion=$buildName
|
||||||
echo "nexus.knecon.com:5001/red/${dir}-server-v1:$buildName"
|
echo "nexus.knecon.com:5001/red/${dir}-server-v1:$buildName"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user