Merge branch 'RED-8998-fix' into 'master'
RED-8998 - Return merged entities or pending entries for manual changes. Closes RED-8998 See merge request redactmanager/persistence-service!473
This commit is contained in:
commit
c1dda3cd26
@ -22,6 +22,7 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
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.BadRequestException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.manualredactions.PendingDictionaryEntryFactory;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DictionaryPersistenceService;
|
||||
@ -45,6 +46,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations
|
||||
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.type.DictionaryEntryType;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.mongo.service.EntityLogMongoService;
|
||||
|
||||
import io.micrometer.observation.annotation.Observed;
|
||||
import lombok.AccessLevel;
|
||||
@ -60,47 +62,76 @@ public class EntityLogMergeService {
|
||||
|
||||
DictionaryPersistenceService dictionaryPersistenceService;
|
||||
PendingDictionaryEntryFactory pendingDictionaryEntryFactory;
|
||||
EntityLogMongoService entityLogMongoService;
|
||||
|
||||
|
||||
@Observed(name = "EntityLogMergeService", contextualName = "merge-entity-log")
|
||||
public EntityLog mergeEntityLog(ManualRedactions unprocessedManualRedactions, EntityLog entityLog, DossierEntity dossier) {
|
||||
|
||||
log.debug("Merging EntityLog");
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
final int analysisNumber = entityLog.getAnalysisNumber();
|
||||
|
||||
Map<String, List<BaseAnnotation>> allManualChanges = unprocessedManualRedactions.buildAll()
|
||||
.stream()
|
||||
.collect(Collectors.groupingBy(BaseAnnotation::getAnnotationId));
|
||||
Map<String, List<BaseAnnotation>> allManualChanges = groupManualChanges(unprocessedManualRedactions);
|
||||
|
||||
List<EntityLogEntry> entityLogEntries = new LinkedList<>(entityLog.getEntityLogEntry());
|
||||
|
||||
Map<String, EntityLogEntry> addedLocalManualEntries = buildUnprocessedLocalManualRedactions(unprocessedManualRedactions, entityLog, dossier)//
|
||||
merge(unprocessedManualRedactions, entityLog.getEntityLogEntry(), dossier, analysisNumber, entityLogEntries, allManualChanges);
|
||||
|
||||
entityLog.setEntityLogEntry(entityLogEntries);
|
||||
return entityLog;
|
||||
}
|
||||
|
||||
|
||||
@Observed(name = "EntityLogMergeService", contextualName = "merge-entity-log-entries")
|
||||
public List<EntityLogEntry> mergeEntityLogEntries(ManualRedactions unprocessedManualRedactions, List<String> entityLogEntryIds, DossierEntity dossier, String fileId) {
|
||||
|
||||
final int analysisNumber = entityLogMongoService.findLatestAnalysisNumber(dossier.getId(), fileId)
|
||||
.orElseThrow(() -> new BadRequestException("Can't load analysis number"));
|
||||
|
||||
Map<String, List<BaseAnnotation>> allManualChanges = groupManualChanges(unprocessedManualRedactions);
|
||||
|
||||
List<EntityLogEntry> entityLogEntries = entityLogMongoService.findEntityLogEntriesByIds(dossier.getId(), fileId, entityLogEntryIds);
|
||||
|
||||
merge(unprocessedManualRedactions, entityLogEntries, dossier, analysisNumber, entityLogEntries, allManualChanges);
|
||||
|
||||
return entityLogEntries;
|
||||
}
|
||||
|
||||
|
||||
private void merge(ManualRedactions unprocessedManualRedactions,
|
||||
List<EntityLogEntry> entityLog,
|
||||
DossierEntity dossier,
|
||||
int analysisNumber,
|
||||
List<EntityLogEntry> entityLogEntries,
|
||||
Map<String, List<BaseAnnotation>> allManualChanges) {
|
||||
|
||||
Map<String, EntityLogEntry> addedLocalManualEntries = buildUnprocessedLocalManualRedactions(unprocessedManualRedactions, entityLog, dossier, analysisNumber)//
|
||||
.collect(Collectors.toMap(EntityLogEntry::getId, Function.identity()));
|
||||
|
||||
entityLogEntries.addAll(addedLocalManualEntries.values());
|
||||
|
||||
buildPendingDictionaryChanges(unprocessedManualRedactions).forEach(entityLogEntries::add);
|
||||
processEntityLogEntries(dossier, entityLogEntries, addedLocalManualEntries, analysisNumber, allManualChanges);
|
||||
}
|
||||
|
||||
|
||||
private void processEntityLogEntries(DossierEntity dossier,
|
||||
List<EntityLogEntry> entityLogEntries,
|
||||
Map<String, EntityLogEntry> addedLocalManualEntries,
|
||||
int analysisNumber,
|
||||
Map<String, List<BaseAnnotation>> allManualChanges) {
|
||||
|
||||
int numberOfAddedPendingEntries = 0; // since list is dynamically growing we need to keep track of the number of added pending entries to ignore them in the loop
|
||||
for (int i = 0; i + numberOfAddedPendingEntries < entityLogEntries.size(); i++) {
|
||||
|
||||
EntityLogEntry entityLogEntry = entityLogEntries.get(i + numberOfAddedPendingEntries);
|
||||
|
||||
if (isDuplicatedByAny(entityLogEntry, addedLocalManualEntries)) {
|
||||
|
||||
mergeOriginalAndLocallyAddedEntries(addedLocalManualEntries, entityLogEntry, analysisNumber);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (allManualChanges.containsKey(entityLogEntry.getId())) {
|
||||
|
||||
List<EntityLogEntry> pendingImageRecategorizations = mergeLocalManualChangesAndReturnNonMergeableAsPending(dossier,
|
||||
allManualChanges,
|
||||
entityLogEntry,
|
||||
analysisNumber);
|
||||
|
||||
List<EntityLogEntry> pendingDictionaryEntries = buildPendingDictionaryEntries(allManualChanges, entityLogEntry);
|
||||
|
||||
// insert pending entries directly after the associated entry to enable performant linking in UI
|
||||
@ -108,15 +139,16 @@ public class EntityLogMergeService {
|
||||
numberOfAddedPendingEntries++;
|
||||
entityLogEntries.add(i + numberOfAddedPendingEntries, pendingDictionaryEntry);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
entityLog.setEntityLogEntry(entityLogEntries);
|
||||
|
||||
log.debug("EntityLog merged successfully in {} ms.", System.currentTimeMillis() - start);
|
||||
return entityLog;
|
||||
private Map<String, List<BaseAnnotation>> groupManualChanges(ManualRedactions unprocessedManualRedactions) {
|
||||
|
||||
return unprocessedManualRedactions.buildAll()
|
||||
.stream()
|
||||
.collect(Collectors.groupingBy(BaseAnnotation::getAnnotationId));
|
||||
}
|
||||
|
||||
|
||||
@ -149,12 +181,15 @@ public class EntityLogMergeService {
|
||||
}
|
||||
|
||||
|
||||
private Stream<EntityLogEntry> buildUnprocessedLocalManualRedactions(ManualRedactions unprocessedManualRedactions, EntityLog entityLog, DossierEntity dossier) {
|
||||
private Stream<EntityLogEntry> buildUnprocessedLocalManualRedactions(ManualRedactions unprocessedManualRedactions,
|
||||
List<EntityLogEntry> entityLogEntries,
|
||||
DossierEntity dossier,
|
||||
int analysisNumber) {
|
||||
|
||||
return unprocessedManualRedactions.getEntriesToAdd()
|
||||
.stream()
|
||||
.filter(ManualRedactionEntry::isLocal)
|
||||
.map(manualRedactionEntry -> mergeManualRedactionEntries(manualRedactionEntry, entityLog, dossier))
|
||||
.map(manualRedactionEntry -> mergeManualRedactionEntries(manualRedactionEntry, entityLogEntries, dossier, analysisNumber))
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get);
|
||||
}
|
||||
@ -217,27 +252,27 @@ public class EntityLogMergeService {
|
||||
}
|
||||
|
||||
|
||||
private Optional<EntityLogEntry> mergeManualRedactionEntries(ManualRedactionEntry manualRedactionEntry, EntityLog entityLog, DossierEntity dossier) {
|
||||
private Optional<EntityLogEntry> mergeManualRedactionEntries(ManualRedactionEntry manualRedactionEntry,
|
||||
List<EntityLogEntry> entityLogEntries,
|
||||
DossierEntity dossier,
|
||||
int analysisNumber) {
|
||||
|
||||
if (manualRedactionEntry.getPositions() == null || manualRedactionEntry.getPositions().isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
if (isFalsePositive(manualRedactionEntry)) {
|
||||
var matchingEntities = entityLog.getEntityLogEntry()
|
||||
.stream()
|
||||
var matchingEntities = entityLogEntries.stream()
|
||||
.filter(entityLogEntry -> equalPosition(manualRedactionEntry.getPositions()
|
||||
.get(0),
|
||||
entityLogEntry.getPositions()
|
||||
.get(0)))
|
||||
.toList();
|
||||
matchingEntities.forEach(matchingEntity -> mergeFalsePositive(entityLog, matchingEntity));
|
||||
matchingEntities.forEach(matchingEntity -> mergeFalsePositive(analysisNumber, matchingEntity));
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
EntityLogEntry entityLogEntry = buildEntityLogEntry(manualRedactionEntry, entityLog.getAnalysisNumber(), dossier);
|
||||
entityLog.getEntityLogEntry().add(entityLogEntry);
|
||||
return Optional.of(entityLogEntry);
|
||||
return Optional.of(buildEntityLogEntry(manualRedactionEntry, analysisNumber, dossier));
|
||||
}
|
||||
|
||||
|
||||
@ -288,11 +323,11 @@ public class EntityLogMergeService {
|
||||
}
|
||||
|
||||
|
||||
private void mergeFalsePositive(EntityLog entityLog, EntityLogEntry existingEntry) {
|
||||
private void mergeFalsePositive(int analysisNumber, EntityLogEntry existingEntry) {
|
||||
|
||||
existingEntry.setState(EntryState.REMOVED);
|
||||
List<Change> falsePositiveChanges = new ArrayList<>();
|
||||
falsePositiveChanges.add(Change.builder().analysisNumber(entityLog.getAnalysisNumber()).dateTime(OffsetDateTime.now()).type(ChangeType.REMOVED).build());
|
||||
falsePositiveChanges.add(Change.builder().analysisNumber(analysisNumber).dateTime(OffsetDateTime.now()).type(ChangeType.REMOVED).build());
|
||||
if (existingEntry.getChanges() != null && !existingEntry.getChanges().isEmpty()) {
|
||||
existingEntry.getChanges().addAll(falsePositiveChanges);
|
||||
} else {
|
||||
@ -342,13 +377,13 @@ public class EntityLogMergeService {
|
||||
|
||||
public EntityLogEntry mergeRecategorization(ManualRecategorization recategorization, EntityLogEntry entityLogEntry, DossierEntity dossier, int analysisNumber) {
|
||||
|
||||
if ((recategorization.getType() != null && !Objects.equals(recategorization.getType(), entityLogEntry.getType()) && Strings.isNullOrEmpty(recategorization.getLegalBasis()))//
|
||||
if ((recategorization.getType() != null && !Objects.equals(recategorization.getType(), entityLogEntry.getType()) && Strings.isNullOrEmpty(recategorization.getLegalBasis()))
|
||||
//
|
||||
&& (entityLogEntry.getEntryType().equals(EntryType.IMAGE) || entityLogEntry.getEntryType().equals(EntryType.IMAGE_HINT))) {
|
||||
|
||||
return pendingDictionaryEntryFactory.buildPendingImageRecategorizationEntry(recategorization, entityLogEntry);
|
||||
}
|
||||
|
||||
|
||||
entityLogEntry.getEngines().add(Engine.MANUAL);
|
||||
|
||||
if (recategorization.getType() != null && !recategorization.getType().equals(entityLogEntry.getType())) {
|
||||
|
||||
@ -0,0 +1,50 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
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.model.ManualChangesQueryOptions;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.manualredactions.ManualRedactionProviderService;
|
||||
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.annotations.ManualRedactions;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.mongo.service.EntityLogMongoService;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class EntityLogMongoWrapperService {
|
||||
|
||||
private final DossierService dossierService;
|
||||
private final EntityLogMongoService entityLogMongoService;
|
||||
private final ManualRedactionProviderService manualRedactionProviderService;
|
||||
private final EntityLogMergeService entityLogMergeService;
|
||||
|
||||
|
||||
public EntityLogEntry getEntityLogEntryById(String dossierId, String fileId, String annotationId) {
|
||||
|
||||
return entityLogMongoService.findEntityLogEntryById(dossierId, fileId, annotationId)
|
||||
.orElseThrow(() -> new NotFoundException(getEntityLogNotEntryFoundErrorMessage(annotationId)));
|
||||
}
|
||||
|
||||
|
||||
public List<EntityLogEntry> getEntityLogEntriesByIds(String dossierId, String fileId, List<String> ids, boolean includeUnprocessed) {
|
||||
|
||||
List<EntityLogEntry> entityLogEntries = entityLogMongoService.findEntityLogEntriesByIds(dossierId, fileId, ids);
|
||||
if (includeUnprocessed) {
|
||||
DossierEntity dossier = dossierService.getDossierById(dossierId);
|
||||
ManualRedactions unprocessedManualRedactions = manualRedactionProviderService.getManualRedactions(fileId, ManualChangesQueryOptions.unprocessedOnly());
|
||||
entityLogEntries = entityLogMergeService.mergeEntityLogEntries(unprocessedManualRedactions, entityLogEntries.stream().map(EntityLogEntry::getId).toList(), dossier, fileId);
|
||||
}
|
||||
return entityLogEntries;
|
||||
}
|
||||
|
||||
|
||||
private static String getEntityLogNotEntryFoundErrorMessage(String annotationId) {
|
||||
|
||||
return String.format("EntityLogEntry does not exist for annotationId ID \"%s\"!", annotationId);
|
||||
}
|
||||
}
|
||||
@ -5,7 +5,6 @@ import static com.iqser.red.service.persistence.management.v1.processor.utils.Ty
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@ -14,6 +13,8 @@ import org.springframework.stereotype.Service;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRecategorizationEntity;
|
||||
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.EntityLogMongoWrapperService;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.RequestEntryPair;
|
||||
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.EntityLog;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry;
|
||||
@ -23,7 +24,6 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.LegalBasisChangeRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.RecategorizationRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.RemoveRedactionRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.RequestEntryPair;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ResizeRedactionRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.Dossier;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type.DictionaryEntryType;
|
||||
@ -33,7 +33,6 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.Lega
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.RecategorizationRequestModel;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.RemoveRedactionRequestModel;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.ResizeRedactionRequestModel;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.mongo.service.EntityLogMongoService;
|
||||
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
|
||||
|
||||
import io.micrometer.observation.annotation.Observed;
|
||||
@ -46,7 +45,7 @@ import lombok.experimental.FieldDefaults;
|
||||
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
|
||||
public class ManualRedactionMapper {
|
||||
|
||||
EntityLogMongoService entityLogMongoService;
|
||||
EntityLogMongoWrapperService entityLogMongoWrapperService;
|
||||
|
||||
|
||||
@Observed(name = "ManualRedactionMapper", contextualName = "to-add-redaction-request-list")
|
||||
@ -81,16 +80,21 @@ public class ManualRedactionMapper {
|
||||
|
||||
|
||||
public List<RequestEntryPair<RemoveRedactionRequest>> toRemoveRedactionRequestList(String dossierId,
|
||||
String fileId,
|
||||
String dossierTemplateId,
|
||||
Set<RemoveRedactionRequestModel> removeRedactionRequests,
|
||||
boolean includeUnprocessed) {
|
||||
String fileId,
|
||||
String dossierTemplateId,
|
||||
Set<RemoveRedactionRequestModel> removeRedactionRequests,
|
||||
boolean includeUnprocessed) {
|
||||
|
||||
List<EntityLogEntry> entityLogEntries = entityLogMongoWrapperService.getEntityLogEntriesByIds(dossierId,
|
||||
fileId,
|
||||
removeRedactionRequests.stream()
|
||||
.map(RemoveRedactionRequestModel::getAnnotationId)
|
||||
.toList(),
|
||||
includeUnprocessed);
|
||||
List<RequestEntryPair<RemoveRedactionRequest>> requests = new ArrayList<>();
|
||||
for (var removeRedactionRequest : removeRedactionRequests) {
|
||||
|
||||
Optional<EntityLogEntry> optionalEntityLogEntry = entityLogMongoService.findEntityLogEntryById(dossierId, fileId, removeRedactionRequest.getAnnotationId());
|
||||
optionalEntityLogEntry.ifPresent(entityLogEntry -> {
|
||||
entityLogEntries.forEach(entityLogEntry -> {
|
||||
var request = RemoveRedactionRequest.builder()
|
||||
.annotationId(removeRedactionRequest.getAnnotationId())
|
||||
.user(KeycloakSecurity.getUserId())
|
||||
@ -106,10 +110,7 @@ public class ManualRedactionMapper {
|
||||
request.comment(removeRedactionRequest.getComment());
|
||||
}
|
||||
|
||||
requests.add(RequestEntryPair.<RemoveRedactionRequest>builder()
|
||||
.request(request.build())
|
||||
.entityLogEntry(entityLogEntry)
|
||||
.build());
|
||||
requests.add(RequestEntryPair.<RemoveRedactionRequest>builder().request(request.build()).entityLogEntry(entityLogEntry).build());
|
||||
});
|
||||
}
|
||||
|
||||
@ -118,32 +119,27 @@ public class ManualRedactionMapper {
|
||||
|
||||
|
||||
public List<RequestEntryPair<ForceRedactionRequest>> toForceRedactionRequestList(String dossierId,
|
||||
String fileId,
|
||||
Set<ForceRedactionRequestModel> forceRedactionRequests,
|
||||
Consumer<EntityLogEntry> manualRedactionEntryConsumer) {
|
||||
String fileId,
|
||||
Set<ForceRedactionRequestModel> forceRedactionRequests,
|
||||
Consumer<EntityLogEntry> manualRedactionEntryConsumer) {
|
||||
|
||||
List<RequestEntryPair<ForceRedactionRequest>> requests = new ArrayList<>();
|
||||
|
||||
for (ForceRedactionRequestModel forceRedactionRequestModel : forceRedactionRequests) {
|
||||
|
||||
Optional<EntityLogEntry> optionalEntityLogEntry = entityLogMongoService.findEntityLogEntryById(dossierId, fileId, forceRedactionRequestModel.getAnnotationId());
|
||||
optionalEntityLogEntry.ifPresent(entityLogEntry -> {
|
||||
ForceRedactionRequest request = ForceRedactionRequest.builder()
|
||||
.annotationId(forceRedactionRequestModel.getAnnotationId())
|
||||
.user(KeycloakSecurity.getUserId())
|
||||
.legalBasis(forceRedactionRequestModel.getLegalBasis())
|
||||
.comment(forceRedactionRequestModel.getComment())
|
||||
.build();
|
||||
EntityLogEntry entityLogEntry = entityLogMongoWrapperService.getEntityLogEntryById(dossierId, fileId, forceRedactionRequestModel.getAnnotationId());
|
||||
ForceRedactionRequest request = ForceRedactionRequest.builder()
|
||||
.annotationId(forceRedactionRequestModel.getAnnotationId())
|
||||
.user(KeycloakSecurity.getUserId())
|
||||
.legalBasis(forceRedactionRequestModel.getLegalBasis())
|
||||
.comment(forceRedactionRequestModel.getComment())
|
||||
.build();
|
||||
|
||||
if (!entityLogEntry.getEngines().contains(Engine.MANUAL) && entryIsEntityType(entityLogEntry)) {
|
||||
manualRedactionEntryConsumer.accept(entityLogEntry);
|
||||
}
|
||||
if (!entityLogEntry.getEngines().contains(Engine.MANUAL) && entryIsEntityType(entityLogEntry)) {
|
||||
manualRedactionEntryConsumer.accept(entityLogEntry);
|
||||
}
|
||||
|
||||
requests.add(RequestEntryPair.<ForceRedactionRequest>builder()
|
||||
.request(request)
|
||||
.entityLogEntry(entityLogEntry)
|
||||
.build());
|
||||
});
|
||||
requests.add(RequestEntryPair.<ForceRedactionRequest>builder().request(request).entityLogEntry(entityLogEntry).build());
|
||||
}
|
||||
|
||||
return requests;
|
||||
@ -152,34 +148,29 @@ public class ManualRedactionMapper {
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public List<RequestEntryPair<LegalBasisChangeRequest>> toLegalBasisChangeRequestList(String dossierId,
|
||||
String fileId,
|
||||
Set<LegalBasisChangeRequestModel> legalBasisChangeRequests,
|
||||
Consumer<EntityLogEntry> manualRedactionEntryConsumer) {
|
||||
String fileId,
|
||||
Set<LegalBasisChangeRequestModel> legalBasisChangeRequests,
|
||||
Consumer<EntityLogEntry> manualRedactionEntryConsumer) {
|
||||
|
||||
List<RequestEntryPair<LegalBasisChangeRequest>> requests = new ArrayList<>();
|
||||
|
||||
for (LegalBasisChangeRequestModel legalBasisChangeRequest : legalBasisChangeRequests) {
|
||||
|
||||
Optional<EntityLogEntry> optionalEntityLogEntry = entityLogMongoService.findEntityLogEntryById(dossierId, fileId, legalBasisChangeRequest.getAnnotationId());
|
||||
optionalEntityLogEntry.ifPresent(entityLogEntry -> {
|
||||
LegalBasisChangeRequest request = LegalBasisChangeRequest.builder()
|
||||
.annotationId(legalBasisChangeRequest.getAnnotationId())
|
||||
.user(KeycloakSecurity.getUserId())
|
||||
.section(legalBasisChangeRequest.getSection())
|
||||
.legalBasis(legalBasisChangeRequest.getLegalBasis())
|
||||
.comment(legalBasisChangeRequest.getComment())
|
||||
.value(legalBasisChangeRequest.getValue())
|
||||
.build();
|
||||
EntityLogEntry entityLogEntry = entityLogMongoWrapperService.getEntityLogEntryById(dossierId, fileId, legalBasisChangeRequest.getAnnotationId());
|
||||
LegalBasisChangeRequest request = LegalBasisChangeRequest.builder()
|
||||
.annotationId(legalBasisChangeRequest.getAnnotationId())
|
||||
.user(KeycloakSecurity.getUserId())
|
||||
.section(legalBasisChangeRequest.getSection())
|
||||
.legalBasis(legalBasisChangeRequest.getLegalBasis())
|
||||
.comment(legalBasisChangeRequest.getComment())
|
||||
.value(legalBasisChangeRequest.getValue())
|
||||
.build();
|
||||
|
||||
if (!entityLogEntry.getEngines().contains(Engine.MANUAL) && entryIsEntityType(entityLogEntry)) {
|
||||
manualRedactionEntryConsumer.accept(entityLogEntry);
|
||||
}
|
||||
if (!entityLogEntry.getEngines().contains(Engine.MANUAL) && entryIsEntityType(entityLogEntry)) {
|
||||
manualRedactionEntryConsumer.accept(entityLogEntry);
|
||||
}
|
||||
|
||||
requests.add(RequestEntryPair.<LegalBasisChangeRequest>builder()
|
||||
.request(request)
|
||||
.entityLogEntry(entityLogEntry)
|
||||
.build());
|
||||
});
|
||||
requests.add(RequestEntryPair.<LegalBasisChangeRequest>builder().request(request).entityLogEntry(entityLogEntry).build());
|
||||
}
|
||||
|
||||
return requests;
|
||||
@ -187,19 +178,24 @@ public class ManualRedactionMapper {
|
||||
|
||||
|
||||
public List<RequestEntryPair<RecategorizationRequest>> toRecategorizationRequestList(String dossierId,
|
||||
String fileId,
|
||||
String dossierTemplateId,
|
||||
Set<RecategorizationRequestModel> recategorizationRequests,
|
||||
boolean includeUnprocessed,
|
||||
Consumer<EntityLogEntry> manualRedactionEntryConsumer) {
|
||||
String fileId,
|
||||
String dossierTemplateId,
|
||||
Set<RecategorizationRequestModel> recategorizationRequests,
|
||||
boolean includeUnprocessed,
|
||||
Consumer<EntityLogEntry> manualRedactionEntryConsumer) {
|
||||
|
||||
List<EntityLogEntry> entityLogEntries = entityLogMongoWrapperService.getEntityLogEntriesByIds(dossierId,
|
||||
fileId,
|
||||
recategorizationRequests.stream()
|
||||
.map(RecategorizationRequestModel::getAnnotationId)
|
||||
.toList(),
|
||||
includeUnprocessed);
|
||||
|
||||
List<RequestEntryPair<RecategorizationRequest>> requests = new ArrayList<>();
|
||||
|
||||
for (RecategorizationRequestModel recategorizationRequest : recategorizationRequests) {
|
||||
|
||||
Optional<EntityLogEntry> optionalEntityLogEntry = entityLogMongoService.findEntityLogEntryById(dossierId, fileId, recategorizationRequest.getAnnotationId());
|
||||
optionalEntityLogEntry.ifPresent(entityLogEntry -> {
|
||||
|
||||
entityLogEntries.forEach(entityLogEntry -> {
|
||||
String changedValue;
|
||||
String changedTypeId;
|
||||
|
||||
@ -241,10 +237,7 @@ public class ManualRedactionMapper {
|
||||
manualRedactionEntryConsumer.accept(entityLogEntry);
|
||||
}
|
||||
|
||||
requests.add(RequestEntryPair.<RecategorizationRequest>builder()
|
||||
.request(request)
|
||||
.entityLogEntry(entityLogEntry)
|
||||
.build());
|
||||
requests.add(RequestEntryPair.<RecategorizationRequest>builder().request(request).entityLogEntry(entityLogEntry).build());
|
||||
});
|
||||
}
|
||||
|
||||
@ -280,16 +273,23 @@ public class ManualRedactionMapper {
|
||||
|
||||
|
||||
public List<RequestEntryPair<ResizeRedactionRequest>> toResizeRedactionRequestList(String dossierId,
|
||||
String fileId,
|
||||
Set<ResizeRedactionRequestModel> resizeRedactionRequests,
|
||||
Consumer<EntityLogEntry> manualRedactionEntryConsumer) {
|
||||
String fileId,
|
||||
Set<ResizeRedactionRequestModel> resizeRedactionRequests,
|
||||
Consumer<EntityLogEntry> manualRedactionEntryConsumer,
|
||||
boolean includeUnprocessed) {
|
||||
|
||||
List<EntityLogEntry> entityLogEntries = entityLogMongoWrapperService.getEntityLogEntriesByIds(dossierId,
|
||||
fileId,
|
||||
resizeRedactionRequests.stream()
|
||||
.map(ResizeRedactionRequestModel::getAnnotationId)
|
||||
.toList(),
|
||||
includeUnprocessed);
|
||||
|
||||
List<RequestEntryPair<ResizeRedactionRequest>> requests = new ArrayList<>();
|
||||
|
||||
for (ResizeRedactionRequestModel resizeRedactionRequest : resizeRedactionRequests) {
|
||||
|
||||
Optional<EntityLogEntry> optionalEntityLogEntry = entityLogMongoService.findEntityLogEntryById(dossierId, fileId, resizeRedactionRequest.getAnnotationId());
|
||||
optionalEntityLogEntry.ifPresent(entityLogEntry -> {
|
||||
entityLogEntries.forEach(entityLogEntry -> {
|
||||
ResizeRedactionRequest request = ResizeRedactionRequest.builder()
|
||||
.annotationId(resizeRedactionRequest.getAnnotationId())
|
||||
.user(KeycloakSecurity.getUserId())
|
||||
@ -308,11 +308,9 @@ public class ManualRedactionMapper {
|
||||
manualRedactionEntryConsumer.accept(entityLogEntry);
|
||||
}
|
||||
|
||||
requests.add(RequestEntryPair.<ResizeRedactionRequest>builder()
|
||||
.request(request)
|
||||
.entityLogEntry(entityLogEntry)
|
||||
.build());
|
||||
requests.add(RequestEntryPair.<ResizeRedactionRequest>builder().request(request).entityLogEntry(entityLogEntry).build());
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return requests;
|
||||
|
||||
@ -108,6 +108,7 @@ public class ManualRedactionService {
|
||||
ManualRedactionMapper manualRedactionMapper;
|
||||
RabbitTemplate rabbitTemplate;
|
||||
EntityLogMergeService entityLogMergeService;
|
||||
PendingDictionaryEntryFactory pendingDictionaryEntryFactory;
|
||||
|
||||
|
||||
@Transactional
|
||||
@ -138,11 +139,17 @@ public class ManualRedactionService {
|
||||
|
||||
addRedactionPersistenceService.updateModifiedDictionaries(fileId, annotationId, !typeIdsOfModifiedDictionaries.isEmpty(), typeIdsOfModifiedDictionaries);
|
||||
|
||||
EntityLogEntry entityLogEntry = null;
|
||||
EntityLogEntry entityLogEntry;
|
||||
if (!addRedactionRequest.isAddToDictionary() && !addRedactionRequest.isAddToAllDossiers()) {
|
||||
entityLogEntry = entityLogMergeService.buildEntityLogEntry(MagicConverter.convert(manualRedactionEntryEntity, ManualRedactionEntry.class, new ManualRedactionEntryMapper()),
|
||||
entityLogEntry = entityLogMergeService.buildEntityLogEntry(MagicConverter.convert(manualRedactionEntryEntity,
|
||||
ManualRedactionEntry.class,
|
||||
new ManualRedactionEntryMapper()),
|
||||
getAnalysisNumber(dossierId, fileId),
|
||||
dossierEntity);
|
||||
} else {
|
||||
entityLogEntry = pendingDictionaryEntryFactory.buildAddToDictionaryEntry(MagicConverter.convert(manualRedactionEntryEntity,
|
||||
ManualRedactionEntry.class,
|
||||
new ManualRedactionEntryMapper()));
|
||||
}
|
||||
Long commentId = commentService.addCommentAndGetId(fileId, annotationId, addRedactionRequest.getComment(), addRedactionRequest.getUser());
|
||||
response.add(ManualAddResponse.builder().annotationId(annotationId).commentId(commentId).entityLogEntry(entityLogEntry).build());
|
||||
@ -219,6 +226,8 @@ public class ManualRedactionService {
|
||||
|
||||
if (!idRemoval.isRemoveFromAllDossiers() && !idRemoval.isRemoveFromDictionary()) {
|
||||
entityLogMergeService.mergeIdToRemove(MagicConverter.convert(idRemoval, IdRemoval.class), entityLogEntry, getAnalysisNumber(dossierId, fileId));
|
||||
} else {
|
||||
entityLogEntry = pendingDictionaryEntryFactory.buildRemoveFromDictionary(MagicConverter.convert(idRemoval, IdRemoval.class), entityLogEntry);
|
||||
}
|
||||
response.add(ManualAddResponse.builder().annotationId(removeRedactionRequest.getAnnotationId()).commentId(commentId).entityLogEntry(entityLogEntry).build());
|
||||
}
|
||||
@ -339,10 +348,19 @@ public class ManualRedactionService {
|
||||
recategorizationRequest.getUser());
|
||||
|
||||
if (!recategorizationRequest.isAddToAllDossiers() && !recategorizationRequest.isAddToDictionary()) {
|
||||
entityLogMergeService.mergeRecategorization(MagicConverter.convert(recategorizationEntity, ManualRecategorization.class, new ManualRecategorizationMapper()),
|
||||
entityLogEntry,
|
||||
dossierEntity,
|
||||
getAnalysisNumber(dossierId, fileId));
|
||||
var entry = entityLogMergeService.mergeRecategorization(MagicConverter.convert(recategorizationEntity,
|
||||
ManualRecategorization.class,
|
||||
new ManualRecategorizationMapper()),
|
||||
entityLogEntry,
|
||||
dossierEntity,
|
||||
getAnalysisNumber(dossierId, fileId));
|
||||
if (entry != null) {
|
||||
entityLogEntry = entry;
|
||||
}
|
||||
} else {
|
||||
entityLogEntry = pendingDictionaryEntryFactory.buildRecategorizeWithDictionary(MagicConverter.convert(recategorizationEntity,
|
||||
ManualRecategorization.class,
|
||||
new ManualRecategorizationMapper()), entityLogEntry);
|
||||
}
|
||||
response.add(ManualAddResponse.builder().annotationId(recategorizationRequest.getAnnotationId()).commentId(commentId).entityLogEntry(entityLogEntry).build());
|
||||
|
||||
@ -366,7 +384,8 @@ public class ManualRedactionService {
|
||||
List<RequestEntryPair<ResizeRedactionRequest>> requests = manualRedactionMapper.toResizeRedactionRequestList(dossierId,
|
||||
fileId,
|
||||
resizeRedactionRequests,
|
||||
getEntityLogEntryConsumer(fileId));
|
||||
getEntityLogEntryConsumer(fileId),
|
||||
includeUnprocessed);
|
||||
|
||||
for (RequestEntryPair<ResizeRedactionRequest> resizeRedactionRequestRequestEntryPair : requests) {
|
||||
|
||||
@ -392,7 +411,13 @@ public class ManualRedactionService {
|
||||
typeIdsOfModifiedDictionaries);
|
||||
|
||||
if (!resizeRedactionRequest.isAddToAllDossiers() && !resizeRedactionRequest.getUpdateDictionary()) {
|
||||
entityLogMergeService.mergeResizeRedaction(MagicConverter.convert(resizeRedaction, ManualResizeRedaction.class, new ManualResizeRedactionMapper()), entityLogEntry, getAnalysisNumber(dossierId, fileId));
|
||||
entityLogMergeService.mergeResizeRedaction(MagicConverter.convert(resizeRedaction, ManualResizeRedaction.class, new ManualResizeRedactionMapper()),
|
||||
entityLogEntry,
|
||||
getAnalysisNumber(dossierId, fileId));
|
||||
} else {
|
||||
entityLogEntry = pendingDictionaryEntryFactory.buildResizeWithDictionary(MagicConverter.convert(resizeRedaction,
|
||||
ManualResizeRedaction.class,
|
||||
new ManualResizeRedactionMapper()), entityLogEntry);
|
||||
}
|
||||
response.add(ManualAddResponse.builder().annotationId(resizeRedactionRequest.getAnnotationId()).commentId(commentId).entityLogEntry(entityLogEntry).build());
|
||||
}
|
||||
|
||||
@ -171,7 +171,7 @@ public class PendingDictionaryEntryFactory {
|
||||
.propertyChanges(Map.of("type",
|
||||
manualChange.getType(),
|
||||
"legalBasis",
|
||||
manualChange.getLegalBasis(),
|
||||
manualChange.getLegalBasis() == null ? "" : manualChange.getLegalBasis(),
|
||||
"section",
|
||||
manualChange.getSection(),
|
||||
"value",
|
||||
|
||||
@ -56,6 +56,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations
|
||||
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.persistence.service.v1.api.shared.model.dossiertemplate.type.DictionaryEntryType;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.mongo.service.EntityLogMongoService;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
public class EntityLogMergeTest {
|
||||
@ -87,6 +88,9 @@ public class EntityLogMergeTest {
|
||||
@MockBean
|
||||
private FileStatusPersistenceService fileStatusPersistenceService;
|
||||
|
||||
@MockBean
|
||||
private EntityLogMongoService entityLogMongoService;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<AnalyzeRequest> captor;
|
||||
|
||||
@ -96,7 +100,7 @@ public class EntityLogMergeTest {
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
|
||||
entityLogMergeService = new EntityLogMergeService(dictionaryPersistenceService, new PendingDictionaryEntryFactory());
|
||||
entityLogMergeService = new EntityLogMergeService(dictionaryPersistenceService, new PendingDictionaryEntryFactory(), entityLogMongoService);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -367,7 +367,7 @@ public class FileTest extends AbstractPersistenceServerServiceTest {
|
||||
String fileId = file.getId();
|
||||
|
||||
var type = typeProvider.testAndProvideType(dossierTemplate, null, "manual");
|
||||
|
||||
typeProvider.testAndProvideType(dossierTemplate, null, "new-type", false, 2000);
|
||||
var annotationId = "imagine_this_makes_sense";
|
||||
EntityLog entityLog = new EntityLog(1,
|
||||
1,
|
||||
@ -398,6 +398,7 @@ public class FileTest extends AbstractPersistenceServerServiceTest {
|
||||
0,
|
||||
0);
|
||||
|
||||
fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog);
|
||||
when(entityLogService.getEntityLog(any(), any(), anyBoolean())).thenReturn(entityLog);
|
||||
|
||||
assertThat(fileClient.getDossierStatus(dossier.getId()).size()).isEqualTo(1);
|
||||
|
||||
@ -2010,7 +2010,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
|
||||
.annotationId("annotationId")
|
||||
.addToDictionary(true)
|
||||
.addToAllDossiers(true)
|
||||
.legalBasis("")
|
||||
.legalBasis("legalBasis")
|
||||
.section("section")
|
||||
.value("other value")
|
||||
.build();
|
||||
|
||||
@ -53,6 +53,10 @@ public interface EntityLogEntryDocumentRepository extends MongoRepository<Entity
|
||||
Optional<EntityLogEntryDocument> findEntityLogEntryDocumentByEntryId(String entityLogId, String entryId);
|
||||
|
||||
|
||||
@Query(value = "{ 'entityLogId': ?0, 'entryId': { $in: ?1 } }")
|
||||
List<EntityLogEntryDocument> findEntityLogEntryDocumentsByEntryIds(String entityLogId, List<String> entryIds);
|
||||
|
||||
|
||||
@Query(value = "{ 'entityLogId' : ?0}", delete = true)
|
||||
void deleteByEntityLogId(String entityLogId);
|
||||
|
||||
|
||||
@ -53,9 +53,9 @@ public class EntityLogMongoService {
|
||||
EntityLogDocument entityLogDocument = entityLogDocumentRepository.save(mapper.toLogDocument(dossierId, fileId, entityLog));
|
||||
|
||||
entityLogEntryDocumentRepository.saveAll(entityLog.getEntityLogEntry()
|
||||
.stream()
|
||||
.map(entityLogEntry -> mapper.toLogEntryDocument(entityLogDocument.getId(), entityLogEntry))
|
||||
.toList());
|
||||
.stream()
|
||||
.map(entityLogEntry -> mapper.toLogEntryDocument(entityLogDocument.getId(), entityLogEntry))
|
||||
.toList());
|
||||
}
|
||||
|
||||
|
||||
@ -117,6 +117,7 @@ public class EntityLogMongoService {
|
||||
entityLogDocumentRepository.save(entityLogDocument);
|
||||
}
|
||||
|
||||
|
||||
public void saveEntityLogEntries(String dossierId, String fileId, List<EntityLogEntry> entityLogEntries) {
|
||||
|
||||
String entityLogId = mapper.getLogId(dossierId, fileId);
|
||||
@ -134,7 +135,6 @@ public class EntityLogMongoService {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void updateEntityLogEntries(String dossierId, String fileId, List<EntityLogEntry> entityLogEntries) {
|
||||
|
||||
String entityLogId = mapper.getLogId(dossierId, fileId);
|
||||
@ -188,6 +188,15 @@ public class EntityLogMongoService {
|
||||
}
|
||||
|
||||
|
||||
public List<EntityLogEntry> findEntityLogEntriesByIds(String dossierId, String fileId, List<String> entryIds) {
|
||||
|
||||
return entityLogEntryDocumentRepository.findEntityLogEntryDocumentsByEntryIds(mapper.getLogId(dossierId, fileId), entryIds)
|
||||
.stream()
|
||||
.map(mapper::fromLogEntryDocument)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
public boolean entityLogDocumentExists(String dossierId, String fileId) {
|
||||
|
||||
return entityLogDocumentRepository.existsById(mapper.getLogId(dossierId, fileId));
|
||||
@ -210,8 +219,6 @@ public class EntityLogMongoService {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public Set<Integer> findFirstContainingNodeIdForEachEntry(String dossierId, String fileId, Collection<String> entryIds) {
|
||||
|
||||
String entityLogId = mapper.getLogId(dossierId, fileId);
|
||||
@ -297,6 +304,7 @@ public class EntityLogMongoService {
|
||||
return optionalEntityLog;
|
||||
}
|
||||
|
||||
|
||||
public List<EntityLogEntry> findEntityLogEntriesByAnalysisNumber(String dossierId, String fileId, int analysisNumber) {
|
||||
|
||||
return entityLogEntryDocumentRepository.findByEntityLogIdAndChangesAnalysisNumberEquals(mapper.getLogId(dossierId, fileId), analysisNumber)
|
||||
@ -305,6 +313,7 @@ public class EntityLogMongoService {
|
||||
.toList();
|
||||
}
|
||||
|
||||
|
||||
public Optional<EntityLog> findEntityLogWithEntriesByAnalysisNumber(String dossierId, String fileId, Integer analysisNumber) {
|
||||
|
||||
String entityLogId = mapper.getLogId(dossierId, fileId);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user