diff --git a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/DictionaryController.java b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/DictionaryController.java index 94eac1013..d494dd61c 100644 --- a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/DictionaryController.java +++ b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/DictionaryController.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; import org.springframework.core.io.InputStreamResource; @@ -24,6 +25,7 @@ import org.springframework.web.multipart.MultipartFile; import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException; import com.iqser.red.service.persistence.management.v1.processor.service.AccessControlService; +import com.iqser.red.service.persistence.management.v1.processor.service.DictionaryDifferenceService; import com.iqser.red.service.persistence.management.v1.processor.service.DictionaryService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.utils.StringEncodingUtils; @@ -31,11 +33,12 @@ import com.iqser.red.service.persistence.management.v1.processor.utils.TypeValue import com.iqser.red.service.persistence.service.v1.api.external.resource.DictionaryResource; import com.iqser.red.service.persistence.service.v1.api.shared.model.AuditCategory; import com.iqser.red.service.persistence.service.v1.api.shared.model.CreateTypeValue; -import com.iqser.red.service.persistence.service.v1.api.shared.model.Dictionary; import com.iqser.red.service.persistence.service.v1.api.shared.model.TypeResponse; import com.iqser.red.service.persistence.service.v1.api.shared.model.TypeValue; import com.iqser.red.service.persistence.service.v1.api.shared.model.UpdateTypeValue; import com.iqser.red.service.persistence.service.v1.api.shared.model.audit.AuditRequest; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary.Dictionary; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary.DictionaryDifferenceResponse; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.Colors; 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.dossiertemplate.type.Type; @@ -55,6 +58,7 @@ public class DictionaryController implements DictionaryResource { private final DictionaryService dictionaryService; private final AuditPersistenceService auditClient; private final AccessControlService accessControlService; + private final DictionaryDifferenceService dictionaryDifferenceService; @Override @@ -332,4 +336,19 @@ public class DictionaryController implements DictionaryResource { dictionaryService.changeAddToDictionary(type, dossierTemplateId, dossierId, addToDictionary); } + + @Override + public DictionaryDifferenceResponse getDictionaryDifference(String dossierTemplateId, Set types) { + + DictionaryDifferenceResponse dictionaryDifferenceResponse = dictionaryDifferenceService.calculatedDictionaryDifference(dossierTemplateId, types); + auditClient.insertRecord(AuditRequest.builder() + .userId(KeycloakSecurity.getUserId()) + .objectId(dossierTemplateId) + .category(AuditCategory.DICTIONARY.name()) + .message("Dictionary differences was calculated.") + .details(Map.of("DictionaryDifferenceResponse", dictionaryDifferenceResponse, "types", types)) + .build()); + return dictionaryDifferenceResponse; + } + } diff --git a/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/DictionaryResource.java b/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/DictionaryResource.java index 96e296f06..05ae8cf90 100644 --- a/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/DictionaryResource.java +++ b/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/DictionaryResource.java @@ -1,6 +1,7 @@ package com.iqser.red.service.persistence.service.v1.api.external.resource; import java.util.List; +import java.util.Set; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -17,10 +18,11 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.multipart.MultipartFile; import com.iqser.red.service.persistence.service.v1.api.shared.model.CreateTypeValue; -import com.iqser.red.service.persistence.service.v1.api.shared.model.Dictionary; import com.iqser.red.service.persistence.service.v1.api.shared.model.TypeResponse; import com.iqser.red.service.persistence.service.v1.api.shared.model.TypeValue; import com.iqser.red.service.persistence.service.v1.api.shared.model.UpdateTypeValue; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary.Dictionary; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary.DictionaryDifferenceResponse; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.Colors; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type.DictionaryEntryType; @@ -44,19 +46,20 @@ public interface DictionaryResource { String ENTRY_PATH_VARIABLE = "/{" + ENTRY_PARAMETER_NAME + "}"; String DOSSIER_TEMPLATE_PARAMETER_NAME = "dossierTemplateId"; - String DOSSIER_TEMPLATE_PATH_VARIABLE = "/{"+ DOSSIER_TEMPLATE_PARAMETER_NAME + "}"; + String DOSSIER_TEMPLATE_PATH_VARIABLE = "/{" + DOSSIER_TEMPLATE_PARAMETER_NAME + "}"; String UPLOAD = "/upload"; String DOWNLOAD = "/download"; String MERGED = "/merged"; String DELETE = "/delete"; + String DIFFERENCE = "/difference"; String UPDATE_FLAG = "/updateFlag"; String COLOR_REST_PATH = ExternalApi.BASE_PATH + "/color"; String DOSSIER_ID_PARAMETER_NAME = "dossierId"; - String DOSSIER_ID_PATH_VARIABLE = "/{"+ DOSSIER_ID_PARAMETER_NAME + "}"; + String DOSSIER_ID_PATH_VARIABLE = "/{" + DOSSIER_ID_PARAMETER_NAME + "}"; String INCLUDE_DELETED_PARAMETER_NAME = "includeDeleted"; @@ -209,4 +212,11 @@ public interface DictionaryResource { @PathVariable(DOSSIER_ID_PARAMETER_NAME) String dossierId, @RequestParam(value = "addToDictionary") boolean addToDictionary); + + @ResponseStatus(HttpStatus.ACCEPTED) + @PostMapping(value = DICTIONARY_REST_PATH + DIFFERENCE + DOSSIER_TEMPLATE_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Returns the difference between the dictionaries of the dossier template and all the dossiers inside the template for a list of given types.", description = "None") + @ApiResponses(value = {@ApiResponse(responseCode = "202", description = "Successfully returned DictionaryDifferenceResponse."), @ApiResponse(responseCode = "400", description = "The request is not valid.")}) + DictionaryDifferenceResponse getDictionaryDifference(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, @RequestBody Set types); + } \ No newline at end of file diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/DictionaryDifferenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/DictionaryDifferenceService.java new file mode 100644 index 000000000..402163431 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/DictionaryDifferenceService.java @@ -0,0 +1,104 @@ +package com.iqser.red.service.persistence.management.v1.processor.service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.springframework.stereotype.Service; + +import com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary.Dictionary; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary.DictionaryDifference; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary.DictionaryDifferencePerType; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary.DictionaryDifferenceResponse; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary.DictionaryEntriesDifference; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary.DictionaryFalsePositivesDifference; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary.DictionaryFalseRecommendationsDifference; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.Dossier; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class DictionaryDifferenceService { + + private final DossierManagementService dossierManagementService; + private final DictionaryService dictionaryService; + + + public DictionaryDifferenceResponse calculatedDictionaryDifference(String dossierTemplateId, Set types) { + + List dictionaryDifferences = new ArrayList<>(); + List dossiers = dossierManagementService.getAllDossiersForDossierTemplateId(dossierTemplateId, false, false); + + Map templateDictionaryCache = new HashMap<>(); + + dossiers.forEach(dossier -> { + + String dossierId = dossier.getId(); + List dictionaryDifferencePerTypes = new ArrayList<>(); + + types.forEach(type -> { + + // Cache the dossier template dictionary, so we don't load it for each dossier + Dictionary dossierTemplateDictionary = templateDictionaryCache.computeIfAbsent(type, t -> dictionaryService.getDictionaryForType(t, dossierTemplateId, null)); + Dictionary dossierDictionary = dictionaryService.getMergedDictionaryForType(type, dossierTemplateId, dossierId); + dictionaryDifferencePerTypes.add(calculateDifference(dossierTemplateDictionary, dossierDictionary, type)); + }); + + dictionaryDifferences.add(DictionaryDifference.builder().dossierId(dossierId).dictionaryDifferencePerTypes(dictionaryDifferencePerTypes).build()); + }); + + return DictionaryDifferenceResponse.builder().dossierTemplateId(dossierTemplateId).dictionaryDifferences(dictionaryDifferences).build(); + } + + + private DictionaryDifferencePerType calculateDifference(Dictionary dossierTemplateDictionary, Dictionary dossierDictionary, String type) { + + Set dossierTemplateDictionaryEntries = new HashSet<>(dossierTemplateDictionary.getEntries()); + Set dossierDictionaryEntries = new HashSet<>(dossierDictionary.getEntries()); + + Set dossierTemplateFalsePositiveEntries = new HashSet<>(dossierTemplateDictionary.getFalsePositiveEntries()); + Set dossierFalsePositiveEntries = new HashSet<>(dossierDictionary.getFalsePositiveEntries()); + + Set dossierTemplateFalseRecommendationEntries = new HashSet<>(dossierTemplateDictionary.getFalseRecommendationEntries()); + Set dossierFalseRecommendationEntries = new HashSet<>(dossierDictionary.getFalseRecommendationEntries()); + + return DictionaryDifferencePerType.builder() + .type(type) + .dictionaryEntriesDifference(DictionaryEntriesDifference.builder() + .addedEntries(calculateAddedEntries(dossierTemplateDictionaryEntries, dossierDictionaryEntries)) + .removedEntries(calculateRemovedEntries(dossierTemplateDictionaryEntries, dossierDictionaryEntries)) + .build()) + .dictionaryFalseRecommendationsDifference(DictionaryFalseRecommendationsDifference.builder() + .addedFalseRecommendations(calculateAddedEntries(dossierTemplateFalseRecommendationEntries, + dossierFalseRecommendationEntries)) + .removedFalseRecommendations(calculateRemovedEntries(dossierTemplateFalseRecommendationEntries, + dossierFalseRecommendationEntries)) + .build()) + .dictionaryFalsePositivesDifference(DictionaryFalsePositivesDifference.builder() + .addedFalsePositives(calculateAddedEntries(dossierTemplateFalsePositiveEntries, dossierFalsePositiveEntries)) + .removedFalsePositives(calculateRemovedEntries(dossierTemplateFalsePositiveEntries, dossierFalsePositiveEntries)) + .build()) + .build(); + } + + + private Set calculateAddedEntries(Set dossierTemplateEntries, Set dossierEntries) { + + Set addedEntries = new HashSet<>(dossierEntries); + addedEntries.removeAll(dossierTemplateEntries); + return addedEntries; + } + + + private Set calculateRemovedEntries(Set dossierTemplateEntries, Set dossierEntries) { + + Set removedEntries = new HashSet<>(dossierTemplateEntries); + removedEntries.removeAll(dossierEntries); + return removedEntries; + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/DictionaryService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/DictionaryService.java index 4468ca5c9..7b99704b0 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/DictionaryService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/DictionaryService.java @@ -36,10 +36,10 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist import com.iqser.red.service.persistence.management.v1.processor.service.persistence.EntryPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.utils.ColorUtils; import com.iqser.red.service.persistence.service.v1.api.shared.model.CreateTypeValue; -import com.iqser.red.service.persistence.service.v1.api.shared.model.Dictionary; import com.iqser.red.service.persistence.service.v1.api.shared.model.TypeResponse; import com.iqser.red.service.persistence.service.v1.api.shared.model.TypeValue; import com.iqser.red.service.persistence.service.v1.api.shared.model.UpdateTypeValue; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary.Dictionary; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.Colors; 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.dossiertemplate.type.Type; @@ -160,22 +160,22 @@ public class DictionaryService { accessControlService.verifyUserIsDossierOwner(dossierId); if (typeEntity.isDossierDictionaryOnly()) { - dictionaryManagementService.updateTypeValue(toTypeId(type, dossierTemplateId, dossierId), - Type.builder() - .dossierTemplateId(dossierTemplateId) - .hexColor(typeValue.getHexColor()) - .recommendationHexColor(typeValue.getRecommendationHexColor()) - .skippedHexColor(typeValue.getSkippedHexColor()) - .rank(typeValue.getRank()) - .isHint(typeValue.isHint()) - .isCaseInsensitive(typeValue.isCaseInsensitive()) - .isRecommendation(typeValue.isRecommendation()) - .description(typeValue.getDescription()) - .addToDictionaryAction(typeEntity.isAddToDictionaryAction()) - .label(typeValue.getLabel()) - .hasDictionary(typeValue.isHasDictionary()) - .autoHideSkipped(typeValue.isAutoHideSkipped()) - .build()); + dictionaryManagementService.updateTypeValue(toTypeId(type, dossierTemplateId, dossierId), + Type.builder() + .dossierTemplateId(dossierTemplateId) + .hexColor(typeValue.getHexColor()) + .recommendationHexColor(typeValue.getRecommendationHexColor()) + .skippedHexColor(typeValue.getSkippedHexColor()) + .rank(typeValue.getRank()) + .isHint(typeValue.isHint()) + .isCaseInsensitive(typeValue.isCaseInsensitive()) + .isRecommendation(typeValue.isRecommendation()) + .description(typeValue.getDescription()) + .addToDictionaryAction(typeEntity.isAddToDictionaryAction()) + .label(typeValue.getLabel()) + .hasDictionary(typeValue.isHasDictionary()) + .autoHideSkipped(typeValue.isAutoHideSkipped()) + .build()); } else { updateType(dossierTemplateId, toTypeId(type, dossierTemplateId, dossierId), typeValue); } diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/service/TypeProvider.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/service/TypeProvider.java index 047cf00ff..4f7a0fb68 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/service/TypeProvider.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/service/TypeProvider.java @@ -24,6 +24,12 @@ public class TypeProvider { } + public TypeValue testAndProvideType(DossierTemplateModel dossierTemplate, String typeName, int rank) { + + return testAndProvideType(dossierTemplate, null, typeName, false, rank); + } + + public TypeValue testAndProvideType(DossierTemplateModel dossierTemplate, Dossier dossier, String typeName) { return testAndProvideType(dossierTemplate, dossier, typeName, false); diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DictionaryTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DictionaryTest.java index b016ba95d..584cbd23c 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DictionaryTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/DictionaryTest.java @@ -1,10 +1,14 @@ package com.iqser.red.service.peristence.v1.server.integration.tests; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.ArrayList; import java.util.Comparator; import java.util.List; +import java.util.Set; import java.util.stream.IntStream; import org.junit.jupiter.api.Assertions; @@ -21,9 +25,12 @@ import com.iqser.red.service.peristence.v1.server.integration.service.TypeProvid import com.iqser.red.service.peristence.v1.server.integration.utils.AbstractPersistenceServerServiceTest; import com.iqser.red.service.persistence.management.v1.processor.service.DictionaryService; import com.iqser.red.service.persistence.service.v1.api.shared.model.CreateTypeValue; -import com.iqser.red.service.persistence.service.v1.api.shared.model.Dictionary; import com.iqser.red.service.persistence.service.v1.api.shared.model.TypeValue; import com.iqser.red.service.persistence.service.v1.api.shared.model.UpdateTypeValue; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary.Dictionary; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary.DictionaryDifference; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary.DictionaryDifferencePerType; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary.DictionaryDifferenceResponse; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type.DictionaryEntryType; import com.knecon.fforesight.tenantcommons.TenantContext; @@ -46,8 +53,8 @@ public class DictionaryTest extends AbstractPersistenceServerServiceTest { @Autowired private DossierTemplateClient dossierTemplateClient; - private List testList1 = List.of("William c. Spare", "Charalampos", "Carina Wilson", "PATRICIA A. SHEEHY", "William C. Spare", "carlsen", "Patricia A. Sheehy"); - private List testList2 = List.of("William C. Spare", "Charalampos", "Carina Wilson", "Patricia A. Sheehy", "William c. Spare", "carlsen", "PATRICIA A. SHEEHY"); + private final List testList1 = List.of("William c. Spare", "Charalampos", "Carina Wilson", "PATRICIA A. SHEEHY", "William C. Spare", "carlsen", "Patricia A. Sheehy"); + private final List testList2 = List.of("William C. Spare", "Charalampos", "Carina Wilson", "Patricia A. Sheehy", "William c. Spare", "carlsen", "PATRICIA A. SHEEHY"); @BeforeEach @@ -753,6 +760,97 @@ public class DictionaryTest extends AbstractPersistenceServerServiceTest { } + @Test + public void testCalculateDictionaryDifference() { + + var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate(); + var dossier = dossierTesterAndProvider.provideTestDossier(dossierTemplate, "testDossier"); + var type = typeProvider.testAndProvideType(dossierTemplate, "type1", 100); + var type2 = typeProvider.testAndProvideType(dossierTemplate, "type2", 101); + + // Add entries for the dossier template + dictionaryClient.addEntry(type.getType(), type.getDossierTemplateId(), List.of("entry1", "entry2"), false, null, DictionaryEntryType.ENTRY); + dictionaryClient.addEntry(type.getType(), type.getDossierTemplateId(), List.of("falsePositive1", "falsePositive2"), false, null, DictionaryEntryType.FALSE_POSITIVE); + dictionaryClient.addEntry(type.getType(), + type.getDossierTemplateId(), + List.of("falseRecommendation1", "falseRecommendation2"), + false, + null, + DictionaryEntryType.FALSE_RECOMMENDATION); + dictionaryClient.addEntry(type2.getType(), type2.getDossierTemplateId(), List.of("entry1", "entry2"), false, null, DictionaryEntryType.ENTRY); + dictionaryClient.addEntry(type2.getType(), type2.getDossierTemplateId(), List.of("falsePositive1", "falsePositive2"), false, null, DictionaryEntryType.FALSE_POSITIVE); + dictionaryClient.addEntry(type2.getType(), type2.getDossierTemplateId(), List.of("random"), false, null, DictionaryEntryType.FALSE_RECOMMENDATION); + + // Add entries for the dossier + dictionaryClient.deleteEntries(type.getType(), type.getDossierTemplateId(), List.of("entry1"), dossier.getId(), DictionaryEntryType.ENTRY); + dictionaryClient.addEntry(type.getType(), + type.getDossierTemplateId(), + List.of("falsePositive1", "falsePositive2", "falsePositive3"), + false, + dossier.getId(), + DictionaryEntryType.FALSE_POSITIVE); + dictionaryClient.addEntry(type.getType(), + type.getDossierTemplateId(), + List.of("falseRecommendation1", "falseRecommendation2"), + false, + dossier.getId(), + DictionaryEntryType.FALSE_RECOMMENDATION); + dictionaryClient.addEntry(type2.getType(), type2.getDossierTemplateId(), List.of("entry1", "entry2"), false, dossier.getId(), DictionaryEntryType.ENTRY); + dictionaryClient.addEntry(type2.getType(), + type2.getDossierTemplateId(), + List.of("falsePositive2", "falsePositive3"), + false, + dossier.getId(), + DictionaryEntryType.FALSE_POSITIVE); + dictionaryClient.deleteEntries(type2.getType(), type2.getDossierTemplateId(), List.of("falsePositive1"), dossier.getId(), DictionaryEntryType.FALSE_POSITIVE); + dictionaryClient.addEntry(type2.getType(), + type2.getDossierTemplateId(), + List.of("falseRecommendation1", "falseRecommendation2"), + false, + dossier.getId(), + DictionaryEntryType.FALSE_RECOMMENDATION); + dictionaryClient.deleteEntries(type2.getType(), type2.getDossierTemplateId(), List.of("random"), dossier.getId(), DictionaryEntryType.FALSE_RECOMMENDATION); + + DictionaryDifferenceResponse dictionaryDifferenceResponse = dictionaryClient.getDictionaryDifference(dossierTemplate.getId(), Set.of(type.getType(), type2.getType())); + Assertions.assertNotNull(dictionaryDifferenceResponse); + assertEquals(dictionaryDifferenceResponse.getDossierTemplateId(), dossierTemplate.getId()); + assertFalse(dictionaryDifferenceResponse.getDictionaryDifferences().isEmpty()); + DictionaryDifference dictionaryDifference = dictionaryDifferenceResponse.getDictionaryDifferences() + .get(0); + assertEquals(dictionaryDifference.getDossierId(), dossier.getId()); + assertFalse(dictionaryDifference.getDictionaryDifferencePerTypes().isEmpty()); + DictionaryDifferencePerType dictionaryDifferencePerType1 = dictionaryDifference.getDictionaryDifferencePerTypes() + .stream() + .filter(d -> d.getType().equals("type1")) + .findFirst() + .get(); + DictionaryDifferencePerType dictionaryDifferencePerType2 = dictionaryDifference.getDictionaryDifferencePerTypes() + .stream() + .filter(d -> d.getType().equals("type2")) + .findFirst() + .get(); + + assertTrue(dictionaryDifferencePerType1.getDictionaryEntriesDifference().getAddedEntries().isEmpty()); + assertTrue(dictionaryDifferencePerType1.getDictionaryEntriesDifference().getRemovedEntries().contains("entry1")); + + assertTrue(dictionaryDifferencePerType1.getDictionaryFalsePositivesDifference().getAddedFalsePositives().contains("falsePositive3")); + assertTrue(dictionaryDifferencePerType1.getDictionaryFalsePositivesDifference().getRemovedFalsePositives().isEmpty()); + + assertTrue(dictionaryDifferencePerType1.getDictionaryFalseRecommendationsDifference().getAddedFalseRecommendations().isEmpty()); + assertTrue(dictionaryDifferencePerType1.getDictionaryFalseRecommendationsDifference().getRemovedFalseRecommendations().isEmpty()); + + assertTrue(dictionaryDifferencePerType2.getDictionaryEntriesDifference().getAddedEntries().isEmpty()); + assertTrue(dictionaryDifferencePerType2.getDictionaryEntriesDifference().getRemovedEntries().isEmpty()); + + assertTrue(dictionaryDifferencePerType2.getDictionaryFalsePositivesDifference().getAddedFalsePositives().contains("falsePositive3")); + assertTrue(dictionaryDifferencePerType2.getDictionaryFalsePositivesDifference().getRemovedFalsePositives().contains("falsePositive1")); + + assertTrue(dictionaryDifferencePerType2.getDictionaryFalseRecommendationsDifference().getAddedFalseRecommendations().contains("falseRecommendation1")); + assertTrue(dictionaryDifferencePerType2.getDictionaryFalseRecommendationsDifference().getAddedFalseRecommendations().contains("falseRecommendation2")); + assertTrue(dictionaryDifferencePerType2.getDictionaryFalseRecommendationsDifference().getRemovedFalseRecommendations().contains("random")); + } + + @SuppressWarnings("SameParameterValue") private List createDummyEntries(int numberOfEntries) { 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 eb1502180..c040b19cc 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 @@ -21,7 +21,6 @@ import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import com.fasterxml.jackson.databind.ObjectMapper; @@ -44,8 +43,6 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.redactionlog.RedactionRequest; import com.iqser.red.service.persistence.service.v1.api.shared.model.AnalyzeResult; -import com.iqser.red.service.persistence.service.v1.api.shared.model.Dictionary; -import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierTemplateModel; import com.iqser.red.service.persistence.service.v1.api.shared.model.MessageType; 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; @@ -56,9 +53,8 @@ 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.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.Position; -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.Rectangle; -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.dictionary.Dictionary; 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; diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/Dictionary.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dictionary/Dictionary.java similarity index 99% rename from persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/Dictionary.java rename to persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dictionary/Dictionary.java index b32db4bbe..fad4143d8 100644 --- a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/Dictionary.java +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dictionary/Dictionary.java @@ -1,4 +1,4 @@ -package com.iqser.red.service.persistence.service.v1.api.shared.model; +package com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary; import java.util.List; diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dictionary/DictionaryDifference.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dictionary/DictionaryDifference.java new file mode 100644 index 000000000..5f4c3726f --- /dev/null +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dictionary/DictionaryDifference.java @@ -0,0 +1,17 @@ +package com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +@AllArgsConstructor +public class DictionaryDifference { + + private String dossierId; + private List dictionaryDifferencePerTypes; + +} diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dictionary/DictionaryDifferencePerType.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dictionary/DictionaryDifferencePerType.java new file mode 100644 index 000000000..de05a0eae --- /dev/null +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dictionary/DictionaryDifferencePerType.java @@ -0,0 +1,17 @@ +package com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +@AllArgsConstructor +public class DictionaryDifferencePerType { + + private String type; + private DictionaryEntriesDifference dictionaryEntriesDifference; + private DictionaryFalsePositivesDifference dictionaryFalsePositivesDifference; + private DictionaryFalseRecommendationsDifference dictionaryFalseRecommendationsDifference; + +} diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dictionary/DictionaryDifferenceResponse.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dictionary/DictionaryDifferenceResponse.java new file mode 100644 index 000000000..230731328 --- /dev/null +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dictionary/DictionaryDifferenceResponse.java @@ -0,0 +1,17 @@ +package com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +@AllArgsConstructor +public class DictionaryDifferenceResponse { + + private String dossierTemplateId; + private List dictionaryDifferences; + +} diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dictionary/DictionaryEntriesDifference.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dictionary/DictionaryEntriesDifference.java new file mode 100644 index 000000000..b8341a143 --- /dev/null +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dictionary/DictionaryEntriesDifference.java @@ -0,0 +1,17 @@ +package com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary; + +import java.util.Set; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +@AllArgsConstructor +public class DictionaryEntriesDifference { + + private Set addedEntries; + private Set removedEntries; + +} diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dictionary/DictionaryFalsePositivesDifference.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dictionary/DictionaryFalsePositivesDifference.java new file mode 100644 index 000000000..93d8c958b --- /dev/null +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dictionary/DictionaryFalsePositivesDifference.java @@ -0,0 +1,17 @@ +package com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary; + +import java.util.Set; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +@AllArgsConstructor +public class DictionaryFalsePositivesDifference { + + private Set addedFalsePositives; + private Set removedFalsePositives; + +} diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dictionary/DictionaryFalseRecommendationsDifference.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dictionary/DictionaryFalseRecommendationsDifference.java new file mode 100644 index 000000000..0972c8883 --- /dev/null +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dictionary/DictionaryFalseRecommendationsDifference.java @@ -0,0 +1,17 @@ +package com.iqser.red.service.persistence.service.v1.api.shared.model.dictionary; + +import java.util.Set; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +@AllArgsConstructor +public class DictionaryFalseRecommendationsDifference { + + private Set addedFalseRecommendations; + private Set removedFalseRecommendations; + +}