From 540129a0514ffcfd4cb0283df9fbcab817111182 Mon Sep 17 00:00:00 2001 From: maverickstuder Date: Wed, 13 Mar 2024 15:26:35 +0100 Subject: [PATCH 1/9] RED-8702 --- .../service/EntityLogMergeService.java | 16 +- .../processor/service/EntityLogService.java | 2 +- .../ManualRedactionMapper.java | 3 +- .../ManualRedactionService.java | 2 +- .../ManualRedactionUndoService.java | 2 +- .../PendingDictionaryEntryFactory.java | 8 +- .../service/FileTesterAndProvider.java | 6 +- .../integration/tests/EntityLogMergeTest.java | 36 ++-- .../v1/server/integration/tests/FileTest.java | 7 +- .../tests/ManualRedactionTest.java | 166 ++++++++++++------ .../AbstractPersistenceServerServiceTest.java | 6 +- .../build.gradle.kts | 3 + .../analysislog/entitylog/CascadeSave.java | 12 ++ .../analysislog/entitylog/EntityLog.java | 42 +++++ .../analysislog/entitylog/EntityLogEntry.java | 6 +- 15 files changed, 225 insertions(+), 92 deletions(-) create mode 100644 persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/CascadeSave.java diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogMergeService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogMergeService.java index 12ba5b1ea..a588c72e5 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogMergeService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogMergeService.java @@ -81,7 +81,7 @@ public class EntityLogMergeService { List matchingEntities = entityLog.getEntityLogEntry() .stream() - .filter(entityLogEntry -> manualChangesIds.contains(entityLogEntry.getId())) + .filter(entityLogEntry -> manualChangesIds.contains(entityLogEntry.getEntryId())) .collect(Collectors.toList()); final int analysisNumber = entityLog.getAnalysisNumber(); @@ -143,7 +143,7 @@ public class EntityLogMergeService { private EntityLogEntry findMatchingEntry(String annotationId, List matchingEntities) { return matchingEntities.stream() - .filter(entityLogEntry -> entityLogEntry.getId().equals(annotationId)) + .filter(entityLogEntry -> entityLogEntry.getEntryId().equals(annotationId)) .findAny() .orElseThrow(() -> new NotFoundException("No matching EntityLogEntry found for id " + annotationId)); } @@ -182,7 +182,7 @@ public class EntityLogMergeService { boolean isHint = isHint(manualRedactionEntry.getType(), dossier); EntityLogEntry entityLogEntry = EntityLogEntry.builder() - .id(manualRedactionEntry.getAnnotationId()) + .entryId(manualRedactionEntry.getAnnotationId()) .type(manualRedactionEntry.getType()) .value(manualRedactionEntry.getValue()) .legalBasis(manualRedactionEntry.getLegalBasis()) @@ -237,7 +237,7 @@ public class EntityLogMergeService { private void mergeIdsToRemove(IdRemoval idRemoval, List entityLogEntries, int analysisNumber) { var entity = entityLogEntries.stream() - .filter(entityLogEntry -> entityLogEntry.getId().equals(idRemoval.getAnnotationId())) + .filter(entityLogEntry -> entityLogEntry.getEntryId().equals(idRemoval.getAnnotationId())) .findAny(); entity.ifPresent(entityLogEntry -> { entityLogEntry.setState(EntryState.IGNORED); @@ -258,7 +258,7 @@ public class EntityLogMergeService { private void mergeResizeRedactions(ManualResizeRedaction manualResizeRedaction, List entityLogEntries, int analysisNumber) { var entity = entityLogEntries.stream() - .filter(entityLogEntry -> entityLogEntry.getId().equals(manualResizeRedaction.getAnnotationId())) + .filter(entityLogEntry -> entityLogEntry.getEntryId().equals(manualResizeRedaction.getAnnotationId())) .findAny(); entity.ifPresent(entityLogEntry -> { entityLogEntry.setTextAfter(manualResizeRedaction.getTextAfter()); @@ -283,7 +283,7 @@ public class EntityLogMergeService { private void mergeLegalBasisChanges(ManualLegalBasisChange manualLegalBasisChange, List entityLogEntries, int analysisNumber) { var entity = entityLogEntries.stream() - .filter(entityLogEntry -> entityLogEntry.getId().equals(manualLegalBasisChange.getAnnotationId())) + .filter(entityLogEntry -> entityLogEntry.getEntryId().equals(manualLegalBasisChange.getAnnotationId())) .findAny(); entity.ifPresent(entityLogEntry -> { entityLogEntry.setLegalBasis(manualLegalBasisChange.getLegalBasis()); @@ -325,7 +325,7 @@ public class EntityLogMergeService { boolean isHint = isHint(recategorization.getType(), dossier); var entity = entityLogEntries.stream() - .filter(entityLogEntry -> entityLogEntry.getId().equals(recategorization.getAnnotationId())) + .filter(entityLogEntry -> entityLogEntry.getEntryId().equals(recategorization.getAnnotationId())) .findAny(); entity.ifPresent(entityLogEntry -> { entityLogEntry.setType(recategorization.getType()); @@ -348,7 +348,7 @@ public class EntityLogMergeService { private void mergeForceRedactions(ManualForceRedaction forceRedaction, List entityLogEntries, int analysisNumber) { var entity = entityLogEntries.stream() - .filter(entityLogEntry -> entityLogEntry.getId().equals(forceRedaction.getAnnotationId())) + .filter(entityLogEntry -> entityLogEntry.getEntryId().equals(forceRedaction.getAnnotationId())) .findAny(); entity.ifPresent(entityLogEntry -> { entityLogEntry.setLegalBasis(forceRedaction.getLegalBasis()); diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogService.java index d763854da..dd6e406a7 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogService.java @@ -80,7 +80,7 @@ public class EntityLogService { Map commentCountPerAnnotationId = commentService.getCommentCounts(fileId); entityLog.getEntityLogEntry() - .forEach(entityLogEntry -> entityLogEntry.setNumberOfComments(commentCountPerAnnotationId.getOrDefault(entityLogEntry.getId(), 0))); + .forEach(entityLogEntry -> entityLogEntry.setNumberOfComments(commentCountPerAnnotationId.getOrDefault(entityLogEntry.getEntryId(), 0))); return entityLog; } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionMapper.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionMapper.java index 83a314bae..f667dabe4 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionMapper.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionMapper.java @@ -10,7 +10,6 @@ import java.util.Set; import org.springframework.stereotype.Service; -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.service.EntityLogService; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLog; @@ -187,7 +186,7 @@ public class ManualRedactionMapper { return entityLog.getEntityLogEntry() .stream() - .filter(entry -> entry.getId().equals(annotationId)) + .filter(entry -> entry.getEntryId().equals(annotationId)) .findFirst() .orElseThrow(() -> new NotFoundException("Annotation does not exist in entity log.")); } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionService.java index 82e4549a5..f3c56a10a 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionService.java @@ -348,7 +348,7 @@ public class ManualRedactionService { return entityLog.getEntityLogEntry() .stream() - .filter(entry -> entry.getId().equals(annotationId)) + .filter(entry -> entry.getEntryId().equals(annotationId)) .findFirst() .orElseThrow(() -> new NotFoundException("Annotation does not exist in entity log.")); } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionUndoService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionUndoService.java index d753850c1..b47411bba 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionUndoService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionUndoService.java @@ -343,7 +343,7 @@ public class ManualRedactionUndoService { return entityLog.getEntityLogEntry() .stream() - .filter(entry -> entry.getId().equals(annotationId)) + .filter(entry -> entry.getEntryId().equals(annotationId)) .findFirst() .orElseThrow(() -> new NotFoundException("Annotation does not exist in entity log.")); } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/PendingDictionaryEntryFactory.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/PendingDictionaryEntryFactory.java index 6c9a317ed..8c53a07d0 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/PendingDictionaryEntryFactory.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/PendingDictionaryEntryFactory.java @@ -35,7 +35,7 @@ public class PendingDictionaryEntryFactory { .propertyChanges(Map.of("value", manualRedactionEntry.getValue())) .build()); return EntityLogEntry.builder() - .id(manualRedactionEntry.getAnnotationId()) + .entryId(manualRedactionEntry.getAnnotationId()) .value(manualRedactionEntry.getValue()) .type(manualRedactionEntry.getType()) .entryType(Optional.ofNullable(manualRedactionEntry.getDictionaryEntryType()) @@ -82,7 +82,7 @@ public class PendingDictionaryEntryFactory { .build()); return EntityLogEntry.builder() - .id(originalEntry.getId()) + .entryId(originalEntry.getEntryId()) .value(originalEntry.getValue()) .type(originalEntry.getType()) .entryType(originalEntry.getEntryType()) @@ -121,7 +121,7 @@ public class PendingDictionaryEntryFactory { .propertyChanges(propertyChanges) .build()); return EntityLogEntry.builder() - .id(originalEntry.getId()) + .entryId(originalEntry.getEntryId()) .value(manualChange.getValue()) .type(originalEntry.getType()) .entryType(originalEntry.getEntryType()) @@ -171,7 +171,7 @@ public class PendingDictionaryEntryFactory { .build()); return EntityLogEntry.builder() - .id(originalEntry.getId()) + .entryId(originalEntry.getEntryId()) .value(originalEntry.getValue()) .type(manualChange.getType()) .entryType(originalEntry.getEntryType()) 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 e856e1b16..8ffe31af6 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 @@ -67,10 +67,12 @@ public class FileTesterAndProvider { fileManagementStorageService.storeJSONObject(dossier.getId(), file.getFileId(), FileType.ENTITY_LOG, - new EntityLog(1, + new EntityLog(dossier.getId(), + fileId, + 1, 1, List.of(EntityLogEntry.builder() - .id("annotationId") + .entryId("annotationId") .type("manual") .value("value entry") .entryType(EntryType.ENTITY) diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/EntityLogMergeTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/EntityLogMergeTest.java index 7a041bc58..2de272ccf 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/EntityLogMergeTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/EntityLogMergeTest.java @@ -120,7 +120,7 @@ public class EntityLogMergeTest { ManualRedactions manualRedactions = provideManualRedactions(entryToAddId, entryToRemoveId, entryToResizeId, entryLegalBasisId, forceRedactionId, fileId, rectangleToAddId); - var entityLog = provideEntityLog(entryToRemoveId, entryToResizeId, entryLegalBasisId, forceRedactionId); + var entityLog = provideEntityLog(dossierId, fileId, entryToRemoveId, entryToResizeId, entryLegalBasisId, forceRedactionId); when(manualRedactionProviderService.getManualRedactions(any(), any())).thenReturn(manualRedactions); when(fileStatusService.getStatus(fileId)).thenReturn(FileModel.builder().excluded(false).dossierStatusId(dossierTemplateId).id(fileId).build()); @@ -137,7 +137,7 @@ public class EntityLogMergeTest { var optionalEntityLogEntry = response.getEntityLogEntry() .stream() - .filter(entityLogEntry1 -> entityLogEntry1.getId().equals(entryToAddId)) + .filter(entityLogEntry1 -> entityLogEntry1.getEntryId().equals(entryToAddId)) .findFirst(); assertTrue(optionalEntityLogEntry.isPresent()); var entityLogEntry = optionalEntityLogEntry.get(); @@ -152,7 +152,7 @@ public class EntityLogMergeTest { var optionalRemoveEntryLogEntry = response.getEntityLogEntry() .stream() - .filter(entityLogEntry1 -> entityLogEntry1.getId().equals(entryToRemoveId)) + .filter(entityLogEntry1 -> entityLogEntry1.getEntryId().equals(entryToRemoveId)) .findFirst(); assertTrue(optionalRemoveEntryLogEntry.isPresent()); var removeEntryLogEntry = optionalRemoveEntryLogEntry.get(); @@ -166,7 +166,7 @@ public class EntityLogMergeTest { var optionalResizeEntryLogEntry = response.getEntityLogEntry() .stream() - .filter(entityLogEntry1 -> entityLogEntry1.getId().equals(entryToResizeId)) + .filter(entityLogEntry1 -> entityLogEntry1.getEntryId().equals(entryToResizeId)) .findFirst(); assertTrue(optionalResizeEntryLogEntry.isPresent()); var resizeEntryLogEntry = optionalResizeEntryLogEntry.get(); @@ -190,7 +190,7 @@ public class EntityLogMergeTest { var optionalLegalBasisEntryLogEntry = response.getEntityLogEntry() .stream() - .filter(entityLogEntry1 -> entityLogEntry1.getId().equals(entryLegalBasisId)) + .filter(entityLogEntry1 -> entityLogEntry1.getEntryId().equals(entryLegalBasisId)) .findFirst(); assertTrue(optionalLegalBasisEntryLogEntry.isPresent()); var legalBasisEntryLogEntry = optionalLegalBasisEntryLogEntry.get(); @@ -205,7 +205,7 @@ public class EntityLogMergeTest { var optionalForceRedactionEntryLogEntry = response.getEntityLogEntry() .stream() - .filter(entityLogEntry1 -> entityLogEntry1.getId().equals(forceRedactionId)) + .filter(entityLogEntry1 -> entityLogEntry1.getEntryId().equals(forceRedactionId)) .findFirst(); assertTrue(optionalForceRedactionEntryLogEntry.isPresent()); var forceRedactionEntryLogEntry = optionalForceRedactionEntryLogEntry.get(); @@ -220,7 +220,7 @@ public class EntityLogMergeTest { var optionalRectangleEntryLogEntry = response.getEntityLogEntry() .stream() - .filter(entityLogEntry1 -> entityLogEntry1.getId().equals(rectangleToAddId)) + .filter(entityLogEntry1 -> entityLogEntry1.getEntryId().equals(rectangleToAddId)) .findFirst(); assertTrue(optionalRectangleEntryLogEntry.isPresent()); var rectangleEntryLogEntry = optionalRectangleEntryLogEntry.get(); @@ -236,22 +236,24 @@ public class EntityLogMergeTest { } - private EntityLog provideEntityLog(String entryToRemoveId, String entryToResizeId, String entryLegalBasisId, String forceRedactionId) { + private EntityLog provideEntityLog(String dossierId, String fileId, String entryToRemoveId, String entryToResizeId, String entryLegalBasisId, String forceRedactionId) { List positions = new ArrayList<>(); positions.add(new Position(1, 1, 1, 1, 1)); - return new EntityLog(1, + return new EntityLog(dossierId, + fileId, 1, - Lists.newArrayList(EntityLogEntry.builder() - .id(entryToRemoveId) + 1, + Lists.newArrayList(EntityLogEntry.builder().entityLogId(EntityLog.getId(dossierId, fileId)) + .entryId(entryToRemoveId) .type("manual") .value("Luke Skywalker") .entryType(EntryType.ENTITY) .state(EntryState.APPLIED) .dictionaryEntry(true) .build(), - EntityLogEntry.builder() - .id(entryToResizeId) + EntityLogEntry.builder().entityLogId(EntityLog.getId(dossierId, fileId)) + .entryId(entryToResizeId) .type("manual") .value("Darth Vader") .entryType(EntryType.ENTITY) @@ -259,8 +261,8 @@ public class EntityLogMergeTest { .dictionaryEntry(true) .positions(positions) .build(), - EntityLogEntry.builder() - .id(entryLegalBasisId) + EntityLogEntry.builder().entityLogId(EntityLog.getId(dossierId, fileId)) + .entryId(entryLegalBasisId) .type("manual") .value("Darth Luke") .entryType(EntryType.ENTITY) @@ -268,8 +270,8 @@ public class EntityLogMergeTest { .dictionaryEntry(true) .positions(positions) .build(), - EntityLogEntry.builder() - .id(forceRedactionId) + EntityLogEntry.builder().entityLogId(EntityLog.getId(dossierId, fileId)) + .entryId(forceRedactionId) .type("manual") .value("Darth Luke") .entryType(EntryType.ENTITY) 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 fe831f9d0..3193deebd 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 @@ -369,10 +369,13 @@ public class FileTest extends AbstractPersistenceServerServiceTest { var type = typeProvider.testAndProvideType(dossierTemplate, null, "manual"); var annotationId = "imagine_this_makes_sense"; - EntityLog entityLog = new EntityLog(1, + EntityLog entityLog = new EntityLog(dossierId, + fileId, + 1, 1, List.of(EntityLogEntry.builder() - .id(annotationId) + .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) + .entryId(annotationId) .type(type.getType()) .value("value entry") .state(EntryState.APPLIED) diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ManualRedactionTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ManualRedactionTest.java index 7b6107283..ac7ff40ac 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ManualRedactionTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ManualRedactionTest.java @@ -45,10 +45,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryState; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryType; -import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AddRedactionRequest; -import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualRedactions; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Rectangle; -import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRedactionEntry; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type.DictionaryEntryType; import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.AddRedactionRequestModel; @@ -124,10 +121,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { dictionaryClient.addEntry(type.getType(), type.getDossierTemplateId(), List.of("Luke Skywalker"), false, dossier.getId(), DictionaryEntryType.ENTRY); - var entityLog = new EntityLog(1, + var entityLog = new EntityLog(dossier.getId(), + file.getFileId(), + 1, 1, List.of(EntityLogEntry.builder() - .id("AnnotationId") + .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) + .entryId("AnnotationId") .type(type.getType()) .value("Luke Skywalker") .entryType(EntryType.ENTITY) @@ -318,10 +318,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { Dictionary dossierDictionary = dictionaryClient.getDictionaryForType(type.getType(), type.getDossierTemplateId(), dossier.getId()); assertThat(dossierDictionary.getEntries()).containsExactlyInAnyOrder("Luke Skywalker"); - var entityLog = new EntityLog(1, + var entityLog = new EntityLog(dossier.getId(), + file.getFileId(), + 1, 1, List.of(EntityLogEntry.builder() - .id("AnnotationId") + .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) + .entryId("AnnotationId") .type("test") .value("Luke Skywalker") .entryType(EntryType.ENTITY) @@ -378,10 +381,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { // CreateTypeValue dossierDictionaryType = MagicConverter.convert(type, CreateTypeValue.class); // dictionaryClient.addType(dossierDictionaryType, dossier.getId()); - var entityLog = new EntityLog(1, + var entityLog = new EntityLog(dossier.getId(), + file.getFileId(), + 1, 1, List.of(EntityLogEntry.builder() - .id("AnnotationId") + .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) + .entryId("AnnotationId") .type("test") .value("Luke Skywalker") .entryType(EntryType.ENTITY) @@ -433,10 +439,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { // dictionaryClient.addType(dossierDictionaryType, dossier.getId()); dictionaryClient.addEntry(type.getType(), type.getDossierTemplateId(), List.of("Luke Skywalker"), false, dossier.getId(), DictionaryEntryType.ENTRY); - var entityLog = new EntityLog(1, + var entityLog = new EntityLog(dossier.getId(), + file.getFileId(), + 1, 1, List.of(EntityLogEntry.builder() - .id("AnnotationId") + .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) + .entryId("AnnotationId") .type("test") .value("Luke Skywalker") .entryType(EntryType.ENTITY) @@ -520,10 +529,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { var addRedactions = manualRedactionClient.addRedactionBulk(dossier1.getId(), file1.getId(), Set.of(redactionDos, redactionDosTempDict)); var loadedRedactionsFile1 = manualRedactionClient.getManualRedactions(file1.getDossierId(), file1.getFileId(), false, true); - var entityLog1 = new EntityLog(1, + var entityLog1 = new EntityLog(dossier1.getId(), + file1.getFileId(), + 1, 1, List.of(EntityLogEntry.builder() - .id(addRedactions.get(0).getAnnotationId()) + .entityLogId(EntityLog.getId(dossier1.getId(), file1.getFileId())) + .entryId(addRedactions.get(0).getAnnotationId()) .type(typeDosDict.getType()) .value("test redaction in dossier") .dossierDictionaryEntry(true) @@ -531,7 +543,8 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { .state(EntryState.APPLIED) .build(), EntityLogEntry.builder() - .id(addRedactions.get(1).getAnnotationId()) + .entityLogId(EntityLog.getId(dossier1.getId(), file1.getFileId())) + .entryId(addRedactions.get(1).getAnnotationId()) .type(typeDosTempDict.getType()) .value("test redaction in dossier template") .dictionaryEntry(true) @@ -547,10 +560,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { var redactionRequest1 = RedactionRequest.builder().dossierId(file1.getDossierId()).fileId(file1.getFileId()).dossierTemplateId(file1.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(eq(file1.getDossierId()), eq(file1.getFileId()), any(), anyBoolean())).thenReturn(entityLog1); - var entityLog2 = new EntityLog(1, + var entityLog2 = new EntityLog(dossier2.getId(), + file2.getFileId(), + 1, 1, List.of(EntityLogEntry.builder() - .id(addRedactions.get(1).getAnnotationId()) + .entityLogId(EntityLog.getId(dossier2.getId(), file2.getFileId())) + .entryId(addRedactions.get(1).getAnnotationId()) .type(typeDosTempDict.getType()) .value("test redaction in dossier template") .dictionaryEntry(true) @@ -685,10 +701,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { var addRedactions = manualRedactionClient.addRedactionBulk(dossier1.getId(), file1.getId(), Set.of(redactionDos, redactionDosTempDict)); var loadedRedactionsFile1 = manualRedactionClient.getManualRedactions(file1.getDossierId(), file1.getFileId(), false, true); - var entityLog1 = new EntityLog(1, + var entityLog1 = new EntityLog(dossier1.getId(), + file1.getFileId(), + 1, 1, List.of(EntityLogEntry.builder() - .id(addRedactions.get(0).getAnnotationId()) + .entityLogId(EntityLog.getId(dossier1.getId(), file1.getFileId())) + .entryId(addRedactions.get(0).getAnnotationId()) .type(typeDosDict.getType()) .value("test redaction in dossier yayy") .dossierDictionaryEntry(true) @@ -696,7 +715,8 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { .state(EntryState.APPLIED) .build(), EntityLogEntry.builder() - .id(addRedactions.get(1).getAnnotationId()) + .entityLogId(EntityLog.getId(dossier1.getId(), file1.getFileId())) + .entryId(addRedactions.get(1).getAnnotationId()) .type(typeDosTempDict.getType()) .value("test redaction in dossier template yayy") .dictionaryEntry(true) @@ -712,10 +732,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { var redactionRequest1 = RedactionRequest.builder().dossierId(file1.getDossierId()).fileId(file1.getFileId()).dossierTemplateId(file1.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(eq(file1.getDossierId()), eq(file1.getFileId()), any(), anyBoolean())).thenReturn(entityLog1); - var entityLog2 = new EntityLog(1, + var entityLog2 = new EntityLog(dossier2.getId(), + file2.getFileId(), + 1, 1, List.of(EntityLogEntry.builder() - .id(addRedactions.get(1).getAnnotationId()) + .entityLogId(EntityLog.getId(dossier2.getId(), file2.getFileId())) + .entryId(addRedactions.get(1).getAnnotationId()) .type(typeDosTempDict.getType()) .value("test redaction in dossier template yayy") .dictionaryEntry(true) @@ -854,10 +877,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { var addRedactions = manualRedactionClient.addRedactionBulk(dossier1.getId(), file1.getId(), Set.of(redactionDos, redactionDosTempDict)); - var entityLog1 = new EntityLog(1, + var entityLog1 = new EntityLog(dossier1.getId(), + file1.getFileId(), + 1, 1, List.of(EntityLogEntry.builder() - .id(addRedactions.get(0).getAnnotationId()) + .entityLogId(EntityLog.getId(dossier1.getId(), file1.getFileId())) + .entryId(addRedactions.get(0).getAnnotationId()) .type(typeDosDict.getType()) .value("test redaction in dossier") .dossierDictionaryEntry(true) @@ -865,7 +891,8 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { .state(EntryState.APPLIED) .build(), EntityLogEntry.builder() - .id(addRedactions.get(1).getAnnotationId()) + .entityLogId(EntityLog.getId(dossier1.getId(), file1.getFileId())) + .entryId(addRedactions.get(1).getAnnotationId()) .type(typeDosTempDict.getType()) .value("test redaction in dossier template") .dictionaryEntry(true) @@ -881,10 +908,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { var redactionRequest1 = RedactionRequest.builder().dossierId(file1.getDossierId()).fileId(file1.getFileId()).dossierTemplateId(file1.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(file1.getDossierId(), file1.getFileId())).thenReturn(entityLog1); - var entityLog2 = new EntityLog(1, + var entityLog2 = new EntityLog(dossier2.getId(), + file2.getFileId(), + 1, 1, List.of(EntityLogEntry.builder() - .id(addRedactions.get(1).getAnnotationId()) + .entityLogId(EntityLog.getId(dossier2.getId(), file2.getFileId())) + .entryId(addRedactions.get(1).getAnnotationId()) .type(typeDosTempDict.getType()) .value("test redaction in dossier template") .dictionaryEntry(true) @@ -1020,10 +1050,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { var addRedactions = manualRedactionClient.addRedactionBulk(dossier1.getId(), file1.getId(), Set.of(redactionDos, redactionDosTempDict)); - var entityLog1 = new EntityLog(1, + var entityLog1 = new EntityLog(dossier1.getId(), + file1.getFileId(), + 1, 1, List.of(EntityLogEntry.builder() - .id(addRedactions.get(0).getAnnotationId()) + .entityLogId(EntityLog.getId(dossier1.getId(), file1.getFileId())) + .entryId(addRedactions.get(0).getAnnotationId()) .type(typeDosDict.getType()) .value("test redaction in dossier yayy") .dossierDictionaryEntry(true) @@ -1031,7 +1064,8 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { .state(EntryState.APPLIED) .build(), EntityLogEntry.builder() - .id(addRedactions.get(1).getAnnotationId()) + .entityLogId(EntityLog.getId(dossier1.getId(), file1.getFileId())) + .entryId(addRedactions.get(1).getAnnotationId()) .type(typeDosTempDict.getType()) .value("test redaction in dossier template yayy") .dictionaryEntry(true) @@ -1047,10 +1081,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { var redactionRequest1 = RedactionRequest.builder().dossierId(file1.getDossierId()).fileId(file1.getFileId()).dossierTemplateId(file1.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(file1.getDossierId(), file1.getFileId())).thenReturn(entityLog1); - var entityLog2 = new EntityLog(1, + var entityLog2 = new EntityLog(dossier2.getId(), + file2.getFileId(), + 1, 1, List.of(EntityLogEntry.builder() - .id(addRedactions.get(1).getAnnotationId()) + .entityLogId(EntityLog.getId(dossier2.getId(), file2.getFileId())) + .entryId(addRedactions.get(1).getAnnotationId()) .type(typeDosTempDict.getType()) .value("test redaction in dossier template yayy") .dictionaryEntry(true) @@ -1171,10 +1208,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { assertThat(dossierDictionary2.getEntries()).isEmpty(); var annotationId = "AnnotationId"; - var entityLog = new EntityLog(1, + var entityLog = new EntityLog(dossier.getId(), + file.getFileId(), + 1, 1, List.of(EntityLogEntry.builder() - .id(annotationId) + .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) + .entryId(annotationId) .type(type.getType()) .value(lukeSkywalker) .dictionaryEntry(true) @@ -1255,10 +1295,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { assertThat(dossierDictionary2.getEntries()).isEmpty(); var annotationId = "AnnotationId"; - var entityLog = new EntityLog(1, + var entityLog = new EntityLog(dossier.getId(), + file.getFileId(), + 1, 1, List.of(EntityLogEntry.builder() - .id(annotationId) + .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) + .entryId(annotationId) .type(type.getType()) .value(lukeSkywalker) .dictionaryEntry(true) @@ -1426,10 +1469,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { dictionaryClient.addEntry(type.getType(), type.getDossierTemplateId(), List.of("Anakin"), false, dossier.getId(), DictionaryEntryType.ENTRY); - var entityLog = new EntityLog(1, + var entityLog = new EntityLog(dossier.getId(), + file.getFileId(), + 1, 1, List.of(EntityLogEntry.builder() - .id("AnnotationId") + .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) + .entryId("AnnotationId") .type(type.getType()) .value("Anakin") .entryType(EntryType.ENTITY) @@ -1437,7 +1483,8 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { .dictionaryEntry(false) .build(), EntityLogEntry.builder() - .id("AnnotationId2") + .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) + .entryId("AnnotationId2") .type(type.getType()) .value("Anakin2") .entryType(EntryType.ENTITY) @@ -1625,10 +1672,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { dictionaryClient.addEntry(type.getType(), type.getDossierTemplateId(), List.of("Darth Vader"), false, dossier.getId(), DictionaryEntryType.ENTRY); - var entityLog = new EntityLog(1, + var entityLog = new EntityLog(dossier.getId(), + file.getFileId(), + 1, 1, List.of(EntityLogEntry.builder() - .id("dv") + .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) + .entryId("dv") .type(type.getType()) .value("Darth Vader") .entryType(EntryType.ENTITY) @@ -1636,7 +1686,8 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { .dictionaryEntry(false) .build(), EntityLogEntry.builder() - .id("dv2") + .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) + .entryId("dv2") .type(type.getType()) .value("Vader Darth") .entryType(EntryType.ENTITY) @@ -1731,10 +1782,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { dictionaryClient.addEntry(type.getType(), type.getDossierTemplateId(), List.of("Luke Skywalker"), false, dossier.getId(), DictionaryEntryType.ENTRY); - var entityLog = new EntityLog(1, + var entityLog = new EntityLog(dossier.getId(), + file.getFileId(), + 1, 1, List.of(EntityLogEntry.builder() - .id("AnnotationId") + .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) + .entryId("AnnotationId") .type(type.getType()) .value("Luke Skywalker") .entryType(EntryType.ENTITY) @@ -1742,7 +1796,8 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { .dictionaryEntry(false) .build(), EntityLogEntry.builder() - .id("AnnotationId2") + .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) + .entryId("AnnotationId2") .type(type.getType()) .value("Skywalker Luke") .entryType(EntryType.ENTITY) @@ -1841,10 +1896,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { dictionaryClient.addEntry(type.getType(), type.getDossierTemplateId(), List.of("Luke Skywalker"), false, dossier.getId(), DictionaryEntryType.ENTRY); - var entityLog = new EntityLog(1, + var entityLog = new EntityLog(dossier.getId(), + file.getFileId(), + 1, 1, List.of(EntityLogEntry.builder() - .id("AnnotationId") + .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) + .entryId("AnnotationId") .type(type.getType()) .value("Luke Skywalker") .entryType(EntryType.ENTITY) @@ -1852,7 +1910,8 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { .dictionaryEntry(false) .build(), EntityLogEntry.builder() - .id("AnnotationId2") + .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) + .entryId("AnnotationId2") .type(type.getType()) .value("Skywalker Luke") .entryType(EntryType.ENTITY) @@ -1917,10 +1976,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { var type = typeProvider.testAndProvideType(dossierTemplate, null, "type", false); - var entityLog = new EntityLog(1, + var entityLog = new EntityLog(dossier.getId(), + file.getFileId(), + 1, 1, List.of(EntityLogEntry.builder() - .id("annotationId") + .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) + .entryId("annotationId") .type(type.getType()) .value("lukeSkywalker") .dictionaryEntry(true) @@ -1928,7 +1990,8 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { .state(EntryState.APPLIED) .build(), EntityLogEntry.builder() - .id("annotationId2") + .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) + .entryId("annotationId2") .type(type.getType()) .value("Johannesbrotkernmehl") .dictionaryEntry(true) @@ -1936,7 +1999,8 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { .state(EntryState.APPLIED) .build(), EntityLogEntry.builder() - .id("annotationId3") + .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) + .entryId("annotationId3") .type(type.getType()) .value("Baustelle") .dictionaryEntry(true) 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 76eb9a805..344d95169 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 @@ -249,8 +249,10 @@ public abstract class AbstractPersistenceServerServiceTest { // doNothing().when(pdfTronRedactionClient).testDigitalCurrentSignature(Mockito.any()); when(amqpAdmin.getQueueInfo(Mockito.any())).thenReturn(null); - when(entityLogService.getEntityLog(Mockito.any(), Mockito.any())).thenReturn(new EntityLog(1, 1, Lists.newArrayList(), null, 0, 0, 0, 0)); - when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyBoolean())).thenReturn(new EntityLog(1, + when(entityLogService.getEntityLog(Mockito.any(), Mockito.any())).thenReturn(new EntityLog("", "", 1, 1, Lists.newArrayList(), null, 0, 0, 0, 0)); + when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyBoolean())).thenReturn(new EntityLog("", + "", + 1, 1, Lists.newArrayList(), null, diff --git a/persistence-service-v1/persistence-service-shared-api-v1/build.gradle.kts b/persistence-service-v1/persistence-service-shared-api-v1/build.gradle.kts index a10ac954d..8e4c8efce 100644 --- a/persistence-service-v1/persistence-service-shared-api-v1/build.gradle.kts +++ b/persistence-service-v1/persistence-service-shared-api-v1/build.gradle.kts @@ -3,12 +3,15 @@ plugins { id("io.freefair.lombok") version "8.4" } +val springBootStarterVersion = "3.1.5" + dependencies { api("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.16.0") api("com.google.guava:guava:31.1-jre") api("org.springframework.boot:spring-boot-starter-validation:3.1.3") api("com.iqser.red.commons:jackson-commons:2.1.0") api("com.iqser.red.commons:dictionary-merge-commons:1.3.0") + implementation("org.springframework.boot:spring-boot-starter-data-mongodb:${springBootStarterVersion}") testImplementation("com.iqser.red.commons:test-commons:2.1.0") testImplementation("org.springframework.boot:spring-boot-starter-test:3.0.4") compileOnly("org.springdoc:springdoc-openapi-ui:1.7.0") diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/CascadeSave.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/CascadeSave.java new file mode 100644 index 000000000..05888eda4 --- /dev/null +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/CascadeSave.java @@ -0,0 +1,12 @@ +package com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface CascadeSave { + // +} diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/EntityLog.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/EntityLog.java index b1de32916..9c23a9551 100644 --- a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/EntityLog.java +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/EntityLog.java @@ -3,6 +3,10 @@ package com.iqser.red.service.persistence.service.v1.api.shared.model.analysislo import java.util.ArrayList; import java.util.List; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.DBRef; +import org.springframework.data.mongodb.core.mapping.Document; + import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -10,8 +14,15 @@ import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor +@Document(collection = "entity-logs") public class EntityLog { + @Id + private String id; + + private String dossierId; + + private String fileId; /** * Version 0 Redaction Logs have manual redactions merged inside them * Version 1 Redaction Logs only contain system ( rule/dictionary ) redactions. Manual Redactions are merged in at runtime. @@ -23,6 +34,8 @@ public class EntityLog { */ private int analysisNumber; + @DBRef + @CascadeSave private List entityLogEntry = new ArrayList<>(); private List legalBasis = new ArrayList<>(); @@ -31,4 +44,33 @@ public class EntityLog { private long rulesVersion = -1; private long legalBasisVersion = -1; + + public EntityLog(String dossierId, + String fileId, + long analysisVersion, + int analysisNumber, + List entityLogEntry, + List legalBasis, + long dictionaryVersion, + long dossierDictionaryVersion, + long rulesVersion, + long legalBasisVersion) { + + this.id = getId(dossierId, fileId); + this.dossierId = dossierId; + this.fileId = fileId; + this.analysisVersion = analysisVersion; + this.analysisNumber = analysisNumber; + this.entityLogEntry = entityLogEntry; + this.legalBasis = legalBasis; + this.dictionaryVersion = dictionaryVersion; + this.dossierDictionaryVersion = dossierDictionaryVersion; + this.rulesVersion = rulesVersion; + this.legalBasisVersion = legalBasisVersion; + } + + public static String getId(String dossierId, String fileId) { + return dossierId + "/" + fileId; + } + } diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/EntityLogEntry.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/EntityLogEntry.java index 362ead2dc..1a222de20 100644 --- a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/EntityLogEntry.java +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/EntityLogEntry.java @@ -5,6 +5,8 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import org.springframework.data.mongodb.core.mapping.Document; + import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; @@ -19,9 +21,11 @@ import lombok.experimental.FieldDefaults; @AllArgsConstructor @EqualsAndHashCode @FieldDefaults(level = AccessLevel.PRIVATE) +@Document(collection = "entity-log-entries") public class EntityLogEntry { - String id; + String entryId; + String entityLogId; String type; EntryType entryType; EntryState state; From f8741b54d3b3c7c3519cdfeae7b364a0a7f040a3 Mon Sep 17 00:00:00 2001 From: maverickstuder Date: Thu, 14 Mar 2024 09:17:12 +0100 Subject: [PATCH 2/9] RED-8702 --- .../service/EntityLogMergeService.java | 16 +- .../processor/service/EntityLogService.java | 2 +- .../ManualRedactionMapper.java | 3 +- .../ManualRedactionService.java | 2 +- .../ManualRedactionUndoService.java | 2 +- .../PendingDictionaryEntryFactory.java | 8 +- .../service/FileTesterAndProvider.java | 6 +- .../integration/tests/EntityLogMergeTest.java | 36 ++-- .../v1/server/integration/tests/FileTest.java | 7 +- .../tests/ManualRedactionTest.java | 166 ++++++------------ .../AbstractPersistenceServerServiceTest.java | 6 +- .../analysislog/entitylog/CascadeSave.java | 12 -- .../analysislog/entitylog/EntityLog.java | 42 ----- .../analysislog/entitylog/EntityLogEntry.java | 6 +- 14 files changed, 92 insertions(+), 222 deletions(-) delete mode 100644 persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/CascadeSave.java diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogMergeService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogMergeService.java index a588c72e5..12ba5b1ea 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogMergeService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogMergeService.java @@ -81,7 +81,7 @@ public class EntityLogMergeService { List matchingEntities = entityLog.getEntityLogEntry() .stream() - .filter(entityLogEntry -> manualChangesIds.contains(entityLogEntry.getEntryId())) + .filter(entityLogEntry -> manualChangesIds.contains(entityLogEntry.getId())) .collect(Collectors.toList()); final int analysisNumber = entityLog.getAnalysisNumber(); @@ -143,7 +143,7 @@ public class EntityLogMergeService { private EntityLogEntry findMatchingEntry(String annotationId, List matchingEntities) { return matchingEntities.stream() - .filter(entityLogEntry -> entityLogEntry.getEntryId().equals(annotationId)) + .filter(entityLogEntry -> entityLogEntry.getId().equals(annotationId)) .findAny() .orElseThrow(() -> new NotFoundException("No matching EntityLogEntry found for id " + annotationId)); } @@ -182,7 +182,7 @@ public class EntityLogMergeService { boolean isHint = isHint(manualRedactionEntry.getType(), dossier); EntityLogEntry entityLogEntry = EntityLogEntry.builder() - .entryId(manualRedactionEntry.getAnnotationId()) + .id(manualRedactionEntry.getAnnotationId()) .type(manualRedactionEntry.getType()) .value(manualRedactionEntry.getValue()) .legalBasis(manualRedactionEntry.getLegalBasis()) @@ -237,7 +237,7 @@ public class EntityLogMergeService { private void mergeIdsToRemove(IdRemoval idRemoval, List entityLogEntries, int analysisNumber) { var entity = entityLogEntries.stream() - .filter(entityLogEntry -> entityLogEntry.getEntryId().equals(idRemoval.getAnnotationId())) + .filter(entityLogEntry -> entityLogEntry.getId().equals(idRemoval.getAnnotationId())) .findAny(); entity.ifPresent(entityLogEntry -> { entityLogEntry.setState(EntryState.IGNORED); @@ -258,7 +258,7 @@ public class EntityLogMergeService { private void mergeResizeRedactions(ManualResizeRedaction manualResizeRedaction, List entityLogEntries, int analysisNumber) { var entity = entityLogEntries.stream() - .filter(entityLogEntry -> entityLogEntry.getEntryId().equals(manualResizeRedaction.getAnnotationId())) + .filter(entityLogEntry -> entityLogEntry.getId().equals(manualResizeRedaction.getAnnotationId())) .findAny(); entity.ifPresent(entityLogEntry -> { entityLogEntry.setTextAfter(manualResizeRedaction.getTextAfter()); @@ -283,7 +283,7 @@ public class EntityLogMergeService { private void mergeLegalBasisChanges(ManualLegalBasisChange manualLegalBasisChange, List entityLogEntries, int analysisNumber) { var entity = entityLogEntries.stream() - .filter(entityLogEntry -> entityLogEntry.getEntryId().equals(manualLegalBasisChange.getAnnotationId())) + .filter(entityLogEntry -> entityLogEntry.getId().equals(manualLegalBasisChange.getAnnotationId())) .findAny(); entity.ifPresent(entityLogEntry -> { entityLogEntry.setLegalBasis(manualLegalBasisChange.getLegalBasis()); @@ -325,7 +325,7 @@ public class EntityLogMergeService { boolean isHint = isHint(recategorization.getType(), dossier); var entity = entityLogEntries.stream() - .filter(entityLogEntry -> entityLogEntry.getEntryId().equals(recategorization.getAnnotationId())) + .filter(entityLogEntry -> entityLogEntry.getId().equals(recategorization.getAnnotationId())) .findAny(); entity.ifPresent(entityLogEntry -> { entityLogEntry.setType(recategorization.getType()); @@ -348,7 +348,7 @@ public class EntityLogMergeService { private void mergeForceRedactions(ManualForceRedaction forceRedaction, List entityLogEntries, int analysisNumber) { var entity = entityLogEntries.stream() - .filter(entityLogEntry -> entityLogEntry.getEntryId().equals(forceRedaction.getAnnotationId())) + .filter(entityLogEntry -> entityLogEntry.getId().equals(forceRedaction.getAnnotationId())) .findAny(); entity.ifPresent(entityLogEntry -> { entityLogEntry.setLegalBasis(forceRedaction.getLegalBasis()); diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogService.java index dd6e406a7..d763854da 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogService.java @@ -80,7 +80,7 @@ public class EntityLogService { Map commentCountPerAnnotationId = commentService.getCommentCounts(fileId); entityLog.getEntityLogEntry() - .forEach(entityLogEntry -> entityLogEntry.setNumberOfComments(commentCountPerAnnotationId.getOrDefault(entityLogEntry.getEntryId(), 0))); + .forEach(entityLogEntry -> entityLogEntry.setNumberOfComments(commentCountPerAnnotationId.getOrDefault(entityLogEntry.getId(), 0))); return entityLog; } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionMapper.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionMapper.java index f667dabe4..83a314bae 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionMapper.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionMapper.java @@ -10,6 +10,7 @@ import java.util.Set; import org.springframework.stereotype.Service; +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.service.EntityLogService; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLog; @@ -186,7 +187,7 @@ public class ManualRedactionMapper { return entityLog.getEntityLogEntry() .stream() - .filter(entry -> entry.getEntryId().equals(annotationId)) + .filter(entry -> entry.getId().equals(annotationId)) .findFirst() .orElseThrow(() -> new NotFoundException("Annotation does not exist in entity log.")); } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionService.java index f3c56a10a..82e4549a5 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionService.java @@ -348,7 +348,7 @@ public class ManualRedactionService { return entityLog.getEntityLogEntry() .stream() - .filter(entry -> entry.getEntryId().equals(annotationId)) + .filter(entry -> entry.getId().equals(annotationId)) .findFirst() .orElseThrow(() -> new NotFoundException("Annotation does not exist in entity log.")); } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionUndoService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionUndoService.java index b47411bba..d753850c1 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionUndoService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionUndoService.java @@ -343,7 +343,7 @@ public class ManualRedactionUndoService { return entityLog.getEntityLogEntry() .stream() - .filter(entry -> entry.getEntryId().equals(annotationId)) + .filter(entry -> entry.getId().equals(annotationId)) .findFirst() .orElseThrow(() -> new NotFoundException("Annotation does not exist in entity log.")); } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/PendingDictionaryEntryFactory.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/PendingDictionaryEntryFactory.java index 8c53a07d0..6c9a317ed 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/PendingDictionaryEntryFactory.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/PendingDictionaryEntryFactory.java @@ -35,7 +35,7 @@ public class PendingDictionaryEntryFactory { .propertyChanges(Map.of("value", manualRedactionEntry.getValue())) .build()); return EntityLogEntry.builder() - .entryId(manualRedactionEntry.getAnnotationId()) + .id(manualRedactionEntry.getAnnotationId()) .value(manualRedactionEntry.getValue()) .type(manualRedactionEntry.getType()) .entryType(Optional.ofNullable(manualRedactionEntry.getDictionaryEntryType()) @@ -82,7 +82,7 @@ public class PendingDictionaryEntryFactory { .build()); return EntityLogEntry.builder() - .entryId(originalEntry.getEntryId()) + .id(originalEntry.getId()) .value(originalEntry.getValue()) .type(originalEntry.getType()) .entryType(originalEntry.getEntryType()) @@ -121,7 +121,7 @@ public class PendingDictionaryEntryFactory { .propertyChanges(propertyChanges) .build()); return EntityLogEntry.builder() - .entryId(originalEntry.getEntryId()) + .id(originalEntry.getId()) .value(manualChange.getValue()) .type(originalEntry.getType()) .entryType(originalEntry.getEntryType()) @@ -171,7 +171,7 @@ public class PendingDictionaryEntryFactory { .build()); return EntityLogEntry.builder() - .entryId(originalEntry.getEntryId()) + .id(originalEntry.getId()) .value(originalEntry.getValue()) .type(manualChange.getType()) .entryType(originalEntry.getEntryType()) 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 8ffe31af6..e856e1b16 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 @@ -67,12 +67,10 @@ public class FileTesterAndProvider { fileManagementStorageService.storeJSONObject(dossier.getId(), file.getFileId(), FileType.ENTITY_LOG, - new EntityLog(dossier.getId(), - fileId, - 1, + new EntityLog(1, 1, List.of(EntityLogEntry.builder() - .entryId("annotationId") + .id("annotationId") .type("manual") .value("value entry") .entryType(EntryType.ENTITY) diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/EntityLogMergeTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/EntityLogMergeTest.java index 2de272ccf..7a041bc58 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/EntityLogMergeTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/EntityLogMergeTest.java @@ -120,7 +120,7 @@ public class EntityLogMergeTest { ManualRedactions manualRedactions = provideManualRedactions(entryToAddId, entryToRemoveId, entryToResizeId, entryLegalBasisId, forceRedactionId, fileId, rectangleToAddId); - var entityLog = provideEntityLog(dossierId, fileId, entryToRemoveId, entryToResizeId, entryLegalBasisId, forceRedactionId); + var entityLog = provideEntityLog(entryToRemoveId, entryToResizeId, entryLegalBasisId, forceRedactionId); when(manualRedactionProviderService.getManualRedactions(any(), any())).thenReturn(manualRedactions); when(fileStatusService.getStatus(fileId)).thenReturn(FileModel.builder().excluded(false).dossierStatusId(dossierTemplateId).id(fileId).build()); @@ -137,7 +137,7 @@ public class EntityLogMergeTest { var optionalEntityLogEntry = response.getEntityLogEntry() .stream() - .filter(entityLogEntry1 -> entityLogEntry1.getEntryId().equals(entryToAddId)) + .filter(entityLogEntry1 -> entityLogEntry1.getId().equals(entryToAddId)) .findFirst(); assertTrue(optionalEntityLogEntry.isPresent()); var entityLogEntry = optionalEntityLogEntry.get(); @@ -152,7 +152,7 @@ public class EntityLogMergeTest { var optionalRemoveEntryLogEntry = response.getEntityLogEntry() .stream() - .filter(entityLogEntry1 -> entityLogEntry1.getEntryId().equals(entryToRemoveId)) + .filter(entityLogEntry1 -> entityLogEntry1.getId().equals(entryToRemoveId)) .findFirst(); assertTrue(optionalRemoveEntryLogEntry.isPresent()); var removeEntryLogEntry = optionalRemoveEntryLogEntry.get(); @@ -166,7 +166,7 @@ public class EntityLogMergeTest { var optionalResizeEntryLogEntry = response.getEntityLogEntry() .stream() - .filter(entityLogEntry1 -> entityLogEntry1.getEntryId().equals(entryToResizeId)) + .filter(entityLogEntry1 -> entityLogEntry1.getId().equals(entryToResizeId)) .findFirst(); assertTrue(optionalResizeEntryLogEntry.isPresent()); var resizeEntryLogEntry = optionalResizeEntryLogEntry.get(); @@ -190,7 +190,7 @@ public class EntityLogMergeTest { var optionalLegalBasisEntryLogEntry = response.getEntityLogEntry() .stream() - .filter(entityLogEntry1 -> entityLogEntry1.getEntryId().equals(entryLegalBasisId)) + .filter(entityLogEntry1 -> entityLogEntry1.getId().equals(entryLegalBasisId)) .findFirst(); assertTrue(optionalLegalBasisEntryLogEntry.isPresent()); var legalBasisEntryLogEntry = optionalLegalBasisEntryLogEntry.get(); @@ -205,7 +205,7 @@ public class EntityLogMergeTest { var optionalForceRedactionEntryLogEntry = response.getEntityLogEntry() .stream() - .filter(entityLogEntry1 -> entityLogEntry1.getEntryId().equals(forceRedactionId)) + .filter(entityLogEntry1 -> entityLogEntry1.getId().equals(forceRedactionId)) .findFirst(); assertTrue(optionalForceRedactionEntryLogEntry.isPresent()); var forceRedactionEntryLogEntry = optionalForceRedactionEntryLogEntry.get(); @@ -220,7 +220,7 @@ public class EntityLogMergeTest { var optionalRectangleEntryLogEntry = response.getEntityLogEntry() .stream() - .filter(entityLogEntry1 -> entityLogEntry1.getEntryId().equals(rectangleToAddId)) + .filter(entityLogEntry1 -> entityLogEntry1.getId().equals(rectangleToAddId)) .findFirst(); assertTrue(optionalRectangleEntryLogEntry.isPresent()); var rectangleEntryLogEntry = optionalRectangleEntryLogEntry.get(); @@ -236,24 +236,22 @@ public class EntityLogMergeTest { } - private EntityLog provideEntityLog(String dossierId, String fileId, String entryToRemoveId, String entryToResizeId, String entryLegalBasisId, String forceRedactionId) { + private EntityLog provideEntityLog(String entryToRemoveId, String entryToResizeId, String entryLegalBasisId, String forceRedactionId) { List positions = new ArrayList<>(); positions.add(new Position(1, 1, 1, 1, 1)); - return new EntityLog(dossierId, - fileId, + return new EntityLog(1, 1, - 1, - Lists.newArrayList(EntityLogEntry.builder().entityLogId(EntityLog.getId(dossierId, fileId)) - .entryId(entryToRemoveId) + Lists.newArrayList(EntityLogEntry.builder() + .id(entryToRemoveId) .type("manual") .value("Luke Skywalker") .entryType(EntryType.ENTITY) .state(EntryState.APPLIED) .dictionaryEntry(true) .build(), - EntityLogEntry.builder().entityLogId(EntityLog.getId(dossierId, fileId)) - .entryId(entryToResizeId) + EntityLogEntry.builder() + .id(entryToResizeId) .type("manual") .value("Darth Vader") .entryType(EntryType.ENTITY) @@ -261,8 +259,8 @@ public class EntityLogMergeTest { .dictionaryEntry(true) .positions(positions) .build(), - EntityLogEntry.builder().entityLogId(EntityLog.getId(dossierId, fileId)) - .entryId(entryLegalBasisId) + EntityLogEntry.builder() + .id(entryLegalBasisId) .type("manual") .value("Darth Luke") .entryType(EntryType.ENTITY) @@ -270,8 +268,8 @@ public class EntityLogMergeTest { .dictionaryEntry(true) .positions(positions) .build(), - EntityLogEntry.builder().entityLogId(EntityLog.getId(dossierId, fileId)) - .entryId(forceRedactionId) + EntityLogEntry.builder() + .id(forceRedactionId) .type("manual") .value("Darth Luke") .entryType(EntryType.ENTITY) 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 3193deebd..fe831f9d0 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 @@ -369,13 +369,10 @@ public class FileTest extends AbstractPersistenceServerServiceTest { var type = typeProvider.testAndProvideType(dossierTemplate, null, "manual"); var annotationId = "imagine_this_makes_sense"; - EntityLog entityLog = new EntityLog(dossierId, - fileId, - 1, + EntityLog entityLog = new EntityLog(1, 1, List.of(EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) - .entryId(annotationId) + .id(annotationId) .type(type.getType()) .value("value entry") .state(EntryState.APPLIED) diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ManualRedactionTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ManualRedactionTest.java index ac7ff40ac..7b6107283 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ManualRedactionTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ManualRedactionTest.java @@ -45,7 +45,10 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryState; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryType; +import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AddRedactionRequest; +import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualRedactions; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Rectangle; +import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRedactionEntry; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type.DictionaryEntryType; import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.AddRedactionRequestModel; @@ -121,13 +124,10 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { dictionaryClient.addEntry(type.getType(), type.getDossierTemplateId(), List.of("Luke Skywalker"), false, dossier.getId(), DictionaryEntryType.ENTRY); - var entityLog = new EntityLog(dossier.getId(), - file.getFileId(), - 1, + var entityLog = new EntityLog(1, 1, List.of(EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) - .entryId("AnnotationId") + .id("AnnotationId") .type(type.getType()) .value("Luke Skywalker") .entryType(EntryType.ENTITY) @@ -318,13 +318,10 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { Dictionary dossierDictionary = dictionaryClient.getDictionaryForType(type.getType(), type.getDossierTemplateId(), dossier.getId()); assertThat(dossierDictionary.getEntries()).containsExactlyInAnyOrder("Luke Skywalker"); - var entityLog = new EntityLog(dossier.getId(), - file.getFileId(), - 1, + var entityLog = new EntityLog(1, 1, List.of(EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) - .entryId("AnnotationId") + .id("AnnotationId") .type("test") .value("Luke Skywalker") .entryType(EntryType.ENTITY) @@ -381,13 +378,10 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { // CreateTypeValue dossierDictionaryType = MagicConverter.convert(type, CreateTypeValue.class); // dictionaryClient.addType(dossierDictionaryType, dossier.getId()); - var entityLog = new EntityLog(dossier.getId(), - file.getFileId(), - 1, + var entityLog = new EntityLog(1, 1, List.of(EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) - .entryId("AnnotationId") + .id("AnnotationId") .type("test") .value("Luke Skywalker") .entryType(EntryType.ENTITY) @@ -439,13 +433,10 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { // dictionaryClient.addType(dossierDictionaryType, dossier.getId()); dictionaryClient.addEntry(type.getType(), type.getDossierTemplateId(), List.of("Luke Skywalker"), false, dossier.getId(), DictionaryEntryType.ENTRY); - var entityLog = new EntityLog(dossier.getId(), - file.getFileId(), - 1, + var entityLog = new EntityLog(1, 1, List.of(EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) - .entryId("AnnotationId") + .id("AnnotationId") .type("test") .value("Luke Skywalker") .entryType(EntryType.ENTITY) @@ -529,13 +520,10 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { var addRedactions = manualRedactionClient.addRedactionBulk(dossier1.getId(), file1.getId(), Set.of(redactionDos, redactionDosTempDict)); var loadedRedactionsFile1 = manualRedactionClient.getManualRedactions(file1.getDossierId(), file1.getFileId(), false, true); - var entityLog1 = new EntityLog(dossier1.getId(), - file1.getFileId(), - 1, + var entityLog1 = new EntityLog(1, 1, List.of(EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier1.getId(), file1.getFileId())) - .entryId(addRedactions.get(0).getAnnotationId()) + .id(addRedactions.get(0).getAnnotationId()) .type(typeDosDict.getType()) .value("test redaction in dossier") .dossierDictionaryEntry(true) @@ -543,8 +531,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { .state(EntryState.APPLIED) .build(), EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier1.getId(), file1.getFileId())) - .entryId(addRedactions.get(1).getAnnotationId()) + .id(addRedactions.get(1).getAnnotationId()) .type(typeDosTempDict.getType()) .value("test redaction in dossier template") .dictionaryEntry(true) @@ -560,13 +547,10 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { var redactionRequest1 = RedactionRequest.builder().dossierId(file1.getDossierId()).fileId(file1.getFileId()).dossierTemplateId(file1.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(eq(file1.getDossierId()), eq(file1.getFileId()), any(), anyBoolean())).thenReturn(entityLog1); - var entityLog2 = new EntityLog(dossier2.getId(), - file2.getFileId(), - 1, + var entityLog2 = new EntityLog(1, 1, List.of(EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier2.getId(), file2.getFileId())) - .entryId(addRedactions.get(1).getAnnotationId()) + .id(addRedactions.get(1).getAnnotationId()) .type(typeDosTempDict.getType()) .value("test redaction in dossier template") .dictionaryEntry(true) @@ -701,13 +685,10 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { var addRedactions = manualRedactionClient.addRedactionBulk(dossier1.getId(), file1.getId(), Set.of(redactionDos, redactionDosTempDict)); var loadedRedactionsFile1 = manualRedactionClient.getManualRedactions(file1.getDossierId(), file1.getFileId(), false, true); - var entityLog1 = new EntityLog(dossier1.getId(), - file1.getFileId(), - 1, + var entityLog1 = new EntityLog(1, 1, List.of(EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier1.getId(), file1.getFileId())) - .entryId(addRedactions.get(0).getAnnotationId()) + .id(addRedactions.get(0).getAnnotationId()) .type(typeDosDict.getType()) .value("test redaction in dossier yayy") .dossierDictionaryEntry(true) @@ -715,8 +696,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { .state(EntryState.APPLIED) .build(), EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier1.getId(), file1.getFileId())) - .entryId(addRedactions.get(1).getAnnotationId()) + .id(addRedactions.get(1).getAnnotationId()) .type(typeDosTempDict.getType()) .value("test redaction in dossier template yayy") .dictionaryEntry(true) @@ -732,13 +712,10 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { var redactionRequest1 = RedactionRequest.builder().dossierId(file1.getDossierId()).fileId(file1.getFileId()).dossierTemplateId(file1.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(eq(file1.getDossierId()), eq(file1.getFileId()), any(), anyBoolean())).thenReturn(entityLog1); - var entityLog2 = new EntityLog(dossier2.getId(), - file2.getFileId(), - 1, + var entityLog2 = new EntityLog(1, 1, List.of(EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier2.getId(), file2.getFileId())) - .entryId(addRedactions.get(1).getAnnotationId()) + .id(addRedactions.get(1).getAnnotationId()) .type(typeDosTempDict.getType()) .value("test redaction in dossier template yayy") .dictionaryEntry(true) @@ -877,13 +854,10 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { var addRedactions = manualRedactionClient.addRedactionBulk(dossier1.getId(), file1.getId(), Set.of(redactionDos, redactionDosTempDict)); - var entityLog1 = new EntityLog(dossier1.getId(), - file1.getFileId(), - 1, + var entityLog1 = new EntityLog(1, 1, List.of(EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier1.getId(), file1.getFileId())) - .entryId(addRedactions.get(0).getAnnotationId()) + .id(addRedactions.get(0).getAnnotationId()) .type(typeDosDict.getType()) .value("test redaction in dossier") .dossierDictionaryEntry(true) @@ -891,8 +865,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { .state(EntryState.APPLIED) .build(), EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier1.getId(), file1.getFileId())) - .entryId(addRedactions.get(1).getAnnotationId()) + .id(addRedactions.get(1).getAnnotationId()) .type(typeDosTempDict.getType()) .value("test redaction in dossier template") .dictionaryEntry(true) @@ -908,13 +881,10 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { var redactionRequest1 = RedactionRequest.builder().dossierId(file1.getDossierId()).fileId(file1.getFileId()).dossierTemplateId(file1.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(file1.getDossierId(), file1.getFileId())).thenReturn(entityLog1); - var entityLog2 = new EntityLog(dossier2.getId(), - file2.getFileId(), - 1, + var entityLog2 = new EntityLog(1, 1, List.of(EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier2.getId(), file2.getFileId())) - .entryId(addRedactions.get(1).getAnnotationId()) + .id(addRedactions.get(1).getAnnotationId()) .type(typeDosTempDict.getType()) .value("test redaction in dossier template") .dictionaryEntry(true) @@ -1050,13 +1020,10 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { var addRedactions = manualRedactionClient.addRedactionBulk(dossier1.getId(), file1.getId(), Set.of(redactionDos, redactionDosTempDict)); - var entityLog1 = new EntityLog(dossier1.getId(), - file1.getFileId(), - 1, + var entityLog1 = new EntityLog(1, 1, List.of(EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier1.getId(), file1.getFileId())) - .entryId(addRedactions.get(0).getAnnotationId()) + .id(addRedactions.get(0).getAnnotationId()) .type(typeDosDict.getType()) .value("test redaction in dossier yayy") .dossierDictionaryEntry(true) @@ -1064,8 +1031,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { .state(EntryState.APPLIED) .build(), EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier1.getId(), file1.getFileId())) - .entryId(addRedactions.get(1).getAnnotationId()) + .id(addRedactions.get(1).getAnnotationId()) .type(typeDosTempDict.getType()) .value("test redaction in dossier template yayy") .dictionaryEntry(true) @@ -1081,13 +1047,10 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { var redactionRequest1 = RedactionRequest.builder().dossierId(file1.getDossierId()).fileId(file1.getFileId()).dossierTemplateId(file1.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(file1.getDossierId(), file1.getFileId())).thenReturn(entityLog1); - var entityLog2 = new EntityLog(dossier2.getId(), - file2.getFileId(), - 1, + var entityLog2 = new EntityLog(1, 1, List.of(EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier2.getId(), file2.getFileId())) - .entryId(addRedactions.get(1).getAnnotationId()) + .id(addRedactions.get(1).getAnnotationId()) .type(typeDosTempDict.getType()) .value("test redaction in dossier template yayy") .dictionaryEntry(true) @@ -1208,13 +1171,10 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { assertThat(dossierDictionary2.getEntries()).isEmpty(); var annotationId = "AnnotationId"; - var entityLog = new EntityLog(dossier.getId(), - file.getFileId(), - 1, + var entityLog = new EntityLog(1, 1, List.of(EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) - .entryId(annotationId) + .id(annotationId) .type(type.getType()) .value(lukeSkywalker) .dictionaryEntry(true) @@ -1295,13 +1255,10 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { assertThat(dossierDictionary2.getEntries()).isEmpty(); var annotationId = "AnnotationId"; - var entityLog = new EntityLog(dossier.getId(), - file.getFileId(), - 1, + var entityLog = new EntityLog(1, 1, List.of(EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) - .entryId(annotationId) + .id(annotationId) .type(type.getType()) .value(lukeSkywalker) .dictionaryEntry(true) @@ -1469,13 +1426,10 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { dictionaryClient.addEntry(type.getType(), type.getDossierTemplateId(), List.of("Anakin"), false, dossier.getId(), DictionaryEntryType.ENTRY); - var entityLog = new EntityLog(dossier.getId(), - file.getFileId(), - 1, + var entityLog = new EntityLog(1, 1, List.of(EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) - .entryId("AnnotationId") + .id("AnnotationId") .type(type.getType()) .value("Anakin") .entryType(EntryType.ENTITY) @@ -1483,8 +1437,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { .dictionaryEntry(false) .build(), EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) - .entryId("AnnotationId2") + .id("AnnotationId2") .type(type.getType()) .value("Anakin2") .entryType(EntryType.ENTITY) @@ -1672,13 +1625,10 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { dictionaryClient.addEntry(type.getType(), type.getDossierTemplateId(), List.of("Darth Vader"), false, dossier.getId(), DictionaryEntryType.ENTRY); - var entityLog = new EntityLog(dossier.getId(), - file.getFileId(), - 1, + var entityLog = new EntityLog(1, 1, List.of(EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) - .entryId("dv") + .id("dv") .type(type.getType()) .value("Darth Vader") .entryType(EntryType.ENTITY) @@ -1686,8 +1636,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { .dictionaryEntry(false) .build(), EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) - .entryId("dv2") + .id("dv2") .type(type.getType()) .value("Vader Darth") .entryType(EntryType.ENTITY) @@ -1782,13 +1731,10 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { dictionaryClient.addEntry(type.getType(), type.getDossierTemplateId(), List.of("Luke Skywalker"), false, dossier.getId(), DictionaryEntryType.ENTRY); - var entityLog = new EntityLog(dossier.getId(), - file.getFileId(), - 1, + var entityLog = new EntityLog(1, 1, List.of(EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) - .entryId("AnnotationId") + .id("AnnotationId") .type(type.getType()) .value("Luke Skywalker") .entryType(EntryType.ENTITY) @@ -1796,8 +1742,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { .dictionaryEntry(false) .build(), EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) - .entryId("AnnotationId2") + .id("AnnotationId2") .type(type.getType()) .value("Skywalker Luke") .entryType(EntryType.ENTITY) @@ -1896,13 +1841,10 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { dictionaryClient.addEntry(type.getType(), type.getDossierTemplateId(), List.of("Luke Skywalker"), false, dossier.getId(), DictionaryEntryType.ENTRY); - var entityLog = new EntityLog(dossier.getId(), - file.getFileId(), - 1, + var entityLog = new EntityLog(1, 1, List.of(EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) - .entryId("AnnotationId") + .id("AnnotationId") .type(type.getType()) .value("Luke Skywalker") .entryType(EntryType.ENTITY) @@ -1910,8 +1852,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { .dictionaryEntry(false) .build(), EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) - .entryId("AnnotationId2") + .id("AnnotationId2") .type(type.getType()) .value("Skywalker Luke") .entryType(EntryType.ENTITY) @@ -1976,13 +1917,10 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { var type = typeProvider.testAndProvideType(dossierTemplate, null, "type", false); - var entityLog = new EntityLog(dossier.getId(), - file.getFileId(), - 1, + var entityLog = new EntityLog(1, 1, List.of(EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) - .entryId("annotationId") + .id("annotationId") .type(type.getType()) .value("lukeSkywalker") .dictionaryEntry(true) @@ -1990,8 +1928,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { .state(EntryState.APPLIED) .build(), EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) - .entryId("annotationId2") + .id("annotationId2") .type(type.getType()) .value("Johannesbrotkernmehl") .dictionaryEntry(true) @@ -1999,8 +1936,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { .state(EntryState.APPLIED) .build(), EntityLogEntry.builder() - .entityLogId(EntityLog.getId(dossier.getId(), file.getFileId())) - .entryId("annotationId3") + .id("annotationId3") .type(type.getType()) .value("Baustelle") .dictionaryEntry(true) 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 344d95169..76eb9a805 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 @@ -249,10 +249,8 @@ public abstract class AbstractPersistenceServerServiceTest { // doNothing().when(pdfTronRedactionClient).testDigitalCurrentSignature(Mockito.any()); when(amqpAdmin.getQueueInfo(Mockito.any())).thenReturn(null); - when(entityLogService.getEntityLog(Mockito.any(), Mockito.any())).thenReturn(new EntityLog("", "", 1, 1, Lists.newArrayList(), null, 0, 0, 0, 0)); - when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyBoolean())).thenReturn(new EntityLog("", - "", - 1, + when(entityLogService.getEntityLog(Mockito.any(), Mockito.any())).thenReturn(new EntityLog(1, 1, Lists.newArrayList(), null, 0, 0, 0, 0)); + when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyBoolean())).thenReturn(new EntityLog(1, 1, Lists.newArrayList(), null, diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/CascadeSave.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/CascadeSave.java deleted file mode 100644 index 05888eda4..000000000 --- a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/CascadeSave.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface CascadeSave { - // -} diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/EntityLog.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/EntityLog.java index 9c23a9551..b1de32916 100644 --- a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/EntityLog.java +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/EntityLog.java @@ -3,10 +3,6 @@ package com.iqser.red.service.persistence.service.v1.api.shared.model.analysislo import java.util.ArrayList; import java.util.List; -import org.springframework.data.annotation.Id; -import org.springframework.data.mongodb.core.mapping.DBRef; -import org.springframework.data.mongodb.core.mapping.Document; - import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -14,15 +10,8 @@ import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor -@Document(collection = "entity-logs") public class EntityLog { - @Id - private String id; - - private String dossierId; - - private String fileId; /** * Version 0 Redaction Logs have manual redactions merged inside them * Version 1 Redaction Logs only contain system ( rule/dictionary ) redactions. Manual Redactions are merged in at runtime. @@ -34,8 +23,6 @@ public class EntityLog { */ private int analysisNumber; - @DBRef - @CascadeSave private List entityLogEntry = new ArrayList<>(); private List legalBasis = new ArrayList<>(); @@ -44,33 +31,4 @@ public class EntityLog { private long rulesVersion = -1; private long legalBasisVersion = -1; - - public EntityLog(String dossierId, - String fileId, - long analysisVersion, - int analysisNumber, - List entityLogEntry, - List legalBasis, - long dictionaryVersion, - long dossierDictionaryVersion, - long rulesVersion, - long legalBasisVersion) { - - this.id = getId(dossierId, fileId); - this.dossierId = dossierId; - this.fileId = fileId; - this.analysisVersion = analysisVersion; - this.analysisNumber = analysisNumber; - this.entityLogEntry = entityLogEntry; - this.legalBasis = legalBasis; - this.dictionaryVersion = dictionaryVersion; - this.dossierDictionaryVersion = dossierDictionaryVersion; - this.rulesVersion = rulesVersion; - this.legalBasisVersion = legalBasisVersion; - } - - public static String getId(String dossierId, String fileId) { - return dossierId + "/" + fileId; - } - } diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/EntityLogEntry.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/EntityLogEntry.java index 1a222de20..362ead2dc 100644 --- a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/EntityLogEntry.java +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/EntityLogEntry.java @@ -5,8 +5,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import org.springframework.data.mongodb.core.mapping.Document; - import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; @@ -21,11 +19,9 @@ import lombok.experimental.FieldDefaults; @AllArgsConstructor @EqualsAndHashCode @FieldDefaults(level = AccessLevel.PRIVATE) -@Document(collection = "entity-log-entries") public class EntityLogEntry { - String entryId; - String entityLogId; + String id; String type; EntryType entryType; EntryState state; From cfdd6a6924c1f154e8239703447ccb830eac0a0a Mon Sep 17 00:00:00 2001 From: maverickstuder Date: Mon, 18 Mar 2024 15:05:41 +0100 Subject: [PATCH 3/9] RED-8702: Explore document databases to store entityLog * added mongodb documents, repositories and EntityLogMongoService * refactored places where entity logs were stored and loaded to use new logic --- .../internal/AdminInterfaceController.java | 4 +- .../build.gradle.kts | 5 +- .../processor/document/EntityLogDocument.java | 75 ++++++ .../document/EntityLogEntryDocument.java | 114 +++++++++ .../EntityLogDocumentNotFoundException.java | 10 + .../migration/SaasMigrationService.java | 1 + .../ManualRedactionTypeRenameMigration15.java | 4 +- .../service/FileManagementStorageService.java | 30 ++- .../processor/service/FileStatusService.java | 4 +- .../persistence/EntityLogMongoService.java | 238 ++++++++++++++++++ .../EntityLogDocumentRepository.java | 15 ++ .../EntityLogEntryDocumentRepository.java | 23 ++ .../service/FileTesterAndProvider.java | 3 +- .../tests/ManualRedactionTest.java | 40 +-- .../build.gradle.kts | 1 - 15 files changed, 528 insertions(+), 39 deletions(-) create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogDocument.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogEntryDocument.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/EntityLogDocumentNotFoundException.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/EntityLogMongoService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntityLogDocumentRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntityLogEntryDocumentRepository.java diff --git a/persistence-service-v1/persistence-service-internal-api-impl-v1/src/main/java/com/iqser/red/service/persistence/v1/internal/api/controller/internal/AdminInterfaceController.java b/persistence-service-v1/persistence-service-internal-api-impl-v1/src/main/java/com/iqser/red/service/persistence/v1/internal/api/controller/internal/AdminInterfaceController.java index 0cdb2ca51..0f58f9dad 100644 --- a/persistence-service-v1/persistence-service-internal-api-impl-v1/src/main/java/com/iqser/red/service/persistence/v1/internal/api/controller/internal/AdminInterfaceController.java +++ b/persistence-service-v1/persistence-service-internal-api-impl-v1/src/main/java/com/iqser/red/service/persistence/v1/internal/api/controller/internal/AdminInterfaceController.java @@ -36,7 +36,7 @@ public class AdminInterfaceController { public void resetFile(@RequestParam("dossierId") String dossierId, @RequestParam("fileId") String fileId) { fileManagementStorageService.deleteObject(dossierId, fileId, FileType.REDACTION_LOG); - fileManagementStorageService.deleteObject(dossierId, fileId, FileType.ENTITY_LOG); + fileManagementStorageService.deleteEntityLog(dossierId, fileId); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.DOCUMENT_PAGES); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.DOCUMENT_TEXT); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.DOCUMENT_POSITION); @@ -141,7 +141,7 @@ public class AdminInterfaceController { var fileId = file.getId(); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.REDACTION_LOG); - fileManagementStorageService.deleteObject(dossierId, fileId, FileType.ENTITY_LOG); + fileManagementStorageService.deleteEntityLog(dossierId, fileId); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.DOCUMENT_STRUCTURE); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.DOCUMENT_TEXT); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.DOCUMENT_PAGES); 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 1fb9d4bcf..0e277da9a 100644 --- a/persistence-service-v1/persistence-service-processor-v1/build.gradle.kts +++ b/persistence-service-v1/persistence-service-processor-v1/build.gradle.kts @@ -34,8 +34,8 @@ dependencies { exclude(group = "com.iqser.red.service", module = "persistence-service-shared-api-v1") } api("com.knecon.fforesight:jobs-commons:0.10.0") - api("com.knecon.fforesight:database-tenant-commons:0.21.0") - api("com.knecon.fforesight:keycloak-commons:0.25.0") + api("com.knecon.fforesight:database-tenant-commons:maverick-mongo") + api("com.knecon.fforesight:keycloak-commons:maverick-mongo") api("com.knecon.fforesight:tracing-commons:0.5.0") api("com.knecon.fforesight:swagger-commons:0.5.0") api("com.giffing.bucket4j.spring.boot.starter:bucket4j-spring-boot-starter:0.4.0") @@ -43,6 +43,7 @@ dependencies { api("org.springframework.boot:spring-boot-starter-mail:${springBootStarterVersion}") api("org.springframework.boot:spring-boot-starter-data-jpa:${springBootStarterVersion}") api("org.springframework.boot:spring-boot-starter-data-redis:${springBootStarterVersion}") + api("org.springframework.boot:spring-boot-starter-data-mongodb:${springBootStarterVersion}") api("org.springframework.boot:spring-boot-starter-amqp:${springBootStarterVersion}") api("org.springframework.boot:spring-boot-starter-web:${springBootStarterVersion}") api("com.iqser.red.commons:spring-commons:2.1.0") diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogDocument.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogDocument.java new file mode 100644 index 000000000..2e3d06b46 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogDocument.java @@ -0,0 +1,75 @@ +package com.iqser.red.service.persistence.management.v1.processor.document; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.DBRef; +import org.springframework.data.mongodb.core.mapping.Document; + +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLog; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogLegalBasis; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +@EqualsAndHashCode(onlyExplicitlyIncluded = true) +@Document(collection = "entity-logs") +public class EntityLogDocument { + + @Id + @EqualsAndHashCode.Include + private String id; + + private String dossierId; + private String fileId; + + private long analysisVersion; + + //@Indexed(direction = IndexDirection.DESCENDING) + private int analysisNumber; + + @DBRef + private List entityLogEntryDocument = new ArrayList<>(); + + private List legalBasis = new ArrayList<>(); + + private long dictionaryVersion = -1; + private long dossierDictionaryVersion = -1; + + private long rulesVersion = -1; + private long legalBasisVersion = -1; + + + public EntityLogDocument(String dossierId, String fileId, EntityLog entityLog) { + + this.id = getDocumentId(dossierId, fileId); + this.dossierId = dossierId; + this.fileId = fileId; + this.analysisVersion = entityLog.getAnalysisVersion(); + this.analysisNumber = entityLog.getAnalysisNumber(); + this.entityLogEntryDocument = new ArrayList<>(entityLog.getEntityLogEntry() + .stream() + .map(entityLogEntry -> new EntityLogEntryDocument(this.id, entityLogEntry)).toList()); + this.legalBasis = entityLog.getLegalBasis(); + this.dictionaryVersion = entityLog.getDictionaryVersion(); + this.dossierDictionaryVersion = entityLog.getDossierDictionaryVersion(); + this.rulesVersion = entityLog.getRulesVersion(); + this.legalBasisVersion = entityLog.getLegalBasisVersion(); + + } + + + public static String getDocumentId(String dossierId, String fileId) { + + return dossierId + "/" + fileId; + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogEntryDocument.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogEntryDocument.java new file mode 100644 index 000000000..87963463a --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogEntryDocument.java @@ -0,0 +1,114 @@ +package com.iqser.red.service.persistence.management.v1.processor.document; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Change; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Engine; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryState; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryType; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.ManualChange; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Position; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.FieldDefaults; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(onlyExplicitlyIncluded = true) +@FieldDefaults(level = AccessLevel.PRIVATE) +@Document(collection = "entity-log-entries") +//@CompoundIndexes({ + //@CompoundIndex(name = "changes_analysisNumber", def = "{ 'changes.analysisNumber': 1 }") +// }) +public class EntityLogEntryDocument { + + @Id + @EqualsAndHashCode.Include + String id; + String entryId; + String entityLogId; + String type; + EntryType entryType; + EntryState state; + String value; + String reason; + String matchedRule; + String legalBasis; + + List containingNodeId; + String closestHeadline; + String section; + + List positions = new ArrayList<>(); + + String textBefore; + String textAfter; + + int startOffset; + int endOffset; + + boolean imageHasTransparency; + + boolean dictionaryEntry; + boolean dossierDictionaryEntry; + + boolean excluded; + + List changes = new ArrayList<>(); + + List manualChanges = new ArrayList<>(); + + Set engines = new HashSet<>(); + + Set reference = new HashSet<>(); + + Set importedRedactionIntersections = new HashSet<>(); + + int numberOfComments; + + + public EntityLogEntryDocument(String entityLogId, EntityLogEntry entityLogEntry) { + + this.id = entityLogId + "/" + entityLogEntry.getId(); + this.entryId = entityLogEntry.getId(); + this.entityLogId = entityLogId; + this.type = entityLogEntry.getType(); + this.entryType = entityLogEntry.getEntryType(); + this.state = entityLogEntry.getState(); + this.value = entityLogEntry.getValue(); + this.reason = entityLogEntry.getReason(); + this.matchedRule = entityLogEntry.getMatchedRule(); + this.legalBasis = entityLogEntry.getLegalBasis(); + this.containingNodeId = new ArrayList<>(entityLogEntry.getContainingNodeId()); + this.closestHeadline = entityLogEntry.getClosestHeadline(); + this.section = entityLogEntry.getSection(); + this.positions = new ArrayList<>(entityLogEntry.getPositions()); + this.textBefore = entityLogEntry.getTextBefore(); + this.textAfter = entityLogEntry.getTextAfter(); + this.startOffset = entityLogEntry.getStartOffset(); + this.endOffset = entityLogEntry.getEndOffset(); + this.imageHasTransparency = entityLogEntry.isImageHasTransparency(); + this.dictionaryEntry = entityLogEntry.isDictionaryEntry(); + this.dossierDictionaryEntry = entityLogEntry.isDossierDictionaryEntry(); + this.excluded = entityLogEntry.isExcluded(); + this.changes = new ArrayList<>(entityLogEntry.getChanges()); + this.manualChanges = new ArrayList<>(entityLogEntry.getManualChanges()); + this.engines = new HashSet<>(entityLogEntry.getEngines()); + this.reference = new HashSet<>(entityLogEntry.getReference()); + this.importedRedactionIntersections = new HashSet<>(entityLogEntry.getImportedRedactionIntersections()); + this.numberOfComments = entityLogEntry.getNumberOfComments(); + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/EntityLogDocumentNotFoundException.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/EntityLogDocumentNotFoundException.java new file mode 100644 index 000000000..fe33d0df9 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/EntityLogDocumentNotFoundException.java @@ -0,0 +1,10 @@ +package com.iqser.red.service.persistence.management.v1.processor.exception; + +public class EntityLogDocumentNotFoundException extends RuntimeException { + + public EntityLogDocumentNotFoundException(String errorMessage) { + + super(errorMessage); + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/migration/SaasMigrationService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/migration/SaasMigrationService.java index 3606f9a74..cfeb20f8a 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/migration/SaasMigrationService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/migration/SaasMigrationService.java @@ -200,6 +200,7 @@ public class SaasMigrationService implements TenantSyncService { } + //todo: 8702 private boolean entityLogMigrationFilesExist(String dossierId, String fileId) { return storageService.objectExists(TenantContext.getTenantId(), StorageIdUtils.getStorageId(dossierId, fileId, FileType.ENTITY_LOG)) && storageService.objectExists( diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/migration/migrations/ManualRedactionTypeRenameMigration15.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/migration/migrations/ManualRedactionTypeRenameMigration15.java index c42fdcfe3..8494b32e2 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/migration/migrations/ManualRedactionTypeRenameMigration15.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/migration/migrations/ManualRedactionTypeRenameMigration15.java @@ -69,7 +69,7 @@ public class ManualRedactionTypeRenameMigration15 extends Migration { continue; } - if (!fileManagementStorageService.objectExists(file.getDossierId(), file.getId(), FileType.ENTITY_LOG)) { + if (!fileManagementStorageService.entityLogExists(file.getDossierId(), file.getId())) { continue; } @@ -92,7 +92,7 @@ public class ManualRedactionTypeRenameMigration15 extends Migration { } } } - fileManagementStorageService.storeJSONObject(file.getDossierId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(file.getDossierId(), file.getId(), entityLog); } } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileManagementStorageService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileManagementStorageService.java index b199fb4ae..facc78513 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileManagementStorageService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileManagementStorageService.java @@ -12,6 +12,7 @@ import org.springframework.stereotype.Service; import com.iqser.red.service.persistence.management.v1.processor.exception.InternalServerErrorException; import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.EntityLogMongoService; import com.iqser.red.service.persistence.management.v1.processor.utils.StorageIdUtils; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLog; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLog; @@ -36,6 +37,8 @@ public class FileManagementStorageService { private final StorageService storageService; + private final EntityLogMongoService entityLogMongoService; + @SneakyThrows public byte[] getStoredObjectBytes(String dossierId, String fileId, FileType fileType) { @@ -99,14 +102,20 @@ public class FileManagementStorageService { public EntityLog getEntityLog(String dossierId, String fileId) { - try { - return storageService.readJSONObject(TenantContext.getTenantId(), StorageIdUtils.getStorageId(dossierId, fileId, FileType.ENTITY_LOG), EntityLog.class); - } catch (StorageObjectDoesNotExist e) { - log.debug("EntityLog does not exist"); - throw new NotFoundException(String.format("EntityLog does not exist for Dossier ID \"%s\" and File ID \"%s\"!", dossierId, fileId)); - } catch (StorageException e) { - throw new InternalServerErrorException(e.getMessage()); - } + return entityLogMongoService.findEntityLogByDossierIdAndFileId(dossierId, fileId) + .orElseThrow(() -> new NotFoundException(String.format("EntityLog does not exist for Dossier ID \"%s\" and File ID \"%s\"!", dossierId, fileId))); + + } + + @SneakyThrows + public void saveEntityLog(String dossierId, String fileId, EntityLog entityLog) { + + entityLogMongoService.saveEntityLog(dossierId, fileId, entityLog); + } + + public boolean entityLogExists(String dossierId, String fileId) { + + return entityLogMongoService.entityLogDocumentExists(dossierId, fileId); } @@ -161,6 +170,11 @@ public class FileManagementStorageService { storageService.deleteObject(TenantContext.getTenantId(), StorageIdUtils.getStorageId(dossierId, fileId, fileType)); } + public void deleteEntityLog(String dossierId, String fileId) { + + entityLogMongoService.deleteEntityLog(dossierId, fileId); + } + public void deleteObject(String storageId) { 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 22273f6a8..4ad2d6cf3 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 @@ -690,7 +690,7 @@ public class FileStatusService { fileManagementStorageService.deleteObject(dossierId, fileId, FileType.ORIGIN); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.REDACTION_LOG); - fileManagementStorageService.deleteObject(dossierId, fileId, FileType.ENTITY_LOG); + fileManagementStorageService.deleteEntityLog(dossierId, fileId); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.IMAGE_INFO); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.DOCUMENT_STRUCTURE); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.DOCUMENT_PAGES); @@ -719,7 +719,7 @@ public class FileStatusService { OffsetDateTime now = OffsetDateTime.now(); // remove everything related to redaction fileManagementStorageService.deleteObject(dossierId, fileId, FileType.REDACTION_LOG); - fileManagementStorageService.deleteObject(dossierId, fileId, FileType.ENTITY_LOG); + fileManagementStorageService.deleteEntityLog(dossierId, fileId); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.IMAGE_INFO); // wipe comments diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/EntityLogMongoService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/EntityLogMongoService.java new file mode 100644 index 000000000..f398ddf69 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/EntityLogMongoService.java @@ -0,0 +1,238 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.springframework.stereotype.Service; + +import com.iqser.red.service.persistence.management.v1.processor.document.EntityLogDocument; +import com.iqser.red.service.persistence.management.v1.processor.document.EntityLogEntryDocument; +import com.iqser.red.service.persistence.management.v1.processor.exception.EntityLogDocumentNotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.EntityLogDocumentRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.EntityLogEntryDocumentRepository; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLog; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry; + +@Service +public class EntityLogMongoService { + + private final EntityLogDocumentRepository entityLogDocumentRepository; + private final EntityLogEntryDocumentRepository entityLogEntryDocumentRepository; + + + public EntityLogMongoService(EntityLogDocumentRepository entityLogDocumentRepository, EntityLogEntryDocumentRepository entityLogEntryDocumentRepository) { + + this.entityLogDocumentRepository = entityLogDocumentRepository; + this.entityLogEntryDocumentRepository = entityLogEntryDocumentRepository; + } + + + public void insertEntityLog(String dossierId, String fileId, EntityLog entityLog) { + + EntityLogDocument entityLogDocument = entityLogDocumentRepository.insert(new EntityLogDocument(dossierId, fileId, entityLog)); + + entityLogEntryDocumentRepository.insert(entityLog.getEntityLogEntry() + .stream() + .map(entityLogEntry -> new EntityLogEntryDocument(entityLogDocument.getId(), entityLogEntry)) + .toList()); + } + + + // this does everything : insert when not found and update if found + // todo: remove and replace when services use insert,update,delete correctly + public void saveEntityLog(String dossierId, String fileId, EntityLog entityLog) { + + Optional optionalEntityLogDocument = entityLogDocumentRepository.findById(EntityLogDocument.getDocumentId(dossierId, fileId)); + if (optionalEntityLogDocument.isEmpty()) { + // throw new EntityLogDocumentNotFoundException(String.format("Entity log for dossier %s and file %s not found.", dossierId, fileId)); + insertEntityLog(dossierId, fileId, entityLog); + return; + } + + EntityLogDocument oldEntityLogDocument = optionalEntityLogDocument.get(); + List oldEntityLogEntryDocuments = oldEntityLogDocument.getEntityLogEntryDocument(); + + EntityLogDocument newEntityLogDocument = new EntityLogDocument(dossierId, fileId, entityLog); + List newEntityLogEntryDocuments = newEntityLogDocument.getEntityLogEntryDocument(); + + List toUpdate = new ArrayList<>(oldEntityLogEntryDocuments); + toUpdate.retainAll(newEntityLogEntryDocuments); + + List toRemove = new ArrayList<>(oldEntityLogEntryDocuments); + toRemove.removeAll(toUpdate); + + List toInsert = new ArrayList<>(newEntityLogEntryDocuments); + toInsert.removeAll(toUpdate); + + entityLogEntryDocumentRepository.saveAll(toUpdate); + entityLogEntryDocumentRepository.deleteAll(toRemove); + entityLogEntryDocumentRepository.insert(toInsert); + + entityLogDocumentRepository.save(newEntityLogDocument); + } + + + public void deleteEntityLog(String dossierId, String fileId) { + + String entityLogId = EntityLogDocument.getDocumentId(dossierId, fileId); + + entityLogDocumentRepository.deleteById(entityLogId); + + entityLogEntryDocumentRepository.deleteByEntityLogId(entityLogId); + } + + + public void insertEntityLogEntries(String dossierId, String fileId, List entityLogEntries) { + + String entityLogId = EntityLogDocument.getDocumentId(dossierId, fileId); + + EntityLogDocument entityLogDocument = getEntityLogDocument(entityLogId); + + List entityLogEntryDocuments = entityLogEntries.stream() + .map(entityLogEntry -> new EntityLogEntryDocument(entityLogId, entityLogEntry)) + .toList(); + + entityLogDocument.getEntityLogEntryDocument().addAll(entityLogEntryDocuments); + + entityLogEntryDocumentRepository.insert(entityLogEntryDocuments); + entityLogDocumentRepository.save(entityLogDocument); + } + + + public void updateEntityLogEntries(String dossierId, String fileId, List entityLogEntries) { + + String entityLogId = EntityLogDocument.getDocumentId(dossierId, fileId); + + entityLogEntryDocumentRepository.saveAll(entityLogEntries.stream() + .map(entityLogEntry -> new EntityLogEntryDocument(entityLogId, entityLogEntry)) + .toList()); + } + + public void deleteEntityLogEntries(String dossierId, String fileId, List entityLogEntries) { + + String entityLogId = EntityLogDocument.getDocumentId(dossierId, fileId); + + EntityLogDocument entityLogDocument = getEntityLogDocument(entityLogId); + + List entityLogEntryDocuments = entityLogEntries.stream() + .map(entityLogEntry -> new EntityLogEntryDocument(entityLogId, entityLogEntry)) + .toList(); + + entityLogDocument.getEntityLogEntryDocument().removeAll(entityLogEntryDocuments); + + entityLogEntryDocumentRepository.deleteAll(entityLogEntryDocuments); + entityLogDocumentRepository.save(entityLogDocument); + } + + + private EntityLogDocument getEntityLogDocument(String entityLogId) { + + Optional optionalEntityLogDocument = entityLogDocumentRepository.findById(entityLogId); + + if (optionalEntityLogDocument.isEmpty()) { + throw new EntityLogDocumentNotFoundException(String.format("Entity log not found for %s", entityLogId)); + } + + return optionalEntityLogDocument.get(); + } + + + public Optional findEntityLogByDossierIdAndFileId(String dossierId, String fileId) { + + return entityLogDocumentRepository.findById(EntityLogDocument.getDocumentId(dossierId, fileId)) + .map(EntityLogMongoService::fromDocument); + } + + + public boolean entityLogDocumentExists(String dossierId, String fileId) { + + return entityLogDocumentRepository.existsById(EntityLogDocument.getDocumentId(dossierId, fileId)); + } + + + public Optional findLatestAnalysisNumber(String dossierId, String fileId) { + + return entityLogDocumentRepository.findAnalysisNumberById(EntityLogDocument.getDocumentId(dossierId, fileId)) + .map(EntityLogDocument::getAnalysisNumber); + } + + + public List findAllEntityLogEntriesWithManualChanges(String dossierId, String fileId) { + + return entityLogEntryDocumentRepository.findByEntityLogIdAndManualChangesNotEmpty(EntityLogDocument.getDocumentId(dossierId, fileId)) + .stream() + .map(EntityLogMongoService::fromDocument) + .toList(); + } + + + public List findAllEntityLogEntriesByAnalysisNumber(String dossierId, String fileId, int analysisNumber) { + + return entityLogEntryDocumentRepository.findByEntityLogIdAndChangesAnalysisNumber(EntityLogDocument.getDocumentId(dossierId, fileId), analysisNumber) + .stream() + .map(EntityLogMongoService::fromDocument) + .toList(); + } + + + public List findAllEntriesByDossierIdAndFileId(String dossierId, String fileId) { + + return entityLogEntryDocumentRepository.findByEntityLogId(EntityLogDocument.getDocumentId(dossierId, fileId)) + .stream() + .map(EntityLogMongoService::fromDocument) + .toList(); + } + + + private static EntityLog fromDocument(EntityLogDocument entityLogDocument) { + + EntityLog entityLog = new EntityLog(); + entityLog.setAnalysisVersion(entityLogDocument.getAnalysisVersion()); + entityLog.setAnalysisNumber(entityLogDocument.getAnalysisNumber()); + entityLog.setEntityLogEntry(entityLogDocument.getEntityLogEntryDocument() + .stream() + .map(EntityLogMongoService::fromDocument) + .collect(Collectors.toList())); + entityLog.setLegalBasis(entityLogDocument.getLegalBasis()); + entityLog.setDictionaryVersion(entityLogDocument.getDictionaryVersion()); + entityLog.setDossierDictionaryVersion(entityLogDocument.getDossierDictionaryVersion()); + entityLog.setRulesVersion(entityLogDocument.getRulesVersion()); + entityLog.setLegalBasisVersion(entityLogDocument.getLegalBasisVersion()); + return entityLog; + } + + + private static EntityLogEntry fromDocument(EntityLogEntryDocument entityLogEntryDocument) { + + EntityLogEntry entityLogEntry = new EntityLogEntry(); + entityLogEntry.setId(entityLogEntryDocument.getEntryId()); + entityLogEntry.setState(entityLogEntryDocument.getState()); + entityLogEntry.setValue(entityLogEntryDocument.getValue()); + entityLogEntry.setReason(entityLogEntryDocument.getReason()); + entityLogEntry.setMatchedRule(entityLogEntryDocument.getMatchedRule()); + entityLogEntry.setLegalBasis(entityLogEntryDocument.getLegalBasis()); + entityLogEntry.setContainingNodeId(new ArrayList<>(entityLogEntryDocument.getContainingNodeId())); + entityLogEntry.setClosestHeadline(entityLogEntryDocument.getClosestHeadline()); + entityLogEntry.setSection(entityLogEntryDocument.getSection()); + entityLogEntry.setPositions(new ArrayList<>(entityLogEntryDocument.getPositions())); + entityLogEntry.setTextBefore(entityLogEntryDocument.getTextBefore()); + entityLogEntry.setTextAfter(entityLogEntryDocument.getTextAfter()); + entityLogEntry.setStartOffset(entityLogEntryDocument.getStartOffset()); + entityLogEntry.setEndOffset(entityLogEntryDocument.getEndOffset()); + entityLogEntry.setImageHasTransparency(entityLogEntryDocument.isImageHasTransparency()); + entityLogEntry.setDictionaryEntry(entityLogEntryDocument.isDictionaryEntry()); + entityLogEntry.setDossierDictionaryEntry(entityLogEntryDocument.isDossierDictionaryEntry()); + entityLogEntry.setExcluded(entityLogEntryDocument.isExcluded()); + entityLogEntry.setChanges(new ArrayList<>(entityLogEntryDocument.getChanges())); + entityLogEntry.setManualChanges(new ArrayList<>(entityLogEntryDocument.getManualChanges())); + entityLogEntry.setEngines(new HashSet<>(entityLogEntryDocument.getEngines())); + entityLogEntry.setReference(new HashSet<>(entityLogEntryDocument.getReference())); + entityLogEntry.setImportedRedactionIntersections(new HashSet<>(entityLogEntryDocument.getImportedRedactionIntersections())); + entityLogEntry.setNumberOfComments(entityLogEntryDocument.getNumberOfComments()); + return entityLogEntry; + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntityLogDocumentRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntityLogDocumentRepository.java new file mode 100644 index 000000000..81249cfcd --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntityLogDocumentRepository.java @@ -0,0 +1,15 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import java.util.Optional; + +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.mongodb.repository.Query; +import org.springframework.data.repository.query.Param; + +import com.iqser.red.service.persistence.management.v1.processor.document.EntityLogDocument; + +public interface EntityLogDocumentRepository extends MongoRepository { + + @Query(value = "{ '_id' : ?0 }", fields = "{ 'analysisNumber' : 1 }") + Optional findAnalysisNumberById(@Param("_id") String id); +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntityLogEntryDocumentRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntityLogEntryDocumentRepository.java new file mode 100644 index 000000000..8e1d82a06 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntityLogEntryDocumentRepository.java @@ -0,0 +1,23 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import java.util.List; + +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.mongodb.repository.Query; + +import com.iqser.red.service.persistence.management.v1.processor.document.EntityLogEntryDocument; + +public interface EntityLogEntryDocumentRepository extends MongoRepository { + + @Query("{ 'entityLogId' : ?0, 'manualChanges' : { $exists: true, $not: { $size: 0 } } }") + List findByEntityLogIdAndManualChangesNotEmpty(String entityLogId); + + @Query("{ 'entityLogId' : ?0, 'changes.analysisNumber' : ?1 }") + List findByEntityLogIdAndChangesAnalysisNumber(String entityLogId, int analysisNumber); + + @Query("{ 'entityLogId' : ?0}") + List findByEntityLogId(String entityLogId); + + @Query(value = "{ 'entityLogId' : ?0}", delete = true) + void deleteByEntityLogId(String entityLogId); +} 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 e856e1b16..d702fb1c6 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 @@ -64,9 +64,8 @@ public class FileTesterAndProvider { assertThat(fileClient.getDossierStatus(dossier.getId()).size()).isGreaterThanOrEqualTo(1); - fileManagementStorageService.storeJSONObject(dossier.getId(), + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getFileId(), - FileType.ENTITY_LOG, new EntityLog(1, 1, List.of(EntityLogEntry.builder() diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ManualRedactionTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ManualRedactionTest.java index 7b6107283..7672880cc 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ManualRedactionTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ManualRedactionTest.java @@ -139,7 +139,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyBoolean())).thenReturn(entityLog); @@ -333,7 +333,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog); @@ -393,7 +393,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog); @@ -448,7 +448,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog); @@ -543,7 +543,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier1.getId(), file1.getId(), FileType.ENTITY_LOG, entityLog1); + fileManagementStorageService.saveEntityLog(dossier1.getId(), file1.getId(), entityLog1); var redactionRequest1 = RedactionRequest.builder().dossierId(file1.getDossierId()).fileId(file1.getFileId()).dossierTemplateId(file1.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(eq(file1.getDossierId()), eq(file1.getFileId()), any(), anyBoolean())).thenReturn(entityLog1); @@ -562,7 +562,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier2.getId(), file2.getId(), FileType.ENTITY_LOG, entityLog2); + fileManagementStorageService.saveEntityLog(dossier2.getId(), file2.getId(), entityLog2); var redactionRequest2 = RedactionRequest.builder().dossierId(file2.getDossierId()).fileId(file2.getFileId()).dossierTemplateId(file2.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(eq(file2.getDossierId()), eq(file2.getFileId()), any(), anyBoolean())).thenReturn(entityLog2); @@ -708,7 +708,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier1.getId(), file1.getId(), FileType.ENTITY_LOG, entityLog1); + fileManagementStorageService.saveEntityLog(dossier1.getId(), file1.getId(), entityLog1); var redactionRequest1 = RedactionRequest.builder().dossierId(file1.getDossierId()).fileId(file1.getFileId()).dossierTemplateId(file1.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(eq(file1.getDossierId()), eq(file1.getFileId()), any(), anyBoolean())).thenReturn(entityLog1); @@ -727,7 +727,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier2.getId(), file2.getId(), FileType.ENTITY_LOG, entityLog2); + fileManagementStorageService.saveEntityLog(dossier2.getId(), file2.getId(), entityLog2); var redactionRequest2 = RedactionRequest.builder().dossierId(file2.getDossierId()).fileId(file2.getFileId()).dossierTemplateId(file2.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(eq(file2.getDossierId()), eq(file2.getFileId()), any(), anyBoolean())).thenReturn(entityLog2); @@ -877,7 +877,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier1.getId(), file1.getId(), FileType.ENTITY_LOG, entityLog1); + fileManagementStorageService.saveEntityLog(dossier1.getId(), file1.getId(), entityLog1); var redactionRequest1 = RedactionRequest.builder().dossierId(file1.getDossierId()).fileId(file1.getFileId()).dossierTemplateId(file1.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(file1.getDossierId(), file1.getFileId())).thenReturn(entityLog1); @@ -896,7 +896,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier2.getId(), file2.getId(), FileType.ENTITY_LOG, entityLog2); + fileManagementStorageService.saveEntityLog(dossier2.getId(), file2.getId(), entityLog2); var redactionRequest2 = RedactionRequest.builder().dossierId(file2.getDossierId()).fileId(file2.getFileId()).dossierTemplateId(file2.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(eq(file2.getDossierId()), eq(file2.getFileId()), any(), anyBoolean())).thenReturn(entityLog2); @@ -1043,7 +1043,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier1.getId(), file1.getId(), FileType.ENTITY_LOG, entityLog1); + fileManagementStorageService.saveEntityLog(dossier1.getId(), file1.getId(), entityLog1); var redactionRequest1 = RedactionRequest.builder().dossierId(file1.getDossierId()).fileId(file1.getFileId()).dossierTemplateId(file1.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(file1.getDossierId(), file1.getFileId())).thenReturn(entityLog1); @@ -1062,7 +1062,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier2.getId(), file2.getId(), FileType.ENTITY_LOG, entityLog2); + fileManagementStorageService.saveEntityLog(dossier2.getId(), file2.getId(), entityLog2); var redactionRequest2 = RedactionRequest.builder().dossierId(file2.getDossierId()).fileId(file2.getFileId()).dossierTemplateId(file2.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(eq(file2.getDossierId()), eq(file2.getFileId()), any(), anyBoolean())).thenReturn(entityLog2); @@ -1186,7 +1186,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog); @@ -1270,7 +1270,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog); @@ -1449,7 +1449,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog); @@ -1648,7 +1648,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog); @@ -1754,7 +1754,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any())).thenReturn(entityLog); @@ -1864,7 +1864,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any())).thenReturn(entityLog); @@ -1948,8 +1948,8 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog); var recatModel = RecategorizationRequestModel.builder() diff --git a/persistence-service-v1/persistence-service-shared-api-v1/build.gradle.kts b/persistence-service-v1/persistence-service-shared-api-v1/build.gradle.kts index 8e4c8efce..b2dfa2a93 100644 --- a/persistence-service-v1/persistence-service-shared-api-v1/build.gradle.kts +++ b/persistence-service-v1/persistence-service-shared-api-v1/build.gradle.kts @@ -11,7 +11,6 @@ dependencies { api("org.springframework.boot:spring-boot-starter-validation:3.1.3") api("com.iqser.red.commons:jackson-commons:2.1.0") api("com.iqser.red.commons:dictionary-merge-commons:1.3.0") - implementation("org.springframework.boot:spring-boot-starter-data-mongodb:${springBootStarterVersion}") testImplementation("com.iqser.red.commons:test-commons:2.1.0") testImplementation("org.springframework.boot:spring-boot-starter-test:3.0.4") compileOnly("org.springdoc:springdoc-openapi-ui:1.7.0") From 3060f5f28a2995a638fd2f57f8c1234009c616a1 Mon Sep 17 00:00:00 2001 From: maverickstuder Date: Tue, 19 Mar 2024 11:26:52 +0100 Subject: [PATCH 4/9] RED-8702: Explore document databases to store entityLog --- .../migration/SaasMigrationService.java | 3 +- .../service/FileManagementStorageService.java | 2 +- .../EntityLogMongoService.java | 2 +- .../EntityLogDocumentRepository.java | 17 +++++++++ .../EntityLogEntryDocumentRepository.java | 25 +++++++++++++ .../EntityLogDocumentRepository.java | 2 ++ .../build.gradle.kts | 1 + .../peristence/v1/server/Application.java | 9 +++-- .../src/main/resources/application.yaml | 9 +++++ .../AbstractPersistenceServerServiceTest.java | 36 +++++++++++++++++++ .../utils/MongoDBTestContainer.java | 35 ++++++++++++++++++ .../src/test/resources/application.yml | 10 +++++- 12 files changed, 145 insertions(+), 6 deletions(-) rename persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/{persistence => mongo}/EntityLogMongoService.java (99%) create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/repository/EntityLogDocumentRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/repository/EntityLogEntryDocumentRepository.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/MongoDBTestContainer.java diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/migration/SaasMigrationService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/migration/SaasMigrationService.java index cfeb20f8a..46444ec4b 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/migration/SaasMigrationService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/migration/SaasMigrationService.java @@ -45,6 +45,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import static com.iqser.red.service.persistence.management.v1.processor.configuration.MessagingConfiguration.MIGRATION_QUEUE; +import static com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType.ENTITY_LOG; import static com.knecon.fforesight.service.layoutparser.internal.api.queue.LayoutParsingQueueNames.LAYOUT_PARSING_REQUEST_QUEUE; @Slf4j @@ -203,7 +204,7 @@ public class SaasMigrationService implements TenantSyncService { //todo: 8702 private boolean entityLogMigrationFilesExist(String dossierId, String fileId) { - return storageService.objectExists(TenantContext.getTenantId(), StorageIdUtils.getStorageId(dossierId, fileId, FileType.ENTITY_LOG)) && storageService.objectExists( + return storageService.objectExists(TenantContext.getTenantId(), StorageIdUtils.getStorageId(dossierId, fileId, ENTITY_LOG)) && storageService.objectExists( TenantContext.getTenantId(), StorageIdUtils.getStorageId(dossierId, fileId, FileType.MIGRATED_IDS)); } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileManagementStorageService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileManagementStorageService.java index facc78513..8036fb11f 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileManagementStorageService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileManagementStorageService.java @@ -12,7 +12,7 @@ import org.springframework.stereotype.Service; import com.iqser.red.service.persistence.management.v1.processor.exception.InternalServerErrorException; import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; -import com.iqser.red.service.persistence.management.v1.processor.service.persistence.EntityLogMongoService; +import com.iqser.red.service.persistence.management.v1.processor.service.mongo.EntityLogMongoService; import com.iqser.red.service.persistence.management.v1.processor.utils.StorageIdUtils; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLog; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLog; diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/EntityLogMongoService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/EntityLogMongoService.java similarity index 99% rename from persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/EntityLogMongoService.java rename to persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/EntityLogMongoService.java index f398ddf69..b820787aa 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/EntityLogMongoService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/EntityLogMongoService.java @@ -1,4 +1,4 @@ -package com.iqser.red.service.persistence.management.v1.processor.service.persistence; +package com.iqser.red.service.persistence.management.v1.processor.service.mongo; import java.util.ArrayList; import java.util.HashSet; diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/repository/EntityLogDocumentRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/repository/EntityLogDocumentRepository.java new file mode 100644 index 000000000..d7aa23952 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/repository/EntityLogDocumentRepository.java @@ -0,0 +1,17 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.mongo.repository; + +import java.util.Optional; + +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.mongodb.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import com.iqser.red.service.persistence.management.v1.processor.document.EntityLogDocument; + +@Repository +public interface EntityLogDocumentRepository extends MongoRepository { + + @Query(value = "{ '_id' : ?0 }", fields = "{ 'analysisNumber' : 1 }") + Optional findAnalysisNumberById(@Param("_id") String id); +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/repository/EntityLogEntryDocumentRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/repository/EntityLogEntryDocumentRepository.java new file mode 100644 index 000000000..c8e4f2015 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/repository/EntityLogEntryDocumentRepository.java @@ -0,0 +1,25 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.mongo.repository; + +import java.util.List; + +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.mongodb.repository.Query; +import org.springframework.stereotype.Repository; + +import com.iqser.red.service.persistence.management.v1.processor.document.EntityLogEntryDocument; + +@Repository +public interface EntityLogEntryDocumentRepository extends MongoRepository { + + @Query("{ 'entityLogId' : ?0, 'manualChanges' : { $exists: true, $not: { $size: 0 } } }") + List findByEntityLogIdAndManualChangesNotEmpty(String entityLogId); + + @Query("{ 'entityLogId' : ?0, 'changes.analysisNumber' : ?1 }") + List findByEntityLogIdAndChangesAnalysisNumber(String entityLogId, int analysisNumber); + + @Query("{ 'entityLogId' : ?0}") + List findByEntityLogId(String entityLogId); + + @Query(value = "{ 'entityLogId' : ?0}", delete = true) + void deleteByEntityLogId(String entityLogId); +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntityLogDocumentRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntityLogDocumentRepository.java index 81249cfcd..e9916d08f 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntityLogDocumentRepository.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntityLogDocumentRepository.java @@ -5,9 +5,11 @@ import java.util.Optional; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.data.mongodb.repository.Query; import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; import com.iqser.red.service.persistence.management.v1.processor.document.EntityLogDocument; +@Repository public interface EntityLogDocumentRepository extends MongoRepository { @Query(value = "{ '_id' : ?0 }", fields = "{ 'analysisNumber' : 1 }") diff --git a/persistence-service-v1/persistence-service-server-v1/build.gradle.kts b/persistence-service-v1/persistence-service-server-v1/build.gradle.kts index 521247b80..56535f7ff 100644 --- a/persistence-service-v1/persistence-service-server-v1/build.gradle.kts +++ b/persistence-service-v1/persistence-service-server-v1/build.gradle.kts @@ -23,6 +23,7 @@ dependencies { api(project(":persistence-service-external-api-impl-v2")) api(project(":persistence-service-internal-api-impl-v1")) api("com.iqser.red.commons:storage-commons:2.45.0") + api("com.knecon.fforesight:mongo-database-commons:maverick-mongo") api("junit:junit:4.13.2") api("org.apache.logging.log4j:log4j-slf4j-impl:2.19.0") api("net.logstash.logback:logstash-logback-encoder:7.4") 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 50f039237..9a638d226 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 @@ -14,6 +14,7 @@ import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfigurati import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; +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.cache.annotation.EnableCaching; @@ -21,6 +22,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; import org.springframework.http.server.observation.DefaultServerRequestObservationConvention; import org.springframework.http.server.observation.ServerRequestObservationContext; import org.springframework.http.server.observation.ServerRequestObservationConvention; @@ -43,6 +45,8 @@ import com.iqser.red.storage.commons.StorageAutoConfiguration; import com.knecon.fforesight.databasetenantcommons.DatabaseTenantCommonsAutoConfiguration; import com.knecon.fforesight.jobscommons.JobsAutoConfiguration; import com.knecon.fforesight.keycloakcommons.DefaultKeyCloakCommonsAutoConfiguration; +import com.knecon.fforesight.mongo.database.commons.MongoDatabaseCommonsAutoConfiguration; +import com.knecon.fforesight.mongo.database.commons.service.MongoDataSources; import com.knecon.fforesight.swaggercommons.SpringDocAutoConfiguration; import com.knecon.fforesight.tenantcommons.MultiTenancyAutoConfiguration; import com.knecon.fforesight.tenantcommons.MultiTenancyMessagingConfiguration; @@ -62,9 +66,10 @@ import lombok.extern.slf4j.Slf4j; @EnableScheduling @EnableCaching @EnableConfigurationProperties({FileManagementServiceSettings.class}) -@ImportAutoConfiguration({StorageAutoConfiguration.class, JobsAutoConfiguration.class, DatabaseTenantCommonsAutoConfiguration.class, MultiTenancyAutoConfiguration.class, SpringDocAutoConfiguration.class, DefaultKeyCloakCommonsAutoConfiguration.class}) +@ImportAutoConfiguration({StorageAutoConfiguration.class, JobsAutoConfiguration.class, DatabaseTenantCommonsAutoConfiguration.class, MultiTenancyAutoConfiguration.class, SpringDocAutoConfiguration.class, DefaultKeyCloakCommonsAutoConfiguration.class, MongoDatabaseCommonsAutoConfiguration.class}) @SpringBootApplication(exclude = {SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class, CassandraAutoConfiguration.class, DataSourceAutoConfiguration.class, LiquibaseAutoConfiguration.class}) -@Import({PersistenceServiceExternalApiConfigurationV2.class, PersistenceServiceExternalApiConfiguration.class, PersistenceServiceInternalApiConfiguration.class, PersistenceServiceExternalApiCacheConfiguration.class, MultiTenancyWebConfiguration.class, PersistenceServiceProcessorConfiguration.class, MessagingConfiguration.class, MultiTenancyMessagingConfiguration.class}) +@Import({PersistenceServiceExternalApiConfigurationV2.class, PersistenceServiceExternalApiConfiguration.class, PersistenceServiceInternalApiConfiguration.class, PersistenceServiceExternalApiCacheConfiguration.class, MultiTenancyWebConfiguration.class, PersistenceServiceProcessorConfiguration.class, MessagingConfiguration.class, MultiTenancyMessagingConfiguration.class, MongoDataSources.class}) +@EnableMongoRepositories(basePackages = "com.iqser.red.service.persistence.management.v1.processor.service.mongo.repository") public class Application implements 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 0af757fe1..6960236c6 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 @@ -37,6 +37,15 @@ spring: batch_size: 1000 order_inserts: true order_updates: true + data: + mongodb: + auto-index-creation: true + # todo: multi-tenancy + database: redaction + host: ${MONGODB_HOST:localhost} + port: 27017 + username: ${MONGODB_USER} + password: ${MONGODB_PASSWORD} cache: type: redis mvc: 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 76eb9a805..e36ae8be7 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 @@ -14,6 +14,7 @@ import com.iqser.red.service.persistence.management.v1.processor.roles.Applicati import com.iqser.red.service.persistence.management.v1.processor.service.ApplicationConfigService; import com.iqser.red.service.persistence.management.v1.processor.service.EntityLogService; import com.iqser.red.service.persistence.management.v1.processor.service.FileManagementStorageService; +import com.iqser.red.service.persistence.management.v1.processor.service.mongo.EntityLogMongoService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.*; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.*; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry.EntryRepository; @@ -28,6 +29,8 @@ 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.mongo.database.commons.config.MongoDbConfiguration; +import com.knecon.fforesight.mongo.database.commons.service.MongoDataSources; import com.knecon.fforesight.tenantcommons.EncryptionDecryptionService; import com.knecon.fforesight.tenantcommons.TenantContext; import com.knecon.fforesight.tenantcommons.TenantsClient; @@ -46,7 +49,9 @@ import org.springframework.amqp.core.AmqpAdmin; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.util.TestPropertyValues; @@ -54,6 +59,8 @@ import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.*; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.StatementCallback; import org.springframework.jdbc.datasource.SingleConnectionDataSource; @@ -100,6 +107,12 @@ public abstract class AbstractPersistenceServerServiceTest { @Autowired protected StorageService storageService; @Autowired + protected EntityLogDocumentRepository entityLogDocumentRepository; + @Autowired + protected EntityLogEntryDocumentRepository entityLogEntryDocumentRepository; + @Autowired + protected EntityLogMongoService entityLogMongoService; + @Autowired protected FileManagementStorageService fileManagementStorageService; @Autowired protected DossierTemplateRepository dossierTemplateRepository; @@ -268,6 +281,7 @@ public abstract class AbstractPersistenceServerServiceTest { private void createDefaultTenant() { var postgreSQLContainerMaster = SpringPostgreSQLTestContainer.getInstance().withDatabaseName("integration-tests-db-master").withUsername("sa").withPassword("sa"); + var mongoDbContainer = MongoDBTestContainer.getInstance(); var port = postgreSQLContainerMaster.getJdbcUrl().substring(0, postgreSQLContainerMaster.getJdbcUrl().lastIndexOf('/')).split(":")[3]; @@ -296,6 +310,7 @@ public abstract class AbstractPersistenceServerServiceTest { .numberOfShards("1") .numberOfReplicas("5") .build()); + redactionTenant.setS3StorageConnection(S3StorageConnection.builder() .key("key") .secret("secret") @@ -304,6 +319,15 @@ public abstract class AbstractPersistenceServerServiceTest { .region("eu") .endpoint("endpoint") .build()); + + redactionTenant.setMongoDBConnection(MongoDBConnection.builder() + .host(mongoDbContainer.getHost()) + .port(String.valueOf(mongoDbContainer.getFirstMappedPort())) + .username(MongoDBTestContainer.MONGO_USERNAME) + .password(MongoDBTestContainer.MONGO_PASSWORD) + .database(MongoDBTestContainer.MONGO_DATABASE) + .build()); + when(tenantsClient.getTenant("redaction")).thenReturn(redactionTenant); when(tenantsClient.getTenants()).thenReturn(List.of(redactionTenant)); @@ -385,6 +409,9 @@ public abstract class AbstractPersistenceServerServiceTest { indexInformationRepository.deleteAll(); applicationConfigRepository.deleteAll(); + entityLogEntryDocumentRepository.deleteAll(); + entityLogDocumentRepository.deleteAll(); + }); } @@ -401,10 +428,17 @@ public abstract class AbstractPersistenceServerServiceTest { var redisContainer = RedisTestContainer.getInstance(); redisContainer.start(); + var mongoInstance = MongoDBTestContainer.getInstance(); + mongoInstance.start(); + log.info("Hosts are - Redis: {}, Postgres: {}", redisContainer.getHost(), postgreSQLContainerMaster.getHost()); TestPropertyValues.of("REDIS_PORT=" + redisContainer.getFirstMappedPort(), "REDIS_HOST=" + redisContainer.getHost(), + "MONGODB_HOST=" + mongoInstance.getHost(), + "MONGODB_PORT=" + mongoInstance.getFirstMappedPort(), + "MONGODB_USER=" + MongoDBTestContainer.MONGO_USERNAME, + "MONGODB_PASSWORD=" + MongoDBTestContainer.MONGO_PASSWORD, "fforesight.jobs.enabled=false", "fforesight.keycloak.enabled=false").applyTo(configurableApplicationContext.getEnvironment()); @@ -416,7 +450,9 @@ public abstract class AbstractPersistenceServerServiceTest { @EnableWebSecurity @EnableMethodSecurity @EnableAutoConfiguration(exclude = {RabbitAutoConfiguration.class}) + @Import({MongoDataSources.class, MongoDbConfiguration.class}) @ComponentScan("com.iqser.red.service.persistence") + @EnableMongoRepositories("com.iqser.red.service.persistence.management.v1.processor.service.mongo.repository") public static class TestConfiguration { @Bean diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/MongoDBTestContainer.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/MongoDBTestContainer.java new file mode 100644 index 000000000..61abcab1a --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/MongoDBTestContainer.java @@ -0,0 +1,35 @@ +package com.iqser.red.service.peristence.v1.server.integration.utils; + +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; + +public final class MongoDBTestContainer extends GenericContainer { + + private static final String IMAGE_VERSION = "mongo:7.0.2"; + public static final Integer MONGO_PORT = 27017; + public static final String MONGO_DATABASE = "mongo_database"; + public static final String MONGO_PASSWORD = "mongo_password"; + public static final String MONGO_USERNAME = "mongo_username"; + private static MongoDBTestContainer mongoDB; + + + private MongoDBTestContainer() { + + super(DockerImageName.parse(IMAGE_VERSION)); + + } + + + public static MongoDBTestContainer getInstance() { + + if (mongoDB == null) { + mongoDB = new MongoDBTestContainer().withEnv("MONGO_INITDB_ROOT_USERNAME", MONGO_USERNAME) + .withEnv("MONGO_INITDB_ROOT_PASSWORD", MONGO_PASSWORD) + .withEnv("MONGO_INITDB_DATABASE", MONGO_DATABASE) + .withExposedPorts(MONGO_PORT); + + } + return mongoDB; + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml b/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml index 968397e81..7f5c1f6a7 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml +++ b/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml @@ -19,7 +19,15 @@ spring: order_inserts: true order_updates: true open-in-view: true - + data: + mongodb: + auto-index-creation: true + # todo: multi-tenancy + database: redaction + host: ${MONGODB_HOST:localhost} + port: 27017 + username: ${MONGODB_USER} + password: ${MONGODB_PASSWORD} rabbitmq: host: ${RABBITMQ_HOST:localhost} port: ${RABBITMQ_PORT:5672} From 0edb28f164cadb8757ff89ec6e3d5a8390dfd618 Mon Sep 17 00:00:00 2001 From: maverickstuder Date: Tue, 19 Mar 2024 13:25:19 +0100 Subject: [PATCH 5/9] RED-8702: Explore document databases to store entityLog * first fix for failing tests --- .../service/mongo/EntityLogMongoService.java | 4 ++-- .../EntityLogDocumentRepository.java | 17 -------------- .../EntityLogEntryDocumentRepository.java | 23 ------------------- .../build.gradle.kts | 3 +++ .../peristence/v1/server/Application.java | 10 ++++---- .../AbstractPersistenceServerServiceTest.java | 16 ++++++------- 6 files changed, 18 insertions(+), 55 deletions(-) delete mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntityLogDocumentRepository.java delete mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntityLogEntryDocumentRepository.java diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/EntityLogMongoService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/EntityLogMongoService.java index b820787aa..87ebd379d 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/EntityLogMongoService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/EntityLogMongoService.java @@ -11,8 +11,8 @@ import org.springframework.stereotype.Service; import com.iqser.red.service.persistence.management.v1.processor.document.EntityLogDocument; import com.iqser.red.service.persistence.management.v1.processor.document.EntityLogEntryDocument; import com.iqser.red.service.persistence.management.v1.processor.exception.EntityLogDocumentNotFoundException; -import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.EntityLogDocumentRepository; -import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.EntityLogEntryDocumentRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.mongo.repository.EntityLogDocumentRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.mongo.repository.EntityLogEntryDocumentRepository; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLog; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry; diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntityLogDocumentRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntityLogDocumentRepository.java deleted file mode 100644 index e9916d08f..000000000 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntityLogDocumentRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; - -import java.util.Optional; - -import org.springframework.data.mongodb.repository.MongoRepository; -import org.springframework.data.mongodb.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -import com.iqser.red.service.persistence.management.v1.processor.document.EntityLogDocument; - -@Repository -public interface EntityLogDocumentRepository extends MongoRepository { - - @Query(value = "{ '_id' : ?0 }", fields = "{ 'analysisNumber' : 1 }") - Optional findAnalysisNumberById(@Param("_id") String id); -} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntityLogEntryDocumentRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntityLogEntryDocumentRepository.java deleted file mode 100644 index 8e1d82a06..000000000 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntityLogEntryDocumentRepository.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; - -import java.util.List; - -import org.springframework.data.mongodb.repository.MongoRepository; -import org.springframework.data.mongodb.repository.Query; - -import com.iqser.red.service.persistence.management.v1.processor.document.EntityLogEntryDocument; - -public interface EntityLogEntryDocumentRepository extends MongoRepository { - - @Query("{ 'entityLogId' : ?0, 'manualChanges' : { $exists: true, $not: { $size: 0 } } }") - List findByEntityLogIdAndManualChangesNotEmpty(String entityLogId); - - @Query("{ 'entityLogId' : ?0, 'changes.analysisNumber' : ?1 }") - List findByEntityLogIdAndChangesAnalysisNumber(String entityLogId, int analysisNumber); - - @Query("{ 'entityLogId' : ?0}") - List findByEntityLogId(String entityLogId); - - @Query(value = "{ 'entityLogId' : ?0}", delete = true) - void deleteByEntityLogId(String entityLogId); -} diff --git a/persistence-service-v1/persistence-service-server-v1/build.gradle.kts b/persistence-service-v1/persistence-service-server-v1/build.gradle.kts index 56535f7ff..8d867fef9 100644 --- a/persistence-service-v1/persistence-service-server-v1/build.gradle.kts +++ b/persistence-service-v1/persistence-service-server-v1/build.gradle.kts @@ -17,7 +17,10 @@ configurations { } } +val springBootStarterVersion = "3.1.5" + dependencies { + api("org.springframework.boot:spring-boot-starter-data-mongodb:${springBootStarterVersion}") api(project(":persistence-service-processor-v1")) api(project(":persistence-service-external-api-impl-v1")) api(project(":persistence-service-external-api-impl-v2")) 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 9a638d226..f50606f28 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 @@ -14,7 +14,6 @@ import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfigurati import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; -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.cache.annotation.EnableCaching; @@ -39,6 +38,8 @@ import com.iqser.red.service.dictionarymerge.commons.DictionaryMergeService; import com.iqser.red.service.persistence.management.v1.processor.PersistenceServiceProcessorConfiguration; import com.iqser.red.service.persistence.management.v1.processor.cache.PersistenceServiceExternalApiCacheConfiguration; import com.iqser.red.service.persistence.management.v1.processor.configuration.MessagingConfiguration; +import com.iqser.red.service.persistence.management.v1.processor.service.mongo.repository.EntityLogDocumentRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.mongo.repository.EntityLogEntryDocumentRepository; import com.iqser.red.service.persistence.management.v1.processor.settings.FileManagementServiceSettings; import com.iqser.red.service.persistence.v1.internal.api.PersistenceServiceInternalApiConfiguration; import com.iqser.red.storage.commons.StorageAutoConfiguration; @@ -46,7 +47,6 @@ import com.knecon.fforesight.databasetenantcommons.DatabaseTenantCommonsAutoConf import com.knecon.fforesight.jobscommons.JobsAutoConfiguration; import com.knecon.fforesight.keycloakcommons.DefaultKeyCloakCommonsAutoConfiguration; import com.knecon.fforesight.mongo.database.commons.MongoDatabaseCommonsAutoConfiguration; -import com.knecon.fforesight.mongo.database.commons.service.MongoDataSources; import com.knecon.fforesight.swaggercommons.SpringDocAutoConfiguration; import com.knecon.fforesight.tenantcommons.MultiTenancyAutoConfiguration; import com.knecon.fforesight.tenantcommons.MultiTenancyMessagingConfiguration; @@ -66,10 +66,10 @@ import lombok.extern.slf4j.Slf4j; @EnableScheduling @EnableCaching @EnableConfigurationProperties({FileManagementServiceSettings.class}) -@ImportAutoConfiguration({StorageAutoConfiguration.class, JobsAutoConfiguration.class, DatabaseTenantCommonsAutoConfiguration.class, MultiTenancyAutoConfiguration.class, SpringDocAutoConfiguration.class, DefaultKeyCloakCommonsAutoConfiguration.class, MongoDatabaseCommonsAutoConfiguration.class}) +@EnableMongoRepositories(basePackages = "com.iqser.red.service.persistence") +@ImportAutoConfiguration({StorageAutoConfiguration.class, JobsAutoConfiguration.class, DatabaseTenantCommonsAutoConfiguration.class, MultiTenancyAutoConfiguration.class, SpringDocAutoConfiguration.class, DefaultKeyCloakCommonsAutoConfiguration.class}) @SpringBootApplication(exclude = {SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class, CassandraAutoConfiguration.class, DataSourceAutoConfiguration.class, LiquibaseAutoConfiguration.class}) -@Import({PersistenceServiceExternalApiConfigurationV2.class, PersistenceServiceExternalApiConfiguration.class, PersistenceServiceInternalApiConfiguration.class, PersistenceServiceExternalApiCacheConfiguration.class, MultiTenancyWebConfiguration.class, PersistenceServiceProcessorConfiguration.class, MessagingConfiguration.class, MultiTenancyMessagingConfiguration.class, MongoDataSources.class}) -@EnableMongoRepositories(basePackages = "com.iqser.red.service.persistence.management.v1.processor.service.mongo.repository") +@Import({PersistenceServiceExternalApiConfigurationV2.class, PersistenceServiceExternalApiConfiguration.class, PersistenceServiceInternalApiConfiguration.class, PersistenceServiceExternalApiCacheConfiguration.class, MultiTenancyWebConfiguration.class, PersistenceServiceProcessorConfiguration.class, MessagingConfiguration.class, MultiTenancyMessagingConfiguration.class}) public class Application implements ApplicationContextAware { /** 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 e36ae8be7..90e1ec9f7 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 @@ -25,11 +25,15 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.ApplicationConfig; import com.iqser.red.service.redaction.v1.model.DroolsValidation; import com.iqser.red.storage.commons.service.StorageService; +import com.iqser.red.storage.commons.service.StorageServiceImpl; 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.mongo.database.commons.config.MongoDbConfiguration; +import com.knecon.fforesight.mongo.database.commons.config.MultiTenantMongoDBFactory; +import com.knecon.fforesight.mongo.database.commons.service.MongoClientCache; +import com.knecon.fforesight.mongo.database.commons.service.MongoConnectionProviderImpl; import com.knecon.fforesight.mongo.database.commons.service.MongoDataSources; import com.knecon.fforesight.tenantcommons.EncryptionDecryptionService; import com.knecon.fforesight.tenantcommons.TenantContext; @@ -51,6 +55,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; +import org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration; +import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; @@ -107,10 +113,6 @@ public abstract class AbstractPersistenceServerServiceTest { @Autowired protected StorageService storageService; @Autowired - protected EntityLogDocumentRepository entityLogDocumentRepository; - @Autowired - protected EntityLogEntryDocumentRepository entityLogEntryDocumentRepository; - @Autowired protected EntityLogMongoService entityLogMongoService; @Autowired protected FileManagementStorageService fileManagementStorageService; @@ -409,8 +411,8 @@ public abstract class AbstractPersistenceServerServiceTest { indexInformationRepository.deleteAll(); applicationConfigRepository.deleteAll(); - entityLogEntryDocumentRepository.deleteAll(); - entityLogDocumentRepository.deleteAll(); + //entityLogEntryDocumentRepository.deleteAll(); + //entityLogDocumentRepository.deleteAll(); }); } @@ -450,9 +452,7 @@ public abstract class AbstractPersistenceServerServiceTest { @EnableWebSecurity @EnableMethodSecurity @EnableAutoConfiguration(exclude = {RabbitAutoConfiguration.class}) - @Import({MongoDataSources.class, MongoDbConfiguration.class}) @ComponentScan("com.iqser.red.service.persistence") - @EnableMongoRepositories("com.iqser.red.service.persistence.management.v1.processor.service.mongo.repository") public static class TestConfiguration { @Bean From e9c26e37dfa5a5c4b14df3f18102b23b93e1c324 Mon Sep 17 00:00:00 2001 From: maverickstuder Date: Tue, 19 Mar 2024 14:52:34 +0100 Subject: [PATCH 6/9] RED-8702: Explore document databases to store entityLog * fix for AbstractPersistenceServerServiceTest to include mongodb container --- .../build.gradle.kts | 3 - .../peristence/v1/server/Application.java | 4 +- .../AbstractPersistenceServerServiceTest.java | 187 ++++++++++++------ .../utils/MongoDBTestContainer.java | 6 +- 4 files changed, 131 insertions(+), 69 deletions(-) diff --git a/persistence-service-v1/persistence-service-server-v1/build.gradle.kts b/persistence-service-v1/persistence-service-server-v1/build.gradle.kts index 8d867fef9..56535f7ff 100644 --- a/persistence-service-v1/persistence-service-server-v1/build.gradle.kts +++ b/persistence-service-v1/persistence-service-server-v1/build.gradle.kts @@ -17,10 +17,7 @@ configurations { } } -val springBootStarterVersion = "3.1.5" - dependencies { - api("org.springframework.boot:spring-boot-starter-data-mongodb:${springBootStarterVersion}") api(project(":persistence-service-processor-v1")) api(project(":persistence-service-external-api-impl-v1")) api(project(":persistence-service-external-api-impl-v2")) 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 f50606f28..a90522e03 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 @@ -38,8 +38,6 @@ import com.iqser.red.service.dictionarymerge.commons.DictionaryMergeService; import com.iqser.red.service.persistence.management.v1.processor.PersistenceServiceProcessorConfiguration; import com.iqser.red.service.persistence.management.v1.processor.cache.PersistenceServiceExternalApiCacheConfiguration; import com.iqser.red.service.persistence.management.v1.processor.configuration.MessagingConfiguration; -import com.iqser.red.service.persistence.management.v1.processor.service.mongo.repository.EntityLogDocumentRepository; -import com.iqser.red.service.persistence.management.v1.processor.service.mongo.repository.EntityLogEntryDocumentRepository; import com.iqser.red.service.persistence.management.v1.processor.settings.FileManagementServiceSettings; import com.iqser.red.service.persistence.v1.internal.api.PersistenceServiceInternalApiConfiguration; import com.iqser.red.storage.commons.StorageAutoConfiguration; @@ -67,7 +65,7 @@ import lombok.extern.slf4j.Slf4j; @EnableCaching @EnableConfigurationProperties({FileManagementServiceSettings.class}) @EnableMongoRepositories(basePackages = "com.iqser.red.service.persistence") -@ImportAutoConfiguration({StorageAutoConfiguration.class, JobsAutoConfiguration.class, DatabaseTenantCommonsAutoConfiguration.class, MultiTenancyAutoConfiguration.class, SpringDocAutoConfiguration.class, DefaultKeyCloakCommonsAutoConfiguration.class}) +@ImportAutoConfiguration({StorageAutoConfiguration.class, JobsAutoConfiguration.class, DatabaseTenantCommonsAutoConfiguration.class, MultiTenancyAutoConfiguration.class, SpringDocAutoConfiguration.class, DefaultKeyCloakCommonsAutoConfiguration.class, MongoDatabaseCommonsAutoConfiguration.class}) @SpringBootApplication(exclude = {SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class, CassandraAutoConfiguration.class, DataSourceAutoConfiguration.class, LiquibaseAutoConfiguration.class}) @Import({PersistenceServiceExternalApiConfigurationV2.class, PersistenceServiceExternalApiConfiguration.class, PersistenceServiceInternalApiConfiguration.class, PersistenceServiceExternalApiCacheConfiguration.class, MultiTenancyWebConfiguration.class, PersistenceServiceProcessorConfiguration.class, MessagingConfiguration.class, MultiTenancyMessagingConfiguration.class}) public class Application implements ApplicationContextAware { 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 90e1ec9f7..a9413bd12 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 @@ -1,5 +1,53 @@ package com.iqser.red.service.peristence.v1.server.integration.utils; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import org.assertj.core.util.Lists; +import org.bson.BsonArray; +import org.bson.BsonDocument; +import org.bson.BsonString; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.quartz.Scheduler; +import org.springframework.amqp.core.AmqpAdmin; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.Primary; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.StatementCallback; +import org.springframework.jdbc.datasource.SingleConnectionDataSource; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + import com.iqser.red.commons.jackson.ObjectMapperFactory; import com.iqser.red.service.peristence.v1.server.Application; import com.iqser.red.service.peristence.v1.server.integration.client.ApplicationConfigClient; @@ -15,8 +63,35 @@ import com.iqser.red.service.persistence.management.v1.processor.service.Applica import com.iqser.red.service.persistence.management.v1.processor.service.EntityLogService; import com.iqser.red.service.persistence.management.v1.processor.service.FileManagementStorageService; import com.iqser.red.service.persistence.management.v1.processor.service.mongo.EntityLogMongoService; -import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.*; -import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.*; +import com.iqser.red.service.persistence.management.v1.processor.service.mongo.repository.EntityLogDocumentRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.mongo.repository.EntityLogEntryDocumentRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.ApplicationConfigRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.AuditRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DigitalSignatureRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierAttributeConfigRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierAttributeRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierStatusRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierTemplateRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DownloadStatusRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.FileAttributeConfigRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.FileAttributesGeneralConfigurationRepository; +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.management.v1.processor.service.persistence.repository.IndexInformationRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.LegalBasisMappingRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.NotificationPreferencesRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.NotificationRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.ReportTemplateRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.RuleSetRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.TypeRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.ViewedPagesRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.WatermarkRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.ForceRedactionRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.LegalBasisChangeRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.ManualRedactionRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.RecategorizationRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.RemoveRedactionRepository; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry.EntryRepository; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry.FalsePositiveEntryRepository; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry.FalseRecommendationEntryRepository; @@ -25,71 +100,27 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.ApplicationConfig; import com.iqser.red.service.redaction.v1.model.DroolsValidation; import com.iqser.red.storage.commons.service.StorageService; -import com.iqser.red.storage.commons.service.StorageServiceImpl; 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.mongo.database.commons.config.MongoDbConfiguration; -import com.knecon.fforesight.mongo.database.commons.config.MultiTenantMongoDBFactory; -import com.knecon.fforesight.mongo.database.commons.service.MongoClientCache; -import com.knecon.fforesight.mongo.database.commons.service.MongoConnectionProviderImpl; -import com.knecon.fforesight.mongo.database.commons.service.MongoDataSources; import com.knecon.fforesight.tenantcommons.EncryptionDecryptionService; import com.knecon.fforesight.tenantcommons.TenantContext; import com.knecon.fforesight.tenantcommons.TenantsClient; -import com.knecon.fforesight.tenantcommons.model.*; +import com.knecon.fforesight.tenantcommons.model.AuthDetails; +import com.knecon.fforesight.tenantcommons.model.DatabaseConnection; +import com.knecon.fforesight.tenantcommons.model.MongoDBConnection; +import com.knecon.fforesight.tenantcommons.model.S3StorageConnection; +import com.knecon.fforesight.tenantcommons.model.SearchConnection; +import com.knecon.fforesight.tenantcommons.model.TenantResponse; +import com.mongodb.MongoCommandException; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; +import com.mongodb.client.MongoDatabase; import io.micrometer.prometheus.PrometheusMeterRegistry; import lombok.extern.slf4j.Slf4j; -import org.assertj.core.util.Lists; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mockito; -import org.quartz.Scheduler; -import org.springframework.amqp.core.AmqpAdmin; -import org.springframework.amqp.rabbit.core.RabbitTemplate; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; -import org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration; -import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; -import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.cloud.openfeign.EnableFeignClients; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.*; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.StatementCallback; -import org.springframework.jdbc.datasource.SingleConnectionDataSource; -import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; -import org.springframework.security.web.SecurityFilterChain; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import static org.mockito.Mockito.when; - @Slf4j @ExtendWith(SpringExtension.class) @EnableFeignClients(basePackageClasses = FileClient.class) @@ -115,6 +146,10 @@ public abstract class AbstractPersistenceServerServiceTest { @Autowired protected EntityLogMongoService entityLogMongoService; @Autowired + protected EntityLogDocumentRepository entityLogDocumentRepository; + @Autowired + protected EntityLogEntryDocumentRepository entityLogEntryDocumentRepository; + @Autowired protected FileManagementStorageService fileManagementStorageService; @Autowired protected DossierTemplateRepository dossierTemplateRepository; @@ -326,7 +361,7 @@ public abstract class AbstractPersistenceServerServiceTest { .host(mongoDbContainer.getHost()) .port(String.valueOf(mongoDbContainer.getFirstMappedPort())) .username(MongoDBTestContainer.MONGO_USERNAME) - .password(MongoDBTestContainer.MONGO_PASSWORD) + .password(encryptionDecryptionService.encrypt(MongoDBTestContainer.MONGO_PASSWORD)) .database(MongoDBTestContainer.MONGO_DATABASE) .build()); @@ -358,6 +393,8 @@ public abstract class AbstractPersistenceServerServiceTest { } + + @AfterEach public void cleanupStorage() { @@ -411,8 +448,8 @@ public abstract class AbstractPersistenceServerServiceTest { indexInformationRepository.deleteAll(); applicationConfigRepository.deleteAll(); - //entityLogEntryDocumentRepository.deleteAll(); - //entityLogDocumentRepository.deleteAll(); + entityLogEntryDocumentRepository.deleteAll(); + entityLogDocumentRepository.deleteAll(); }); } @@ -432,6 +469,7 @@ public abstract class AbstractPersistenceServerServiceTest { var mongoInstance = MongoDBTestContainer.getInstance(); mongoInstance.start(); + createMongoDBDatabase(mongoInstance); log.info("Hosts are - Redis: {}, Postgres: {}", redisContainer.getHost(), postgreSQLContainerMaster.getHost()); @@ -448,11 +486,40 @@ public abstract class AbstractPersistenceServerServiceTest { } + + private static void createMongoDBDatabase(MongoDBTestContainer mongoDBTestContainer) { + + try (MongoClient mongoClient = MongoClients.create(String.format("mongodb://%s:%s@%s:%s/", + MongoDBTestContainer.MONGO_USERNAME, + MongoDBTestContainer.MONGO_PASSWORD, + mongoDBTestContainer.getHost(), + mongoDBTestContainer.getFirstMappedPort()))) { + MongoDatabase database = mongoClient.getDatabase(MongoDBTestContainer.MONGO_DATABASE); + BsonDocument createUserCommand = new BsonDocument(); + createUserCommand.append("createUser", new BsonString(MongoDBTestContainer.MONGO_USERNAME)); + createUserCommand.append("pwd", new BsonString(MongoDBTestContainer.MONGO_PASSWORD)); + BsonArray roles = new BsonArray(); + roles.add(new BsonString("readWrite")); + createUserCommand.append("roles", roles); + + try { + database.runCommand(createUserCommand); + } catch (MongoCommandException mongoCommandException) { + // ignore user already exists + if(mongoCommandException.getErrorCode() != 51003) { + throw mongoCommandException; + } + + } + + } + } + @Configuration @EnableWebSecurity @EnableMethodSecurity @EnableAutoConfiguration(exclude = {RabbitAutoConfiguration.class}) - @ComponentScan("com.iqser.red.service.persistence") + @ComponentScan(basePackages = {"com.iqser.red.service.persistence" }) public static class TestConfiguration { @Bean diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/MongoDBTestContainer.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/MongoDBTestContainer.java index 61abcab1a..6db3c46ec 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/MongoDBTestContainer.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/MongoDBTestContainer.java @@ -7,9 +7,9 @@ public final class MongoDBTestContainer extends GenericContainer Date: Tue, 19 Mar 2024 15:30:32 +0100 Subject: [PATCH 7/9] RED-8702: Explore document databases to store entityLog * refactoring --- .../processor/document/EntityLogDocument.java | 9 ++---- .../document/EntityLogEntryDocument.java | 30 ++++--------------- 2 files changed, 7 insertions(+), 32 deletions(-) diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogDocument.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogDocument.java index 2e3d06b46..48ebf6651 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogDocument.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogDocument.java @@ -9,6 +9,7 @@ import org.springframework.data.mongodb.core.mapping.Document; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLog; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogLegalBasis; +import com.knecon.fforesight.databasetenantcommons.providers.utils.MagicConverter; import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; @@ -50,19 +51,13 @@ public class EntityLogDocument { public EntityLogDocument(String dossierId, String fileId, EntityLog entityLog) { + MagicConverter.copyAllFields(entityLog, this); this.id = getDocumentId(dossierId, fileId); this.dossierId = dossierId; this.fileId = fileId; - this.analysisVersion = entityLog.getAnalysisVersion(); - this.analysisNumber = entityLog.getAnalysisNumber(); this.entityLogEntryDocument = new ArrayList<>(entityLog.getEntityLogEntry() .stream() .map(entityLogEntry -> new EntityLogEntryDocument(this.id, entityLogEntry)).toList()); - this.legalBasis = entityLog.getLegalBasis(); - this.dictionaryVersion = entityLog.getDictionaryVersion(); - this.dossierDictionaryVersion = entityLog.getDossierDictionaryVersion(); - this.rulesVersion = entityLog.getRulesVersion(); - this.legalBasisVersion = entityLog.getLegalBasisVersion(); } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogEntryDocument.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogEntryDocument.java index 87963463a..aa20ebd04 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogEntryDocument.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogEntryDocument.java @@ -8,6 +8,7 @@ import java.util.Set; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; +import com.fasterxml.jackson.databind.ObjectMapper; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Change; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Engine; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry; @@ -15,6 +16,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryType; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.ManualChange; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Position; +import com.knecon.fforesight.databasetenantcommons.providers.utils.MagicConverter; import lombok.AccessLevel; import lombok.AllArgsConstructor; @@ -81,34 +83,12 @@ public class EntityLogEntryDocument { public EntityLogEntryDocument(String entityLogId, EntityLogEntry entityLogEntry) { + MagicConverter.copyAllFields(entityLogEntry, this); this.id = entityLogId + "/" + entityLogEntry.getId(); this.entryId = entityLogEntry.getId(); this.entityLogId = entityLogId; - this.type = entityLogEntry.getType(); - this.entryType = entityLogEntry.getEntryType(); - this.state = entityLogEntry.getState(); - this.value = entityLogEntry.getValue(); - this.reason = entityLogEntry.getReason(); - this.matchedRule = entityLogEntry.getMatchedRule(); - this.legalBasis = entityLogEntry.getLegalBasis(); - this.containingNodeId = new ArrayList<>(entityLogEntry.getContainingNodeId()); - this.closestHeadline = entityLogEntry.getClosestHeadline(); - this.section = entityLogEntry.getSection(); - this.positions = new ArrayList<>(entityLogEntry.getPositions()); - this.textBefore = entityLogEntry.getTextBefore(); - this.textAfter = entityLogEntry.getTextAfter(); - this.startOffset = entityLogEntry.getStartOffset(); - this.endOffset = entityLogEntry.getEndOffset(); - this.imageHasTransparency = entityLogEntry.isImageHasTransparency(); - this.dictionaryEntry = entityLogEntry.isDictionaryEntry(); - this.dossierDictionaryEntry = entityLogEntry.isDossierDictionaryEntry(); - this.excluded = entityLogEntry.isExcluded(); - this.changes = new ArrayList<>(entityLogEntry.getChanges()); - this.manualChanges = new ArrayList<>(entityLogEntry.getManualChanges()); - this.engines = new HashSet<>(entityLogEntry.getEngines()); - this.reference = new HashSet<>(entityLogEntry.getReference()); - this.importedRedactionIntersections = new HashSet<>(entityLogEntry.getImportedRedactionIntersections()); - this.numberOfComments = entityLogEntry.getNumberOfComments(); + + } } From aed3da331ba4e985c2a010dc6898b33cb89bebd6 Mon Sep 17 00:00:00 2001 From: maverickstuder Date: Tue, 19 Mar 2024 16:36:59 +0100 Subject: [PATCH 8/9] RED-8702: Explore document databases to store entityLog * refactoring --- .../integration/utils/AbstractPersistenceServerServiceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 a9413bd12..6a2c43035 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 @@ -471,7 +471,7 @@ public abstract class AbstractPersistenceServerServiceTest { mongoInstance.start(); createMongoDBDatabase(mongoInstance); - log.info("Hosts are - Redis: {}, Postgres: {}", redisContainer.getHost(), postgreSQLContainerMaster.getHost()); + log.info("Hosts are - Redis: {}, Postgres: {}, MongoDB: {}", redisContainer.getHost(), postgreSQLContainerMaster.getHost(), mongoInstance.getHost()); TestPropertyValues.of("REDIS_PORT=" + redisContainer.getFirstMappedPort(), "REDIS_HOST=" + redisContainer.getHost(), From 49932a9074688e3356759991febb76a34ea199b9 Mon Sep 17 00:00:00 2001 From: maverickstuder Date: Wed, 13 Mar 2024 15:26:35 +0100 Subject: [PATCH 9/9] RED-8702: Explore document databases to store entityLog * refactoring RED-8702: Explore document databases to store entityLog * refactoring RED-8702: Explore document databases to store entityLog * fix for AbstractPersistenceServerServiceTest to include mongodb container RED-8702: Explore document databases to store entityLog * first fix for failing tests RED-8702: Explore document databases to store entityLog RED-8702: Explore document databases to store entityLog * added mongodb documents, repositories and EntityLogMongoService * refactored places where entity logs were stored and loaded to use new logic RED-8702 RED-8702 --- .../internal/AdminInterfaceController.java | 4 +- .../build.gradle.kts | 5 +- .../processor/document/EntityLogDocument.java | 70 ++++++ .../document/EntityLogEntryDocument.java | 94 +++++++ .../EntityLogDocumentNotFoundException.java | 10 + .../migration/SaasMigrationService.java | 4 +- .../ManualRedactionTypeRenameMigration15.java | 4 +- .../service/FileManagementStorageService.java | 30 ++- .../processor/service/FileStatusService.java | 4 +- .../service/mongo/EntityLogMongoService.java | 238 ++++++++++++++++++ .../EntityLogDocumentRepository.java | 17 ++ .../EntityLogEntryDocumentRepository.java | 25 ++ .../build.gradle.kts | 1 + .../peristence/v1/server/Application.java | 5 +- .../src/main/resources/application.yaml | 9 + .../service/FileTesterAndProvider.java | 3 +- .../tests/ManualRedactionTest.java | 40 +-- .../AbstractPersistenceServerServiceTest.java | 189 ++++++++++---- .../utils/MongoDBTestContainer.java | 35 +++ .../src/test/resources/application.yml | 10 +- .../build.gradle.kts | 2 + 21 files changed, 715 insertions(+), 84 deletions(-) create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogDocument.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogEntryDocument.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/EntityLogDocumentNotFoundException.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/EntityLogMongoService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/repository/EntityLogDocumentRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/repository/EntityLogEntryDocumentRepository.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/MongoDBTestContainer.java diff --git a/persistence-service-v1/persistence-service-internal-api-impl-v1/src/main/java/com/iqser/red/service/persistence/v1/internal/api/controller/internal/AdminInterfaceController.java b/persistence-service-v1/persistence-service-internal-api-impl-v1/src/main/java/com/iqser/red/service/persistence/v1/internal/api/controller/internal/AdminInterfaceController.java index 0cdb2ca51..0f58f9dad 100644 --- a/persistence-service-v1/persistence-service-internal-api-impl-v1/src/main/java/com/iqser/red/service/persistence/v1/internal/api/controller/internal/AdminInterfaceController.java +++ b/persistence-service-v1/persistence-service-internal-api-impl-v1/src/main/java/com/iqser/red/service/persistence/v1/internal/api/controller/internal/AdminInterfaceController.java @@ -36,7 +36,7 @@ public class AdminInterfaceController { public void resetFile(@RequestParam("dossierId") String dossierId, @RequestParam("fileId") String fileId) { fileManagementStorageService.deleteObject(dossierId, fileId, FileType.REDACTION_LOG); - fileManagementStorageService.deleteObject(dossierId, fileId, FileType.ENTITY_LOG); + fileManagementStorageService.deleteEntityLog(dossierId, fileId); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.DOCUMENT_PAGES); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.DOCUMENT_TEXT); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.DOCUMENT_POSITION); @@ -141,7 +141,7 @@ public class AdminInterfaceController { var fileId = file.getId(); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.REDACTION_LOG); - fileManagementStorageService.deleteObject(dossierId, fileId, FileType.ENTITY_LOG); + fileManagementStorageService.deleteEntityLog(dossierId, fileId); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.DOCUMENT_STRUCTURE); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.DOCUMENT_TEXT); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.DOCUMENT_PAGES); 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 1fb9d4bcf..0e277da9a 100644 --- a/persistence-service-v1/persistence-service-processor-v1/build.gradle.kts +++ b/persistence-service-v1/persistence-service-processor-v1/build.gradle.kts @@ -34,8 +34,8 @@ dependencies { exclude(group = "com.iqser.red.service", module = "persistence-service-shared-api-v1") } api("com.knecon.fforesight:jobs-commons:0.10.0") - api("com.knecon.fforesight:database-tenant-commons:0.21.0") - api("com.knecon.fforesight:keycloak-commons:0.25.0") + api("com.knecon.fforesight:database-tenant-commons:maverick-mongo") + api("com.knecon.fforesight:keycloak-commons:maverick-mongo") api("com.knecon.fforesight:tracing-commons:0.5.0") api("com.knecon.fforesight:swagger-commons:0.5.0") api("com.giffing.bucket4j.spring.boot.starter:bucket4j-spring-boot-starter:0.4.0") @@ -43,6 +43,7 @@ dependencies { api("org.springframework.boot:spring-boot-starter-mail:${springBootStarterVersion}") api("org.springframework.boot:spring-boot-starter-data-jpa:${springBootStarterVersion}") api("org.springframework.boot:spring-boot-starter-data-redis:${springBootStarterVersion}") + api("org.springframework.boot:spring-boot-starter-data-mongodb:${springBootStarterVersion}") api("org.springframework.boot:spring-boot-starter-amqp:${springBootStarterVersion}") api("org.springframework.boot:spring-boot-starter-web:${springBootStarterVersion}") api("com.iqser.red.commons:spring-commons:2.1.0") diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogDocument.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogDocument.java new file mode 100644 index 000000000..48ebf6651 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogDocument.java @@ -0,0 +1,70 @@ +package com.iqser.red.service.persistence.management.v1.processor.document; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.DBRef; +import org.springframework.data.mongodb.core.mapping.Document; + +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLog; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogLegalBasis; +import com.knecon.fforesight.databasetenantcommons.providers.utils.MagicConverter; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +@EqualsAndHashCode(onlyExplicitlyIncluded = true) +@Document(collection = "entity-logs") +public class EntityLogDocument { + + @Id + @EqualsAndHashCode.Include + private String id; + + private String dossierId; + private String fileId; + + private long analysisVersion; + + //@Indexed(direction = IndexDirection.DESCENDING) + private int analysisNumber; + + @DBRef + private List entityLogEntryDocument = new ArrayList<>(); + + private List legalBasis = new ArrayList<>(); + + private long dictionaryVersion = -1; + private long dossierDictionaryVersion = -1; + + private long rulesVersion = -1; + private long legalBasisVersion = -1; + + + public EntityLogDocument(String dossierId, String fileId, EntityLog entityLog) { + + MagicConverter.copyAllFields(entityLog, this); + this.id = getDocumentId(dossierId, fileId); + this.dossierId = dossierId; + this.fileId = fileId; + this.entityLogEntryDocument = new ArrayList<>(entityLog.getEntityLogEntry() + .stream() + .map(entityLogEntry -> new EntityLogEntryDocument(this.id, entityLogEntry)).toList()); + + } + + + public static String getDocumentId(String dossierId, String fileId) { + + return dossierId + "/" + fileId; + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogEntryDocument.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogEntryDocument.java new file mode 100644 index 000000000..aa20ebd04 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/document/EntityLogEntryDocument.java @@ -0,0 +1,94 @@ +package com.iqser.red.service.persistence.management.v1.processor.document; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Change; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Engine; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryState; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryType; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.ManualChange; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Position; +import com.knecon.fforesight.databasetenantcommons.providers.utils.MagicConverter; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.FieldDefaults; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(onlyExplicitlyIncluded = true) +@FieldDefaults(level = AccessLevel.PRIVATE) +@Document(collection = "entity-log-entries") +//@CompoundIndexes({ + //@CompoundIndex(name = "changes_analysisNumber", def = "{ 'changes.analysisNumber': 1 }") +// }) +public class EntityLogEntryDocument { + + @Id + @EqualsAndHashCode.Include + String id; + String entryId; + String entityLogId; + String type; + EntryType entryType; + EntryState state; + String value; + String reason; + String matchedRule; + String legalBasis; + + List containingNodeId; + String closestHeadline; + String section; + + List positions = new ArrayList<>(); + + String textBefore; + String textAfter; + + int startOffset; + int endOffset; + + boolean imageHasTransparency; + + boolean dictionaryEntry; + boolean dossierDictionaryEntry; + + boolean excluded; + + List changes = new ArrayList<>(); + + List manualChanges = new ArrayList<>(); + + Set engines = new HashSet<>(); + + Set reference = new HashSet<>(); + + Set importedRedactionIntersections = new HashSet<>(); + + int numberOfComments; + + + public EntityLogEntryDocument(String entityLogId, EntityLogEntry entityLogEntry) { + + MagicConverter.copyAllFields(entityLogEntry, this); + this.id = entityLogId + "/" + entityLogEntry.getId(); + this.entryId = entityLogEntry.getId(); + this.entityLogId = entityLogId; + + + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/EntityLogDocumentNotFoundException.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/EntityLogDocumentNotFoundException.java new file mode 100644 index 000000000..fe33d0df9 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/EntityLogDocumentNotFoundException.java @@ -0,0 +1,10 @@ +package com.iqser.red.service.persistence.management.v1.processor.exception; + +public class EntityLogDocumentNotFoundException extends RuntimeException { + + public EntityLogDocumentNotFoundException(String errorMessage) { + + super(errorMessage); + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/migration/SaasMigrationService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/migration/SaasMigrationService.java index 3606f9a74..46444ec4b 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/migration/SaasMigrationService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/migration/SaasMigrationService.java @@ -45,6 +45,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import static com.iqser.red.service.persistence.management.v1.processor.configuration.MessagingConfiguration.MIGRATION_QUEUE; +import static com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType.ENTITY_LOG; import static com.knecon.fforesight.service.layoutparser.internal.api.queue.LayoutParsingQueueNames.LAYOUT_PARSING_REQUEST_QUEUE; @Slf4j @@ -200,9 +201,10 @@ public class SaasMigrationService implements TenantSyncService { } + //todo: 8702 private boolean entityLogMigrationFilesExist(String dossierId, String fileId) { - return storageService.objectExists(TenantContext.getTenantId(), StorageIdUtils.getStorageId(dossierId, fileId, FileType.ENTITY_LOG)) && storageService.objectExists( + return storageService.objectExists(TenantContext.getTenantId(), StorageIdUtils.getStorageId(dossierId, fileId, ENTITY_LOG)) && storageService.objectExists( TenantContext.getTenantId(), StorageIdUtils.getStorageId(dossierId, fileId, FileType.MIGRATED_IDS)); } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/migration/migrations/ManualRedactionTypeRenameMigration15.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/migration/migrations/ManualRedactionTypeRenameMigration15.java index c42fdcfe3..8494b32e2 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/migration/migrations/ManualRedactionTypeRenameMigration15.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/migration/migrations/ManualRedactionTypeRenameMigration15.java @@ -69,7 +69,7 @@ public class ManualRedactionTypeRenameMigration15 extends Migration { continue; } - if (!fileManagementStorageService.objectExists(file.getDossierId(), file.getId(), FileType.ENTITY_LOG)) { + if (!fileManagementStorageService.entityLogExists(file.getDossierId(), file.getId())) { continue; } @@ -92,7 +92,7 @@ public class ManualRedactionTypeRenameMigration15 extends Migration { } } } - fileManagementStorageService.storeJSONObject(file.getDossierId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(file.getDossierId(), file.getId(), entityLog); } } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileManagementStorageService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileManagementStorageService.java index b199fb4ae..8036fb11f 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileManagementStorageService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileManagementStorageService.java @@ -12,6 +12,7 @@ import org.springframework.stereotype.Service; import com.iqser.red.service.persistence.management.v1.processor.exception.InternalServerErrorException; import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.mongo.EntityLogMongoService; import com.iqser.red.service.persistence.management.v1.processor.utils.StorageIdUtils; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.componentlog.ComponentLog; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLog; @@ -36,6 +37,8 @@ public class FileManagementStorageService { private final StorageService storageService; + private final EntityLogMongoService entityLogMongoService; + @SneakyThrows public byte[] getStoredObjectBytes(String dossierId, String fileId, FileType fileType) { @@ -99,14 +102,20 @@ public class FileManagementStorageService { public EntityLog getEntityLog(String dossierId, String fileId) { - try { - return storageService.readJSONObject(TenantContext.getTenantId(), StorageIdUtils.getStorageId(dossierId, fileId, FileType.ENTITY_LOG), EntityLog.class); - } catch (StorageObjectDoesNotExist e) { - log.debug("EntityLog does not exist"); - throw new NotFoundException(String.format("EntityLog does not exist for Dossier ID \"%s\" and File ID \"%s\"!", dossierId, fileId)); - } catch (StorageException e) { - throw new InternalServerErrorException(e.getMessage()); - } + return entityLogMongoService.findEntityLogByDossierIdAndFileId(dossierId, fileId) + .orElseThrow(() -> new NotFoundException(String.format("EntityLog does not exist for Dossier ID \"%s\" and File ID \"%s\"!", dossierId, fileId))); + + } + + @SneakyThrows + public void saveEntityLog(String dossierId, String fileId, EntityLog entityLog) { + + entityLogMongoService.saveEntityLog(dossierId, fileId, entityLog); + } + + public boolean entityLogExists(String dossierId, String fileId) { + + return entityLogMongoService.entityLogDocumentExists(dossierId, fileId); } @@ -161,6 +170,11 @@ public class FileManagementStorageService { storageService.deleteObject(TenantContext.getTenantId(), StorageIdUtils.getStorageId(dossierId, fileId, fileType)); } + public void deleteEntityLog(String dossierId, String fileId) { + + entityLogMongoService.deleteEntityLog(dossierId, fileId); + } + public void deleteObject(String storageId) { 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 22273f6a8..4ad2d6cf3 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 @@ -690,7 +690,7 @@ public class FileStatusService { fileManagementStorageService.deleteObject(dossierId, fileId, FileType.ORIGIN); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.REDACTION_LOG); - fileManagementStorageService.deleteObject(dossierId, fileId, FileType.ENTITY_LOG); + fileManagementStorageService.deleteEntityLog(dossierId, fileId); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.IMAGE_INFO); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.DOCUMENT_STRUCTURE); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.DOCUMENT_PAGES); @@ -719,7 +719,7 @@ public class FileStatusService { OffsetDateTime now = OffsetDateTime.now(); // remove everything related to redaction fileManagementStorageService.deleteObject(dossierId, fileId, FileType.REDACTION_LOG); - fileManagementStorageService.deleteObject(dossierId, fileId, FileType.ENTITY_LOG); + fileManagementStorageService.deleteEntityLog(dossierId, fileId); fileManagementStorageService.deleteObject(dossierId, fileId, FileType.IMAGE_INFO); // wipe comments diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/EntityLogMongoService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/EntityLogMongoService.java new file mode 100644 index 000000000..87ebd379d --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/EntityLogMongoService.java @@ -0,0 +1,238 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.mongo; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.springframework.stereotype.Service; + +import com.iqser.red.service.persistence.management.v1.processor.document.EntityLogDocument; +import com.iqser.red.service.persistence.management.v1.processor.document.EntityLogEntryDocument; +import com.iqser.red.service.persistence.management.v1.processor.exception.EntityLogDocumentNotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.mongo.repository.EntityLogDocumentRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.mongo.repository.EntityLogEntryDocumentRepository; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLog; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry; + +@Service +public class EntityLogMongoService { + + private final EntityLogDocumentRepository entityLogDocumentRepository; + private final EntityLogEntryDocumentRepository entityLogEntryDocumentRepository; + + + public EntityLogMongoService(EntityLogDocumentRepository entityLogDocumentRepository, EntityLogEntryDocumentRepository entityLogEntryDocumentRepository) { + + this.entityLogDocumentRepository = entityLogDocumentRepository; + this.entityLogEntryDocumentRepository = entityLogEntryDocumentRepository; + } + + + public void insertEntityLog(String dossierId, String fileId, EntityLog entityLog) { + + EntityLogDocument entityLogDocument = entityLogDocumentRepository.insert(new EntityLogDocument(dossierId, fileId, entityLog)); + + entityLogEntryDocumentRepository.insert(entityLog.getEntityLogEntry() + .stream() + .map(entityLogEntry -> new EntityLogEntryDocument(entityLogDocument.getId(), entityLogEntry)) + .toList()); + } + + + // this does everything : insert when not found and update if found + // todo: remove and replace when services use insert,update,delete correctly + public void saveEntityLog(String dossierId, String fileId, EntityLog entityLog) { + + Optional optionalEntityLogDocument = entityLogDocumentRepository.findById(EntityLogDocument.getDocumentId(dossierId, fileId)); + if (optionalEntityLogDocument.isEmpty()) { + // throw new EntityLogDocumentNotFoundException(String.format("Entity log for dossier %s and file %s not found.", dossierId, fileId)); + insertEntityLog(dossierId, fileId, entityLog); + return; + } + + EntityLogDocument oldEntityLogDocument = optionalEntityLogDocument.get(); + List oldEntityLogEntryDocuments = oldEntityLogDocument.getEntityLogEntryDocument(); + + EntityLogDocument newEntityLogDocument = new EntityLogDocument(dossierId, fileId, entityLog); + List newEntityLogEntryDocuments = newEntityLogDocument.getEntityLogEntryDocument(); + + List toUpdate = new ArrayList<>(oldEntityLogEntryDocuments); + toUpdate.retainAll(newEntityLogEntryDocuments); + + List toRemove = new ArrayList<>(oldEntityLogEntryDocuments); + toRemove.removeAll(toUpdate); + + List toInsert = new ArrayList<>(newEntityLogEntryDocuments); + toInsert.removeAll(toUpdate); + + entityLogEntryDocumentRepository.saveAll(toUpdate); + entityLogEntryDocumentRepository.deleteAll(toRemove); + entityLogEntryDocumentRepository.insert(toInsert); + + entityLogDocumentRepository.save(newEntityLogDocument); + } + + + public void deleteEntityLog(String dossierId, String fileId) { + + String entityLogId = EntityLogDocument.getDocumentId(dossierId, fileId); + + entityLogDocumentRepository.deleteById(entityLogId); + + entityLogEntryDocumentRepository.deleteByEntityLogId(entityLogId); + } + + + public void insertEntityLogEntries(String dossierId, String fileId, List entityLogEntries) { + + String entityLogId = EntityLogDocument.getDocumentId(dossierId, fileId); + + EntityLogDocument entityLogDocument = getEntityLogDocument(entityLogId); + + List entityLogEntryDocuments = entityLogEntries.stream() + .map(entityLogEntry -> new EntityLogEntryDocument(entityLogId, entityLogEntry)) + .toList(); + + entityLogDocument.getEntityLogEntryDocument().addAll(entityLogEntryDocuments); + + entityLogEntryDocumentRepository.insert(entityLogEntryDocuments); + entityLogDocumentRepository.save(entityLogDocument); + } + + + public void updateEntityLogEntries(String dossierId, String fileId, List entityLogEntries) { + + String entityLogId = EntityLogDocument.getDocumentId(dossierId, fileId); + + entityLogEntryDocumentRepository.saveAll(entityLogEntries.stream() + .map(entityLogEntry -> new EntityLogEntryDocument(entityLogId, entityLogEntry)) + .toList()); + } + + public void deleteEntityLogEntries(String dossierId, String fileId, List entityLogEntries) { + + String entityLogId = EntityLogDocument.getDocumentId(dossierId, fileId); + + EntityLogDocument entityLogDocument = getEntityLogDocument(entityLogId); + + List entityLogEntryDocuments = entityLogEntries.stream() + .map(entityLogEntry -> new EntityLogEntryDocument(entityLogId, entityLogEntry)) + .toList(); + + entityLogDocument.getEntityLogEntryDocument().removeAll(entityLogEntryDocuments); + + entityLogEntryDocumentRepository.deleteAll(entityLogEntryDocuments); + entityLogDocumentRepository.save(entityLogDocument); + } + + + private EntityLogDocument getEntityLogDocument(String entityLogId) { + + Optional optionalEntityLogDocument = entityLogDocumentRepository.findById(entityLogId); + + if (optionalEntityLogDocument.isEmpty()) { + throw new EntityLogDocumentNotFoundException(String.format("Entity log not found for %s", entityLogId)); + } + + return optionalEntityLogDocument.get(); + } + + + public Optional findEntityLogByDossierIdAndFileId(String dossierId, String fileId) { + + return entityLogDocumentRepository.findById(EntityLogDocument.getDocumentId(dossierId, fileId)) + .map(EntityLogMongoService::fromDocument); + } + + + public boolean entityLogDocumentExists(String dossierId, String fileId) { + + return entityLogDocumentRepository.existsById(EntityLogDocument.getDocumentId(dossierId, fileId)); + } + + + public Optional findLatestAnalysisNumber(String dossierId, String fileId) { + + return entityLogDocumentRepository.findAnalysisNumberById(EntityLogDocument.getDocumentId(dossierId, fileId)) + .map(EntityLogDocument::getAnalysisNumber); + } + + + public List findAllEntityLogEntriesWithManualChanges(String dossierId, String fileId) { + + return entityLogEntryDocumentRepository.findByEntityLogIdAndManualChangesNotEmpty(EntityLogDocument.getDocumentId(dossierId, fileId)) + .stream() + .map(EntityLogMongoService::fromDocument) + .toList(); + } + + + public List findAllEntityLogEntriesByAnalysisNumber(String dossierId, String fileId, int analysisNumber) { + + return entityLogEntryDocumentRepository.findByEntityLogIdAndChangesAnalysisNumber(EntityLogDocument.getDocumentId(dossierId, fileId), analysisNumber) + .stream() + .map(EntityLogMongoService::fromDocument) + .toList(); + } + + + public List findAllEntriesByDossierIdAndFileId(String dossierId, String fileId) { + + return entityLogEntryDocumentRepository.findByEntityLogId(EntityLogDocument.getDocumentId(dossierId, fileId)) + .stream() + .map(EntityLogMongoService::fromDocument) + .toList(); + } + + + private static EntityLog fromDocument(EntityLogDocument entityLogDocument) { + + EntityLog entityLog = new EntityLog(); + entityLog.setAnalysisVersion(entityLogDocument.getAnalysisVersion()); + entityLog.setAnalysisNumber(entityLogDocument.getAnalysisNumber()); + entityLog.setEntityLogEntry(entityLogDocument.getEntityLogEntryDocument() + .stream() + .map(EntityLogMongoService::fromDocument) + .collect(Collectors.toList())); + entityLog.setLegalBasis(entityLogDocument.getLegalBasis()); + entityLog.setDictionaryVersion(entityLogDocument.getDictionaryVersion()); + entityLog.setDossierDictionaryVersion(entityLogDocument.getDossierDictionaryVersion()); + entityLog.setRulesVersion(entityLogDocument.getRulesVersion()); + entityLog.setLegalBasisVersion(entityLogDocument.getLegalBasisVersion()); + return entityLog; + } + + + private static EntityLogEntry fromDocument(EntityLogEntryDocument entityLogEntryDocument) { + + EntityLogEntry entityLogEntry = new EntityLogEntry(); + entityLogEntry.setId(entityLogEntryDocument.getEntryId()); + entityLogEntry.setState(entityLogEntryDocument.getState()); + entityLogEntry.setValue(entityLogEntryDocument.getValue()); + entityLogEntry.setReason(entityLogEntryDocument.getReason()); + entityLogEntry.setMatchedRule(entityLogEntryDocument.getMatchedRule()); + entityLogEntry.setLegalBasis(entityLogEntryDocument.getLegalBasis()); + entityLogEntry.setContainingNodeId(new ArrayList<>(entityLogEntryDocument.getContainingNodeId())); + entityLogEntry.setClosestHeadline(entityLogEntryDocument.getClosestHeadline()); + entityLogEntry.setSection(entityLogEntryDocument.getSection()); + entityLogEntry.setPositions(new ArrayList<>(entityLogEntryDocument.getPositions())); + entityLogEntry.setTextBefore(entityLogEntryDocument.getTextBefore()); + entityLogEntry.setTextAfter(entityLogEntryDocument.getTextAfter()); + entityLogEntry.setStartOffset(entityLogEntryDocument.getStartOffset()); + entityLogEntry.setEndOffset(entityLogEntryDocument.getEndOffset()); + entityLogEntry.setImageHasTransparency(entityLogEntryDocument.isImageHasTransparency()); + entityLogEntry.setDictionaryEntry(entityLogEntryDocument.isDictionaryEntry()); + entityLogEntry.setDossierDictionaryEntry(entityLogEntryDocument.isDossierDictionaryEntry()); + entityLogEntry.setExcluded(entityLogEntryDocument.isExcluded()); + entityLogEntry.setChanges(new ArrayList<>(entityLogEntryDocument.getChanges())); + entityLogEntry.setManualChanges(new ArrayList<>(entityLogEntryDocument.getManualChanges())); + entityLogEntry.setEngines(new HashSet<>(entityLogEntryDocument.getEngines())); + entityLogEntry.setReference(new HashSet<>(entityLogEntryDocument.getReference())); + entityLogEntry.setImportedRedactionIntersections(new HashSet<>(entityLogEntryDocument.getImportedRedactionIntersections())); + entityLogEntry.setNumberOfComments(entityLogEntryDocument.getNumberOfComments()); + return entityLogEntry; + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/repository/EntityLogDocumentRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/repository/EntityLogDocumentRepository.java new file mode 100644 index 000000000..d7aa23952 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/repository/EntityLogDocumentRepository.java @@ -0,0 +1,17 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.mongo.repository; + +import java.util.Optional; + +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.mongodb.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import com.iqser.red.service.persistence.management.v1.processor.document.EntityLogDocument; + +@Repository +public interface EntityLogDocumentRepository extends MongoRepository { + + @Query(value = "{ '_id' : ?0 }", fields = "{ 'analysisNumber' : 1 }") + Optional findAnalysisNumberById(@Param("_id") String id); +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/repository/EntityLogEntryDocumentRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/repository/EntityLogEntryDocumentRepository.java new file mode 100644 index 000000000..c8e4f2015 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/mongo/repository/EntityLogEntryDocumentRepository.java @@ -0,0 +1,25 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.mongo.repository; + +import java.util.List; + +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.mongodb.repository.Query; +import org.springframework.stereotype.Repository; + +import com.iqser.red.service.persistence.management.v1.processor.document.EntityLogEntryDocument; + +@Repository +public interface EntityLogEntryDocumentRepository extends MongoRepository { + + @Query("{ 'entityLogId' : ?0, 'manualChanges' : { $exists: true, $not: { $size: 0 } } }") + List findByEntityLogIdAndManualChangesNotEmpty(String entityLogId); + + @Query("{ 'entityLogId' : ?0, 'changes.analysisNumber' : ?1 }") + List findByEntityLogIdAndChangesAnalysisNumber(String entityLogId, int analysisNumber); + + @Query("{ 'entityLogId' : ?0}") + List findByEntityLogId(String entityLogId); + + @Query(value = "{ 'entityLogId' : ?0}", delete = true) + void deleteByEntityLogId(String entityLogId); +} diff --git a/persistence-service-v1/persistence-service-server-v1/build.gradle.kts b/persistence-service-v1/persistence-service-server-v1/build.gradle.kts index 521247b80..56535f7ff 100644 --- a/persistence-service-v1/persistence-service-server-v1/build.gradle.kts +++ b/persistence-service-v1/persistence-service-server-v1/build.gradle.kts @@ -23,6 +23,7 @@ dependencies { api(project(":persistence-service-external-api-impl-v2")) api(project(":persistence-service-internal-api-impl-v1")) api("com.iqser.red.commons:storage-commons:2.45.0") + api("com.knecon.fforesight:mongo-database-commons:maverick-mongo") api("junit:junit:4.13.2") api("org.apache.logging.log4j:log4j-slf4j-impl:2.19.0") api("net.logstash.logback:logstash-logback-encoder:7.4") 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 50f039237..a90522e03 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 @@ -21,6 +21,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; import org.springframework.http.server.observation.DefaultServerRequestObservationConvention; import org.springframework.http.server.observation.ServerRequestObservationContext; import org.springframework.http.server.observation.ServerRequestObservationConvention; @@ -43,6 +44,7 @@ import com.iqser.red.storage.commons.StorageAutoConfiguration; import com.knecon.fforesight.databasetenantcommons.DatabaseTenantCommonsAutoConfiguration; import com.knecon.fforesight.jobscommons.JobsAutoConfiguration; import com.knecon.fforesight.keycloakcommons.DefaultKeyCloakCommonsAutoConfiguration; +import com.knecon.fforesight.mongo.database.commons.MongoDatabaseCommonsAutoConfiguration; import com.knecon.fforesight.swaggercommons.SpringDocAutoConfiguration; import com.knecon.fforesight.tenantcommons.MultiTenancyAutoConfiguration; import com.knecon.fforesight.tenantcommons.MultiTenancyMessagingConfiguration; @@ -62,7 +64,8 @@ import lombok.extern.slf4j.Slf4j; @EnableScheduling @EnableCaching @EnableConfigurationProperties({FileManagementServiceSettings.class}) -@ImportAutoConfiguration({StorageAutoConfiguration.class, JobsAutoConfiguration.class, DatabaseTenantCommonsAutoConfiguration.class, MultiTenancyAutoConfiguration.class, SpringDocAutoConfiguration.class, DefaultKeyCloakCommonsAutoConfiguration.class}) +@EnableMongoRepositories(basePackages = "com.iqser.red.service.persistence") +@ImportAutoConfiguration({StorageAutoConfiguration.class, JobsAutoConfiguration.class, DatabaseTenantCommonsAutoConfiguration.class, MultiTenancyAutoConfiguration.class, SpringDocAutoConfiguration.class, DefaultKeyCloakCommonsAutoConfiguration.class, MongoDatabaseCommonsAutoConfiguration.class}) @SpringBootApplication(exclude = {SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class, CassandraAutoConfiguration.class, DataSourceAutoConfiguration.class, LiquibaseAutoConfiguration.class}) @Import({PersistenceServiceExternalApiConfigurationV2.class, PersistenceServiceExternalApiConfiguration.class, PersistenceServiceInternalApiConfiguration.class, PersistenceServiceExternalApiCacheConfiguration.class, MultiTenancyWebConfiguration.class, PersistenceServiceProcessorConfiguration.class, MessagingConfiguration.class, MultiTenancyMessagingConfiguration.class}) public class Application implements 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 0af757fe1..6960236c6 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 @@ -37,6 +37,15 @@ spring: batch_size: 1000 order_inserts: true order_updates: true + data: + mongodb: + auto-index-creation: true + # todo: multi-tenancy + database: redaction + host: ${MONGODB_HOST:localhost} + port: 27017 + username: ${MONGODB_USER} + password: ${MONGODB_PASSWORD} cache: type: redis mvc: 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 e856e1b16..d702fb1c6 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 @@ -64,9 +64,8 @@ public class FileTesterAndProvider { assertThat(fileClient.getDossierStatus(dossier.getId()).size()).isGreaterThanOrEqualTo(1); - fileManagementStorageService.storeJSONObject(dossier.getId(), + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getFileId(), - FileType.ENTITY_LOG, new EntityLog(1, 1, List.of(EntityLogEntry.builder() diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ManualRedactionTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ManualRedactionTest.java index 7b6107283..7672880cc 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ManualRedactionTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/ManualRedactionTest.java @@ -139,7 +139,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyBoolean())).thenReturn(entityLog); @@ -333,7 +333,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog); @@ -393,7 +393,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog); @@ -448,7 +448,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog); @@ -543,7 +543,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier1.getId(), file1.getId(), FileType.ENTITY_LOG, entityLog1); + fileManagementStorageService.saveEntityLog(dossier1.getId(), file1.getId(), entityLog1); var redactionRequest1 = RedactionRequest.builder().dossierId(file1.getDossierId()).fileId(file1.getFileId()).dossierTemplateId(file1.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(eq(file1.getDossierId()), eq(file1.getFileId()), any(), anyBoolean())).thenReturn(entityLog1); @@ -562,7 +562,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier2.getId(), file2.getId(), FileType.ENTITY_LOG, entityLog2); + fileManagementStorageService.saveEntityLog(dossier2.getId(), file2.getId(), entityLog2); var redactionRequest2 = RedactionRequest.builder().dossierId(file2.getDossierId()).fileId(file2.getFileId()).dossierTemplateId(file2.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(eq(file2.getDossierId()), eq(file2.getFileId()), any(), anyBoolean())).thenReturn(entityLog2); @@ -708,7 +708,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier1.getId(), file1.getId(), FileType.ENTITY_LOG, entityLog1); + fileManagementStorageService.saveEntityLog(dossier1.getId(), file1.getId(), entityLog1); var redactionRequest1 = RedactionRequest.builder().dossierId(file1.getDossierId()).fileId(file1.getFileId()).dossierTemplateId(file1.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(eq(file1.getDossierId()), eq(file1.getFileId()), any(), anyBoolean())).thenReturn(entityLog1); @@ -727,7 +727,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier2.getId(), file2.getId(), FileType.ENTITY_LOG, entityLog2); + fileManagementStorageService.saveEntityLog(dossier2.getId(), file2.getId(), entityLog2); var redactionRequest2 = RedactionRequest.builder().dossierId(file2.getDossierId()).fileId(file2.getFileId()).dossierTemplateId(file2.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(eq(file2.getDossierId()), eq(file2.getFileId()), any(), anyBoolean())).thenReturn(entityLog2); @@ -877,7 +877,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier1.getId(), file1.getId(), FileType.ENTITY_LOG, entityLog1); + fileManagementStorageService.saveEntityLog(dossier1.getId(), file1.getId(), entityLog1); var redactionRequest1 = RedactionRequest.builder().dossierId(file1.getDossierId()).fileId(file1.getFileId()).dossierTemplateId(file1.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(file1.getDossierId(), file1.getFileId())).thenReturn(entityLog1); @@ -896,7 +896,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier2.getId(), file2.getId(), FileType.ENTITY_LOG, entityLog2); + fileManagementStorageService.saveEntityLog(dossier2.getId(), file2.getId(), entityLog2); var redactionRequest2 = RedactionRequest.builder().dossierId(file2.getDossierId()).fileId(file2.getFileId()).dossierTemplateId(file2.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(eq(file2.getDossierId()), eq(file2.getFileId()), any(), anyBoolean())).thenReturn(entityLog2); @@ -1043,7 +1043,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier1.getId(), file1.getId(), FileType.ENTITY_LOG, entityLog1); + fileManagementStorageService.saveEntityLog(dossier1.getId(), file1.getId(), entityLog1); var redactionRequest1 = RedactionRequest.builder().dossierId(file1.getDossierId()).fileId(file1.getFileId()).dossierTemplateId(file1.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(file1.getDossierId(), file1.getFileId())).thenReturn(entityLog1); @@ -1062,7 +1062,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier2.getId(), file2.getId(), FileType.ENTITY_LOG, entityLog2); + fileManagementStorageService.saveEntityLog(dossier2.getId(), file2.getId(), entityLog2); var redactionRequest2 = RedactionRequest.builder().dossierId(file2.getDossierId()).fileId(file2.getFileId()).dossierTemplateId(file2.getDossierTemplateId()).build(); when(entityLogService.getEntityLog(eq(file2.getDossierId()), eq(file2.getFileId()), any(), anyBoolean())).thenReturn(entityLog2); @@ -1186,7 +1186,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog); @@ -1270,7 +1270,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog); @@ -1449,7 +1449,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog); @@ -1648,7 +1648,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog); @@ -1754,7 +1754,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any())).thenReturn(entityLog); @@ -1864,7 +1864,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any())).thenReturn(entityLog); @@ -1948,8 +1948,8 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest { 0, 0, 0); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); - fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog); var recatModel = RecategorizationRequestModel.builder() 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 76eb9a805..6a2c43035 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 @@ -1,42 +1,17 @@ package com.iqser.red.service.peristence.v1.server.integration.utils; -import com.iqser.red.commons.jackson.ObjectMapperFactory; -import com.iqser.red.service.peristence.v1.server.Application; -import com.iqser.red.service.peristence.v1.server.integration.client.ApplicationConfigClient; -import com.iqser.red.service.peristence.v1.server.integration.client.FileClient; -import com.iqser.red.service.peristence.v1.server.utils.MetricsPrinterService; -import com.iqser.red.service.persistence.management.v1.processor.client.pdftronredactionservice.PDFTronClient; -import com.iqser.red.service.persistence.management.v1.processor.client.redactionservice.RedactionClient; -import com.iqser.red.service.persistence.management.v1.processor.client.searchservice.SearchClient; -import com.iqser.red.service.persistence.management.v1.processor.client.tenantusermanagementservice.UsersClient; -import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.ApplicationConfigurationEntity; -import com.iqser.red.service.persistence.management.v1.processor.roles.ApplicationRoles; -import com.iqser.red.service.persistence.management.v1.processor.service.ApplicationConfigService; -import com.iqser.red.service.persistence.management.v1.processor.service.EntityLogService; -import com.iqser.red.service.persistence.management.v1.processor.service.FileManagementStorageService; -import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.*; -import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.*; -import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry.EntryRepository; -import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry.FalsePositiveEntryRepository; -import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry.FalseRecommendationEntryRepository; -import com.iqser.red.service.persistence.management.v1.processor.service.users.UserService; -import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLog; -import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.ApplicationConfig; -import com.iqser.red.service.redaction.v1.model.DroolsValidation; -import com.iqser.red.storage.commons.service.StorageService; -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.tenantcommons.EncryptionDecryptionService; -import com.knecon.fforesight.tenantcommons.TenantContext; -import com.knecon.fforesight.tenantcommons.TenantsClient; -import com.knecon.fforesight.tenantcommons.model.*; +import static org.mockito.Mockito.when; -import io.micrometer.prometheus.PrometheusMeterRegistry; -import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; import org.assertj.core.util.Lists; +import org.bson.BsonArray; +import org.bson.BsonDocument; +import org.bson.BsonString; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; @@ -53,7 +28,11 @@ import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.*; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.Primary; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.StatementCallback; import org.springframework.jdbc.datasource.SingleConnectionDataSource; @@ -69,13 +48,78 @@ import org.springframework.security.web.SecurityFilterChain; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; +import com.iqser.red.commons.jackson.ObjectMapperFactory; +import com.iqser.red.service.peristence.v1.server.Application; +import com.iqser.red.service.peristence.v1.server.integration.client.ApplicationConfigClient; +import com.iqser.red.service.peristence.v1.server.integration.client.FileClient; +import com.iqser.red.service.peristence.v1.server.utils.MetricsPrinterService; +import com.iqser.red.service.persistence.management.v1.processor.client.pdftronredactionservice.PDFTronClient; +import com.iqser.red.service.persistence.management.v1.processor.client.redactionservice.RedactionClient; +import com.iqser.red.service.persistence.management.v1.processor.client.searchservice.SearchClient; +import com.iqser.red.service.persistence.management.v1.processor.client.tenantusermanagementservice.UsersClient; +import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.ApplicationConfigurationEntity; +import com.iqser.red.service.persistence.management.v1.processor.roles.ApplicationRoles; +import com.iqser.red.service.persistence.management.v1.processor.service.ApplicationConfigService; +import com.iqser.red.service.persistence.management.v1.processor.service.EntityLogService; +import com.iqser.red.service.persistence.management.v1.processor.service.FileManagementStorageService; +import com.iqser.red.service.persistence.management.v1.processor.service.mongo.EntityLogMongoService; +import com.iqser.red.service.persistence.management.v1.processor.service.mongo.repository.EntityLogDocumentRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.mongo.repository.EntityLogEntryDocumentRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.ApplicationConfigRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.AuditRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DigitalSignatureRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierAttributeConfigRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierAttributeRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierStatusRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierTemplateRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DownloadStatusRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.FileAttributeConfigRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.FileAttributesGeneralConfigurationRepository; +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.management.v1.processor.service.persistence.repository.IndexInformationRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.LegalBasisMappingRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.NotificationPreferencesRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.NotificationRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.ReportTemplateRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.RuleSetRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.TypeRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.ViewedPagesRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.WatermarkRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.ForceRedactionRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.LegalBasisChangeRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.ManualRedactionRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.RecategorizationRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.RemoveRedactionRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry.EntryRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry.FalsePositiveEntryRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry.FalseRecommendationEntryRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.users.UserService; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLog; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.ApplicationConfig; +import com.iqser.red.service.redaction.v1.model.DroolsValidation; +import com.iqser.red.storage.commons.service.StorageService; +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.tenantcommons.EncryptionDecryptionService; +import com.knecon.fforesight.tenantcommons.TenantContext; +import com.knecon.fforesight.tenantcommons.TenantsClient; +import com.knecon.fforesight.tenantcommons.model.AuthDetails; +import com.knecon.fforesight.tenantcommons.model.DatabaseConnection; +import com.knecon.fforesight.tenantcommons.model.MongoDBConnection; +import com.knecon.fforesight.tenantcommons.model.S3StorageConnection; +import com.knecon.fforesight.tenantcommons.model.SearchConnection; +import com.knecon.fforesight.tenantcommons.model.TenantResponse; +import com.mongodb.MongoCommandException; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; +import com.mongodb.client.MongoDatabase; -import static org.mockito.Mockito.when; +import io.micrometer.prometheus.PrometheusMeterRegistry; +import lombok.extern.slf4j.Slf4j; @Slf4j @ExtendWith(SpringExtension.class) @@ -100,6 +144,12 @@ public abstract class AbstractPersistenceServerServiceTest { @Autowired protected StorageService storageService; @Autowired + protected EntityLogMongoService entityLogMongoService; + @Autowired + protected EntityLogDocumentRepository entityLogDocumentRepository; + @Autowired + protected EntityLogEntryDocumentRepository entityLogEntryDocumentRepository; + @Autowired protected FileManagementStorageService fileManagementStorageService; @Autowired protected DossierTemplateRepository dossierTemplateRepository; @@ -268,6 +318,7 @@ public abstract class AbstractPersistenceServerServiceTest { private void createDefaultTenant() { var postgreSQLContainerMaster = SpringPostgreSQLTestContainer.getInstance().withDatabaseName("integration-tests-db-master").withUsername("sa").withPassword("sa"); + var mongoDbContainer = MongoDBTestContainer.getInstance(); var port = postgreSQLContainerMaster.getJdbcUrl().substring(0, postgreSQLContainerMaster.getJdbcUrl().lastIndexOf('/')).split(":")[3]; @@ -296,6 +347,7 @@ public abstract class AbstractPersistenceServerServiceTest { .numberOfShards("1") .numberOfReplicas("5") .build()); + redactionTenant.setS3StorageConnection(S3StorageConnection.builder() .key("key") .secret("secret") @@ -304,6 +356,15 @@ public abstract class AbstractPersistenceServerServiceTest { .region("eu") .endpoint("endpoint") .build()); + + redactionTenant.setMongoDBConnection(MongoDBConnection.builder() + .host(mongoDbContainer.getHost()) + .port(String.valueOf(mongoDbContainer.getFirstMappedPort())) + .username(MongoDBTestContainer.MONGO_USERNAME) + .password(encryptionDecryptionService.encrypt(MongoDBTestContainer.MONGO_PASSWORD)) + .database(MongoDBTestContainer.MONGO_DATABASE) + .build()); + when(tenantsClient.getTenant("redaction")).thenReturn(redactionTenant); when(tenantsClient.getTenants()).thenReturn(List.of(redactionTenant)); @@ -332,6 +393,8 @@ public abstract class AbstractPersistenceServerServiceTest { } + + @AfterEach public void cleanupStorage() { @@ -385,6 +448,9 @@ public abstract class AbstractPersistenceServerServiceTest { indexInformationRepository.deleteAll(); applicationConfigRepository.deleteAll(); + entityLogEntryDocumentRepository.deleteAll(); + entityLogDocumentRepository.deleteAll(); + }); } @@ -401,10 +467,18 @@ public abstract class AbstractPersistenceServerServiceTest { var redisContainer = RedisTestContainer.getInstance(); redisContainer.start(); - log.info("Hosts are - Redis: {}, Postgres: {}", redisContainer.getHost(), postgreSQLContainerMaster.getHost()); + var mongoInstance = MongoDBTestContainer.getInstance(); + mongoInstance.start(); + createMongoDBDatabase(mongoInstance); + + log.info("Hosts are - Redis: {}, Postgres: {}, MongoDB: {}", redisContainer.getHost(), postgreSQLContainerMaster.getHost(), mongoInstance.getHost()); TestPropertyValues.of("REDIS_PORT=" + redisContainer.getFirstMappedPort(), "REDIS_HOST=" + redisContainer.getHost(), + "MONGODB_HOST=" + mongoInstance.getHost(), + "MONGODB_PORT=" + mongoInstance.getFirstMappedPort(), + "MONGODB_USER=" + MongoDBTestContainer.MONGO_USERNAME, + "MONGODB_PASSWORD=" + MongoDBTestContainer.MONGO_PASSWORD, "fforesight.jobs.enabled=false", "fforesight.keycloak.enabled=false").applyTo(configurableApplicationContext.getEnvironment()); @@ -412,11 +486,40 @@ public abstract class AbstractPersistenceServerServiceTest { } + + private static void createMongoDBDatabase(MongoDBTestContainer mongoDBTestContainer) { + + try (MongoClient mongoClient = MongoClients.create(String.format("mongodb://%s:%s@%s:%s/", + MongoDBTestContainer.MONGO_USERNAME, + MongoDBTestContainer.MONGO_PASSWORD, + mongoDBTestContainer.getHost(), + mongoDBTestContainer.getFirstMappedPort()))) { + MongoDatabase database = mongoClient.getDatabase(MongoDBTestContainer.MONGO_DATABASE); + BsonDocument createUserCommand = new BsonDocument(); + createUserCommand.append("createUser", new BsonString(MongoDBTestContainer.MONGO_USERNAME)); + createUserCommand.append("pwd", new BsonString(MongoDBTestContainer.MONGO_PASSWORD)); + BsonArray roles = new BsonArray(); + roles.add(new BsonString("readWrite")); + createUserCommand.append("roles", roles); + + try { + database.runCommand(createUserCommand); + } catch (MongoCommandException mongoCommandException) { + // ignore user already exists + if(mongoCommandException.getErrorCode() != 51003) { + throw mongoCommandException; + } + + } + + } + } + @Configuration @EnableWebSecurity @EnableMethodSecurity @EnableAutoConfiguration(exclude = {RabbitAutoConfiguration.class}) - @ComponentScan("com.iqser.red.service.persistence") + @ComponentScan(basePackages = {"com.iqser.red.service.persistence" }) public static class TestConfiguration { @Bean diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/MongoDBTestContainer.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/MongoDBTestContainer.java new file mode 100644 index 000000000..6db3c46ec --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/utils/MongoDBTestContainer.java @@ -0,0 +1,35 @@ +package com.iqser.red.service.peristence.v1.server.integration.utils; + +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; + +public final class MongoDBTestContainer extends GenericContainer { + + private static final String IMAGE_VERSION = "mongo:7.0.2"; + public static final Integer MONGO_PORT = 27017; + public static final String MONGO_DATABASE = "redaction"; + public static final String MONGO_PASSWORD = "mongopassword"; + public static final String MONGO_USERNAME = "mongousername"; + private static MongoDBTestContainer mongoDB; + + + private MongoDBTestContainer() { + + super(DockerImageName.parse(IMAGE_VERSION)); + + } + + + public static MongoDBTestContainer getInstance() { + + if (mongoDB == null) { + mongoDB = new MongoDBTestContainer().withEnv("MONGO_INITDB_ROOT_USERNAME", MONGO_USERNAME) + .withEnv("MONGO_INITDB_ROOT_PASSWORD", MONGO_PASSWORD) + .withEnv("MONGO_INITDB_DATABASE", MONGO_DATABASE) + .withExposedPorts(MONGO_PORT); + + } + return mongoDB; + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml b/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml index 968397e81..7f5c1f6a7 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml +++ b/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml @@ -19,7 +19,15 @@ spring: order_inserts: true order_updates: true open-in-view: true - + data: + mongodb: + auto-index-creation: true + # todo: multi-tenancy + database: redaction + host: ${MONGODB_HOST:localhost} + port: 27017 + username: ${MONGODB_USER} + password: ${MONGODB_PASSWORD} rabbitmq: host: ${RABBITMQ_HOST:localhost} port: ${RABBITMQ_PORT:5672} diff --git a/persistence-service-v1/persistence-service-shared-api-v1/build.gradle.kts b/persistence-service-v1/persistence-service-shared-api-v1/build.gradle.kts index a10ac954d..b2dfa2a93 100644 --- a/persistence-service-v1/persistence-service-shared-api-v1/build.gradle.kts +++ b/persistence-service-v1/persistence-service-shared-api-v1/build.gradle.kts @@ -3,6 +3,8 @@ plugins { id("io.freefair.lombok") version "8.4" } +val springBootStarterVersion = "3.1.5" + dependencies { api("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.16.0") api("com.google.guava:guava:31.1-jre")