RED-7782 - Merge unprocessed redactions into entity log without re-analysis. #200

Merged
andrei.isvoran.ext merged 5 commits from RED-7784-unprocessed-redactions into master 2023-10-27 12:03:11 +02:00
9 changed files with 538 additions and 13 deletions

View File

@ -27,9 +27,10 @@ public class EntityLogController implements EntityLogResource {
@PreAuthorize("hasAuthority('" + READ_REDACTION_LOG + "')")
public EntityLog getEntityLog(@PathVariable(DOSSIER_ID) String dossierId,
@PathVariable(FILE_ID) String fileId,
@RequestParam(value = "excludedType", required = false) List<String> excludedTypes) {
@RequestParam(value = "excludedType", required = false) List<String> excludedTypes,
@RequestParam(value = "includeUnprocessed", required = false, defaultValue = FALSE) boolean includeUnprocessed) {
return entityLogService.getEntityLog(dossierId, fileId, excludedTypes);
return entityLogService.getEntityLog(dossierId, fileId, excludedTypes, includeUnprocessed);
}

View File

@ -29,13 +29,16 @@ public interface EntityLogResource {
String DOSSIER_ID = "dossierId";
String DOSSIER_ID_PATH_VARIABLE = "/{" + DOSSIER_ID + "}";
String FALSE = "false";
@GetMapping(value = ENTITY_LOG_PATH + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Gets the entity log for a fileId", description = "None")
@Operation(summary = "Gets the entity log for a fileId", description = "Gets the entity log for a given file. The flag includeUnprocessed will merge into the entity log all the unprocessed changes if it's set to true." +
"Default value for the flag is false.")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "400", description = "Request contains error."), @ApiResponse(responseCode = "404", description = "The entity log is not found.")})
EntityLog getEntityLog(@PathVariable(DOSSIER_ID) String dossierId,
@PathVariable(FILE_ID) String fileId,
@RequestParam(value = "excludedType", required = false) List<String> excludedTypes);
@RequestParam(value = "excludedType", required = false) List<String> excludedTypes,
@RequestParam(value = "includeUnprocessed", required = false, defaultValue = FALSE) boolean includeUnprocessed);
@PostMapping(value = ENTITY_LOG_PATH + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE + "/filtered", produces = MediaType.APPLICATION_JSON_VALUE)

View File

@ -21,9 +21,10 @@ public class EntityLogInternalController implements EntityLogResource {
public EntityLog getEntityLog(@PathVariable(DOSSIER_ID) String dossierId,
@PathVariable(FILE_ID) String fileId,
@RequestParam(value = "excludedType", required = false) List<String> excludedTypes) {
@RequestParam(value = "excludedType", required = false) List<String> excludedTypes,
@RequestParam(value = "includeUnprocessed", required = false, defaultValue = FALSE) boolean includeUnprocessed) {
return entityLogService.getEntityLog(dossierId, fileId, excludedTypes);
return entityLogService.getEntityLog(dossierId, fileId, excludedTypes, includeUnprocessed);
}

View File

@ -26,11 +26,14 @@ public interface EntityLogResource {
String DOSSIER_ID = "dossierId";
String DOSSIER_ID_PATH_VARIABLE = "/{" + DOSSIER_ID + "}";
String FALSE = "false";
@GetMapping(value = ENTITY_LOG_PATH + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Gets the entity log for a fileId", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "400", description = "Request contains error."), @ApiResponse(responseCode = "404", description = "The entity log is not found.")})
EntityLog getEntityLog(@PathVariable(DOSSIER_ID) String dossierId,
@PathVariable(FILE_ID) String fileId,
@RequestParam(value = "excludedType", required = false) List<String> excludedTypes);
@RequestParam(value = "excludedType", required = false) List<String> excludedTypes,
@RequestParam(value = "includeUnprocessed", required = false, defaultValue = FALSE) boolean includeUnprocessed);
}

View File

@ -0,0 +1,10 @@
package com.iqser.red.service.persistence.management.v1.processor.client.redactionservice;
import org.springframework.cloud.openfeign.FeignClient;
import com.iqser.red.service.redaction.v1.resources.UnprocessedManualEntityResource;
@FeignClient(name = "UnprocessedManualEntityClient", url = "${redaction-service.url}")
public interface UnprocessedManualEntityClient extends UnprocessedManualEntityResource {
}

View File

@ -1,39 +1,70 @@
package com.iqser.red.service.persistence.management.v1.processor.service;
import static com.iqser.red.service.persistence.management.v1.processor.utils.TypeIdUtils.toTypeId;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.stereotype.Service;
import com.iqser.red.service.persistence.management.v1.processor.client.redactionservice.UnprocessedManualEntityClient;
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.TypeEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.service.manualredactions.ManualRedactionProviderService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DictionaryPersistenceService;
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.ChangeType;
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;
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.FilteredEntityLogRequest;
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.ManualRedactionType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Position;
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.entitymapped.IdRemoval;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualForceRedaction;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualLegalBasisChange;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRecategorization;
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.annotations.entitymapped.ManualResizeRedaction;
import com.iqser.red.service.redaction.v1.model.UnprocessedManualEntity;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults;
import lombok.extern.slf4j.Slf4j;
@Service
@RequiredArgsConstructor
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@Slf4j
public class EntityLogService {
FileManagementStorageService fileManagementStorageService;
FileStatusService fileStatusService;
ManualRedactionProviderService manualRedactionProviderService;
UnprocessedManualEntityClient unprocessedManualEntityClient;
DossierService dossierService;
CommentService commentService;
DictionaryPersistenceService dictionaryPersistenceService;
public EntityLog getEntityLog(String dossierId, String fileId) {
return getEntityLog(dossierId, fileId, Collections.emptyList());
return getEntityLog(dossierId, fileId, Collections.emptyList(), false);
}
public EntityLog getEntityLog(String dossierId, String fileId, List<String> excludedTypes) {
public EntityLog getEntityLog(String dossierId, String fileId, List<String> excludedTypes, boolean includeUnprocessed) {
var fileStatus = fileStatusService.getStatus(fileId);
@ -49,6 +80,13 @@ public class EntityLogService {
entityLog.getEntityLogEntry().removeIf(entry -> excludedTypes.contains(entry.getType()));
}
if (includeUnprocessed) {
DossierEntity dossier = dossierService.getDossierById(dossierId);
ManualRedactions manualRedactions = manualRedactionProviderService.getManualRedactions(fileId, true);
List<UnprocessedManualEntity> unprocessedManualEntities = getUnprocessedManualEntities(dossierId, fileId, dossier.getDossierTemplateId(), manualRedactions);
mergeEntityLog(manualRedactions, unprocessedManualEntities, entityLog, dossier.getDossierTemplateId());
}
Map<String, Integer> commentCountPerAnnotationId = commentService.getCommentCounts(fileId);
entityLog.getEntityLogEntry().forEach(entityLogEntry -> entityLogEntry.setNumberOfComments(commentCountPerAnnotationId.getOrDefault(entityLogEntry.getId(), 0)));
@ -62,7 +100,7 @@ public class EntityLogService {
filteredEntityLogRequest.setSpecifiedDate(OffsetDateTime.MIN);
}
var entityLog = getEntityLog(dossierId, fileId, filteredEntityLogRequest.getExcludedTypes());
var entityLog = getEntityLog(dossierId, fileId, filteredEntityLogRequest.getExcludedTypes(), false);
var entityLogEntry = entityLog.getEntityLogEntry();
Iterator<EntityLogEntry> it = entityLogEntry.iterator();
@ -92,4 +130,194 @@ public class EntityLogService {
return entityLog;
}
private List<UnprocessedManualEntity> getUnprocessedManualEntities(String dossierId, String fileId, String dossierTemplateId, ManualRedactions manualRedactions) {
return unprocessedManualEntityClient.mergeUnprocessedManualEntities(fileId, dossierId, dossierTemplateId, manualRedactions);
}
public void mergeEntityLog(ManualRedactions manualRedactions, List<UnprocessedManualEntity> unprocessedManualEntities, EntityLog entityLog, String dossierTemplateId) {
log.info("Merging EntityLog");
mergeManualRedactionEntries(manualRedactions.getEntriesToAdd(), unprocessedManualEntities, entityLog, dossierTemplateId);
mergeIdsToRemove(manualRedactions.getIdsToRemove(), entityLog);
mergeResizeRedactions(manualRedactions.getResizeRedactions(), entityLog);
mergeLegalBasisChanges(manualRedactions.getLegalBasisChanges(), entityLog);
mergeRecategorizations(manualRedactions.getRecategorizations(), entityLog);
mergeForceRedactions(manualRedactions.getForceRedactions(), entityLog);
log.info("EntityLog merged successfully!");
}
private void mergeManualRedactionEntries(Set<ManualRedactionEntry> manualRedactionEntries, List<UnprocessedManualEntity> unprocessedManualEntities, EntityLog entityLog, String dossierTemplateId) {
manualRedactionEntries.forEach(manualRedactionEntry -> {
UnprocessedManualEntity unprocessedManualEntity = unprocessedManualEntities.stream()
.filter(manualEntity -> manualEntity.getAnnotationId().equals(manualRedactionEntry.getAnnotationId()))
.findFirst().orElseThrow(() -> new NotFoundException("Entry with annotationId " + manualRedactionEntry.getAnnotationId() + " not found"));
List<Change> changes = new ArrayList<>();
changes.add(Change.builder()
.analysisNumber(entityLog.getAnalysisNumber())
.dateTime(OffsetDateTime.now())
.type(ChangeType.ADDED)
.build());
entityLog.getEntityLogEntry().add(EntityLogEntry.builder()
.id(manualRedactionEntry.getAnnotationId())
.type(manualRedactionEntry.getType())
.value(manualRedactionEntry.getValue())
.legalBasis(manualRedactionEntry.getLegalBasis())
.reason(manualRedactionEntry.getReason())
.entryType(isHint(manualRedactionEntry.getType(), dossierTemplateId) ? EntryType.HINT : EntryType.ENTITY)
.imported(false)
.matchedRule("")
.section(manualRedactionEntry.getSection())
.color(unprocessedManualEntity.getColor())
.positions(unprocessedManualEntity.getPositions())
.textAfter(unprocessedManualEntity.getTextAfter())
.textBefore(unprocessedManualEntity.getTextBefore())
.startOffset(unprocessedManualEntity.getStartOffset())
.endOffset(unprocessedManualEntity.getEndOffset())
.containingNodeId(unprocessedManualEntity.getContainingNodeId())
.closestHeadline(unprocessedManualEntity.getClosestHeadline())
.imageHasTransparency(false)
.dictionaryEntry(manualRedactionEntry.isAddToDictionary())
.dossierDictionaryEntry(manualRedactionEntry.isAddToDossierDictionary())
.excluded(false)
.changes(changes)
.manualChanges(List.of(ManualChange.builder()
.manualRedactionType(ManualRedactionType.ADD_LOCALLY)
.requestedDate(manualRedactionEntry.getRequestDate())
.processedDate(null)
.userId(manualRedactionEntry.getUser())
.propertyChanges(Map.of("value", manualRedactionEntry.getValue()))
.build()))
.engines(new HashSet<>())
.reference(new HashSet<>())
.importedRedactionIntersections(new HashSet<>())
.build());
});
}
private void mergeIdsToRemove(Set<IdRemoval> idRemovals, EntityLog entityLog) {
idRemovals.forEach(idRemoval -> {
var entity = entityLog.getEntityLogEntry().stream().filter(entityLogEntry -> entityLogEntry.getId().equals(idRemoval.getAnnotationId())).findAny();
if (entity.isPresent()) {
entity.get().setState(EntryState.IGNORED);
addChanges(entity.get().getChanges(), ChangeType.REMOVED, entityLog.getAnalysisNumber());
entity.get().getManualChanges().add(ManualChange.builder()
.manualRedactionType(ManualRedactionType.REMOVE_LOCALLY)
.requestedDate(idRemoval.getRequestDate())
.processedDate(null)
.userId(idRemoval.getUser()).build());
}
});
}
private void mergeResizeRedactions(Set<ManualResizeRedaction> manualResizeRedactions, EntityLog entityLog) {
manualResizeRedactions.forEach(manualResizeRedaction -> {
var entity = entityLog.getEntityLogEntry().stream().filter(entityLogEntry -> entityLogEntry.getId().equals(manualResizeRedaction.getAnnotationId())).findAny();
if (entity.isPresent()) {
var newPosition = manualResizeRedaction.getPositions().get(0);
entity.get().setPositions(List.of(new Position(
newPosition.getTopLeftX(),
newPosition.getTopLeftY(),
newPosition.getWidth(),
newPosition.getHeight(),
newPosition.getPage())));
addChanges(entity.get().getChanges(), ChangeType.CHANGED, entityLog.getAnalysisNumber());
entity.get().getManualChanges().add(ManualChange.builder()
.manualRedactionType(ManualRedactionType.RESIZE)
.requestedDate(manualResizeRedaction.getRequestDate())
.processedDate(null)
.propertyChanges(Map.of("value", manualResizeRedaction.getValue()))
.userId(manualResizeRedaction.getUser()).build());
}
});
}
private void mergeLegalBasisChanges(Set<ManualLegalBasisChange> manualLegalBasisChanges, EntityLog entityLog) {
manualLegalBasisChanges.forEach(manualLegalBasisChange -> {
var entity = entityLog.getEntityLogEntry().stream().filter(entityLogEntry -> entityLogEntry.getId().equals(manualLegalBasisChange.getAnnotationId())).findAny();
if (entity.isPresent()) {
entity.get().setLegalBasis(manualLegalBasisChange.getLegalBasis());
entity.get().setSection(manualLegalBasisChange.getSection());
entity.get().setValue(manualLegalBasisChange.getValue());
addChanges(entity.get().getChanges(), ChangeType.CHANGED, entityLog.getAnalysisNumber());
entity.get().getManualChanges().add(ManualChange.builder()
.manualRedactionType(ManualRedactionType.LEGAL_BASIS_CHANGE)
.requestedDate(manualLegalBasisChange.getRequestDate())
.processedDate(null)
.propertyChanges(Map.of("value", manualLegalBasisChange.getValue(),
"section", manualLegalBasisChange.getSection(),
"legalBasis", manualLegalBasisChange.getLegalBasis()))
.userId(manualLegalBasisChange.getUser())
.build());
}
});
}
private void mergeRecategorizations(Set<ManualRecategorization> recategorizations, EntityLog entityLog) {
recategorizations.forEach(recategorization -> {
var entity = entityLog.getEntityLogEntry().stream().filter(entityLogEntry -> entityLogEntry.getId().equals(recategorization.getAnnotationId())).findAny();
if (entity.isPresent()) {
entity.get().setType(recategorization.getType());
addChanges(entity.get().getChanges(), ChangeType.CHANGED, entityLog.getAnalysisNumber());
entity.get().getManualChanges().add(ManualChange.builder()
.manualRedactionType(ManualRedactionType.RECATEGORIZE)
.requestedDate(recategorization.getRequestDate())
.processedDate(recategorization.getProcessedDate())
.userId(recategorization.getUser())
.propertyChanges(Map.of("type", recategorization.getType()))
.build());
}
});
}
private void mergeForceRedactions(Set<ManualForceRedaction> forceRedactions, EntityLog entityLog) {
forceRedactions.forEach(forceRedaction -> {
var entity = entityLog.getEntityLogEntry().stream().filter(entityLogEntry -> entityLogEntry.getId().equals(forceRedaction.getAnnotationId())).findAny();
if (entity.isPresent()) {
entity.get().setLegalBasis(forceRedaction.getLegalBasis());
entity.get().setState(EntryState.APPLIED);
addChanges(entity.get().getChanges(), ChangeType.CHANGED, entityLog.getAnalysisNumber());
entity.get().getManualChanges().add(ManualChange.builder()
.manualRedactionType(ManualRedactionType.FORCE_REDACT)
.requestedDate(forceRedaction.getRequestDate())
.processedDate(forceRedaction.getProcessedDate())
.userId(forceRedaction.getUser())
.propertyChanges(Map.of("legalBasis", forceRedaction.getLegalBasis()))
.build());
}
});
}
private void addChanges(List<Change> changes, ChangeType changeType, int analysisNumber) {
if (!changes.isEmpty()) {
changes.add(Change.builder()
.analysisNumber(analysisNumber + 1)
.dateTime(OffsetDateTime.now())
.type(changeType)
.build());
} else {
changes.add(Change.builder().analysisNumber(analysisNumber).dateTime(OffsetDateTime.now()).type(changeType).build());
}
}
private boolean isHint(String type, String dossierTemplateId) {
String typeId = toTypeId(type, dossierTemplateId);
TypeEntity typeEntity = dictionaryPersistenceService.getType(typeId);
if (typeEntity == null) {
throw new NotFoundException("TypeEntity could not be found for typeId: " + typeId);
}
return typeEntity.isHint();
}
}

View File

@ -0,0 +1,280 @@
package com.iqser.red.service.peristence.v1.server.integration.tests;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.testcontainers.shaded.com.google.common.collect.Lists;
import com.iqser.red.service.persistence.management.v1.processor.client.redactionservice.UnprocessedManualEntityClient;
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.TypeEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierEntity;
import com.iqser.red.service.persistence.management.v1.processor.service.CommentService;
import com.iqser.red.service.persistence.management.v1.processor.service.DossierService;
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.FileStatusService;
import com.iqser.red.service.persistence.management.v1.processor.service.manualredactions.ManualRedactionProviderService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DictionaryPersistenceService;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.ChangeType;
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;
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.ManualRedactionType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Position;
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.IdRemoval;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualForceRedaction;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualLegalBasisChange;
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.annotations.entitymapped.ManualResizeRedaction;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileModel;
import com.iqser.red.service.redaction.v1.model.UnprocessedManualEntity;
@ExtendWith(SpringExtension.class)
public class EntityLogTest {
@MockBean
private FileStatusService fileStatusService;
@MockBean
private FileManagementStorageService fileManagementStorageService;
@MockBean
private DossierService dossierService;
@MockBean
private CommentService commentService;
@MockBean
private ManualRedactionProviderService manualRedactionProviderService;
@MockBean
private UnprocessedManualEntityClient unprocessedManualEntityClient;
@MockBean
private DictionaryPersistenceService dictionaryPersistenceService;
private EntityLogService entityLogService;
@BeforeEach
public void setUp() {
entityLogService = new EntityLogService(fileManagementStorageService, fileStatusService, manualRedactionProviderService, unprocessedManualEntityClient, dossierService, commentService, dictionaryPersistenceService);
}
@Test
public void testGetEntityLogWithUnprocessedRedactions() {
String fileId = "fileId";
String dossierId = "dossierId";
String dossierTemplateId = "dossierTemplateId";
String entryToAddId = UUID.randomUUID().toString();
String entryToRemoveId = UUID.randomUUID().toString();
String entryToResizeId = UUID.randomUUID().toString();
String entryLegalBasisId = UUID.randomUUID().toString();
String forceRedactionId = UUID.randomUUID().toString();
ManualRedactions manualRedactions = provideManualRedactions(entryToAddId, entryToRemoveId, entryToResizeId, entryLegalBasisId, forceRedactionId, fileId);
UnprocessedManualEntity unprocessedManualEntity = UnprocessedManualEntity.builder()
.textBefore("textBefore")
.textAfter("textAfter")
.containingNodeId(List.of(0, 0))
.endOffset(10)
.startOffset(1)
.annotationId(entryToAddId)
.closestHeadline("closestHeadline")
.color(new float[]{0,0,0})
.build();
var entityLog = provideEntityLog(entryToRemoveId, entryToResizeId, entryLegalBasisId, forceRedactionId);
when(manualRedactionProviderService.getManualRedactions(fileId, true)).thenReturn(manualRedactions);
when(unprocessedManualEntityClient.mergeUnprocessedManualEntities(any(), any(), any(), any())).thenReturn(List.of(unprocessedManualEntity));
when(fileStatusService.getStatus(fileId)).thenReturn(FileModel.builder()
.excluded(false)
.dossierStatusId(dossierTemplateId)
.id(fileId)
.build());
when(fileManagementStorageService.getEntityLog(dossierId, fileId)).thenReturn(entityLog);
when(dossierService.getDossierById(dossierId)).thenReturn(DossierEntity.builder()
.dossierTemplateId(dossierTemplateId)
.build());
when(dictionaryPersistenceService.getType(anyString())).thenReturn(TypeEntity.builder().isHint(false).build());
EntityLog response = entityLogService.getEntityLog(dossierId, fileId, null, true);
assertNotNull(response);
assertFalse(response.getEntityLogEntry().isEmpty());
var optionalEntityLogEntry = response.getEntityLogEntry().stream().filter(entityLogEntry1 -> entityLogEntry1.getId().equals(entryToAddId)).findFirst();
assertTrue(optionalEntityLogEntry.isPresent());
var entityLogEntry = optionalEntityLogEntry.get();
assertEquals(entityLogEntry.getType(), "manual");
assertEquals(entityLogEntry.getEntryType(), EntryType.ENTITY);
assertNull(entityLogEntry.getState());
assertEquals(entityLogEntry.getValue(), "Test");
assertEquals(entityLogEntry.getReason(), "Reason");
assertEquals(entityLogEntry.getTextAfter(), "textAfter");
assertEquals(entityLogEntry.getTextBefore(), "textBefore");
assertEquals(entityLogEntry.getStartOffset(), 1);
assertEquals(entityLogEntry.getEndOffset(), 10);
assertEquals(entityLogEntry.getManualChanges().get(0).getManualRedactionType(), ManualRedactionType.ADD_LOCALLY);
var optionalRemoveEntryLogEntry = response.getEntityLogEntry().stream().filter(entityLogEntry1 -> entityLogEntry1.getId().equals(entryToRemoveId)).findFirst();
assertTrue(optionalRemoveEntryLogEntry.isPresent());
var removeEntryLogEntry = optionalRemoveEntryLogEntry.get();
assertEquals(removeEntryLogEntry.getEntryType(), EntryType.ENTITY);
assertEquals(removeEntryLogEntry.getState(), EntryState.IGNORED);
assertEquals(removeEntryLogEntry.getManualChanges().get(0).getManualRedactionType(), ManualRedactionType.REMOVE_LOCALLY);
assertEquals(removeEntryLogEntry.getChanges().get(0).getType(), ChangeType.REMOVED);
var optionalResizeEntryLogEntry = response.getEntityLogEntry().stream().filter(entityLogEntry1 -> entityLogEntry1.getId().equals(entryToResizeId)).findFirst();
assertTrue(optionalResizeEntryLogEntry.isPresent());
var resizeEntryLogEntry = optionalResizeEntryLogEntry.get();
assertEquals(resizeEntryLogEntry.getPositions().get(0).getRectangle()[0], 2);
assertEquals(resizeEntryLogEntry.getPositions().get(0).getRectangle()[1], 2);
assertEquals(resizeEntryLogEntry.getPositions().get(0).getRectangle()[2], 2);
assertEquals(resizeEntryLogEntry.getPositions().get(0).getRectangle()[3], 2);
assertEquals(resizeEntryLogEntry.getPositions().get(0).getPageNumber(), 1);
assertEquals(resizeEntryLogEntry.getEntryType(), EntryType.ENTITY);
assertEquals(resizeEntryLogEntry.getState(), EntryState.APPLIED);
assertEquals(resizeEntryLogEntry.getManualChanges().get(0).getManualRedactionType(), ManualRedactionType.RESIZE);
assertEquals(resizeEntryLogEntry.getChanges().get(0).getType(), ChangeType.CHANGED);
var optionalLegalBasisEntryLogEntry = response.getEntityLogEntry().stream().filter(entityLogEntry1 -> entityLogEntry1.getId().equals(entryLegalBasisId)).findFirst();
assertTrue(optionalLegalBasisEntryLogEntry.isPresent());
var legalBasisEntryLogEntry = optionalLegalBasisEntryLogEntry.get();
assertEquals(legalBasisEntryLogEntry.getLegalBasis(), "New legal basis");
assertEquals(legalBasisEntryLogEntry.getEntryType(), EntryType.ENTITY);
assertEquals(legalBasisEntryLogEntry.getState(), EntryState.APPLIED);
assertEquals(legalBasisEntryLogEntry.getManualChanges().get(0).getManualRedactionType(), ManualRedactionType.LEGAL_BASIS_CHANGE);
assertEquals(legalBasisEntryLogEntry.getChanges().get(0).getType(), ChangeType.CHANGED);
var optionalForceRedactionEntryLogEntry = response.getEntityLogEntry().stream().filter(entityLogEntry1 -> entityLogEntry1.getId().equals(forceRedactionId)).findFirst();
assertTrue(optionalForceRedactionEntryLogEntry.isPresent());
var forceRedactionEntryLogEntry = optionalForceRedactionEntryLogEntry.get();
assertEquals(forceRedactionEntryLogEntry.getLegalBasis(), "Force");
assertEquals(forceRedactionEntryLogEntry.getEntryType(), EntryType.ENTITY);
assertEquals(forceRedactionEntryLogEntry.getState(), EntryState.APPLIED);
assertEquals(forceRedactionEntryLogEntry.getManualChanges().get(0).getManualRedactionType(), ManualRedactionType.FORCE_REDACT);
assertEquals(forceRedactionEntryLogEntry.getChanges().get(0).getType(), ChangeType.CHANGED);
}
private EntityLog provideEntityLog(String entryToRemoveId, String entryToResizeId, String entryLegalBasisId, String forceRedactionId) {
List<Position> positions = new ArrayList<>();
positions.add(new Position(1, 1, 1, 1, 1));
return new EntityLog(1,
1,
Lists.newArrayList(EntityLogEntry.builder()
.id(entryToRemoveId)
.type("manual")
.value("Luke Skywalker")
.entryType(EntryType.ENTITY)
.state(EntryState.APPLIED)
.dictionaryEntry(true)
.build(),
EntityLogEntry.builder()
.id(entryToResizeId)
.type("manual")
.value("Darth Vader")
.entryType(EntryType.ENTITY)
.state(EntryState.APPLIED)
.dictionaryEntry(true)
.positions(positions)
.build(),
EntityLogEntry.builder()
.id(entryLegalBasisId)
.type("manual")
.value("Darth Luke")
.entryType(EntryType.ENTITY)
.state(EntryState.APPLIED)
.dictionaryEntry(true)
.positions(positions)
.build(),
EntityLogEntry.builder()
.id(forceRedactionId)
.type("manual")
.value("Darth Luke")
.entryType(EntryType.ENTITY)
.state(EntryState.APPLIED)
.dictionaryEntry(true)
.positions(positions)
.build()),
null,
0,
0,
0,
0);
}
private ManualRedactions provideManualRedactions(String entryToAddId, String entryToRemoveId, String entryToResizeId, String entryLegalBasisId, String forceRedactionId, String fileId) {
List<Rectangle> positions = new ArrayList<>();
positions.add(new Rectangle(2, 2, 2, 2, 1));
return ManualRedactions.builder()
.entriesToAdd(Set.of(
ManualRedactionEntry.builder()
.positions(List.of(new Rectangle(1f, 2f, 3f, 4f, 1)))
.annotationId(entryToAddId)
.value("Test")
.reason("Reason")
.addToDictionary(false)
.addToDossierDictionary(false)
.fileId(fileId)
.requestDate(OffsetDateTime.now())
.type("manual")
.build()))
.idsToRemove(Set.of(
IdRemoval.builder()
.annotationId(entryToRemoveId)
.build()
))
.resizeRedactions(Set.of(
ManualResizeRedaction.builder()
.fileId(fileId)
.value("Random")
.annotationId(entryToResizeId)
.positions(positions)
.build()
))
.legalBasisChanges(Set.of(
ManualLegalBasisChange.builder()
.annotationId(entryLegalBasisId)
.value("Random")
.legalBasis("New legal basis")
.section("Section")
.build()
))
.forceRedactions(Set.of(
ManualForceRedaction.builder()
.annotationId(forceRedactionId)
.fileId(fileId)
.legalBasis("Force")
.build()
))
.build();
}
}

View File

@ -3,6 +3,5 @@ package com.iqser.red.service.persistence.service.v1.api.shared.model;
public enum MessageType {
ANALYSE,
REANALYSE,
SURROUNDING_TEXT
REANALYSE
}

View File

@ -31,7 +31,7 @@
</modules>
<properties>
<redaction-service.version>4.126.0</redaction-service.version>
<redaction-service.version>4.157.0</redaction-service.version>
<search-service.version>2.71.0</search-service.version>
<pdftron-redaction-service.version>4.29.0</pdftron-redaction-service.version>
<redaction-report-service.version>4.13.0</redaction-report-service.version>