Merge branch 'RED-9225-4.0' into 'release/2.349.x'
RED-9225: Implemented new endpoints for api v2 See merge request redactmanager/persistence-service!510
This commit is contained in:
commit
12d1df7f71
@ -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.service.DossierCreatorService;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -42,6 +44,7 @@ import com.iqser.red.service.persistence.management.v1.processor.service.AccessC
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.DossierManagementService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusManagementService;
|
||||
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;
|
||||
@ -55,6 +58,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;
|
||||
|
||||
@ -76,6 +80,7 @@ public class DossierController implements DossierResource {
|
||||
private final AccessControlService accessControlService;
|
||||
private final DossierACLService dossierACLService;
|
||||
private final DossierCreatorService dossierCreatorService;
|
||||
private final DossierAttributePersistenceService dossierAttributePersistenceService;
|
||||
|
||||
|
||||
@Override
|
||||
@ -112,8 +117,8 @@ public class DossierController implements DossierResource {
|
||||
Set<String> approvers = getAndValidateMembers(ownerId, dossierRequest.getApproverIds());
|
||||
members.addAll(approvers);
|
||||
|
||||
if ((dossierRequest.getDownloadFileTypes() == null || dossierRequest.getDownloadFileTypes()
|
||||
.isEmpty()) && (dossierRequest.getReportTemplateIds() == null || dossierRequest.getReportTemplateIds().isEmpty())) {
|
||||
if ((dossierRequest.getDownloadFileTypes() == null || dossierRequest.getDownloadFileTypes().isEmpty()) && (dossierRequest.getReportTemplateIds() == null
|
||||
|| dossierRequest.getReportTemplateIds().isEmpty())) {
|
||||
throw new BadRequestException("Download and report types cannot both be empty");
|
||||
}
|
||||
|
||||
@ -128,16 +133,16 @@ public class DossierController implements DossierResource {
|
||||
|
||||
// update using data from request and computed owner/members/approvers
|
||||
Dossier updatedDossier = dossierManagementService.updateDossier(CreateOrUpdateDossierRequest.builder()
|
||||
.dossierName(dossierRequest.getDossierName())
|
||||
.description(dossierRequest.getDescription())
|
||||
.dossierTemplateId(dossierRequest.getDossierTemplateId())
|
||||
.downloadFileTypes(dossierRequest.getDownloadFileTypes())
|
||||
.dueDate(dossierRequest.getDueDate())
|
||||
.reportTemplateIds(new ArrayList<>(dossierRequest.getReportTemplateIds()))
|
||||
.watermarkId(dossierRequest.getWatermarkId())
|
||||
.previewWatermarkId(dossierRequest.getPreviewWatermarkId())
|
||||
.dossierStatusId(dossierRequest.getDossierStatusId())
|
||||
.build(), existingDossier.getId());
|
||||
.dossierName(dossierRequest.getDossierName())
|
||||
.description(dossierRequest.getDescription())
|
||||
.dossierTemplateId(dossierRequest.getDossierTemplateId())
|
||||
.downloadFileTypes(dossierRequest.getDownloadFileTypes())
|
||||
.dueDate(dossierRequest.getDueDate())
|
||||
.reportTemplateIds(new ArrayList<>(dossierRequest.getReportTemplateIds()))
|
||||
.watermarkId(dossierRequest.getWatermarkId())
|
||||
.previewWatermarkId(dossierRequest.getPreviewWatermarkId())
|
||||
.dossierStatusId(dossierRequest.getDossierStatusId())
|
||||
.build(), existingDossier.getId());
|
||||
|
||||
dossierACLService.updateDossierACL(members, approvers, ownerId, updatedDossier.getId());
|
||||
dossierACLService.enhanceDossierWithACLData(updatedDossier);
|
||||
@ -145,28 +150,28 @@ public class DossierController implements DossierResource {
|
||||
updateFileStatusForDossierFiles(updatedDossier.getId(), members);
|
||||
|
||||
auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(updatedDossier.getId())
|
||||
.category(AuditCategory.DOSSIER.name())
|
||||
.message("Dossier has been updated.")
|
||||
.build());
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(updatedDossier.getId())
|
||||
.category(AuditCategory.DOSSIER.name())
|
||||
.message("Dossier has been updated.")
|
||||
.build());
|
||||
|
||||
if (existingDossier.getOwnerId() == null || !existingDossier.getOwnerId().equals(ownerId)) {
|
||||
if (ownerId != null && !ownerId.equals(KeycloakSecurity.getUserId())) {
|
||||
notificationPersistenceService.insertNotification(AddNotificationRequest.builder()
|
||||
.userId(ownerId)
|
||||
.issuerId(KeycloakSecurity.getUserId())
|
||||
.notificationType(NotificationType.DOSSIER_OWNER_SET.name())
|
||||
.target(Map.of("dossierId", dossierRequest.getDossierId()))
|
||||
.build());
|
||||
.userId(ownerId)
|
||||
.issuerId(KeycloakSecurity.getUserId())
|
||||
.notificationType(NotificationType.DOSSIER_OWNER_SET.name())
|
||||
.target(Map.of("dossierId", dossierRequest.getDossierId()))
|
||||
.build());
|
||||
}
|
||||
if (existingDossier.getOwnerId() != null && !existingDossier.getOwnerId().equals(KeycloakSecurity.getUserId())) {
|
||||
notificationPersistenceService.insertNotification(AddNotificationRequest.builder()
|
||||
.userId(existingDossier.getOwnerId())
|
||||
.issuerId(KeycloakSecurity.getUserId())
|
||||
.notificationType(NotificationType.DOSSIER_OWNER_REMOVED.name())
|
||||
.target(Map.of("dossierId", dossierRequest.getDossierId()))
|
||||
.build());
|
||||
.userId(existingDossier.getOwnerId())
|
||||
.issuerId(KeycloakSecurity.getUserId())
|
||||
.notificationType(NotificationType.DOSSIER_OWNER_REMOVED.name())
|
||||
.target(Map.of("dossierId", dossierRequest.getDossierId()))
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,46 +179,50 @@ public class DossierController implements DossierResource {
|
||||
uniqueMembers.addAll(approvers);
|
||||
|
||||
uniqueMembers.stream()
|
||||
.filter(member -> !member.equals(ownerId) && !member.equals(KeycloakSecurity.getUserId()) && (existingDossier.getMemberIds() == null || !existingDossier.getMemberIds()
|
||||
.contains(member)))
|
||||
.filter(member -> !member.equals(ownerId) && !member.equals(KeycloakSecurity.getUserId()) && (existingDossier.getMemberIds() == null
|
||||
|| !existingDossier.getMemberIds().contains(member)))
|
||||
.forEach(member -> notificationPersistenceService.insertNotification(AddNotificationRequest.builder()
|
||||
.userId(member)
|
||||
.issuerId(KeycloakSecurity.getUserId())
|
||||
.notificationType(NotificationType.USER_BECOMES_DOSSIER_MEMBER.name())
|
||||
.target(Map.of("dossierId", dossierRequest.getDossierId()))
|
||||
.build()));
|
||||
.userId(member)
|
||||
.issuerId(KeycloakSecurity.getUserId())
|
||||
.notificationType(NotificationType.USER_BECOMES_DOSSIER_MEMBER.name())
|
||||
.target(Map.of("dossierId", dossierRequest.getDossierId()))
|
||||
.build()));
|
||||
|
||||
if (existingDossier.getMemberIds() != null) {
|
||||
existingDossier.getMemberIds()
|
||||
.stream()
|
||||
.filter(member -> !members.contains(member) && !approvers.contains(member) && !member.equals(KeycloakSecurity.getUserId()))
|
||||
.forEach(member -> notificationPersistenceService.insertNotification(AddNotificationRequest.builder()
|
||||
.userId(member)
|
||||
.issuerId(KeycloakSecurity.getUserId())
|
||||
.notificationType(NotificationType.USER_REMOVED_AS_DOSSIER_MEMBER.name())
|
||||
.target(Map.of("dossierId", dossierRequest.getDossierId()))
|
||||
.build()));
|
||||
.userId(member)
|
||||
.issuerId(KeycloakSecurity.getUserId())
|
||||
.notificationType(NotificationType.USER_REMOVED_AS_DOSSIER_MEMBER.name())
|
||||
.target(Map.of("dossierId", dossierRequest.getDossierId()))
|
||||
.build()));
|
||||
}
|
||||
|
||||
approvers.stream()
|
||||
.filter(approver -> !KeycloakSecurity.getUserId().equals(approver) && existingDossier.getMemberIds() != null && existingDossier.getMemberIds()
|
||||
.contains(approver) && (existingDossier.getApproverIds() == null || !existingDossier.getApproverIds().contains(approver)))
|
||||
.forEach(approver -> notificationPersistenceService.insertNotification(AddNotificationRequest.builder()
|
||||
.userId(approver)
|
||||
.issuerId(KeycloakSecurity.getUserId())
|
||||
.notificationType(NotificationType.USER_PROMOTED_TO_APPROVER.name())
|
||||
.target(Map.of("dossierId", dossierRequest.getDossierId()))
|
||||
.build()));
|
||||
.userId(approver)
|
||||
.issuerId(KeycloakSecurity.getUserId())
|
||||
.notificationType(NotificationType.USER_PROMOTED_TO_APPROVER.name())
|
||||
.target(Map.of("dossierId", dossierRequest.getDossierId()))
|
||||
.build()));
|
||||
|
||||
members.stream()
|
||||
.filter(member -> !member.equals(KeycloakSecurity.getUserId()) && existingDossier.getApproverIds() != null && existingDossier.getApproverIds()
|
||||
.contains(member) && !approvers.contains(member))
|
||||
.filter(member -> !member.equals(KeycloakSecurity.getUserId())
|
||||
&& existingDossier.getApproverIds() != null
|
||||
&& existingDossier.getApproverIds().contains(member)
|
||||
&& !approvers.contains(member))
|
||||
.forEach(member -> notificationPersistenceService.insertNotification(AddNotificationRequest.builder()
|
||||
.userId(member)
|
||||
.issuerId(KeycloakSecurity.getUserId())
|
||||
.notificationType(NotificationType.USER_DEGRADED_TO_REVIEWER.name())
|
||||
.target(Map.of("dossierId", dossierRequest.getDossierId()))
|
||||
.build()));
|
||||
.userId(member)
|
||||
.issuerId(KeycloakSecurity.getUserId())
|
||||
.notificationType(NotificationType.USER_DEGRADED_TO_REVIEWER.name())
|
||||
.target(Map.of("dossierId", dossierRequest.getDossierId()))
|
||||
.build()));
|
||||
|
||||
updatedDossier.setDossierAttributes(convertDossierAttributes(dossierAttributePersistenceService.getDossierAttributes(updatedDossier.getId())));
|
||||
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
|
||||
@ -223,11 +232,11 @@ public class DossierController implements DossierResource {
|
||||
Dossier created = createNewDossier(dossierRequest, ownerId, members, approvers);
|
||||
|
||||
auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(created.getId())
|
||||
.category(AuditCategory.DOSSIER.name())
|
||||
.message("Dossier has been created.")
|
||||
.build());
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(created.getId())
|
||||
.category(AuditCategory.DOSSIER.name())
|
||||
.message("Dossier has been created.")
|
||||
.build());
|
||||
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
|
||||
@ -254,7 +263,9 @@ public class DossierController implements DossierResource {
|
||||
}
|
||||
|
||||
// check he has a manager role, thus he can be the owner
|
||||
if (user.isPresent() && user.get().getRoles().stream().noneMatch(ApplicationRoles.RED_MANAGER_ROLE::equals)) {
|
||||
if (user.isPresent() && user.get().getRoles()
|
||||
.stream()
|
||||
.noneMatch(ApplicationRoles.RED_MANAGER_ROLE::equals)) {
|
||||
throw new BadRequestException("Make sure provided user id has the manager role.");
|
||||
}
|
||||
|
||||
@ -266,7 +277,8 @@ public class DossierController implements DossierResource {
|
||||
private Set<String> getAndValidateMembers(String ownerId, Set<String> memberIds) {
|
||||
|
||||
Set<String> actualMemberIds = memberIds == null ? new TreeSet<>() : memberIds;
|
||||
if (actualMemberIds.stream().anyMatch(Objects::isNull)) {
|
||||
if (actualMemberIds.stream()
|
||||
.anyMatch(Objects::isNull)) {
|
||||
throw new BadRequestException("Member IDs cannot be null");
|
||||
}
|
||||
|
||||
@ -280,7 +292,10 @@ public class DossierController implements DossierResource {
|
||||
Set<String> deletedUserIds = userService.removeDeletedUsers(actualMemberIds);
|
||||
actualMemberIds.removeAll(deletedUserIds);
|
||||
}
|
||||
if (users.stream().anyMatch(u -> u.getRoles().stream().noneMatch(VALID_MEMBER_ROLES::contains))) {
|
||||
if (users.stream()
|
||||
.anyMatch(u -> u.getRoles()
|
||||
.stream()
|
||||
.noneMatch(VALID_MEMBER_ROLES::contains))) {
|
||||
throw new BadRequestException("Make sure each provided member id has the permission to be a member of a dossier.");
|
||||
}
|
||||
return actualMemberIds;
|
||||
@ -299,12 +314,15 @@ public class DossierController implements DossierResource {
|
||||
|
||||
private void updateFileStatusForDossierFiles(String dossierId, Collection<String> members) {
|
||||
|
||||
fileStatusManagementService.getDossierStatus(dossierId).stream().filter(fileStatus -> !fileStatus.isSoftOrHardDeleted()).forEach(f -> {
|
||||
fileStatusManagementService.getDossierStatus(dossierId)
|
||||
.stream()
|
||||
.filter(fileStatus -> !fileStatus.isSoftOrHardDeleted())
|
||||
.forEach(f -> {
|
||||
|
||||
if (f.getAssignee() != null && !members.contains(f.getAssignee())) {
|
||||
fileStatusManagementService.setCurrentFileAssignee(dossierId, f.getId(), null);
|
||||
}
|
||||
});
|
||||
if (f.getAssignee() != null && !members.contains(f.getAssignee())) {
|
||||
fileStatusManagementService.setCurrentFileAssignee(dossierId, f.getId(), null);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@ -312,18 +330,20 @@ public class DossierController implements DossierResource {
|
||||
private Dossier createNewDossier(DossierRequest dossier, String ownerId, Set<String> members, Set<String> approvers) {
|
||||
|
||||
Dossier newDossier = dossierCreatorService.addDossier(CreateOrUpdateDossierRequest.builder()
|
||||
.dossierName(dossier.getDossierName().trim())
|
||||
.description(dossier.getDescription())
|
||||
.dossierTemplateId(dossier.getDossierTemplateId())
|
||||
.downloadFileTypes(dossier.getDownloadFileTypes())
|
||||
.dueDate(dossier.getDueDate())
|
||||
.reportTemplateIds(dossier.getReportTemplateIds() != null ? new ArrayList<>(dossier.getReportTemplateIds()) : Lists.newArrayList())
|
||||
.watermarkId(dossier.getWatermarkId())
|
||||
.previewWatermarkId(dossier.getPreviewWatermarkId())
|
||||
.dossierStatusId(dossier.getDossierStatusId())
|
||||
.build(), members, approvers, ownerId);
|
||||
.dossierName(dossier.getDossierName().trim())
|
||||
.description(dossier.getDescription())
|
||||
.dossierTemplateId(dossier.getDossierTemplateId())
|
||||
.downloadFileTypes(dossier.getDownloadFileTypes())
|
||||
.dueDate(dossier.getDueDate())
|
||||
.reportTemplateIds(dossier.getReportTemplateIds()
|
||||
!= null ? new ArrayList<>(dossier.getReportTemplateIds()) : Lists.newArrayList())
|
||||
.watermarkId(dossier.getWatermarkId())
|
||||
.previewWatermarkId(dossier.getPreviewWatermarkId())
|
||||
.dossierStatusId(dossier.getDossierStatusId())
|
||||
.build(), members, approvers, ownerId);
|
||||
|
||||
dossierACLService.enhanceDossierWithACLData(newDossier);
|
||||
newDossier.setDossierAttributes(new DossierAttributes());
|
||||
|
||||
return newDossier;
|
||||
|
||||
@ -358,21 +378,21 @@ public class DossierController implements DossierResource {
|
||||
dossierManagementService.delete(dossierId);
|
||||
|
||||
auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(dossierId)
|
||||
.category(AuditCategory.DOSSIER.name())
|
||||
.message("Dossier moved to trash.")
|
||||
.build());
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(dossierId)
|
||||
.category(AuditCategory.DOSSIER.name())
|
||||
.message("Dossier moved to trash.")
|
||||
.build());
|
||||
|
||||
dossier.getMemberIds()
|
||||
.stream()
|
||||
.filter(m -> !KeycloakSecurity.getUserId().equals(m))
|
||||
.forEach(member -> notificationPersistenceService.insertNotification(AddNotificationRequest.builder()
|
||||
.userId(member)
|
||||
.issuerId(KeycloakSecurity.getUserId())
|
||||
.notificationType(NotificationType.DOSSIER_DELETED.name())
|
||||
.target(Map.of("dossierId", dossierId, "dossierName", dossier.getDossierName()))
|
||||
.build()));
|
||||
.userId(member)
|
||||
.issuerId(KeycloakSecurity.getUserId())
|
||||
.notificationType(NotificationType.DOSSIER_DELETED.name())
|
||||
.target(Map.of("dossierId", dossierId, "dossierName", dossier.getDossierName()))
|
||||
.build()));
|
||||
|
||||
}
|
||||
|
||||
@ -383,8 +403,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);
|
||||
}
|
||||
|
||||
|
||||
@ -393,7 +414,12 @@ public class DossierController implements DossierResource {
|
||||
public List<Dossier> 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).stream().map(dossierACLService::enhanceDossierWithACLData).collect(Collectors.toList());
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -403,10 +429,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;
|
||||
}
|
||||
|
||||
|
||||
@ -414,8 +442,12 @@ public class DossierController implements DossierResource {
|
||||
@PostFilter("hasPermission(filterObject.id, 'Dossier', 'VIEW_OBJECT')")
|
||||
public List<Dossier> getSoftDeletedDossiers() {
|
||||
|
||||
return dossierManagementService.getSoftDeletedDossiers().stream().map(dossierACLService::enhanceDossierWithACLData).collect(Collectors.toList());
|
||||
|
||||
var dossiers = dossierManagementService.getSoftDeletedDossiers()
|
||||
.stream()
|
||||
.map(dossierACLService::enhanceDossierWithACLData)
|
||||
.collect(Collectors.toList());
|
||||
dossiers.forEach(dossier -> dossier.setDossierAttributes(convertDossierAttributes(dossierAttributePersistenceService.getDossierAttributes(dossier.getId()))));
|
||||
return dossiers;
|
||||
}
|
||||
|
||||
|
||||
@ -423,7 +455,12 @@ public class DossierController implements DossierResource {
|
||||
@PostFilter("hasPermission(filterObject.id, 'Dossier', 'VIEW_OBJECT')")
|
||||
public List<Dossier> getArchivedDossiers() {
|
||||
|
||||
return dossierManagementService.getArchivedDossiers().stream().map(dossierACLService::enhanceDossierWithACLData).collect(Collectors.toList());
|
||||
var dossiers = dossierManagementService.getArchivedDossiers()
|
||||
.stream()
|
||||
.map(dossierACLService::enhanceDossierWithACLData)
|
||||
.collect(Collectors.toList());
|
||||
dossiers.forEach(dossier -> dossier.setDossierAttributes(convertDossierAttributes(dossierAttributePersistenceService.getDossierAttributes(dossier.getId()))));
|
||||
return dossiers;
|
||||
}
|
||||
|
||||
|
||||
@ -431,10 +468,12 @@ public class DossierController implements DossierResource {
|
||||
@PostFilter("hasPermission(filterObject.id, 'Dossier', 'VIEW_OBJECT')")
|
||||
public List<Dossier> 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;
|
||||
}
|
||||
|
||||
|
||||
@ -449,11 +488,11 @@ public class DossierController implements DossierResource {
|
||||
|
||||
for (String dossierId : dossierIds) {
|
||||
auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(dossierId)
|
||||
.category(AuditCategory.DOSSIER.name())
|
||||
.message("Dossier archived.")
|
||||
.build());
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(dossierId)
|
||||
.category(AuditCategory.DOSSIER.name())
|
||||
.message("Dossier archived.")
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
@ -466,11 +505,11 @@ public class DossierController implements DossierResource {
|
||||
|
||||
for (String dossierId : dossierIds) {
|
||||
auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(dossierId)
|
||||
.category(AuditCategory.DOSSIER.name())
|
||||
.message("Dossier restored from archive.")
|
||||
.build());
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(dossierId)
|
||||
.category(AuditCategory.DOSSIER.name())
|
||||
.message("Dossier restored from archive.")
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
@ -486,11 +525,11 @@ public class DossierController implements DossierResource {
|
||||
for (String dossierId : filteredDossierIds) {
|
||||
|
||||
auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(dossierId)
|
||||
.category(AuditCategory.DOSSIER.name())
|
||||
.message("Dossier permanently deleted.")
|
||||
.build());
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(dossierId)
|
||||
.category(AuditCategory.DOSSIER.name())
|
||||
.message("Dossier permanently deleted.")
|
||||
.build());
|
||||
|
||||
}
|
||||
}
|
||||
@ -506,11 +545,11 @@ public class DossierController implements DossierResource {
|
||||
|
||||
for (String dossierId : filteredDossierIds) {
|
||||
auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(dossierId)
|
||||
.category(AuditCategory.DOSSIER.name())
|
||||
.message("Dossier restored from trash.")
|
||||
.build());
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(dossierId)
|
||||
.category(AuditCategory.DOSSIER.name())
|
||||
.message("Dossier restored from trash.")
|
||||
.build());
|
||||
|
||||
}
|
||||
}
|
||||
@ -526,5 +565,15 @@ public class DossierController implements DossierResource {
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
|
||||
private DossierAttributes convertDossierAttributes(List<DossierAttributeEntity> dossierAttributeEntities) {
|
||||
|
||||
Map<String, String> attributeIdToValue = new HashMap<>();
|
||||
for (DossierAttributeEntity dossierAttributeEntity : dossierAttributeEntities) {
|
||||
attributeIdToValue.put(dossierAttributeEntity.getId().getDossierAttributeConfigId(), dossierAttributeEntity.getValue());
|
||||
}
|
||||
return new DossierAttributes(attributeIdToValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -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,
|
||||
@ -42,7 +66,9 @@ public class DossierControllerV2 implements DossierResource {
|
||||
var dossiers = dossierController.getDossiersForDossierTemplate(dossierTemplateId, includeArchived, includeSoftDeleted);
|
||||
|
||||
if (!includeActive) {
|
||||
return new DossierList(dossiers.stream().filter(dossier -> dossier.getSoftDeletedTime() != null || dossier.getArchivedTime() != null).toList());
|
||||
return new DossierList(dossiers.stream()
|
||||
.filter(dossier -> dossier.getSoftDeletedTime() != null || dossier.getArchivedTime() != null)
|
||||
.toList());
|
||||
}
|
||||
|
||||
return new DossierList(dossiers);
|
||||
@ -77,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()
|
||||
|
||||
@ -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;
|
||||
@ -28,6 +30,8 @@ import com.iqser.red.persistence.service.v1.external.api.impl.controller.FileAtt
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
|
||||
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.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.StringEncodingUtils;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.AuditCategory;
|
||||
@ -35,6 +39,10 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierTemp
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.RuleFileType;
|
||||
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.rules.RulesUploadRequest;
|
||||
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.model.RulesValidationMessage;
|
||||
@ -62,6 +70,8 @@ public class DossierTemplateControllerV2 implements DossierTemplateResource {
|
||||
private final RulesValidationService rulesValidationService;
|
||||
private final AuditPersistenceService auditPersistenceService;
|
||||
private final FileAttributesController fileAttributesController;
|
||||
private final DossierStatusPersistenceService dossierStatusPersistenceService;
|
||||
private final DossierAttributeConfigPersistenceService dossierAttributeConfigPersistenceService;
|
||||
|
||||
|
||||
public List<DossierTemplateModel> getAllDossierTemplates() {
|
||||
@ -134,7 +144,8 @@ public class DossierTemplateControllerV2 implements DossierTemplateResource {
|
||||
.filenameMappingCsvColumnHeader(fileAttributeConfigs.getFilenameMappingColumnHeaderName())
|
||||
.build();
|
||||
|
||||
var fileAttributeDefinitions = fileAttributeConfigs.getFileAttributeConfigs().stream()
|
||||
var fileAttributeDefinitions = fileAttributeConfigs.getFileAttributeConfigs()
|
||||
.stream()
|
||||
.map(fileAttributeConfig -> FileAttributeDefinition.builder()
|
||||
.id(fileAttributeConfig.getId())
|
||||
.name(fileAttributeConfig.getLabel())
|
||||
@ -142,11 +153,11 @@ public class DossierTemplateControllerV2 implements DossierTemplateResource {
|
||||
.mappedCsvColumnHeader(fileAttributeConfig.getCsvColumnHeader())
|
||||
.reportingPlaceholder(fileAttributeConfig.getPlaceholder())
|
||||
.displaySettings(FileAttributeDefinition.DisplaySettings.builder()
|
||||
.primaryAttribute(fileAttributeConfig.isPrimaryAttribute())
|
||||
.editable(fileAttributeConfig.isEditable())
|
||||
.filterable(fileAttributeConfig.isFilterable())
|
||||
.displayedInFileList(fileAttributeConfig.isDisplayedInFileList())
|
||||
.build())
|
||||
.primaryAttribute(fileAttributeConfig.isPrimaryAttribute())
|
||||
.editable(fileAttributeConfig.isEditable())
|
||||
.filterable(fileAttributeConfig.isFilterable())
|
||||
.displayedInFileList(fileAttributeConfig.isDisplayedInFileList())
|
||||
.build())
|
||||
.build())
|
||||
.toList();
|
||||
|
||||
@ -154,6 +165,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<RulesValidationResponse> uploadRules(String dossierTemplateId, RuleFileType ruleFileType, MultipartFile file, boolean dryRun) {
|
||||
|
||||
@ -188,11 +236,11 @@ public class DossierTemplateControllerV2 implements DossierTemplateResource {
|
||||
}
|
||||
|
||||
auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(rulesUploadRequest.getDossierTemplateId())
|
||||
.category(AuditCategory.DOSSIER_TEMPLATE.name())
|
||||
.message(String.format("%s rules have been %s", rulesUploadRequest.getRuleFileType(), dryRun ? "validated" : "updated"))
|
||||
.build());
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(rulesUploadRequest.getDossierTemplateId())
|
||||
.category(AuditCategory.DOSSIER_TEMPLATE.name())
|
||||
.message(String.format("%s rules have been %s", rulesUploadRequest.getRuleFileType(), dryRun ? "validated" : "updated"))
|
||||
.build());
|
||||
|
||||
// TODO Add warning and deprecations to response
|
||||
return new ResponseEntity<>(RulesValidationResponse.builder().build(), HttpStatus.OK);
|
||||
@ -208,7 +256,8 @@ public class DossierTemplateControllerV2 implements DossierTemplateResource {
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.setContentType(MediaType.TEXT_PLAIN);
|
||||
|
||||
httpHeaders.add("Content-Disposition", "attachment" + "; filename*=utf-8''" + StringEncodingUtils.urlEncode(ruleFileType.name().toLowerCase(Locale.ROOT) + RULES_DOWNLOAD_FILE_NAME_SUFFIX));
|
||||
httpHeaders.add("Content-Disposition",
|
||||
"attachment" + "; filename*=utf-8''" + StringEncodingUtils.urlEncode(ruleFileType.name().toLowerCase(Locale.ROOT) + RULES_DOWNLOAD_FILE_NAME_SUFFIX));
|
||||
|
||||
InputStream is = new ByteArrayInputStream(data);
|
||||
|
||||
|
||||
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -11,7 +11,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;
|
||||
|
||||
@ -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<String> reportTemplateIds = new ArrayList<>();
|
||||
private Set<DownloadFileType> downloadFileTypes = new HashSet<>();
|
||||
private String redactionPreviewColor;
|
||||
private List<String> fileIds = new ArrayList<>();
|
||||
}
|
||||
@ -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;
|
||||
|
||||
}
|
||||
@ -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<DossierAttributeDefinition> dossierAttributeDefinitions= new ArrayList<>();
|
||||
}
|
||||
@ -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;
|
||||
|
||||
}
|
||||
@ -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<DossierStatusDefinition> dossierStatusDefinitions = new ArrayList<>();
|
||||
}
|
||||
@ -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<String> reportTemplateIds = new ArrayList<>();
|
||||
private Set<DownloadFileType> downloadFileTypes = new HashSet<>();
|
||||
private String redactionPreviewColor;
|
||||
|
||||
}
|
||||
@ -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<String> fileIds = new ArrayList<>();
|
||||
private List<DownloadFileType> downloadFileTypes = new ArrayList<>();
|
||||
private List<String> reportTemplateIds = new ArrayList<>();
|
||||
|
||||
}
|
||||
@ -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> downloadStatus = new ArrayList<>();
|
||||
|
||||
}
|
||||
@ -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);
|
||||
|
||||
}
|
||||
|
||||
@ -2,6 +2,8 @@ package com.iqser.red.service.persistence.service.v2.api.external.resource;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierTemplateModel;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.RuleFileType;
|
||||
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 com.iqser.red.service.persistence.service.v2.api.external.model.FileAttributeDefinitionList;
|
||||
import com.iqser.red.service.persistence.service.v2.api.external.model.RulesValidationResponse;
|
||||
|
||||
@ -36,13 +38,13 @@ public interface DossierTemplateResource {
|
||||
|
||||
String ENTITY_RULES_PATH = "/entity-rules";
|
||||
String COMPONENT_RULES_PATH = "/component-rules";
|
||||
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";
|
||||
String DOSSIER_TEMPLATE_ID_PATH_VARIABLE = "/{" + DOSSIER_TEMPLATE_ID_PARAM + "}";
|
||||
|
||||
String RULE_FILE_TYPE_PARAMETER_NAME = "ruleFileType";
|
||||
|
||||
String DRY_RUN_PARAM = "dryRun";
|
||||
|
||||
|
||||
@ -54,64 +56,61 @@ public interface DossierTemplateResource {
|
||||
|
||||
@GetMapping(value = PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Get a specific DossierTemplate by its identifier.", description = "None")
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(responseCode = "200", description = "Get a specific DossierTemplate by its identifier."),
|
||||
@ApiResponse(responseCode = "404", description = "The DossierTemplate is not found.")
|
||||
})
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Get a specific DossierTemplate by its identifier."), @ApiResponse(responseCode = "404", description = "The DossierTemplate is not found.")})
|
||||
DossierTemplateModel getDossierTemplate(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId);
|
||||
|
||||
|
||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||
@PostMapping(value = PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + ENTITY_RULES_PATH, consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Upload a component or entity rules file in drools format for a specific DossierTemplate.")
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(responseCode = "200", description = "Rules upload successful."),
|
||||
@ApiResponse(responseCode = "404", description = "The DossierTemplate is not found."),
|
||||
@ApiResponse(responseCode = "422", description = "Uploaded rules could not be verified.")
|
||||
})
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Rules upload successful."), @ApiResponse(responseCode = "404", description = "The DossierTemplate is not found."), @ApiResponse(responseCode = "422", description = "Uploaded rules could not be verified.")})
|
||||
ResponseEntity<RulesValidationResponse> uploadEntityRules(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
|
||||
@Schema(type = "string", format = "binary", name = "file") @RequestPart(name = "file") MultipartFile file,
|
||||
@Parameter(name = DRY_RUN_PARAM, description = "If true rules will be only validated not stored.") @RequestParam(value = DRY_RUN_PARAM, required = false ,defaultValue = "false") boolean dryRun);
|
||||
@Schema(type = "string", format = "binary", name = "file") @RequestPart(name = "file") MultipartFile file,
|
||||
@Parameter(name = DRY_RUN_PARAM, description = "If true rules will be only validated not stored.") @RequestParam(value = DRY_RUN_PARAM, required = false, defaultValue = "false") boolean dryRun);
|
||||
|
||||
|
||||
@ResponseBody
|
||||
@ResponseStatus(value = HttpStatus.OK)
|
||||
@Operation(summary = "Returns file containing the currently used entity rules.")
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(responseCode = "200", description = "OK"),
|
||||
@ApiResponse(responseCode = "404", description = "The DossierTemplate is not found.")
|
||||
})
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "The DossierTemplate is not found.")})
|
||||
@GetMapping(value = PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + ENTITY_RULES_PATH)
|
||||
ResponseEntity<?> downloadEntityRules(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId);
|
||||
|
||||
|
||||
|
||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||
@PostMapping(value = PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + COMPONENT_RULES_PATH, consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@PostMapping(value = PATH
|
||||
+ DOSSIER_TEMPLATE_ID_PATH_VARIABLE
|
||||
+ COMPONENT_RULES_PATH, consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Upload a component or entity rules file in drools format for a specific DossierTemplate.")
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(responseCode = "200", description = "Rules upload successful."),
|
||||
@ApiResponse(responseCode = "404", description = "The DossierTemplate is not found."),
|
||||
@ApiResponse(responseCode = "422", description = "Uploaded rules could not be verified.")
|
||||
})
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Rules upload successful."), @ApiResponse(responseCode = "404", description = "The DossierTemplate is not found."), @ApiResponse(responseCode = "422", description = "Uploaded rules could not be verified.")})
|
||||
ResponseEntity<RulesValidationResponse> uploadComponentRules(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
|
||||
@Schema(type = "string", format = "binary", name = "file") @RequestPart(name = "file") MultipartFile file,
|
||||
@Parameter(name = DRY_RUN_PARAM, description = "If true rules will be only validated not stored.") @RequestParam(value = DRY_RUN_PARAM, required = false ,defaultValue = "false") boolean dryRun);
|
||||
@Schema(type = "string", format = "binary", name = "file") @RequestPart(name = "file") MultipartFile file,
|
||||
@Parameter(name = DRY_RUN_PARAM, description = "If true rules will be only validated not stored.") @RequestParam(value = DRY_RUN_PARAM, required = false, defaultValue = "false") boolean dryRun);
|
||||
|
||||
|
||||
@ResponseBody
|
||||
@ResponseStatus(value = HttpStatus.OK)
|
||||
@Operation(summary = "Returns file containing the currently used component rules.")
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(responseCode = "200", description = "OK"),
|
||||
@ApiResponse(responseCode = "404", description = "The DossierTemplate is not found.")
|
||||
})
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "The DossierTemplate is not found.")})
|
||||
@GetMapping(value = PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + COMPONENT_RULES_PATH)
|
||||
ResponseEntity<?> downloadComponentRules(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId);
|
||||
|
||||
|
||||
@Operation(summary = "Get the file attribute definitions of a DossierTemplate.", description = "None")
|
||||
@GetMapping(value = PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + FILE_ATTRIBUTE_DEFINITIONS_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(responseCode = "200", description = "File attribute definitions returned successfully."),
|
||||
@ApiResponse(responseCode = "404", description = "The DossierTemplate is not found.")
|
||||
})
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "File attribute definitions returned successfully."), @ApiResponse(responseCode = "404", description = "The DossierTemplate is not found.")})
|
||||
FileAttributeDefinitionList getFileAttributeDefinitions(@PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId);
|
||||
|
||||
|
||||
@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);
|
||||
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
}
|
||||
@ -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);
|
||||
|
||||
}
|
||||
|
||||
@ -45,6 +45,8 @@ public class DownloadStatusEntity {
|
||||
@Id
|
||||
String storageId;
|
||||
@Column
|
||||
String uuid;
|
||||
@Column
|
||||
String userId;
|
||||
@Column
|
||||
String filename;
|
||||
|
||||
@ -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);
|
||||
@ -105,6 +107,7 @@ public class DownloadStatusPersistenceService {
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public DownloadStatusEntity getStatus(String storageId) {
|
||||
|
||||
return downloadStatusRepository.findById(storageId).orElseThrow(() -> new NotFoundException(String.format("DownloadStatus not found for storageId: %s", storageId)));
|
||||
@ -125,6 +128,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<DownloadStatusEntity> getStatus() {
|
||||
|
||||
return downloadStatusRepository.findAll();
|
||||
|
||||
@ -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<DownloadStatusEn
|
||||
|
||||
List<DownloadStatusEntity> 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<DownloadStatusEntity> findByUuid(String uuid);
|
||||
|
||||
@Modifying
|
||||
@Query("update DownloadStatusEntity ds set ds.status = :status where ds.storageId = :storageId")
|
||||
|
||||
@ -199,3 +199,5 @@ databaseChangeLog:
|
||||
file: db/changelog/tenant/sql/207-acl-migration-cleanup.sql
|
||||
- include:
|
||||
file: db/changelog/tenant/125-drop-not-null-for-legal-basis-in-manual-recategorization.yaml
|
||||
- include:
|
||||
file: 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
|
||||
@ -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
|
||||
|
||||
@ -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<String, String> attributeIdToValue = new HashMap<>();
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user