RED-6853 - Add update entries endpoint for dictionary entries #480

Merged
andrei.isvoran.ext merged 1 commits from RED-6853 into master 2024-05-09 13:22:50 +02:00
5 changed files with 181 additions and 0 deletions

View File

@ -30,6 +30,7 @@ import com.iqser.red.service.persistence.management.v1.processor.service.Diction
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService;
import com.iqser.red.service.persistence.management.v1.processor.utils.StringEncodingUtils;
import com.iqser.red.service.persistence.management.v1.processor.utils.TypeValueMapper;
import com.iqser.red.service.persistence.service.v1.api.external.model.UpdateEntries;
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;
@ -110,6 +111,31 @@ public class DictionaryController implements DictionaryResource {
}
@Override
public void updateEntries(String type, String dossierTemplateId, UpdateEntries updateEntries, String dossierId, DictionaryEntryType dictionaryEntryType) {
if (dossierId == null) {
dictionaryService.updateGlobalEntries(type, dossierTemplateId, updateEntries.entriesToAdd(), updateEntries.entriesToDelete(), dictionaryEntryType);
} else {
accessControlService.checkDossierExistenceAndAccessPermissionsToDossier(dossierId);
dictionaryService.updateDossierEntries(type, dossierTemplateId, updateEntries.entriesToAdd(), updateEntries.entriesToDelete(), dossierId, dictionaryEntryType);
}
auditClient.insertRecord(AuditRequest.builder()
.userId(KeycloakSecurity.getUserId())
.objectId(dossierTemplateId)
.category(AuditCategory.DICTIONARY.name())
.message("Dictionary entries were updated.")
.details(Map.of("Type",
type,
"Number of added entries",
updateEntries.entriesToAdd().size(),
"Number of deleted entries",
updateEntries.entriesToDelete().size()))
.build());
}
@Override
public void deleteEntries(@PathVariable(TYPE_PARAMETER_NAME) String type,
@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId,

View File

@ -0,0 +1,7 @@
package com.iqser.red.service.persistence.service.v1.api.external.model;
import java.util.List;
public record UpdateEntries(List<String> entriesToAdd, List<String> entriesToDelete) {
}

View File

@ -17,6 +17,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.multipart.MultipartFile;
import com.iqser.red.service.persistence.service.v1.api.external.model.UpdateEntries;
import com.iqser.red.service.persistence.service.v1.api.shared.model.CreateTypeValue;
import com.iqser.red.service.persistence.service.v1.api.shared.model.TypeResponse;
import com.iqser.red.service.persistence.service.v1.api.shared.model.TypeValue;
@ -53,6 +54,7 @@ public interface DictionaryResource {
String MERGED = "/merged";
String DELETE = "/delete";
String DIFFERENCE = "/difference";
String UPDATE = "/update";
String UPDATE_FLAG = "/updateFlag";
@ -101,6 +103,17 @@ public interface DictionaryResource {
@RequestParam(value = DICTIONARY_ENTRY_TYPE_PARAM, required = false, defaultValue = DEFAULT_DICTIONARY_ENTRY_TYPE) DictionaryEntryType dictionaryEntryType);
@ResponseStatus(HttpStatus.NO_CONTENT)
@PostMapping(value = DICTIONARY_REST_PATH + UPDATE + TYPE_PATH_VARIABLE + DOSSIER_TEMPLATE_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Update dictionary entries with type.", description = "None")
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Successfully updated the dictionary entries."), @ApiResponse(responseCode = "400", description = "Request contains error."), @ApiResponse(responseCode = "404", description = "The dossier or the entry type is not found."), @ApiResponse(responseCode = "403", description = "Forbidden")})
void updateEntries(@PathVariable(TYPE_PARAMETER_NAME) String type,
@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId,
@RequestBody UpdateEntries updateEntries,
@RequestParam(value = DOSSIER_ID_PARAMETER_NAME, required = false) String dossierId,
@RequestParam(value = DICTIONARY_ENTRY_TYPE_PARAM, required = false, defaultValue = DEFAULT_DICTIONARY_ENTRY_TYPE) DictionaryEntryType dictionaryEntryType);
@ResponseStatus(HttpStatus.NO_CONTENT)
@PostMapping(value = TYPE_PATH + TYPE_PATH_VARIABLE + DOSSIER_TEMPLATE_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Updates colors, hint and caseInsensitive of an entry type. Only label, colors and description are updatable for system managed entry types", description = "None")

View File

@ -24,6 +24,7 @@ import org.apache.commons.collections4.CollectionUtils;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.iqser.red.service.dictionarymerge.commons.CommonsDictionaryModel;
import com.iqser.red.service.dictionarymerge.commons.DictionaryEntry;
@ -124,6 +125,37 @@ public class DictionaryService {
}
@PreAuthorize("hasAuthority('" + ADD_DICTIONARY_ENTRY + "') and hasAuthority('" + DELETE_DICTIONARY_ENTRY + "')")
@Transactional
public void updateGlobalEntries(String type, String dossierTemplateId, List<String> entriesToAdd, List<String> entriesToDelete, DictionaryEntryType dictionaryEntryType) {
if (entriesToDelete != null && !entriesToDelete.isEmpty()) {
deleteGlobalEntries(type, dossierTemplateId, entriesToDelete, dictionaryEntryType);
}
if (entriesToAdd != null && !entriesToAdd.isEmpty()) {
addGlobalEntries(type, dossierTemplateId, entriesToAdd, false, dictionaryEntryType);
}
}
@PreAuthorize("hasAuthority('" + ADD_DOSSIER_DICTIONARY_ENTRY + "') and hasAuthority('" + DELETE_DOSSIER_DICTIONARY_ENTRY + "')")
@Transactional
public void updateDossierEntries(String type,
String dossierTemplateId,
List<String> entriesToAdd,
List<String> entriesToDelete,
String dossierId,
DictionaryEntryType dictionaryEntryType) {
if (entriesToDelete != null && !entriesToDelete.isEmpty()) {
deleteDossierEntries(type, dossierTemplateId, entriesToDelete, dossierId, dictionaryEntryType);
}
if (entriesToAdd != null && !entriesToAdd.isEmpty()) {
addDossierEntries(type, dossierTemplateId, entriesToAdd, false, dossierId, dictionaryEntryType);
}
}
@PreAuthorize("hasAuthority('" + ADD_UPDATE_DICTIONARY_TYPE + "')")
public void updateGlobalType(String type, String dossierTemplateId, UpdateTypeValue typeValue) {

View File

@ -24,6 +24,7 @@ import com.iqser.red.service.peristence.v1.server.integration.service.DossierTes
import com.iqser.red.service.peristence.v1.server.integration.service.TypeProvider;
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.external.model.UpdateEntries;
import com.iqser.red.service.persistence.service.v1.api.shared.model.CreateTypeValue;
import com.iqser.red.service.persistence.service.v1.api.shared.model.TypeValue;
import com.iqser.red.service.persistence.service.v1.api.shared.model.UpdateTypeValue;
@ -492,6 +493,108 @@ public class DictionaryTest extends AbstractPersistenceServerServiceTest {
}
@Test
public void testUpdateGlobalEntries() {
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
var dossier = dossierTesterAndProvider.provideTestDossier(dossierTemplate, "dossier");
var createdType = createDossierRedactionsDictionary(dossierTemplate.getId());
var word1 = "Luke Skywalker";
var word2 = "Anakin Skywalker";
var word3 = "Yoda";
var entriesToAdd = new ArrayList<String>();
entriesToAdd.add(word1);
entriesToAdd.add(word2);
entriesToAdd.add(word3);
dictionaryClient.addEntry(createdType.getType(), createdType.getDossierTemplateId(), entriesToAdd, false, dossier.getId(), DictionaryEntryType.ENTRY);
var dictionary = dictionaryClient.getDictionaryForType(createdType.getType(), createdType.getDossierTemplateId(), dossier.getId());
assertThat(dictionary.getEntries().size()).isEqualTo(3);
var word4 = "Padme";
var word5 = "Obiwan";
entriesToAdd.clear();
entriesToAdd.add(word4);
entriesToAdd.add(word5);
var entriesToDelete = new ArrayList<String>();
entriesToDelete.add(word1);
entriesToDelete.add(word2);
UpdateEntries updateEntries = new UpdateEntries(entriesToAdd, entriesToDelete);
dictionaryClient.updateEntries(createdType.getType(), createdType.getDossierTemplateId(), updateEntries, dossier.getId(), DictionaryEntryType.ENTRY);
dictionary = dictionaryClient.getDictionaryForType(createdType.getType(), createdType.getDossierTemplateId(), dossier.getId());
assertThat(dictionary.getEntries().size()).isEqualTo(3);
assertTrue(dictionary.getEntries()
.stream()
.anyMatch(entry -> entry.equals("Yoda")));
assertTrue(dictionary.getEntries()
.stream()
.anyMatch(entry -> entry.equals("Padme")));
assertTrue(dictionary.getEntries()
.stream()
.anyMatch(entry -> entry.equals("Obiwan")));
assertTrue(dictionary.getEntries()
.stream()
.noneMatch(entry -> entry.equals("Luke Skywalker")));
assertTrue(dictionary.getEntries()
.stream()
.noneMatch(entry -> entry.equals("Anakin Skywalker")));
}
@Test
public void testUpdateDossierEntries() {
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
var createdType = createDossierRedactionsDictionary(dossierTemplate.getId());
var word1 = "Luke Skywalker";
var word2 = "Anakin Skywalker";
var word3 = "Yoda";
var entriesToAdd = new ArrayList<String>();
entriesToAdd.add(word1);
entriesToAdd.add(word2);
entriesToAdd.add(word3);
dictionaryClient.addEntry(createdType.getType(), createdType.getDossierTemplateId(), entriesToAdd, false, null, DictionaryEntryType.ENTRY);
var dictionary = dictionaryClient.getDictionaryForType(createdType.getType(), createdType.getDossierTemplateId(), null);
assertThat(dictionary.getEntries().size()).isEqualTo(3);
var word4 = "Padme";
var word5 = "Obiwan";
entriesToAdd.clear();
entriesToAdd.add(word4);
entriesToAdd.add(word5);
var entriesToDelete = new ArrayList<String>();
entriesToDelete.add(word1);
entriesToDelete.add(word2);
UpdateEntries updateEntries = new UpdateEntries(entriesToAdd, entriesToDelete);
dictionaryClient.updateEntries(createdType.getType(), createdType.getDossierTemplateId(), updateEntries, null, DictionaryEntryType.ENTRY);
dictionary = dictionaryClient.getDictionaryForType(createdType.getType(), createdType.getDossierTemplateId(), null);
assertThat(dictionary.getEntries().size()).isEqualTo(3);
assertTrue(dictionary.getEntries()
.stream()
.anyMatch(entry -> entry.equals("Yoda")));
assertTrue(dictionary.getEntries()
.stream()
.anyMatch(entry -> entry.equals("Padme")));
assertTrue(dictionary.getEntries()
.stream()
.anyMatch(entry -> entry.equals("Obiwan")));
assertTrue(dictionary.getEntries()
.stream()
.noneMatch(entry -> entry.equals("Luke Skywalker")));
assertTrue(dictionary.getEntries()
.stream()
.noneMatch(entry -> entry.equals("Anakin Skywalker")));
}
@Test
public void testDossierTemplateAndDossierMissmatched() {