From 3e205d0b1ba1cdbee442d1c5f697ff7d96e78244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominique=20Eifl=C3=A4nder?= Date: Tue, 28 May 2024 15:44:25 +0200 Subject: [PATCH] RED-9225: Implemented new endpoints for api v2 --- .../impl/controller/DossierController.java | 44 ++++++-- .../impl/controller/DossierControllerV2.java | 88 +++++++++++++++ .../DossierTemplateControllerV2.java | 47 ++++++++ .../impl/controller/DownloadControllerV2.java | 102 ++++++++++++++++++ .../api/impl/controller/FileControllerV2.java | 68 +++++++++++- .../impl/controller/LicenseControllerV2.java | 2 +- .../external/model/BulkDownloadRequest.java | 25 +++++ .../model/DossierAttributeDefinition.java | 21 ++++ .../model/DossierAttributeDefinitionList.java | 18 ++++ .../model/DossierStatusDefinition.java | 21 ++++ .../model/DossierStatusDefinitionList.java | 18 ++++ .../api/external/model/DownloadRequest.java | 25 +++++ .../v2/api/external/model/DownloadStatus.java | 35 ++++++ .../external/model/DownloadStatusList.java | 19 ++++ .../external/resource/DossierResource.java | 25 +++++ .../resource/DossierTemplateResource.java | 15 +++ .../external/resource/DownloadResource.java | 55 ++++++++++ .../api/external/resource/FileResource.java | 28 ++++- .../entity/download/DownloadStatusEntity.java | 2 + .../DownloadStatusPersistenceService.java | 10 ++ .../repository/DownloadStatusRepository.java | 4 + .../db/changelog/db.changelog-tenant.yaml | 2 + .../126-add-uuid-to-download-status.yaml | 11 ++ .../dossiertemplate/dossier/Dossier.java | 1 + .../dossier/DossierAttributes.java | 17 +++ 25 files changed, 691 insertions(+), 12 deletions(-) create mode 100644 persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DownloadControllerV2.java create mode 100644 persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/BulkDownloadRequest.java create mode 100644 persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DossierAttributeDefinition.java create mode 100644 persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DossierAttributeDefinitionList.java create mode 100644 persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DossierStatusDefinition.java create mode 100644 persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DossierStatusDefinitionList.java create mode 100644 persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DownloadRequest.java create mode 100644 persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DownloadStatus.java create mode 100644 persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DownloadStatusList.java create mode 100644 persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/DownloadResource.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/resources/db/changelog/tenant/126-add-uuid-to-download-status.yaml create mode 100644 persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/dossier/DossierAttributes.java 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/DossierController.java b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/DossierController.java index 5bf26c6f1..96de1dc80 100644 --- a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/DossierController.java +++ b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/DossierController.java @@ -10,6 +10,7 @@ import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -18,6 +19,7 @@ import java.util.Set; import java.util.TreeSet; import java.util.stream.Collectors; +import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierAttributeEntity; import com.iqser.red.service.persistence.management.v1.processor.model.websocket.DossierEventType; import com.iqser.red.service.persistence.management.v1.processor.service.DossierCreatorService; @@ -44,6 +46,7 @@ import com.iqser.red.service.persistence.management.v1.processor.service.Dossier import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusManagementService; import com.iqser.red.service.persistence.management.v1.processor.service.WebsocketService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierAttributePersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.NotificationPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.users.UserService; import com.iqser.red.service.persistence.management.v1.processor.service.users.model.User; @@ -57,6 +60,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.audit.Audit import com.iqser.red.service.persistence.service.v1.api.shared.model.common.JSONPrimitive; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.CreateOrUpdateDossierRequest; 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.dossier.DossierAttributes; import com.iqser.red.service.persistence.service.v1.api.shared.model.notification.NotificationType; import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity; @@ -79,6 +83,7 @@ public class DossierController implements DossierResource { private final DossierACLService dossierACLService; private final DossierCreatorService dossierCreatorService; private final WebsocketService websocketService; + private final DossierAttributePersistenceService dossierAttributePersistenceService; @Override @@ -222,6 +227,8 @@ public class DossierController implements DossierResource { websocketService.sendDossierEvent(dossierRequest.getDossierId(), DossierEventType.UPDATE); + updatedDossier.setDossierAttributes(convertDossierAttributes(dossierAttributePersistenceService.getDossierAttributes(updatedDossier.getId()))); + HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setContentType(MediaType.APPLICATION_JSON); return new ResponseEntity<>(updatedDossier, httpHeaders, HttpStatus.OK); @@ -342,6 +349,7 @@ public class DossierController implements DossierResource { .build(), members, approvers, ownerId); dossierACLService.enhanceDossierWithACLData(newDossier); + newDossier.setDossierAttributes(new DossierAttributes()); return newDossier; @@ -403,8 +411,9 @@ public class DossierController implements DossierResource { @RequestParam(name = INCLUDE_DELETED_PARAM, defaultValue = "false", required = false) boolean includeDeleted) { accessControlService.checkViewPermissionsToDossier(dossierId); - - return dossierACLService.enhanceDossierWithACLData(dossierManagementService.getDossierById(dossierId, includeArchived, includeDeleted)); + var dossier = dossierManagementService.getDossierById(dossierId, includeArchived, includeDeleted); + dossier.setDossierAttributes(convertDossierAttributes(dossierAttributePersistenceService.getDossierAttributes(dossierId))); + return dossierACLService.enhanceDossierWithACLData(dossier); } @@ -413,10 +422,12 @@ public class DossierController implements DossierResource { public List getDossiers(@RequestParam(name = INCLUDE_ARCHIVED_PARAM, defaultValue = "false", required = false) boolean includeArchived, @RequestParam(name = INCLUDE_DELETED_PARAM, defaultValue = "false", required = false) boolean includeDeleted) { - return dossierManagementService.getAllDossiers(includeArchived, includeDeleted) + var dossiers = dossierManagementService.getAllDossiers(includeArchived, includeDeleted) .stream() .map(dossierACLService::enhanceDossierWithACLData) .collect(Collectors.toList()); + dossiers.forEach(dossier -> dossier.setDossierAttributes(convertDossierAttributes(dossierAttributePersistenceService.getDossierAttributes(dossier.getId())))); + return dossiers; } @@ -426,10 +437,12 @@ public class DossierController implements DossierResource { @RequestParam(name = INCLUDE_ARCHIVED_PARAM, defaultValue = "false", required = false) boolean includeArchived, @RequestParam(name = INCLUDE_DELETED_PARAM, defaultValue = "false", required = false) boolean includeDeleted) { - return dossierManagementService.getAllDossiersForDossierTemplateId(dossierTemplateId, includeArchived, includeDeleted) + var dossiers = dossierManagementService.getAllDossiersForDossierTemplateId(dossierTemplateId, includeArchived, includeDeleted) .stream() .map(dossierACLService::enhanceDossierWithACLData) .collect(Collectors.toList()); + dossiers.forEach(dossier -> dossier.setDossierAttributes(convertDossierAttributes(dossierAttributePersistenceService.getDossierAttributes(dossier.getId())))); + return dossiers; } @@ -437,11 +450,12 @@ public class DossierController implements DossierResource { @PostFilter("hasPermission(filterObject.id, 'Dossier', 'VIEW_OBJECT')") public List getSoftDeletedDossiers() { - return dossierManagementService.getSoftDeletedDossiers() + var dossiers = dossierManagementService.getSoftDeletedDossiers() .stream() .map(dossierACLService::enhanceDossierWithACLData) .collect(Collectors.toList()); - + dossiers.forEach(dossier -> dossier.setDossierAttributes(convertDossierAttributes(dossierAttributePersistenceService.getDossierAttributes(dossier.getId())))); + return dossiers; } @@ -449,10 +463,12 @@ public class DossierController implements DossierResource { @PostFilter("hasPermission(filterObject.id, 'Dossier', 'VIEW_OBJECT')") public List getArchivedDossiers() { - return dossierManagementService.getArchivedDossiers() + var dossiers = dossierManagementService.getArchivedDossiers() .stream() .map(dossierACLService::enhanceDossierWithACLData) .collect(Collectors.toList()); + dossiers.forEach(dossier -> dossier.setDossierAttributes(convertDossierAttributes(dossierAttributePersistenceService.getDossierAttributes(dossier.getId())))); + return dossiers; } @@ -460,10 +476,12 @@ public class DossierController implements DossierResource { @PostFilter("hasPermission(filterObject.id, 'Dossier', 'VIEW_OBJECT')") public List getArchivedDossiersForDossierTemplate(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId) { - return dossierManagementService.getArchivedDossiersForDossierTemplateId(dossierTemplateId) + var dossiers = dossierManagementService.getArchivedDossiersForDossierTemplateId(dossierTemplateId) .stream() .map(dossierACLService::enhanceDossierWithACLData) .collect(Collectors.toList()); + dossiers.forEach(dossier -> dossier.setDossierAttributes(convertDossierAttributes(dossierAttributePersistenceService.getDossierAttributes(dossier.getId())))); + return dossiers; } @@ -558,5 +576,15 @@ public class DossierController implements DossierResource { .collect(Collectors.toSet()); } + + private DossierAttributes convertDossierAttributes(List dossierAttributeEntities) { + + Map attributeIdToValue = new HashMap<>(); + for (DossierAttributeEntity dossierAttributeEntity : dossierAttributeEntities) { + attributeIdToValue.put(dossierAttributeEntity.getId().getDossierAttributeConfigId(), dossierAttributeEntity.getValue()); + } + return new DossierAttributes(attributeIdToValue); + } + } diff --git a/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DossierControllerV2.java b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DossierControllerV2.java index 03eb1cb98..0b3de8bda 100644 --- a/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DossierControllerV2.java +++ b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DossierControllerV2.java @@ -1,10 +1,12 @@ package com.iqser.red.persistence.service.v2.external.api.impl.controller; +import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.WRITE_DOSSIER_ATTRIBUTES; import static com.iqser.red.service.persistence.service.v2.api.external.resource.DossierTemplateResource.DOSSIER_TEMPLATE_ID_PARAM; import java.util.Set; import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; @@ -12,12 +14,28 @@ import org.springframework.web.bind.annotation.RestController; import com.iqser.red.persistence.service.v1.external.api.impl.controller.DossierController; import com.iqser.red.persistence.service.v1.external.api.impl.controller.DossierTemplateController; +import com.iqser.red.persistence.service.v1.external.api.impl.controller.DownloadController; +import com.iqser.red.persistence.service.v1.external.api.impl.controller.StatusController; +import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity; +import com.iqser.red.service.persistence.management.v1.processor.service.AccessControlService; +import com.iqser.red.service.persistence.management.v1.processor.service.DossierAttributesManagementService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DownloadStatusPersistenceService; +import com.iqser.red.service.persistence.service.v1.api.shared.model.AuditCategory; import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierRequest; +import com.iqser.red.service.persistence.service.v1.api.shared.model.FileStatus; +import com.iqser.red.service.persistence.service.v1.api.shared.model.PrepareDownloadWithOptionRequest; +import com.iqser.red.service.persistence.service.v1.api.shared.model.audit.AuditRequest; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DownloadFileType; 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.dossier.DossierAttribute; import com.iqser.red.service.persistence.service.v2.api.external.model.DocuMineDossierRequest; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.DossierAttributes; import com.iqser.red.service.persistence.service.v2.api.external.model.DossierList; +import com.iqser.red.service.persistence.service.v2.api.external.model.DownloadRequest; +import com.iqser.red.service.persistence.service.v2.api.external.model.DownloadStatus; import com.iqser.red.service.persistence.service.v2.api.external.resource.DossierResource; +import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -30,6 +48,12 @@ public class DossierControllerV2 implements DossierResource { private final DossierTemplateController dossierTemplateController; private final DossierController dossierController; + private final AccessControlService accessControlService; + private final DossierAttributesManagementService dossierAttributesManagementService; + private final AuditPersistenceService auditPersistenceService; + private final DownloadController downloadController; + private final StatusController statusController; + private final DownloadStatusPersistenceService downloadStatusPersistenceService; public DossierList getDossiers(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId, @@ -79,6 +103,70 @@ public class DossierControllerV2 implements DossierResource { } + @PreAuthorize("hasAuthority('" + WRITE_DOSSIER_ATTRIBUTES + "')") + public void setDossierAttributes(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId, + @PathVariable(DOSSIER_ID_PARAM) String dossierId, + @RequestBody DossierAttributes dossierAttributes) { + + accessControlService.checkDossierExistenceAndAccessPermissionsToDossier(dossierId); + accessControlService.verifyUserIsDossierOwner(dossierId); + + var dossierAttributeList = dossierAttributes.getAttributeIdToValue().entrySet() + .stream() + .map(entry -> new DossierAttribute(dossierId, entry.getKey(), entry.getValue())) + .toList(); + + dossierAttributesManagementService.setDossierAttributes(dossierId, dossierAttributeList); + auditPersistenceService.insertRecord(AuditRequest.builder() + .userId(KeycloakSecurity.getUserId()) + .objectId(dossierId) + .category(AuditCategory.DOSSIER.name()) + .message("Changed dossier attributes.") + .build()); + } + + + public DownloadStatus prepareDossierDownload(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId, + @PathVariable(DOSSIER_ID_PARAM) String dossierId, + @RequestBody DownloadRequest downloadRequest) { + + var storageId = downloadController.prepareDownload(PrepareDownloadWithOptionRequest.builder() + .dossierId(dossierId) + .fileIds(statusController.getDossierStatus(dossierId) + .stream() + .map(FileStatus::getId) + .toList()) + .reportTemplateIds(downloadRequest.getReportTemplateIds()) + .downloadFileTypes(downloadRequest.getDownloadFileTypes()) + .redactionPreviewColor(downloadRequest.getRedactionPreviewColor()) + .includeUnprocessed(false) + .build()).getStorageId(); + + var status = downloadStatusPersistenceService.getStatus(storageId); + + return DownloadStatus.builder() + .id(status.getUuid()) // This is a workaround the real is the storageId. + .userId(status.getUserId()) + .filename(status.getFilename()) + .mimeType(status.getMimeType()) + .errorCause(status.getErrorCause()) + .status(status.getStatus()) + .creationDate(status.getCreationDate()) + .lastDownload(status.getLastDownload()) + .fileSize(status.getFileSize()) + .dossierId(status.getDossier().getId()) + .fileIds(status.getFiles() + .stream() + .map(FileEntity::getId) + .toList()) + .downloadFileTypes(status.getDownloadFileTypes() + .stream() + .toList()) + .reportTemplateIds(downloadRequest.getReportTemplateIds()) + .build(); + } + + private static DossierRequest mapToDossierRequest(String dossierTemplateId, DocuMineDossierRequest dossier) { return DossierRequest.builder() diff --git a/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DossierTemplateControllerV2.java b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DossierTemplateControllerV2.java index 3662294a1..d7cd0d692 100644 --- a/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DossierTemplateControllerV2.java +++ b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DossierTemplateControllerV2.java @@ -1,6 +1,8 @@ package com.iqser.red.persistence.service.v2.external.api.impl.controller; import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.EXPERIMENTAL; +import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_DOSSIER_ATTRIBUTES_CONFIG; +import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_DOSSIER_STATUS; import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_FILE_ATTRIBUTES_CONFIG; import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_RULES; import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.WRITE_RULES; @@ -37,6 +39,8 @@ import com.iqser.red.service.persistence.management.v1.processor.service.Compone import com.iqser.red.service.persistence.management.v1.processor.service.RulesValidationService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierTemplatePersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierAttributeConfigPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierStatusPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.RulesPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.utils.RulesValidationMapper; import com.iqser.red.service.persistence.management.v1.processor.utils.StringEncodingUtils; @@ -48,6 +52,10 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemp import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesUploadRequest; import com.iqser.red.service.persistence.service.v2.api.external.model.ComponentMappingMetadataModel; import com.iqser.red.service.persistence.service.v2.api.external.model.ComponentMappingSummary; +import com.iqser.red.service.persistence.service.v2.api.external.model.DossierAttributeDefinition; +import com.iqser.red.service.persistence.service.v2.api.external.model.DossierAttributeDefinitionList; +import com.iqser.red.service.persistence.service.v2.api.external.model.DossierStatusDefinition; +import com.iqser.red.service.persistence.service.v2.api.external.model.DossierStatusDefinitionList; import com.iqser.red.service.persistence.service.v2.api.external.model.FileAttributeDefinition; import com.iqser.red.service.persistence.service.v2.api.external.model.FileAttributeDefinitionList; import com.iqser.red.service.persistence.service.v2.api.external.resource.DossierTemplateResource; @@ -78,6 +86,8 @@ public class DossierTemplateControllerV2 implements DossierTemplateResource { ComponentMappingService componentMappingService; ComponentMappingMapper componentMappingMapper = ComponentMappingMapper.INSTANCE; DossierTemplatePersistenceService dossierTemplatePersistenceService; + DossierStatusPersistenceService dossierStatusPersistenceService; + DossierAttributeConfigPersistenceService dossierAttributeConfigPersistenceService; public List getAllDossierTemplates() { @@ -171,6 +181,43 @@ public class DossierTemplateControllerV2 implements DossierTemplateResource { } + @PreAuthorize("hasAuthority('" + READ_DOSSIER_STATUS + "')") + public DossierStatusDefinitionList getDossierStatusDefinitions(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId) { + + getDossierTemplate(dossierTemplateId); + + return new DossierStatusDefinitionList(dossierStatusPersistenceService.getAllDossierStatusForTemplate(dossierTemplateId) + .stream() + .map(dossierStatusInfo -> DossierStatusDefinition.builder() + .id(dossierStatusInfo.getId()) + .name(dossierStatusInfo.getName()) + .description(dossierStatusInfo.getDescription()) + .rank(dossierStatusInfo.getRank()) + .color(dossierStatusInfo.getColor()) + .dossierCount(dossierStatusInfo.getDossierCount() != null ? dossierStatusInfo.getDossierCount() : 0) + .build()) + .toList()); + } + + + @PreAuthorize("hasAuthority('" + READ_DOSSIER_ATTRIBUTES_CONFIG + "')") + public DossierAttributeDefinitionList getDossierAttributeDefinitions(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId) { + + getDossierTemplate(dossierTemplateId); + + return new DossierAttributeDefinitionList(dossierAttributeConfigPersistenceService.getDossierAttributes(dossierTemplateId) + .stream() + .map(config -> DossierAttributeDefinition.builder() + + .id(config.getId()) + .name(config.getLabel()) + .type(config.getType()) + .reportingPlaceholder(config.getPlaceholder()) + .build()) + .toList()); + } + + @SneakyThrows private ResponseEntity uploadRules(String dossierTemplateId, RuleFileType ruleFileType, MultipartFile file, boolean dryRun) { diff --git a/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DownloadControllerV2.java b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DownloadControllerV2.java new file mode 100644 index 000000000..85d08c24b --- /dev/null +++ b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/DownloadControllerV2.java @@ -0,0 +1,102 @@ +package com.iqser.red.persistence.service.v2.external.api.impl.controller; + +import java.util.List; + +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import com.iqser.red.persistence.service.v1.external.api.impl.controller.DownloadController; +import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity; +import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.ReportTemplateEntity; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DownloadStatusPersistenceService; +import com.iqser.red.service.persistence.service.v1.api.shared.model.RemoveDownloadRequest; +import com.iqser.red.service.persistence.service.v2.api.external.model.DownloadStatus; +import com.iqser.red.service.persistence.service.v2.api.external.model.DownloadStatusList; +import com.iqser.red.service.persistence.service.v2.api.external.resource.DownloadResource; +import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity; + +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@Tag(name = "5. Downloads", description = "Operations related to download packages.") +public class DownloadControllerV2 implements DownloadResource { + + private final DownloadController downloadController; + private final DownloadStatusPersistenceService downloadStatusPersistenceService; + + @Transactional + public DownloadStatusList getDownloadStatusList() { + + var downloads = downloadStatusPersistenceService.getStatusesByUser(KeycloakSecurity.getUserId()); + + return new DownloadStatusList(downloads.stream().map( + status -> + DownloadStatus.builder() + .id(status.getUuid()) // This is a workaround the real id is the storageId. + .userId(status.getUserId()) + .filename(status.getFilename()) + .mimeType(status.getMimeType()) + .errorCause(status.getErrorCause()) + .status(status.getStatus()) + .creationDate(status.getCreationDate()) + .lastDownload(status.getLastDownload()) + .fileSize(status.getFileSize()) + .dossierId(status.getDossier().getId()) + .fileIds(status.getFiles() + .stream() + .map(FileEntity::getId) + .toList()) + .downloadFileTypes(status.getDownloadFileTypes() + .stream() + .toList()) + .reportTemplateIds(status.getReports().stream().map(ReportTemplateEntity::getTemplateId).toList()) + .build()).toList() + ); + } + + + @Transactional + public DownloadStatus getDownloadStatus(@PathVariable(DOWNLOAD_ID_PARAM) String downloadId) { + + var status = downloadStatusPersistenceService.getStatusesByUuid(downloadId); + + return DownloadStatus.builder() + .id(status.getUuid()) // This is a workaround the real id is the storageId. + .userId(status.getUserId()) + .filename(status.getFilename()) + .mimeType(status.getMimeType()) + .errorCause(status.getErrorCause()) + .status(status.getStatus()) + .creationDate(status.getCreationDate()) + .lastDownload(status.getLastDownload()) + .fileSize(status.getFileSize()) + .dossierId(status.getDossier().getId()) + .fileIds(status.getFiles() + .stream() + .map(FileEntity::getId) + .toList()) + .downloadFileTypes(status.getDownloadFileTypes() + .stream() + .toList()) + .reportTemplateIds(status.getReports().stream().map(ReportTemplateEntity::getTemplateId).toList()) + .build(); + } + + + public void deleteDownload(@PathVariable(DOWNLOAD_ID_PARAM) String downloadId) { + + var status = downloadStatusPersistenceService.getStatusesByUuid(downloadId); + downloadController.deleteDownloadStatus(new RemoveDownloadRequest(List.of(status.getStorageId()))); + } + + + public void download(@PathVariable(DOWNLOAD_ID_PARAM) String downloadId) { + + var status = downloadStatusPersistenceService.getStatusesByUuid(downloadId); + downloadController.downloadFile(status.getStorageId()); + } + +} diff --git a/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/FileControllerV2.java b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/FileControllerV2.java index 97c3ec5c8..eae54a546 100644 --- a/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/FileControllerV2.java +++ b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/FileControllerV2.java @@ -7,9 +7,7 @@ import static com.iqser.red.service.persistence.service.v2.api.external.resource import static com.iqser.red.service.persistence.service.v2.api.external.resource.DossierTemplateResource.DOSSIER_TEMPLATE_ID_PARAM; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; @@ -20,15 +18,22 @@ import org.springframework.web.multipart.MultipartFile; import com.iqser.red.persistence.service.v1.external.api.impl.controller.DossierController; import com.iqser.red.persistence.service.v1.external.api.impl.controller.DossierTemplateController; +import com.iqser.red.persistence.service.v1.external.api.impl.controller.DownloadController; import com.iqser.red.persistence.service.v1.external.api.impl.controller.FileAttributesController; import com.iqser.red.persistence.service.v1.external.api.impl.controller.FileManagementController; import com.iqser.red.persistence.service.v1.external.api.impl.controller.StatusController; import com.iqser.red.persistence.service.v1.external.api.impl.controller.UploadController; +import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity; import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusManagementService; import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusMapper; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DownloadStatusPersistenceService; import com.iqser.red.service.persistence.service.v1.api.shared.model.FileAttributes; import com.iqser.red.service.persistence.service.v1.api.shared.model.FileStatus; import com.iqser.red.service.persistence.service.v1.api.shared.model.FileUploadResult; +import com.iqser.red.service.persistence.service.v1.api.shared.model.PrepareDownloadWithOptionRequest; +import com.iqser.red.service.persistence.service.v2.api.external.model.BulkDownloadRequest; +import com.iqser.red.service.persistence.service.v2.api.external.model.DownloadRequest; +import com.iqser.red.service.persistence.service.v2.api.external.model.DownloadStatus; import com.iqser.red.service.persistence.service.v2.api.external.model.FileDeleteRequest; import com.iqser.red.service.persistence.service.v2.api.external.model.FileStatusList; import com.iqser.red.service.persistence.service.v2.api.external.resource.FileResource; @@ -48,6 +53,8 @@ public class FileControllerV2 implements FileResource { private final FileStatusManagementService fileStatusManagementService; private final FileAttributesController fileAttributesController; private final DossierTemplateController dossierTemplateController; + private final DownloadController downloadController; + private final DownloadStatusPersistenceService downloadStatusPersistenceService; public FileUploadResult upload(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId, @@ -141,4 +148,61 @@ public class FileControllerV2 implements FileResource { fileAttributesController.setFileAttributes(dossierId, fileId, fileAttributes); } + + public DownloadStatus prepareFileDownload(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId, + @PathVariable(DOSSIER_ID_PARAM) String dossierId, + @PathVariable(FILE_ID_PARAM) String fileId, + @RequestBody DownloadRequest downloadRequest) { + + return prepareBulkDownload(dossierTemplateId, + dossierId, + BulkDownloadRequest.builder() + .reportTemplateIds(downloadRequest.getReportTemplateIds()) + .downloadFileTypes(downloadRequest.getDownloadFileTypes()) + .redactionPreviewColor(downloadRequest.getRedactionPreviewColor()) + .fileIds(List.of(fileId)) + .build()); + } + + + public DownloadStatus prepareBulkDownload(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId, + @PathVariable(DOSSIER_ID_PARAM) String dossierId, + @RequestBody BulkDownloadRequest bulkDownloadRequest) { + + var storageId = downloadController.prepareDownload(PrepareDownloadWithOptionRequest.builder() + .dossierId(dossierId) + .fileIds(statusController.getDossierStatus(dossierId) + .stream() + .map(FileStatus::getId) + .toList()) + .reportTemplateIds(bulkDownloadRequest.getReportTemplateIds()) + .downloadFileTypes(bulkDownloadRequest.getDownloadFileTypes()) + .redactionPreviewColor(bulkDownloadRequest.getRedactionPreviewColor()) + .includeUnprocessed(false) + .build()).getStorageId(); + + var status = downloadStatusPersistenceService.getStatus(storageId); + + return DownloadStatus.builder() + .id(status.getUuid()) // This is a workaround the real is the storageId. + .userId(status.getUserId()) + .filename(status.getFilename()) + .mimeType(status.getMimeType()) + .errorCause(status.getErrorCause()) + .status(status.getStatus()) + .creationDate(status.getCreationDate()) + .lastDownload(status.getLastDownload()) + .fileSize(status.getFileSize()) + .dossierId(status.getDossier().getId()) + .fileIds(status.getFiles() + .stream() + .map(FileEntity::getId) + .toList()) + .downloadFileTypes(status.getDownloadFileTypes() + .stream() + .toList()) + .reportTemplateIds(bulkDownloadRequest.getReportTemplateIds()) + .build(); + } + } diff --git a/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/LicenseControllerV2.java b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/LicenseControllerV2.java index 1c63c6a5c..6daec99c0 100644 --- a/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/LicenseControllerV2.java +++ b/persistence-service-v1/persistence-service-external-api-impl-v2/src/main/java/com/iqser/red/persistence/service/v2/external/api/impl/controller/LicenseControllerV2.java @@ -13,7 +13,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController @RequiredArgsConstructor -@Tag(name = "5. License endpoints", description = "Provides operations related to the license") +@Tag(name = "7. License", description = "Operations related to license information and usage metrics.") public class LicenseControllerV2 implements LicenseResource { private final LicenseReportController licenseReportController; diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/BulkDownloadRequest.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/BulkDownloadRequest.java new file mode 100644 index 000000000..ace05e4fe --- /dev/null +++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/BulkDownloadRequest.java @@ -0,0 +1,25 @@ +package com.iqser.red.service.persistence.service.v2.api.external.model; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DownloadFileType; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class BulkDownloadRequest { + + private List reportTemplateIds = new ArrayList<>(); + private Set downloadFileTypes = new HashSet<>(); + private String redactionPreviewColor; + private List fileIds = new ArrayList<>(); +} diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DossierAttributeDefinition.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DossierAttributeDefinition.java new file mode 100644 index 000000000..fb214d6d7 --- /dev/null +++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DossierAttributeDefinition.java @@ -0,0 +1,21 @@ +package com.iqser.red.service.persistence.service.v2.api.external.model; + +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.DossierAttributeType; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DossierAttributeDefinition { + + private String id; + private String name; + private DossierAttributeType type; + private String reportingPlaceholder; + +} diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DossierAttributeDefinitionList.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DossierAttributeDefinitionList.java new file mode 100644 index 000000000..a8ec38b8d --- /dev/null +++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DossierAttributeDefinitionList.java @@ -0,0 +1,18 @@ +package com.iqser.red.service.persistence.service.v2.api.external.model; + +import java.util.ArrayList; +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DossierAttributeDefinitionList { + + private List dossierAttributeDefinitions= new ArrayList<>(); +} diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DossierStatusDefinition.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DossierStatusDefinition.java new file mode 100644 index 000000000..f90a8b013 --- /dev/null +++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DossierStatusDefinition.java @@ -0,0 +1,21 @@ +package com.iqser.red.service.persistence.service.v2.api.external.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DossierStatusDefinition { + + private String id; + private String name; + private String description; + private int rank; + private String color; + private long dossierCount; + +} diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DossierStatusDefinitionList.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DossierStatusDefinitionList.java new file mode 100644 index 000000000..20d62ae92 --- /dev/null +++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DossierStatusDefinitionList.java @@ -0,0 +1,18 @@ +package com.iqser.red.service.persistence.service.v2.api.external.model; + +import java.util.ArrayList; +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DossierStatusDefinitionList { + + private List dossierStatusDefinitions = new ArrayList<>(); +} diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DownloadRequest.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DownloadRequest.java new file mode 100644 index 000000000..960c530f0 --- /dev/null +++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DownloadRequest.java @@ -0,0 +1,25 @@ +package com.iqser.red.service.persistence.service.v2.api.external.model; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DownloadFileType; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DownloadRequest { + + private List reportTemplateIds = new ArrayList<>(); + private Set downloadFileTypes = new HashSet<>(); + private String redactionPreviewColor; + +} diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DownloadStatus.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DownloadStatus.java new file mode 100644 index 000000000..6ce41e2e1 --- /dev/null +++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DownloadStatus.java @@ -0,0 +1,35 @@ +package com.iqser.red.service.persistence.service.v2.api.external.model; + +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.List; + +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DownloadFileType; +import com.iqser.red.service.persistence.service.v1.api.shared.model.download.DownloadStatusValue; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DownloadStatus { + + private String id; + private String userId; + private String filename; + private String mimeType; + private String errorCause; + private DownloadStatusValue status; + private OffsetDateTime creationDate; + private OffsetDateTime lastDownload; + private long fileSize; + private String dossierId; + private List fileIds = new ArrayList<>(); + private List downloadFileTypes = new ArrayList<>(); + private List reportTemplateIds = new ArrayList<>(); + +} diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DownloadStatusList.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DownloadStatusList.java new file mode 100644 index 000000000..d42d92d2d --- /dev/null +++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/model/DownloadStatusList.java @@ -0,0 +1,19 @@ +package com.iqser.red.service.persistence.service.v2.api.external.model; + +import java.util.ArrayList; +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DownloadStatusList { + + List downloadStatus = new ArrayList<>(); + +} diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/DossierResource.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/DossierResource.java index 0887c8ff2..106b4dc3d 100644 --- a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/DossierResource.java +++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/DossierResource.java @@ -18,7 +18,10 @@ import org.springframework.web.bind.annotation.ResponseStatus; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.Dossier; import com.iqser.red.service.persistence.service.v2.api.external.model.DocuMineDossierRequest; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.DossierAttributes; import com.iqser.red.service.persistence.service.v2.api.external.model.DossierList; +import com.iqser.red.service.persistence.service.v2.api.external.model.DownloadRequest; +import com.iqser.red.service.persistence.service.v2.api.external.model.DownloadStatus; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -32,6 +35,8 @@ public interface DossierResource { String PATH = ExternalApiConstants.BASE_PATH + DOSSIER_TEMPLATE_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + DOSSIER_PATH; String DOSSIER_ID_PARAM = "dossierId"; String DOSSIER_ID_PATH_PARAM = "/{" + DOSSIER_ID_PARAM + "}"; + String ATTRIBUTES_PATH = "/attributes"; + String CREATE_DOWNLOAD_PATH = "/create-download"; String INCLUDE_ACTIVE_PARAM = "includeActive"; String INCLUDE_ARCHIVED_PARAM = "includeArchived"; @@ -74,4 +79,24 @@ public interface DossierResource { void deleteDossier(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId, @Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier to retrieve.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId); + + @ResponseStatus(value = HttpStatus.NO_CONTENT) + @ResponseBody + @PostMapping(value = PATH + DOSSIER_ID_PATH_PARAM + ATTRIBUTES_PATH, consumes = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Update or set attributes for a specific dossier.", description = "None") + @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Dossier attributes successfully updated."), @ApiResponse(responseCode = "404", description = "Not found")}) + void setDossierAttributes(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of a dossier template", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId, + @Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of a dossier", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId, + @RequestBody DossierAttributes dossierAttributes); + + + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @PostMapping(value = PATH + CREATE_DOWNLOAD_PATH + DOSSIER_ID_PATH_PARAM, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Initiate the creation of a download package for all files of a dossier.") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Successfully started the creation of the download package for all files of the requested dossier."), @ApiResponse(responseCode = "404", description = "Not found")}) + DownloadStatus prepareDossierDownload(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of a dossier template", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId, + @Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of a dossier", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId, + @RequestBody DownloadRequest downloadRequest); + } diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/DossierTemplateResource.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/DossierTemplateResource.java index 7257cdd41..92eb6f61c 100644 --- a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/DossierTemplateResource.java +++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/DossierTemplateResource.java @@ -5,6 +5,8 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemp import com.iqser.red.service.persistence.service.v2.api.external.model.ComponentMappingMetadataModel; import com.iqser.red.service.persistence.service.v2.api.external.model.ComponentMappingSummary; import com.iqser.red.service.persistence.service.v2.api.external.model.FileAttributeDefinitionList; +import com.iqser.red.service.persistence.service.v2.api.external.model.DossierAttributeDefinitionList; +import com.iqser.red.service.persistence.service.v2.api.external.model.DossierStatusDefinitionList; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -38,6 +40,8 @@ public interface DossierTemplateResource { String ENTITY_RULES_PATH = "/entity-rules"; String COMPONENT_RULES_PATH = "/component-rules"; String COMPONENT_MAPPINGS_PATH = "/component-mappings"; + String DOSSIER_STATUS_DEFINITIONS_PATH = "/dossier-status-definitions"; + String DOSSIER_ATTRIBUTE_DEFINITION_PATH = "/dossier-attribute-definitions"; String FILE_ATTRIBUTE_DEFINITIONS_PATH = "/file-attribute-definitions"; String DOSSIER_TEMPLATE_ID_PARAM = "dossierTemplateId"; @@ -152,4 +156,15 @@ public interface DossierTemplateResource { @DeleteMapping(value = PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + COMPONENT_MAPPINGS_PATH + COMPONENT_MAPPING_ID_PATH_VARIABLE) ResponseEntity deleteMapping(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId, @PathVariable(COMPONENT_MAPPING_ID_PARAM) String componentMappingId); + @Operation(summary = "Returns the list of all existing dossier status definitions.", description = "None") + @GetMapping(value = PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + DOSSIER_STATUS_DEFINITIONS_PATH, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Successfully returned the dossier status definitions for the specified dossier template."), @ApiResponse(responseCode = "404", description = "The DossierTemplate is not found.")}) + DossierStatusDefinitionList getDossierStatusDefinitions(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId); + + + @Operation(summary = "Returns the list of all existing dossier attribute definitions.", description = "None") + @GetMapping(value = PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + DOSSIER_ATTRIBUTE_DEFINITION_PATH, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Successfully returned the dossier attribute definitions for the specified dossier template."), @ApiResponse(responseCode = "404", description = "The DossierTemplate is not found.")}) + DossierAttributeDefinitionList getDossierAttributeDefinitions(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId); + } diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/DownloadResource.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/DownloadResource.java new file mode 100644 index 000000000..28da06059 --- /dev/null +++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/DownloadResource.java @@ -0,0 +1,55 @@ +package com.iqser.red.service.persistence.service.v2.api.external.resource; + +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +import com.iqser.red.service.persistence.service.v2.api.external.model.DownloadStatus; +import com.iqser.red.service.persistence.service.v2.api.external.model.DownloadStatusList; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; + +@ApiResponses(value = {@ApiResponse(responseCode = "429", description = "Too many requests.")}) +@ResponseStatus(HttpStatus.OK) +public interface DownloadResource { + + String DOWNLOAD_PATH = "/download"; + String PATH = ExternalApiConstants.BASE_PATH + DOWNLOAD_PATH; + String DOWNLOAD_ID_PARAM = "downloadId"; + String DOWNLOAD_ID_PATH_PARAM = "/{" + DOWNLOAD_ID_PARAM + "}"; + + + @GetMapping(value = PATH, produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Get the list of downloads for the current user", description = "None") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "List of all downloads of the current users successfully retrieved.")}) + DownloadStatusList getDownloadStatusList(); + + + @GetMapping(value = PATH + DOWNLOAD_ID_PATH_PARAM, produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Get the status for a specific download of the current user", description = "None") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Status of the download successfully retrieved.")}) + DownloadStatus getDownloadStatus(@Parameter(name = DOWNLOAD_ID_PARAM, description = "The identifier for the file to download.", required = true) @PathVariable(DOWNLOAD_ID_PARAM) String downloadId); + + + @ResponseStatus(HttpStatus.NO_CONTENT) + @DeleteMapping(value = PATH + DOWNLOAD_ID_PATH_PARAM) + @Operation(summary = "Deletes a specific download.", description = "None") + @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Download deletion successful. This confirms the absence of the specified download, irrespective of its previous existence.")}) + void deleteDownload(@Parameter(name = DOWNLOAD_ID_PARAM, description = "The identifier for the file to download.", required = true) @PathVariable(DOWNLOAD_ID_PARAM) String downloadId); + + + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @Operation(summary = "Download the download package.") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Successfully downloaded the requested file."), @ApiResponse(responseCode = "404", description = "Download not found. This happens if the requested download does not exist for the current user.")}) + @GetMapping(value = PATH + DOWNLOAD_ID_PATH_PARAM + DOWNLOAD_PATH) + void download(@Parameter(name = DOWNLOAD_ID_PARAM, description = "The identifier for the file to download.", required = true) @PathVariable(DOWNLOAD_ID_PARAM) String downloadId); + +} diff --git a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/FileResource.java b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/FileResource.java index dd5f07b7b..4f05b90c3 100644 --- a/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/FileResource.java +++ b/persistence-service-v1/persistence-service-external-api-v2/src/main/java/com/iqser/red/service/persistence/service/v2/api/external/resource/FileResource.java @@ -26,6 +26,9 @@ import org.springframework.web.multipart.MultipartFile; import com.iqser.red.service.persistence.service.v1.api.shared.model.FileAttributes; import com.iqser.red.service.persistence.service.v1.api.shared.model.FileStatus; import com.iqser.red.service.persistence.service.v1.api.shared.model.FileUploadResult; +import com.iqser.red.service.persistence.service.v2.api.external.model.BulkDownloadRequest; +import com.iqser.red.service.persistence.service.v2.api.external.model.DownloadRequest; +import com.iqser.red.service.persistence.service.v2.api.external.model.DownloadStatus; import com.iqser.red.service.persistence.service.v2.api.external.model.FileDeleteRequest; import com.iqser.red.service.persistence.service.v2.api.external.model.FileStatusList; @@ -42,6 +45,8 @@ public interface FileResource { String PATH = ExternalApiConstants.BASE_PATH + DOSSIER_TEMPLATE_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + DOSSIER_PATH + DOSSIER_ID_PATH_PARAM + FILE_PATH; String BULK_DELETE_PATH = "/bulk/delete"; String FILE_ATTRIBUTES_PATH = "/attributes"; + String CREATE_DOWNLOAD_PATH = "/create-download"; + String BULK_CREATE_DOWNLOAD_PATH = "/bulk/create-download"; String KEEP_MANUAL_CHANGES_PARAM = "keepManualChanges"; String DELETE_PERMANENTLY_PARAM = "deletePermanently"; String FILE_PARAM = "file"; @@ -104,11 +109,32 @@ public interface FileResource { @Operation(summary = "Set file attributes to an existing file", description = "None") - @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")}) + @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK")}) @PostMapping(value = PATH + FILE_ID_PATH_VARIABLE + FILE_ATTRIBUTES_PATH, consumes = MediaType.APPLICATION_JSON_VALUE) void setFileAttributes(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId, @Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier that contains the file.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId, @Parameter(name = FILE_ID_PARAM, description = "The identifier of the file of which the file attributes are set.", required = true) @PathVariable(FILE_ID_PARAM) String fileId, @RequestBody FileAttributes fileAttributes); + + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @PostMapping(value = PATH + FILE_ID_PATH_VARIABLE + CREATE_DOWNLOAD_PATH, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Initiate the creation of a download package for a single file of a dossier.") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Successfully started the creation of the download package for the requested file."), @ApiResponse(responseCode = "404", description = "Not found")}) + DownloadStatus prepareFileDownload(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of a dossier template", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId, + @Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of a dossier", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId, + @Parameter(name = FILE_ID_PARAM, description = "The identifier of a file", required = true) @PathVariable(FILE_ID_PARAM) String fileId, + @RequestBody DownloadRequest downloadRequest); + + + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @PostMapping(value = PATH + BULK_CREATE_DOWNLOAD_PATH, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "Initiate the creation of a download package for specific files within a dossier.") + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Successfully started the creation of the download package for the requested files."), @ApiResponse(responseCode = "404", description = "Not found")}) + DownloadStatus prepareBulkDownload(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of a dossier template", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId, + @Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of a dossier", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId, + @RequestBody BulkDownloadRequest bulkDownloadRequest); + } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/entity/download/DownloadStatusEntity.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/entity/download/DownloadStatusEntity.java index 098e1d2c5..4556f02a1 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/entity/download/DownloadStatusEntity.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/entity/download/DownloadStatusEntity.java @@ -45,6 +45,8 @@ public class DownloadStatusEntity { @Id String storageId; @Column + String uuid; + @Column String userId; @Column String filename; diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DownloadStatusPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DownloadStatusPersistenceService.java index 3d12ae614..a9ec3de3c 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DownloadStatusPersistenceService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DownloadStatusPersistenceService.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.UUID; import org.springframework.stereotype.Service; @@ -50,6 +51,7 @@ public class DownloadStatusPersistenceService { DownloadStatusEntity downloadStatus = new DownloadStatusEntity(); downloadStatus.setUserId(userId); downloadStatus.setStorageId(storageId); + downloadStatus.setUuid(UUID.randomUUID().toString()); downloadStatus.setFilename(filename); downloadStatus.setMimeType(mimeType); downloadStatus.setDossier(dossier); @@ -107,6 +109,7 @@ public class DownloadStatusPersistenceService { } + @Transactional public DownloadStatusEntity getStatus(String storageId) { return downloadStatusRepository.findById(storageId) @@ -128,6 +131,13 @@ public class DownloadStatusPersistenceService { } + @Transactional + public DownloadStatusEntity getStatusesByUuid(String uuid) { + + return downloadStatusRepository.findByUuid(uuid).orElseThrow(() -> new NotFoundException(String.format("DownloadStatus not found for uuid: %s", uuid))); + } + + public List getStatus() { return downloadStatusRepository.findAll(); diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DownloadStatusRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DownloadStatusRepository.java index 1a0af6eec..4b2424bb6 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DownloadStatusRepository.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DownloadStatusRepository.java @@ -2,6 +2,7 @@ package com.iqser.red.service.persistence.management.v1.processor.service.persis import java.time.OffsetDateTime; import java.util.List; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; @@ -16,6 +17,9 @@ public interface DownloadStatusRepository extends JpaRepository findAllByUserId(String userId); + // The real id is currently the storageId, this is a quick fix fpr the new customer api + // because i have no time to rewrite the complete logic that uses the storageId everywhere. + Optional findByUuid(String uuid); @Modifying @Query("update DownloadStatusEntity ds set ds.status = :status where ds.storageId = :storageId") diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/resources/db/changelog/db.changelog-tenant.yaml b/persistence-service-v1/persistence-service-processor-v1/src/main/resources/db/changelog/db.changelog-tenant.yaml index 470f13643..d79a21be9 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/resources/db/changelog/db.changelog-tenant.yaml +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/resources/db/changelog/db.changelog-tenant.yaml @@ -207,3 +207,5 @@ databaseChangeLog: file: db/changelog/tenant/127-add-component-mapping-table.yaml - include: file: db/changelog/tenant/128-add-component-mapping-versions-to-file.yaml + - include: + file: db/changelog/tenant/126-add-uuid-to-download-status.yaml diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/resources/db/changelog/tenant/126-add-uuid-to-download-status.yaml b/persistence-service-v1/persistence-service-processor-v1/src/main/resources/db/changelog/tenant/126-add-uuid-to-download-status.yaml new file mode 100644 index 000000000..80203c9a3 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/resources/db/changelog/tenant/126-add-uuid-to-download-status.yaml @@ -0,0 +1,11 @@ +databaseChangeLog: + - changeSet: + id: add-uuid-to-download-status + author: dom + changes: + - addColumn: + columns: + - column: + name: uuid + type: VARCHAR(255) + tableName: download_status \ No newline at end of file diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/dossier/Dossier.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/dossier/Dossier.java index f3c16e436..e962ad6e0 100644 --- a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/dossier/Dossier.java +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/dossier/Dossier.java @@ -38,6 +38,7 @@ public class Dossier { private String dossierTemplateId; private String dossierStatusId; private DossierVisibility visibility; + private DossierAttributes dossierAttributes; // TODO: The following getters and setter ensure backwards compatibility. Remove them as soon as UI does not use them anymore diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/dossier/DossierAttributes.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/dossier/DossierAttributes.java new file mode 100644 index 000000000..00294650e --- /dev/null +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/dossiertemplate/dossier/DossierAttributes.java @@ -0,0 +1,17 @@ +package com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier; + +import java.util.HashMap; +import java.util.Map; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class DossierAttributes { + + Map attributeIdToValue = new HashMap<>(); + +} -- 2.47.2