RED-8480: adjusted propertyChanges in manual changes

(cherry picked from commit 8a4c754250e88fa1d5455c10138ef808478eed04)
This commit is contained in:
Ali Oezyetimoglu 2024-03-15 16:26:39 +01:00
parent abfb88755e
commit e5c1126c7e
6 changed files with 186 additions and 55 deletions

View File

@ -51,6 +51,8 @@ public class ManualRecategorizationEntity implements IBaseAnnotation {
private String legalBasis; private String legalBasis;
@Column(length = 1024) @Column(length = 1024)
private String section; private String section;
@Column
private String value;
@ManyToOne @ManyToOne
private FileEntity fileStatus; private FileEntity fileStatus;

View File

@ -280,6 +280,7 @@ public class EntityLogMergeService {
} }
@Deprecated(forRemoval = true)
private void mergeLegalBasisChanges(ManualLegalBasisChange manualLegalBasisChange, List<EntityLogEntry> entityLogEntries, int analysisNumber) { private void mergeLegalBasisChanges(ManualLegalBasisChange manualLegalBasisChange, List<EntityLogEntry> entityLogEntries, int analysisNumber) {
var entity = entityLogEntries.stream() var entity = entityLogEntries.stream()
@ -305,6 +306,7 @@ public class EntityLogMergeService {
} }
@Deprecated(forRemoval = true)
private Map<String, String> getPropertyChanges(ManualLegalBasisChange manualLegalBasisChange) { private Map<String, String> getPropertyChanges(ManualLegalBasisChange manualLegalBasisChange) {
Map<String, String> propertyChanges = new HashMap<>(); Map<String, String> propertyChanges = new HashMap<>();
@ -339,12 +341,31 @@ public class EntityLogMergeService {
.requestedDate(recategorization.getRequestDate()) .requestedDate(recategorization.getRequestDate())
.processedDate(recategorization.getProcessedDate()) .processedDate(recategorization.getProcessedDate())
.userId(recategorization.getUser()) .userId(recategorization.getUser())
.propertyChanges(Map.of("type", recategorization.getType())) .propertyChanges(getPropertyChanges(recategorization))
.build()); .build());
}); });
} }
private Map<String, String> getPropertyChanges(ManualRecategorization recategorization) {
Map<String, String> propertyChanges = new HashMap<>();
if (!Strings.isNullOrEmpty(recategorization.getType())) {
propertyChanges.put("type", recategorization.getType());
}
if (!Strings.isNullOrEmpty(recategorization.getLegalBasis())) {
propertyChanges.put("legalBasis", recategorization.getLegalBasis());
}
if (!Strings.isNullOrEmpty(recategorization.getValue())) {
propertyChanges.put("value", recategorization.getValue());
}
if (!Strings.isNullOrEmpty(recategorization.getSection())) {
propertyChanges.put("section", recategorization.getSection());
}
return propertyChanges;
}
private void mergeForceRedactions(ManualForceRedaction forceRedaction, List<EntityLogEntry> entityLogEntries, int analysisNumber) { private void mergeForceRedactions(ManualForceRedaction forceRedaction, List<EntityLogEntry> entityLogEntries, int analysisNumber) {
var entity = entityLogEntries.stream() var entity = entityLogEntries.stream()

View File

@ -113,16 +113,21 @@ public class ManualRedactionUndoService {
.stream() .stream()
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualResizeRedaction) .filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualResizeRedaction)
.map(ManualRedactionWrapperModel::getId) .map(ManualRedactionWrapperModel::getId)
.collect(Collectors.toList()); .toList();
if (!manualResizeRedactions.isEmpty()) { if (!manualResizeRedactions.isEmpty()) {
deleteResizeRedaction(dossierId, fileId, manualResizeRedactions); deleteResizeRedaction(dossierId, fileId, manualResizeRedactions);
manualResizeRedactions.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder() manualResizeRedactions.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder()
.userId(KeycloakSecurity.getUserId()) .userId(KeycloakSecurity.getUserId())
.objectId(fileId) .objectId(fileId)
.category(AuditCategory.DOCUMENT.name()) .category(AuditCategory.DOCUMENT.name())
.message("Undo of manual resize redaction was done.") .message("Undo of manual resize redaction was done.")
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId)) .details(Map.of(DOSSIER_ID,
.build())); dossierId,
FILE_ID,
fileId,
ANNOTATION_ID,
annotationId))
.build()));
} }
} }
@ -143,17 +148,22 @@ public class ManualRedactionUndoService {
.stream() .stream()
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualLegalBasisChange) .filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualLegalBasisChange)
.map(ManualRedactionWrapperModel::getId) .map(ManualRedactionWrapperModel::getId)
.collect(Collectors.toList()); .toList();
if (!manualLegalBasisChanges.isEmpty()) { if (!manualLegalBasisChanges.isEmpty()) {
deleteLegalBasisChange(dossierId, fileId, manualLegalBasisChanges); deleteLegalBasisChange(dossierId, fileId, manualLegalBasisChanges);
manualLegalBasisChanges.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder() manualLegalBasisChanges.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder()
.userId(KeycloakSecurity.getUserId()) .userId(KeycloakSecurity.getUserId())
.objectId(fileId) .objectId(fileId)
.category(AuditCategory.DOCUMENT.name()) .category(AuditCategory.DOCUMENT.name())
.message("Undo of legal basis change was done.") .message("Undo of legal basis change was done.")
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId)) .details(Map.of(DOSSIER_ID,
.build())); dossierId,
FILE_ID,
fileId,
ANNOTATION_ID,
annotationId))
.build()));
} }
} }
@ -169,21 +179,26 @@ public class ManualRedactionUndoService {
private void undoRecategorization(String dossierId, String fileId, Map<String, ManualRedactionWrapperModel> manualRedactionWrappers, boolean includeUnprocessed) { private void undoRecategorization(String dossierId, String fileId, Map<String, ManualRedactionWrapperModel> manualRedactionWrappers, boolean includeUnprocessed) {
List<String> manualImageRecategorizations = manualRedactionWrappers.values() List<String> manualRecategorizations = manualRedactionWrappers.values()
.stream() .stream()
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualRecategorization) .filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualRecategorization)
.map(ManualRedactionWrapperModel::getId) .map(ManualRedactionWrapperModel::getId)
.collect(Collectors.toList()); .toList();
if (!manualImageRecategorizations.isEmpty()) { if (!manualRecategorizations.isEmpty()) {
deleteRecategorization(dossierId, fileId, manualImageRecategorizations, includeUnprocessed); deleteRecategorization(dossierId, fileId, manualRecategorizations, includeUnprocessed);
manualImageRecategorizations.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder() manualRecategorizations.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder()
.userId(KeycloakSecurity.getUserId()) .userId(KeycloakSecurity.getUserId())
.objectId(fileId) .objectId(fileId)
.category(AuditCategory.DOCUMENT.name()) .category(AuditCategory.DOCUMENT.name())
.message("Undo of manual image recategorization was done.") .message("Undo of manual recategorization was done.")
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId)) .details(Map.of(DOSSIER_ID,
.build())); dossierId,
FILE_ID,
fileId,
ANNOTATION_ID,
annotationId))
.build()));
} }
} }
@ -198,10 +213,10 @@ public class ManualRedactionUndoService {
String originalValue = getEntityLogEntry(entityLog, annotationId).getValue(); String originalValue = getEntityLogEntry(entityLog, annotationId).getValue();
manualRedactionDictionaryUpdateHandler.revertRemoveFromDictionary(originalValue, dossierId, fileId, recategorizationEntity.getTypeIdsOfDictionariesWithDelete()); manualRedactionDictionaryUpdateHandler.revertRemoveFromDictionary(originalValue, dossierId, fileId, recategorizationEntity.getTypeIdsOfDictionariesWithDelete());
manualRedactionDictionaryUpdateHandler.revertAddToDictionary(originalValue, manualRedactionDictionaryUpdateHandler.revertAddToDictionary(originalValue,
DictionaryEntryType.ENTRY, DictionaryEntryType.ENTRY,
fileId, fileId,
dossierId, dossierId,
recategorizationEntity.getTypeIdsOfDictionariesWithAdd()); recategorizationEntity.getTypeIdsOfDictionariesWithAdd());
recategorizationPersistenceService.updateModifiedDictionaries(fileId, annotationId, Collections.emptySet(), Collections.emptySet()); recategorizationPersistenceService.updateModifiedDictionaries(fileId, annotationId, Collections.emptySet(), Collections.emptySet());
recategorizationPersistenceService.softDelete(fileId, annotationId, OffsetDateTime.now()); recategorizationPersistenceService.softDelete(fileId, annotationId, OffsetDateTime.now());
} }
@ -215,17 +230,22 @@ public class ManualRedactionUndoService {
.stream() .stream()
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualForceRedaction) .filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualForceRedaction)
.map(ManualRedactionWrapperModel::getId) .map(ManualRedactionWrapperModel::getId)
.collect(Collectors.toList()); .toList();
if (!manualForceRedactions.isEmpty()) { if (!manualForceRedactions.isEmpty()) {
deleteForceRedaction(dossierId, fileId, manualForceRedactions); deleteForceRedaction(dossierId, fileId, manualForceRedactions);
manualForceRedactions.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder() manualForceRedactions.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder()
.userId(KeycloakSecurity.getUserId()) .userId(KeycloakSecurity.getUserId())
.objectId(fileId) .objectId(fileId)
.category(AuditCategory.DOCUMENT.name()) .category(AuditCategory.DOCUMENT.name())
.message("Undo of manual force redaction was done.") .message("Undo of manual force redaction was done.")
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId)) .details(Map.of(DOSSIER_ID,
.build())); dossierId,
FILE_ID,
fileId,
ANNOTATION_ID,
annotationId))
.build()));
} }
} }
@ -247,16 +267,16 @@ public class ManualRedactionUndoService {
.stream() .stream()
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof IdRemoval) .filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof IdRemoval)
.map(ManualRedactionWrapperModel::getId) .map(ManualRedactionWrapperModel::getId)
.collect(Collectors.toList()); .toList();
if (!idRemovals.isEmpty()) { if (!idRemovals.isEmpty()) {
deleteRemoveRedaction(dossierId, fileId, idRemovals); deleteRemoveRedaction(dossierId, fileId, idRemovals);
idRemovals.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder() idRemovals.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder()
.userId(KeycloakSecurity.getUserId()) .userId(KeycloakSecurity.getUserId())
.objectId(fileId) .objectId(fileId)
.category(AuditCategory.DOCUMENT.name()) .category(AuditCategory.DOCUMENT.name())
.message("Undo of manual remove redaction was done.") .message("Undo of manual remove redaction was done.")
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId)) .details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId))
.build())); .build()));
} }
} }
@ -284,16 +304,21 @@ public class ManualRedactionUndoService {
.stream() .stream()
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualRedactionEntry) .filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualRedactionEntry)
.map(ManualRedactionWrapperModel::getId) .map(ManualRedactionWrapperModel::getId)
.collect(Collectors.toList()); .toList();
if (!manualRedactionEntries.isEmpty()) { if (!manualRedactionEntries.isEmpty()) {
deleteAddRedaction(dossierId, fileId, manualRedactionEntries); deleteAddRedaction(dossierId, fileId, manualRedactionEntries);
manualRedactionEntries.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder() manualRedactionEntries.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder()
.userId(KeycloakSecurity.getUserId()) .userId(KeycloakSecurity.getUserId())
.objectId(fileId) .objectId(fileId)
.category(AuditCategory.DOCUMENT.name()) .category(AuditCategory.DOCUMENT.name())
.message("Undo of manual add redaction was done.") .message("Undo of manual add redaction was done.")
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId)) .details(Map.of(DOSSIER_ID,
.build())); dossierId,
FILE_ID,
fileId,
ANNOTATION_ID,
annotationId))
.build()));
} }
} }

View File

@ -167,7 +167,14 @@ public class PendingDictionaryEntryFactory {
.requestedDate(manualChange.getRequestDate()) .requestedDate(manualChange.getRequestDate())
.processedDate(manualChange.getProcessedDate()) .processedDate(manualChange.getProcessedDate())
.userId(manualChange.getUser()) .userId(manualChange.getUser())
.propertyChanges(Map.of("type", manualChange.getType())) .propertyChanges(Map.of("type",
manualChange.getType(),
"legalBasis",
manualChange.getLegalBasis(),
"value",
manualChange.getValue(),
"section",
manualChange.getSection()))
.build()); .build());
return EntityLogEntry.builder() return EntityLogEntry.builder()

View File

@ -8,4 +8,7 @@ databaseChangeLog:
columns: columns:
- column: - column:
name: section name: section
type: VARCHAR(1024) type: VARCHAR(1024)
- column:
name: value
type: VARCHAR(4000)

View File

@ -1827,7 +1827,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
EntityLogEntry.builder() EntityLogEntry.builder()
.id("annotationId2") .id("annotationId2")
.type(type.getType()) .type(type.getType())
.value("Johannesbrotkernmehl") .value("Johannisbrotkernmehl")
.dictionaryEntry(true) .dictionaryEntry(true)
.entryType(EntryType.ENTITY) .entryType(EntryType.ENTITY)
.state(EntryState.APPLIED) .state(EntryState.APPLIED)
@ -1846,7 +1846,6 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
0, 0,
0); 0);
fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog); fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog);
fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog);
when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog); when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog);
var recatModel = RecategorizationRequestModel.builder() var recatModel = RecategorizationRequestModel.builder()
@ -1963,4 +1962,78 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
} }
@Test
public void testPropertyChangesForLegalBasisInManualRecategorization() {
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
var dossier = dossierTesterAndProvider.provideTestDossier(dossierTemplate);
var file = fileTesterAndProvider.testAndProvideFile(dossier);
var type = typeProvider.testAndProvideType(dossierTemplate, null, "type", false);
var entityLog = new EntityLog(1,
1,
List.of(EntityLogEntry.builder()
.id("annotationId")
.type(type.getType())
.value("lukeSkywalker")
.dictionaryEntry(true)
.entryType(EntryType.ENTITY)
.state(EntryState.APPLIED)
.legalBasis("lb1")
.section("section")
.build(),
EntityLogEntry.builder()
.id("annotationId2")
.type(type.getType())
.value("Johannisbrotkernmehl")
.dictionaryEntry(true)
.entryType(EntryType.ENTITY)
.state(EntryState.APPLIED)
.build(),
EntityLogEntry.builder()
.id("annotationId3")
.type(type.getType())
.value("Baustelle")
.dictionaryEntry(true)
.entryType(EntryType.ENTITY)
.state(EntryState.APPLIED)
.build()),
null,
0,
0,
0,
0);
fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog);
when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog);
var recatModel = RecategorizationRequestModel.builder()
.type(type.getType())
.annotationId("annotationId")
.addToDictionary(false)
.addToAllDossiers(false)
.legalBasis("lb2")
.section("section")
.value("lukeSkywalker")
.build();
manualRedactionClient.recategorizeBulk(dossier.getId(), file.getId(), Set.of(recatModel), false);
var allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, true);
assertEquals(1, allManualRedactions.getRecategorizations().size());
assertTrue(allManualRedactions.getRecategorizations()
.stream()
.anyMatch(entry -> entry.getAnnotationId().equals("annotationId")));
assertTrue(allManualRedactions.getRecategorizations()
.stream()
.anyMatch(entry -> entry.getLegalBasis().equals("lb2")));
assertTrue(allManualRedactions.getRecategorizations()
.stream()
.anyMatch(entry -> entry.getSection().equals("section")));
assertTrue(allManualRedactions.getRecategorizations()
.stream()
.anyMatch(entry -> entry.getValue().equals("lukeSkywalker")));
}
} }