From a2ee61c08719da36f69e6c4e67bcd00d605c7e74 Mon Sep 17 00:00:00 2001 From: Timo Bejan Date: Tue, 14 Sep 2021 12:02:35 +0300 Subject: [PATCH] Initial Commit --- .gitignore | 28 + CHANGELOG.md | 12 + bamboo-specs/pom.xml | 37 ++ .../src/main/java/buildjob/PlanSpec.java | 118 ++++ .../src/main/resources/scripts/build-java.sh | 51 ++ .../src/test/java/buildjob/PlanSpecTest.java | 17 + persistence-service-image-v1/pom.xml | 96 +++ .../src/main/docker/Dockerfile | 9 + .../persistence-service-api-v1/pom.xml | 55 ++ .../v1/api/model/AddRedactionRequest.java | 32 + .../v1/api/model/BinaryFileRequest.java | 20 + .../v1/api/model/BinaryFileResult.java | 16 + .../service/v1/api/model/CommentRequest.java | 17 + .../model/CreateOrUpdateDossierRequest.java | 49 ++ .../CreateOrUpdateDossierTemplateRequest.java | 40 ++ .../service/v1/api/model/DeletedDossier.java | 15 + .../model/DigitalSignatureUpdateModel.java | 16 + .../service/v1/api/model/DownloadRequest.java | 20 + .../service/v1/api/model/FileType.java | 15 + .../v1/api/model/ForceRedactionRequest.java | 21 + .../model/ImageRecategorizationRequest.java | 21 + .../v1/api/model/ImportCsvRequest.java | 16 + .../v1/api/model/ImportCsvResponse.java | 23 + .../service/v1/api/model/JSONPrimitive.java | 12 + .../v1/api/model/LegalBasisChangeRequest.java | 21 + .../service/v1/api/model/LicenseReport.java | 40 ++ .../v1/api/model/LicenseReportRequest.java | 50 ++ .../v1/api/model/ManualAddResponse.java | 16 + .../v1/api/model/ManualRedactions.java | 35 ++ .../v1/api/model/RemoveRedactionRequest.java | 21 + .../service/v1/api/model/ReportData.java | 21 + .../v1/api/model/ReportTemplateDownload.java | 15 + .../model/ReportTemplateUploadRequest.java | 21 + .../v1/api/model/SetDownloadedRequest.java | 13 + .../model/data/annotations/AnnotationId.java | 22 + .../data/annotations/AnnotationStatus.java | 8 + .../api/model/data/annotations/Comment.java | 40 ++ .../api/model/data/annotations/IdRemoval.java | 38 ++ .../annotations/ManualForceRedaction.java | 38 ++ .../ManualImageRecategorization.java | 37 ++ .../annotations/ManualLegalBasisChange.java | 39 ++ .../annotations/ManualRedactionEntry.java | 49 ++ .../api/model/data/annotations/Rectangle.java | 29 + .../model/data/annotations/ViewedPage.java | 39 ++ .../api/model/data/configuration/Colors.java | 50 ++ .../data/configuration/DictionaryEntry.java | 26 + .../data/configuration/DigitalSignature.java | 35 ++ .../FileAttributesGeneralConfiguration.java | 28 + .../model/data/configuration/LegalBasis.java | 28 + .../data/configuration/LegalBasisMapping.java | 24 + .../api/model/data/configuration/RuleSet.java | 26 + .../data/configuration/SMTPConfiguration.java | 48 ++ .../v1/api/model/data/configuration/Type.java | 56 ++ .../model/data/configuration/Watermark.java | 41 ++ .../v1/api/model/data/dossier/Dossier.java | 78 +++ .../model/data/dossier/DossierAttribute.java | 41 ++ .../data/dossier/DossierAttributeConfig.java | 35 ++ .../api/model/data/dossier/DossierStatus.java | 5 + .../model/data/dossier/DossierTemplate.java | 57 ++ .../model/data/dossier/DownloadFileType.java | 5 + .../v1/api/model/data/dossier/File.java | 124 ++++ .../api/model/data/dossier/FileAttribute.java | 38 ++ .../data/dossier/FileAttributeConfig.java | 40 ++ .../v1/api/model/data/dossier/FileStatus.java | 5 + .../model/data/dossier/ReportTemplate.java | 35 ++ .../model/data/download/DownloadStatus.java | 49 ++ .../data/download/DownloadStatusValue.java | 2 + .../service/v1/api/model/lombok.config | 1 + .../v1/api/resources/DictionaryResource.java | 89 +++ .../resources/DigitalSignatureResource.java | 28 + .../resources/DossierAttributesResource.java | 50 ++ .../v1/api/resources/DossierResource.java | 47 ++ .../resources/DossierTemplateResource.java | 40 ++ .../v1/api/resources/DownloadResource.java | 32 + .../api/resources/FileAttributesResource.java | 64 ++ .../FileStatusProcessingUpdateResource.java | 57 ++ .../resources/LegalBasisMappingResource.java | 33 + .../api/resources/LicenseReportResource.java | 18 + .../resources/ManualRedactionResource.java | 154 +++++ .../v1/api/resources/ReanalysisResource.java | 53 ++ .../api/resources/RedactionLogResource.java | 31 + .../api/resources/ReportTemplateResource.java | 41 ++ .../v1/api/resources/RulesResource.java | 29 + .../resources/SMTPConfigurationResource.java | 40 ++ .../v1/api/resources/StatusResource.java | 71 +++ .../v1/api/resources/UploadResource.java | 71 +++ .../api/resources/UserPreferenceResource.java | 34 ++ .../v1/api/resources/ViewedPagesResource.java | 35 ++ .../v1/api/resources/WatermarkResource.java | 26 + .../persistence-service-processor-v1/pom.xml | 95 +++ ...sistenceServiceProcessorConfiguration.java | 12 + .../client/PDFTronRedactionClient.java | 9 + .../exception/BadRequestException.java | 13 + .../exception/ConflictException.java | 9 + .../exception/DossierNotFoundException.java | 11 + .../exception/FileNotFoundException.java | 9 + .../InternalServerErrorException.java | 13 + .../exception/NotFoundException.java | 9 + .../exception/UserNotFoundException.java | 10 + .../exception/ValidationException.java | 9 + .../v1/processor/model/UnprocessedFile.java | 13 + .../v1/processor/service/ColorsService.java | 29 + .../service/DigitalSignatureService.java | 64 ++ .../v1/processor/service/EmailService.java | 106 ++++ .../service/EncryptionDecryptionService.java | 61 ++ .../processor/service/WatermarkService.java | 30 + .../AddRedactionPersistenceService.java | 91 +++ .../CommentPersistenceService.java | 68 +++ .../DictionaryPersistenceService.java | 114 ++++ ...sierAttributeConfigPersistenceService.java | 97 +++ .../DossierAttributePersistenceService.java | 42 ++ .../DossierPersistenceService.java | 118 ++++ .../DossierTemplatePersistenceService.java | 72 +++ .../DownloadStatusPersistenceService.java | 89 +++ .../persistence/EntryPersistenceService.java | 56 ++ ...FileAttributeConfigPersistenceService.java | 116 ++++ .../FileStatusPersistenceService.java | 314 ++++++++++ .../ForceRedactionPersistenceService.java | 73 +++ ...ageRecategorizationPersistenceService.java | 74 +++ .../LegalBasisChangePersistenceService.java | 74 +++ .../RemoveRedactionPersistenceService.java | 83 +++ .../ReportTemplatePersistenceService.java | 53 ++ .../persistence/RulesPersistenceService.java | 40 ++ .../persistence/SMTPConfigurationService.java | 28 + .../ViewedPagesPersistenceService.java | 42 ++ .../repository/ColorsRepository.java | 7 + .../repository/CommentRepository.java | 14 + .../DigitalSignatureRepository.java | 7 + .../DossierAttributeConfigRepository.java | 13 + .../DossierAttributeRepository.java | 12 + .../repository/DossierRepository.java | 7 + .../repository/DossierTemplateRepository.java | 10 + .../repository/DownloadStatusRepository.java | 10 + .../repository/EntryRepository.java | 15 + .../FileAttributeConfigRepository.java | 13 + ...ributesGeneralConfigurationRepository.java | 7 + .../repository/FileRepository.java | 10 + .../repository/ForceRedactionRepository.java | 12 + .../ImageRecategorizationRepository.java | 11 + .../LegalBasisChangeRepository.java | 12 + .../LegalBasisMappingRepository.java | 11 + .../repository/ManualRedactionRepository.java | 12 + .../repository/RemoveRedactionRepository.java | 12 + .../repository/ReportTemplateRepository.java | 10 + .../repository/RuleSetRepository.java | 8 + .../repository/SMTPRepository.java | 7 + .../repository/TypeRepository.java | 22 + .../repository/ViewedPagesRepository.java | 14 + .../repository/WatermarkRepository.java | 7 + .../settings/FileUploadSettings.java | 16 + .../src/test/resources/application.yml | 10 + .../src/test/resources/log4j2-test.xml | 15 + .../persistence-service-server-v1/pom.xml | 215 +++++++ .../management/v1/server/Application.java | 59 ++ .../management/v1/server/ResourceLoader.java | 45 ++ .../v1/server/TextNormalizationUtilities.java | 17 + .../server/client/PDFTronRedactionClient.java | 10 + .../v1/server/client/RedactionClient.java | 9 + .../server/client/RedactionServiceClient.java | 8 + .../v1/server/client/SearchClient.java | 10 + ...CleanupDownloadSchedulerConfiguration.java | 31 + .../configuration/MessagingConfiguration.java | 147 +++++ .../server/controller/ControllerAdvice.java | 62 ++ .../controller/DictionaryController.java | 299 ++++++++++ .../DigitalSignatureController.java | 38 ++ .../DossierAttributesController.java | 48 ++ .../server/controller/DossierController.java | 135 +++++ .../controller/DossierTemplateController.java | 43 ++ .../server/controller/DownloadController.java | 154 +++++ .../controller/FileAttributesController.java | 58 ++ .../controller/FileStatusController.java | 131 ++++ .../FileStatusProcessingUpdateController.java | 63 ++ .../LegalBasisMappingController.java | 49 ++ .../controller/LicenseReportController.java | 29 + .../controller/ManualRedactionController.java | 222 +++++++ .../controller/ReanalysisController.java | 177 ++++++ .../controller/RedactionLogController.java | 35 ++ .../controller/ReportTemplateController.java | 87 +++ .../v1/server/controller/RulesController.java | 51 ++ .../SMTPConfigurationController.java | 71 +++ .../server/controller/UploadController.java | 175 ++++++ .../controller/ViewedPagesController.java | 39 ++ .../controller/WatermarkController.java | 29 + .../exception/InvalidRulesException.java | 9 + .../server/exception/JSONParseException.java | 10 + .../v1/server/model/DownloadJob.java | 18 + .../DictionarySearchAndNotifyService.java | 65 ++ .../v1/server/service/DossierService.java | 98 +++ .../service/ExcludeFromAnalysisService.java | 73 +++ .../service/FileManagementStorageService.java | 99 +++ .../v1/server/service/FileService.java | 229 +++++++ .../FileStatusProcessingUpdateService.java | 105 ++++ .../v1/server/service/FileStatusService.java | 274 +++++++++ .../v1/server/service/IndexingService.java | 97 +++ .../server/service/LicenseReportService.java | 121 ++++ .../ManualRedactionProviderService.java | 47 ++ .../service/ManualRedactionService.java | 563 ++++++++++++++++++ .../service/ManualRedactionsConverter.java | 160 +++++ .../server/service/RedactionLogService.java | 48 ++ .../download/DownloadCleanupService.java | 73 +++ .../download/DownloadDLQMessageReceiver.java | 69 +++ .../download/DownloadMessageReceiver.java | 79 +++ .../download/DownloadPreparationService.java | 246 ++++++++ .../DownloadReportCleanupService.java | 28 + .../DownloadReportMessageReceiver.java | 36 ++ .../FileManagementServiceSettings.java | 23 + .../utils/FileSystemBackedArchiver.java | 100 ++++ .../v1/server/utils/StorageIdUtils.java | 22 + .../validation/DictionaryValidator.java | 82 +++ .../src/main/resources/application-dev.yml | 19 + .../src/main/resources/application.yml | 48 ++ .../src/main/resources/banner.txt | 22 + .../src/main/resources/bootstrap.yml | 7 + .../controller/DossierControllerTest.java | 91 +++ .../controller/FileStatusControllerTest.java | 109 ++++ .../LicenseReportControllerTest.java | 63 ++ .../controller/ReanalysisControllerTest.java | 85 +++ ...stractFileManagementServerServiceTest.java | 58 ++ .../integration/DossierAttributesTest.java | 147 +++++ .../server/integration/DossierDeleteTest.java | 232 ++++++++ .../integration/ExcludeFromAnalysisTest.java | 86 +++ .../integration/FileAttributesTest.java | 80 +++ .../FileSystemBackedStorageService.java | 61 ++ .../integration/ManualRedactionTest.java | 144 +++++ .../integration/ReportTemplateTest.java | 96 +++ .../server/integration/ViewedPagesTest.java | 42 ++ .../v1/server/service/DossierServiceTest.java | 66 ++ .../service/DownloadCleanupServiceTest.java | 163 +++++ .../service/LicenseReportServiceTest.java | 310 ++++++++++ .../utils/FileSystemBackArchiverTest.java | 54 ++ .../src/test/resources/application.yml | 29 + .../test/resources/files/export_summary.csv | 5 + persistence-service-v1/pom.xml | 44 ++ pom.xml | 21 + 234 files changed, 13120 insertions(+) create mode 100644 .gitignore create mode 100644 CHANGELOG.md create mode 100644 bamboo-specs/pom.xml create mode 100644 bamboo-specs/src/main/java/buildjob/PlanSpec.java create mode 100755 bamboo-specs/src/main/resources/scripts/build-java.sh create mode 100644 bamboo-specs/src/test/java/buildjob/PlanSpecTest.java create mode 100644 persistence-service-image-v1/pom.xml create mode 100644 persistence-service-image-v1/src/main/docker/Dockerfile create mode 100644 persistence-service-v1/persistence-service-api-v1/pom.xml create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/AddRedactionRequest.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/BinaryFileRequest.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/BinaryFileResult.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/CommentRequest.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/CreateOrUpdateDossierRequest.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/CreateOrUpdateDossierTemplateRequest.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/DeletedDossier.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/DigitalSignatureUpdateModel.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/DownloadRequest.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/FileType.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ForceRedactionRequest.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ImageRecategorizationRequest.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ImportCsvRequest.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ImportCsvResponse.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/JSONPrimitive.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/LegalBasisChangeRequest.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/LicenseReport.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/LicenseReportRequest.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ManualAddResponse.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ManualRedactions.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/RemoveRedactionRequest.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ReportData.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ReportTemplateDownload.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ReportTemplateUploadRequest.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/SetDownloadedRequest.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/AnnotationId.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/AnnotationStatus.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/Comment.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/IdRemoval.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/ManualForceRedaction.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/ManualImageRecategorization.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/ManualLegalBasisChange.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/ManualRedactionEntry.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/Rectangle.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/ViewedPage.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/Colors.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/DictionaryEntry.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/DigitalSignature.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/FileAttributesGeneralConfiguration.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/LegalBasis.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/LegalBasisMapping.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/RuleSet.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/SMTPConfiguration.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/Type.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/Watermark.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/Dossier.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/DossierAttribute.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/DossierAttributeConfig.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/DossierStatus.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/DossierTemplate.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/DownloadFileType.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/File.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/FileAttribute.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/FileAttributeConfig.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/FileStatus.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/ReportTemplate.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/download/DownloadStatus.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/download/DownloadStatusValue.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/lombok.config create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DictionaryResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DigitalSignatureResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DossierAttributesResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DossierResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DossierTemplateResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DownloadResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/FileAttributesResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/FileStatusProcessingUpdateResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/LegalBasisMappingResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/LicenseReportResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/ManualRedactionResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/ReanalysisResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/RedactionLogResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/ReportTemplateResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/RulesResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/SMTPConfigurationResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/StatusResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/UploadResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/UserPreferenceResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/ViewedPagesResource.java create mode 100644 persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/WatermarkResource.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/pom.xml create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/PersistenceServiceProcessorConfiguration.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/client/PDFTronRedactionClient.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/BadRequestException.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/ConflictException.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/DossierNotFoundException.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/FileNotFoundException.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/InternalServerErrorException.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/NotFoundException.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/UserNotFoundException.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/ValidationException.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/UnprocessedFile.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/ColorsService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/DigitalSignatureService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EmailService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EncryptionDecryptionService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/WatermarkService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/AddRedactionPersistenceService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/CommentPersistenceService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DictionaryPersistenceService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierAttributeConfigPersistenceService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierAttributePersistenceService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierPersistenceService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierTemplatePersistenceService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DownloadStatusPersistenceService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/EntryPersistenceService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/FileAttributeConfigPersistenceService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/FileStatusPersistenceService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/ForceRedactionPersistenceService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/ImageRecategorizationPersistenceService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/LegalBasisChangePersistenceService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/RemoveRedactionPersistenceService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/ReportTemplatePersistenceService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/RulesPersistenceService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/SMTPConfigurationService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/ViewedPagesPersistenceService.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ColorsRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/CommentRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DigitalSignatureRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierAttributeConfigRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierAttributeRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierTemplateRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DownloadStatusRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntryRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FileAttributeConfigRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FileAttributesGeneralConfigurationRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FileRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ForceRedactionRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ImageRecategorizationRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/LegalBasisChangeRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/LegalBasisMappingRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ManualRedactionRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/RemoveRedactionRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ReportTemplateRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/RuleSetRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/SMTPRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/TypeRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ViewedPagesRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/WatermarkRepository.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/settings/FileUploadSettings.java create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/test/resources/application.yml create mode 100644 persistence-service-v1/persistence-service-processor-v1/src/test/resources/log4j2-test.xml create mode 100644 persistence-service-v1/persistence-service-server-v1/pom.xml create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/Application.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/ResourceLoader.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/TextNormalizationUtilities.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/client/PDFTronRedactionClient.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/client/RedactionClient.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/client/RedactionServiceClient.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/client/SearchClient.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/configuration/CleanupDownloadSchedulerConfiguration.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/configuration/MessagingConfiguration.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/ControllerAdvice.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DictionaryController.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DigitalSignatureController.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DossierAttributesController.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DossierController.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DossierTemplateController.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DownloadController.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/FileAttributesController.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/FileStatusController.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/FileStatusProcessingUpdateController.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/LegalBasisMappingController.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/LicenseReportController.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/ManualRedactionController.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/ReanalysisController.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/RedactionLogController.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/ReportTemplateController.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/RulesController.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/SMTPConfigurationController.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/UploadController.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/ViewedPagesController.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/WatermarkController.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/exception/InvalidRulesException.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/exception/JSONParseException.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/model/DownloadJob.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/DictionarySearchAndNotifyService.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/DossierService.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/ExcludeFromAnalysisService.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/FileManagementStorageService.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/FileService.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/FileStatusProcessingUpdateService.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/FileStatusService.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/IndexingService.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/LicenseReportService.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/ManualRedactionProviderService.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/ManualRedactionService.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/ManualRedactionsConverter.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/RedactionLogService.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadCleanupService.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadDLQMessageReceiver.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadMessageReceiver.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadPreparationService.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadReportCleanupService.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadReportMessageReceiver.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/settings/FileManagementServiceSettings.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/utils/FileSystemBackedArchiver.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/utils/StorageIdUtils.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/validation/DictionaryValidator.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/resources/application-dev.yml create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yml create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/resources/banner.txt create mode 100644 persistence-service-v1/persistence-service-server-v1/src/main/resources/bootstrap.yml create mode 100644 persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/controller/DossierControllerTest.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/controller/FileStatusControllerTest.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/controller/LicenseReportControllerTest.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/controller/ReanalysisControllerTest.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/AbstractFileManagementServerServiceTest.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/DossierAttributesTest.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/DossierDeleteTest.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/ExcludeFromAnalysisTest.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/FileAttributesTest.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/FileSystemBackedStorageService.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/ManualRedactionTest.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/ReportTemplateTest.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/ViewedPagesTest.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/service/DossierServiceTest.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/service/DownloadCleanupServiceTest.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/service/LicenseReportServiceTest.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/utils/FileSystemBackArchiverTest.java create mode 100644 persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml create mode 100644 persistence-service-v1/persistence-service-server-v1/src/test/resources/files/export_summary.csv create mode 100755 persistence-service-v1/pom.xml create mode 100644 pom.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..6bb4badae --- /dev/null +++ b/.gitignore @@ -0,0 +1,28 @@ +!.gitignore +*.project +*.classpath +**/.settings/ +**/target/ +**/logs/ +**/.metadata/ +**/bin/ +**/tmp/ +**/.apt_generated/ + + +.factorypath +.springBeans +.checkstyle +.eclipse-pmd +.pmdruleset.xml +.pmd + +**/.idea/ +*.iml + +*.pid +*~ +**/.DS_Store/ +**/.DS_Store +**/classpath-data.json +**/dependencies-and-licenses-overview.txt diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..2c28d4d9d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,12 @@ +# Changelog +All notable changes to this project will be documented in this file. + +## [Unreleased] + +### Fixed + +### Added + +### Changed + +### Removed \ No newline at end of file diff --git a/bamboo-specs/pom.xml b/bamboo-specs/pom.xml new file mode 100644 index 000000000..aaabe920a --- /dev/null +++ b/bamboo-specs/pom.xml @@ -0,0 +1,37 @@ + + 4.0.0 + + + com.atlassian.bamboo + bamboo-specs-parent + 7.2.2 + + + + bamboo-specs + 1.0.0-SNAPSHOT + jar + + + + com.atlassian.bamboo + bamboo-specs-api + + + com.atlassian.bamboo + bamboo-specs + + + + + junit + junit + test + + + + + + + diff --git a/bamboo-specs/src/main/java/buildjob/PlanSpec.java b/bamboo-specs/src/main/java/buildjob/PlanSpec.java new file mode 100644 index 000000000..1ddcd5872 --- /dev/null +++ b/bamboo-specs/src/main/java/buildjob/PlanSpec.java @@ -0,0 +1,118 @@ +package buildjob; + +import com.atlassian.bamboo.specs.api.BambooSpec; +import com.atlassian.bamboo.specs.api.builders.BambooKey; +import com.atlassian.bamboo.specs.api.builders.docker.DockerConfiguration; +import com.atlassian.bamboo.specs.api.builders.permission.PermissionType; +import com.atlassian.bamboo.specs.api.builders.permission.Permissions; +import com.atlassian.bamboo.specs.api.builders.permission.PlanPermissions; +import com.atlassian.bamboo.specs.api.builders.plan.Job; +import com.atlassian.bamboo.specs.api.builders.plan.Plan; +import com.atlassian.bamboo.specs.api.builders.plan.PlanIdentifier; +import com.atlassian.bamboo.specs.api.builders.plan.Stage; +import com.atlassian.bamboo.specs.api.builders.plan.branches.BranchCleanup; +import com.atlassian.bamboo.specs.api.builders.plan.branches.PlanBranchManagement; +import com.atlassian.bamboo.specs.api.builders.plan.configuration.ConcurrentBuilds; +import com.atlassian.bamboo.specs.api.builders.project.Project; +import com.atlassian.bamboo.specs.builders.task.*; +import com.atlassian.bamboo.specs.builders.trigger.BitbucketServerTrigger; +import com.atlassian.bamboo.specs.model.task.InjectVariablesScope; +import com.atlassian.bamboo.specs.model.task.ScriptTaskProperties.Location; +import com.atlassian.bamboo.specs.util.BambooServer; + +import static com.atlassian.bamboo.specs.builders.task.TestParserTask.createJUnitParserTask; + +/** + * Plan configuration for Bamboo. + * Learn more on: https://confluence.atlassian.com/display/BAMBOO/Bamboo+Specs + */ +@BambooSpec +public class PlanSpec { + + private static final String SERVICE_NAME = "persistence-service"; + + private static final String SERVICE_KEY = SERVICE_NAME.toUpperCase().replaceAll("-", ""); + + /** + * Run main to publish plan on Bamboo + */ + public static void main(final String[] args) throws Exception { + //By default credentials are read from the '.credentials' file. + BambooServer bambooServer = new BambooServer("http://localhost:8085"); + + Plan plan = new PlanSpec().createPlan(); + bambooServer.publish(plan); + PlanPermissions planPermission = new PlanSpec().createPlanPermission(plan.getIdentifier()); + bambooServer.publish(planPermission); + } + + private PlanPermissions createPlanPermission(PlanIdentifier planIdentifier) { + Permissions permission = new Permissions() + .userPermissions("atlbamboo", PermissionType.EDIT, PermissionType.VIEW, PermissionType.ADMIN, PermissionType.CLONE, PermissionType.BUILD) + .groupPermissions("red-backend", PermissionType.EDIT, PermissionType.VIEW, PermissionType.CLONE, PermissionType.BUILD) + .loggedInUserPermissions(PermissionType.VIEW) + .anonymousUserPermissionView(); + return new PlanPermissions(planIdentifier.getProjectKey(), planIdentifier.getPlanKey()).permissions(permission); + } + + private Project project() { + return new Project() + .name("RED") + .key(new BambooKey("RED")); + } + + public Plan createPlan() { + return new Plan( + project(), + SERVICE_NAME, new BambooKey(SERVICE_KEY)) + .description("Plan created from (enter repository url of your plan)") + .stages(new Stage("Default Stage") + .jobs(new Job("Default Job", + new BambooKey("JOB1")) + .tasks( + new ScriptTask() + .description("Clean") + .inlineBody("#!/bin/bash\n" + + "set -e\n" + + "rm -rf ./*"), + new VcsCheckoutTask() + .description("Checkout Default Repository") + .checkoutItems(new CheckoutItem().defaultRepository()), + new ScriptTask() + .description("Build") + .location(Location.FILE) + .fileFromPath("bamboo-specs/src/main/resources/scripts/build-java.sh") + .argument(SERVICE_NAME), + createJUnitParserTask() + .description("Resultparser") + .resultDirectories("**/test-reports/*.xml, **/target/surefire-reports/*.xml, **/target/failsafe-reports/*.xml") + .enabled(true), + new InjectVariablesTask() + .description("Inject git Tag") + .path("git.tag") + .namespace("g") + .scope(InjectVariablesScope.LOCAL), + new VcsTagTask() + .description("${bamboo.g.gitTag}") + .tagName("${bamboo.g.gitTag}") + .defaultRepository()) + .dockerConfiguration( + new DockerConfiguration() + .image("nexus.iqser.com:5001/infra/maven:3.6.2-jdk-13-3.0.0") + .dockerRunArguments("--net=host") + .volume("/etc/maven/settings.xml", "/usr/share/maven/ref/settings.xml") + .volume("/var/run/docker.sock", "/var/run/docker.sock") + ) + ) + ) + .linkedRepositories("RED / " + SERVICE_NAME) + .pluginConfigurations(new ConcurrentBuilds() + .maximumNumberOfConcurrentBuilds(1)) + .triggers(new BitbucketServerTrigger()) + .planBranchManagement(new PlanBranchManagement() + .createForVcsBranch() + .delete(new BranchCleanup() + .whenInactiveInRepositoryAfterDays(14)) + .notificationForCommitters()); + } +} diff --git a/bamboo-specs/src/main/resources/scripts/build-java.sh b/bamboo-specs/src/main/resources/scripts/build-java.sh new file mode 100755 index 000000000..60dfe783c --- /dev/null +++ b/bamboo-specs/src/main/resources/scripts/build-java.sh @@ -0,0 +1,51 @@ +#!/bin/bash +set -e + +SERVICE_NAME=$1 + +if [[ "${bamboo_version_tag}" = "dev" ]] +then + ${bamboo_capability_system_builder_mvn3_Maven_3}/bin/mvn \ + -f ${bamboo_build_working_directory}/$SERVICE_NAME-v1/pom.xml \ + --no-transfer-progress \ + clean install \ + -Djava.security.egd=file:/dev/./urandomelse +else + ${bamboo_capability_system_builder_mvn3_Maven_3}/bin/mvn \ + --no-transfer-progress \ + -f ${bamboo_build_working_directory}/$SERVICE_NAME-v1/pom.xml \ + versions:set \ + -DnewVersion=${bamboo_version_tag} + ${bamboo_capability_system_builder_mvn3_Maven_3}/bin/mvn \ + --no-transfer-progress \ + -f ${bamboo_build_working_directory}/$SERVICE_NAME-image-v1/pom.xml \ + versions:set \ + -DnewVersion=${bamboo_version_tag} + ${bamboo_capability_system_builder_mvn3_Maven_3}/bin/mvn \ + -f ${bamboo_build_working_directory}/$SERVICE_NAME-v1/pom.xml \ + --no-transfer-progress \ + clean deploy \ + -e \ + -DdeployAtEnd=true \ + -Dmaven.wagon.http.ssl.insecure=true \ + -Dmaven.wagon.http.ssl.allowall=true \ + -Dmaven.wagon.http.ssl.ignore.validity.dates=true \ + -DaltDeploymentRepository=iqser_release::default::https://nexus.iqser.com/repository/red-platform-releases +fi + +${bamboo_capability_system_builder_mvn3_Maven_3}/bin/mvn \ + --no-transfer-progress \ + -f ${bamboo_build_working_directory}/$SERVICE_NAME-image-v1/pom.xml \ + package + +${bamboo_capability_system_builder_mvn3_Maven_3}/bin/mvn \ + --no-transfer-progress \ + -f ${bamboo_build_working_directory}/$SERVICE_NAME-image-v1/pom.xml \ + docker:push + +if [[ "${bamboo_version_tag}" = "dev" ]] +then + echo "gitTag=${bamboo_planRepository_1_branch}_${bamboo_buildNumber}" > git.tag +else + echo "gitTag=${bamboo_version_tag}" > git.tag +fi diff --git a/bamboo-specs/src/test/java/buildjob/PlanSpecTest.java b/bamboo-specs/src/test/java/buildjob/PlanSpecTest.java new file mode 100644 index 000000000..d09a7f1fb --- /dev/null +++ b/bamboo-specs/src/test/java/buildjob/PlanSpecTest.java @@ -0,0 +1,17 @@ +package buildjob; + + +import org.junit.Test; + +import com.atlassian.bamboo.specs.api.builders.plan.Plan; +import com.atlassian.bamboo.specs.api.exceptions.PropertiesValidationException; +import com.atlassian.bamboo.specs.api.util.EntityPropertiesBuilders; + +public class PlanSpecTest { + @Test + public void checkYourPlanOffline() throws PropertiesValidationException { + Plan plan = new PlanSpec().createPlan(); + + EntityPropertiesBuilders.build(plan); + } +} \ No newline at end of file diff --git a/persistence-service-image-v1/pom.xml b/persistence-service-image-v1/pom.xml new file mode 100644 index 000000000..c14e9c1bb --- /dev/null +++ b/persistence-service-image-v1/pom.xml @@ -0,0 +1,96 @@ + + + + com.iqser.red + platform-docker-dependency + 1.0.1 + + 4.0.0 + + persistence-service-image-v1 + com.iqser.red.service + 1.0-SNAPSHOT + pom + + + persistence-service-server-v1 + ${service.server}.jar + false + ${docker.image.prefix}/${service.server} + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + org.apache.maven.plugins + maven-resources-plugin + + + org.codehaus.mojo + exec-maven-plugin + + + io.fabric8 + docker-maven-plugin + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + download-platform-jar + prepare-package + + copy + + + + + ${project.groupId} + ${service.server} + ${project.version} + jar + true + ${platform.jar} + + + ${docker.build.directory} + + + + + + io.fabric8 + docker-maven-plugin + + + + ${docker.image.name} + + ${docker.build.directory} + + ${platform.jar} + + + ${docker.image.version} + latest + + + + + + + + + + diff --git a/persistence-service-image-v1/src/main/docker/Dockerfile b/persistence-service-image-v1/src/main/docker/Dockerfile new file mode 100644 index 000000000..dd0387fb1 --- /dev/null +++ b/persistence-service-image-v1/src/main/docker/Dockerfile @@ -0,0 +1,9 @@ +FROM red/base-image:1.0.0 + +ARG PLATFORM_JAR + +ENV PLATFORM_JAR ${PLATFORM_JAR} + +ENV USES_ELASTICSEARCH false + +COPY ["${PLATFORM_JAR}", "/"] diff --git a/persistence-service-v1/persistence-service-api-v1/pom.xml b/persistence-service-v1/persistence-service-api-v1/pom.xml new file mode 100644 index 000000000..d4a7bc4fb --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/pom.xml @@ -0,0 +1,55 @@ + + + + + persistence-service-v1 + com.iqser.red.service + 1.0-SNAPSHOT + + + 4.0.0 + + persistence-service-api-v1 + + + + com.iqser.red.service + redaction-service-api-v1 + + + com.iqser.red.service + persistence-service-api-v1 + + + + + + + + io.github.openfeign + feign-core + true + + + + jakarta.persistence + jakarta.persistence-api + + + + + + org.springframework + spring-web + + + + + com.iqser.red.commons + jackson-commons + + + + diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/AddRedactionRequest.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/AddRedactionRequest.java new file mode 100644 index 000000000..fe3f247f6 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/AddRedactionRequest.java @@ -0,0 +1,32 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.AnnotationStatus; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.Rectangle; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class AddRedactionRequest { + + private String user; + private String type; + private String value; + private String reason; + private String legalBasis; + private boolean addToDictionary; + private boolean addToDossierDictionary; + private AnnotationStatus status; + + @Builder.Default + private List positions = new ArrayList<>(); + + private String comment; +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/BinaryFileRequest.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/BinaryFileRequest.java new file mode 100644 index 000000000..425218e92 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/BinaryFileRequest.java @@ -0,0 +1,20 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import lombok.*; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class BinaryFileRequest { + + @NonNull + private byte[] data; + @NonNull + private String filename; + @NonNull + private String dossierId; + + private String uploader; + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/BinaryFileResult.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/BinaryFileResult.java new file mode 100644 index 000000000..5f8abb1bc --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/BinaryFileResult.java @@ -0,0 +1,16 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import lombok.*; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class BinaryFileResult { + + @NonNull + private byte[] data; + + @NonNull + private String filename; +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/CommentRequest.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/CommentRequest.java new file mode 100644 index 000000000..dbbbbcfcd --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/CommentRequest.java @@ -0,0 +1,17 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class CommentRequest { + + private String user; + private String text; + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/CreateOrUpdateDossierRequest.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/CreateOrUpdateDossierRequest.java new file mode 100644 index 000000000..f260be05c --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/CreateOrUpdateDossierRequest.java @@ -0,0 +1,49 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierStatus; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DownloadFileType; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class CreateOrUpdateDossierRequest { + + private String dossierName; + + private OffsetDateTime date; + + private String description; + + private DossierStatus status; + + private String ownerId; + + private Set memberIds = new HashSet<>(); + + private Set approverIds = new HashSet<>(); + + private Set downloadFileTypes = new HashSet<>(); + + private boolean watermarkEnabled; + + private OffsetDateTime dueDate; + + private String dossierTemplateId; + + private List reportTemplateIds = new ArrayList<>(); + + private String requestingUser; + + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/CreateOrUpdateDossierTemplateRequest.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/CreateOrUpdateDossierTemplateRequest.java new file mode 100644 index 000000000..1b98da5ce --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/CreateOrUpdateDossierTemplateRequest.java @@ -0,0 +1,40 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DownloadFileType; +import lombok.Data; + +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +@Data +public class CreateOrUpdateDossierTemplateRequest { + + private String dossierTemplateId; + + private String name; + + private String description; + + private OffsetDateTime dateAdded; + + private OffsetDateTime dateModified; + + private String createdBy; + + private String modifiedBy; + + private OffsetDateTime validFrom; + + private OffsetDateTime validTo; + + private String requestingUser; + + private Set downloadFileTypes = new HashSet<>(); + + private List reportTemplateIds = new ArrayList<>(); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/DeletedDossier.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/DeletedDossier.java new file mode 100644 index 000000000..fbb9b24c3 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/DeletedDossier.java @@ -0,0 +1,15 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import lombok.Builder; +import lombok.Data; + +import java.time.OffsetDateTime; + +@Data +@Builder +public class DeletedDossier { + + private OffsetDateTime deletionTime; + private String dossierId; + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/DigitalSignatureUpdateModel.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/DigitalSignatureUpdateModel.java new file mode 100644 index 000000000..2115c160a --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/DigitalSignatureUpdateModel.java @@ -0,0 +1,16 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import lombok.*; + +@Data +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor +@Builder +public class DigitalSignatureUpdateModel { + + private String location; + private String reason; + private String contactInfo; + private String certificateName; + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/DownloadRequest.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/DownloadRequest.java new file mode 100644 index 000000000..9c850c10e --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/DownloadRequest.java @@ -0,0 +1,20 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import lombok.*; + +import java.util.ArrayList; +import java.util.List; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class DownloadRequest { + + private String userId; + private String dossierId; + + @Builder.Default + private List fileIds = new ArrayList<>(); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/FileType.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/FileType.java new file mode 100644 index 000000000..f28ff2e39 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/FileType.java @@ -0,0 +1,15 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import lombok.Getter; + +public enum FileType { + ORIGIN(".pdf"), REDACTION_LOG(".json"), SECTION_GRID(".json"), TEXT(".json"); + + @Getter + private final String extension; + + FileType(String extension) { + this.extension = extension; + } + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ForceRedactionRequest.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ForceRedactionRequest.java new file mode 100644 index 000000000..22f690d43 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ForceRedactionRequest.java @@ -0,0 +1,21 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.AnnotationStatus; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ForceRedactionRequest { + + private String annotationId; + private String user; + private AnnotationStatus status; + private String legalBasis; + private String comment; + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ImageRecategorizationRequest.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ImageRecategorizationRequest.java new file mode 100644 index 000000000..fed3a5fcb --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ImageRecategorizationRequest.java @@ -0,0 +1,21 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.AnnotationStatus; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ImageRecategorizationRequest { + + private String annotationId; + private String user; + private AnnotationStatus status; + private String type; + private String comment; + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ImportCsvRequest.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ImportCsvRequest.java new file mode 100644 index 000000000..cbe251e14 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ImportCsvRequest.java @@ -0,0 +1,16 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ImportCsvRequest { + + private byte[] csvFile; + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ImportCsvResponse.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ImportCsvResponse.java new file mode 100644 index 000000000..474067899 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ImportCsvResponse.java @@ -0,0 +1,23 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.HashSet; +import java.util.Set; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ImportCsvResponse { + + @Builder.Default + private Set affectedFileIds = new HashSet<>(); + + @Builder.Default + private Set foundAttributes = new HashSet<>(); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/JSONPrimitive.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/JSONPrimitive.java new file mode 100644 index 000000000..f4a392723 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/JSONPrimitive.java @@ -0,0 +1,12 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import lombok.Data; +import lombok.RequiredArgsConstructor; + +@Data +@RequiredArgsConstructor +public class JSONPrimitive { + + private final T value; + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/LegalBasisChangeRequest.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/LegalBasisChangeRequest.java new file mode 100644 index 000000000..522b10f7c --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/LegalBasisChangeRequest.java @@ -0,0 +1,21 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.AnnotationStatus; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class LegalBasisChangeRequest { + + private String annotationId; + private String user; + private AnnotationStatus status; + private String legalBasis; + private String comment; + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/LicenseReport.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/LicenseReport.java new file mode 100644 index 000000000..65cdf79a8 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/LicenseReport.java @@ -0,0 +1,40 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class LicenseReport { + + private int numberOfAnalyzedFiles; + private int numberOfOcrFiles; + + private int numberOfDossiers; + + private int numberOfAnalyzedPages; + private int numberOfOcrPages; + + private int numberOfAnalyses; // includes reanalysis counts + + private Instant startDate; + + private Instant endDate; + + private int offset; + + private int limit; + + private List data = new ArrayList<>(); + + // To be used for consecutive/paged calls + private String requestId; + +} + diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/LicenseReportRequest.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/LicenseReportRequest.java new file mode 100644 index 000000000..366603947 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/LicenseReportRequest.java @@ -0,0 +1,50 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.time.Instant; +import java.time.Year; +import java.time.ZoneOffset; +import java.util.ArrayList; +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@EqualsAndHashCode(of = "requestId") +public class LicenseReportRequest { + + private String requestId; + + private Instant startDate; + + private Instant endDate; + + private List dossierIds = new ArrayList<>(); + + + public Instant getStartDate() { + + if (startDate == null) { + startDate = Year.of(getEndDate().atOffset(ZoneOffset.UTC).getYear()) + .atMonth(1) + .atDay(1) + .atStartOfDay() + .toInstant(ZoneOffset.UTC); + } + return startDate; + } + + + public Instant getEndDate() { + + if (endDate == null) { + endDate = Instant.now(); + } + return endDate; + } + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ManualAddResponse.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ManualAddResponse.java new file mode 100644 index 000000000..54a346141 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ManualAddResponse.java @@ -0,0 +1,16 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ManualAddResponse { + + private String annotationId; + private String commentId; +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ManualRedactions.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ManualRedactions.java new file mode 100644 index 000000000..3f53332a7 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ManualRedactions.java @@ -0,0 +1,35 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.*; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ManualRedactions { + + @Builder.Default + private Set idsToRemove = new HashSet<>(); + + @Builder.Default + private Set entriesToAdd = new HashSet<>(); + + @Builder.Default + private Set forceRedactions = new HashSet<>(); + + @Builder.Default + private Set imageRecategorization = new HashSet<>(); + + @Builder.Default + private Set legalBasisChanges = new HashSet<>(); + + @Builder.Default + private Map> comments = new HashMap<>(); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/RemoveRedactionRequest.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/RemoveRedactionRequest.java new file mode 100644 index 000000000..4eb1b0d5c --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/RemoveRedactionRequest.java @@ -0,0 +1,21 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.AnnotationStatus; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class RemoveRedactionRequest { + + private String annotationId; + private String user; + private AnnotationStatus status; + private boolean removeFromDictionary; + private String comment; + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ReportData.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ReportData.java new file mode 100644 index 000000000..acb80a30f --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ReportData.java @@ -0,0 +1,21 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.FileStatus; +import lombok.Data; + +import java.time.Instant; + +@Data +public class ReportData { + + private String dossier; + private String fileName; + private Instant addedDate; + private Instant lastUpdatedDate; + private Instant deletedDate; + private int numberOfAnalyzedPages; + private int numberOfOcrPages; + private FileStatus status; + private int analysisCount; + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ReportTemplateDownload.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ReportTemplateDownload.java new file mode 100644 index 000000000..ee24a3aa8 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ReportTemplateDownload.java @@ -0,0 +1,15 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ReportTemplateDownload { + + private byte[] file; +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ReportTemplateUploadRequest.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ReportTemplateUploadRequest.java new file mode 100644 index 000000000..364d72fb0 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/ReportTemplateUploadRequest.java @@ -0,0 +1,21 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import lombok.*; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class ReportTemplateUploadRequest { + + @NonNull + private byte[] template; + @NonNull + private String dossierTemplateId; + @NonNull + private String fileName; + @NonNull + private boolean multiFileReport; + @NonNull + private boolean activeByDefault; +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/SetDownloadedRequest.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/SetDownloadedRequest.java new file mode 100644 index 000000000..6cdc33cac --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/SetDownloadedRequest.java @@ -0,0 +1,13 @@ +package com.iqser.red.service.persistence.service.v1.api.model; + +import lombok.*; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class SetDownloadedRequest { + + private String userId; + private String storageId; +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/AnnotationId.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/AnnotationId.java new file mode 100644 index 000000000..d2b9000f1 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/AnnotationId.java @@ -0,0 +1,22 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.annotations; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import java.io.Serializable; + +@Embeddable +@Data +@NoArgsConstructor +@AllArgsConstructor +public class AnnotationId implements Serializable { + + @Column + private String id; + @Column + private String fileId; + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/AnnotationStatus.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/AnnotationStatus.java new file mode 100644 index 000000000..154fe576a --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/AnnotationStatus.java @@ -0,0 +1,8 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.annotations; + +public enum AnnotationStatus { + REQUESTED, + APPROVED, + DECLINED + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/Comment.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/Comment.java new file mode 100644 index 000000000..797c4ecd9 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/Comment.java @@ -0,0 +1,40 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.annotations; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import java.time.OffsetDateTime; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class Comment { + + @Id + @GeneratedValue + private long id; + + @Column + private String fileId; + + @Column + private String annotationId; + + @Column + private OffsetDateTime date; + @Column + private String text; + @Column + private String user; + + @Column + private OffsetDateTime softDeletedTime; + + @ManyToOne + private File fileStatus; +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/IdRemoval.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/IdRemoval.java new file mode 100644 index 000000000..1c88157ae --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/IdRemoval.java @@ -0,0 +1,38 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.annotations; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.ManyToOne; +import java.time.OffsetDateTime; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class IdRemoval { + + @EmbeddedId + private AnnotationId id; + @Column + private String user; + @Column + private AnnotationStatus status; + @Column + private boolean removeFromDictionary; + @Column + private OffsetDateTime requestDate; + @Column + private OffsetDateTime processedDate; + @Column + private OffsetDateTime softDeletedTime; + + @ManyToOne + private File fileStatus; + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/ManualForceRedaction.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/ManualForceRedaction.java new file mode 100644 index 000000000..554f68d38 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/ManualForceRedaction.java @@ -0,0 +1,38 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.annotations; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.ManyToOne; +import java.time.OffsetDateTime; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ManualForceRedaction { + + @EmbeddedId + private AnnotationId id; + @Column + private String user; + @Column + private AnnotationStatus status; + @Column + private String legalBasis; + @Column + private OffsetDateTime requestDate; + @Column + private OffsetDateTime processedDate; + @Column + private OffsetDateTime softDeletedTime; + + @ManyToOne + private File fileStatus; + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/ManualImageRecategorization.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/ManualImageRecategorization.java new file mode 100644 index 000000000..b66ce84d1 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/ManualImageRecategorization.java @@ -0,0 +1,37 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.annotations; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.ManyToOne; +import java.time.OffsetDateTime; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ManualImageRecategorization { + + @EmbeddedId + private AnnotationId id; + @Column + private String user; + @Column + private AnnotationStatus status; + @Column + private String type; + @Column + private OffsetDateTime requestDate; + @Column + private OffsetDateTime processedDate; + @Column + private OffsetDateTime softDeletedTime; + + @ManyToOne + private File fileStatus; +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/ManualLegalBasisChange.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/ManualLegalBasisChange.java new file mode 100644 index 000000000..266408ed3 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/ManualLegalBasisChange.java @@ -0,0 +1,39 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.annotations; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.ManyToOne; +import java.time.OffsetDateTime; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ManualLegalBasisChange { + + @EmbeddedId + private AnnotationId id; + + @Column + private String user; + @Column + private AnnotationStatus status; + @Column + private String legalBasis; + @Column + private OffsetDateTime requestDate; + @Column + private OffsetDateTime processedDate; + @Column + private OffsetDateTime softDeletedTime; + + @ManyToOne + private File fileStatus; + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/ManualRedactionEntry.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/ManualRedactionEntry.java new file mode 100644 index 000000000..22c7acc9b --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/ManualRedactionEntry.java @@ -0,0 +1,49 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.annotations; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import lombok.Data; + +import javax.persistence.*; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.List; + +@Data +@Entity +@Table(name = "manual_redaction") +public class ManualRedactionEntry { + + @EmbeddedId + private AnnotationId id; + @Column + private String user; + @Column + private String typeId; + @Column + private String value; + @Column + private String reason; + @Column + private String legalBasis; + @Column + private AnnotationStatus status; + @Column + private boolean addToDictionary; + @Column + private boolean addToDossierDictionary; + @Column + private OffsetDateTime requestDate; + @Column + private OffsetDateTime processedDate; + @Column + private OffsetDateTime softDeletedTime; + + + @OneToMany(mappedBy = "manualRedaction", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private List positions = new ArrayList<>(); + + @ManyToOne + private File fileStatus; + + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/Rectangle.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/Rectangle.java new file mode 100644 index 000000000..6c51aa22f --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/Rectangle.java @@ -0,0 +1,29 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.annotations; + +import lombok.Data; + +import javax.persistence.*; + +@Data +@Entity +@Table(name = "rectangle") +public class Rectangle { + + @Id + @GeneratedValue + private long id; + + @Column + private float topLeftX; + @Column + private float topLeftY; + @Column + private float width; + @Column + private float height; + @Column + private int page; + + @ManyToOne(fetch = FetchType.LAZY) + private ManualRedactionEntry manualRedaction; +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/ViewedPage.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/ViewedPage.java new file mode 100644 index 000000000..05028c67b --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/annotations/ViewedPage.java @@ -0,0 +1,39 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.annotations; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import java.io.Serializable; +import java.time.OffsetDateTime; + +@Data +@Entity +@Table(name = "viewed_page") +public class ViewedPage { + + @EmbeddedId + private ViewedPageId id; + @Column + private OffsetDateTime viewedTime; + + @ManyToOne(fetch = FetchType.LAZY) + private File file; + + @Data + @Embeddable + @NoArgsConstructor + @AllArgsConstructor + public static class ViewedPageId implements Serializable { + + @Column + private String fileId; + @Column + private int page; + @Column + private String userId; + } + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/Colors.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/Colors.java new file mode 100644 index 000000000..e0cf1e69a --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/Colors.java @@ -0,0 +1,50 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.configuration; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "color_configuration") +public class Colors { + + @Id + @Column + private String dossierTemplateId; + + @Column + private String defaultColor; + + @Column + private String requestAdd; + + @Column + private String requestRemove; + + @Column + private String notRedacted; + + @Column + private String analysisColor; + + @Column + private String updatedColor; + + @Column + private String dictionaryRequestColor; + + @Column + private String manualRedactionColor; + + @Column + private String previewColor; + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/DictionaryEntry.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/DictionaryEntry.java new file mode 100644 index 000000000..50a352277 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/DictionaryEntry.java @@ -0,0 +1,26 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.configuration; + +import lombok.Data; + +import javax.persistence.*; + +@Data +@Entity +@Table(name = "dictionary_entry") +public class DictionaryEntry { + + @Id + @GeneratedValue + private long entryId; + @Column + private String value; + @Column + private long version; + @Column + private boolean deleted; + + @ManyToOne(fetch = FetchType.LAZY) + private Type type; + + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/DigitalSignature.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/DigitalSignature.java new file mode 100644 index 000000000..097986aab --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/DigitalSignature.java @@ -0,0 +1,35 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.configuration; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Data +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "digital_signature") +public class DigitalSignature { + + public final static String ID = "CONFIG_ID"; + + @Id + private final String id = DigitalSignature.ID; + + @Column + private String location; + @Column + private String reason; + @Column + private String contactInfo; + @Column + private String certificateName; + @Column + private String password; + @Column + @Lob + private byte[] privateKey; + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/FileAttributesGeneralConfiguration.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/FileAttributesGeneralConfiguration.java new file mode 100644 index 000000000..8d086de15 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/FileAttributesGeneralConfiguration.java @@ -0,0 +1,28 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.configuration; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierTemplate; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.Column; +import javax.persistence.Id; +import javax.persistence.OneToOne; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class FileAttributesGeneralConfiguration { + + @Id + @Column + private String dossierTemplateId; + @Column + private String filenameMappingColumnHeaderName; + @Column + private String delimiter; + + @OneToOne + private DossierTemplate dossierTemplate; + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/LegalBasis.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/LegalBasis.java new file mode 100644 index 000000000..a71563c0a --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/LegalBasis.java @@ -0,0 +1,28 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.configuration; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Data +@NoArgsConstructor +@Entity +@Table(name = "legal_basis") +public class LegalBasis { + + @Id + @GeneratedValue + private long id; + @Column + private String name; + @Column + private String description; + @Column + private String reason; + + @ManyToOne + private LegalBasisMapping legalBasisMapping; + + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/LegalBasisMapping.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/LegalBasisMapping.java new file mode 100644 index 000000000..348a5dbef --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/LegalBasisMapping.java @@ -0,0 +1,24 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.configuration; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.List; + +@Data +@NoArgsConstructor +@Entity +@Table(name = "legal_basis_mapping") +public class LegalBasisMapping { + + @Id + private String dossierTemplateId; + @Column + private long version; + + @OneToMany(mappedBy = "legalBasisMapping", cascade = CascadeType.ALL) + private List legalBasis = new ArrayList<>(); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/RuleSet.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/RuleSet.java new file mode 100644 index 000000000..942a6c457 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/RuleSet.java @@ -0,0 +1,26 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.configuration; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "rule_set") +public class RuleSet { + + @Id + @Column + private String dossierTemplateId; + + @Column + private long version; + + @Lob + @Column(name = "value", columnDefinition="CLOB") + private String value; +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/SMTPConfiguration.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/SMTPConfiguration.java new file mode 100644 index 000000000..169fb03d0 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/SMTPConfiguration.java @@ -0,0 +1,48 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.configuration; + +import lombok.Data; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Data +@Entity +@Table(name = "smtp_configuration") +public class SMTPConfiguration { + + public final static String ID = "CONFIG_ID"; + + @Id + private final String id = SMTPConfiguration.ID; + + @Column + private String from; + @Column + private String fromDisplayName; + @Column + private String envelopeFrom; + @Column + private String host; + @Column + private Integer port; + @Column + private String replyTo; + @Column + private String replyToDisplayName; + @Column + private boolean ssl; + @Column + private boolean starttls; + + // if AUTH is true, following must also be set + @Column + private boolean auth; + @Column + private String user; + @Column + private String password; + + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/Type.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/Type.java new file mode 100644 index 000000000..f2df42e62 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/Type.java @@ -0,0 +1,56 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.configuration; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.Dossier; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierTemplate; +import lombok.Data; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.List; + +import static javax.persistence.CascadeType.ALL; + +@Data +@Entity +@Table(name = "type") +public class Type { + + @Id + private String id; + @Column + private String type; + @Column + private String label; + @Column + private String hexColor; + @Column + private int rank; + @Column + private boolean isHint; + @Column + private boolean isCaseInsensitive; + @Column + private boolean isRecommendation; + @Column + private String description; + @Column + private long version; + @Column + private boolean addToDictionaryAction; + + @OneToMany(cascade = ALL, mappedBy = "type", orphanRemoval = true, fetch = FetchType.LAZY) + private List entries = new ArrayList<>(); + + @ManyToOne + private DossierTemplate dossierTemplate; + + @Column(updatable = false, insertable = false) + private String dossierTemplateId; + + @ManyToOne + private Dossier dossier; + + @Column(updatable = false, insertable = false) + private String dossierId; + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/Watermark.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/Watermark.java new file mode 100644 index 000000000..50389ceff --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/configuration/Watermark.java @@ -0,0 +1,41 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.configuration; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierTemplate; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Data +@Entity +@Table(name = "watermark_config") +@NoArgsConstructor +@AllArgsConstructor +public class Watermark { + + @Id + @Column + private String dossierTemplateId; + @Column + private String text; + @Column + private String hexColor; + @Column + private int opacity; + @Column + private int fontSize; + @Column + private String fontType; + @Column + private WatermarkOrientation orientation; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "dossier_template_id") + private DossierTemplate dossierTemplate; + + public enum WatermarkOrientation { + VERTICAL, HORIZONTAL, DIAGONAL + } + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/Dossier.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/Dossier.java new file mode 100644 index 000000000..b9d457b28 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/Dossier.java @@ -0,0 +1,78 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.dossier; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.Type; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@Data +@Entity +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "dossier") +public class Dossier { + + @Id + private String id; + + @Column + private String dossierName; + + @Column + private OffsetDateTime date; + + @Column + private String description; + + @Column + private DossierStatus status; + + @Column + private String ownerId; + + @ElementCollection + private Set memberIds = new HashSet<>(); + + @ElementCollection + private Set approverIds = new HashSet<>(); + + @ElementCollection + private Set downloadFileTypes = new HashSet<>(); + + @Column + private boolean watermarkEnabled; + + @Column + private OffsetDateTime softDeletedTime; + + @Column + private OffsetDateTime hardDeletedTime; + + @Column + private OffsetDateTime startDate; + + @Column + private OffsetDateTime dueDate; + + @ManyToOne(fetch = FetchType.LAZY) + private DossierTemplate dossierTemplate; + + @Column(updatable=false, insertable=false) + private String dossierTemplateId; + + @ManyToMany(fetch = FetchType.LAZY, mappedBy = "dossiers") + private List reportTemplates = new ArrayList<>(); + + @OneToMany + private List dossierTypes = new ArrayList<>(); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/DossierAttribute.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/DossierAttribute.java new file mode 100644 index 000000000..0c113b4f5 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/DossierAttribute.java @@ -0,0 +1,41 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.dossier; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import java.io.Serializable; + + +@Data +@Table(name = "dossier_attribute") +@Entity +public class DossierAttribute { + + @EmbeddedId + private DossierAttributeId id; + + @Column + private String value; + + @ManyToOne(fetch = FetchType.LAZY) + private Dossier dossier; + + @ManyToOne(fetch = FetchType.LAZY) + private DossierAttributeConfig dossierAttributeConfig; + + @Data + @NoArgsConstructor + @AllArgsConstructor + @Embeddable + public static class DossierAttributeId implements Serializable { + + @Column + private String dossierId; + + @Column + private String dossierAttributeConfigId; + } + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/DossierAttributeConfig.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/DossierAttributeConfig.java new file mode 100644 index 000000000..cba98e97c --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/DossierAttributeConfig.java @@ -0,0 +1,35 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.dossier; + +import lombok.Data; + +import javax.persistence.*; + + +@Data +@Entity +@Table(name = "dossier_attribute_config") +public class DossierAttributeConfig { + + @Id + private String id; + @Column + private String label; + @Column + private boolean editable; + @Column + private String placeholder; + + @Column + private DossierAttributeType type = DossierAttributeType.TEXT; + + + @ManyToOne + private DossierTemplate dossierTemplate; + + + public enum DossierAttributeType { + TEXT, NUMBER, DATE, IMAGE + } + + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/DossierStatus.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/DossierStatus.java new file mode 100644 index 000000000..fad4f4821 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/DossierStatus.java @@ -0,0 +1,5 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.dossier; + +public enum DossierStatus { + ACTIVE, DELETED +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/DossierTemplate.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/DossierTemplate.java new file mode 100644 index 000000000..bffd81784 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/DossierTemplate.java @@ -0,0 +1,57 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.dossier; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.Type; +import lombok.Data; + +import javax.persistence.*; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +@Data +@Entity +@Table(name = "dossier_template") +public class DossierTemplate { + + @Id + private String id; + + @Column + private String name; + + @Column + private String description; + + @Column + private OffsetDateTime dateAdded; + + @Column + private OffsetDateTime dateModified; + + @Column + private String createdBy; + + @Column + private String modifiedBy; + + @Column + private OffsetDateTime validFrom; + + @Column + private OffsetDateTime validTo; + + @Column + private boolean deleted; + + @ElementCollection + private Set downloadFileTypes = new HashSet<>(); + + @ManyToMany + private List reportTemplates = new ArrayList<>(); + + @OneToMany + private List dossierTypes = new ArrayList<>(); +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/DownloadFileType.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/DownloadFileType.java new file mode 100644 index 000000000..dd3ff0496 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/DownloadFileType.java @@ -0,0 +1,5 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.dossier; + +public enum DownloadFileType { + ORIGINAL, PREVIEW, REDACTED, ANNOTATED, FLATTEN +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/File.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/File.java new file mode 100644 index 000000000..f8842b16a --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/File.java @@ -0,0 +1,124 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.dossier; + +import lombok.Data; + +import javax.persistence.*; +import java.time.OffsetDateTime; +import java.util.List; +import java.util.Set; + +@Data +@Entity +@Table(name = "file") +public class File { + + @Id + private String id; + + @Column + private String filename; + + @Column + private FileStatus status; + + @Column + private FileStatus lastSuccessfulStatus; + + @Column + private int numberOfPages; + + @Column + private OffsetDateTime added; + + @Column + private OffsetDateTime lastUpdated; + + @Column + private OffsetDateTime deleted; + + @Column + private OffsetDateTime lastProcessed; + + @Column + private OffsetDateTime lastIndexed; + + @Column + private int numberOfAnalyses; + + @Column + private String currentReviewer; + + @Column + private String lastReviewer; + + @Column + private OffsetDateTime lastManualRedaction; + + @Column + private boolean hasRedactions; + + @Column + private boolean hasHints; + + @Column + private boolean hasSuggestions; + + @Column + private boolean hasImages; + + @Column + private boolean hasUpdates; + + @Column + private String uploader; + + @Column + private long dictionaryVersion; + + @Column + private long rulesVersion; + + @Column + private long dossierDictionaryVersion; + + @Column + private long legalBasisVersion; + + @Column + private OffsetDateTime approvalDate; + + @Column + private OffsetDateTime lastUploaded; + + @Column + private long analysisDuration; + + @Column + private OffsetDateTime lastOCRTime; + + @Column + private boolean hasAnnotationComments; + + @Column + private boolean excluded; + + @Column + private OffsetDateTime hardDeletedTime; + + @Column + private OffsetDateTime lastFileAttributeChange; + + @Column + private int analysisVersion; + + @ElementCollection + private Set excludedPages; + + @OneToMany(mappedBy = "file", fetch = FetchType.LAZY, cascade = CascadeType.ALL) + private List fileAttributes; + + @ManyToOne + private Dossier dossier; + + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/FileAttribute.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/FileAttribute.java new file mode 100644 index 000000000..52289b173 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/FileAttribute.java @@ -0,0 +1,38 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.dossier; + +import lombok.Data; + +import javax.persistence.*; +import java.io.Serializable; + +@Data +@Entity +@Table(name = "file_attribute") +public class FileAttribute { + + @EmbeddedId + private FileAttributeId fileAttributeId; + + @Column + private String value; + + @ManyToOne(fetch = FetchType.LAZY) + private File file; + + @ManyToOne(fetch = FetchType.LAZY) + private FileAttributeConfig fileAttributeConfig; + + + @Data + @Embeddable + public static class FileAttributeId implements Serializable { + + @Column + private String fileId; + + @Column + private String fileAttributeConfigId; + } +} + + diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/FileAttributeConfig.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/FileAttributeConfig.java new file mode 100644 index 000000000..6ca86869a --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/FileAttributeConfig.java @@ -0,0 +1,40 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.dossier; + +import lombok.Data; + +import javax.persistence.*; + +@Data +@Entity +@Table(name = "file_attribute_config") +public class FileAttributeConfig { + + @Id + private String id; + @Column + private String csvColumnHeader; + @Column + private String label; + @Column + private boolean primaryAttribute; + @Column + private boolean editable; + @Column + private boolean filterable; + @Column + private boolean displayedInFileList; + @Column + private String placeholder; + @Column + private FileAttributeType type = FileAttributeType.TEXT; + + @ManyToOne + private DossierTemplate dossierTemplate; + + + public enum FileAttributeType { + TEXT, NUMBER, DATE + } + + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/FileStatus.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/FileStatus.java new file mode 100644 index 000000000..ed0ddd4ed --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/FileStatus.java @@ -0,0 +1,5 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.dossier; + +public enum FileStatus { + UNPROCESSED, REPROCESS, PROCESSING, ERROR, DELETED, UNASSIGNED, UNDER_REVIEW, UNDER_APPROVAL, APPROVED, FULLREPROCESS, OCR_PROCESSING, INDEXING +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/ReportTemplate.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/ReportTemplate.java new file mode 100644 index 000000000..1b93d407a --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/dossier/ReportTemplate.java @@ -0,0 +1,35 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.dossier; + +import lombok.Data; + +import javax.persistence.*; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.List; + +@Data +@Entity +@Table(name = "report_template") +public class ReportTemplate { + + @Id + private String templateId; + + @Column + private String storageId; + @Column + private String fileName; + @Column + private OffsetDateTime uploadDate; + @Column + private boolean multiFileReport; + @Column + private boolean activeByDefault; + + @ManyToOne(fetch = FetchType.LAZY) + private DossierTemplate dossierTemplate; + + @ManyToMany + private List dossiers = new ArrayList<>(); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/download/DownloadStatus.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/download/DownloadStatus.java new file mode 100644 index 000000000..4c01bc080 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/download/DownloadStatus.java @@ -0,0 +1,49 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.download; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.Dossier; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DownloadFileType; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import lombok.Data; + +import javax.persistence.*; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.List; + +@Data +@Entity +@Table(name = "download_status") +public class DownloadStatus { + + @Id + private String storageId; + @Column + private String userId; + @Column + private String filename; + @Column + private String mimeType; + @Column + private DownloadStatusValue status; + @Column + private OffsetDateTime creationDate; + @Column + private OffsetDateTime lastDownload; + @Column + private long fileSize; + + @ManyToOne + private Dossier dossier; + + @ManyToMany + private List files = new ArrayList<>(); + + @ElementCollection + private List downloadFileTypes = new ArrayList<>(); + + public enum DownloadStatusValue { + QUEUED, GENERATING, READY, FAILED + } + + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/download/DownloadStatusValue.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/download/DownloadStatusValue.java new file mode 100644 index 000000000..cd9ad5027 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/data/download/DownloadStatusValue.java @@ -0,0 +1,2 @@ +package com.iqser.red.service.persistence.service.v1.api.model.data.download; + diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/lombok.config b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/lombok.config new file mode 100644 index 000000000..f902278dd --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/model/lombok.config @@ -0,0 +1 @@ +lombok.anyConstructor.addConstructorProperties=true \ No newline at end of file diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DictionaryResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DictionaryResource.java new file mode 100644 index 000000000..5bdc3bb2a --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DictionaryResource.java @@ -0,0 +1,89 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.Colors; +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.Type; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@ResponseStatus(value = HttpStatus.OK) +public interface DictionaryResource { + + String DICTIONARY_PATH = "/dictionary"; + String TYPE_PATH = DICTIONARY_PATH + "/type"; + + String TYPE_PARAMETER_NAME = "type"; + String TYPE_PATH_VARIABLE = "/{" + TYPE_PARAMETER_NAME + "}"; + + String DOSSIER_TEMPLATE_PARAMETER_NAME = "dossierTemplateId"; + String DOSSIER_TEMPLATE_PATH_VARIABLE = "/{" + DOSSIER_TEMPLATE_PARAMETER_NAME + "}"; + + String DOSSIER_ID_PARAMETER_NAME = "dossierId"; + String DOSSIER_PATH = "/dossier"; + String DOSSIER_ID_PATH_VARIABLE = "/{" + DOSSIER_ID_PARAMETER_NAME + "}"; + + String COLOR_PATH = "/color"; + String VERSION_PATH = "/version"; + + + + + @ResponseStatus(HttpStatus.NO_CONTENT) + @PostMapping(value = DICTIONARY_PATH + TYPE_PATH_VARIABLE + DOSSIER_TEMPLATE_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE) + void addEntries(@PathVariable(TYPE_PARAMETER_NAME) String typeId, + @RequestBody List entries, + @RequestParam(value = "removeCurrent", required = false, defaultValue = "false") boolean removeCurrent); + + + @ResponseStatus(HttpStatus.NO_CONTENT) + @DeleteMapping(value = DICTIONARY_PATH + TYPE_PATH_VARIABLE + DOSSIER_TEMPLATE_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE) + void deleteEntries(@PathVariable(TYPE_PARAMETER_NAME) String typeId, + @RequestBody List entries); + + + @ResponseStatus(HttpStatus.NO_CONTENT) + @PostMapping(value = TYPE_PATH + TYPE_PATH_VARIABLE + DOSSIER_TEMPLATE_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE) + void updateTypeValue(@PathVariable(TYPE_PARAMETER_NAME) String typeId, + @RequestBody Type typeValue); + + + @ResponseStatus(HttpStatus.NO_CONTENT) + @PostMapping(value = TYPE_PATH, consumes = MediaType.APPLICATION_JSON_VALUE) + void addType(@RequestBody Type typeValue); + + + @ResponseStatus(HttpStatus.NO_CONTENT) + @DeleteMapping(value = TYPE_PATH + TYPE_PATH_VARIABLE + DOSSIER_TEMPLATE_PATH_VARIABLE) + void deleteType(@PathVariable(TYPE_PARAMETER_NAME) String typeId); + + + @GetMapping(value = TYPE_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + List getAllTypesForDossierTemplate(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId); + + @GetMapping(value = TYPE_PATH + DOSSIER_PATH + DOSSIER_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + List getAllTypesForDossier(@PathVariable(DOSSIER_ID_PARAMETER_NAME) String dossierId); + + + @GetMapping(value = DICTIONARY_PATH + TYPE_PATH_VARIABLE + DOSSIER_TEMPLATE_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + Type getDictionaryForType(@PathVariable(TYPE_PARAMETER_NAME) String typeId); + + + @GetMapping(value = VERSION_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE) + long getVersion(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId); + + @GetMapping(value = VERSION_PATH + DOSSIER_PATH+DOSSIER_ID_PATH_VARIABLE) + long getVersionForDossier(@PathVariable(DOSSIER_ID_PARAMETER_NAME) String dossierId); + + + @ResponseStatus(HttpStatus.NO_CONTENT) + @PostMapping(value = COLOR_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE) + void setColors(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, @RequestBody Colors colors); + + + @ResponseBody + @GetMapping(value = COLOR_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + Colors getColors(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DigitalSignatureResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DigitalSignatureResource.java new file mode 100644 index 000000000..984bb1c5b --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DigitalSignatureResource.java @@ -0,0 +1,28 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.DigitalSignature; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +@ResponseStatus(value = HttpStatus.OK) +public interface DigitalSignatureResource { + + String DIGITAL_SIGNATURE_PATH = "/digital-signature"; + + @ResponseStatus(HttpStatus.CREATED) + @PostMapping(value = DIGITAL_SIGNATURE_PATH, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + DigitalSignature saveDigitalSignature(@RequestBody DigitalSignature digitalSignatureModel); + + @ResponseStatus(HttpStatus.CREATED) + @PutMapping(value = DIGITAL_SIGNATURE_PATH, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + void updateDigitalSignature(@RequestBody DigitalSignature digitalSignatureModel); + + @GetMapping(value = DIGITAL_SIGNATURE_PATH, produces = MediaType.APPLICATION_JSON_VALUE) + DigitalSignature getDigitalSignature(); + + @ResponseStatus(HttpStatus.NO_CONTENT) + @DeleteMapping(value = DIGITAL_SIGNATURE_PATH) + void deleteDigitalSignature(); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DossierAttributesResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DossierAttributesResource.java new file mode 100644 index 000000000..c69f1de7c --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DossierAttributesResource.java @@ -0,0 +1,50 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierAttributeConfig; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +public interface DossierAttributesResource { + + String DOSSIER_ATTRIBUTES_PATH = "/dossierAttributes"; + String DOSSIER_ATTRIBUTE_PATH = "/dossierAttribute"; + String BASE_CONFIG_PATH = "/baseConfig"; + + String DOSSIER_TEMPLATE_ID = "dossierTemplateId"; + String DOSSIER_TEMPLATE_ID_PATH_VARIABLE = "/{" + DOSSIER_TEMPLATE_ID + "}"; + + String DOSSIER_ATTRIBUTE_ID = "dossierAttributeId"; + String DOSSIER_ATTRIBUTE_ID_PATH_VARIABLE = "/{" + DOSSIER_ATTRIBUTE_ID + "}"; + + @ResponseBody + @ResponseStatus(HttpStatus.OK) + @PostMapping(value = DOSSIER_ATTRIBUTES_PATH + DOSSIER_ATTRIBUTE_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + DossierAttributeConfig addOrUpdateDossierAttribute(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId, + @RequestBody DossierAttributeConfig dossierAttributeConfig); + + @ResponseBody + @ResponseStatus(HttpStatus.OK) + @PutMapping(value = DOSSIER_ATTRIBUTES_PATH + DOSSIER_ATTRIBUTE_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + List setDossierAttributesConfig(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId, + @RequestBody List dossierAttributesConfig); + + + @ResponseStatus(HttpStatus.NO_CONTENT) + @DeleteMapping(value = DOSSIER_ATTRIBUTES_PATH + DOSSIER_ATTRIBUTE_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + DOSSIER_ATTRIBUTE_ID_PATH_VARIABLE) + void deleteDossierAttribute(@PathVariable(DOSSIER_ATTRIBUTE_ID) String dossierAttributeId); + + + @ResponseStatus(HttpStatus.NO_CONTENT) + @PostMapping(value = DOSSIER_ATTRIBUTES_PATH + DOSSIER_ATTRIBUTE_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + "/delete") + void deleteDossierAttributes(@RequestBody List dossierAttributeIds); + + + @ResponseBody + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = DOSSIER_ATTRIBUTES_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + List getDossierAttributes(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DossierResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DossierResource.java new file mode 100644 index 000000000..d2061fcd6 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DossierResource.java @@ -0,0 +1,47 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.iqser.red.service.persistence.service.v1.api.model.CreateOrUpdateDossierRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.Dossier; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Set; + +@ResponseStatus(value = HttpStatus.OK) +public interface DossierResource { + + String REST_PATH = "/dossier"; + String DELETED_DOSSIERS_PATH = "/deletedDossiers"; + String HARD_DELETE_PATH = "/hardDelete"; + String UNDELETE_PATH = "/undelete"; + + String DOSSIER_ID_PARAM = "dossierId"; + String DOSSIER_ID_PATH_PARAM = "/{" + DOSSIER_ID_PARAM + "}"; + + @PostMapping(value = REST_PATH, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + Dossier addDossier(@RequestBody CreateOrUpdateDossierRequest dossierRequest); + + @PostMapping(value = REST_PATH + DOSSIER_ID_PATH_PARAM, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + Dossier updateDossier(@RequestBody CreateOrUpdateDossierRequest dossierRequest, @PathVariable(DOSSIER_ID_PARAM) String dossierId); + + @DeleteMapping(value = REST_PATH + DOSSIER_ID_PATH_PARAM) + void delete(@PathVariable(DOSSIER_ID_PARAM) String dossierId); + + @GetMapping(value = REST_PATH, produces = MediaType.APPLICATION_JSON_VALUE) + List getAllDossiers(); + + @GetMapping(value = REST_PATH + DOSSIER_ID_PATH_PARAM, produces = MediaType.APPLICATION_JSON_VALUE) + Dossier getDossierById(@PathVariable(DOSSIER_ID_PARAM) String dossierId); + + @GetMapping(value = DELETED_DOSSIERS_PATH, produces = MediaType.APPLICATION_JSON_VALUE) + List getSoftDeletedDossiers(); + + @DeleteMapping(value = DELETED_DOSSIERS_PATH + HARD_DELETE_PATH) + void hardDeleteDossiers(@RequestBody Set dossierIds); + + @PostMapping(value = DELETED_DOSSIERS_PATH + UNDELETE_PATH) + void undeleteDossiers(@RequestBody Set dossierIds); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DossierTemplateResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DossierTemplateResource.java new file mode 100644 index 000000000..cd19897d9 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DossierTemplateResource.java @@ -0,0 +1,40 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.iqser.red.service.persistence.service.v1.api.model.CreateOrUpdateDossierTemplateRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +public interface DossierTemplateResource { + + String DOSSIER_TEMPLATE_PATH = "/dossier-template"; + + String DOSSIER_TEMPLATE_ID = "dossierTemplateId"; + String DOSSIER_TEMPLATE_ID_PATH_VARIABLE = "/{" + DOSSIER_TEMPLATE_ID + "}"; + + String USER_ID_PARAM = "userId"; + + @ResponseBody + @ResponseStatus(HttpStatus.ACCEPTED) + @PostMapping(value = DOSSIER_TEMPLATE_PATH, consumes = MediaType.APPLICATION_JSON_VALUE) + DossierTemplate createOrUpdateDossierTemplate(@RequestBody CreateOrUpdateDossierTemplateRequest dossierTemplate); + + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @GetMapping(value = DOSSIER_TEMPLATE_PATH, produces = MediaType.APPLICATION_JSON_VALUE) + List getAllDossierTemplates(); + + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @GetMapping(value = DOSSIER_TEMPLATE_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + DossierTemplate getDossierTemplate(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId); + + @ResponseBody + @ResponseStatus(value = HttpStatus.NO_CONTENT) + @DeleteMapping(value = DOSSIER_TEMPLATE_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE) + void deleteDossierTemplate(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId, @RequestParam(USER_ID_PARAM) String deletingUserId); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DownloadResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DownloadResource.java new file mode 100644 index 000000000..548167db4 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/DownloadResource.java @@ -0,0 +1,32 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.iqser.red.service.persistence.service.v1.api.model.DownloadRequest; +import com.iqser.red.service.persistence.service.v1.api.model.JSONPrimitive; +import com.iqser.red.service.persistence.service.v1.api.model.SetDownloadedRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.download.DownloadStatus; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@ResponseStatus(value = HttpStatus.OK) +public interface DownloadResource { + + String REST_PATH = "/download"; + String USER_ID = "userId"; + + + @PostMapping(value = REST_PATH + "/prepare", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + JSONPrimitive prepareDownload(@RequestBody DownloadRequest request); + + + @GetMapping(value = REST_PATH + "/status/{" + USER_ID + "}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + List getDownloadStatus(@PathVariable(USER_ID) String userId); + + @PostMapping(value = REST_PATH + "/setDownloaded", consumes = MediaType.APPLICATION_JSON_VALUE) + void setDownloaded(@RequestBody JSONPrimitive setDownloadedRequest); + + @PostMapping(value = REST_PATH + "/delete", consumes = MediaType.APPLICATION_JSON_VALUE) + void deleteDownloadStatus(@RequestBody JSONPrimitive setDownloadedRequest); +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/FileAttributesResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/FileAttributesResource.java new file mode 100644 index 000000000..7e4db5861 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/FileAttributesResource.java @@ -0,0 +1,64 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.FileAttributesGeneralConfiguration; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.FileAttributeConfig; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +public interface FileAttributesResource { + + String FILE_ATTRIBUTES_PATH = "/fileAttributes"; + String FILE_ATTRIBUTE_PATH = "/fileAttribute"; + String BASE_CONFIG_PATH = "/baseConfig"; + + String DOSSIER_TEMPLATE_ID = "dossierTemplateId"; + String DOSSIER_TEMPLATE_ID_PATH_VARIABLE = "/{" + DOSSIER_TEMPLATE_ID + "}"; + + String FILE_ATTRIBUTE_ID = "fileAttributeId"; + String FILE_ATTRIBUTE_ID_PATH_VARIABLE = "/{" + FILE_ATTRIBUTE_ID + "}"; + + @ResponseBody + @ResponseStatus(HttpStatus.OK) + @PostMapping(value = FILE_ATTRIBUTES_PATH + FILE_ATTRIBUTE_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + FileAttributeConfig addOrUpdateFileAttribute(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId, + @RequestBody FileAttributeConfig fileAttributeConfig); + + + @ResponseBody + @ResponseStatus(HttpStatus.OK) + @PutMapping(value = FILE_ATTRIBUTES_PATH + BASE_CONFIG_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + FileAttributesGeneralConfiguration setFileAttributesGeneralConfig(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId, + @RequestBody FileAttributesGeneralConfiguration fileAttributesConfig); + + @ResponseBody + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = FILE_ATTRIBUTES_PATH + BASE_CONFIG_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + FileAttributesGeneralConfiguration getFileAttributesGeneralConfiguration(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId); + + @ResponseBody + @ResponseStatus(HttpStatus.OK) + @PutMapping(value = FILE_ATTRIBUTES_PATH + FILE_ATTRIBUTE_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + List setFileAttributesConfig(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId, + @RequestBody List fileAttributesConfig); + + + @ResponseStatus(HttpStatus.NO_CONTENT) + @DeleteMapping(value = FILE_ATTRIBUTES_PATH + FILE_ATTRIBUTE_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + FILE_ATTRIBUTE_ID_PATH_VARIABLE) + void deleteFileAttribute(@PathVariable(FILE_ATTRIBUTE_ID) String fileAttributeId); + + + @ResponseStatus(HttpStatus.NO_CONTENT) + @PostMapping(value = FILE_ATTRIBUTES_PATH + FILE_ATTRIBUTE_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + "/delete") + void deleteFileAttributes(@RequestBody List fileAttributeIds); + + + @ResponseBody + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = FILE_ATTRIBUTES_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + List getFileAttributes(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId); + + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/FileStatusProcessingUpdateResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/FileStatusProcessingUpdateResource.java new file mode 100644 index 000000000..fdef5cc3b --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/FileStatusProcessingUpdateResource.java @@ -0,0 +1,57 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.iqser.red.service.redaction.v1.model.AnalyzeResult; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseStatus; + + +public interface FileStatusProcessingUpdateResource { + + String STATUS_PATH = "/status-updates"; + String DOSSIER_ID_PARAM = "dossierId"; + String DOSSIER_ID_PATH_PARAM = "/{" + DOSSIER_ID_PARAM + "}"; + + String FILE_ID = "fileId"; + String FILE_ID_PATH_VARIABLE = "/{" + FILE_ID + "}"; + + + @ResponseStatus(value = HttpStatus.OK) + @PostMapping(value = STATUS_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + "/analysis-successful", consumes = MediaType.APPLICATION_JSON_VALUE) + void analysisSuccessful(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId, + @RequestBody AnalyzeResult analyzeResult); + + + @ResponseStatus(value = HttpStatus.OK) + @PostMapping(value = STATUS_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + "/ocr-successful") + void ocrSuccessful(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId); + + + @ResponseStatus(value = HttpStatus.OK) + @PostMapping(value = STATUS_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + "/analysis-failed") + void analysisFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId); + + + @ResponseStatus(value = HttpStatus.OK) + @PostMapping(value = STATUS_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + "/ocr-failed") + void ocrFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId); + + + @ResponseStatus(value = HttpStatus.OK) + @PostMapping(value = STATUS_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + "/indexing") + void indexing(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId); + + + @ResponseStatus(value = HttpStatus.OK) + @PostMapping(value = STATUS_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + "/indexing-successful") + void indexingSuccessful(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId); + + + @ResponseStatus(value = HttpStatus.OK) + @PostMapping(value = STATUS_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + "/indexing-failed") + void indexingFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/LegalBasisMappingResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/LegalBasisMappingResource.java new file mode 100644 index 000000000..74e1729f3 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/LegalBasisMappingResource.java @@ -0,0 +1,33 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.LegalBasis; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +public interface LegalBasisMappingResource { + + String LEGAL_BASIS_PATH = "/legalBasis"; + String VERSION_PATH = "/version"; + String DOSSIER_TEMPLATE_PARAMETER_NAME = "dossierTemplateId"; + String DOSSIER_TEMPLATE_PATH_VARIABLE = "/{" + DOSSIER_TEMPLATE_PARAMETER_NAME + "}"; + + + @ResponseStatus(HttpStatus.NO_CONTENT) + @PostMapping(value = LEGAL_BASIS_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE) + void setLegalBasisMapping(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, @RequestBody List legalBasisMapping); + + + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @GetMapping(value = LEGAL_BASIS_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + List getLegalBasisMapping(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId); + + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = LEGAL_BASIS_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE + VERSION_PATH) + long getVersion(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId); + + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/LicenseReportResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/LicenseReportResource.java new file mode 100644 index 000000000..9bfbea81c --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/LicenseReportResource.java @@ -0,0 +1,18 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.iqser.red.service.persistence.service.v1.api.model.LicenseReport; +import com.iqser.red.service.persistence.service.v1.api.model.LicenseReportRequest; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +public interface LicenseReportResource { + + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @PostMapping(value = "/report/license", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + LicenseReport getLicenseReport(@RequestBody LicenseReportRequest licenseReportRequest, + @RequestParam(value = "offset", defaultValue = "0") int offset, + @RequestParam(value = "limit", defaultValue = "20") int limit); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/ManualRedactionResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/ManualRedactionResource.java new file mode 100644 index 000000000..39c01beff --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/ManualRedactionResource.java @@ -0,0 +1,154 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.iqser.red.service.persistence.service.v1.api.model.*; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.*; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +@ResponseStatus(value = HttpStatus.OK) +public interface ManualRedactionResource { + + String MANUAL_REDACTION_REST_PATH = "/manualRedaction"; + + String DOSSIER_ID = "dossierId"; + String DOSSIER_ID_PATH_PARAM = "/{" + DOSSIER_ID + "}"; + + String FILE_ID = "fileId"; + String FILE_ID_PATH_VARIABLE = "/{" + FILE_ID + "}"; + + String ANNOTATION_ID = "annotationId"; + String ANNOTATION_ID_PATH_VARIABLE = "/{" + ANNOTATION_ID + "}"; + + String COMMENT_ID = "commentId"; + String COMMENT_ID_PATH_VARIABLE = "/{" + COMMENT_ID + "}"; + + + @PostMapping(value = MANUAL_REDACTION_REST_PATH + "/add" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + ManualAddResponse addAddRedaction(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, + @RequestBody AddRedactionRequest addRedactionRequest); + + + @PostMapping(value = MANUAL_REDACTION_REST_PATH + "/remove" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + ManualAddResponse addRemoveRedaction(@PathVariable(DOSSIER_ID) String dossierId, + @PathVariable(FILE_ID) String fileId, + @RequestBody RemoveRedactionRequest removeRedactionRequest); + + + @PostMapping(value = MANUAL_REDACTION_REST_PATH + "/force" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + ManualAddResponse addForceRedaction(@PathVariable(DOSSIER_ID) String dossierId, + @PathVariable(FILE_ID) String fileId, + @RequestBody ForceRedactionRequest forceRedactionRequest); + + + @PostMapping(value = MANUAL_REDACTION_REST_PATH + "/legalBasis" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + ManualAddResponse addLegalBasisChange(@PathVariable(DOSSIER_ID) String dossierId, + @PathVariable(FILE_ID) String fileId, + @RequestBody LegalBasisChangeRequest legalBasisChangeRequest); + + + @PostMapping(value = MANUAL_REDACTION_REST_PATH + "/recategorize" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + ManualAddResponse addImageRecategorization(@PathVariable(DOSSIER_ID) String dossierId, + @PathVariable(FILE_ID) String fileId, + @RequestBody ImageRecategorizationRequest imageRecategorizationRequest); + + + @PostMapping(value = MANUAL_REDACTION_REST_PATH + "/comment" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + ANNOTATION_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + Comment addComment(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId, @RequestBody CommentRequest comment); + + + @GetMapping(value = MANUAL_REDACTION_REST_PATH + "/add" + FILE_ID_PATH_VARIABLE + ANNOTATION_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + ManualRedactionEntry getAddRedaction(@PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId); + + + @GetMapping(value = MANUAL_REDACTION_REST_PATH + "/remove" + FILE_ID_PATH_VARIABLE + ANNOTATION_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + IdRemoval getRemoveRedaction(@PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId); + + + @GetMapping(value = MANUAL_REDACTION_REST_PATH + "/force" + FILE_ID_PATH_VARIABLE + ANNOTATION_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + ManualForceRedaction getForceRedaction(@PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId); + + + @GetMapping(value = MANUAL_REDACTION_REST_PATH + "/legalBasis" + FILE_ID_PATH_VARIABLE + ANNOTATION_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + ManualLegalBasisChange getLegalBasisChange(@PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId); + + + @GetMapping(value = MANUAL_REDACTION_REST_PATH + "/recategorize" + FILE_ID_PATH_VARIABLE + ANNOTATION_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + ManualImageRecategorization getImageRecategorization(@PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId); + + + @GetMapping(value = MANUAL_REDACTION_REST_PATH + "/comment" + COMMENT_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + Comment getComment( @PathVariable(COMMENT_ID) long commentId); + + + @DeleteMapping(MANUAL_REDACTION_REST_PATH + "/add" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + ANNOTATION_ID_PATH_VARIABLE) + void deleteAddRedaction(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId); + + + @DeleteMapping(MANUAL_REDACTION_REST_PATH + "/remove" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + ANNOTATION_ID_PATH_VARIABLE) + void deleteRemoveRedaction(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId); + + + @DeleteMapping(MANUAL_REDACTION_REST_PATH + "/force" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + ANNOTATION_ID_PATH_VARIABLE) + void deleteForceRedaction(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId); + + + @DeleteMapping(MANUAL_REDACTION_REST_PATH + "/legalBasis" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + ANNOTATION_ID_PATH_VARIABLE) + void deleteLegalBasisChange(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId); + + + @DeleteMapping(MANUAL_REDACTION_REST_PATH + "/recategorize" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + ANNOTATION_ID_PATH_VARIABLE) + void deleteImageRecategorization(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId); + + + @DeleteMapping(MANUAL_REDACTION_REST_PATH + "/comment" + FILE_ID_PATH_VARIABLE + COMMENT_ID_PATH_VARIABLE) + void deleteComment( @PathVariable(FILE_ID) String fileId,@PathVariable(COMMENT_ID) long commentId); + + + @PostMapping(value = MANUAL_REDACTION_REST_PATH + "/status/add" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + ANNOTATION_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE) + void updateAddRedactionStatus(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId, + @RequestBody JSONPrimitive updateStatusRequest); + + + @PostMapping(value = MANUAL_REDACTION_REST_PATH + "/status/remove" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + ANNOTATION_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE) + void updateRemoveRedactionStatus(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId, + @RequestBody JSONPrimitive updateStatusRequest); + + + @PostMapping(value = MANUAL_REDACTION_REST_PATH + "/status/force" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + ANNOTATION_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE) + void updateForceRedactionStatus(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId, + @RequestBody JSONPrimitive updateStatusRequest); + + + @PostMapping(value = MANUAL_REDACTION_REST_PATH + "/status/legalBasis" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + ANNOTATION_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE) + void updateLegalBasisChangeStatus(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId, + @RequestBody JSONPrimitive updateStatusRequest); + + + @PostMapping(value = MANUAL_REDACTION_REST_PATH + "/status/recategorize" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + ANNOTATION_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE) + void updateImageRecategorizationStatus(@PathVariable(DOSSIER_ID) String dossierId, + @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId, + @RequestBody JSONPrimitive updateStatusRequest); + + + @GetMapping(value = MANUAL_REDACTION_REST_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + ManualRedactions getManualRedactions(@PathVariable(DOSSIER_ID) String dossierId, + @PathVariable(FILE_ID) String fileId); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/ReanalysisResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/ReanalysisResource.java new file mode 100644 index 000000000..114546d8d --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/ReanalysisResource.java @@ -0,0 +1,53 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +import java.util.Set; + +@ResponseStatus(value = HttpStatus.NO_CONTENT) +public interface ReanalysisResource { + + String REANALYZE_PATH = "/reanalyze"; + String OCR_REANALYZE_PATH = "/ocr/reanalyze"; + String REINDEX_PATH = "/reindex"; + String DOSSIER_ID_PARAM = "dossierId"; + String DOSSIER_ID_PATH_PARAM = "/{" + DOSSIER_ID_PARAM + "}"; + String FILE_ID_PARAM = "fileId"; + String FILE_ID_PATH_PARAM = "/{" + FILE_ID_PARAM + "}"; + String BULK_REST_PATH = "/bulk"; + String FALSE = "false"; + + + @PostMapping(value = REANALYZE_PATH + DOSSIER_ID_PATH_PARAM) + void reanalyzeDossier(@PathVariable(DOSSIER_ID_PARAM) String dossierId, + @RequestParam(value = "force", required = false, defaultValue = FALSE) boolean force); + + + @PostMapping(value = REANALYZE_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_PARAM) + void reanalyzeFile(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID_PARAM) String fileId, + @RequestBody Set sectionsToReanalyse); + + + @PostMapping(value = REANALYZE_PATH + DOSSIER_ID_PATH_PARAM + BULK_REST_PATH) + void reanalyzeFiles(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @RequestBody Set fileIds, + @RequestParam(value = "force", required = false, defaultValue = FALSE) boolean force); + + + @PostMapping(value = OCR_REANALYZE_PATH + DOSSIER_ID_PATH_PARAM) + void ocrDossier(@PathVariable(DOSSIER_ID_PARAM) String dossierId); + + + @PostMapping(value = OCR_REANALYZE_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_PARAM) + void ocrFile(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID_PARAM) String fileId, @RequestParam(value = "force", required = false, defaultValue = FALSE) boolean force); + + + @PostMapping(value = OCR_REANALYZE_PATH + DOSSIER_ID_PATH_PARAM + BULK_REST_PATH) + void ocrFiles(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @RequestBody Set fileIds); + + + @PostMapping(value = REINDEX_PATH) + void reindex(@RequestParam(value = DOSSIER_ID_PARAM, required = false) String dossierId, @RequestBody Set fileIds); + + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/RedactionLogResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/RedactionLogResource.java new file mode 100644 index 000000000..913c8e9f0 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/RedactionLogResource.java @@ -0,0 +1,31 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.iqser.red.service.redaction.v1.model.RedactionLog; +import com.iqser.red.service.redaction.v1.model.SectionGrid; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(value = HttpStatus.OK) +public interface RedactionLogResource { + + String REDACTION_LOG_PATH = "/redactionLog"; + String SECTION_GRID_PATH = "/sectionGrid"; + + String FILE_ID = "fileId"; + String FILE_ID_PATH_VARIABLE = "/{" + FILE_ID + "}"; + + String DOSSIER_ID_PARAM = "dossierId"; + String DOSSIER_ID_PATH_PARAM = "/{" + DOSSIER_ID_PARAM + "}"; + + @GetMapping(value = REDACTION_LOG_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + RedactionLog getRedactionLog(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId, + @RequestParam(value = "withManualRedactions", required = false, defaultValue = "true") boolean withManualRedactions); + + @GetMapping(value = SECTION_GRID_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + SectionGrid getSectionGrid(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/ReportTemplateResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/ReportTemplateResource.java new file mode 100644 index 000000000..f61da3387 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/ReportTemplateResource.java @@ -0,0 +1,41 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.iqser.red.service.persistence.service.v1.api.model.ReportTemplateDownload; +import com.iqser.red.service.persistence.service.v1.api.model.ReportTemplateUploadRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.ReportTemplate; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +public interface ReportTemplateResource { + + String REPORT_TEMPLATE_UPLOAD_PATH = "/templateUpload"; + + String DOSSIER_TEMPLATE_ID = "dossierTemplateId"; + String DOSSIER_TEMPLATE_ID_PATH_VARIABLE = "/{" + DOSSIER_TEMPLATE_ID + "}"; + + String TEMPLATE_ID = "templateId"; + String TEMPLATE_ID_PATH_VARIABLE = "/{" + TEMPLATE_ID + "}"; + + String DOWNLOAD_PATH = "download"; + + + @PostMapping(value = REPORT_TEMPLATE_UPLOAD_PATH, consumes = MediaType.APPLICATION_JSON_VALUE, produces = + MediaType.APPLICATION_JSON_VALUE) + ReportTemplate uploadTemplate(@RequestBody ReportTemplateUploadRequest reportTemplateUploadRequest); + + @GetMapping(value = REPORT_TEMPLATE_UPLOAD_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + List getAvailableReportTemplates(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId); + + @GetMapping(value = REPORT_TEMPLATE_UPLOAD_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + TEMPLATE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + ReportTemplate getReportTemplate(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId, @PathVariable(TEMPLATE_ID) String templateId); + + @GetMapping(value = REPORT_TEMPLATE_UPLOAD_PATH + DOWNLOAD_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + TEMPLATE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + ReportTemplateDownload downloadReportTemplate(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId, @PathVariable(TEMPLATE_ID) String templateId); + + @DeleteMapping(value = REPORT_TEMPLATE_UPLOAD_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + TEMPLATE_ID_PATH_VARIABLE) + void deleteTemplate(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId, @PathVariable(TEMPLATE_ID) String templateId); + + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/RulesResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/RulesResource.java new file mode 100644 index 000000000..799c46269 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/RulesResource.java @@ -0,0 +1,29 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.iqser.red.service.persistence.service.v1.api.model.JSONPrimitive; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +public interface RulesResource { + + String PATH = "/rules"; + + String DOSSIER_TEMPLATE_PARAMETER_NAME = "dossierTemplateId"; + String DOSSIER_TEMPLATE_PATH_VARIABLE = "/{" + DOSSIER_TEMPLATE_PARAMETER_NAME + "}"; + String VERSION_PATH = "/version"; + + @ResponseStatus(HttpStatus.NO_CONTENT) + @PostMapping(value = PATH + DOSSIER_TEMPLATE_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE) + void setRules(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, @RequestBody JSONPrimitive rules); + + @ResponseBody + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = PATH + DOSSIER_TEMPLATE_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + JSONPrimitive getRules(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId); + + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = PATH + DOSSIER_TEMPLATE_PATH_VARIABLE + VERSION_PATH) + long getVersion(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/SMTPConfigurationResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/SMTPConfigurationResource.java new file mode 100644 index 000000000..191e4b3f6 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/SMTPConfigurationResource.java @@ -0,0 +1,40 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.SMTPConfiguration; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + + +public interface SMTPConfigurationResource { + + String SMTP_PATH = "/smtp"; + + String TEST_PATH = "/test"; + + String TEST_EMAIL = "testEmail"; + + String MASK_PASSWORD = "maskPassword"; + + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @GetMapping(value = SMTP_PATH, produces = MediaType.APPLICATION_JSON_VALUE) + SMTPConfiguration getCurrentSMTPConfiguration(@RequestParam(value = MASK_PASSWORD, required = false, defaultValue = "true") boolean maskPassword); + + + @ResponseStatus(value = HttpStatus.NO_CONTENT) + @PostMapping(value = SMTP_PATH, consumes = MediaType.APPLICATION_JSON_VALUE) + void updateSMTPConfiguration(@RequestBody SMTPConfiguration smtpConfigurationModel); + + + @ResponseStatus(value = HttpStatus.OK) + @PostMapping(value = SMTP_PATH + TEST_PATH, consumes = MediaType.APPLICATION_JSON_VALUE) + void testSMTPConfiguration(@RequestParam(value = TEST_EMAIL, required = false) String testEmail, @RequestBody SMTPConfiguration smtpConfigurationModel); + + + @ResponseStatus(value = HttpStatus.NO_CONTENT) + @DeleteMapping(value = SMTP_PATH) + void clearSMTPConfiguration(); + + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/StatusResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/StatusResource.java new file mode 100644 index 000000000..7cbfcde79 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/StatusResource.java @@ -0,0 +1,71 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.iqser.red.service.persistence.service.v1.api.model.JSONPrimitive; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Set; + +public interface StatusResource { + + String STATUS_PATH = "/status"; + String DELETED_PATH = "/softdeleted"; + String DOSSIER_ID_PARAM = "dossierId"; + String DOSSIER_ID_PATH_PARAM = "/{" + DOSSIER_ID_PARAM + "}"; + + String FILE_ID = "fileId"; + String FILE_ID_PATH_VARIABLE = "/{" + FILE_ID + "}"; + + String EXCLUDED_STATUS_PARAM = "excluded"; + + String APPROVER_ID_REQUEST_PARAM = "approverId"; + + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @GetMapping(value = STATUS_PATH, produces = MediaType.APPLICATION_JSON_VALUE) + List getAllStatuses(); + + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @GetMapping(value = STATUS_PATH + DOSSIER_ID_PATH_PARAM, produces = MediaType.APPLICATION_JSON_VALUE) + List getDossierStatus(@PathVariable(DOSSIER_ID_PARAM) String dossierId); + + + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @GetMapping(value = STATUS_PATH + DELETED_PATH + DOSSIER_ID_PATH_PARAM, produces = MediaType.APPLICATION_JSON_VALUE) + List getSoftDeletedDossierStatus(@PathVariable(DOSSIER_ID_PARAM) String dossierId); + + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @GetMapping(value = STATUS_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + File getFileStatus(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId); + + + @PostMapping(value = STATUS_PATH + "/reviewer" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE) + void setCurrentFileReviewer(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId, + @RequestBody JSONPrimitive currentReviewer); + + + @PostMapping(value = STATUS_PATH + "/underreview" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE) + void setStatusUnderReview(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId); + + @PostMapping(value = STATUS_PATH + "/underapproval" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE) + void setStatusUnderApproval(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestParam(value = APPROVER_ID_REQUEST_PARAM, required = false) String approverId); + + + @PostMapping(value = STATUS_PATH + "/approved" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE) + void setStatusApproved(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId); + + @PostMapping(value = STATUS_PATH + "/toggle-analysis" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE) + void toggleExclusion(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestParam(EXCLUDED_STATUS_PARAM) boolean excluded); + + @PostMapping(value = STATUS_PATH + "/exclude-pages" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE) + void excludePages(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody Set pages); + + @PostMapping(value = STATUS_PATH + "/include-pages" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE) + void includePages(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody Set pages); +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/UploadResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/UploadResource.java new file mode 100644 index 000000000..d6e56173f --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/UploadResource.java @@ -0,0 +1,71 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.iqser.red.service.persistence.service.v1.api.model.BinaryFileRequest; +import com.iqser.red.service.persistence.service.v1.api.model.BinaryFileResult; +import com.iqser.red.service.persistence.service.v1.api.model.JSONPrimitive; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +import java.util.Set; + +@ResponseStatus(value = HttpStatus.OK) +public interface UploadResource { + + String SERVICE_NAME = "file-management-service-v1"; + + String REST_PATH = "/file"; + + String DELETE_PATH = REST_PATH + "/delete"; + String UPLOAD_PATH = REST_PATH + "/upload"; + String ORIGINAL_PATH = REST_PATH + "/original"; + String ANNOTATED_PATH = REST_PATH + "/annotated"; + String REDACTED_PATH = REST_PATH + "/redacted"; + String PREVIEW_PATH = REST_PATH + "/preview"; + String FLATTED_PATH = REST_PATH + "/flatted"; + String HARD_DELETE_PATH = REST_PATH + "/hardDelete"; + String UNDELETE_PATH = REST_PATH + "/undelete"; + + String FILE_ID = "fileId"; + String FILE_ID_PATH_VARIABLE = "/{" + FILE_ID + "}"; + + String DOSSIER_ID_PARAM = "dossierId"; + String DOSSIER_ID_PATH_PARAM = "/{" + DOSSIER_ID_PARAM + "}"; + + + @PostMapping(value = UPLOAD_PATH, consumes = MediaType.APPLICATION_JSON_VALUE, produces = + MediaType.APPLICATION_JSON_VALUE) + JSONPrimitive upload(@RequestBody BinaryFileRequest request); + + + @DeleteMapping(value = DELETE_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE) + void deleteFile(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId); + + + @DeleteMapping(value = HARD_DELETE_PATH + DOSSIER_ID_PATH_PARAM) + void hardDeleteFiles(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @RequestBody Set fileIds); + + + @PostMapping(value = UNDELETE_PATH + DOSSIER_ID_PATH_PARAM) + void undeleteFiles(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @RequestBody Set fileIds); + + + @PostMapping(value = ORIGINAL_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + BinaryFileResult getOriginal(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId); + + + @PostMapping(value = ANNOTATED_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + BinaryFileResult getAnnotated(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId); + + + @PostMapping(value = REDACTED_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + BinaryFileResult getRedacted(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId); + + @PostMapping(value = PREVIEW_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + BinaryFileResult getPreview(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId); + + + @PostMapping(value = FLATTED_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + BinaryFileResult getFlatRedacted(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/UserPreferenceResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/UserPreferenceResource.java new file mode 100644 index 000000000..5534c7c48 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/UserPreferenceResource.java @@ -0,0 +1,34 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.fasterxml.jackson.databind.JsonNode; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +public interface UserPreferenceResource { + + String PREFERENCES_PATH = "/preferences"; + + String KEY_PARAMETER_NAME = "key"; + String KEY_PATH_VARIABLE = "/{" + KEY_PARAMETER_NAME + "}"; + + String USER_ID_PARAMETER_NAME = "userId"; + String USER_ID_PATH_VARIABLE = "/{" + USER_ID_PARAMETER_NAME + "}"; + + @ResponseStatus(HttpStatus.NO_CONTENT) + @PutMapping(value = PREFERENCES_PATH + USER_ID_PATH_VARIABLE + KEY_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE) + void savePreferences(@PathVariable(USER_ID_PARAMETER_NAME) String userId, @PathVariable(KEY_PARAMETER_NAME) String key, @RequestBody JsonNode jsonNode); + + + @ResponseBody + @ResponseStatus(value = HttpStatus.OK) + @GetMapping(value = PREFERENCES_PATH + USER_ID_PATH_VARIABLE + KEY_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + JsonNode getPreferences(@PathVariable(USER_ID_PARAMETER_NAME) String userId, @PathVariable(KEY_PARAMETER_NAME) String key); + + + @ResponseBody + @ResponseStatus(value = HttpStatus.NO_CONTENT) + @DeleteMapping(value = PREFERENCES_PATH + USER_ID_PATH_VARIABLE + KEY_PATH_VARIABLE) + void deletePreferences(@PathVariable(USER_ID_PARAMETER_NAME) String userId, @PathVariable(KEY_PARAMETER_NAME) String key); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/ViewedPagesResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/ViewedPagesResource.java new file mode 100644 index 000000000..86ff2f74f --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/ViewedPagesResource.java @@ -0,0 +1,35 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ViewedPage; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@ResponseStatus(value = HttpStatus.OK) +public interface ViewedPagesResource { + + String REST_PATH = "/viewedPages"; + + String FILE_ID = "fileId"; + String FILE_ID_PATH_VARIABLE = "/{" + FILE_ID + "}"; + + String ROLE = "role"; + String ROLE_PATH_VARIABLE = "/{" + ROLE + "}"; + + + @PostMapping(value = REST_PATH + FILE_ID_PATH_VARIABLE + ROLE_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE) + void addPage(@PathVariable(FILE_ID) String fileId, @PathVariable(ROLE) String role, + @RequestBody Integer page); + + + @DeleteMapping(value = REST_PATH + FILE_ID_PATH_VARIABLE + ROLE_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE) + void removePage(@PathVariable(FILE_ID) String fileId, @PathVariable(ROLE) String role, + @RequestBody Integer page); + + + @GetMapping(value = REST_PATH + FILE_ID_PATH_VARIABLE + ROLE_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + List getViewedPages(@PathVariable(FILE_ID) String fileId, @PathVariable(ROLE) String role); + +} diff --git a/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/WatermarkResource.java b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/WatermarkResource.java new file mode 100644 index 000000000..383889bd8 --- /dev/null +++ b/persistence-service-v1/persistence-service-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/resources/WatermarkResource.java @@ -0,0 +1,26 @@ +package com.iqser.red.service.persistence.service.v1.api.resources; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.Watermark; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +@ResponseStatus(value = HttpStatus.OK) +public interface WatermarkResource { + + String WATERMARK_PATH = "/watermark"; + String DOSSIER_TEMPLATE_PARAMETER_NAME = "dossierTemplateId"; + String DOSSIER_TEMPLATE_PATH_VARIABLE = "/{" + DOSSIER_TEMPLATE_PARAMETER_NAME + "}"; + + @ResponseStatus(HttpStatus.CREATED) + @PostMapping(value = WATERMARK_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + Watermark saveWatermark(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, @RequestBody Watermark watermark); + + @GetMapping(value = WATERMARK_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE) + Watermark getWatermark(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId); + + @ResponseStatus(HttpStatus.NO_CONTENT) + @DeleteMapping(value = WATERMARK_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE) + void deleteWatermark(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId); + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/pom.xml b/persistence-service-v1/persistence-service-processor-v1/pom.xml new file mode 100644 index 000000000..4a4caa1f2 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/pom.xml @@ -0,0 +1,95 @@ + + + + + persistence-service-v1 + com.iqser.red.service + 1.0-SNAPSHOT + + + 4.0.0 + + persistence-service-processor-v1 + + + + com.iqser.red.service + persistence-service-api-v1 + ${project.version} + + + com.iqser.red.service + pdftron-redaction-service-api-v1 + 2.18.0 + + + org.springframework.boot + spring-boot-starter-mail + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + com.iqser.red.commons + jackson-commons + + + com.iqser.red.commons + storage-commons + + + com.iqser.red.commons + logging-commons + + + org.apache.commons + commons-lang3 + + + + org.apache.commons + commons-collections4 + 4.4 + + + + org.springframework.cloud + spring-cloud-starter-openfeign + provided + + + + + commons-io + commons-io + test + + + + commons-codec + commons-codec + test + + + org.testcontainers + postgresql + 1.15.0 + test + + + org.springframework.boot + spring-boot-starter-test + test + + + org.apache.logging.log4j + log4j-slf4j-impl + test + + + + diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/PersistenceServiceProcessorConfiguration.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/PersistenceServiceProcessorConfiguration.java new file mode 100644 index 000000000..c0c3c02c6 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/PersistenceServiceProcessorConfiguration.java @@ -0,0 +1,12 @@ +package com.iqser.red.service.persistence.management.v1.processor; + +import com.iqser.red.service.persistence.management.v1.processor.client.PDFTronRedactionClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan +@EnableFeignClients(basePackageClasses = {PDFTronRedactionClient.class}) +public class PersistenceServiceProcessorConfiguration { +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/client/PDFTronRedactionClient.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/client/PDFTronRedactionClient.java new file mode 100644 index 000000000..554f19fe5 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/client/PDFTronRedactionClient.java @@ -0,0 +1,9 @@ +package com.iqser.red.service.persistence.management.v1.processor.client; + +import com.iqser.red.service.pdftron.redaction.v1.api.resources.PDFTronRedactionResource; +import org.springframework.cloud.openfeign.FeignClient; + +@FeignClient(name = "PDFTronRedactionResource", url = "${pdftron-redaction-service.url}") +public interface PDFTronRedactionClient extends PDFTronRedactionResource { + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/BadRequestException.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/BadRequestException.java new file mode 100644 index 000000000..172267e67 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/BadRequestException.java @@ -0,0 +1,13 @@ +package com.iqser.red.service.persistence.management.v1.processor.exception; + +public class BadRequestException extends RuntimeException { + + public BadRequestException(String message) { + super(message); + } + + public BadRequestException(String message, Throwable t) { + super(message, t); + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/ConflictException.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/ConflictException.java new file mode 100644 index 000000000..ff1eebe3f --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/ConflictException.java @@ -0,0 +1,9 @@ +package com.iqser.red.service.persistence.management.v1.processor.exception; + +public class ConflictException extends RuntimeException { + + public ConflictException(String message) { + super(message); + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/DossierNotFoundException.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/DossierNotFoundException.java new file mode 100644 index 000000000..cb961bed7 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/DossierNotFoundException.java @@ -0,0 +1,11 @@ +package com.iqser.red.service.persistence.management.v1.processor.exception; + +public class DossierNotFoundException extends RuntimeException { + + public static final String DOSSIER_NOT_FOUND_MESSAGE = "Dossier with DossierId %s not found in the database."; + + public DossierNotFoundException(String message) { + super(message); + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/FileNotFoundException.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/FileNotFoundException.java new file mode 100644 index 000000000..8a2b824d9 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/FileNotFoundException.java @@ -0,0 +1,9 @@ +package com.iqser.red.service.persistence.management.v1.processor.exception; + +public class FileNotFoundException extends RuntimeException { + + public FileNotFoundException(String message) { + super(message); + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/InternalServerErrorException.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/InternalServerErrorException.java new file mode 100644 index 000000000..3f8bfe827 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/InternalServerErrorException.java @@ -0,0 +1,13 @@ +package com.iqser.red.service.persistence.management.v1.processor.exception; + +public class InternalServerErrorException extends RuntimeException { + + public InternalServerErrorException(String message) { + super(message); + } + + public InternalServerErrorException(String message, Throwable t) { + super(message, t); + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/NotFoundException.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/NotFoundException.java new file mode 100644 index 000000000..bfa84359c --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/NotFoundException.java @@ -0,0 +1,9 @@ +package com.iqser.red.service.persistence.management.v1.processor.exception; + +public class NotFoundException extends RuntimeException { + + public NotFoundException(String message) { + super(message); + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/UserNotFoundException.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/UserNotFoundException.java new file mode 100644 index 000000000..bf952e107 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/UserNotFoundException.java @@ -0,0 +1,10 @@ +package com.iqser.red.service.persistence.management.v1.processor.exception; + +public class UserNotFoundException extends RuntimeException { + + public UserNotFoundException(String message) { + + super(message); + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/ValidationException.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/ValidationException.java new file mode 100644 index 000000000..d6d0545f0 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/exception/ValidationException.java @@ -0,0 +1,9 @@ +package com.iqser.red.service.persistence.management.v1.processor.exception; + +public class ValidationException extends RuntimeException { + + public ValidationException(String message) { + super(message); + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/UnprocessedFile.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/UnprocessedFile.java new file mode 100644 index 000000000..2ccd1f354 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/model/UnprocessedFile.java @@ -0,0 +1,13 @@ +package com.iqser.red.service.persistence.management.v1.processor.model; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class UnprocessedFile { + + private String fileId; + private String dossierId; + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/ColorsService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/ColorsService.java new file mode 100644 index 000000000..61b6885cb --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/ColorsService.java @@ -0,0 +1,29 @@ +package com.iqser.red.service.persistence.management.v1.processor.service; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.Colors; +import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.ColorsRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class ColorsService { + + private final ColorsRepository colorsRepository; + + public void deleteColors(String dossierTemplateId) { + + colorsRepository.deleteById(dossierTemplateId); + } + + public Colors getColors(String dossierTemplateId) { + return colorsRepository.findById(dossierTemplateId).orElseThrow(() -> new NotFoundException("Colors Configuration not found")); + } + + public Colors saveColors(Colors colors) { + return colorsRepository.save(colors); + } +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/DigitalSignatureService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/DigitalSignatureService.java new file mode 100644 index 000000000..c398b9215 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/DigitalSignatureService.java @@ -0,0 +1,64 @@ +package com.iqser.red.service.persistence.management.v1.processor.service; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.DigitalSignature; +import com.iqser.red.service.persistence.management.v1.processor.client.PDFTronRedactionClient; +import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException; +import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DigitalSignatureRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class DigitalSignatureService { + + private final EncryptionDecryptionService encryptionDecryptionService; + private final DigitalSignatureRepository digitalSignatureRepository; + private final PDFTronRedactionClient pdfTronRedactionClient; + + public void deleteDigitalSignature() { + digitalSignatureRepository.deleteById(DigitalSignature.ID); + } + + public DigitalSignature getDigitalSignature() { + return digitalSignatureRepository.findById(DigitalSignature.ID).map(digitalSignature -> { + DigitalSignature result = new DigitalSignature(); + BeanUtils.copyProperties(digitalSignature, result); + result.setPrivateKey(encryptionDecryptionService.decrypt(digitalSignature.getPrivateKey())); + result.setPassword(encryptionDecryptionService.decrypt(digitalSignature.getPassword())); + return result; + }).orElseThrow(() -> new NotFoundException("Digital Signature Not found")); + } + + public DigitalSignature saveDigitalSignature(DigitalSignature digitalSignature) { + + try { + // TODO + // pdfTronRedactionClient.testDigitalCurrentSignature(digitalSignature); + } catch (Exception e) { + throw new BadRequestException("Failed to test digital signature"); + } + + digitalSignature.setPrivateKey(encryptionDecryptionService.encrypt(digitalSignature.getPrivateKey())); + digitalSignature.setPassword(encryptionDecryptionService.encrypt(digitalSignature.getPassword())); + return digitalSignatureRepository.save(digitalSignature); + + } + + public void updateDigitalSignature(DigitalSignature digitalSignatureModel) { + + digitalSignatureRepository.findById(DigitalSignature.ID).ifPresentOrElse((digitalSignature -> { + digitalSignature.setCertificateName(digitalSignatureModel.getCertificateName()); + digitalSignature.setLocation(digitalSignatureModel.getLocation()); + digitalSignature.setContactInfo(digitalSignatureModel.getContactInfo()); + digitalSignature.setReason(digitalSignatureModel.getReason()); + }), () -> { + throw new NotFoundException("Digital Signature Not found"); + }); + } + + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EmailService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EmailService.java new file mode 100644 index 000000000..ff093c1c6 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EmailService.java @@ -0,0 +1,106 @@ +package com.iqser.red.service.persistence.management.v1.processor.service; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.SMTPConfiguration; +import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.JavaMailSenderImpl; +import org.springframework.stereotype.Service; + +import javax.mail.Address; +import javax.mail.Multipart; +import javax.mail.internet.AddressException; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMultipart; +import java.io.UnsupportedEncodingException; +import java.util.Date; +import java.util.Properties; + +@Slf4j +@Service +/** + * Logic Copied from KeyCloak since we need to test sending an e-mail the same way KeyCloak Does + */ +public class EmailService { + + + public void send(SMTPConfiguration smtpConfiguration, String toAddress, String subject, String textBody) { + try { + + var sender = getJavaMailSender(smtpConfiguration); + + String from = smtpConfiguration.getFrom(); + String fromDisplayName = smtpConfiguration.getFromDisplayName(); + String replyTo = smtpConfiguration.getReplyTo(); + String replyToDisplayName = smtpConfiguration.getReplyToDisplayName(); + + var msg = sender.createMimeMessage(); + + Multipart multipart = new MimeMultipart("alternative"); + + if (textBody != null) { + MimeBodyPart textPart = new MimeBodyPart(); + textPart.setText(textBody, "UTF-8"); + multipart.addBodyPart(textPart); + } + + + msg.setFrom(toInternetAddress(from, fromDisplayName)); + + msg.setReplyTo(new Address[]{toInternetAddress(from, fromDisplayName)}); + if (replyTo != null && !replyTo.isEmpty()) { + msg.setReplyTo(new Address[]{toInternetAddress(replyTo, replyToDisplayName)}); + } + + msg.setHeader("To", toAddress); + msg.setSubject(subject, "utf-8"); + msg.setContent(multipart); + msg.saveChanges(); + msg.setSentDate(new Date()); + + sender.send(msg); + } catch (Exception e) { + throw new BadRequestException("Failed to send e-mail", e); + } + } + + protected InternetAddress toInternetAddress(String email, String displayName) throws UnsupportedEncodingException, AddressException { + if (email == null || "".equals(email.trim())) { + throw new BadRequestException("Please provide a valid address"); + } + if (displayName == null || "".equals(displayName.trim())) { + return new InternetAddress(email); + } + return new InternetAddress(email, displayName, "utf-8"); + } + + public JavaMailSender getJavaMailSender(SMTPConfiguration smtpConfiguration) { + JavaMailSenderImpl mailSender = new JavaMailSenderImpl(); + mailSender.setHost(smtpConfiguration.getHost()); + mailSender.setPort(smtpConfiguration.getPort()); + + Properties props = mailSender.getJavaMailProperties(); + props.put("mail.transport.protocol", "smtp"); + props.setProperty("mail.smtp.timeout", "10000"); + props.setProperty("mail.smtp.connectiontimeout", "10000"); + + if (smtpConfiguration.isAuth()) { + mailSender.setUsername(smtpConfiguration.getUser()); + mailSender.setPassword(smtpConfiguration.getPassword()); + props.put("mail.smtp.auth", "true"); + } + + if (smtpConfiguration.isSsl()) { + props.setProperty("mail.smtp.ssl.enable", "true"); + } + + if (smtpConfiguration.isStarttls()) { + props.setProperty("mail.smtp.starttls.enable", "true"); + } + + return mailSender; + } + + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EncryptionDecryptionService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EncryptionDecryptionService.java new file mode 100644 index 000000000..e6915cbf2 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EncryptionDecryptionService.java @@ -0,0 +1,61 @@ +package com.iqser.red.service.persistence.management.v1.processor.service; + +import lombok.SneakyThrows; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.util.Arrays; +import java.util.Base64; + +@Service +public class EncryptionDecryptionService { + + @Value("${configuration-service.crypto.key:redaction}") + private String key; + private SecretKeySpec secretKey; + + @SneakyThrows + @PostConstruct + protected void postConstruct() { + byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8); + var sha = MessageDigest.getInstance("SHA-1"); + keyBytes = sha.digest(keyBytes); + keyBytes = Arrays.copyOf(keyBytes, 16); + secretKey = new SecretKeySpec(keyBytes, "AES"); + } + + @SneakyThrows + public String encrypt(String strToEncrypt) { + Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); + cipher.init(Cipher.ENCRYPT_MODE, secretKey); + return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes(StandardCharsets.UTF_8))); + } + + @SneakyThrows + public byte[] encrypt(byte[] bytes){ + Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); + cipher.init(Cipher.ENCRYPT_MODE, secretKey); + return cipher.doFinal(bytes); + } + + @SneakyThrows + public byte[] decrypt(byte[] bytes){ + Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); + cipher.init(Cipher.ENCRYPT_MODE, secretKey); + return cipher.doFinal(bytes); + } + + @SneakyThrows + public String decrypt(String strToDecrypt) { + Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING"); + cipher.init(Cipher.DECRYPT_MODE, secretKey); + return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)), StandardCharsets.UTF_8); + } + + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/WatermarkService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/WatermarkService.java new file mode 100644 index 000000000..55edd324a --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/WatermarkService.java @@ -0,0 +1,30 @@ +package com.iqser.red.service.persistence.management.v1.processor.service; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.Watermark; +import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.WatermarkRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class WatermarkService { + + + private final WatermarkRepository watermarkRepository; + + public void deleteWatermark(String dossierTemplateId) { + + watermarkRepository.deleteById(dossierTemplateId); + } + + public Watermark getWatermark(String dossierTemplateId) { + return watermarkRepository.findById(dossierTemplateId).orElseThrow(() -> new NotFoundException("Watermark Configuration not found")); + } + + public Watermark saveWatermark(Watermark watermark) { + return watermarkRepository.save(watermark); + } +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/AddRedactionPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/AddRedactionPersistenceService.java new file mode 100644 index 000000000..df6e2243e --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/AddRedactionPersistenceService.java @@ -0,0 +1,91 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + +import com.iqser.red.service.persistence.service.v1.api.model.AddRedactionRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.AnnotationId; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.AnnotationStatus; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ManualRedactionEntry; +import com.iqser.red.service.persistence.management.v1.processor.exception.FileNotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.ManualRedactionRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.time.OffsetDateTime; +import java.util.Set; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class AddRedactionPersistenceService { + + + private final ManualRedactionRepository manualRedactionRepository; + + + public void insert(String fileId, String annotationId, AddRedactionRequest addRedactionRequest) { + + ManualRedactionEntry manualRedactionEntry = new ManualRedactionEntry(); + manualRedactionEntry.setId(new AnnotationId(annotationId, fileId)); + BeanUtils.copyProperties(addRedactionRequest, manualRedactionEntry); + manualRedactionEntry.setRequestDate(OffsetDateTime.now()); + manualRedactionEntry.setPositions(addRedactionRequest.getPositions()); + + manualRedactionRepository.save(manualRedactionEntry); + + } + + + public ManualRedactionEntry findAddRedaction(String fileId, String annotationId) { + + return manualRedactionRepository.findById(new AnnotationId(annotationId, fileId)) + .filter(mre -> mre.getSoftDeletedTime() == null) + .orElseThrow(() -> + new FileNotFoundException("Unknown file/annotation combination: " + fileId + "/" + annotationId)); + } + + + public Set findAddRedactions(String fileId, boolean includeDeletions) { + + return manualRedactionRepository.findByIdFileId(fileId).stream().filter(mre -> includeDeletions || mre.getSoftDeletedTime() == null).collect(Collectors.toSet()); + + } + + + public void hardDelete(String fileId, String annotationId) { + manualRedactionRepository.deleteById(new AnnotationId(annotationId, fileId)); + } + + + public void softDelete(String fileId, String annotationId, OffsetDateTime softDeleteTime) { + + manualRedactionRepository.findById(new AnnotationId(annotationId, fileId)).ifPresent(mre -> mre.setSoftDeletedTime(softDeleteTime)); + } + + public void undelete(String fileId, String annotationId) { + manualRedactionRepository.findById(new AnnotationId(annotationId, fileId)).ifPresent(mre -> mre.setSoftDeletedTime(null)); + } + + + public void updateStatus(String fileId, String annotationId, AnnotationStatus annotationStatus) { + + manualRedactionRepository.findById(new AnnotationId(annotationId, fileId)).ifPresent(mre -> { + mre.setProcessedDate(OffsetDateTime.now()); + mre.setStatus(annotationStatus); + }); + + + } + + + public void updateStatus(String fileId, String annotationId, AnnotationStatus annotationStatus, boolean isAddOrRemoveFromDictionary) { + + manualRedactionRepository.findById(new AnnotationId(annotationId, fileId)).ifPresent(mre -> { + mre.setProcessedDate(OffsetDateTime.now()); + mre.setStatus(annotationStatus); + mre.setAddToDictionary(isAddOrRemoveFromDictionary); + }); + + } + + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/CommentPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/CommentPersistenceService.java new file mode 100644 index 000000000..415bcbe7e --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/CommentPersistenceService.java @@ -0,0 +1,68 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.Comment; +import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.CommentRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.time.OffsetDateTime; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class CommentPersistenceService { + + + private final CommentRepository commentRepository; + + + public Comment insert(Comment comment) { + + return commentRepository.save(comment); + + } + + + public Comment findComment(long commentId) { + return commentRepository.findById(commentId).orElseThrow(() -> new NotFoundException("Comment with id: " + commentId + " not found")); + } + + + public List findCommentsByAnnotationId(String fileId, String annotationId, boolean includeDeletions) { + return commentRepository.findByFileIdAndAnnotationId(fileId, annotationId).stream().filter(mre -> includeDeletions || mre.getSoftDeletedTime() == null).collect(Collectors.toList()); + } + + + public Map> findCommentsByFileID(String fileId, boolean includeDeletions) { + List comments = commentRepository.findByFileId(fileId).stream().filter(mre -> includeDeletions || mre.getSoftDeletedTime() == null).collect(Collectors.toList()); + + return comments.stream().collect(Collectors.groupingBy(Comment::getAnnotationId)); + } + + public boolean fileHasComments(String fileId) { + return commentRepository.existsByFileIdAAndSoftDeletedTimeIsNull(fileId); + } + + public void hardDelete(long commentId) { + commentRepository.deleteById(commentId); + } + + + public void softDelete(long commentId, OffsetDateTime softDeletedTime) { + + commentRepository.findById(commentId).ifPresent(mre -> { + mre.setSoftDeletedTime(softDeletedTime); + }); + } + + public void undelete(long commentId) { + commentRepository.findById(commentId).ifPresent(mre -> { + mre.setSoftDeletedTime(null); + }); + } + + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DictionaryPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DictionaryPersistenceService.java new file mode 100644 index 000000000..530ff08c5 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DictionaryPersistenceService.java @@ -0,0 +1,114 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.Type; +import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException; +import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierTemplateRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.TypeRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + + +@Service +@RequiredArgsConstructor +public class DictionaryPersistenceService { + + private final TypeRepository typeRepository; + + private final DossierTemplateRepository dossierTemplateRepository; + + private final DossierRepository dossierRepository; + + public Type addType(String type, String dossierTemplateId, String hexColor, int rank, boolean isHint, + boolean caseInsensitive, boolean isRecommendation, String description, + boolean addToDictionaryAction, String label, String dossierId) { + + checkRankAlreadyExists(type, dossierTemplateId, rank, dossierId); + + Type t = new Type(); + t.setDossier(dossierId == null ? null : dossierRepository.getOne(dossierId)); + t.setDossierTemplate(dossierTemplateRepository.getOne(dossierTemplateId)); + t.setHexColor(hexColor); + t.setRank(rank); + t.setDescription(description); + t.setHint(isHint); + t.setCaseInsensitive(caseInsensitive); + t.setRecommendation(isRecommendation); + t.setAddToDictionaryAction(addToDictionaryAction); + t.setLabel(label); + + return typeRepository.save(t); + + } + + + public void updateType(String typeId, Type typeValueRequest){ + + + typeRepository.findById(typeId).ifPresent((type) -> { + checkRankAlreadyExists(type.getType(), type.getDossierTemplate().getId(), typeValueRequest.getRank(), type.getDossier() == null ? null : type.getDossier().getId()); + BeanUtils.copyProperties(typeValueRequest, type); + }); + } + + + public Optional getTypeForRank(String dossierTemplateId, int rank, String dossierId) { + + return typeRepository.findOneByDossierTemplateAndDossierAndRank( + dossierTemplateRepository.getOne(dossierTemplateId), dossierId == null ? null : dossierRepository.getOne(dossierId), rank); + + } + + + public List getCumulatedTypes(String dossierTemplateId, String dossierId) { + + var templateTypes = getAllTypesForDossierTemplate(dossierTemplateId); + templateTypes.addAll(getAllTypesForDossier(dossierId)); + return templateTypes; + } + + + + + + public List getAllTypesForDossierTemplate(String dossierTemplateId) { + + return typeRepository.findByDossierTemplateId(dossierTemplateId); + } + + public List getAllTypesForDossier(String dossierId) { + return typeRepository.findByDossierId(dossierId); + } + + + public void deleteType(String typeId) { + typeRepository.deleteById(typeId); + } + + + public Type getType(String typeId) { + return typeRepository.findById(typeId).orElseThrow(() -> new NotFoundException("No color found for type : " + typeId)); + } + + + private void checkRankAlreadyExists(String type, String dossierTemplateId, int rank, String dossierId) { + + Optional existingTypeValueForRank = getTypeForRank(dossierTemplateId, rank, dossierId); + // not the current type - which we are about to upsert -> throw exception + if (existingTypeValueForRank.isPresent() && !existingTypeValueForRank.get().getType().equalsIgnoreCase(type)) { + throw new BadRequestException("Rank already exists: " + rank + " on type: " + existingTypeValueForRank.get() + .getType()); + } + } + + public void incrementVersion(String typeId) { + typeRepository.updateByIdSetIncrementVersionByOne(typeId); + } + + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierAttributeConfigPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierAttributeConfigPersistenceService.java new file mode 100644 index 000000000..e6d528e4b --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierAttributeConfigPersistenceService.java @@ -0,0 +1,97 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + +import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierAttributeConfigRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierTemplateRepository; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierAttributeConfig; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.text.WordUtils; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +@Service +@RequiredArgsConstructor +public class DossierAttributeConfigPersistenceService { + + private final DossierAttributeConfigRepository dossierAttributeConfigRepository; + private final DossierTemplateRepository dossierTemplateRepository; + + public DossierAttributeConfig addOrUpdateDossierAttribute(String dossierTemplateId, DossierAttributeConfig dossierAttributeConfig) { + var dossierTemplate = dossierTemplateRepository.getOne(dossierTemplateId); + dossierAttributeConfig.setDossierTemplate(dossierTemplate); + if (dossierAttributeConfig.getId() == null) { + dossierAttributeConfig.setId(UUID.randomUUID().toString()); + setPlaceholder(dossierAttributeConfig); + uniqueLabelAndPlaceholder(dossierAttributeConfig); + return dossierAttributeConfigRepository.save(dossierAttributeConfig); + } else { + + Optional optionalConfig = dossierAttributeConfigRepository.findById(dossierAttributeConfig.getId()); + + if (optionalConfig.isPresent()) { + var config = optionalConfig.get(); + config.setLabel(dossierAttributeConfig.getLabel()); + config.setType(dossierAttributeConfig.getType()); + config.setEditable(dossierAttributeConfig.isEditable()); + setPlaceholder(config); + uniqueLabelAndPlaceholder(dossierAttributeConfig); + return dossierAttributeConfigRepository.save(config); + } else { + dossierAttributeConfig.setId(UUID.randomUUID().toString()); + setPlaceholder(dossierAttributeConfig); + uniqueLabelAndPlaceholder(dossierAttributeConfig); + return dossierAttributeConfigRepository.save(dossierAttributeConfig); + } + + } + } + + public List setDossierAttributesConfig(String dossierTemplateId, List dossierAttributesConfig) { + + dossierAttributeConfigRepository.deleteByDossierTemplateId(dossierTemplateId); + var dossierTemplate = dossierTemplateRepository.getOne(dossierTemplateId); + dossierAttributesConfig.forEach(d -> { + d.setDossierTemplate(dossierTemplate); + d.setId(UUID.randomUUID().toString()); + setPlaceholder(d); + uniqueLabelAndPlaceholder(d); + }); + return getDossierAttributes(dossierTemplateId); + } + + public void deleteDossierAttribute(String dossierAttributeId) { + dossierAttributeConfigRepository.deleteById(dossierAttributeId); + } + + public void deleteDossierAttributes(List dossierAttributeIds) { + dossierAttributeIds.forEach(dossierAttributeConfigRepository::deleteById); + } + + public List getDossierAttributes(String dossierTemplateId) { + return dossierAttributeConfigRepository.findAllByDossierTemplateId(dossierTemplateId); + } + + private void setPlaceholder(DossierAttributeConfig dossierAttributeConfig) { + if (dossierAttributeConfig.getPlaceholder() == null || dossierAttributeConfig.getPlaceholder().isEmpty()) { + String placeholder = "{{dossier.attribute." + StringUtils.remove(WordUtils.capitalizeFully(dossierAttributeConfig.getLabel(), ' '), " ") + "}}"; + dossierAttributeConfig.setPlaceholder(placeholder); + } + } + + private void uniqueLabelAndPlaceholder(DossierAttributeConfig dossierAttributesConfig) { + getDossierAttributes(dossierAttributesConfig.getDossierTemplate().getId()).stream().filter( + d -> !d.getId().equals(dossierAttributesConfig.getId())).forEach(other -> { + if (other.getLabel().equalsIgnoreCase(dossierAttributesConfig.getLabel())) { + throw new ConflictException("Label already exists."); + } + if (other.getPlaceholder().equalsIgnoreCase(dossierAttributesConfig.getPlaceholder())) { + throw new ConflictException("Placeholder already exists."); + } + }); + + } +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierAttributePersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierAttributePersistenceService.java new file mode 100644 index 000000000..a045773f4 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierAttributePersistenceService.java @@ -0,0 +1,42 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierAttribute; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierAttributeRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +@SuppressWarnings("PMD.TooManyStaticImports") +public class DossierAttributePersistenceService { + + private final DossierAttributeRepository dossierAttributeRepository; + + + public void insertDossierAttribute(String dossierId, String dossierAttributeId, String dossierAttributeValue) { + + + DossierAttribute dossierAttribute = new DossierAttribute(); + dossierAttribute.setId(new DossierAttribute.DossierAttributeId(dossierId, dossierAttributeId)); + dossierAttribute.setValue(dossierAttributeValue); + dossierAttributeRepository.save(dossierAttribute); + } + + public void updateDossierAttribute(String dossierId, String dossierAttributeId, String dossierAttributeValue) { + + dossierAttributeRepository.findById(new DossierAttribute.DossierAttributeId(dossierId, dossierAttributeId)).ifPresent(dossierAttribute -> dossierAttribute.setValue(dossierAttributeValue)); + } + + public void deleteDossierAttribute(String dossierId, String dossierAttributeId) { + dossierAttributeRepository.deleteById(new DossierAttribute.DossierAttributeId(dossierId, dossierAttributeId)); + } + + public List getDossierAttributes(String dossierId) { + return dossierAttributeRepository.findByIdDossierId(dossierId); + + } + + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierPersistenceService.java new file mode 100644 index 000000000..67007519d --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierPersistenceService.java @@ -0,0 +1,118 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + +import com.iqser.red.service.persistence.service.v1.api.model.CreateOrUpdateDossierRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.Dossier; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierStatus; +import com.iqser.red.service.persistence.management.v1.processor.exception.DossierNotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierTemplateRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.ReportTemplateRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.time.OffsetDateTime; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +import static com.iqser.red.service.persistence.management.v1.processor.exception.DossierNotFoundException.DOSSIER_NOT_FOUND_MESSAGE; + +@Service +@RequiredArgsConstructor +public class DossierPersistenceService { + + private static final String ACTIVE_STATUS = "ACTIVE"; + private static final String DELETED_STATUS = "DELETED"; + + private final DossierRepository dossierRepository; + private final DossierTemplateRepository dossierTemplateRepository; + private final ReportTemplateRepository reportTemplateRepository; + + public Dossier insert(CreateOrUpdateDossierRequest createOrUpdateDossierRequest) { + + Dossier dossier = new Dossier(); + dossier.setId(UUID.randomUUID().toString()); + BeanUtils.copyProperties(createOrUpdateDossierRequest, dossier); + + dossier.setDossierTemplate(dossierTemplateRepository.getOne(createOrUpdateDossierRequest.getDossierTemplateId())); + dossier.setReportTemplates(reportTemplateRepository.findAllById(createOrUpdateDossierRequest.getReportTemplateIds())); + + return dossierRepository.save(dossier); + + + } + + + public void update(String dossierId, CreateOrUpdateDossierRequest createOrUpdateDossierRequest) { + + dossierRepository.findById(dossierId).ifPresent(dossier -> { + BeanUtils.copyProperties(createOrUpdateDossierRequest, dossier); + dossier.setDossierTemplate(dossierTemplateRepository.getOne(createOrUpdateDossierRequest.getDossierTemplateId())); + dossier.setReportTemplates(reportTemplateRepository.findAllById(createOrUpdateDossierRequest.getReportTemplateIds())); + }); + + } + + + public void updateReportTemplateIds(String dossierId, Set reportTemplateIds) { + dossierRepository.findById(dossierId).ifPresent(dossier -> { + dossier.setReportTemplates(reportTemplateRepository.findAllById(reportTemplateIds)); + }); + } + + + public Dossier getAndValidateDossier(String dossierId) { + // check whether the dossierId exists and is not deleted + var dossier = findByDossierId(dossierId); + if (dossier == null || dossier.getStatus().equals(DossierStatus.DELETED)) { + throw new DossierNotFoundException(String.format(DOSSIER_NOT_FOUND_MESSAGE, dossierId)); + } + return dossier; + + } + + + public Dossier findByDossierId(String dossierId) { + return dossierRepository.findById(dossierId).orElseThrow(() -> new DossierNotFoundException(String.format(DOSSIER_NOT_FOUND_MESSAGE, dossierId))); + } + + + public List findAllDossiers() { + return dossierRepository.findAll(); + } + + + public List findSoftDeletedDossiers() { + + return findAllDossiers().stream().filter(d -> d.getSoftDeletedTime() != null).collect(Collectors.toList()); + + } + + + public void hardDelete(String dossierId) { + dossierRepository.findById(dossierId).ifPresent(dossier -> { + dossier.setHardDeletedTime(OffsetDateTime.now()); + dossier.setStatus(DossierStatus.DELETED); + dossier.setSoftDeletedTime(dossier.getSoftDeletedTime() == null ? OffsetDateTime.now() : dossier.getSoftDeletedTime()); + }); + } + + + public void undelete(String dossierId) { + dossierRepository.findById(dossierId).ifPresent(dossier -> { + dossier.setStatus(DossierStatus.ACTIVE); + dossier.setSoftDeletedTime(null); + }); + } + + + public void markDossierAsDeleted(String dossierId, OffsetDateTime softDeletedTime) { + dossierRepository.findById(dossierId).ifPresent(dossier -> { + dossier.setStatus(DossierStatus.DELETED); + dossier.setSoftDeletedTime(softDeletedTime); + }); + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierTemplatePersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierTemplatePersistenceService.java new file mode 100644 index 000000000..54ddcdccc --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DossierTemplatePersistenceService.java @@ -0,0 +1,72 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + +import com.iqser.red.service.persistence.service.v1.api.model.CreateOrUpdateDossierRequest; +import com.iqser.red.service.persistence.service.v1.api.model.CreateOrUpdateDossierTemplateRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierTemplate; +import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierTemplateRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.time.OffsetDateTime; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + + +@Service +@RequiredArgsConstructor +public class DossierTemplatePersistenceService { + + public static final String DOSSIER_TEMPLATE_NOT_FOUND_MESSAGE = "DossierTemplate with Id %s not found."; + + private final DossierTemplateRepository dossierTemplateRepository; + + + public DossierTemplate createOrUpdateDossierTemplate(CreateOrUpdateDossierTemplateRequest createOrUpdateDossierRequest) { + + + if (createOrUpdateDossierRequest.getDossierTemplateId() != null) { + Optional dossierTemplate = dossierTemplateRepository.findById(createOrUpdateDossierRequest.getDossierTemplateId()); + if (dossierTemplate.isPresent()) { + dossierTemplate.get().setDateModified(OffsetDateTime.now()); + dossierTemplate.get().setModifiedBy(createOrUpdateDossierRequest.getRequestingUser()); + return dossierTemplate.get(); + } else { + throw new NotFoundException(String.format(DOSSIER_TEMPLATE_NOT_FOUND_MESSAGE, createOrUpdateDossierRequest.getDossierTemplateId())); + } + } else { + DossierTemplate dossierTemplate = new DossierTemplate(); + dossierTemplate.setId(UUID.randomUUID().toString()); + dossierTemplate.setDateAdded(OffsetDateTime.now()); + dossierTemplate.setCreatedBy(createOrUpdateDossierRequest.getRequestingUser()); + BeanUtils.copyProperties(createOrUpdateDossierRequest, dossierTemplate); + return dossierTemplateRepository.save(dossierTemplate); + } + + } + + + + public List getAllDossierTemplates() { + return dossierTemplateRepository.findAllWhereDeletedIsFalse(); + } + + public DossierTemplate getDossierTemplate(String dossierTemplateId) { + return dossierTemplateRepository.findById(dossierTemplateId).filter(d -> !d.isDeleted()).orElseThrow(() -> new NotFoundException(String.format(DOSSIER_TEMPLATE_NOT_FOUND_MESSAGE, dossierTemplateId))); + } + + public void deleteDossierTemplate(String dossierTemplateId, String deletingUserId) { + dossierTemplateRepository.findById(dossierTemplateId).ifPresentOrElse((dossierTemplate) -> { + dossierTemplate.setModifiedBy(deletingUserId); + dossierTemplate.setDateModified(OffsetDateTime.now()); + dossierTemplate.setDeleted(true); + }, () -> { + throw new NotFoundException(String.format(DOSSIER_TEMPLATE_NOT_FOUND_MESSAGE, dossierTemplateId)); + }); + + } + + +} 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 new file mode 100644 index 000000000..4b083e39b --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/DownloadStatusPersistenceService.java @@ -0,0 +1,89 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.Dossier; +import com.iqser.red.service.persistence.service.v1.api.model.data.download.DownloadStatus; +import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DownloadStatusRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.FileRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.time.OffsetDateTime; +import java.util.List; + +@Service +@RequiredArgsConstructor +public class DownloadStatusPersistenceService { + + private final DownloadStatusRepository downloadStatusRepository; + private final FileRepository fileRepository; + + public void createStatus(String userId, String storageId, Dossier dossier, String filename, String mimeType, + List fileIds) { + + + DownloadStatus downloadStatus = new DownloadStatus(); + downloadStatus.setUserId(userId); + downloadStatus.setStorageId(storageId); + downloadStatus.setFilename(filename); + downloadStatus.setMimeType(mimeType); + downloadStatus.setDossier(dossier); + downloadStatus.setCreationDate(OffsetDateTime.now()); + downloadStatus.setFiles(fileRepository.findAllById(fileIds)); + + downloadStatusRepository.save(downloadStatus); + } + + + public void updateStatus(String storageId, DownloadStatus.DownloadStatusValue status) { + + downloadStatusRepository.findById(storageId).ifPresent(downloadStatus -> downloadStatus.setStatus(status)); + + } + + + public void updateStatus(String storageId, DownloadStatus.DownloadStatusValue status, long fileSize) { + downloadStatusRepository.findById(storageId).ifPresent(downloadStatus -> { + downloadStatus.setStatus(status); + downloadStatus.setFileSize(fileSize); + }); + } + + + + public void updateLastDownload(String storageId) { + + downloadStatusRepository.findById(storageId).ifPresent(downloadStatus -> { + downloadStatus.setLastDownload(OffsetDateTime.now()); + }); + + } + + + public void deleteStatus(String storageId) { + downloadStatusRepository.deleteById(storageId); + } + + + public DownloadStatus getStatus(String storageId) { + + return downloadStatusRepository.findById(storageId).orElseThrow(() -> + new NotFoundException(String.format("DownloadStatus not found for storageId: %s", storageId))); + + } + + + public List getStatusesByUser(String userId) { + + return downloadStatusRepository.findAllByUserId(userId); + + } + + + 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/EntryPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/EntryPersistenceService.java new file mode 100644 index 000000000..5412a564e --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/EntryPersistenceService.java @@ -0,0 +1,56 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.DictionaryEntry; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.EntryRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.TypeRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +@Slf4j +@RequiredArgsConstructor +public class EntryPersistenceService { + + + private final EntryRepository entryRepository; + + private final TypeRepository typeRepository; + + public void addEntry(String typeId, List entries, long version) { + + var type = typeRepository.getOne(typeId); + + var dictionaryEntries = entries.stream().map(word -> { + DictionaryEntry entry = new DictionaryEntry(); + entry.setVersion(version); + entry.setValue(word); + entry.setType(type); + return entry; + }).collect(Collectors.toList()); + + entryRepository.saveAll(dictionaryEntries); + } + + + public void deleteEntries(String typeId, List values, long version) { + entryRepository.deleteAllByTypeIdAndVersionAndValueIn(typeId, version, values); + } + + + public void setVersion(String typeId, List values, long version) { + entryRepository.updateVersionByTypeIdAndValueIn(version, typeId, values); + } + + + public List getEntries(String typeId) { + + return entryRepository.findByTypeId(typeId); + + + } + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/FileAttributeConfigPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/FileAttributeConfigPersistenceService.java new file mode 100644 index 000000000..f635f667b --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/FileAttributeConfigPersistenceService.java @@ -0,0 +1,116 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + + +import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException; +import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierTemplateRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.FileAttributeConfigRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.FileAttributesGeneralConfigurationRepository; +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.FileAttributesGeneralConfiguration; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.FileAttributeConfig; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.text.WordUtils; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +@Service +@RequiredArgsConstructor +public class FileAttributeConfigPersistenceService { + + private final FileAttributeConfigRepository fileAttributeConfigRepository; + private final FileAttributesGeneralConfigurationRepository fileAttributesGeneralConfigurationRepository; + private final DossierTemplateRepository dossierTemplateRepository; + + public FileAttributeConfig addOrUpdateFileAttribute(String dossierTemplateId, FileAttributeConfig fileAttributeConfig) { + var dossierTemplate = dossierTemplateRepository.getOne(dossierTemplateId); + fileAttributeConfig.setDossierTemplate(dossierTemplate); + if (fileAttributeConfig.getId() == null) { + fileAttributeConfig.setId(UUID.randomUUID().toString()); + setPlaceholder(fileAttributeConfig); + uniqueLabelAndPlaceholder(fileAttributeConfig); + return fileAttributeConfigRepository.save(fileAttributeConfig); + } else { + + Optional optionalConfig = fileAttributeConfigRepository.findById(fileAttributeConfig.getId()); + + if (optionalConfig.isPresent()) { + var config = optionalConfig.get(); + config.setLabel(fileAttributeConfig.getLabel()); + config.setType(fileAttributeConfig.getType()); + config.setEditable(fileAttributeConfig.isEditable()); + config.setCsvColumnHeader(fileAttributeConfig.getCsvColumnHeader()); + config.setDisplayedInFileList(fileAttributeConfig.isDisplayedInFileList()); + config.setPrimaryAttribute(fileAttributeConfig.isPrimaryAttribute()); + config.setFilterable(fileAttributeConfig.isFilterable()); + setPlaceholder(config); + uniqueLabelAndPlaceholder(fileAttributeConfig); + return fileAttributeConfigRepository.save(config); + } else { + fileAttributeConfig.setId(UUID.randomUUID().toString()); + setPlaceholder(fileAttributeConfig); + uniqueLabelAndPlaceholder(fileAttributeConfig); + return fileAttributeConfigRepository.save(fileAttributeConfig); + } + + } + } + + public FileAttributesGeneralConfiguration setFileAttributesGeneralConfig(String dossierTemplateId, FileAttributesGeneralConfiguration fileAttributesConfig) { + fileAttributesConfig.setDossierTemplateId(dossierTemplateId); + fileAttributesConfig.setDossierTemplate(dossierTemplateRepository.getOne(dossierTemplateId)); + return fileAttributesGeneralConfigurationRepository.save(fileAttributesConfig); + } + + public FileAttributesGeneralConfiguration getFileAttributesGeneralConfiguration(String dossierTemplateId) { + return fileAttributesGeneralConfigurationRepository.findById(dossierTemplateId).orElseThrow(() -> new NotFoundException("File Attribute Config not found")); + } + + public List setFileAttributesConfig(String dossierTemplateId, List fileAttributesConfig) { + + fileAttributeConfigRepository.deleteByDossierTemplateId(dossierTemplateId); + var dossierTemplate = dossierTemplateRepository.getOne(dossierTemplateId); + fileAttributesConfig.forEach(d -> { + d.setDossierTemplate(dossierTemplate); + d.setId(UUID.randomUUID().toString()); + setPlaceholder(d); + uniqueLabelAndPlaceholder(d); + }); + return getFileAttributes(dossierTemplateId); + } + + public void deleteFileAttribute(String fileAttributeId) { + fileAttributeConfigRepository.deleteById(fileAttributeId); + } + + public void deleteFileAttributes(List fileAttributeIds) { + fileAttributeIds.forEach(fileAttributeConfigRepository::deleteById); + } + + public List getFileAttributes(String dossierTemplateId) { + return fileAttributeConfigRepository.findByDossierTemplateId(dossierTemplateId); + } + + private void setPlaceholder(FileAttributeConfig fileAttributeConfig) { + if (fileAttributeConfig.getPlaceholder() == null || fileAttributeConfig.getPlaceholder().isEmpty()) { + String placeholder = "{{file.attribute." + StringUtils.remove(WordUtils.capitalizeFully(fileAttributeConfig.getLabel(), ' '), " ") + "}}"; + fileAttributeConfig.setPlaceholder(placeholder); + } + } + + private void uniqueLabelAndPlaceholder(FileAttributeConfig fileAttributeConfig) { + getFileAttributes(fileAttributeConfig.getDossierTemplate().getId()).stream().filter( + d -> !d.getId().equals(fileAttributeConfig.getId())).forEach(other -> { + if (other.getLabel().equalsIgnoreCase(fileAttributeConfig.getLabel())) { + throw new ConflictException("Label already exists."); + } + if (other.getPlaceholder().equalsIgnoreCase(fileAttributeConfig.getPlaceholder())) { + throw new ConflictException("Placeholder already exists."); + } + }); + + } +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/FileStatusPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/FileStatusPersistenceService.java new file mode 100644 index 000000000..17675f281 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/FileStatusPersistenceService.java @@ -0,0 +1,314 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.FileAttribute; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.FileStatus; +import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.FileRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.time.OffsetDateTime; +import java.util.List; +import java.util.Set; + + +@Service +@RequiredArgsConstructor +public class FileStatusPersistenceService { + + private final FileRepository fileRepository; + private final DossierRepository dossierRepository; + + + public void createStatus(String dossierId, String fileId, String filename, String uploader) { + + File file = new File(); + file.setId(fileId); + file.setDossier(dossierRepository.getOne(dossierId)); + file.setFilename(filename); + file.setStatus(FileStatus.UNPROCESSED); + file.setNumberOfPages(0); + file.setAdded(OffsetDateTime.now()); + file.setUploader(uploader); + file.setLastUploaded(OffsetDateTime.now()); + + fileRepository.save(file); + } + + + public void updateStatusSuccessful(String fileId, int numberOfPages, FileStatus status, + boolean hasUpdates, long dictionaryVersion, long rulesVersion, + long legalBasisVersion, long duration, long dossierDictionaryVersion, + int analysisVersion) { + + fileRepository.findById(fileId).ifPresentOrElse((file) -> { + file.setNumberOfPages(numberOfPages); + file.setStatus(status); + file.setLastSuccessfulStatus(status); + file.setHasUpdates(hasUpdates); + file.setDictionaryVersion(dictionaryVersion); + file.setRulesVersion(rulesVersion); + file.setLegalBasisVersion(legalBasisVersion); + file.setAnalysisDuration(duration); + file.setDossierDictionaryVersion(dossierDictionaryVersion); + file.setAnalysisVersion(analysisVersion); + file.setLastUpdated(OffsetDateTime.now()); + }, () -> { + throw new NotFoundException("Unknown file=" + fileId); + }); + + } + + + public void updateStatusSuccessful(String fileId, FileStatus status, boolean approval) { + + fileRepository.findById(fileId).ifPresentOrElse((file) -> { + file.setStatus(status); + file.setLastSuccessfulStatus(status); + file.setLastUpdated(OffsetDateTime.now()); + file.setApprovalDate(approval ? OffsetDateTime.now() : null); + }, () -> { + throw new NotFoundException("Unknown file=" + fileId); + }); + + + } + + + public void updateStatus(String fileId, FileStatus status, String uploader) { + + if (status.equals(FileStatus.UNASSIGNED) || status.equals(FileStatus.UNPROCESSED)) { + throw new IllegalArgumentException("please use specific methods for these calls!"); + } + + fileRepository.findById(fileId).ifPresentOrElse((file) -> { + file.setStatus(status); + file.setUploader(uploader); + file.setLastUploaded(OffsetDateTime.now()); + file.setLastUpdated(OffsetDateTime.now()); + }, () -> { + throw new NotFoundException("Unknown file=" + fileId); + }); + + } + + + public void updateStatus(String fileId, FileStatus status) { + fileRepository.findById(fileId).ifPresentOrElse((file) -> { + file.setStatus(status); + file.setLastUpdated(OffsetDateTime.now()); + }, () -> { + throw new NotFoundException("Unknown file=" + fileId); + }); + } + + + public void setUpdateStatusIndexingSuccessful( String fileId, FileStatus status) { + + fileRepository.findById(fileId).ifPresentOrElse((file) -> { + file.setStatus(status); + file.setLastIndexed(OffsetDateTime.now()); + }, () -> { + throw new NotFoundException("Unknown file=" + fileId); + }); + + } + + + public void updateLastOCRTime( String fileId, OffsetDateTime time) { + + fileRepository.findById(fileId).ifPresentOrElse((file) -> { + file.setLastOCRTime(time); + }, () -> { + throw new NotFoundException("Unknown file=" + fileId); + }); + + } + + + public void updateHasComments(String fileId, boolean hasComments) { + + fileRepository.findById(fileId).ifPresentOrElse((file) -> { + file.setHasAnnotationComments(hasComments); + }, () -> { + throw new NotFoundException("Unknown file=" + fileId); + }); + } + + + public void updateLastManualRedaction(String fileId) { + + updateLastManualRedaction(fileId, OffsetDateTime.now()); + } + + + public void updateLastManualRedaction(String fileId, OffsetDateTime date) { + + fileRepository.findById(fileId).ifPresentOrElse((file) -> { + file.setLastManualRedaction(date); + }, () -> { + throw new NotFoundException("Unknown file=" + fileId); + }); + + } + + + public void setUpdateLastManualRedactionAndHasSuggestions(String fileId, OffsetDateTime date, boolean hasSuggestions) { + + fileRepository.findById(fileId).ifPresentOrElse((file) -> { + file.setLastManualRedaction(date); + file.setHasSuggestions(hasSuggestions); + }, () -> { + throw new NotFoundException("Unknown file=" + fileId); + }); + + } + + + public void setFileAttributes(String fileId, List fileAttributes) { + + fileRepository.findById(fileId).ifPresentOrElse((file) -> { + file.setLastFileAttributeChange(OffsetDateTime.now()); + file.setFileAttributes(fileAttributes); + }, () -> { + throw new NotFoundException("Unknown file=" + fileId); + }); + } + + + public void setExcludedPages(String fileId, Set excludedPages) { + + fileRepository.findById(fileId).ifPresentOrElse((file) -> { + file.setLastManualRedaction(OffsetDateTime.now()); + file.setExcludedPages(excludedPages); + }, () -> { + throw new NotFoundException("Unknown file=" + fileId); + }); + + + } + + + public File getStatus(String fileId) { + + return fileRepository.findById(fileId).orElseThrow(() -> new NotFoundException("Unknown file=" + fileId)); + + } + + + public List getStatusesForDossier(String dossierId) { + return fileRepository.findByDossierId(dossierId); + } + + public List getAllStatuses() { + return fileRepository.findAll(); + } + + + public void softDelete(String fileId, OffsetDateTime softDeletedTime) { + + fileRepository.findById(fileId).ifPresentOrElse((file) -> { + file.setStatus(FileStatus.DELETED); + file.setDeleted(softDeletedTime); + }, () -> { + throw new NotFoundException("Unknown file=" + fileId); + }); + + + } + + + public void hardDelete(String fileId) { + + fileRepository.findById(fileId).ifPresentOrElse((file) -> { + file.setStatus(FileStatus.DELETED); + file.setDeleted(file.getDeleted() == null ? OffsetDateTime.now() : file.getDeleted()); + file.setHardDeletedTime(OffsetDateTime.now()); + }, () -> { + throw new NotFoundException("Unknown file=" + fileId); + }); + + } + + + public void undelete(String fileId, FileStatus statusBefore) { + + fileRepository.findById(fileId).ifPresentOrElse((file) -> { + file.setStatus(statusBefore != null ? statusBefore : FileStatus.UNASSIGNED); + file.setDeleted(null); + }, () -> { + throw new NotFoundException("Unknown file=" + fileId); + }); + } + + + public void setCurrentReviewer(String fileId, String currentReviewer, String lastReviewer) { + + fileRepository.findById(fileId).ifPresentOrElse((file) -> { + file.setCurrentReviewer(currentReviewer); + file.setLastReviewer(lastReviewer); + }, () -> { + throw new NotFoundException("Unknown file=" + fileId); + }); + + } + + + public void toggleExclusion(String fileId, boolean excluded) { + + fileRepository.findById(fileId).ifPresentOrElse((file) -> { + file.setExcluded(excluded); + file.setLastProcessed(null); + file.setLastReviewer(null); + file.setCurrentReviewer(null); + file.setApprovalDate(null); + file.setLastManualRedaction(null); + file.setDictionaryVersion(0); + file.setDossierDictionaryVersion(0); + file.setRulesVersion(0); + file.setHasImages(false); + file.setHasHints(false); + file.setHasRedactions(false); + file.setHasSuggestions(false); + file.setHasUpdates(false); + }, () -> { + throw new NotFoundException("Unknown file=" + fileId); + }); + + } + + + public void overwriteFile(String fileId, String uploader, String filename) { + + fileRepository.findById(fileId).ifPresentOrElse((file) -> { + file.setFilename(filename); + file.setUploader(uploader); + file.setStatus(FileStatus.FULLREPROCESS); + file.setLastUploaded(OffsetDateTime.now()); + file.setLastUpdated(OffsetDateTime.now()); + file.setLastOCRTime(null); + file.setExcluded(false); + file.setLastProcessed(null); + file.setLastReviewer(null); + file.setCurrentReviewer(null); + file.setApprovalDate(null); + file.setLastManualRedaction(null); + file.setDictionaryVersion(0); + file.setDossierDictionaryVersion(0); + file.setRulesVersion(0); + file.setHasImages(false); + file.setHasHints(false); + file.setHasRedactions(false); + file.setHasSuggestions(false); + file.setHasUpdates(false); + }, () -> { + throw new NotFoundException("Unknown file=" + fileId); + }); + + + } + + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/ForceRedactionPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/ForceRedactionPersistenceService.java new file mode 100644 index 000000000..695f43193 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/ForceRedactionPersistenceService.java @@ -0,0 +1,73 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + + +import com.iqser.red.service.persistence.service.v1.api.model.ForceRedactionRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.AnnotationId; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.AnnotationStatus; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ManualForceRedaction; +import com.iqser.red.service.persistence.management.v1.processor.exception.FileNotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.ForceRedactionRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.time.OffsetDateTime; +import java.util.Set; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class ForceRedactionPersistenceService { + + + private final ForceRedactionRepository forceRedactionRepository; + + + public void insert(String fileId, ForceRedactionRequest forceRedactionRequest) { + + ManualForceRedaction manualForceRedaction = new ManualForceRedaction(); + manualForceRedaction.setId(new AnnotationId(forceRedactionRequest.getAnnotationId(), fileId)); + BeanUtils.copyProperties(forceRedactionRequest, manualForceRedaction); + manualForceRedaction.setRequestDate(OffsetDateTime.now()); + + forceRedactionRepository.save(manualForceRedaction); + } + + + public void updateStatus(String fileId, String annotationId, AnnotationStatus annotationStatus) { + forceRedactionRepository.findById(new AnnotationId(annotationId, fileId)).ifPresent(mre -> { + mre.setProcessedDate(OffsetDateTime.now()); + mre.setStatus(annotationStatus); + }); + } + + + public void hardDelete(String fileId, String annotationId) { + forceRedactionRepository.deleteById(new AnnotationId(annotationId, fileId)); + } + + public void softDelete(String fileId, String annotationId, OffsetDateTime softDeleteTime) { + forceRedactionRepository.findById(new AnnotationId(annotationId, fileId)).ifPresent(mre -> mre.setSoftDeletedTime(softDeleteTime)); + } + + public void undelete(String fileId, String annotationId) { + forceRedactionRepository.findById(new AnnotationId(annotationId, fileId)).ifPresent(mre -> mre.setSoftDeletedTime(null)); + } + + public ManualForceRedaction findForceRedaction(String fileId, String annotationId) { + + return forceRedactionRepository.findById(new AnnotationId(annotationId, fileId)) + .filter(mre -> mre.getSoftDeletedTime() == null) + .orElseThrow(() -> + new FileNotFoundException("Unknown file/annotation combination: " + fileId + "/" + annotationId)); + } + + + public Set findForceRedactions(String fileId, boolean includeDeletions) { + + return forceRedactionRepository.findByIdFileId(fileId).stream().filter(mre -> includeDeletions || mre.getSoftDeletedTime() == null).collect(Collectors.toSet()); + + } + + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/ImageRecategorizationPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/ImageRecategorizationPersistenceService.java new file mode 100644 index 000000000..e7392b89e --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/ImageRecategorizationPersistenceService.java @@ -0,0 +1,74 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + +import com.iqser.red.service.persistence.service.v1.api.model.ImageRecategorizationRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.AnnotationId; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.AnnotationStatus; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ManualImageRecategorization; +import com.iqser.red.service.persistence.management.v1.processor.exception.FileNotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.ImageRecategorizationRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.time.OffsetDateTime; +import java.util.Set; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class ImageRecategorizationPersistenceService { + + private final ImageRecategorizationRepository imageRecategorizationRepository; + + public void insert(String fileId, ImageRecategorizationRequest imageRecategorizationRequest) { + + + ManualImageRecategorization manualImageRecategorization = new ManualImageRecategorization(); + manualImageRecategorization.setId(new AnnotationId(imageRecategorizationRequest.getAnnotationId(), fileId)); + BeanUtils.copyProperties(imageRecategorizationRequest, manualImageRecategorization); + manualImageRecategorization.setRequestDate(OffsetDateTime.now()); + imageRecategorizationRepository.save(manualImageRecategorization); + + } + + + public void updateStatus(String fileId, String annotationId, AnnotationStatus annotationStatus) { + + imageRecategorizationRepository.findById(new AnnotationId(annotationId, fileId)).ifPresent(mre -> { + mre.setProcessedDate(OffsetDateTime.now()); + mre.setStatus(annotationStatus); + }); + + } + + public void hardDelete(String fileId, String annotationId) { + imageRecategorizationRepository.deleteById(new AnnotationId(annotationId, fileId)); + } + + + public void softDelete(String fileId, String annotationId, OffsetDateTime softDeleteTime) { + + imageRecategorizationRepository.findById(new AnnotationId(annotationId, fileId)).ifPresent(mre -> mre.setSoftDeletedTime(softDeleteTime)); + } + + public void undelete(String fileId, String annotationId) { + imageRecategorizationRepository.findById(new AnnotationId(annotationId, fileId)).ifPresent(mre -> mre.setSoftDeletedTime(null)); + } + + public ManualImageRecategorization findRecategorization(String fileId, String annotationId) { + + return imageRecategorizationRepository.findById(new AnnotationId(annotationId, fileId)) + .filter(mre -> mre.getSoftDeletedTime() == null) + .orElseThrow(() -> + new FileNotFoundException("Unknown file/annotation combination: " + fileId + "/" + annotationId)); + } + + + public Set findRecategorizations(String fileId, boolean includeDeletions) { + + return imageRecategorizationRepository.findByIdFileId(fileId).stream().filter(mre -> includeDeletions || mre.getSoftDeletedTime() == null).collect(Collectors.toSet()); + + } + + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/LegalBasisChangePersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/LegalBasisChangePersistenceService.java new file mode 100644 index 000000000..b928a0efe --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/LegalBasisChangePersistenceService.java @@ -0,0 +1,74 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + +import com.iqser.red.service.persistence.service.v1.api.model.LegalBasisChangeRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.AnnotationId; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.AnnotationStatus; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ManualLegalBasisChange; +import com.iqser.red.service.persistence.management.v1.processor.exception.FileNotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.LegalBasisChangeRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.time.OffsetDateTime; +import java.util.Set; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class LegalBasisChangePersistenceService { + + private final LegalBasisChangeRepository legalBasisChangeRepository; + + + public void insert(String fileId, LegalBasisChangeRequest legalBasisChangeRequest) { + + ManualLegalBasisChange manualLegalBasisChange = new ManualLegalBasisChange(); + manualLegalBasisChange.setId(new AnnotationId(legalBasisChangeRequest.getAnnotationId(), fileId)); + BeanUtils.copyProperties(legalBasisChangeRequest, manualLegalBasisChange); + manualLegalBasisChange.setRequestDate(OffsetDateTime.now()); + legalBasisChangeRepository.save(manualLegalBasisChange); + + } + + public void hardDelete(String fileId, String annotationId) { + legalBasisChangeRepository.deleteById(new AnnotationId(annotationId, fileId)); + } + + + public void softDelete(String fileId, String annotationId, OffsetDateTime softDeleteTime) { + + legalBasisChangeRepository.findById(new AnnotationId(annotationId, fileId)).ifPresent(mre -> mre.setSoftDeletedTime(softDeleteTime)); + } + + public void undelete(String fileId, String annotationId) { + legalBasisChangeRepository.findById(new AnnotationId(annotationId, fileId)).ifPresent(mre -> mre.setSoftDeletedTime(null)); + } + + + public void updateStatus(String fileId, String annotationId, AnnotationStatus annotationStatus) { + + legalBasisChangeRepository.findById(new AnnotationId(annotationId, fileId)).ifPresent(mre -> { + mre.setProcessedDate(OffsetDateTime.now()); + mre.setStatus(annotationStatus); + }); + + + } + + public ManualLegalBasisChange findLegalBasisChange(String fileId, String annotationId) { + return legalBasisChangeRepository.findById(new AnnotationId(annotationId, fileId)) + .filter(mre -> mre.getSoftDeletedTime() == null) + .orElseThrow(() -> + new FileNotFoundException("Unknown file/annotation combination: " + fileId + "/" + annotationId)); + } + + + public Set findLegalBasisChanges(String fileId, boolean includeDeletions) { + + return legalBasisChangeRepository.findByIdFileId(fileId).stream().filter(mre -> includeDeletions || mre.getSoftDeletedTime() == null).collect(Collectors.toSet()); + + } + + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/RemoveRedactionPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/RemoveRedactionPersistenceService.java new file mode 100644 index 000000000..6da455f6e --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/RemoveRedactionPersistenceService.java @@ -0,0 +1,83 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + +import com.iqser.red.service.persistence.service.v1.api.model.RemoveRedactionRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.AnnotationId; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.AnnotationStatus; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.IdRemoval; +import com.iqser.red.service.persistence.management.v1.processor.exception.FileNotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.RemoveRedactionRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.time.OffsetDateTime; +import java.util.Set; +import java.util.stream.Collectors; + + +@Service +@RequiredArgsConstructor +public class RemoveRedactionPersistenceService { + + + private final RemoveRedactionRepository removeRedactionRepository; + + public void insert(String fileId, RemoveRedactionRequest removeRedactionRequest) { + + + IdRemoval idRemoval = new IdRemoval(); + idRemoval.setId(new AnnotationId(removeRedactionRequest.getAnnotationId(), fileId)); + BeanUtils.copyProperties(removeRedactionRequest, idRemoval); + idRemoval.setRequestDate(OffsetDateTime.now()); + + removeRedactionRepository.save(idRemoval); + } + + + public IdRemoval findRemoveRedaction(String fileId, String annotationId) { + + return removeRedactionRepository.findById(new AnnotationId(annotationId, fileId)) + .filter(mre -> mre.getSoftDeletedTime() == null) + .orElseThrow(() -> + new FileNotFoundException("Unknown file/annotation combination: " + fileId + "/" + annotationId)); + } + + + public Set findRemoveRedactions(String fileId, boolean includeDeletions) { + return removeRedactionRepository.findByIdFileId(fileId).stream().filter(mre -> includeDeletions || mre.getSoftDeletedTime() == null).collect(Collectors.toSet()); + } + + public void hardDelete(String fileId, String annotationId) { + removeRedactionRepository.deleteById(new AnnotationId(annotationId, fileId)); + } + + + public void softDelete(String fileId, String annotationId, OffsetDateTime softDeleteTime) { + removeRedactionRepository.findById(new AnnotationId(annotationId, fileId)).ifPresent(mre -> mre.setSoftDeletedTime(softDeleteTime)); + } + + public void undelete(String fileId, String annotationId) { + removeRedactionRepository.findById(new AnnotationId(annotationId, fileId)).ifPresent(mre -> mre.setSoftDeletedTime(null)); + } + + public void updateStatus(String fileId, String annotationId, AnnotationStatus annotationStatus) { + + removeRedactionRepository.findById(new AnnotationId(annotationId, fileId)).ifPresent(mre -> { + mre.setProcessedDate(OffsetDateTime.now()); + mre.setStatus(annotationStatus); + }); + + } + + public void updateStatus(String fileId, String annotationId, AnnotationStatus annotationStatus, boolean isAddOrRemoveFromDictionary) { + + removeRedactionRepository.findById(new AnnotationId(annotationId, fileId)).ifPresent(mre -> { + mre.setProcessedDate(OffsetDateTime.now()); + mre.setStatus(annotationStatus); + mre.setRemoveFromDictionary(isAddOrRemoveFromDictionary); + }); + + } + + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/ReportTemplatePersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/ReportTemplatePersistenceService.java new file mode 100644 index 000000000..a6f91b3a9 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/ReportTemplatePersistenceService.java @@ -0,0 +1,53 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.ReportTemplate; +import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierTemplateRepository; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.ReportTemplateRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class ReportTemplatePersistenceService { + + private final ReportTemplateRepository reportTemplateRepository; + private final DossierTemplateRepository dossierTemplateRepository; + + + public void insert(String dossierTemplateId, String templateId, String storageId, String templateName, + boolean activeByDefault, boolean multiFileReport) { + + ReportTemplate reportTemplate = new ReportTemplate(); + reportTemplate.setTemplateId(templateId); + reportTemplate.setDossierTemplate(dossierTemplateRepository.getOne(dossierTemplateId)); + reportTemplate.setStorageId(storageId); + reportTemplate.setFileName(templateName); + reportTemplate.setMultiFileReport(multiFileReport); + reportTemplate.setActiveByDefault(activeByDefault); + + reportTemplateRepository.save(reportTemplate); + + + } + + public void delete(String templateId) { + reportTemplateRepository.deleteById(templateId); + } + + public List findByDossierTemplateId(String dossierTemplateId) { + + return reportTemplateRepository.findAllByDossierTemplateId(dossierTemplateId); + + } + + public ReportTemplate find(String templateId) { + + return reportTemplateRepository.findById(templateId).orElseThrow(() -> new NotFoundException("Report Template not found: " + templateId)); + + } + + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/RulesPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/RulesPersistenceService.java new file mode 100644 index 000000000..6d52d8fae --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/RulesPersistenceService.java @@ -0,0 +1,40 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.RuleSet; +import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.RuleSetRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +@SuppressWarnings("PMD.TooManyStaticImports") +public class RulesPersistenceService { + + private final RuleSetRepository ruleSetRepository; + + private static final String RULES_NOT_FOUND = "Could not find rules in database."; + + + public RuleSet getRules(String dossierTemplateId) { + return ruleSetRepository.findById(dossierTemplateId).orElseThrow(() -> new NotFoundException(RULES_NOT_FOUND)); + } + + public void setRules(String rules, String dossierTemplateId) { + + ruleSetRepository.findById(dossierTemplateId).ifPresentOrElse(r -> { + r.setValue(rules); + r.setVersion(r.getVersion() + 1); + }, () -> { + RuleSet ruleSet = new RuleSet(); + ruleSet.setDossierTemplateId(dossierTemplateId); + ruleSet.setValue(rules); + ruleSet.setVersion(1); + + ruleSetRepository.save(ruleSet); + }); + + } + + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/SMTPConfigurationService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/SMTPConfigurationService.java new file mode 100644 index 000000000..16ddcc5b7 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/SMTPConfigurationService.java @@ -0,0 +1,28 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.SMTPConfiguration; +import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.SMTPRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class SMTPConfigurationService { + + private final SMTPRepository smtpRepository; + + public void deleteConfiguration() { + smtpRepository.deleteById(SMTPConfiguration.ID); + } + + public SMTPConfiguration getConfiguration() { + return smtpRepository.findById(SMTPConfiguration.ID).orElseThrow(() -> new NotFoundException("SMTP Configuration not found")); + } + + public SMTPConfiguration saveConfiguration(SMTPConfiguration smtpConfiguration) { + return smtpRepository.save(smtpConfiguration); + } +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/ViewedPagesPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/ViewedPagesPersistenceService.java new file mode 100644 index 000000000..332dd8455 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/ViewedPagesPersistenceService.java @@ -0,0 +1,42 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence; + +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ViewedPage; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.ViewedPagesRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.time.OffsetDateTime; +import java.util.List; + +@Service +@RequiredArgsConstructor +public class ViewedPagesPersistenceService { + + + private final ViewedPagesRepository viewedPagesRepository; + + public void insertPage(String fileId, String userId, int page) { + + var viewedPage = new ViewedPage(); + viewedPage.setViewedTime(OffsetDateTime.now()); + viewedPage.setId(new ViewedPage.ViewedPageId(fileId, page, userId)); + viewedPagesRepository.save(viewedPage); + } + + + public void removePage(String fileId, String role, int page) { + viewedPagesRepository.deleteById(new ViewedPage.ViewedPageId(fileId, page, role)); + } + + + public List findViewedPages(String fileId, String userId) { + return viewedPagesRepository.findByFileIdAndIdUserId(fileId, userId); + } + + + public void deleteForFile(String fileId) { + viewedPagesRepository.deleteByFileId(fileId); + } + + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ColorsRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ColorsRepository.java new file mode 100644 index 000000000..f62348779 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ColorsRepository.java @@ -0,0 +1,7 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.Colors; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ColorsRepository extends JpaRepository { +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/CommentRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/CommentRepository.java new file mode 100644 index 000000000..9a5f98671 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/CommentRepository.java @@ -0,0 +1,14 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.Comment; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface CommentRepository extends JpaRepository { + List findByFileIdAndAnnotationId(String fileId, String annotationId); + + List findByFileId(String fileId); + + boolean existsByFileIdAAndSoftDeletedTimeIsNull(String fileId); +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DigitalSignatureRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DigitalSignatureRepository.java new file mode 100644 index 000000000..90491710c --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DigitalSignatureRepository.java @@ -0,0 +1,7 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.DigitalSignature; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface DigitalSignatureRepository extends JpaRepository { +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierAttributeConfigRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierAttributeConfigRepository.java new file mode 100644 index 000000000..f4e9167cf --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierAttributeConfigRepository.java @@ -0,0 +1,13 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierAttributeConfig; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface DossierAttributeConfigRepository extends JpaRepository { + + List findAllByDossierTemplateId(String dossierTemplateId); + + void deleteByDossierTemplateId(String dossierTemplateId); +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierAttributeRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierAttributeRepository.java new file mode 100644 index 000000000..2e0096ffc --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierAttributeRepository.java @@ -0,0 +1,12 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierAttribute; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface DossierAttributeRepository extends JpaRepository { + + List findByIdDossierId(String dossierId); + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierRepository.java new file mode 100644 index 000000000..76279cbfd --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierRepository.java @@ -0,0 +1,7 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.Dossier; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface DossierRepository extends JpaRepository { +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierTemplateRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierTemplateRepository.java new file mode 100644 index 000000000..e779737f5 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DossierTemplateRepository.java @@ -0,0 +1,10 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierTemplate; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface DossierTemplateRepository extends JpaRepository { + List findAllWhereDeletedIsFalse(); +} 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 new file mode 100644 index 000000000..820e342e8 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/DownloadStatusRepository.java @@ -0,0 +1,10 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.download.DownloadStatus; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface DownloadStatusRepository extends JpaRepository { + List findAllByUserId(String userId); +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntryRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntryRepository.java new file mode 100644 index 000000000..bbfc7550b --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/EntryRepository.java @@ -0,0 +1,15 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.DictionaryEntry; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface EntryRepository extends JpaRepository { + + void deleteAllByTypeIdAndVersionAndValueIn(String typeId, long version, List values); + + void updateVersionByTypeIdAndValueIn(long version, String typeId, List values); + + List findByTypeId(String typeId); +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FileAttributeConfigRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FileAttributeConfigRepository.java new file mode 100644 index 000000000..7e437f3ab --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FileAttributeConfigRepository.java @@ -0,0 +1,13 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.FileAttributeConfig; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface FileAttributeConfigRepository extends JpaRepository { + + List findByDossierTemplateId(String dossierTemplateId); + + void deleteByDossierTemplateId(String dossierTemplateId); +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FileAttributesGeneralConfigurationRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FileAttributesGeneralConfigurationRepository.java new file mode 100644 index 000000000..6d5774853 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FileAttributesGeneralConfigurationRepository.java @@ -0,0 +1,7 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.FileAttributesGeneralConfiguration; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface FileAttributesGeneralConfigurationRepository extends JpaRepository { +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FileRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FileRepository.java new file mode 100644 index 000000000..3624e27cc --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/FileRepository.java @@ -0,0 +1,10 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface FileRepository extends JpaRepository { + List findByDossierId(String dossierId); +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ForceRedactionRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ForceRedactionRepository.java new file mode 100644 index 000000000..70e9d1caa --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ForceRedactionRepository.java @@ -0,0 +1,12 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.AnnotationId; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ManualForceRedaction; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface ForceRedactionRepository extends JpaRepository { + + List findByIdFileId(String fileId); +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ImageRecategorizationRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ImageRecategorizationRepository.java new file mode 100644 index 000000000..eb27259b3 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ImageRecategorizationRepository.java @@ -0,0 +1,11 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.AnnotationId; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ManualImageRecategorization; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface ImageRecategorizationRepository extends JpaRepository { + List findByIdFileId(String fileId); +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/LegalBasisChangeRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/LegalBasisChangeRepository.java new file mode 100644 index 000000000..8279b3335 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/LegalBasisChangeRepository.java @@ -0,0 +1,12 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.AnnotationId; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ManualLegalBasisChange; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface LegalBasisChangeRepository extends JpaRepository { + + List findByIdFileId(String fileId); +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/LegalBasisMappingRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/LegalBasisMappingRepository.java new file mode 100644 index 000000000..9d21949a5 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/LegalBasisMappingRepository.java @@ -0,0 +1,11 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.LegalBasisMapping; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface LegalBasisMappingRepository extends JpaRepository { + + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ManualRedactionRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ManualRedactionRepository.java new file mode 100644 index 000000000..c72979694 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ManualRedactionRepository.java @@ -0,0 +1,12 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.AnnotationId; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ManualRedactionEntry; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface ManualRedactionRepository extends JpaRepository { + + List findByIdFileId(String fileId); +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/RemoveRedactionRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/RemoveRedactionRepository.java new file mode 100644 index 000000000..c67c7d6bd --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/RemoveRedactionRepository.java @@ -0,0 +1,12 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.AnnotationId; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.IdRemoval; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface RemoveRedactionRepository extends JpaRepository { + + List findByIdFileId(String fileId); +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ReportTemplateRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ReportTemplateRepository.java new file mode 100644 index 000000000..3d58d7d88 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ReportTemplateRepository.java @@ -0,0 +1,10 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.ReportTemplate; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface ReportTemplateRepository extends JpaRepository { + List findAllByDossierTemplateId(String dossierTemplateId); +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/RuleSetRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/RuleSetRepository.java new file mode 100644 index 000000000..b335cc427 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/RuleSetRepository.java @@ -0,0 +1,8 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.RuleSet; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface RuleSetRepository extends JpaRepository { + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/SMTPRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/SMTPRepository.java new file mode 100644 index 000000000..494f0d287 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/SMTPRepository.java @@ -0,0 +1,7 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.SMTPConfiguration; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface SMTPRepository extends JpaRepository { +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/TypeRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/TypeRepository.java new file mode 100644 index 000000000..e3372358c --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/TypeRepository.java @@ -0,0 +1,22 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.Type; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.Dossier; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierTemplate; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; +import java.util.Optional; + +public interface TypeRepository extends JpaRepository { + + Optional findOneByDossierTemplateAndDossierAndRank(DossierTemplate dossierTemplate, Dossier dossier, int rank); + + List findByDossierTemplateId(String dossierTemplateId); + + List findByDossierId(String dossierId); + + @Query("update Type t set t.version = t.version +1 where t.id = :typeId") + void updateByIdSetIncrementVersionByOne(String typeId); +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ViewedPagesRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ViewedPagesRepository.java new file mode 100644 index 000000000..633ed60aa --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ViewedPagesRepository.java @@ -0,0 +1,14 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ViewedPage; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface ViewedPagesRepository extends JpaRepository { + + void deleteByFileId(String fileId); + + List findByFileIdAndIdUserId(String fileId, String userId); + +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/WatermarkRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/WatermarkRepository.java new file mode 100644 index 000000000..1b6453e14 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/WatermarkRepository.java @@ -0,0 +1,7 @@ +package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.Watermark; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface WatermarkRepository extends JpaRepository { +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/settings/FileUploadSettings.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/settings/FileUploadSettings.java new file mode 100644 index 000000000..94791ac4c --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/settings/FileUploadSettings.java @@ -0,0 +1,16 @@ +package com.iqser.red.service.persistence.management.v1.processor.settings; + +import lombok.Data; + +@Data +public class FileUploadSettings { + + private static final int MEGABYTE = 1024 * 1024; + + private int chunkSizeInByte = MEGABYTE; + + /** + * The maximum size of chunks to store in a single batch statement. + */ + private int maxBatchSize = 8 * MEGABYTE; +} diff --git a/persistence-service-v1/persistence-service-processor-v1/src/test/resources/application.yml b/persistence-service-v1/persistence-service-processor-v1/src/test/resources/application.yml new file mode 100644 index 000000000..be5849a82 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/test/resources/application.yml @@ -0,0 +1,10 @@ +cassandra: + keyspace-name: file_management_service + migrations-location: 'classpath:cassandra/migrations/*.cql' + + +spring: + test: + context: + cache: + maxSize: 60 \ No newline at end of file diff --git a/persistence-service-v1/persistence-service-processor-v1/src/test/resources/log4j2-test.xml b/persistence-service-v1/persistence-service-processor-v1/src/test/resources/log4j2-test.xml new file mode 100644 index 000000000..850803d26 --- /dev/null +++ b/persistence-service-v1/persistence-service-processor-v1/src/test/resources/log4j2-test.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/persistence-service-v1/persistence-service-server-v1/pom.xml b/persistence-service-v1/persistence-service-server-v1/pom.xml new file mode 100644 index 000000000..2dad0c4b8 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/pom.xml @@ -0,0 +1,215 @@ + + + + + persistence-service-v1 + com.iqser.red.service + 1.0-SNAPSHOT + + + 4.0.0 + + persistence-service-server-v1 + + 1.7.30 + UTF-8 + + + + + com.iqser.red.service + search-service-api-v1 + 1.2.0 + + + com.iqser.red.service + redaction-report-service-api-v1 + 2.17.0 + + + com.iqser.red.service + redaction-service-api-v1 + + + com.iqser.red.service + persistence-service-api-v1 + + + com.iqser.red.service + file-management-service-api-v1 + + + com.iqser.red.service + pdftron-redaction-service-api-v1 + + + com.iqser.red.service + configuration-service-api-v1 + + + + + com.iqser.red.service + persistence-service-processor-v1 + ${project.version} + + + com.iqser.red.service + redaction-service-api-v1 + + + + + + com.iqser.red.commons + storage-commons + + + com.iqser.red.service + pdftron-redaction-service-api-v1 + 2.12.0 + + + com.iqser.red.service + redaction-service-api-v1 + + + com.iqser.red.service + configuration-service-api-v1 + + + + + + + com.iqser.red.commons + spring-commons + + + org.apache.commons + commons-lang3 + + + com.iqser.red.commons + logging-commons + + + org.slf4j + slf4j-simple + ${slf4j.version} + + + com.iqser.red.commons + spring-boot-starter-web-custom-commons + + + com.iqser.red.commons + metric-commons + + + com.google.guava + guava + 29.0-jre + + + com.opencsv + opencsv + 5.4 + + + + com.github.ben-manes.caffeine + caffeine + 2.8.5 + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + org.springframework.boot + spring-boot-starter-amqp + 2.3.1.RELEASE + + + + + org.springframework.amqp + spring-rabbit-test + 2.3.1 + test + + + + com.iqser.red.commons + cassandra-commons + + + gremlin-driver + org.apache.tinkerpop + + + test + test-jar + + + org.testcontainers + cassandra + 1.15.0 + test + + + org.springframework.boot + spring-boot-starter-test + test + + + org.apache.logging.log4j + log4j-slf4j-impl + test + + + + + + + pl.project13.maven + git-commit-id-plugin + + + + revision + + + true + + true + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + true + + + + + + + diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/Application.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/Application.java new file mode 100644 index 000000000..5d24ee57a --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/Application.java @@ -0,0 +1,59 @@ +package com.iqser.red.service.file.management.v1.server; + +import com.iqser.red.commons.spring.DefaultWebMvcConfiguration; +import com.iqser.red.service.file.management.v1.server.client.RedactionClient; +import com.iqser.red.service.file.management.v1.server.configuration.CleanupDownloadSchedulerConfiguration; +import com.iqser.red.service.file.management.v1.server.configuration.MessagingConfiguration; +import com.iqser.red.service.file.management.v1.server.settings.FileManagementServiceSettings; +import com.iqser.red.service.persistence.management.v1.processor.PersistenceServiceProcessorConfiguration; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.retry.annotation.EnableRetry; +import org.springframework.retry.backoff.ExponentialBackOffPolicy; +import org.springframework.retry.policy.SimpleRetryPolicy; +import org.springframework.retry.support.RetryTemplate; +import org.springframework.scheduling.annotation.EnableAsync; + +@EnableAsync +@EnableRetry +@EnableConfigurationProperties(FileManagementServiceSettings.class) +@SpringBootApplication(exclude = {SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class, CassandraAutoConfiguration.class}) +@Import({DefaultWebMvcConfiguration.class, PersistenceServiceProcessorConfiguration.class, MessagingConfiguration.class, CleanupDownloadSchedulerConfiguration.class}) +@EnableFeignClients(basePackageClasses = {RedactionClient.class}) +public class Application { + + + @Bean + public RetryTemplate retryTemplate(FileManagementServiceSettings settings) { + RetryTemplate retryTemplate = new RetryTemplate(); + + ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy(); + backOffPolicy.setMaxInterval(settings.getMaxRetryInterval()); + retryTemplate.setBackOffPolicy(backOffPolicy); + + SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(); + retryPolicy.setMaxAttempts(settings.getMaxRetryAttempts()); + retryTemplate.setRetryPolicy(retryPolicy); + + return retryTemplate; + } + + /** + * Entry point to the service application. + * + * @param args Any command line parameter given upon startup. + */ + public static void main(String[] args) { + + SpringApplication.run(Application.class, args); + } + + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/ResourceLoader.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/ResourceLoader.java new file mode 100644 index 000000000..982ac6f09 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/ResourceLoader.java @@ -0,0 +1,45 @@ +package com.iqser.red.service.file.management.v1.server; + +import lombok.experimental.UtilityClass; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.Set; +import java.util.stream.Collectors; + +@UtilityClass +public class ResourceLoader { + + + public Set load(String classpathPath) { + + URL resource = ResourceLoader.class.getClassLoader().getResource(classpathPath); + if (resource == null) { + throw new IllegalArgumentException("could not load classpath resource: " + classpathPath); + } + try (BufferedReader br = new BufferedReader(new InputStreamReader(resource.openStream(), StandardCharsets.UTF_8))) { + return br.lines().collect(Collectors.toSet()); + } catch (IOException e) { + throw new IllegalArgumentException("could not load classpath resource: " + classpathPath, e); + } + } + + + public String loadToString(String classpathPath) { + + URL resource = ResourceLoader.class.getClassLoader().getResource(classpathPath); + if (resource == null) { + throw new IllegalArgumentException("could not load classpath resource: " + classpathPath); + } + try (BufferedReader br = new BufferedReader(new InputStreamReader(resource.openStream(), StandardCharsets.UTF_8))) { + return br.lines().collect(Collectors.joining("\n")); + } catch (IOException e) { + throw new IllegalArgumentException("could not load classpath resource: " + classpathPath, e); + } + + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/TextNormalizationUtilities.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/TextNormalizationUtilities.java new file mode 100644 index 000000000..0e75ea118 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/TextNormalizationUtilities.java @@ -0,0 +1,17 @@ +package com.iqser.red.service.file.management.v1.server; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public class TextNormalizationUtilities { + + /** + * Revert hyphenation due to line breaks. + * @param text Text to be processed. + * @return Text without line-break hyphenation. + */ + public static String removeHyphenLineBreaks(String text) { + return text.replaceAll("\\s(\\S+)[\\-\\u00AD]\\R|\n\r(.+ )", "\n$1$2"); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/client/PDFTronRedactionClient.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/client/PDFTronRedactionClient.java new file mode 100644 index 000000000..21f3a2f01 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/client/PDFTronRedactionClient.java @@ -0,0 +1,10 @@ +package com.iqser.red.service.file.management.v1.server.client; + +import org.springframework.cloud.openfeign.FeignClient; + +import com.iqser.red.service.pdftron.redaction.v1.api.resources.PDFTronRedactionResource; + +@FeignClient(name = "PDFTronRedactionResource", url = "${pdftron-redaction-service.url}") +public interface PDFTronRedactionClient extends PDFTronRedactionResource { + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/client/RedactionClient.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/client/RedactionClient.java new file mode 100644 index 000000000..c92713f20 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/client/RedactionClient.java @@ -0,0 +1,9 @@ +package com.iqser.red.service.file.management.v1.server.client; + +import com.iqser.red.service.redaction.v1.resources.RedactionResource; +import org.springframework.cloud.openfeign.FeignClient; + +@FeignClient(name = "RedactionResource", url = "${redaction-service.url}") +public interface RedactionClient extends RedactionResource { + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/client/RedactionServiceClient.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/client/RedactionServiceClient.java new file mode 100644 index 000000000..64344481a --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/client/RedactionServiceClient.java @@ -0,0 +1,8 @@ +package com.iqser.red.service.file.management.v1.server.client; + +import com.iqser.red.service.redaction.v1.resources.RedactionResource; +import org.springframework.cloud.openfeign.FeignClient; + +@FeignClient(name = "RedactionResource", url = "${redaction-service.url}") +public interface RedactionServiceClient extends RedactionResource { +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/client/SearchClient.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/client/SearchClient.java new file mode 100644 index 000000000..e4d22914c --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/client/SearchClient.java @@ -0,0 +1,10 @@ +package com.iqser.red.service.file.management.v1.server.client; + +import com.iqser.red.service.search.v1.resources.SearchResource; +import org.springframework.cloud.openfeign.FeignClient; + + +@FeignClient(name = "SearchResource", url = "${search-service-service.url}") +public interface SearchClient extends SearchResource { + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/configuration/CleanupDownloadSchedulerConfiguration.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/configuration/CleanupDownloadSchedulerConfiguration.java new file mode 100644 index 000000000..3e491bf79 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/configuration/CleanupDownloadSchedulerConfiguration.java @@ -0,0 +1,31 @@ +package com.iqser.red.service.file.management.v1.server.configuration; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; + +@Slf4j +@Configuration +@EnableScheduling +@RequiredArgsConstructor +public class CleanupDownloadSchedulerConfiguration { + + + @Bean + public Executor taskExecutor() { + + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(1); + executor.setMaxPoolSize(1); + executor.setThreadNamePrefix("CleanupDownloadScheduler-"); + executor.initialize(); + return executor; + } + + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/configuration/MessagingConfiguration.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/configuration/MessagingConfiguration.java new file mode 100644 index 000000000..920c2fb05 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/configuration/MessagingConfiguration.java @@ -0,0 +1,147 @@ +package com.iqser.red.service.file.management.v1.server.configuration; + +import org.springframework.amqp.core.Queue; +import org.springframework.amqp.core.QueueBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import lombok.RequiredArgsConstructor; + +@Configuration +@RequiredArgsConstructor +public class MessagingConfiguration { + + public static final String REDACTION_QUEUE = "redactionQueue"; + public static final String REDACTION_DQL = "redactionDQL"; + + public static final String DOWNLOAD_QUEUE = "downloadQueue"; + public static final String DOWNLOAD_DLQ = "downloadDLQ"; + + public static final String REPORT_QUEUE = "reportQueue"; + public static final String REPORT_DLQ = "reportDLQ"; + + public static final String REPORT_RESULT_QUEUE = "reportResultQueue"; + public static final String REPORT_RESULT_DLQ = "reportResultDLQ"; + + public static final String OCR_QUEUE = "ocrQueue"; + public static final String OCR_DLQ = "ocrDLQ"; + + public static final String INDEXING_QUEUE = "indexingQueue"; + public static final String INDEXING_DQL = "indexingDQL"; + + public static final String DELETE_FROM_INDEX_QUEUE = "deleteFromIndexQueue"; + public static final String DELETE_FROM_INDEX_DLQ = "deleteFromIndexDLQ"; + + + @Bean + public Queue redactionQueue() { + + return QueueBuilder.durable(REDACTION_QUEUE) + .withArgument("x-dead-letter-exchange", "") + .withArgument("x-dead-letter-routing-key", REDACTION_DQL) + .maxPriority(2) + .build(); + } + + + @Bean + public Queue ocrQueue() { + + return QueueBuilder.durable(OCR_QUEUE) + .withArgument("x-dead-letter-exchange", "") + .withArgument("x-dead-letter-routing-key", OCR_DLQ) + .withArgument("x-max-priority", 2) + .maxPriority(2) + .build(); + } + + + @Bean + public Queue downloadQueue() { + + return QueueBuilder.durable(DOWNLOAD_QUEUE) + .withArgument("x-dead-letter-exchange", "") + .withArgument("x-dead-letter-routing-key", DOWNLOAD_DLQ) + .build(); + } + + + @Bean + public Queue downloadDeadLetterQueue() { + + return QueueBuilder.durable(DOWNLOAD_DLQ).build(); + } + + + @Bean + public Queue reportQueue() { + + return QueueBuilder.durable(REPORT_QUEUE) + .withArgument("x-dead-letter-exchange", "") + .withArgument("x-dead-letter-routing-key", REPORT_DLQ) + .withArgument("x-max-priority", 2) + .maxPriority(2) + .build(); + } + + + @Bean + public Queue reportDeadLetterQueue() { + + return QueueBuilder.durable(REPORT_DLQ).build(); + } + + + @Bean + public Queue reportResultQueue() { + + return QueueBuilder.durable(REPORT_RESULT_QUEUE) + .withArgument("x-dead-letter-exchange", "") + .withArgument("x-dead-letter-routing-key", REPORT_RESULT_DLQ) + .build(); + } + + + @Bean + public Queue reportResultDeadLetterQueue() { + + return QueueBuilder.durable(REPORT_RESULT_DLQ).build(); + } + + + @Bean + public Queue indexingQueue() { + + return QueueBuilder.durable(INDEXING_QUEUE) + .withArgument("x-dead-letter-exchange", "") + .withArgument("x-dead-letter-routing-key", INDEXING_DQL) + .maxPriority(2) + .build(); + } + + + @Bean + public Queue indexingDeadLetterQueue() { + + return QueueBuilder.durable(INDEXING_DQL).build(); + } + + + @Bean + public Queue deleteFromIndexQueue() { + + return QueueBuilder.durable(DELETE_FROM_INDEX_QUEUE) + .withArgument("x-dead-letter-exchange", "") + .withArgument("x-dead-letter-routing-key", DELETE_FROM_INDEX_DLQ) + .maxPriority(2) + .build(); + } + + + @Bean + public Queue deleteFromIndexDLQ() { + + return QueueBuilder.durable(DELETE_FROM_INDEX_DLQ).build(); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/ControllerAdvice.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/ControllerAdvice.java new file mode 100644 index 000000000..f522abb9b --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/ControllerAdvice.java @@ -0,0 +1,62 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import com.iqser.red.commons.spring.ErrorMessage; +import com.iqser.red.service.file.management.v1.server.exception.InvalidRulesException; +import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException; +import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException; +import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.time.OffsetDateTime; + +@Slf4j +@RestControllerAdvice +public class ControllerAdvice { + + /* error handling */ + + @ResponseBody + @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) + @ExceptionHandler(value = NullPointerException.class) + public ErrorMessage handleContentNotFoundException(NullPointerException e) { + if (e != null) { + log.error(e.getMessage(), e); + return new ErrorMessage(OffsetDateTime.now(), e.getMessage()); + } + log.error("Nullpointer exception at ", e); + return new ErrorMessage(OffsetDateTime.now(), "Nullpointer exception"); + } + + @ResponseBody + @ResponseStatus(value = HttpStatus.NOT_FOUND) + @ExceptionHandler(value = NotFoundException.class) + public ErrorMessage handleFileNotFoundException(NotFoundException e) { + return new ErrorMessage(OffsetDateTime.now(), e.getMessage()); + } + + @ResponseBody + @ResponseStatus(value = HttpStatus.BAD_REQUEST) + @ExceptionHandler(value = InvalidRulesException.class) + public ErrorMessage handleInvalidRulesException(InvalidRulesException e) { + return new ErrorMessage(OffsetDateTime.now(), e.getMessage()); + } + + @ResponseBody + @ResponseStatus(value = HttpStatus.CONFLICT) + @ExceptionHandler(value = ConflictException.class) + public ErrorMessage handleIConflictException(ConflictException e) { + return new ErrorMessage(OffsetDateTime.now(), e.getMessage()); + } + + @ResponseBody + @ResponseStatus(value = HttpStatus.BAD_REQUEST) + @ExceptionHandler(value = BadRequestException.class) + public ErrorMessage handleIBadRequestException(BadRequestException e) { + return new ErrorMessage(OffsetDateTime.now(), e.getMessage()); + } +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DictionaryController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DictionaryController.java new file mode 100644 index 000000000..4f037763b --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DictionaryController.java @@ -0,0 +1,299 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import com.iqser.red.service.file.management.v1.server.TextNormalizationUtilities; +import com.iqser.red.service.file.management.v1.server.validation.DictionaryValidator; +import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException; +import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException; +import com.iqser.red.service.persistence.management.v1.processor.service.ColorsService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DictionaryPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.EntryPersistenceService; +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.Colors; +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.DictionaryEntry; +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.Type; +import com.iqser.red.service.persistence.service.v1.api.resources.DictionaryResource; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static java.util.stream.Collectors.toList; + +@RestController +@RequiredArgsConstructor +@Slf4j +public class DictionaryController implements DictionaryResource { + + + private final EntryPersistenceService entryPersistenceService; + private final DictionaryPersistenceService dictionaryPersistenceService; + private final ColorsService colorsService; + + + @Override + public void addEntries(@PathVariable(TYPE_PARAMETER_NAME) String typeId, + @RequestBody List entries, + @RequestParam(value = "removeCurrent", required = false, defaultValue = "false") boolean removeCurrent) { + + + List cleanEntries = entries.stream().map(this::cleanDictionaryEntry).collect(toList()); + + validateEntries(cleanEntries); + + // To check whether the type exists, type should not be added into database implicitly by addEntry. + Type typeResult = dictionaryPersistenceService.getType(typeId); + + List entriesToSearch = new ArrayList<>(); + + long currentVersion = typeResult.getVersion(); + if (removeCurrent) { + List existing = entryPersistenceService.getEntries(typeId) + .stream() + .filter(e -> !e.isDeleted()) + .map(DictionaryEntry::getValue) + .collect(toList()); + + List removed = new ArrayList<>(existing); + removed.removeAll(cleanEntries); + + List added = new ArrayList<>(cleanEntries); + added.removeAll(existing); + + entryPersistenceService.deleteEntries(typeId, removed, currentVersion + 1); + entryPersistenceService.addEntry(typeId, added, currentVersion + 1); + + entriesToSearch.addAll(added); + entriesToSearch.addAll(removed); + } else { + entryPersistenceService.addEntry(typeId, cleanEntries, currentVersion + 1); + entriesToSearch.addAll(cleanEntries); + } + + dictionaryPersistenceService.incrementVersion(typeId); + } + + + @Override + public void deleteEntries(@PathVariable(TYPE_PARAMETER_NAME) String typeId, + @RequestBody List entries) { + + validateEntries(entries); + // To check whether the type exists + Type typeResult = dictionaryPersistenceService.getType(typeId); + long currentVersion = typeResult.getVersion(); + + if (typeResult.isCaseInsensitive()) { + List existing = entryPersistenceService.getEntries(typeId) + .stream() + .map(DictionaryEntry::getValue) + .collect(toList()); + entryPersistenceService.deleteEntries(typeId, existing.stream() + .filter(e -> entries.stream().anyMatch(e::equalsIgnoreCase)) + .collect(toList()), currentVersion + 1); + } else { + entryPersistenceService.deleteEntries(typeId, entries, currentVersion + 1); + } + + dictionaryPersistenceService.incrementVersion(typeId); + } + + + @Override + public void updateTypeValue(@PathVariable(TYPE_PARAMETER_NAME) String typeId, + @RequestBody Type typeValueRequest) { + + validateColor(typeValueRequest.getHexColor()); + validateBoolean(typeValueRequest.isHint(), "isHint"); + validateBoolean(typeValueRequest.isCaseInsensitive(), "isCaseInsensitive"); + // To check whether the type exists + Type typeResult = dictionaryPersistenceService.getType(typeId); + + + if (typeValueRequest.getLabel() != null) { + checkForDuplicateLabels(typeResult.getDossierTemplateId(), typeResult.getDossierId(), typeId, typeValueRequest.getLabel()); + } + + + if (typeValueRequest.getLabel() == null) { + typeValueRequest.setLabel(typeResult.getLabel()); + } + dictionaryPersistenceService.updateType(typeId, typeValueRequest); + + if (typeResult.isHint() != typeValueRequest.isHint() || typeResult.isCaseInsensitive() != typeValueRequest.isCaseInsensitive() || typeResult + .getRank() != typeValueRequest.getRank()) { + long currentVersion = typeResult.getVersion(); + List entries = entryPersistenceService.getEntries(typeId); + entryPersistenceService.setVersion(typeId, entries.stream() + .filter(entry -> !entry.isDeleted()) + .map(DictionaryEntry::getValue) + .collect(toList()), currentVersion + 1); + } + + dictionaryPersistenceService.incrementVersion(typeId); + } + + + @Override + public void addType(@RequestBody Type typeRequest) { + + if (typeRequest.getDossierTemplateId() == null) { + throw new BadRequestException("Dossier template id does not exist."); + } + + if (typeRequest.getLabel() == null || typeRequest.getLabel().isEmpty()) { + String label = humanizedDictionaryType(typeRequest.getType()); + typeRequest.setLabel(label); + } + + checkForDuplicateLabels(typeRequest.getDossierTemplateId(), typeRequest.getDossierId(), typeRequest.getId(), typeRequest.getLabel()); + + if (dictionaryPersistenceService.getCumulatedTypes(typeRequest.getDossierTemplateId(), typeRequest.getDossierId()) + .stream() + .anyMatch(typeResult -> typeResult.getType().equals(typeRequest.getType()))) { + throw new ConflictException("The type already exists, could not be added again."); + } + String color = typeRequest.getHexColor(); + validateColor(color); + var type = dictionaryPersistenceService.addType(typeRequest.getType(), typeRequest.getDossierTemplateId(), color, typeRequest + .getRank(), typeRequest.isHint(), typeRequest.isCaseInsensitive(), typeRequest.isRecommendation(), typeRequest + .getDescription(), typeRequest.isAddToDictionaryAction(), typeRequest.getLabel(), typeRequest.getDossierId()); + dictionaryPersistenceService.incrementVersion(type.getId()); + } + + + @Override + public void deleteType(@PathVariable(TYPE_PARAMETER_NAME) String typeId) { + + // NotFoundException would be thrown if the type not found in database. + Type typeResult = dictionaryPersistenceService.getType(typeId); + long currentVersion = typeResult.getVersion(); + + dictionaryPersistenceService.deleteType(typeId); + List existing = entryPersistenceService.getEntries(typeId) + .stream() + .map(DictionaryEntry::getValue) + .collect(toList()); + + entryPersistenceService.deleteEntries(typeId, existing, currentVersion + 1); + dictionaryPersistenceService.incrementVersion(typeId); + } + + + @Override + public List getAllTypesForDossierTemplate(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId) { + + return dictionaryPersistenceService.getAllTypesForDossierTemplate(dossierTemplateId); + } + + @Override + public List getAllTypesForDossier(@PathVariable(DOSSIER_ID_PARAMETER_NAME) String dossierId) { + + return dictionaryPersistenceService.getAllTypesForDossier(dossierId); + } + + @Override + public Type getDictionaryForType(String typeId) { + return dictionaryPersistenceService.getType(typeId); + } + + + private void validateEntries(List entries) { + + if (CollectionUtils.isEmpty(entries)) { + throw new BadRequestException("Entry list is empty."); + } + List errorMessages = entries.stream() + .filter(entry -> DictionaryValidator.validateDictionaryEntry(entry).isPresent()) + .collect(toList()); + if (CollectionUtils.isNotEmpty(errorMessages)) { + throw new BadRequestException("Error(s) validating dictionary entries:\n" + String.join("\n", errorMessages)); + } + + } + + + private void validateBoolean(Boolean bool, String name) { + + Optional errorMessage = DictionaryValidator.validateBoolean(bool, name); + if (errorMessage.isPresent()) { + throw new BadRequestException(errorMessage.get()); + } + } + + + private void validateColor(String hexColor) { + + Optional errorMessage = DictionaryValidator.validateColor(hexColor); + if (errorMessage.isPresent()) { + throw new BadRequestException(errorMessage.get()); + } + + } + + + @Override + public long getVersion(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId) { + return getAllTypesForDossierTemplate(dossierTemplateId).stream().map(Type::getVersion).reduce(0L, Long::sum); + } + + @Override + public long getVersionForDossier(@PathVariable(DOSSIER_ID_PARAMETER_NAME) String dossierId) { + return getAllTypesForDossier(dossierId).stream().map(Type::getVersion).reduce(0L, Long::sum); + } + + + @Override + public void setColors(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, + @RequestBody Colors colors) { + colorsService.saveColors(colors); + } + + + @Override + public Colors getColors(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId) { + return colorsService.getColors(dossierTemplateId); + } + + + private String cleanDictionaryEntry(String entry) { + + return TextNormalizationUtilities.removeHyphenLineBreaks(entry).replaceAll("\\n", " "); + } + + + private void checkForDuplicateLabels(String dossierTemplateId, String dossierId, String typeId, String labelToCheck) { + + List typeResponse = dictionaryPersistenceService.getCumulatedTypes(dossierTemplateId, dossierId); + for (Type res : typeResponse) { + if (typeId != res.getId() && labelToCheck.equals(res.getLabel())) { + throw new ConflictException("Label must be unique."); + } + } + } + + + private String humanizedDictionaryType(String label) { + + String str = label; + str = str.replaceAll("-+?", " "); + str = str.replaceAll("_+?", " "); + str = str.replaceAll(" +", " "); + + StringBuffer strbf = new StringBuffer(); + Matcher match = Pattern.compile("([a-z])([a-z]*)", Pattern.CASE_INSENSITIVE).matcher(str); + while (match.find()) { + match.appendReplacement(strbf, match.group(1).toUpperCase() + match.group(2)); + } + return match.appendTail(strbf).toString(); + + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DigitalSignatureController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DigitalSignatureController.java new file mode 100644 index 000000000..86da41c38 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DigitalSignatureController.java @@ -0,0 +1,38 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import com.iqser.red.service.persistence.service.v1.api.model.DigitalSignatureUpdateModel; +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.DigitalSignature; +import com.iqser.red.service.persistence.service.v1.api.resources.DigitalSignatureResource; +import com.iqser.red.service.persistence.management.v1.processor.service.DigitalSignatureService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +public class DigitalSignatureController implements DigitalSignatureResource { + + private final DigitalSignatureService digitalSignatureService; + + @Override + public DigitalSignature saveDigitalSignature(@RequestBody DigitalSignature digitalSignatureModel) { + return digitalSignatureService.saveDigitalSignature(digitalSignatureModel); + } + + + @Override + public void updateDigitalSignature(@RequestBody DigitalSignature digitalSignatureUpdateModel) { + digitalSignatureService.updateDigitalSignature(digitalSignatureUpdateModel); + } + + @Override + public DigitalSignature getDigitalSignature() { + return digitalSignatureService.getDigitalSignature(); + } + + + @Override + public void deleteDigitalSignature() { + digitalSignatureService.deleteDigitalSignature(); + } +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DossierAttributesController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DossierAttributesController.java new file mode 100644 index 000000000..79e631548 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DossierAttributesController.java @@ -0,0 +1,48 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierAttributeConfigPersistenceService; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierAttributeConfig; +import com.iqser.red.service.persistence.service.v1.api.resources.DossierAttributesResource; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@Slf4j +@RestController +@RequiredArgsConstructor +public class DossierAttributesController implements DossierAttributesResource { + + + private final DossierAttributeConfigPersistenceService dossierAttributeConfigPersistenceService; + + @Override + public DossierAttributeConfig addOrUpdateDossierAttribute(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId, + @RequestBody DossierAttributeConfig dossierAttributeConfig) { + return dossierAttributeConfigPersistenceService.addOrUpdateDossierAttribute(dossierTemplateId, dossierAttributeConfig); + } + + @Override + public List setDossierAttributesConfig(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId, + @RequestBody List dossierAttributesConfig) { + return dossierAttributeConfigPersistenceService.setDossierAttributesConfig(dossierTemplateId, dossierAttributesConfig); + } + + @Override + public void deleteDossierAttribute(@PathVariable(DOSSIER_ATTRIBUTE_ID) String dossierAttributeId) { + dossierAttributeConfigPersistenceService.deleteDossierAttribute(dossierAttributeId); + } + + @Override + public void deleteDossierAttributes(@RequestBody List dossierAttributeIds) { + dossierAttributeConfigPersistenceService.deleteDossierAttributes(dossierAttributeIds); + } + + @Override + public List getDossierAttributes(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId) { + return dossierAttributeConfigPersistenceService.getDossierAttributes(dossierTemplateId); + } +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DossierController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DossierController.java new file mode 100644 index 000000000..1c3a474b0 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DossierController.java @@ -0,0 +1,135 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import com.iqser.red.service.file.management.v1.server.service.DossierService; +import com.iqser.red.service.file.management.v1.server.service.FileService; +import com.iqser.red.service.file.management.v1.server.service.FileStatusService; +import com.iqser.red.service.persistence.management.v1.processor.exception.DossierNotFoundException; +import com.iqser.red.service.persistence.service.v1.api.model.CreateOrUpdateDossierRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.Dossier; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierStatus; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import com.iqser.red.service.persistence.service.v1.api.resources.DossierResource; +import feign.Param; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.time.OffsetDateTime; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import static com.iqser.red.service.persistence.management.v1.processor.exception.DossierNotFoundException.DOSSIER_NOT_FOUND_MESSAGE; + +@RestController +@RequiredArgsConstructor +public class DossierController implements DossierResource { + + private final DossierService dossierService; + private final FileStatusService fileStatusService; + private final FileService fileService; + + + @Override + public Dossier addDossier(@RequestBody CreateOrUpdateDossierRequest dossierRequest) { + + return dossierService.addDossier(dossierRequest); + } + + + @Override + public Dossier updateDossier(@RequestBody CreateOrUpdateDossierRequest dossierRequest, + @PathVariable(DOSSIER_ID_PARAM) String dossierId) { + + return dossierService.updateDossier(dossierRequest, dossierId); + } + + + @Override + public void delete(@Param(DOSSIER_ID_PARAM) @PathVariable(DOSSIER_ID_PARAM) String dossierId) { + + OffsetDateTime now = OffsetDateTime.now(); + + Dossier dossier = dossierService.getDossierById(dossierId); + if (dossier.getStatus().equals(DossierStatus.DELETED)) { + throw new DossierNotFoundException(String.format(DOSSIER_NOT_FOUND_MESSAGE, dossierId)); + } + + List fileStatuses = fileStatusService.getDossierStatus(dossierId); + fileStatuses.stream().filter(fileStatus -> fileStatus.getDeleted() == null).forEach(fileStatus -> { + fileService.softDeleteFile(dossierId, fileStatus.getId(), now); + fileStatusService.setFileStatusDeleted( fileStatus.getId(), now); + }); + + dossierService.softDeleteDossier(dossierId, now); + } + + + @Override + public List getAllDossiers() { + + return dossierService.getAllDossiers() + .stream() + .filter(p -> p.getStatus().equals(DossierStatus.ACTIVE)) + .collect(Collectors.toList()); + } + + + @Override + public Dossier getDossierById(@Param(DOSSIER_ID_PARAM) @PathVariable(DOSSIER_ID_PARAM) String dossierId) { + + Dossier dossier = dossierService.getDossierById(dossierId); + if (dossier.getStatus().equals(DossierStatus.DELETED)) { + throw new DossierNotFoundException(String.format(DOSSIER_NOT_FOUND_MESSAGE, dossierId)); + } + return dossier; + } + + + @Override + public List getSoftDeletedDossiers() { + + return dossierService.getAllDossiers() + .stream() + .filter(p -> p.getStatus().equals(DossierStatus.DELETED) && p.getHardDeletedTime() == null) + .collect(Collectors.toList()); + } + + + @Override + public void hardDeleteDossiers(@RequestBody Set dossierIds) { + + for (String dossierId : dossierIds) { + Dossier dossier = dossierService.getDossierById(dossierId); + dossierService.hardDeleteDossier(dossier.getId()); + List fileStatuses = fileStatusService.getDossierStatus(dossierId); + fileStatuses.forEach(fileStatus -> { + fileService.hardDeleteFile(dossierId, fileStatus.getId()); + fileStatusService.setFileStatusHardDeleted(fileStatus.getId()); + }); + } + + } + + + @Override + public void undeleteDossiers(@RequestBody Set dossierIds) { + + for (String dossierId : dossierIds) { + var dossier = dossierService.getDossierById(dossierId); + List fileStatuses = fileStatusService.getDossierStatus(dossierId); + fileStatuses.forEach(fileStatus -> { + if (fileStatus.getDeleted().equals(dossier.getSoftDeletedTime()) || fileStatus.getDeleted() + .isAfter(dossier.getSoftDeletedTime())) { + fileService.undeleteFile(dossier.getDossierTemplateId(), dossierId, fileStatus.getId(), dossier.getSoftDeletedTime()); + fileStatusService.setFileStatusUndeleted( fileStatus.getId()); + } + }); + + dossierService.undeleteDossier(dossierId); + } + + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DossierTemplateController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DossierTemplateController.java new file mode 100644 index 000000000..b1c146187 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DossierTemplateController.java @@ -0,0 +1,43 @@ +package com.iqser.red.service.file.management.v1.server.controller; + + +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierTemplatePersistenceService; +import com.iqser.red.service.persistence.service.v1.api.model.CreateOrUpdateDossierTemplateRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierTemplate; +import com.iqser.red.service.persistence.service.v1.api.resources.DossierTemplateResource; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@Slf4j +@RestController +@RequiredArgsConstructor +public class DossierTemplateController implements DossierTemplateResource { + + private final DossierTemplatePersistenceService dossierTemplatePersistenceService; + + @Override + public DossierTemplate createOrUpdateDossierTemplate(@RequestBody CreateOrUpdateDossierTemplateRequest dossierTemplate) { + return dossierTemplatePersistenceService.createOrUpdateDossierTemplate(dossierTemplate); + } + + @Override + public List getAllDossierTemplates() { + return dossierTemplatePersistenceService.getAllDossierTemplates(); + } + + @Override + public DossierTemplate getDossierTemplate(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId) { + return dossierTemplatePersistenceService.getDossierTemplate(dossierTemplateId); + } + + @Override + public void deleteDossierTemplate(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId, @RequestParam(USER_ID_PARAM) String deletingUserId) { + dossierTemplatePersistenceService.deleteDossierTemplate(dossierTemplateId, deletingUserId); + } +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DownloadController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DownloadController.java new file mode 100644 index 000000000..75501e8c1 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/DownloadController.java @@ -0,0 +1,154 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.iqser.red.service.file.management.v1.server.model.DownloadJob; +import com.iqser.red.service.file.management.v1.server.utils.StorageIdUtils; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DownloadStatusPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService; +import com.iqser.red.service.persistence.service.v1.api.model.DownloadRequest; +import com.iqser.red.service.persistence.service.v1.api.model.JSONPrimitive; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import com.iqser.red.service.persistence.service.v1.api.model.data.download.DownloadStatus; +import com.iqser.red.service.persistence.service.v1.api.resources.DownloadResource; +import lombok.RequiredArgsConstructor; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import static com.iqser.red.service.file.management.v1.server.configuration.MessagingConfiguration.DOWNLOAD_QUEUE; + +@RestController +@RequiredArgsConstructor +public class DownloadController implements DownloadResource { + + private final DownloadStatusPersistenceService downloadStatusPersistenceService; + private final FileStatusPersistenceService fileStatusPersistenceService; + private final DossierPersistenceService dossierPersistenceService; + private final ObjectMapper objectMapper; + private final RabbitTemplate rabbitTemplate; + + + public JSONPrimitive prepareDownload(@RequestBody DownloadRequest request) { + + var mimeType = "application/zip"; + + var existingFileStatuses = fileStatusPersistenceService.getStatusesForDossier(request.getDossierId()); + + String downloadFilename = buildName(request.getDossierId(), request.getFileIds(), request.getUserId(), mimeType, existingFileStatuses); + + String storageId = StorageIdUtils.getStorageId(request.getUserId(), request.getDossierId(), downloadFilename); + + var dossier = dossierPersistenceService.getAndValidateDossier(request.getDossierId()); + + downloadStatusPersistenceService.createStatus(request.getUserId(), storageId, dossier, downloadFilename, mimeType, request.getFileIds()); + + addToDownloadQueue(DownloadJob.builder().storageId(storageId).userId(request.getUserId()).build(), 1); + + return new JSONPrimitive<>(storageId); + } + + + public List getDownloadStatus(@PathVariable(USER_ID) String userId) { + + return downloadStatusPersistenceService.getStatusesByUser(userId); + } + + + public void setDownloaded(@RequestBody JSONPrimitive setDownloadedRequest) { + + downloadStatusPersistenceService.updateLastDownload(setDownloadedRequest.getValue()); + } + + + @Override + public void deleteDownloadStatus(@RequestBody JSONPrimitive setDownloadedRequest) { + + downloadStatusPersistenceService.deleteStatus(setDownloadedRequest.getValue()); + } + + + private void addToDownloadQueue(DownloadJob downloadJob, int priority) { + + try { + rabbitTemplate.convertAndSend(DOWNLOAD_QUEUE, objectMapper.writeValueAsString(downloadJob), message -> { + message.getMessageProperties().setPriority(priority); + return message; + }); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + + + private String buildName(String dossierId, List fileIds, String userId, String mimeType, + List existingFileStatuses) { + + var dossier = dossierPersistenceService.getAndValidateDossier(dossierId); + + Set existingFilenames = downloadStatusPersistenceService.getStatusesByUser(userId) + .stream() + .map(DownloadStatus::getFilename) + .collect(Collectors.toSet()); + + if (fileIds.size() == 1) { + var file = fileStatusPersistenceService.getStatus(fileIds.iterator().next()); + + String cleanName = getCleanName(file.getFilename()); + + String name = cleanName + getExtension(mimeType); + int i = 1; + while (existingFilenames.contains(name)) { + name = cleanName + " (" + i + ")" + getExtension(mimeType); + i++; + } + return name; + } + + int i = 1; + if (existingFileStatuses.size() != fileIds.size()) { + String name = dossier.getDossierName() + ".bulk" + getExtension(mimeType); + while (existingFilenames.contains(name)) { + name = dossier.getDossierName() + ".bulk (" + i + ")" + getExtension(mimeType); + i++; + } + return name; + } else { + String name = dossier.getDossierName() + ".full" + getExtension(mimeType); + while (existingFilenames.contains(name)) { + name = dossier.getDossierName() + ".full (" + i + ")" + getExtension(mimeType); + i++; + } + return name; + } + } + + + private String getCleanName(String fileName) { + + var lastIndexOfDot = fileName.lastIndexOf("."); + String cleanName; + if (lastIndexOfDot > 0) { + cleanName = fileName.substring(0, fileName.lastIndexOf(".")); + } else { + cleanName = fileName; + } + return cleanName; + } + + + private String getExtension(String mimeType) { + + if ("application/zip".equalsIgnoreCase(mimeType)) { + return ".zip"; + } + return ".data"; + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/FileAttributesController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/FileAttributesController.java new file mode 100644 index 000000000..f6577fe06 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/FileAttributesController.java @@ -0,0 +1,58 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileAttributeConfigPersistenceService; +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.FileAttributesGeneralConfiguration; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.FileAttributeConfig; +import com.iqser.red.service.persistence.service.v1.api.resources.FileAttributesResource; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@Slf4j +@RestController +@RequiredArgsConstructor +public class FileAttributesController implements FileAttributesResource { + + + private final FileAttributeConfigPersistenceService fileAttributeConfigPersistenceService; + + @Override + public FileAttributeConfig addOrUpdateFileAttribute(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId, @RequestBody FileAttributeConfig fileAttributeConfig) { + return fileAttributeConfigPersistenceService.addOrUpdateFileAttribute(dossierTemplateId, fileAttributeConfig); + } + + @Override + public FileAttributesGeneralConfiguration setFileAttributesGeneralConfig(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId, + @RequestBody FileAttributesGeneralConfiguration fileAttributesConfig) { + return fileAttributeConfigPersistenceService.setFileAttributesGeneralConfig(dossierTemplateId, fileAttributesConfig); + } + + @Override + public FileAttributesGeneralConfiguration getFileAttributesGeneralConfiguration(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId) { + return fileAttributeConfigPersistenceService.getFileAttributesGeneralConfiguration(dossierTemplateId); + } + + @Override + public List setFileAttributesConfig(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId, @RequestBody List fileAttributesConfig) { + return fileAttributeConfigPersistenceService.setFileAttributesConfig(dossierTemplateId, fileAttributesConfig); + } + + @Override + public void deleteFileAttribute(@PathVariable(FILE_ATTRIBUTE_ID) String fileAttributeId) { + fileAttributeConfigPersistenceService.deleteFileAttribute(fileAttributeId); + } + + @Override + public void deleteFileAttributes(@RequestBody List fileAttributeIds) { + fileAttributeConfigPersistenceService.deleteFileAttributes(fileAttributeIds); + } + + @Override + public List getFileAttributes(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId) { + return fileAttributeConfigPersistenceService.getFileAttributes(dossierTemplateId); + } +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/FileStatusController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/FileStatusController.java new file mode 100644 index 000000000..3296ad375 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/FileStatusController.java @@ -0,0 +1,131 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import com.iqser.red.service.file.management.v1.server.service.DossierService; +import com.iqser.red.service.file.management.v1.server.service.ExcludeFromAnalysisService; +import com.iqser.red.service.file.management.v1.server.service.FileStatusService; +import com.iqser.red.service.persistence.service.v1.api.model.JSONPrimitive; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.FileStatus; +import com.iqser.red.service.persistence.service.v1.api.resources.StatusResource; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +@RestController +@RequiredArgsConstructor +public class FileStatusController implements StatusResource { + + private final FileStatusService fileStatusService; + private final DossierService dossierService; + private final ExcludeFromAnalysisService excludeFromAnalysis; + + @Override + public List getAllStatuses() { + + return fileStatusService.getAllStatuses() + .stream() + .filter(f -> !f.getStatus().equals(FileStatus.DELETED)) + .collect(Collectors.toList()); + } + + + @Override + public List getDossierStatus(@PathVariable(DOSSIER_ID_PARAM) String dossierId) { + + return fileStatusService.getDossierStatus(dossierId) + .stream() + .filter(f -> !f.getStatus().equals(FileStatus.DELETED)) + .collect(Collectors.toList()); + } + + @Override + public List getSoftDeletedDossierStatus(@PathVariable(DOSSIER_ID_PARAM) String dossierId) { + + return fileStatusService.getDossierStatus(dossierId) + .stream() + .filter(f -> f.getStatus().equals(FileStatus.DELETED) && f.getHardDeletedTime() == null) + .collect(Collectors.toList()); + } + + + @Override + public File getFileStatus(@PathVariable(DOSSIER_ID_PARAM) String dossierId, + @PathVariable(FILE_ID) String fileId) { + + return fileStatusService.getStatus(fileId); + } + + + @Override + public void setCurrentFileReviewer(@PathVariable(DOSSIER_ID_PARAM) String dossierId, + @PathVariable(FILE_ID) String fileId, + @RequestBody JSONPrimitive currentFileReviewerRequest) { + + fileStatusService.setCurrentReviewer(dossierId, fileId, currentFileReviewerRequest.getValue()); + fileStatusService.setStatusSuccessful(fileId, FileStatus.UNDER_REVIEW); + } + + + public void setStatusUnderReview(@PathVariable(DOSSIER_ID_PARAM) String dossierId, + @PathVariable(FILE_ID) String fileId) { + + + File fileStatus = fileStatusService.getStatus(fileId); + String lastReviewer = fileStatus.getLastReviewer(); + fileStatusService.setCurrentReviewer(dossierId, fileId, lastReviewer); + fileStatusService.setStatusSuccessful(fileId, FileStatus.UNDER_REVIEW); + } + + + public void setStatusUnderApproval(@PathVariable(DOSSIER_ID_PARAM) String dossierId, + @PathVariable(FILE_ID) String fileId, + @RequestParam(value = APPROVER_ID_REQUEST_PARAM, required = false) String approverId) { + + + var dossier = dossierService.getDossierById(dossierId); + + String dossierOwner = dossier.getOwnerId(); + + fileStatusService.setCurrentReviewer(dossierId, fileId, approverId != null ? approverId : dossierOwner); + fileStatusService.setStatusSuccessful(fileId, FileStatus.UNDER_APPROVAL); + } + + + public void setStatusApproved(@PathVariable(DOSSIER_ID_PARAM) String dossierId, + @PathVariable(FILE_ID) String fileId) { + + fileStatusService.setApprovalStatusSuccessful(fileId, FileStatus.APPROVED); + } + + public void toggleExclusion(@PathVariable(DOSSIER_ID_PARAM) String dossierId, + @PathVariable(FILE_ID) String fileId, @RequestParam(EXCLUDED_STATUS_PARAM) boolean excluded) { + + excludeFromAnalysis.toggleExclusion(dossierId, fileId, excluded); + + } + + + public void excludePages(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody Set pages) { + File fileStatus = fileStatusService.getStatus(fileId); + Set excludedPages = fileStatus.getExcludedPages(); + excludedPages.addAll(pages); + + fileStatusService.setExcludedPages(fileId, pages); + } + + + public void includePages(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody Set pages) { + + File fileStatus = fileStatusService.getStatus(fileId); + Set excludedPages = fileStatus.getExcludedPages(); + excludedPages.removeAll(pages); + fileStatusService.setExcludedPages(fileId, pages); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/FileStatusProcessingUpdateController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/FileStatusProcessingUpdateController.java new file mode 100644 index 000000000..5007a4561 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/FileStatusProcessingUpdateController.java @@ -0,0 +1,63 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import com.iqser.red.service.persistence.service.v1.api.resources.FileStatusProcessingUpdateResource; +import com.iqser.red.service.file.management.v1.server.service.FileStatusProcessingUpdateService; +import com.iqser.red.service.redaction.v1.model.AnalyzeResult; + +import lombok.RequiredArgsConstructor; + +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +public class FileStatusProcessingUpdateController implements FileStatusProcessingUpdateResource { + + private final FileStatusProcessingUpdateService fileStatusProcessingUpdateService; + + + public void analysisSuccessful(@PathVariable(DOSSIER_ID_PARAM) String dossierId, + @PathVariable(FILE_ID) String fileId, @RequestBody AnalyzeResult analyzeResult) { + + fileStatusProcessingUpdateService.analysisSuccessful(dossierId, fileId, analyzeResult); + } + + + public void ocrSuccessful(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId) { + + fileStatusProcessingUpdateService.ocrSuccessful(dossierId, fileId); + } + + + public void analysisFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId) { + + fileStatusProcessingUpdateService.analysisFailed(dossierId, fileId); + } + + + public void ocrFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId) { + + fileStatusProcessingUpdateService.ocrFailed(dossierId, fileId); + } + + + public void indexing(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId) { + + fileStatusProcessingUpdateService.indexing(dossierId, fileId); + } + + + public void indexingSuccessful(@PathVariable(DOSSIER_ID_PARAM) String dossierId, + @PathVariable(FILE_ID) String fileId) { + + fileStatusProcessingUpdateService.indexingSuccessful(dossierId, fileId); + } + + + public void indexingFailed(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId) { + + fileStatusProcessingUpdateService.indexingFailed(dossierId, fileId); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/LegalBasisMappingController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/LegalBasisMappingController.java new file mode 100644 index 000000000..b3e477886 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/LegalBasisMappingController.java @@ -0,0 +1,49 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.LegalBasisMappingRepository; +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.LegalBasis; +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.LegalBasisMapping; +import com.iqser.red.service.persistence.service.v1.api.resources.LegalBasisMappingResource; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + + +@RestController +@RequiredArgsConstructor +public class LegalBasisMappingController implements LegalBasisMappingResource { + + + private final LegalBasisMappingRepository legalBasisMappingRepository; + + + @Override + public void setLegalBasisMapping(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, @RequestBody List legalBasisMapping) { + + legalBasisMappingRepository.findById(dossierTemplateId).ifPresentOrElse((lbm) -> { + lbm.setVersion(lbm.getVersion() + 1); + lbm.setLegalBasis(legalBasisMapping); + legalBasisMappingRepository.save(lbm); + }, () -> { + var lbm = new LegalBasisMapping(); + lbm.setDossierTemplateId(dossierTemplateId); + lbm.setLegalBasis(legalBasisMapping); + lbm.setVersion(0); + legalBasisMappingRepository.save(lbm); + }); + + } + + @Override + public List getLegalBasisMapping(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId) { + return legalBasisMappingRepository.findById(dossierTemplateId).get().getLegalBasis(); + } + + @Override + public long getVersion(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId) { + return legalBasisMappingRepository.findById(dossierTemplateId).get().getVersion(); + } +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/LicenseReportController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/LicenseReportController.java new file mode 100644 index 000000000..12e73b74a --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/LicenseReportController.java @@ -0,0 +1,29 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.iqser.red.service.persistence.service.v1.api.model.LicenseReport; +import com.iqser.red.service.persistence.service.v1.api.model.LicenseReportRequest; +import com.iqser.red.service.persistence.service.v1.api.resources.LicenseReportResource; +import com.iqser.red.service.file.management.v1.server.service.LicenseReportService; + +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +public class LicenseReportController implements LicenseReportResource { + + private final LicenseReportService licenseReportService; + + + @Override + public LicenseReport getLicenseReport(@RequestBody LicenseReportRequest licenseReportRequest, + @RequestParam(value = "offset", defaultValue = "0") int offset, + @RequestParam(value = "limit", defaultValue = "20") int limit) { + + return licenseReportService.getLicenseReport(licenseReportRequest, offset, limit); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/ManualRedactionController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/ManualRedactionController.java new file mode 100644 index 000000000..53c4de500 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/ManualRedactionController.java @@ -0,0 +1,222 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import com.iqser.red.service.file.management.v1.server.service.ManualRedactionService; +import com.iqser.red.service.persistence.service.v1.api.model.*; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.*; +import com.iqser.red.service.persistence.service.v1.api.resources.ManualRedactionResource; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +public class ManualRedactionController implements ManualRedactionResource { + + private final ManualRedactionService manualRedactionService; + + + @Override + public ManualAddResponse addAddRedaction(@PathVariable(DOSSIER_ID) String dossierId, + @PathVariable(FILE_ID) String fileId, + @RequestBody AddRedactionRequest addRedactionRequest) { + + return manualRedactionService.addAddRedaction(dossierId, fileId, addRedactionRequest); + } + + + @Override + public ManualAddResponse addRemoveRedaction(@PathVariable(DOSSIER_ID) String dossierId, + @PathVariable(FILE_ID) String fileId, + @RequestBody RemoveRedactionRequest removeRedactionRequest) { + + return manualRedactionService.addRemoveRedaction(dossierId, fileId, removeRedactionRequest); + } + + + @Override + public ManualAddResponse addForceRedaction(@PathVariable(DOSSIER_ID) String dossierId, + @PathVariable(FILE_ID) String fileId, + @RequestBody ForceRedactionRequest forceRedactionRequest) { + + return manualRedactionService.addForceRedaction(dossierId, fileId, forceRedactionRequest); + } + + + @Override + public ManualAddResponse addLegalBasisChange(@PathVariable(DOSSIER_ID) String dossierId, + @PathVariable(FILE_ID) String fileId, + @RequestBody LegalBasisChangeRequest legalBasisChangeRequest) { + + return manualRedactionService.addLegalBasisChange(dossierId, fileId, legalBasisChangeRequest); + } + + + @Override + public ManualAddResponse addImageRecategorization(@PathVariable(DOSSIER_ID) String dossierId, + @PathVariable(FILE_ID) String fileId, + @RequestBody ImageRecategorizationRequest imageRecategorizationRequest) { + + return manualRedactionService.addImageRecategorization(dossierId, fileId, imageRecategorizationRequest); + } + + + @Override + public Comment addComment(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId, + @RequestBody CommentRequest comment) { + + return manualRedactionService.addComment(fileId, annotationId, comment); + } + + + @Override + public ManualRedactionEntry getAddRedaction(@PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId) { + + return manualRedactionService.getAddRedaction(fileId, annotationId); + } + + + @Override + public IdRemoval getRemoveRedaction(@PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId) { + + return manualRedactionService.getRemoveRedaction(fileId, annotationId); + } + + + public ManualForceRedaction getForceRedaction(@PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId) { + + return manualRedactionService.getForceRedaction(fileId, annotationId); + } + + + public ManualLegalBasisChange getLegalBasisChange(@PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId) { + + return manualRedactionService.getLegalBasisChange(fileId, annotationId); + } + + + @Override + public ManualImageRecategorization getImageRecategorization(@PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId) { + + return manualRedactionService.getImageRecategorization(fileId, annotationId); + } + + + @Override + public Comment getComment(@PathVariable(COMMENT_ID) long commentId) { + + return manualRedactionService.getComment(commentId); + } + + + @Override + public void deleteAddRedaction(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId) { + + manualRedactionService.deleteAddRedaction(dossierId, fileId, annotationId); + } + + + @Override + public void deleteRemoveRedaction(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId) { + + manualRedactionService.deleteRemoveRedaction(dossierId, fileId, annotationId); + } + + + @Override + public void deleteForceRedaction(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId) { + + manualRedactionService.deleteForceRedaction(dossierId, fileId, annotationId); + } + + + @Override + public void deleteLegalBasisChange(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId) { + + manualRedactionService.deleteLegalBasisChange(dossierId, fileId, annotationId); + } + + + @Override + public void deleteImageRecategorization(@PathVariable(DOSSIER_ID) String dossierId, + @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId) { + + manualRedactionService.deleteImageRecategorization(dossierId, fileId, annotationId); + } + + + @Override + public void deleteComment(@PathVariable(FILE_ID) String fileId, @PathVariable(COMMENT_ID) long commentId) { + + manualRedactionService.deleteComment(fileId, commentId); + } + + + @Override + public void updateAddRedactionStatus(@PathVariable(DOSSIER_ID) String dossierId, + @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId, + @RequestBody JSONPrimitive updateStatusRequest) { + + manualRedactionService.updateAddRedactionStatus(dossierId, fileId, annotationId, updateStatusRequest.getValue()); + } + + + @Override + public void updateRemoveRedactionStatus(@PathVariable(DOSSIER_ID) String dossierId, + @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId, + @RequestBody JSONPrimitive updateStatusRequest) { + + manualRedactionService.updateRemoveRedactionStatus(dossierId, fileId, annotationId, updateStatusRequest.getValue()); + } + + + @Override + public void updateForceRedactionStatus(@PathVariable(DOSSIER_ID) String dossierId, + @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId, + @RequestBody JSONPrimitive updateStatusRequest) { + + manualRedactionService.updateForceRedactionStatus(dossierId, fileId, annotationId, updateStatusRequest.getValue()); + } + + + public void updateLegalBasisChangeStatus(@PathVariable(DOSSIER_ID) String dossierId, + @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId, + @RequestBody JSONPrimitive updateStatusRequest) { + + manualRedactionService.updateLegalBasisChangeStatus(dossierId, fileId, annotationId, updateStatusRequest.getValue()); + } + + + @Override + public void updateImageRecategorizationStatus(@PathVariable(DOSSIER_ID) String dossierId, + @PathVariable(FILE_ID) String fileId, + @PathVariable(ANNOTATION_ID) String annotationId, + @RequestBody JSONPrimitive updateStatusRequest) { + + manualRedactionService.updateImageRecategorizationStatus(dossierId, fileId, annotationId, updateStatusRequest.getValue()); + } + + + @Override + public ManualRedactions getManualRedactions(@PathVariable(DOSSIER_ID) String dossierId, + @PathVariable(FILE_ID) String fileId) { + + return manualRedactionService.getManualRedactions(fileId); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/ReanalysisController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/ReanalysisController.java new file mode 100644 index 000000000..674548c5c --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/ReanalysisController.java @@ -0,0 +1,177 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import com.google.common.collect.Sets; +import com.iqser.red.service.file.management.v1.server.service.FileStatusService; +import com.iqser.red.service.file.management.v1.server.service.IndexingService; +import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException; +import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierPersistenceService; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.FileStatus; +import com.iqser.red.service.persistence.service.v1.api.resources.ReanalysisResource; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +@Slf4j +@RestController +@RequiredArgsConstructor +public class ReanalysisController implements ReanalysisResource { + + private final FileStatusService fileStatusService; + private final DossierPersistenceService dossierPersistenceService; + private final DictionaryController dictionaryClient; + private final RulesController rulesClient; + private final IndexingService indexingService; + + + @Override + public void reanalyzeDossier(@PathVariable(DOSSIER_ID_PARAM) String dossierId, + @RequestParam(value = "force", required = false, defaultValue = FALSE) boolean force) { + + var relevantFiles = getRelevantFiles(dossierId); + + reanalyseFiles(dossierId, force, relevantFiles); + } + + + @Override + public void reanalyzeFile(@PathVariable(DOSSIER_ID_PARAM) String dossierId, + @PathVariable(FILE_ID_PARAM) String fileId, + @RequestBody Set sectionsToReanalyse) { + + log.info("Reanalyse: {} / {} with sections: {}", dossierId, fileId, sectionsToReanalyse); + if (sectionsToReanalyse != null) { + var relevantFiles = getRelevantFiles(dossierId, Sets.newHashSet(fileId)); + relevantFiles.forEach(file -> { + fileStatusService.setStatusReprocess(dossierId, fileId, 10, sectionsToReanalyse); + }); + } else { + this.reanalyzeFiles(dossierId, Sets.newHashSet(fileId), false); + } + } + + + @Override + public void reanalyzeFiles(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @RequestBody Set fileIds, + @RequestParam(value = "force", required = false, defaultValue = FALSE) boolean force) { + + var relevantFiles = getRelevantFiles(dossierId, fileIds); + reanalyseFiles(dossierId, force, relevantFiles); + } + + + public void ocrDossier(@PathVariable(DOSSIER_ID_PARAM) String dossierId) { + + var relevantFiles = getRelevantFiles(dossierId); + + relevantFiles.stream().filter(fileStatus -> fileStatus.getLastOCRTime() == null).forEach(fileStatus -> fileStatusService.setStatusOcrProcessing(dossierId, fileStatus.getId())); + } + + + public void ocrFiles(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @RequestBody Set fileIds) { + + var relevantFiles = getRelevantFiles(dossierId, fileIds); + + relevantFiles.stream().filter(fileStatus -> fileStatus.getLastOCRTime() == null).forEach(fileStatus -> fileStatusService.setStatusOcrProcessing(dossierId, fileStatus.getId())); + } + + + public void reindex(@RequestParam(value = DOSSIER_ID_PARAM, required = false) String dossierId, @RequestBody Set fileIds) { + indexingService.reindex(dossierId, fileIds); + } + + + public void ocrFile(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID_PARAM) String fileId, @RequestParam(value = "force", required = false, defaultValue = FALSE) boolean force) { + + if (force) { + fileStatusService.setStatusOcrProcessing(dossierId, fileId); + } else { + File dossierFile = fileStatusService.getStatus( fileId); + if (dossierFile.getStatus().equals(FileStatus.DELETED) || dossierFile.getStatus().equals(FileStatus.APPROVED)) { + throw new ConflictException("Cannot analyse a deleted/approved file"); + } + if (dossierFile.getLastOCRTime() != null) { + throw new ConflictException("File already has been OCR processed"); + } + ocrFiles(dossierId, Sets.newHashSet(fileId)); + } + } + + + private List getRelevantFiles(String dossierId) { + + var dossier = dossierPersistenceService.getAndValidateDossier(dossierId); + return fileStatusService.getDossierStatus(dossier.getId()) + .stream() + .filter(fileStatus -> !fileStatus.getStatus().equals(FileStatus.DELETED)) + .filter(fileStatus -> !fileStatus.getStatus().equals(FileStatus.APPROVED)) + .collect(Collectors.toList()); + + } + + + private List getRelevantFiles(String dossierId, Collection fileIds) { + + var relevantDossierFiles = getRelevantFiles(dossierId); + + var relevantFiles = new ArrayList(); + for (var fileId : fileIds) { + var dossierFileOptional = relevantDossierFiles.stream().filter(f -> f.getId().equals(fileId)).findAny(); + if (dossierFileOptional.isEmpty()) { + throw new BadRequestException("Cannot reanalyse file from different dossier!"); + } + + var dossierFile = dossierFileOptional.get(); + + if (dossierFile.getStatus().equals(FileStatus.DELETED) || dossierFile.getStatus().equals(FileStatus.APPROVED)) { + throw new ConflictException("Cannot analyse a deleted/approved file"); + } + + relevantFiles.add(dossierFile); + + } + return relevantFiles; + } + + + private void reanalyseFiles(String dossierId, boolean force, List filesToReanalyse) { + + var dossier = dossierPersistenceService.getAndValidateDossier(dossierId); + // TODO + var dictionaryVersion = dictionaryClient.getVersion(dossier.getDossierTemplateId()); + var dossierDictionaryVersion = dictionaryClient.getVersionForDossier(dossierId); + var rulesVersion = rulesClient.getVersion(dossier.getDossierTemplateId()); + + filesToReanalyse.forEach(fileStatus -> { + if (fileStatus.getStatus().equals(FileStatus.ERROR) || !allManualRedactionsApplied(fileStatus) || !allFileAttributesChangesApplied(fileStatus) + || fileStatus.getRulesVersion() < rulesVersion || fileStatus.getDictionaryVersion() < dictionaryVersion || fileStatus.getDossierDictionaryVersion() < dossierDictionaryVersion || force) { + fileStatusService.setStatusReprocess(dossierId, fileStatus.getId(), 1); + } + }); + } + + + private boolean allManualRedactionsApplied(File fileStatus) { + + return fileStatus.getLastManualRedaction() == null || fileStatus.getLastProcessed() == null || fileStatus.getLastProcessed() + .isAfter(fileStatus.getLastManualRedaction()); + } + + + private boolean allFileAttributesChangesApplied(File fileStatus) { + + return fileStatus.getLastFileAttributeChange() == null || fileStatus.getLastProcessed() == null || fileStatus.getLastProcessed() + .isAfter(fileStatus.getLastFileAttributeChange()); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/RedactionLogController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/RedactionLogController.java new file mode 100644 index 000000000..6b2fc1053 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/RedactionLogController.java @@ -0,0 +1,35 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.iqser.red.service.persistence.service.v1.api.resources.RedactionLogResource; +import com.iqser.red.service.file.management.v1.server.service.RedactionLogService; +import com.iqser.red.service.redaction.v1.model.RedactionLog; +import com.iqser.red.service.redaction.v1.model.SectionGrid; + +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +public class RedactionLogController implements RedactionLogResource { + + private final RedactionLogService redactionLogService; + + + public RedactionLog getRedactionLog(@PathVariable(DOSSIER_ID_PARAM) String dossierId, + @PathVariable(FILE_ID) String fileId, + @RequestParam(value = "withManualRedactions", required = false, defaultValue = "true") boolean withManualRedactions) { + + return redactionLogService.getRedactionLog(dossierId, fileId, withManualRedactions); + } + + + public SectionGrid getSectionGrid(@PathVariable(DOSSIER_ID_PARAM) String dossierId, + @PathVariable(FILE_ID) String fileId) { + + return redactionLogService.getSectionGrid(dossierId, fileId); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/ReportTemplateController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/ReportTemplateController.java new file mode 100644 index 000000000..834dfb45b --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/ReportTemplateController.java @@ -0,0 +1,87 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import com.iqser.red.service.file.management.v1.server.utils.StorageIdUtils; +import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException; +import com.iqser.red.service.persistence.management.v1.processor.exception.FileNotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.ReportTemplatePersistenceService; +import com.iqser.red.service.persistence.service.v1.api.model.ReportTemplateDownload; +import com.iqser.red.service.persistence.service.v1.api.model.ReportTemplateUploadRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.ReportTemplate; +import com.iqser.red.service.persistence.service.v1.api.resources.ReportTemplateResource; +import com.iqser.red.storage.commons.exception.StorageObjectDoesNotExist; +import com.iqser.red.storage.commons.service.StorageService; +import lombok.RequiredArgsConstructor; +import org.apache.commons.io.IOUtils; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.io.IOException; +import java.util.List; +import java.util.UUID; + +@RestController +@RequiredArgsConstructor +public class ReportTemplateController implements ReportTemplateResource { + + private final StorageService storageService; + private final ReportTemplatePersistenceService reportTemplatePersistenceService; + + + public ReportTemplate uploadTemplate(@RequestBody ReportTemplateUploadRequest reportTemplateUploadRequest) { + + List reportTemplates = reportTemplatePersistenceService.findByDossierTemplateId(reportTemplateUploadRequest.getDossierTemplateId()); + for (ReportTemplate reportTemplate : reportTemplates) { + if (reportTemplate.getFileName().equals(reportTemplateUploadRequest.getFileName())) { + throw new ConflictException("Template already exists."); + } + } + String storageId = StorageIdUtils.getReportStorageId(reportTemplateUploadRequest.getDossierTemplateId(), reportTemplateUploadRequest + .getFileName()); + storageService.storeObject(storageId, reportTemplateUploadRequest.getTemplate()); + String templateId = UUID.randomUUID().toString(); + reportTemplatePersistenceService.insert(reportTemplateUploadRequest.getDossierTemplateId(), templateId, storageId, reportTemplateUploadRequest + .getFileName(), reportTemplateUploadRequest.isMultiFileReport(), reportTemplateUploadRequest.isActiveByDefault()); + + return reportTemplatePersistenceService.find(templateId); + + } + + + public List getAvailableReportTemplates( + @PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId) { + + return reportTemplatePersistenceService.findByDossierTemplateId(dossierTemplateId); + } + + + public ReportTemplate getReportTemplate(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId, + @PathVariable(TEMPLATE_ID) String templateId) { + + return reportTemplatePersistenceService.find(templateId); + } + + + public ReportTemplateDownload downloadReportTemplate(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId, + @PathVariable(TEMPLATE_ID) String templateId) { + + String storageId = reportTemplatePersistenceService.find(templateId).getStorageId(); + try { + byte[] file = IOUtils.toByteArray(storageService.getObject(storageId).getInputStream()); + return ReportTemplateDownload.builder().file(file).build(); + } catch (StorageObjectDoesNotExist | IOException e) { + throw new FileNotFoundException("Template does not exist"); + } + } + + + public void deleteTemplate(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId, + @PathVariable(TEMPLATE_ID) String templateId) { + + String storageId = reportTemplatePersistenceService.find(templateId).getStorageId(); + storageService.deleteObject(storageId); + reportTemplatePersistenceService.delete(templateId); + + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/RulesController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/RulesController.java new file mode 100644 index 000000000..62d9db3b6 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/RulesController.java @@ -0,0 +1,51 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import com.iqser.red.service.file.management.v1.server.client.RedactionServiceClient; +import com.iqser.red.service.file.management.v1.server.exception.InvalidRulesException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.RulesPersistenceService; +import com.iqser.red.service.persistence.service.v1.api.model.JSONPrimitive; +import com.iqser.red.service.persistence.service.v1.api.resources.RulesResource; +import feign.FeignException; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +public class RulesController implements RulesResource { + + private final RulesPersistenceService rulesPersistenceService; + private final RedactionServiceClient redactionServiceClient; + + + @Override + public void setRules(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, @RequestBody JSONPrimitive request) { + + try { + redactionServiceClient.testRules(request.getValue()); + } catch (FeignException e) { + if (e.status() == HttpStatus.BAD_REQUEST.value()) { + throw new InvalidRulesException("Rules could not be updated, validation check failed: " + e.getMessage()); + } + throw e; + } + rulesPersistenceService.setRules(request.getValue(), dossierTemplateId); + + } + + + @Override + public JSONPrimitive getRules(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId) { + + return new JSONPrimitive<>(rulesPersistenceService.getRules(dossierTemplateId).getValue()); + } + + + @Override + public long getVersion(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId) { + return rulesPersistenceService.getRules(dossierTemplateId).getVersion(); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/SMTPConfigurationController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/SMTPConfigurationController.java new file mode 100644 index 000000000..48c048509 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/SMTPConfigurationController.java @@ -0,0 +1,71 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.SMTPConfiguration; +import com.iqser.red.service.persistence.service.v1.api.resources.SMTPConfigurationResource; +import com.iqser.red.service.persistence.management.v1.processor.service.EmailService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.SMTPConfigurationService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController +@RequiredArgsConstructor +public class SMTPConfigurationController implements SMTPConfigurationResource { + + private final EmailService emailService; + private final SMTPConfigurationService smtpConfigurationService; + + private final static String DEFAULT_PASSWORD = "********"; + + + @Override + public SMTPConfiguration getCurrentSMTPConfiguration(@RequestParam(value = MASK_PASSWORD, required = false, defaultValue = "true") boolean maskPassword) { + var smtpConfiguration = smtpConfigurationService.getConfiguration(); + if (smtpConfiguration.isAuth() && maskPassword) { + smtpConfiguration.setPassword(DEFAULT_PASSWORD); + } + return smtpConfiguration; + } + + @Override + public void updateSMTPConfiguration(@RequestBody SMTPConfiguration smtpConfiguration) { + updatePassword(smtpConfiguration); + smtpConfigurationService.saveConfiguration(smtpConfiguration); + } + + @Override + public void testSMTPConfiguration(@RequestParam(value = "TEST_EMAIL", required = false) String testEmail, @RequestBody SMTPConfiguration smtpConfiguration) { + + String targetEmail = null; + if (StringUtils.isBlank(testEmail)) { + // will send e-mail to self in case testEmail is not set + targetEmail = smtpConfiguration.getFrom(); + } else { + targetEmail = testEmail; + } + + updatePassword(smtpConfiguration); + emailService.send(smtpConfiguration, targetEmail, "Redaction Test Message", "This is a test message"); + } + + @Override + public void clearSMTPConfiguration() { + smtpConfigurationService.deleteConfiguration(); + } + + private void updatePassword(SMTPConfiguration smtpConfiguration) { + if (DEFAULT_PASSWORD.equals(smtpConfiguration.getPassword())) { + try { + var currentSMTPConfig = getCurrentSMTPConfiguration(false); + smtpConfiguration.setPassword(currentSMTPConfig.getPassword()); + } catch (Exception e) { + log.debug("No current SMTP Config exists", e); + } + } + } +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/UploadController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/UploadController.java new file mode 100644 index 000000000..1bf268e98 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/UploadController.java @@ -0,0 +1,175 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import com.iqser.red.service.file.management.v1.server.client.PDFTronRedactionClient; +import com.iqser.red.service.file.management.v1.server.client.RedactionClient; +import com.iqser.red.service.file.management.v1.server.service.DossierService; +import com.iqser.red.service.file.management.v1.server.service.FileManagementStorageService; +import com.iqser.red.service.file.management.v1.server.service.FileService; +import com.iqser.red.service.file.management.v1.server.service.FileStatusService; +import com.iqser.red.service.pdftron.redaction.v1.api.model.PdfTronFlattenRequest; +import com.iqser.red.service.pdftron.redaction.v1.api.model.PdfTronFlattenResponse; +import com.iqser.red.service.pdftron.redaction.v1.api.model.PdfTronRedactionRequest; +import com.iqser.red.service.pdftron.redaction.v1.api.model.PdfTronRedactionResult; +import com.iqser.red.service.persistence.management.v1.processor.exception.DossierNotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.exception.FileNotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierPersistenceService; +import com.iqser.red.service.persistence.service.v1.api.model.BinaryFileRequest; +import com.iqser.red.service.persistence.service.v1.api.model.BinaryFileResult; +import com.iqser.red.service.persistence.service.v1.api.model.FileType; +import com.iqser.red.service.persistence.service.v1.api.model.JSONPrimitive; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierStatus; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import com.iqser.red.service.persistence.service.v1.api.resources.UploadResource; +import com.iqser.red.service.redaction.v1.model.AnnotateRequest; +import com.iqser.red.service.redaction.v1.model.AnnotateResponse; +import com.iqser.red.storage.commons.exception.StorageObjectDoesNotExist; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.time.OffsetDateTime; +import java.util.Set; + +import static com.iqser.red.service.persistence.management.v1.processor.exception.DossierNotFoundException.DOSSIER_NOT_FOUND_MESSAGE; + +@RestController +@RequiredArgsConstructor +public class UploadController implements UploadResource { + + private final FileService fileService; + private final FileStatusService fileStatusService; + private final DossierService dossierService; + private final PDFTronRedactionClient pdfTronRedactionClient; + private final FileManagementStorageService fileManagementStorageService; + private final RedactionClient redactionClient; + private final DossierPersistenceService dossierPersistenceService; + + @Override + public JSONPrimitive upload(@RequestBody BinaryFileRequest request) { + + return fileService.upload(request); + } + + + @Override + public void deleteFile(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId) { + + var dossier = dossierService.getDossierById(dossierId); + if (dossier.getStatus().equals(DossierStatus.DELETED)) { + throw new DossierNotFoundException(String.format(DOSSIER_NOT_FOUND_MESSAGE, dossierId)); + } + + OffsetDateTime softDeleteTime = OffsetDateTime.now(); + fileService.softDeleteFile(dossierId, fileId, softDeleteTime); + fileStatusService.setFileStatusDeleted(fileId, softDeleteTime); + } + + @Override + public void hardDeleteFiles(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @RequestBody Set fileIds) { + + var dossier = dossierService.getDossierById(dossierId); + if (dossier.getStatus().equals(DossierStatus.DELETED)) { + throw new DossierNotFoundException(String.format(DOSSIER_NOT_FOUND_MESSAGE, dossierId)); + } + + for (String fileId : fileIds) { + fileService.hardDeleteFile(dossierId, fileId); + fileStatusService.setFileStatusHardDeleted(fileId); + } + + } + + @Override + public void undeleteFiles(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @RequestBody Set fileIds) { + var dossier = dossierService.getDossierById(dossierId); + if (dossier.getStatus().equals(DossierStatus.DELETED)) { + throw new DossierNotFoundException(String.format(DOSSIER_NOT_FOUND_MESSAGE, dossierId)); + } + + for (String fileId : fileIds) { + + File fileStatus = fileStatusService.getStatus(fileId); + OffsetDateTime softDeletedTime = fileStatus.getDeleted(); + + fileService.undeleteFile(dossier.getDossierTemplateId(), dossierId, fileId, softDeletedTime); + fileStatusService.setFileStatusUndeleted(fileId); + } + } + + + @Override + public BinaryFileResult getOriginal(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId) { + var fileStatus = fileStatusService.getStatus(fileId); + + if (fileStatus.getDeleted() != null) { + throw new FileNotFoundException("File is deleted."); + } + + try { + return new BinaryFileResult(fileManagementStorageService.getStoredObjectBytes(dossierId, fileId, FileType.ORIGIN), fileStatus.getFilename()); + } catch (StorageObjectDoesNotExist e) { + throw new FileNotFoundException(e.getMessage()); + } + } + + @Override + public BinaryFileResult getAnnotated(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId) { + + var fileStatus = fileStatusService.getStatus(fileId); + var dossier = dossierService.getDossierById(dossierId); + AnnotateResponse annotateResponse = redactionClient.annotate(AnnotateRequest.builder() + .fileId(fileId) + .dossierId(dossierId) + .dossierTemplateId(dossier.getDossierTemplateId()) + .build()); + + return new BinaryFileResult(annotateResponse.getDocument(), fileStatus.getFilename()); + } + + @Override + @SneakyThrows + public BinaryFileResult getRedacted(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId) { + + var fileStatus = fileStatusService.getStatus(fileId); + var dossier = dossierService.getDossierById(dossierId); + + PdfTronRedactionResult pdfTronRedactionResult = pdfTronRedactionClient.redact(PdfTronRedactionRequest.builder() + .dossierTemplateId(dossier.getDossierTemplateId()) + .document(fileManagementStorageService.getStoredObjectBytes(dossierId, fileId, FileType.ORIGIN)) + .redactionLog(fileManagementStorageService.getRedactionLog(dossierId, fileId)) + .build()); + + return new BinaryFileResult(pdfTronRedactionResult.getDocument(), fileStatus.getFilename()); + } + + @Override + @SneakyThrows + public BinaryFileResult getPreview(String dossierId, String fileId) { + + var fileStatus = fileStatusService.getStatus(fileId); + var dossier = dossierService.getDossierById(dossierId); + + PdfTronRedactionResult pdfTronRedactionResult = pdfTronRedactionClient.redactionPreview(PdfTronRedactionRequest.builder() + .dossierTemplateId(dossier.getDossierTemplateId()) + .document(fileManagementStorageService.getStoredObjectBytes(dossierId, fileId, FileType.ORIGIN)) + .redactionLog(fileManagementStorageService.getRedactionLog(dossierId, fileId)) + .build()); + + return new BinaryFileResult(pdfTronRedactionResult.getDocument(), fileStatus.getFilename()); + } + + + @Override + public BinaryFileResult getFlatRedacted(@PathVariable(DOSSIER_ID_PARAM) String dossierId, @PathVariable(FILE_ID) String fileId) { + + var redacted = getRedacted(dossierId, fileId); + + PdfTronFlattenResponse flattenResponse = pdfTronRedactionClient.flatDocument(PdfTronFlattenRequest.builder() + .document(redacted.getData()) + .build()); + return BinaryFileResult.builder().filename(redacted.getFilename()).data(flattenResponse.getDocument()).build(); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/ViewedPagesController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/ViewedPagesController.java new file mode 100644 index 000000000..0c928036b --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/ViewedPagesController.java @@ -0,0 +1,39 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ViewedPage; +import com.iqser.red.service.persistence.service.v1.api.resources.ViewedPagesResource; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.ViewedPagesPersistenceService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequiredArgsConstructor +public class ViewedPagesController implements ViewedPagesResource { + + private final ViewedPagesPersistenceService viewedPagesPersistenceService; + + + public void addPage(@PathVariable(FILE_ID) String fileId, @PathVariable(ROLE) String role, + @RequestBody Integer page) { + + viewedPagesPersistenceService.insertPage(fileId, role, page); + } + + + public void removePage(@PathVariable(FILE_ID) String fileId, @PathVariable(ROLE) String role, + @RequestBody Integer page) { + + viewedPagesPersistenceService.removePage(fileId, role, page); + } + + + public List getViewedPages(@PathVariable(FILE_ID) String fileId, @PathVariable(ROLE) String role) { + + return viewedPagesPersistenceService.findViewedPages(fileId, role); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/WatermarkController.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/WatermarkController.java new file mode 100644 index 000000000..eb16c0165 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/controller/WatermarkController.java @@ -0,0 +1,29 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import com.iqser.red.service.persistence.service.v1.api.model.data.configuration.Watermark; +import com.iqser.red.service.persistence.service.v1.api.resources.WatermarkResource; +import com.iqser.red.service.persistence.management.v1.processor.service.WatermarkService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +public class WatermarkController implements WatermarkResource { + + private final WatermarkService watermarkService; + + + public Watermark saveWatermark(String dossierTemplateId, @RequestBody Watermark watermark) { + return watermarkService.saveWatermark(watermark); + } + + public Watermark getWatermark(String dossierTemplateId) { + return watermarkService.getWatermark(dossierTemplateId); + } + + public void deleteWatermark(String dossierTemplateId) { + watermarkService.deleteWatermark(dossierTemplateId); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/exception/InvalidRulesException.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/exception/InvalidRulesException.java new file mode 100644 index 000000000..457e76003 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/exception/InvalidRulesException.java @@ -0,0 +1,9 @@ +package com.iqser.red.service.file.management.v1.server.exception; + +public class InvalidRulesException extends RuntimeException { + + public InvalidRulesException(String message) { + super(message); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/exception/JSONParseException.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/exception/JSONParseException.java new file mode 100644 index 000000000..177ec904e --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/exception/JSONParseException.java @@ -0,0 +1,10 @@ +package com.iqser.red.service.file.management.v1.server.exception; + +public class JSONParseException extends RuntimeException { + + public JSONParseException(String message, Throwable t) { + + super(message, t); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/model/DownloadJob.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/model/DownloadJob.java new file mode 100644 index 000000000..b993a6261 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/model/DownloadJob.java @@ -0,0 +1,18 @@ +package com.iqser.red.service.file.management.v1.server.model; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class DownloadJob { + + String userId; + String storageId; + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/DictionarySearchAndNotifyService.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/DictionarySearchAndNotifyService.java new file mode 100644 index 000000000..f63e3b770 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/DictionarySearchAndNotifyService.java @@ -0,0 +1,65 @@ +package com.iqser.red.service.file.management.v1.server.service; + +import com.iqser.red.service.file.management.v1.server.client.SearchClient; +import com.iqser.red.service.file.management.v1.server.controller.ReanalysisController; +import com.iqser.red.service.search.v1.model.MatchedSection; +import com.iqser.red.service.search.v1.model.SearchRequest; +import lombok.Builder; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +@Slf4j +@Service +@RequiredArgsConstructor +public class DictionarySearchAndNotifyService { + + private final ReanalysisController reanalysisClient; + private final SearchClient searchClient; + + public void dictionaryEntriesUpdated(String dossierTemplateId, Collection changedEntries) { + + log.info("Detect Changes for dossierTemplateId: {} and entries: {}", dossierTemplateId, changedEntries); + + Map> searchResultMap = new HashMap<>(); + + for (var entry : changedEntries) { + + + var searchResult = searchClient.getDossierStatus(SearchRequest.builder() + .dossierTemplateIds(Collections.singletonList(dossierTemplateId)).page(1).pageSize(10_000) + .returnSections(true) + .queryString(entry) + .build()); + + log.info("Got changes: {} for entry: {}", searchResult.getTotal(), entry); + + searchResult.getMatchedDocuments().forEach(document -> { + + var currentSections = searchResultMap.computeIfAbsent(SearchKey.builder().fileId(document.getFileId()).dossierId(document.getDossierId()).build(), (data) -> new HashSet<>()); + currentSections.addAll(document.getMatchedSections().stream().map(MatchedSection::getSectionNumber).collect(Collectors.toList())); + + }); + } + + + log.info("Should reanalyse: {}", searchResultMap); + searchResultMap.forEach((searchKey, sectionNumbers) -> { + log.info("Reanalyse: {} / {} ", searchKey, sectionNumbers); + reanalysisClient.reanalyzeFile(searchKey.getDossierId(), searchKey.getFileId(), sectionNumbers); + }); + + } + + @Data + @Builder + public static class SearchKey { + private String fileId; + private String dossierId; + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/DossierService.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/DossierService.java new file mode 100644 index 000000000..c9093d8e8 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/DossierService.java @@ -0,0 +1,98 @@ +package com.iqser.red.service.file.management.v1.server.service; + +import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException; +import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService; +import com.iqser.red.service.persistence.service.v1.api.model.CreateOrUpdateDossierRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.Dossier; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierStatus; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.time.OffsetDateTime; +import java.util.List; + +/** + * Provides the internal interface between dossier request and the actual persistence. + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class DossierService { + + private final DossierPersistenceService dossierPersistenceService; + + private final FileStatusPersistenceService fileStatusPersistenceService; + + + public Dossier addDossier(CreateOrUpdateDossierRequest createOrUpdateDossierRequest) { + + if (dossierPersistenceService.findAllDossiers() + .stream() + .anyMatch(p -> !p.getStatus().equals(DossierStatus.DELETED) && p.getDossierName() + .equals(createOrUpdateDossierRequest.getDossierName()))) { + throw new ConflictException("Dossier with this name already exists"); + } + + + return dossierPersistenceService.insert(createOrUpdateDossierRequest); + + } + + + public Dossier updateDossier(CreateOrUpdateDossierRequest dossierRequest, String dossierId) { + + Dossier dossier = dossierPersistenceService.findByDossierId(dossierId); + if (dossier.getDossierName() + .equals(dossierRequest.getDossierName()) || dossierPersistenceService.findAllDossiers() + .stream() + .filter(p -> !p.getStatus().equals(DossierStatus.DELETED) && p.getDossierName() + .equals(dossierRequest.getDossierName())) + .findAny() + .isEmpty()) { + + if (!dossier.getDossierTemplateId().equalsIgnoreCase(dossierRequest.getDossierTemplateId())) { + var canUpdateDossierTemplate = fileStatusPersistenceService.getStatusesForDossier(dossierId).isEmpty(); + if (!canUpdateDossierTemplate) { + throw new BadRequestException("Cannot update Dossier Template. Dossier already has files"); + } + } + + dossierPersistenceService.update(dossierId, dossierRequest); + return dossierPersistenceService.findByDossierId(dossierId); + } else { + throw new ConflictException("Dossier with this name already exists. Please choose another name."); + } + } + + + public void softDeleteDossier(String dossierId, OffsetDateTime softDeleteTime) { + + dossierPersistenceService.markDossierAsDeleted(dossierId, softDeleteTime); + } + + public void hardDeleteDossier(String dossierId) { + + dossierPersistenceService.hardDelete(dossierId); + } + + public void undeleteDossier(String dossierId) { + + dossierPersistenceService.undelete(dossierId); + } + + + public Dossier getDossierById(String dossierId) { + + return dossierPersistenceService.findByDossierId(dossierId); + } + + + public List getAllDossiers() { + + return dossierPersistenceService.findAllDossiers(); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/ExcludeFromAnalysisService.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/ExcludeFromAnalysisService.java new file mode 100644 index 000000000..6c81c8255 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/ExcludeFromAnalysisService.java @@ -0,0 +1,73 @@ +package com.iqser.red.service.file.management.v1.server.service; + +import com.google.common.collect.Sets; +import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.*; +import com.iqser.red.service.persistence.service.v1.api.model.FileType; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.FileStatus; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.time.OffsetDateTime; +import java.util.Set; + +@Service +@RequiredArgsConstructor +public class ExcludeFromAnalysisService { + + private final static Set VALID_STATES_FOR_EXCLUSION = Sets.newHashSet(FileStatus.UNASSIGNED, FileStatus.UNDER_REVIEW, FileStatus.UNDER_APPROVAL); + + private final FileStatusService fileStatusService; + private final FileManagementStorageService fileManagementStorageService; + + private final CommentPersistenceService commentPersistenceService; + private final ForceRedactionPersistenceService forceRedactionPersistenceService; + private final RemoveRedactionPersistenceService removeRedactionPersistenceService; + private final AddRedactionPersistenceService addRedactionPersistenceService; + private final FileStatusPersistenceService fileStatusPersistenceService; + + public void toggleExclusion(String dossierId, String fileId, boolean excluded) { + + var status = fileStatusService.getStatus(fileId); + + OffsetDateTime now = OffsetDateTime.now(); + + if (!VALID_STATES_FOR_EXCLUSION.contains(status.getStatus())) { + throw new BadRequestException("Files in status " + status.getStatus() + " cannot be excluded/included"); + } + + // toggle status + fileStatusService.toggleExclusion(fileId, excluded); + + if (!excluded) { + // if file has been re-enabled - process it + fileStatusService.setStatusFullReprocess(dossierId, fileId, 2); + } else { + // remove everything related to redaction + fileManagementStorageService.deleteObject(dossierId, fileId, FileType.REDACTION_LOG); + fileManagementStorageService.deleteObject(dossierId, fileId, FileType.TEXT); + fileManagementStorageService.deleteObject(dossierId, fileId, FileType.SECTION_GRID); + + // wipe comments + var comments = commentPersistenceService.findCommentsByFileID(fileId, false); + comments.forEach((key, value) -> value.forEach(comment -> + commentPersistenceService.softDelete(comment.getId(), now))); + + // wipe force redactions + var forceRedactions = forceRedactionPersistenceService.findForceRedactions(fileId, false); + forceRedactions.forEach(f -> forceRedactionPersistenceService.softDelete(fileId, f.getId().getId(), now)); + + // wipe add manual redactions + var addRedactions = addRedactionPersistenceService.findAddRedactions(fileId, false); + addRedactions.forEach(f -> addRedactionPersistenceService.softDelete(fileId, f.getId().getId(), now)); + + // wipe removeRedactions + var removeRedactions = removeRedactionPersistenceService.findRemoveRedactions(fileId, false); + removeRedactions.forEach(f -> removeRedactionPersistenceService.softDelete(fileId, f.getId().getId(), now)); + + fileStatusPersistenceService.updateHasComments(fileId, false); + + } + + } +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/FileManagementStorageService.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/FileManagementStorageService.java new file mode 100644 index 000000000..ad59dcf46 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/FileManagementStorageService.java @@ -0,0 +1,99 @@ +package com.iqser.red.service.file.management.v1.server.service; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.commons.io.IOUtils; +import org.springframework.core.io.InputStreamResource; +import org.springframework.stereotype.Service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.iqser.red.service.persistence.service.v1.api.model.FileType; +import com.iqser.red.service.persistence.management.v1.processor.exception.FileNotFoundException; +import com.iqser.red.service.file.management.v1.server.utils.StorageIdUtils; +import com.iqser.red.service.redaction.v1.model.RedactionLog; +import com.iqser.red.service.redaction.v1.model.SectionGrid; +import com.iqser.red.storage.commons.exception.StorageObjectDoesNotExist; +import com.iqser.red.storage.commons.service.StorageService; + +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Service +@RequiredArgsConstructor +public class FileManagementStorageService { + + private final ObjectMapper objectMapper; + private final StorageService storageService; + + + @SneakyThrows + public byte[] getStoredObjectBytes(String dossierId, String fileId, FileType fileType) { + + return IOUtils.toByteArray(storageService.getObject(StorageIdUtils.getStorageId(dossierId, fileId, fileType)) + .getInputStream()); + } + + + @SneakyThrows + public byte[] getStoredObjectBytes(String storageId) { + + return IOUtils.toByteArray(storageService.getObject(storageId).getInputStream()); + } + + + public void storeObject(String dossierId, String fileId, FileType fileType, byte[] data) { + + storageService.storeObject(StorageIdUtils.getStorageId(dossierId, fileId, fileType), data); + } + + + public void storeObject(String storageId, InputStream data) { + storageService.storeObject(storageId, data); + } + + + public RedactionLog getRedactionLog(String dossierId, String fileId) { + + InputStreamResource inputStreamResource; + try { + inputStreamResource = storageService.getObject(StorageIdUtils.getStorageId(dossierId, fileId, FileType.REDACTION_LOG)); + } catch (StorageObjectDoesNotExist e) { + log.debug("Text not available."); + throw new FileNotFoundException("RedactionLog does not exist"); + } + + try { + return objectMapper.readValue(inputStreamResource.getInputStream(), RedactionLog.class); + } catch (IOException e) { + throw new RuntimeException("Could not convert Text", e); + } + } + + + + public SectionGrid getSectionGrid(String dossierId, String fileId) { + + var sectionGrid = storageService.getObject(StorageIdUtils.getStorageId(dossierId, fileId, FileType.SECTION_GRID)); + try { + return objectMapper.readValue(sectionGrid.getInputStream(), SectionGrid.class); + } catch (IOException e) { + throw new RuntimeException("Could not convert RedactionLog", e); + } + } + + + public void deleteObject(String dossierId, String fileId, FileType fileType) { + + storageService.deleteObject(StorageIdUtils.getStorageId(dossierId, fileId, fileType)); + } + + + public void deleteObject(String storageId) { + + storageService.deleteObject(storageId); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/FileService.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/FileService.java new file mode 100644 index 000000000..11d961ddd --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/FileService.java @@ -0,0 +1,229 @@ +package com.iqser.red.service.file.management.v1.server.service; + +import com.google.common.hash.HashFunction; +import com.google.common.hash.Hashing; +import com.iqser.red.service.file.management.v1.server.client.PDFTronRedactionClient; +import com.iqser.red.service.pdftron.redaction.v1.api.model.PdfTronOptimizeRequest; +import com.iqser.red.service.pdftron.redaction.v1.api.model.PdfTronOptimizeResponse; +import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException; +import com.iqser.red.service.persistence.management.v1.processor.exception.FileNotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.*; +import com.iqser.red.service.persistence.service.v1.api.model.BinaryFileRequest; +import com.iqser.red.service.persistence.service.v1.api.model.FileType; +import com.iqser.red.service.persistence.service.v1.api.model.JSONPrimitive; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import com.iqser.red.service.redaction.v1.model.Status; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.time.OffsetDateTime; +import java.util.Arrays; + +/** + * Provides the internal interface between upload request and the actual persistence. + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class FileService { + + private final HashFunction hashFunction = Hashing.murmur3_128(); + + private final AddRedactionPersistenceService addRedactionPersistenceService; + private final CommentPersistenceService commentPersistenceService; + private final ForceRedactionPersistenceService forceRedactionPersistenceService; + private final RemoveRedactionPersistenceService removeRedactionPersistenceService; + private final FileStatusService fileStatusService; + private final PDFTronRedactionClient pdfTronRedactionClient; + private final ViewedPagesPersistenceService viewedPagesPersistenceService; + private final FileManagementStorageService fileManagementStorageService; + private final DossierPersistenceService dossierPersistenceService; + private final ImageRecategorizationPersistenceService recategorizationPersistenceService; + private final LegalBasisChangePersistenceService legalBasisChangePersistenceService; + private final IndexingService indexingService; + + + public JSONPrimitive upload(BinaryFileRequest request) { + + var dossier = dossierPersistenceService.getAndValidateDossier(request.getDossierId()); + + var fileId = generateFileId(request); + var existingStatus = retrieveStatus(dossier.getId(), fileId); + + if (existingStatus != null) { + if (existingStatus.getStatus().name().equals(Status.APPROVED.name())) { + throw new ConflictException("File already exists in status APPROVED"); + } + + if (existingStatus.getCurrentReviewer() != null && !request.getUploader() + .equalsIgnoreCase(existingStatus.getCurrentReviewer())) { + throw new ConflictException("Only the reviewer can overwrite a file"); + } + } + + try { + PdfTronOptimizeResponse optimized = pdfTronRedactionClient.optimize(new PdfTronOptimizeRequest(request.getData())); + // if successful update request with linearized PDF + request.setData(optimized.getDocument()); + } catch (Exception e) { + log.warn("Failed to optimize file: {}", request.getFilename(), e); + } + + fileManagementStorageService.storeObject(request.getDossierId(), fileId, FileType.ORIGIN, request.getData()); + + if (existingStatus != null) { + // the file is already uploaded, just reanalyse it. + + fileStatusService.overwriteFile(request.getDossierId(), fileId, request.getUploader(), request.getFilename(), request + .getData().length); + } else { + // the file is new, should create a new status for it. + log.info("File {} has no status yet, creating one and setting to unprocessed.", request.getFilename()); + fileStatusService.createStatus(request.getDossierId(), fileId, request.getUploader(), request.getFilename(), request + .getData().length); + } + return new JSONPrimitive<>(fileId); + } + + + private File retrieveStatus(String dossierId, String fileId) { + + try { + return fileStatusService.getStatus(fileId); + } catch (FileNotFoundException e) { + // it's a new File. + return null; + } + } + + public void softDeleteFile(String dossierId, String fileId, OffsetDateTime softDeletedTime) { + + forceRedactionPersistenceService.findForceRedactions(fileId, false).forEach(annotation -> { + forceRedactionPersistenceService.softDelete(fileId, annotation.getId().getId(), softDeletedTime); + commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getId(), false).forEach(comment -> { + commentPersistenceService.softDelete(comment.getId(), softDeletedTime); + }); + }); + + removeRedactionPersistenceService.findRemoveRedactions(fileId, false).forEach(annotation -> { + removeRedactionPersistenceService.softDelete(fileId, annotation.getId().getId(), softDeletedTime); + commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getId(), false).forEach(comment -> { + commentPersistenceService.softDelete(comment.getId(), softDeletedTime); + }); + }); + + addRedactionPersistenceService.findAddRedactions(fileId, false).forEach(annotation -> { + addRedactionPersistenceService.softDelete(fileId, annotation.getId().getId(), softDeletedTime); + commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getId(), false).forEach(comment -> { + commentPersistenceService.softDelete(comment.getId(), softDeletedTime); + }); + }); + + recategorizationPersistenceService.findRecategorizations(fileId, false).forEach(recatigorization -> { + recategorizationPersistenceService.softDelete(fileId, recatigorization.getId().getId(), softDeletedTime); + commentPersistenceService.findCommentsByAnnotationId(fileId, recatigorization.getId().getId(), false).forEach(comment -> { + commentPersistenceService.softDelete(comment.getId(), softDeletedTime); + }); + }); + + legalBasisChangePersistenceService.findLegalBasisChanges(fileId, false).forEach(legalBasisChange -> { + legalBasisChangePersistenceService.softDelete(fileId, legalBasisChange.getId().getId(), softDeletedTime); + commentPersistenceService.findCommentsByAnnotationId(fileId, legalBasisChange.getId().getId(), false) + .forEach(comment -> { + commentPersistenceService.softDelete(comment.getId(), softDeletedTime); + }); + }); + + viewedPagesPersistenceService.deleteForFile(fileId); + indexingService.addToDeleteFromIndexQueue(dossierId, fileId, 2); + } + + public void hardDeleteFile(String dossierId, String fileId) { + Arrays.stream(FileType.values()).forEach(fileType -> + fileManagementStorageService.deleteObject(dossierId, fileId, fileType) + ); + + forceRedactionPersistenceService.findForceRedactions(fileId, true).forEach(annotation -> { + forceRedactionPersistenceService.hardDelete(fileId, annotation.getId().getId()); + commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getId(), true).forEach(comment -> { + commentPersistenceService.hardDelete(comment.getId()); + }); + }); + + removeRedactionPersistenceService.findRemoveRedactions(fileId, true).forEach(annotation -> { + removeRedactionPersistenceService.hardDelete(fileId, annotation.getId().getId()); + commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getId(), true).forEach(comment -> { + commentPersistenceService.hardDelete(comment.getId()); + }); + }); + + addRedactionPersistenceService.findAddRedactions(fileId, true).forEach(annotation -> { + addRedactionPersistenceService.hardDelete(fileId, annotation.getId().getId()); + commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getId(), true).forEach(comment -> { + commentPersistenceService.hardDelete(comment.getId()); + }); + }); + + recategorizationPersistenceService.findRecategorizations(fileId, true).forEach(recatigorization -> { + recategorizationPersistenceService.hardDelete(fileId, recatigorization.getId().getId()); + commentPersistenceService.findCommentsByAnnotationId(fileId, recatigorization.getId().getId(), true).forEach(comment -> { + commentPersistenceService.hardDelete(comment.getId()); + }); + }); + + } + + public void undeleteFile(String dossierTemplateId, String dossierId, String fileId, OffsetDateTime softDeletedTime) { + forceRedactionPersistenceService.findForceRedactions(fileId, true).forEach(annotation -> { + if (annotation.getSoftDeletedTime().equals(softDeletedTime) || annotation.getSoftDeletedTime().isAfter(softDeletedTime)) { + forceRedactionPersistenceService.undelete(fileId, annotation.getId().getId()); + commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getId(), true).forEach(comment -> { + if (comment.getSoftDeletedTime().equals(softDeletedTime) || comment.getSoftDeletedTime().isAfter(softDeletedTime)) { + commentPersistenceService.undelete(comment.getId()); + } + }); + } + }); + + removeRedactionPersistenceService.findRemoveRedactions(fileId, true).forEach(annotation -> { + if (annotation.getSoftDeletedTime().equals(softDeletedTime) || annotation.getSoftDeletedTime().isAfter(softDeletedTime)) { + removeRedactionPersistenceService.undelete(fileId, annotation.getId().getId()); + commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getId(), true).forEach(comment -> { + if (comment.getSoftDeletedTime().equals(softDeletedTime) || comment.getSoftDeletedTime().isAfter(softDeletedTime)) { + commentPersistenceService.undelete(comment.getId()); + } + }); + } + }); + + addRedactionPersistenceService.findAddRedactions(fileId, true).forEach(annotation -> { + if (annotation.getSoftDeletedTime().equals(softDeletedTime) || annotation.getSoftDeletedTime().isAfter(softDeletedTime)) { + addRedactionPersistenceService.undelete(fileId, annotation.getId().getId()); + commentPersistenceService.findCommentsByAnnotationId(fileId, annotation.getId().getId(), true).forEach(comment -> { + if (comment.getSoftDeletedTime().equals(softDeletedTime) || comment.getSoftDeletedTime().isAfter(softDeletedTime)) { + commentPersistenceService.undelete(comment.getId()); + } + }); + } + }); + + recategorizationPersistenceService.findRecategorizations(fileId, true).forEach(recatigorization -> { + if (recatigorization.getSoftDeletedTime().equals(softDeletedTime) || recatigorization.getSoftDeletedTime().isAfter(softDeletedTime)) { + recategorizationPersistenceService.undelete(fileId, recatigorization.getId().getId()); + commentPersistenceService.findCommentsByAnnotationId(fileId, recatigorization.getId().getId(), true).forEach(comment -> { + if (comment.getSoftDeletedTime().equals(softDeletedTime) || comment.getSoftDeletedTime().isAfter(softDeletedTime)) { + commentPersistenceService.undelete(comment.getId()); + } + }); + } + }); + + indexingService.addToIndexingQueue(dossierTemplateId, dossierId, fileId, 2); + } + + private String generateFileId(BinaryFileRequest file) { + return hashFunction.hashBytes((file.getFilename() + file.getDossierId()).getBytes()).toString(); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/FileStatusProcessingUpdateService.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/FileStatusProcessingUpdateService.java new file mode 100644 index 000000000..2fec197ba --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/FileStatusProcessingUpdateService.java @@ -0,0 +1,105 @@ +package com.iqser.red.service.file.management.v1.server.service; + +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierPersistenceService; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.FileStatus; +import com.iqser.red.service.redaction.v1.model.AnalyzeResult; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.retry.support.RetryTemplate; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Objects; + +@Slf4j +@RestController +@RequiredArgsConstructor +public class FileStatusProcessingUpdateService { + + private final RetryTemplate retryTemplate; + private final FileStatusService fileStatusService; + private final IndexingService indexingService; + private final DossierPersistenceService dossierPersistenceService; + + + public void analysisSuccessful(String dossierId, String fileId, AnalyzeResult analyzeResult) { + + var dossier = dossierPersistenceService.getAndValidateDossier(dossierId); + var lastSuccessfulStatus = fileStatusService.getStatus(fileId).getLastSuccessfulStatus(); + + retryTemplate.execute(retryContext -> { + log.info("Analysis Successful for dossier {} and file {}, Attempt to update status: {}", dossierId, fileId, retryContext + .getRetryCount()); + fileStatusService.setStatusSuccessful(dossierId, fileId, Objects.requireNonNullElse(lastSuccessfulStatus, FileStatus.UNASSIGNED), analyzeResult); + return null; + }); + + if (!analyzeResult.isWasReanalyzed()) { + indexingService.addToIndexingQueue(dossier.getDossierTemplateId(), dossierId, fileId, 2); + } + + } + + + public void ocrSuccessful(String dossierId, String fileId) { + + retryTemplate.execute(retryContext -> { + log.info("OCR Successful for dossier {} and file {}, Attempt to update status: {}", dossierId, fileId, retryContext + .getRetryCount()); + + fileStatusService.updateLastOCRTime(fileId); + fileStatusService.setStatusFullReprocess(dossierId, fileId, 2); + + return null; + }); + } + + + public void analysisFailed(String dossierId, String fileId) { + + setStatusError(dossierId, fileId); + } + + + public void ocrFailed(String dossierId, String fileId) { + + setStatusError(dossierId, fileId); + } + + + private void setStatusError(String dossierId, String fileId) { + + retryTemplate.execute(retryContext -> { + log.warn("Retrying {} time to set ERROR status for file {} in dossier {}", retryContext.getRetryCount(), fileId, dossierId); + fileStatusService.setStatusError(fileId); + return null; + }); + } + + + public void indexing(String dossierId, String fileId) { + + retryTemplate.execute(retryContext -> { + log.info("Indexing dossier {} and file {}, Attempt to update status: {}", dossierId, fileId, retryContext.getRetryCount()); + fileStatusService.setStatusIndexing(fileId); + return null; + }); + } + + + public void indexingSuccessful(String dossierId, String fileId) { + + retryTemplate.execute(retryContext -> { + log.info("Indexing Successful for dossier {} and file {}, Attempt to update status: {}", dossierId, fileId, retryContext + .getRetryCount()); + fileStatusService.setStatusIndexingSuccessful(fileId); + return null; + }); + } + + + public void indexingFailed(String dossierId, String fileId) { + + setStatusError(dossierId, fileId); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/FileStatusService.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/FileStatusService.java new file mode 100644 index 000000000..06c8f5776 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/FileStatusService.java @@ -0,0 +1,274 @@ +package com.iqser.red.service.file.management.v1.server.service; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.Sets; +import com.iqser.red.service.file.management.v1.server.controller.RulesController; +import com.iqser.red.service.pdftron.redaction.v1.api.model.OcrRequestMessage; +import com.iqser.red.service.persistence.management.v1.processor.exception.UserNotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.FileStatus; +import com.iqser.red.service.redaction.v1.model.AnalyzeRequest; +import com.iqser.red.service.redaction.v1.model.AnalyzeResult; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.stereotype.Service; + +import java.time.OffsetDateTime; +import java.util.List; +import java.util.Set; + +import static com.iqser.red.service.file.management.v1.server.configuration.MessagingConfiguration.OCR_QUEUE; +import static com.iqser.red.service.file.management.v1.server.configuration.MessagingConfiguration.REDACTION_QUEUE; + +@Slf4j +@Service +@RequiredArgsConstructor +public class FileStatusService { + + private final FileStatusPersistenceService fileStatusPersistenceService; + private final DossierPersistenceService dossierPersistenceService; + private final RabbitTemplate rabbitTemplate; + private final ObjectMapper objectMapper; + private final RulesController rulesController; + private final ManualRedactionProviderService manualRedactionProviderService; + + + public List getDossierStatus(String dossierId) { + + return fileStatusPersistenceService.getStatusesForDossier(dossierId); + } + + + public File getStatus(String fileId) { + + return fileStatusPersistenceService.getStatus(fileId); + } + + + public void setExcludedPages(String fileId, Set excludedPages) { + + fileStatusPersistenceService.setExcludedPages(fileId, excludedPages); + } + + + public void setStatusProcessing(String fileId) { + + fileStatusPersistenceService.updateStatus(fileId, FileStatus.PROCESSING); + } + + + public void setStatusSuccessful(String dossierId, String fileId, FileStatus status, + AnalyzeResult analyzeResult) { + + fileStatusPersistenceService.updateStatusSuccessful(fileId, analyzeResult.getNumberOfPages(), status, + analyzeResult.isHasUpdates(), analyzeResult.getDictionaryVersion(), analyzeResult.getRulesVersion(), + analyzeResult.getLegalBasisVersion(), analyzeResult.getDuration(), analyzeResult.getDossierDictionaryVersion(), + analyzeResult.getAnalysisVersion()); + } + + + public void setStatusSuccessful(String fileId, FileStatus status) { + + fileStatusPersistenceService.updateStatusSuccessful(fileId, status, false); + } + + + public void setApprovalStatusSuccessful(String fileId, FileStatus status) { + + fileStatusPersistenceService.updateStatusSuccessful(fileId, status, true); + } + + + public void createStatus(String dossierId, String fileId, String uploader, String filename, int priority) { + + fileStatusPersistenceService.createStatus(dossierId, fileId, filename, uploader); + addToAnalysisQueue(dossierId, fileId, priority, Sets.newHashSet()); + } + + + public void setStatusReprocess(String dossierId, String fileId, int priority) { + setStatusReprocess(dossierId, fileId, priority, Sets.newHashSet()); + } + + public void setStatusReprocess(String dossierId, String fileId, int priority, Set sectionsToReanalyse) { + + log.info("Reprocessing file: {} from dossier {}", fileId, dossierId); + + File fileStatus = fileStatusPersistenceService.getStatus(fileId); + + if (fileStatus.isExcluded()) { + log.debug("File {} is excluded", fileStatus.getId()); + return; + } + + fileStatusPersistenceService.updateStatus(fileId, FileStatus.REPROCESS); + addToAnalysisQueue(dossierId, fileId, priority, sectionsToReanalyse); + } + + + public void setStatusOcrProcessing(String dossierId, String fileId) { + + File fileStatus = fileStatusPersistenceService.getStatus(fileId); + + if (fileStatus.isExcluded()) { + log.debug("File {} is excluded", fileId); + return; + } + + fileStatusPersistenceService.updateStatus(fileId, FileStatus.OCR_PROCESSING); + addToOcrQueue(dossierId, fileId, 2); + } + + + public void setStatusFullReprocess(String dossierId, String fileId, int priority) { + + File fileStatus = fileStatusPersistenceService.getStatus(fileId); + + if (fileStatus.isExcluded()) { + log.debug("File {} is excluded", fileStatus.getId()); + return; + } + + fileStatusPersistenceService.updateStatus(fileId, FileStatus.FULLREPROCESS); + addToAnalysisQueue(dossierId, fileId, priority, Sets.newHashSet()); + } + + public void setStatusIndexingSuccessful(String fileId) { + + File fileStatus = fileStatusPersistenceService.getStatus(fileId); + fileStatusPersistenceService.setUpdateStatusIndexingSuccessful(fileId, fileStatus.getLastSuccessfulStatus()); + } + + + public void setStatusIndexing(String fileId) { + + fileStatusPersistenceService.updateStatus(fileId, FileStatus.INDEXING); + } + + public void setStatusError(String fileId) { + + fileStatusPersistenceService.updateStatus(fileId, FileStatus.ERROR); + } + + + public void setFileStatusDeleted(String fileId, OffsetDateTime softDeletedTime) { + + fileStatusPersistenceService.softDelete(fileId, softDeletedTime); + } + + + public void setFileStatusHardDeleted(String fileId) { + + fileStatusPersistenceService.hardDelete(fileId); + } + + + public void setFileStatusUndeleted(String fileId) { + + var status = fileStatusPersistenceService.getStatus(fileId); + fileStatusPersistenceService.undelete(fileId, status.getLastSuccessfulStatus()); + } + + + public void setCurrentReviewer(String dossierId, String fileId, String currentReviewer) { + + if (StringUtils.isNotEmpty(currentReviewer) && !dossierPersistenceService.getAndValidateDossier(dossierId) + .getMemberIds() + .contains(currentReviewer)) { + throw new UserNotFoundException("User=" + currentReviewer + " must be member or owner of dossier=" + dossierId); + } + + File fileStatus = fileStatusPersistenceService.getStatus(fileId); + + fileStatusPersistenceService.setCurrentReviewer(fileId, currentReviewer, fileStatus.getCurrentReviewer()); + } + + + public void toggleExclusion(String fileId, boolean excluded) { + + fileStatusPersistenceService.toggleExclusion(fileId, excluded); + } + + + private void addToAnalysisQueue(String dossierId, String fileId, int priority, Set sectionsToReanalyse) { + + var dossier = dossierPersistenceService.getAndValidateDossier(dossierId); + var fileStatus = fileStatusPersistenceService.getStatus(fileId); + + if (fileStatus.isExcluded()) { + log.debug("File {} is excluded", fileStatus.getId()); + return; + } + + var fileAttributes = fileStatus.getFileAttributes(); + + setStatusProcessing(fileId); + + var analyseRequest = AnalyzeRequest.builder() + .dossierId(dossierId) + .sectionsToReanalyse(sectionsToReanalyse) + .fileId(fileId) + .manualRedactions(ManualRedactionsConverter.convert(manualRedactionProviderService.getManualRedactions(fileId))) + .dossierTemplateId(dossier.getDossierTemplateId()) + .lastProcessed(fileStatus.getLastProcessed()) + //TODO + // .fileAttributes(fileAttributes) + .build(); + + if (!fileStatus.getStatus().equals(FileStatus.UNPROCESSED) && !fileStatus.getStatus() + .equals(FileStatus.FULLREPROCESS) && fileStatus.getRulesVersion() == rulesController.getVersion(dossier.getDossierTemplateId()) && (fileStatus + .getLastFileAttributeChange() == null || fileStatus.getLastProcessed() + .isAfter(fileStatus.getLastFileAttributeChange()))) { + analyseRequest.setReanalyseOnlyIfPossible(true); + } else { + analyseRequest.setReanalyseOnlyIfPossible(false); + } + + analyseRequest.setExcludedPages(fileStatus.getExcludedPages()); + + try { + rabbitTemplate.convertAndSend(REDACTION_QUEUE, objectMapper.writeValueAsString(analyseRequest), message -> { + message.getMessageProperties().setPriority(priority); + return message; + }); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + + + private void addToOcrQueue(String dossierId, String fileId, int priority) { + + try { + rabbitTemplate.convertAndSend(OCR_QUEUE, objectMapper.writeValueAsString(new OcrRequestMessage(dossierId, fileId)), message -> { + message.getMessageProperties().setPriority(priority); + return message; + }); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + + + public void updateLastOCRTime(String fileId) { + + fileStatusPersistenceService.updateLastOCRTime(fileId, OffsetDateTime.now()); + } + + + public void overwriteFile(String dossierId, String fileId, String uploader, String filename, int length) { + + fileStatusPersistenceService.overwriteFile(fileId, uploader, filename); + setStatusFullReprocess(dossierId, fileId, length); + } + + public List getAllStatuses() { + + return fileStatusPersistenceService.getAllStatuses(); + } +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/IndexingService.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/IndexingService.java new file mode 100644 index 000000000..8eeceda8a --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/IndexingService.java @@ -0,0 +1,97 @@ +package com.iqser.red.service.file.management.v1.server.service; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.Dossier; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierStatus; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.FileStatus; +import com.iqser.red.service.search.v1.model.IndexMessage; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import static com.iqser.red.service.file.management.v1.server.configuration.MessagingConfiguration.DELETE_FROM_INDEX_QUEUE; +import static com.iqser.red.service.file.management.v1.server.configuration.MessagingConfiguration.INDEXING_QUEUE; + +@Service +@RequiredArgsConstructor +public class IndexingService { + + private final RabbitTemplate rabbitTemplate; + private final ObjectMapper objectMapper; + private final FileStatusService fileStatusService; + private final DossierService dossierService; + + + public void reindex(String dossierId, Set fileIds) { + + List> reindexDossierIds = new ArrayList<>(); + if (dossierId == null) { + List dossiers = dossierService.getAllDossiers(); + for (Dossier dossier : dossiers) { + if (dossier.getStatus().equals(DossierStatus.ACTIVE)) { + reindexDossierIds.add(new ImmutablePair<>(dossier.getDossierTemplateId(), dossier.getId())); + } + } + } else { + Dossier dossier = dossierService.getDossierById(dossierId); + if (dossier.getStatus().equals(DossierStatus.ACTIVE)) { + reindexDossierIds.add(new ImmutablePair<>(dossier.getDossierTemplateId(), dossier.getId())); + } + } + + for (Pair reindexDossierId : reindexDossierIds) { + List fileStatuses = fileStatusService.getDossierStatus(reindexDossierId.getRight()); + for (File fileStatus : fileStatuses) { + if (fileStatus.getStatus().equals(FileStatus.DELETED)) { + continue; + } + if (fileIds != null && !fileIds.isEmpty() && !fileIds.contains(fileStatus.getId())) { + continue; + } + addToIndexingQueue(reindexDossierId.getLeft(), reindexDossierId.getRight(), fileStatus.getId(), 2); + } + } + } + + + public void addToIndexingQueue(String dossierTemplateId, String dossierId, String fileId, int priority) { + + try { + rabbitTemplate.convertAndSend(INDEXING_QUEUE, objectMapper.writeValueAsString(IndexMessage.builder() + .dossierTemplateId(dossierTemplateId) + .dossierId(dossierId) + .fileId(fileId) + .build()), message -> { + message.getMessageProperties().setPriority(priority); + return message; + }); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + + + public void addToDeleteFromIndexQueue(String dossierId, String fileId, int priority) { + + try { + rabbitTemplate.convertAndSend(DELETE_FROM_INDEX_QUEUE, objectMapper.writeValueAsString(IndexMessage.builder() + .dossierId(dossierId) + .fileId(fileId) + .build()), message -> { + message.getMessageProperties().setPriority(priority); + return message; + }); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/LicenseReportService.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/LicenseReportService.java new file mode 100644 index 000000000..8555b78df --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/LicenseReportService.java @@ -0,0 +1,121 @@ +package com.iqser.red.service.file.management.v1.server.service; + +import static java.util.stream.Collectors.toList; + +import java.time.Instant; +import java.util.Comparator; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.Dossier; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.LoadingCache; +import com.iqser.red.service.persistence.service.v1.api.model.LicenseReport; +import com.iqser.red.service.persistence.service.v1.api.model.LicenseReportRequest; +import com.iqser.red.service.persistence.service.v1.api.model.ReportData; + +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.Value; + +@Service +@RequiredArgsConstructor +public class LicenseReportService { + + private final FileStatusService fileStatusService; + private final DossierService dossierService; + + private final LoadingCache cachedReports = Caffeine.newBuilder() + .maximumSize(1_000) + .expireAfterAccess(5, TimeUnit.MINUTES) + .build(this::loadReport); + + + public LicenseReport getLicenseReport(LicenseReportRequest licenseReportRequest, int offset, int limit) { + + if (StringUtils.isEmpty(licenseReportRequest.getRequestId())) { + licenseReportRequest.setRequestId(UUID.randomUUID().toString()); + } + CachedReportData cachedReportData = cachedReports.get(licenseReportRequest); + LicenseReport licenseReport = new LicenseReport(); + licenseReport.setNumberOfAnalyzedPages(cachedReportData.getTotalPagesAnalyzed()); + licenseReport.setNumberOfAnalyzedFiles(cachedReportData.getData().size()); + licenseReport.setNumberOfOcrFiles(cachedReportData.getData().stream().filter(reportData -> reportData.getNumberOfOcrPages() > 0).collect(toList()).size()); + licenseReport.setNumberOfOcrPages(cachedReportData.getTotalOcrPages()); + licenseReport.setNumberOfDossiers(cachedReportData.getNumberOfDossiers()); + licenseReport.setNumberOfAnalyses(cachedReportData.getTotalNumberOfAnalyses()); + licenseReport.setData(cachedReportData.getData().subList(offset, Math.min(offset + limit, cachedReportData.getData().size()))); + licenseReport.setOffset(offset); + licenseReport.setLimit(limit); + licenseReport.setStartDate(cachedReportData.getStartDate()); + licenseReport.setEndDate(cachedReportData.getEndDate()); + licenseReport.setRequestId(licenseReportRequest.getRequestId()); + + return licenseReport; + + } + + private CachedReportData loadReport(LicenseReportRequest licenseReportRequest) { + + List dossierIds = licenseReportRequest.getDossierIds(); + if (CollectionUtils.isEmpty(licenseReportRequest.getDossierIds())) { + dossierIds = dossierService.getAllDossiers().stream().map(Dossier::getId).collect(toList()); + } + + AtomicInteger totalPagesAnalyzed = new AtomicInteger(); + AtomicInteger totalPagesOcr = new AtomicInteger(); + AtomicInteger totalNumberOfAnalyses = new AtomicInteger(); + List data = dossierIds.stream() + .flatMap(dossierId -> fileStatusService.getDossierStatus(dossierId) + .stream() + .filter(fileStatus -> fileStatus.getAdded().toInstant().isAfter(licenseReportRequest.getStartDate()) + && fileStatus.getAdded().toInstant().isBefore(licenseReportRequest.getEndDate())) + .map(fileStatus -> { + ReportData reportData = new ReportData(); + reportData.setDossier(dossierId); + reportData.setFileName(fileStatus.getFilename()); + reportData.setAddedDate(fileStatus.getAdded().toInstant()); + reportData.setLastUpdatedDate(fileStatus.getLastUpdated() == null ? null : fileStatus.getLastUpdated().toInstant()); + reportData.setDeletedDate(fileStatus.getDeleted() == null ? null : fileStatus.getDeleted().toInstant()); + reportData.setStatus(fileStatus.getStatus()); + reportData.setNumberOfAnalyzedPages(fileStatus.getNumberOfPages()); + reportData.setNumberOfOcrPages(fileStatus.getLastOCRTime() != null ? fileStatus.getNumberOfPages() : 0); + reportData.setAnalysisCount(fileStatus.getNumberOfAnalyses()); + totalPagesAnalyzed.addAndGet(fileStatus.getNumberOfPages()); + totalPagesOcr.addAndGet(fileStatus.getLastOCRTime() != null ? fileStatus.getNumberOfPages() : 0); + reportData.setStatus(fileStatus.getStatus()); + totalNumberOfAnalyses.addAndGet(fileStatus.getNumberOfAnalyses()); + return reportData; + })) + .sorted(Comparator.comparing(ReportData::getFileName)) + .collect(toList()); + + return new CachedReportData(data, + dossierIds.size(), + totalNumberOfAnalyses.get(), + totalPagesAnalyzed.get(), + totalPagesOcr.get(), + licenseReportRequest.getStartDate(), + licenseReportRequest.getEndDate()); + + } + +} + +@Value +class CachedReportData { + @NonNull + List data; + int numberOfDossiers; + int totalNumberOfAnalyses; + int totalPagesAnalyzed; + int totalOcrPages; + Instant startDate; + Instant endDate; +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/ManualRedactionProviderService.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/ManualRedactionProviderService.java new file mode 100644 index 000000000..479f3f96f --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/ManualRedactionProviderService.java @@ -0,0 +1,47 @@ +package com.iqser.red.service.file.management.v1.server.service; + +import com.iqser.red.service.persistence.service.v1.api.model.ManualRedactions; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.Comment; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ManualImageRecategorization; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ManualLegalBasisChange; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ManualRedactionEntry; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.IdRemoval; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ManualForceRedaction; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.*; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +@Service +@RequiredArgsConstructor +public class ManualRedactionProviderService { + + private final AddRedactionPersistenceService addRedactionPersistenceService; + private final RemoveRedactionPersistenceService removeRedactionPersistenceService; + private final ForceRedactionPersistenceService forceRedactionPersistenceService; + private final CommentPersistenceService commentPersistenceService; + private final ImageRecategorizationPersistenceService recategorizationPersistenceService; + private final LegalBasisChangePersistenceService legalBasisChangePersistenceService; + + public ManualRedactions getManualRedactions(String fileId) { + + Set entriesToAdd = addRedactionPersistenceService.findAddRedactions(fileId, false); + + Set removals = removeRedactionPersistenceService.findRemoveRedactions(fileId, false); + + Set forceRedactions = forceRedactionPersistenceService.findForceRedactions(fileId, false); + + Set recategorizations = recategorizationPersistenceService.findRecategorizations(fileId, false); + + Set legalBasisChanges = legalBasisChangePersistenceService.findLegalBasisChanges(fileId, false); + + Map> comments = commentPersistenceService.findCommentsByFileID(fileId, false); + + return new ManualRedactions(removals, entriesToAdd, forceRedactions, recategorizations, legalBasisChanges, comments); + } + + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/ManualRedactionService.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/ManualRedactionService.java new file mode 100644 index 000000000..f65b75303 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/ManualRedactionService.java @@ -0,0 +1,563 @@ +package com.iqser.red.service.file.management.v1.server.service; + +import com.google.common.hash.HashFunction; +import com.google.common.hash.Hashing; +import com.iqser.red.service.file.management.v1.server.controller.DictionaryController; +import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.*; +import com.iqser.red.service.persistence.service.v1.api.model.*; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.*; +import com.iqser.red.service.redaction.v1.model.RedactionLog; +import com.iqser.red.service.redaction.v1.model.RedactionLogEntry; +import feign.FeignException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; + +import java.nio.charset.StandardCharsets; +import java.time.OffsetDateTime; +import java.util.List; + + +@Slf4j +@Service +@RequiredArgsConstructor +public class ManualRedactionService { + + private final DossierPersistenceService dossierPersistenceService; + private final AddRedactionPersistenceService addRedactionPersistenceService; + private final RemoveRedactionPersistenceService removeRedactionPersistenceService; + private final ForceRedactionPersistenceService forceRedactionPersistenceService; + private final CommentPersistenceService commentPersistenceService; + private final FileStatusPersistenceService fileStatusPersistenceService; + private final DictionaryController dictionaryClient; + private final FileManagementStorageService fileManagementStorageService; + private final ImageRecategorizationPersistenceService recategorizationPersistenceService; + private final LegalBasisChangePersistenceService legalBasisChangePersistenceService; + private final FileStatusService fileStatusService; + private final ManualRedactionProviderService manualRedactionProviderService; + + private final HashFunction hashFunction = Hashing.murmur3_128(); + + + public ManualAddResponse addAddRedaction(String dossierId, String fileId, AddRedactionRequest addRedactionRequest) { + + var dossier = dossierPersistenceService.getAndValidateDossier(dossierId); + + if (addRedactionRequest.isAddToDictionary()) { + try { + dictionaryClient.getDictionaryForType(addRedactionRequest.getType()); + } catch (FeignException e) { + if (e.status() == 404) { + throw new BadRequestException("Invalid type: " + addRedactionRequest.getType()); + } + } + } + + String annotationId = hashFunction.hashString(fileId + addRedactionRequest, StandardCharsets.UTF_8) + .toString(); + OffsetDateTime now = OffsetDateTime.now(); + addRedactionPersistenceService.insert(fileId, annotationId, addRedactionRequest); + + String commentId = null; + if (addRedactionRequest.getComment() != null) { + + addComment(fileId, annotationId, addRedactionRequest.getComment(), addRedactionRequest.getUser()); + } + + handleAddToDictionary(fileId, annotationId, addRedactionRequest.getType(), addRedactionRequest.getValue(), addRedactionRequest + .getStatus(), addRedactionRequest.isAddToDictionary(), false, dossierId); + + if (addRedactionRequest.getStatus().equals(AnnotationStatus.REQUESTED)) { + fileStatusPersistenceService.setUpdateLastManualRedactionAndHasSuggestions(fileId, now, true); + } else { + fileStatusPersistenceService.updateLastManualRedaction(fileId, now); + } + + return ManualAddResponse.builder().annotationId(annotationId).commentId(commentId).build(); + } + + + public ManualAddResponse addRemoveRedaction(String dossierId, String fileId, + RemoveRedactionRequest removeRedactionRequest) { + + var dossier = dossierPersistenceService.getAndValidateDossier(dossierId); + + OffsetDateTime now = OffsetDateTime.now(); + removeRedactionPersistenceService.insert(fileId, removeRedactionRequest); + + String commentId = null; + if (removeRedactionRequest.getComment() != null) { + + addComment(fileId, removeRedactionRequest.getAnnotationId(), removeRedactionRequest.getComment(), removeRedactionRequest + .getUser()); + } + + handleRemoveFromDictionary(dossierId, fileId, removeRedactionRequest.getAnnotationId(), removeRedactionRequest.getStatus(), + removeRedactionRequest.isRemoveFromDictionary(), false); + + if (removeRedactionRequest.getStatus().equals(AnnotationStatus.REQUESTED)) { + fileStatusPersistenceService.setUpdateLastManualRedactionAndHasSuggestions(fileId, now, true); + } else { + fileStatusPersistenceService.updateLastManualRedaction(fileId, now); + } + + return ManualAddResponse.builder() + .annotationId(removeRedactionRequest.getAnnotationId()) + .commentId(commentId) + .build(); + } + + + public ManualAddResponse addForceRedaction(String dossierId, String fileId, + ForceRedactionRequest forceRedactionRequest) { + + dossierPersistenceService.getAndValidateDossier(dossierId); + + OffsetDateTime now = OffsetDateTime.now(); + forceRedactionPersistenceService.insert(fileId, forceRedactionRequest); + + String commentId = null; + if (forceRedactionRequest.getComment() != null) { + + addComment(fileId, forceRedactionRequest.getAnnotationId(), forceRedactionRequest.getComment(), forceRedactionRequest + .getUser()); + } + + if (forceRedactionRequest.getStatus().equals(AnnotationStatus.REQUESTED)) { + fileStatusPersistenceService.setUpdateLastManualRedactionAndHasSuggestions(fileId, now, true); + } else { + fileStatusPersistenceService.updateLastManualRedaction(fileId, now); + } + + return ManualAddResponse.builder() + .annotationId(forceRedactionRequest.getAnnotationId()) + .commentId(commentId) + .build(); + } + + + public ManualAddResponse addLegalBasisChange(String dossierId, String fileId, + LegalBasisChangeRequest legalBasisChangeRequest) { + + dossierPersistenceService.getAndValidateDossier(dossierId); + + OffsetDateTime now = OffsetDateTime.now(); + legalBasisChangePersistenceService.insert(fileId, legalBasisChangeRequest); + + String commentId = null; + if (legalBasisChangeRequest.getComment() != null) { + + addComment(fileId, legalBasisChangeRequest.getAnnotationId(), legalBasisChangeRequest.getComment(), legalBasisChangeRequest + .getUser()); + } + + if (legalBasisChangeRequest.getStatus().equals(AnnotationStatus.REQUESTED)) { + fileStatusPersistenceService.setUpdateLastManualRedactionAndHasSuggestions(fileId, now, true); + } else { + fileStatusPersistenceService.updateLastManualRedaction(fileId, now); + } + + return ManualAddResponse.builder() + .annotationId(legalBasisChangeRequest.getAnnotationId()) + .commentId(commentId) + .build(); + } + + + public ManualAddResponse addImageRecategorization(String dossierId, String fileId, + ImageRecategorizationRequest imageRecategorizationRequest) { + + dossierPersistenceService.getAndValidateDossier(dossierId); + + OffsetDateTime now = OffsetDateTime.now(); + recategorizationPersistenceService.insert(fileId, imageRecategorizationRequest); + + String commentId = null; + if (imageRecategorizationRequest.getComment() != null) { + + addComment(fileId, imageRecategorizationRequest.getAnnotationId(), imageRecategorizationRequest.getComment(), imageRecategorizationRequest + .getUser()); + } + + if (imageRecategorizationRequest.getStatus().equals(AnnotationStatus.REQUESTED)) { + fileStatusPersistenceService.setUpdateLastManualRedactionAndHasSuggestions(fileId, now, true); + } else { + fileStatusPersistenceService.updateLastManualRedaction(fileId, now); + fileStatusService.setStatusReprocess(dossierId, fileId, 100); + } + + return ManualAddResponse.builder() + .annotationId(imageRecategorizationRequest.getAnnotationId()) + .commentId(commentId) + .build(); + } + + + public Comment addComment(String fileId, String annotationId, CommentRequest commentRequest) { + + var createdComment = addComment(fileId, annotationId, commentRequest.getText(), commentRequest.getUser()); + + fileStatusPersistenceService.updateLastManualRedaction(fileId, OffsetDateTime.now()); + return createdComment; + } + + + public ManualRedactionEntry getAddRedaction(String fileId, String annotationId) { + + return addRedactionPersistenceService.findAddRedaction(fileId, annotationId); + } + + + public IdRemoval getRemoveRedaction(String fileId, String annotationId) { + + return removeRedactionPersistenceService.findRemoveRedaction(fileId, annotationId); + } + + + public ManualForceRedaction getForceRedaction(String fileId, String annotationId) { + + return forceRedactionPersistenceService.findForceRedaction(fileId, annotationId); + } + + + public ManualLegalBasisChange getLegalBasisChange(String fileId, String annotationId) { + + return legalBasisChangePersistenceService.findLegalBasisChange(fileId, annotationId); + } + + + public ManualImageRecategorization getImageRecategorization(String fileId, String annotationId) { + + return recategorizationPersistenceService.findRecategorization(fileId, annotationId); + } + + + public Comment getComment(long commentId) { + + return commentPersistenceService.findComment(commentId); + } + + + public void deleteAddRedaction(String dossierId, String fileId, String annotationId) { + + var addRedaction = getAddRedaction(fileId, annotationId); + var dossier = dossierPersistenceService.getAndValidateDossier(dossierId); + + handleAddToDictionary(fileId, annotationId, addRedaction.getTypeId(), addRedaction.getValue(), addRedaction.getStatus(), + addRedaction.isAddToDictionary(), true, dossier.getId()); + + addRedactionPersistenceService.softDelete(fileId, annotationId, OffsetDateTime.now()); + + if (addRedaction.getStatus().equals(AnnotationStatus.REQUESTED)) { + boolean hasSuggestions = calculateHasSuggestions(fileId); + fileStatusPersistenceService.setUpdateLastManualRedactionAndHasSuggestions(fileId, OffsetDateTime.now(), hasSuggestions); + } else { + fileStatusPersistenceService.updateLastManualRedaction(fileId); + } + } + + + public void deleteRemoveRedaction(String dossierId, String fileId, String annotationId) { + + var removeRedaction = getRemoveRedaction(fileId, annotationId); + var dossier = dossierPersistenceService.getAndValidateDossier(dossierId); + handleRemoveFromDictionary(dossierId, fileId, annotationId, removeRedaction.getStatus(), + removeRedaction.isRemoveFromDictionary(), true); + removeRedactionPersistenceService.softDelete(fileId, annotationId, OffsetDateTime.now()); + + if (removeRedaction.getStatus().equals(AnnotationStatus.REQUESTED)) { + boolean hasSuggestions = calculateHasSuggestions(fileId); + fileStatusPersistenceService.setUpdateLastManualRedactionAndHasSuggestions(fileId, OffsetDateTime.now(), hasSuggestions); + } else { + fileStatusPersistenceService.updateLastManualRedaction(fileId); + } + } + + + public void deleteForceRedaction(String dossierId, String fileId, String annotationId) { + + var forceRedaction = getForceRedaction(fileId, annotationId); + + forceRedactionPersistenceService.softDelete(fileId, annotationId, OffsetDateTime.now()); + + if (forceRedaction.getStatus().equals(AnnotationStatus.REQUESTED)) { + boolean hasSuggestions = calculateHasSuggestions(fileId); + fileStatusPersistenceService.setUpdateLastManualRedactionAndHasSuggestions(fileId, OffsetDateTime.now(), hasSuggestions); + } else { + fileStatusPersistenceService.updateLastManualRedaction(fileId); + } + } + + + public void deleteLegalBasisChange(String dossierId, String fileId, String annotationId) { + + var legalBasisChange = getLegalBasisChange(fileId, annotationId); + + legalBasisChangePersistenceService.softDelete(fileId, annotationId, OffsetDateTime.now()); + if (legalBasisChange.getStatus().equals(AnnotationStatus.REQUESTED)) { + boolean hasSuggestions = calculateHasSuggestions(fileId); + fileStatusPersistenceService.setUpdateLastManualRedactionAndHasSuggestions(fileId, OffsetDateTime.now(), hasSuggestions); + } else { + fileStatusPersistenceService.updateLastManualRedaction(fileId); + } + } + + + public void deleteImageRecategorization(String dossierId, String fileId, String annotationId) { + + var imageRecategorization = getImageRecategorization(fileId, annotationId); + + recategorizationPersistenceService.softDelete(fileId, annotationId, OffsetDateTime.now()); + + if (imageRecategorization.getStatus().equals(AnnotationStatus.REQUESTED)) { + boolean hasSuggestions = calculateHasSuggestions(fileId); + fileStatusPersistenceService.setUpdateLastManualRedactionAndHasSuggestions(fileId, OffsetDateTime.now(), hasSuggestions); + } else { + fileStatusPersistenceService.updateLastManualRedaction(fileId); + fileStatusService.setStatusReprocess(dossierId, fileId, 100); + } + } + + + public void deleteComment(String fileId, long commentId) { + + fileStatusPersistenceService.updateLastManualRedaction(fileId); + commentPersistenceService.softDelete(commentId, OffsetDateTime.now()); + + // update indicator + fileStatusPersistenceService.updateHasComments(fileId, commentPersistenceService.fileHasComments(fileId)); + } + + + @SuppressWarnings("PMD") + public void updateRemoveRedactionStatus(String dossierId, String fileId, String annotationId, AnnotationStatus annotationStatus) { + + var dossier = dossierPersistenceService.getAndValidateDossier(dossierId); + + IdRemoval idRemoval = removeRedactionPersistenceService.findRemoveRedaction(fileId, annotationId); + if (idRemoval.isRemoveFromDictionary()) { + + RedactionLog redactionLog = fileManagementStorageService.getRedactionLog(dossierId, fileId); + RedactionLogEntry redactionLogEntry = redactionLog.getRedactionLogEntry() + .stream() + .filter(entry -> entry.getId().equals(idRemoval.getId())) + .findFirst() + .get(); + + if (annotationStatus == AnnotationStatus.APPROVED) { + removeFromDictionary(redactionLogEntry.getType(), redactionLogEntry.getValue(), dossierId, fileId); + } else if (annotationStatus == AnnotationStatus.DECLINED) { + + // if it was previously approved, revert the delete + if (idRemoval.getStatus() == AnnotationStatus.APPROVED) { + addToDictionary(redactionLogEntry.getType(), redactionLogEntry.getValue(), dossierId, fileId); + } + } + } + + removeRedactionPersistenceService.updateStatus(fileId, annotationId, annotationStatus); + + boolean hasSuggestions = calculateHasSuggestions(fileId); + fileStatusPersistenceService.setUpdateLastManualRedactionAndHasSuggestions(fileId, OffsetDateTime.now(), hasSuggestions); + } + + + public void updateForceRedactionStatus(String dossierId, String fileId, String annotationId, AnnotationStatus annotationStatus) { + + dossierPersistenceService.getAndValidateDossier(dossierId); + forceRedactionPersistenceService.updateStatus(fileId, annotationId, annotationStatus); + boolean hasSuggestions = calculateHasSuggestions(fileId); + fileStatusPersistenceService.setUpdateLastManualRedactionAndHasSuggestions(fileId, OffsetDateTime.now(), hasSuggestions); + } + + + public void updateLegalBasisChangeStatus(String dossierId, String fileId, String annotationId, AnnotationStatus annotationStatus) { + + dossierPersistenceService.getAndValidateDossier(dossierId); + legalBasisChangePersistenceService.updateStatus(fileId, annotationId, annotationStatus); + boolean hasSuggestions = calculateHasSuggestions(fileId); + fileStatusPersistenceService.setUpdateLastManualRedactionAndHasSuggestions(fileId, OffsetDateTime.now(), hasSuggestions); + } + + + public void updateImageRecategorizationStatus(String dossierId, String fileId, String annotationId, + AnnotationStatus annotationStatus) { + + + if (annotationStatus.equals(AnnotationStatus.DECLINED)) { + + ManualImageRecategorization imageRecategorization = recategorizationPersistenceService.findRecategorization(fileId, annotationId); + // if it was previously approved, revert the delete + if (imageRecategorization.getStatus() == AnnotationStatus.APPROVED) { + fileStatusService.setStatusReprocess(dossierId, fileId, 100); + } + } else if (annotationStatus.equals(AnnotationStatus.APPROVED)) { + fileStatusService.setStatusReprocess(dossierId, fileId, 100); + } + + dossierPersistenceService.getAndValidateDossier(dossierId); + recategorizationPersistenceService.updateStatus(fileId, annotationId, annotationStatus); + boolean hasSuggestions = calculateHasSuggestions(fileId); + fileStatusPersistenceService.setUpdateLastManualRedactionAndHasSuggestions(fileId, OffsetDateTime.now(), hasSuggestions); + } + + + @SuppressWarnings("PMD") + public void updateAddRedactionStatus(String dossierId, String fileId, String annotationId, AnnotationStatus annotationStatus) { + + var dossier = dossierPersistenceService.getAndValidateDossier(dossierId); + + ManualRedactionEntry manualRedactionEntry = addRedactionPersistenceService.findAddRedaction(fileId, annotationId); + if (manualRedactionEntry.isAddToDictionary() || manualRedactionEntry.isAddToDossierDictionary()) { + if (annotationStatus == AnnotationStatus.APPROVED) { + addToDictionary(manualRedactionEntry.getTypeId(), manualRedactionEntry.getValue(), dossierId, fileId); + } else if (annotationStatus == AnnotationStatus.DECLINED) { + // if it was previously approved, revert the add + if (manualRedactionEntry.getStatus() == AnnotationStatus.APPROVED) { + removeFromDictionary(manualRedactionEntry.getTypeId(), manualRedactionEntry.getValue(), dossierId, fileId); + } + } + } + + addRedactionPersistenceService.updateStatus(fileId, annotationId, annotationStatus); + + boolean hasSuggestions = calculateHasSuggestions(fileId); + fileStatusPersistenceService.setUpdateLastManualRedactionAndHasSuggestions(fileId, OffsetDateTime.now(), hasSuggestions); + } + + + public ManualRedactions getManualRedactions(String fileId) { + + return manualRedactionProviderService.getManualRedactions(fileId); + } + + + private void handleAddToDictionary(String fileId, String annotationId, String typeId, String value, AnnotationStatus status, + boolean addToDictionary, boolean revert, String dossierId) { + + if (status == AnnotationStatus.APPROVED) { + addRedactionPersistenceService.updateStatus(fileId, annotationId, status, addToDictionary); + + if (addToDictionary) { + if (revert) { + removeFromDictionary(typeId, value, dossierId, fileId); + } else { + addToDictionary(typeId, value, dossierId, fileId); + } + } + + } + } + + + private void handleRemoveFromDictionary(String dossierId, String fileId, String annotationId, AnnotationStatus status, + boolean removeFromDictionary, boolean revert) { + + if (status == AnnotationStatus.APPROVED) { + + if (removeFromDictionary) { + RedactionLog redactionLog = fileManagementStorageService.getRedactionLog(dossierId, fileId); + RedactionLogEntry redactionLogEntry = redactionLog.getRedactionLogEntry() + .stream() + .filter(entry -> entry.getId().equals(annotationId)) + .findFirst() + .get(); + if (revert) { + addToDictionary(redactionLogEntry.getType(), redactionLogEntry.getValue(), dossierId, fileId); + } else { + removeFromDictionary(redactionLogEntry.getType(), redactionLogEntry.getValue(), dossierId, fileId); + } + } + removeRedactionPersistenceService.updateStatus(fileId, annotationId, status, removeFromDictionary); + } + } + + + private void addToDictionary(String typeId, String value, String dossierId, String fileId) { + + try { + log.debug("Adding entries for {} / {}", dossierId, fileId); + dictionaryClient.addEntries(typeId, List.of(value), false); + + fileStatusService.setStatusReprocess(dossierId, fileId, 100); + } catch (FeignException e) { + if (e.status() == HttpStatus.NOT_FOUND.value()) { + throw new BadRequestException(e.getMessage()); + } + throw e; + } + } + + + private void removeFromDictionary(String typeId, String value, String dossierId, String fileId) { + + try { + log.debug("Deleting entries for {} / {}", dossierId, fileId); + dictionaryClient.deleteEntries(typeId, List.of(value)); + fileStatusService.setStatusReprocess(dossierId, fileId, 100); + } catch (FeignException e) { + if (e.status() == HttpStatus.NOT_FOUND.value()) { + throw new BadRequestException(e.getMessage()); + } + throw e; + } + } + + + private Comment addComment(String fileId, String annotationId, String comment, String user) { + + + var createdComment = commentPersistenceService.insert(Comment.builder() + .text(comment) + .fileId(fileId) + .annotationId(annotationId) + .user(user) + .date(OffsetDateTime.now()) + .build()); + + fileStatusPersistenceService.updateHasComments(fileId, true); + + return createdComment; + } + + + private boolean calculateHasSuggestions(String fileId) { + + ManualRedactions manualRedactions = getManualRedactions(fileId); + + for (var manualRedaction : manualRedactions.getEntriesToAdd()) { + if (manualRedaction.getStatus().equals(AnnotationStatus.REQUESTED)) { + return true; + } + } + + for (var manualRedaction : manualRedactions.getIdsToRemove()) { + if (manualRedaction.getStatus().equals(AnnotationStatus.REQUESTED)) { + return true; + } + } + + for (var manualRedaction : manualRedactions.getForceRedactions()) { + if (manualRedaction.getStatus().equals(AnnotationStatus.REQUESTED)) { + return true; + } + } + + for (var manualRedaction : manualRedactions.getImageRecategorization()) { + if (manualRedaction.getStatus().equals(AnnotationStatus.REQUESTED)) { + return true; + } + } + + for (var manualRedaction : manualRedactions.getLegalBasisChanges()) { + if (manualRedaction.getStatus().equals(AnnotationStatus.REQUESTED)) { + return true; + } + } + + return false; + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/ManualRedactionsConverter.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/ManualRedactionsConverter.java new file mode 100644 index 000000000..90ba139d8 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/ManualRedactionsConverter.java @@ -0,0 +1,160 @@ +package com.iqser.red.service.file.management.v1.server.service; + +import com.iqser.red.service.persistence.service.v1.api.model.ManualRedactions; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.Comment; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ManualImageRecategorization; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ManualLegalBasisChange; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ManualRedactionEntry; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.IdRemoval; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ManualForceRedaction; +import com.iqser.red.service.redaction.v1.model.Point; +import com.iqser.red.service.redaction.v1.model.Rectangle; + +import javax.net.ssl.SSLEngineResult; +import java.util.*; +import java.util.stream.Collectors; + +public class ManualRedactionsConverter { + + //TODO Conversions + + public static com.iqser.red.service.redaction.v1.model.ManualRedactions convert(ManualRedactions manualRedactions) { + + return com.iqser.red.service.redaction.v1.model.ManualRedactions.builder() + .comments(convertComments(manualRedactions.getComments())) + .entriesToAdd(convertManualRedactionEntries(manualRedactions.getEntriesToAdd())) + .idsToRemove(convertRemovalIds(manualRedactions.getIdsToRemove())) + .forceRedacts(convertForceRedacts(manualRedactions.getForceRedactions())) + .manualLegalBasisChanges(convertLegalBasisChanges(manualRedactions.getLegalBasisChanges())) + .imageRecategorizations(convertImageRecategorizations(manualRedactions.getImageRecategorization())) + .build(); + } + + public static Map> convertComments(Map> comments) { + + Map> commentsMap = new HashMap<>(); + + comments.forEach((key, value) -> commentsMap.put(key, convertComment(value))); + + return commentsMap; + + } + + public static List convertComment(List comments) { + return comments.stream().map(comment -> com.iqser.red.service.redaction.v1.model.Comment.builder() + .id(String.valueOf(comment.getId())) + .user(comment.getUser()) + .date(comment.getDate()) + .text(comment.getText()) + .build()) + .collect(Collectors.toList()); + } + + + public static Set convertManualRedactionEntries( + Set manualRedactionEntries) { + + return manualRedactionEntries.stream() + .map(entry -> com.iqser.red.service.redaction.v1.model.ManualRedactionEntry.builder() + .id(entry.getId().getId()) + .user(entry.getUser()) + .type(entry.getTypeId()) + .value(entry.getValue()) + .reason(entry.getReason()) + .legalBasis(entry.getLegalBasis()) + .positions(convertRectangles(entry.getPositions())) + .processedDate(entry.getProcessedDate()) + .requestDate(entry.getRequestDate()) + .softDeletedTime(entry.getSoftDeletedTime()) + .status(com.iqser.red.service.redaction.v1.model.Status.valueOf(entry.getStatus().name())) + .addToDictionary(entry.isAddToDictionary()) + .build()) + .collect(Collectors.toSet()); + } + + private static List convertRectangles(List positions) { + List result = new ArrayList<>(); + + positions.forEach(p ->{ + var rectangle = new Rectangle(); + + rectangle.setPage(p.getPage()); + rectangle.setWidth(p.getWidth()); + rectangle.setHeight(p.getHeight()); + var point = new Point(); + point.setX(p.getTopLeftX()); + point.setY(p.getTopLeftY()); + rectangle.setTopLeft(point); + result.add(rectangle); + }); + return result; + } + + + public static Set convertRemovalIds(Set idsToRemove) { + + return idsToRemove.stream() + .map(idRemoval -> com.iqser.red.service.redaction.v1.model.IdRemoval.builder() + .id(idRemoval.getId().getId()) + .user(idRemoval.getUser()) + .status(com.iqser.red.service.redaction.v1.model.Status.valueOf(idRemoval.getStatus().name())) + .processedDate(idRemoval.getProcessedDate()) + .requestDate(idRemoval.getRequestDate()) + .softDeletedTime(idRemoval.getSoftDeletedTime()) + .removeFromDictionary(idRemoval.isRemoveFromDictionary()) + .build()) + .collect(Collectors.toSet()); + } + + + public static Set convertForceRedacts( + Set forceRedactions) { + + return forceRedactions.stream() + .map(forceRedact -> com.iqser.red.service.redaction.v1.model.ManualForceRedact.builder() + .id(forceRedact.getId().getId()) + .user(forceRedact.getUser()) + .status(com.iqser.red.service.redaction.v1.model.Status.valueOf(forceRedact.getStatus().name())) + .processedDate(forceRedact.getProcessedDate()) + .requestDate(forceRedact.getRequestDate()) + .softDeletedTime(forceRedact.getSoftDeletedTime()) + .legalBasis(forceRedact.getLegalBasis()) + .build()) + .collect(Collectors.toSet()); + } + + + public static Set convertLegalBasisChanges( + Set legalBasisChanges) { + + return legalBasisChanges.stream() + .map(legalBasisChange -> com.iqser.red.service.redaction.v1.model.ManualLegalBasisChange.builder() + .id(legalBasisChange.getId().getId()) + .user(legalBasisChange.getUser()) + .status(com.iqser.red.service.redaction.v1.model.Status.valueOf(legalBasisChange.getStatus().name())) + .processedDate(legalBasisChange.getProcessedDate()) + .requestDate(legalBasisChange.getRequestDate()) + .softDeletedTime(legalBasisChange.getSoftDeletedTime()) + .legalBasis(legalBasisChange.getLegalBasis()) + .build()) + .collect(Collectors.toSet()); + } + + + public static Set convertImageRecategorizations( + Set manualImageRecategorizations) { + + return manualImageRecategorizations.stream() + .map(recategorization -> com.iqser.red.service.redaction.v1.model.ManualImageRecategorization.builder() + .id(recategorization.getId().getId()) + .user(recategorization.getUser()) + .status(com.iqser.red.service.redaction.v1.model.Status.valueOf(recategorization.getStatus().name())) + .type(recategorization.getType()) + .processedDate(recategorization.getProcessedDate()) + .requestDate(recategorization.getRequestDate()) + .softDeletedTime(recategorization.getSoftDeletedTime()) + .build()) + .collect(Collectors.toSet()); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/RedactionLogService.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/RedactionLogService.java new file mode 100644 index 000000000..984441d7b --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/RedactionLogService.java @@ -0,0 +1,48 @@ +package com.iqser.red.service.file.management.v1.server.service; + +import org.springframework.stereotype.Service; + +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierPersistenceService; +import com.iqser.red.service.file.management.v1.server.client.RedactionClient; +import com.iqser.red.service.redaction.v1.model.RedactionLog; +import com.iqser.red.service.redaction.v1.model.RedactionRequest; +import com.iqser.red.service.redaction.v1.model.SectionGrid; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class RedactionLogService { + + private final FileManagementStorageService fileManagementStorageService; + private final ManualRedactionService manualRedactionService; + private final RedactionClient redactionClient; + private final DossierPersistenceService dossierPersistenceService; + private final FileStatusService fileStatusService; + + + public RedactionLog getRedactionLog(String dossierId, String fileId, boolean withManualRedactions) { + + if (withManualRedactions) { + var dossier = dossierPersistenceService.getAndValidateDossier(dossierId); + var convertedManualRedactions = ManualRedactionsConverter.convert(manualRedactionService.getManualRedactions(fileId)); + var fileStatus = fileStatusService.getStatus( fileId); + return redactionClient.getRedactionLog(RedactionRequest.builder() + .dossierId(dossierId) + .fileId(fileId) + .manualRedactions(convertedManualRedactions) + .dossierTemplateId(dossier.getDossierTemplateId()) + .excludedPages(fileStatus.getExcludedPages()) + .build()); + } else { + return fileManagementStorageService.getRedactionLog(dossierId, fileId); + } + } + + + public SectionGrid getSectionGrid(String dossierId, String fileId) { + + return fileManagementStorageService.getSectionGrid(dossierId, fileId); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadCleanupService.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadCleanupService.java new file mode 100644 index 000000000..5f3779c2e --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadCleanupService.java @@ -0,0 +1,73 @@ +package com.iqser.red.service.file.management.v1.server.service.download; + +import com.iqser.red.service.persistence.service.v1.api.model.data.download.DownloadStatus; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierStatus; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DownloadStatusPersistenceService; +import com.iqser.red.service.file.management.v1.server.service.DossierService; +import com.iqser.red.service.file.management.v1.server.settings.FileManagementServiceSettings; +import com.iqser.red.storage.commons.service.StorageService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +import java.time.OffsetDateTime; +import java.util.List; + +@Slf4j +@RequiredArgsConstructor +@Service +public class DownloadCleanupService { + + private final DownloadStatusPersistenceService downloadStatusPersistenceService; + private final StorageService storageService; + private final FileManagementServiceSettings settings; + private final DossierService dossierService; + + @Scheduled(fixedDelay = 300000, initialDelay = 300000) + public void processDocuments() { + + var now = OffsetDateTime.now(); + log.info("Checking for downloads to delete at {}", now); + List downloadStatusList = downloadStatusPersistenceService.getStatus(); + downloadStatusList.forEach(downloadStatus -> { + + var dossier = downloadStatus.getDossier(); + + if (downloadStatus.getLastDownload() != null && downloadStatus.getLastDownload() + .plusHours(settings.getDownloadCleanupDownloadFilesHours()) + .isBefore(now)) { + log.info("1. Deleting download status {} because DownloadCleanupDownloadFilesHours is {} and c+h {} is after {}", downloadStatus, settings + .getDownloadCleanupDownloadFilesHours(), downloadStatus.getCreationDate() + .plusHours(settings.getDownloadCleanupDownloadFilesHours()), now); + deleteDownload(downloadStatus); + } else if (downloadStatus.getLastDownload() == null && downloadStatus.getCreationDate() + .plusHours(settings.getDownloadCleanupNotDownloadFilesHours()) + .isBefore(now)) { + log.info("2. Deleting download status {} because DownloadCleanupNotDownloadFilesHours is {} and c+h {} is after {}", downloadStatus, settings + .getDownloadCleanupNotDownloadFilesHours(), downloadStatus.getCreationDate() + .plusHours(settings.getDownloadCleanupNotDownloadFilesHours()), now); + deleteDownload(downloadStatus); + } else if (dossierService.getDossierById(dossier.getId()).getStatus() == DossierStatus.DELETED) { + log.info("3. Deleting download {}, because dossier does not exist", downloadStatus.getStorageId()); + deleteDownload(downloadStatus); + } + }); + } + + + public void deleteDownload(DownloadStatus downloadStatus) { + + log.info("Deleting download status {}", downloadStatus); + try { + storageService.deleteObject(downloadStatus.getStorageId()); + } catch (Exception e) { + log.warn("Download could not be deleted: {}" + e.getMessage()); + } + try { + downloadStatusPersistenceService.deleteStatus(downloadStatus.getStorageId()); + } catch (Exception e) { + log.warn("DownloadStatus could not be deleted: {}" + e.getMessage()); + } + } +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadDLQMessageReceiver.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadDLQMessageReceiver.java new file mode 100644 index 000000000..6ccab4322 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadDLQMessageReceiver.java @@ -0,0 +1,69 @@ +package com.iqser.red.service.file.management.v1.server.service.download; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.iqser.red.service.file.management.v1.server.model.DownloadJob; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DownloadStatusPersistenceService; +import com.iqser.red.service.persistence.service.v1.api.model.data.download.DownloadStatus; +import com.iqser.red.service.redaction.report.v1.api.model.ReportRequestMessage; +import com.iqser.red.service.redaction.report.v1.api.model.ReportResultMessage; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.amqp.core.Message; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.retry.support.RetryTemplate; +import org.springframework.stereotype.Service; + +import java.io.IOException; + +import static com.iqser.red.service.file.management.v1.server.configuration.MessagingConfiguration.*; + +@Slf4j +@Service +@RequiredArgsConstructor +public class DownloadDLQMessageReceiver { + + private final DownloadStatusPersistenceService downloadStatusPersistenceService; + private final ObjectMapper objectMapper; + private final RetryTemplate retryTemplate; + + + @RabbitListener(queues = DOWNLOAD_DLQ) + public void handleDlqMessage(Message failedMessage) throws IOException { + + DownloadJob downloadJob = objectMapper.readValue(failedMessage.getBody(), DownloadJob.class); + log.warn("Handling download job in DLQ userId: {} storageId: {} - setting status to error!", downloadJob.getUserId(), downloadJob + .getStorageId()); + setDownloadFailed(downloadJob.getUserId(), downloadJob.getStorageId()); + } + + + @RabbitListener(queues = REPORT_DLQ) + public void handleReportDlqMessage(Message failedMessage) throws IOException { + + ReportRequestMessage reportRequestMessage = objectMapper.readValue(failedMessage.getBody(), ReportRequestMessage.class); + log.warn("Handling report request in DLQ userId: {} storageId: {} - setting status to error!", reportRequestMessage + .getUserId(), reportRequestMessage.getDownloadId()); + setDownloadFailed(reportRequestMessage.getUserId(), reportRequestMessage.getDownloadId()); + } + + + @RabbitListener(queues = REPORT_RESULT_DLQ) + public void handleReportResponseDlqMessage(Message failedMessage) throws IOException { + + ReportResultMessage reportResultMessage = objectMapper.readValue(failedMessage.getBody(), ReportResultMessage.class); + log.warn("Handling report request in DLQ userId: {} storageId: {} - setting status to error!", reportResultMessage + .getUserId(), reportResultMessage.getDownloadId()); + setDownloadFailed(reportResultMessage.getUserId(), reportResultMessage.getDownloadId()); + } + + + public void setDownloadFailed(String userId, String downloadId) { + + retryTemplate.execute(retryContext -> { + log.warn("Retrying {} time to set FAILED status for downloadJob userId: {} storageId: {}", retryContext.getRetryCount(), userId, downloadId); + downloadStatusPersistenceService.updateStatus(downloadId, DownloadStatus.DownloadStatusValue.FAILED); + return null; + }); + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadMessageReceiver.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadMessageReceiver.java new file mode 100644 index 000000000..a699cd700 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadMessageReceiver.java @@ -0,0 +1,79 @@ +package com.iqser.red.service.file.management.v1.server.service.download; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.iqser.red.service.file.management.v1.server.model.DownloadJob; +import com.iqser.red.service.file.management.v1.server.service.DossierService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DownloadStatusPersistenceService; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.ReportTemplate; +import com.iqser.red.service.persistence.service.v1.api.model.data.download.DownloadStatus; +import com.iqser.red.service.redaction.report.v1.api.model.ReportRequestMessage; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.amqp.rabbit.annotation.RabbitHandler; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.stereotype.Service; + +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +import static com.iqser.red.service.file.management.v1.server.configuration.MessagingConfiguration.DOWNLOAD_QUEUE; +import static com.iqser.red.service.file.management.v1.server.configuration.MessagingConfiguration.REPORT_QUEUE; + +@Slf4j +@Service +@RequiredArgsConstructor +@RabbitListener(queues = DOWNLOAD_QUEUE) +public class DownloadMessageReceiver { + + private final ObjectMapper objectMapper; + private final RabbitTemplate rabbitTemplate; + private final DownloadStatusPersistenceService downloadStatusPersistenceService; + private final DossierService dossierService; + + + @RabbitHandler + public void receive(String in) throws JsonProcessingException { + + DownloadJob downloadJob = objectMapper.readValue(in, DownloadJob.class); + log.info("Preparing download for userId: {} and storageId: {}", downloadJob.getUserId(), downloadJob.getStorageId()); + + DownloadStatus downloadStatus = downloadStatusPersistenceService.getStatus(downloadJob.getStorageId()); + downloadStatusPersistenceService.updateStatus(downloadJob.getStorageId(), DownloadStatus.DownloadStatusValue.GENERATING); + + var dossier = downloadStatus.getFiles().iterator().next().getDossier(); + + + List filenameSortedFileIds = downloadStatus.getFiles() + .stream() + .sorted(Comparator.comparing(File::getFilename)) + .map(File::getId) + .collect(Collectors.toList()); + + addReportQueue(ReportRequestMessage.builder() + .userId(downloadJob.getUserId()) + .downloadId(downloadJob.getStorageId()) + .dossierId(dossier.getId()) + .dossierTemplateId(dossierService.getDossierById(dossier.getId()).getDossierTemplateId()) + .fileIds(filenameSortedFileIds) + .templateIds(dossier.getReportTemplates().stream().map(ReportTemplate::getTemplateId).collect(Collectors.toSet())) + .build(), 1); + } + + + private void addReportQueue(ReportRequestMessage reportRequestMessage, int priority) { + + try { + rabbitTemplate.convertAndSend(REPORT_QUEUE, objectMapper.writeValueAsString(reportRequestMessage), message -> { + message.getMessageProperties().setPriority(priority); + return message; + }); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadPreparationService.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadPreparationService.java new file mode 100644 index 000000000..260c5e067 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadPreparationService.java @@ -0,0 +1,246 @@ +package com.iqser.red.service.file.management.v1.server.service.download; + +import com.iqser.red.service.file.management.v1.server.client.PDFTronRedactionClient; +import com.iqser.red.service.file.management.v1.server.client.RedactionClient; +import com.iqser.red.service.file.management.v1.server.service.FileManagementStorageService; +import com.iqser.red.service.file.management.v1.server.service.RedactionLogService; +import com.iqser.red.service.file.management.v1.server.utils.FileSystemBackedArchiver; +import com.iqser.red.service.pdftron.redaction.v1.api.model.PdfTronRedactionRequest; +import com.iqser.red.service.persistence.management.v1.processor.exception.FileNotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DownloadStatusPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.ReportTemplatePersistenceService; +import com.iqser.red.service.persistence.service.v1.api.model.FileType; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DownloadFileType; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.ReportTemplate; +import com.iqser.red.service.persistence.service.v1.api.model.data.download.DownloadStatus; +import com.iqser.red.service.redaction.report.v1.api.model.ReportResultMessage; +import com.iqser.red.service.redaction.report.v1.api.model.ReportType; +import com.iqser.red.service.redaction.report.v1.api.model.StoredFileInformation; +import com.iqser.red.service.redaction.v1.model.AnnotateRequest; +import com.iqser.red.service.redaction.v1.model.RedactionLog; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class DownloadPreparationService { + + private final DownloadStatusPersistenceService downloadStatusPersistenceService; + private final FileStatusPersistenceService fileStatusPersistenceService; + private final FileManagementStorageService fileManagementStorageService; + private final RedactionClient redactionClient; + private final PDFTronRedactionClient pdfTronRedactionClient; + private final ReportTemplatePersistenceService reportTemplatePersistenceService; + private final DossierPersistenceService dossierPersistenceService; + private final RedactionLogService redactionLogService; + + + public void createDownload(ReportResultMessage reportResultMessage) { + + DownloadStatus downloadStatus = downloadStatusPersistenceService.getStatus(reportResultMessage.getDownloadId()); + var dossier = downloadStatus.getDossier(); + + try (FileSystemBackedArchiver fileSystemBackedArchiver = new FileSystemBackedArchiver()) { + + generateAndAddFiles(downloadStatus, fileSystemBackedArchiver, dossier.isWatermarkEnabled()); + addReports(reportResultMessage, downloadStatus, fileSystemBackedArchiver, dossier.getDossierTemplateId()); + storeZipFile(downloadStatus, fileSystemBackedArchiver); + + downloadStatusPersistenceService.updateStatus(downloadStatus.getStorageId(), DownloadStatus.DownloadStatusValue.READY, fileSystemBackedArchiver + .getContentLength()); + } + } + + + private void generateAndAddFiles(DownloadStatus downloadStatus, FileSystemBackedArchiver fileSystemBackedArchiver, + boolean watermarkEnabled) { + + var dossier = downloadStatus.getDossier(); + + int i = 1; + long fileGenerationStart = System.currentTimeMillis(); + for (File fileStatus : downloadStatus.getFiles()) { + + var fileId = fileStatus.getId(); + long start = System.currentTimeMillis(); + byte[] original = fileManagementStorageService.getStoredObjectBytes(dossier.getId(), fileId, FileType.ORIGIN); + + RedactionLog redactionLog = getRedactionLog(dossier.getId(), fileId, fileStatus.isExcluded()); + + + for (DownloadFileType downloadFileType : downloadStatus.getDownloadFileTypes()) { + + if (downloadFileType.name().equals(DownloadFileType.ORIGINAL.name())) { + fileSystemBackedArchiver.addEntry(new FileSystemBackedArchiver.ArchiveModel("Original", fileStatus.getFilename(), original)); + } + if (downloadFileType.name().equals(DownloadFileType.ANNOTATED.name())) { + fileSystemBackedArchiver.addEntry(new FileSystemBackedArchiver.ArchiveModel("Annotated", addSuffix(fileStatus + .getFilename(), "annotated"), getAnnotated(dossier.getDossierTemplateId(), dossier.getId(), fileId))); + } + if (downloadFileType.name().equals(DownloadFileType.PREVIEW.name())) { + fileSystemBackedArchiver.addEntry(new FileSystemBackedArchiver.ArchiveModel("Preview", addSuffix(fileStatus + .getFilename(), "highlighted"), getPreview(original, redactionLog, dossier.getDossierTemplateId()))); + } + if (downloadFileType.name().equals(DownloadFileType.REDACTED.name())) { + fileSystemBackedArchiver.addEntry(new FileSystemBackedArchiver.ArchiveModel("Redacted", addSuffix(fileStatus + .getFilename(), "redacted"), getRedacted(original, redactionLog, dossier.getDossierTemplateId(), watermarkEnabled))); + } + } + log.info("Successfully added file {}/{} for downloadId {}, took {}", i, downloadStatus.getFiles() + .size(), downloadStatus.getStorageId(), System.currentTimeMillis() - start); + i++; + } + log.info("Successfully added {} files for downloadId {}, took {}", i, downloadStatus.getStorageId(), System.currentTimeMillis() - fileGenerationStart); + } + + + private void addReports(ReportResultMessage reportResultMessage, DownloadStatus downloadStatus, + FileSystemBackedArchiver fileSystemBackedArchiver, String dossierTemplateId) { + + long addReportsStart = System.currentTimeMillis(); + for (StoredFileInformation storedFileInformation : reportResultMessage.getStoredFileInformation()) { + + if (storedFileInformation.getReportType().equals(ReportType.EXCEL_MULTI_FILE)) { + byte[] report = fileManagementStorageService.getStoredObjectBytes(storedFileInformation.getStorageId()); + fileSystemBackedArchiver.addEntry(new FileSystemBackedArchiver.ArchiveModel("Excel Reports", "MultiFileReport.xlsx", report)); + continue; + } + + if (storedFileInformation.getReportType().equals(ReportType.EXCEL_TEMPLATE_MULTI_FILE)) { + ReportTemplate reportTemplate = reportTemplatePersistenceService.find(storedFileInformation.getTemplateId()); + byte[] report = fileManagementStorageService.getStoredObjectBytes(storedFileInformation.getStorageId()); + fileSystemBackedArchiver.addEntry(new FileSystemBackedArchiver.ArchiveModel(removeExtension(reportTemplate + .getFileName()) + " (multifile)", reportTemplate.getFileName(), report)); + continue; + } + + var fileStatus = fileStatusPersistenceService.getStatus(storedFileInformation.getFileId()); + + if (storedFileInformation.getReportType().equals(ReportType.EXCEL_SINGLE_FILE)) { + byte[] report = fileManagementStorageService.getStoredObjectBytes(storedFileInformation.getStorageId()); + fileSystemBackedArchiver.addEntry(new FileSystemBackedArchiver.ArchiveModel("Excel Reports", toXlsxFilename(fileStatus + .getFilename()), report)); + } + + if (storedFileInformation.getReportType().equals(ReportType.WORD_SINGLE_FILE_APPENDIX_A1_TEMPLATE)) { + byte[] report = fileManagementStorageService.getStoredObjectBytes(storedFileInformation.getStorageId()); + fileSystemBackedArchiver.addEntry(new FileSystemBackedArchiver.ArchiveModel("Justification Appendix A1", toDocxFilename(addSuffix(fileStatus + .getFilename(), "justification")), report)); + } + + if (storedFileInformation.getReportType().equals(ReportType.WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE)) { + byte[] report = fileManagementStorageService.getStoredObjectBytes(storedFileInformation.getStorageId()); + fileSystemBackedArchiver.addEntry(new FileSystemBackedArchiver.ArchiveModel("Justification Appendix A2", toDocxFilename(addSuffix(fileStatus + .getFilename(), "justification")), report)); + } + + if (storedFileInformation.getReportType().equals(ReportType.WORD_SINGLE_FILE)) { + ReportTemplate reportTemplate = reportTemplatePersistenceService.find(storedFileInformation.getTemplateId()); + byte[] report = fileManagementStorageService.getStoredObjectBytes(storedFileInformation.getStorageId()); + fileSystemBackedArchiver.addEntry(new FileSystemBackedArchiver.ArchiveModel(removeExtension(reportTemplate + .getFileName()), toDocxFilename(fileStatus.getFilename()), report)); + } + + if (storedFileInformation.getReportType().equals(ReportType.EXCEL_TEMPLATE_SINGLE_FILE)) { + ReportTemplate reportTemplate = reportTemplatePersistenceService.find(storedFileInformation.getTemplateId()); + byte[] report = fileManagementStorageService.getStoredObjectBytes(storedFileInformation.getStorageId()); + fileSystemBackedArchiver.addEntry(new FileSystemBackedArchiver.ArchiveModel(removeExtension(reportTemplate + .getFileName()), toXlsxFilename(fileStatus.getFilename()), report)); + } + } + log.info("Successfully added {} reports for downloadId {}, took {}", reportResultMessage.getStoredFileInformation() + .size(), reportResultMessage.getDownloadId(), System.currentTimeMillis() - addReportsStart); + } + + + private void storeZipFile(DownloadStatus downloadStatus, FileSystemBackedArchiver fileSystemBackedArchiver) { + + long start = System.currentTimeMillis(); + fileManagementStorageService.storeObject(downloadStatus.getStorageId(), fileSystemBackedArchiver.toInputStream()); + log.info("Successfully stored zip for downloadId {}, took {}", downloadStatus.getStorageId(), System.currentTimeMillis() - start); + } + + + private byte[] getAnnotated(String dossierTemplateId, String dossierId, String fileId) { + + return redactionClient.annotate(AnnotateRequest.builder() + .fileId(fileId) + .dossierTemplateId(dossierTemplateId) + .dossierId(dossierId) + .build()).getDocument(); + } + + + private byte[] getRedacted(byte[] original, RedactionLog redactionLog, String dossierTemplateId, + boolean watermarkEnabled) { + + return pdfTronRedactionClient.redact(PdfTronRedactionRequest.builder() + .document(original) + .dossierTemplateId(dossierTemplateId) + .redactionLog(redactionLog) + .applyWatermark(watermarkEnabled) + .build()).getDocument(); + } + + + private byte[] getPreview(byte[] original, RedactionLog redactionLog, String dossierTemplateId) { + + return pdfTronRedactionClient.redactionPreview(PdfTronRedactionRequest.builder() + .document(original) + .dossierTemplateId(dossierTemplateId) + .redactionLog(redactionLog) + .build()).getDocument(); + } + + + private String toDocxFilename(String filename) { + + if (filename.toLowerCase().endsWith(".pdf")) { + return filename.substring(0, filename.length() - 3) + "docx"; + } else { + return filename + ".docx"; + } + } + + + private String toXlsxFilename(String filename) { + + if (filename.toLowerCase().endsWith(".pdf")) { + return filename.substring(0, filename.length() - 3) + "xlsx"; + } else { + return filename + ".xlsx"; + } + } + + + private String removeExtension(String filename) { + + return filename.substring(0, filename.length() - 5); + } + + + private String addSuffix(String filename, String suffix) { + + return filename.substring(0, filename.length() - 4) + "_" + suffix + ".pdf"; + } + + + private RedactionLog getRedactionLog(String dossierId, String fileId, boolean isExcluded) { + + if (isExcluded) { + return null; + } + try { + return redactionLogService.getRedactionLog(dossierId, fileId, true); + } catch (FileNotFoundException e) { + return null; + } + + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadReportCleanupService.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadReportCleanupService.java new file mode 100644 index 000000000..4a4240c1a --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadReportCleanupService.java @@ -0,0 +1,28 @@ +package com.iqser.red.service.file.management.v1.server.service.download; + +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import com.iqser.red.service.file.management.v1.server.service.FileManagementStorageService; +import com.iqser.red.service.redaction.report.v1.api.model.ReportResultMessage; +import com.iqser.red.service.redaction.report.v1.api.model.StoredFileInformation; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Service +@RequiredArgsConstructor +public class DownloadReportCleanupService { + + private final FileManagementStorageService fileManagementStorageService; + + @Async + public void deleteTmpReportFiles(ReportResultMessage reportResultMessage){ + + for(StoredFileInformation storedFileInformation : reportResultMessage.getStoredFileInformation()){ + fileManagementStorageService.deleteObject(storedFileInformation.getStorageId()); + log.info("Deleted tmp report file {}", storedFileInformation.getStorageId()); + } + } +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadReportMessageReceiver.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadReportMessageReceiver.java new file mode 100644 index 000000000..71df1fdd1 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/service/download/DownloadReportMessageReceiver.java @@ -0,0 +1,36 @@ +package com.iqser.red.service.file.management.v1.server.service.download; + +import static com.iqser.red.service.file.management.v1.server.configuration.MessagingConfiguration.REPORT_RESULT_QUEUE; + +import org.springframework.amqp.rabbit.annotation.RabbitHandler; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.stereotype.Service; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.iqser.red.service.redaction.report.v1.api.model.ReportResultMessage; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Service +@RequiredArgsConstructor +@RabbitListener(queues = REPORT_RESULT_QUEUE) +public class DownloadReportMessageReceiver { + + private final ObjectMapper objectMapper; + private final DownloadPreparationService downloadPreparationService; + private final DownloadReportCleanupService downloadReportCleanupService; + + + @RabbitHandler + public void receive(String in) throws JsonProcessingException { + + ReportResultMessage reportResultMessage = objectMapper.readValue(in, ReportResultMessage.class); + downloadPreparationService.createDownload(reportResultMessage); + downloadReportCleanupService.deleteTmpReportFiles(reportResultMessage); + log.info("Successfully prepared download {}", reportResultMessage.getDownloadId()); + } + +} \ No newline at end of file diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/settings/FileManagementServiceSettings.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/settings/FileManagementServiceSettings.java new file mode 100644 index 000000000..d6fffddb5 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/settings/FileManagementServiceSettings.java @@ -0,0 +1,23 @@ +package com.iqser.red.service.file.management.v1.server.settings; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +import com.iqser.red.service.persistence.management.v1.processor.settings.FileUploadSettings; + +import lombok.Data; + +@Data +@ConfigurationProperties("persistence-service") +public class FileManagementServiceSettings { + + private FileUploadSettings fileUploadSettings = new FileUploadSettings(); + + private int maxRetryInterval = 60000; + private int maxRetryAttempts = 20; + + private int downloadCleanupFetchLimit = 200; + private int downloadCleanupDownloadFilesHours = 8; + private int downloadCleanupNotDownloadFilesHours = 72; + + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/utils/FileSystemBackedArchiver.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/utils/FileSystemBackedArchiver.java new file mode 100644 index 000000000..6fea368f5 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/utils/FileSystemBackedArchiver.java @@ -0,0 +1,100 @@ +package com.iqser.red.service.file.management.v1.server.utils; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +@Slf4j +public class FileSystemBackedArchiver implements AutoCloseable { + + private Set createdFolders = new HashSet<>(); + private File tempFile; + private ZipOutputStream zipOutputStream; + + @SneakyThrows + public FileSystemBackedArchiver() { + tempFile = File.createTempFile("archive", ".zip"); + zipOutputStream = new ZipOutputStream(new FileOutputStream(tempFile)); + } + + public void addEntries(ArchiveModel... archives) { + addEntries(Arrays.asList(archives)); + + } + + public void addEntries(List archives) { + + archives.forEach(this::addEntry); + } + + @SneakyThrows + public InputStream toInputStream() { + try { + zipOutputStream.close(); + } catch (IOException e) { + log.debug(e.getMessage()); + } + return new BufferedInputStream(new FileInputStream(tempFile)); + } + + @SneakyThrows + public void addEntry(ArchiveModel archiveModel) { + // begin writing a new ZIP entry, positions the stream to the start of the entry data + if (archiveModel.getFolderName() != null && !createdFolders.contains(archiveModel.getFolderName())) { + ZipEntry folder = new ZipEntry(archiveModel.getFolderName() + File.separator); + zipOutputStream.putNextEntry(folder); + zipOutputStream.closeEntry(); + createdFolders.add(archiveModel.getFolderName()); + } + + String zipEntryName = archiveModel.getFolderName() != null ? archiveModel.getFolderName() + File.separator + archiveModel.getName() : archiveModel.getName(); + zipOutputStream.putNextEntry(new ZipEntry(zipEntryName)); + zipOutputStream.write(archiveModel.getBytes(), 0, archiveModel.getBytes().length); + zipOutputStream.closeEntry(); + zipOutputStream.flush(); + } + + + @Override + public void close() { + try { + tempFile.delete(); + zipOutputStream.close(); + } catch (Exception e) { + log.debug("Failed to close FileSystemBackedArchiver"); + } + } + + public long getContentLength() { + try { + zipOutputStream.close(); + } catch (IOException e) { + log.debug(e.getMessage()); + } + return tempFile.length(); + } + + @Data + @AllArgsConstructor + public static class ArchiveModel { + + private String folderName; + private String name; + private byte[] bytes; + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/utils/StorageIdUtils.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/utils/StorageIdUtils.java new file mode 100644 index 000000000..c1455c8f0 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/utils/StorageIdUtils.java @@ -0,0 +1,22 @@ +package com.iqser.red.service.file.management.v1.server.utils; + + +import com.iqser.red.service.persistence.service.v1.api.model.FileType; + +public class StorageIdUtils { + + public static String getStorageId(String dossierId, String fileId, FileType fileType) { + return dossierId + "/" + fileId + "." + fileType.name() + fileType.getExtension(); + } + + + public static String getStorageId(String userId, String dossierId, String filename) { + + return userId + "/" + dossierId + "/" + filename; + } + + public static String getReportStorageId(String dossierTemplateId, String fileName) { + return dossierTemplateId + "/" + fileName; + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/validation/DictionaryValidator.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/validation/DictionaryValidator.java new file mode 100644 index 000000000..5eff6ca0b --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/file/management/v1/server/validation/DictionaryValidator.java @@ -0,0 +1,82 @@ +package com.iqser.red.service.file.management.v1.server.validation; + +import lombok.experimental.UtilityClass; +import org.apache.commons.lang3.StringUtils; + +import java.awt.*; +import java.util.Optional; + +@UtilityClass +public class DictionaryValidator { + + public final String EMPTY_MSG = "%s is empty."; + public final String MIN_LENGTH_MSG = "%s should contain at least 2 letters."; + public final String COLOR_VALUE_MSG = "Invalid HEX color"; + public final String BOOLEAN_MSG = "Boolean value for %s not set."; + + + public Optional validateDictionaryType(String value) { + + return validateValue(value, ValueType.TYPE); + } + + + public Optional validateDictionaryEntry(String value) { + + return validateValue(value, ValueType.ENTRY); + } + + + private Optional validateValue(String value, ValueType valueType) { + + if (StringUtils.isBlank(value)) { + return Optional.of(String.format(EMPTY_MSG, valueType.name())); + } + + if (value.strip().length() < 2) { + return Optional.of(String.format(MIN_LENGTH_MSG, valueType.name())); + } + return Optional.empty(); + } + + + public Optional validateColor(String hexColor) { + + if (hexColor == null) { + return Optional.of(String.format(EMPTY_MSG, "color")); + } + + try { + Color.decode(hexColor); + } catch (NumberFormatException nfe) { + return Optional.of(COLOR_VALUE_MSG); + } + + return Optional.empty(); + + } + + + public Optional validateBoolean(Boolean bool, String name) { + + if (bool == null) { + return Optional.of(String.format(BOOLEAN_MSG, name)); + } + return Optional.empty(); + + } + + + enum ValueType { + TYPE("Dictionary type"), ENTRY("Dictionary entry"); + + public final String label; + + + ValueType(String label) { + + this.label = label; + } + } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/resources/application-dev.yml b/persistence-service-v1/persistence-service-server-v1/src/main/resources/application-dev.yml new file mode 100644 index 000000000..3cd231395 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/resources/application-dev.yml @@ -0,0 +1,19 @@ +server: + port: 8085 + +redaction-service.url: "http://localhost:8083" +configuration-service.url: "http://localhost:8081" +pdftron-redaction-service.url: "http://localhost:8086" +redaction-report-service.url: "http://localhost:8084" + +cassandra: + servers: 127.0.0.1 + role-name: cassandra + password: cassandra + + +storage: + bucket-name: 'redaction' + endpoint: 'http://localhost:9000' + key: minioadmin + secret: minioadmin \ No newline at end of file diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yml b/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yml new file mode 100644 index 000000000..2ae6b04bb --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yml @@ -0,0 +1,48 @@ +info: + description: File Management Service V1 Server + +redaction-service.url: "http://redaction-service-v1:8080" +configuration-service.url: "http://configuration-service-v1:8080" +pdftron-redaction-service.url: "http://pdftron-redaction-service-v1:8080" +redaction-report-service.url: "http://redaction-report-service-v1:8080" + +server: + port: 8080 + +spring: + profiles: + active: kubernetes + rabbitmq: + host: ${RABBITMQ_HOST:localhost} + port: ${RABBITMQ_PORT:5672} + username: ${RABBITMQ_USERNAME:user} + password: ${RABBITMQ_PASSWORD:rabbitmq} + listener: + simple: + acknowledge-mode: AUTO + concurrency: 5 + retry: + enabled: true + max-attempts: 3 + max-interval: 15000 + prefetch: 1 + +management: + endpoint: + metrics.enabled: ${monitoring.enabled:false} + prometheus.enabled: ${monitoring.enabled:false} + health.enabled: true + endpoints.web.exposure.include: prometheus, health + metrics.export.prometheus.enabled: ${monitoring.enabled:false} + + +cassandra: + keyspace-name: file_management_service + migrations-location: 'classpath:cassandra/migrations/*.cql' + + +storage: + signer-type: 'AWSS3V4SignerType' + bucket-name: 'redaction' + region: 'us-east-1' + endpoint: 'https://s3.amazonaws.com' \ No newline at end of file diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/resources/banner.txt b/persistence-service-v1/persistence-service-server-v1/src/main/resources/banner.txt new file mode 100644 index 000000000..3c16c1e17 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/resources/banner.txt @@ -0,0 +1,22 @@ +------------------------------------------------------------------ +| | +| File Management Service V1 Server | +| | + ________________________________________________________________ +| | +| ___ ________ ________ _________ _________ | +| | | / \ / || || \ | +| | | / ____ \ / _____|| _____||______ \ | +| | | / / \ \| / | | \ | | +| | || | | || \____ | |____ ______/ | | +| | || | | || \ | | | | | +| | || | ___| | \_____ || ____| | _ _/ | +| | || | \ \ | \ || | | | \ \ | +| | | \ \_ \ / ______/ || |_____ | | \ \ | +| | | \ \ \ \ | /| || | \ \ | +| |___| \____\ \___\|_________/ |_________||___| \___\ | +| | +| | +| F r o m d a t a t o i n f o r m a t i o n | +| | +|________________________________________________________________| \ No newline at end of file diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/resources/bootstrap.yml b/persistence-service-v1/persistence-service-server-v1/src/main/resources/bootstrap.yml new file mode 100644 index 000000000..2f53db3de --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/main/resources/bootstrap.yml @@ -0,0 +1,7 @@ +spring: + application: + name: file-management-service-v1 + +management.endpoints: + web.base-path: / + enabled-by-default: false \ No newline at end of file diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/controller/DossierControllerTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/controller/DossierControllerTest.java new file mode 100644 index 000000000..60064302e --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/controller/DossierControllerTest.java @@ -0,0 +1,91 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import org.junit.runner.RunWith; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@WebMvcTest(value = DossierController.class) +public class DossierControllerTest { +// +// private static final String SERVICE_PATH = "/" + SERVICE_NAME; +// +// @Autowired +// private ObjectMapper mapper; +// +// @Autowired +// private MockMvc mockMvc; +// +// @MockBean(name = "mainCassandraSession") +// private CassandraSession cassandraSession; +// +// @MockBean(name = "migrationCassandraSession") +// private CassandraSession migrationCassandraSession; +// +// @MockBean +// private Migrator migrator; +// +// @MockBean +// private FileStatusPersistenceService fileStatusPersistenceService; +// +// @MockBean +// private MessagingConfiguration messagingConfiguration; +// +// @MockBean +// private CleanupDownloadSchedulerConfiguration cleanupDownloadSchedulerConfiguration; +// +// @MockBean +// private DossierPersistenceService dossierPersistenceService; +// +// @MockBean +// private FileStatusService fileStatusService; +// +// @MockBean +// private DossierService dossierService; +// +// @MockBean +// private FileService fileService; +// +// @MockBean +// private ManualRedactionService manualRedactionService; +// +// @Test +// public void testAddDossier() throws Exception { +// +// String userId = "userId"; +// Set templateIds = new HashSet<>(Arrays.asList("templateId1", "templateId2", "templateId3")); +// DossierRequest dossierRequest = new DossierRequest("Dossier Name", +// "Dossier Description", +// userId, +// "123", +// Collections.singleton(userId), +// Collections.singleton(userId), +// Sets.newHashSet(), +// Sets.newHashSet(), +// OffsetDateTime.now(), +// templateIds, +// true); +// MockHttpServletRequestBuilder request = MockMvcRequestBuilders.post(SERVICE_PATH + REST_PATH) +// .content(mapper.writeValueAsString(dossierRequest)) +// .contentType(MediaType.APPLICATION_JSON) +// .servletPath(SERVICE_PATH); +// Dossier expected = Dossier.builder() +// .dossierName(dossierRequest.getDossierName()) +// .description(dossierRequest.getDescription()) +// .reportTemplateIds(templateIds) +// .build(); +// when(dossierService.addDossier(dossierRequest)).thenReturn(expected); +// ResultActions requestResult = mockMvc.perform(request); +// requestResult +// .andExpect(status().isOk()) +// .andExpect(content().contentType(MediaType.APPLICATION_JSON)) +// .andExpect(result -> { +// Dossier dossier = mapper.readValue(result.getResponse().getContentAsString(), Dossier.class); +// assertThat(dossier.getDescription()).isEqualTo(dossierRequest.getDescription()); +// assertThat(dossier.getDossierName()).isEqualTo(dossierRequest.getDossierName()); +// assertThat(dossier.getReportTemplateIds()).isEqualTo(dossierRequest.getReportTemplateIds()); +// }); +// +// } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/controller/FileStatusControllerTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/controller/FileStatusControllerTest.java new file mode 100644 index 000000000..c2991109d --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/controller/FileStatusControllerTest.java @@ -0,0 +1,109 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import org.junit.runner.RunWith; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@WebMvcTest(value = FileStatusController.class) +public class FileStatusControllerTest { +// +// private static final String SERVICE_PATH = "/" + SERVICE_NAME; +// +// @Autowired +// private ObjectMapper mapper; +// +// @Autowired +// private MockMvc mockMvc; +// +// @MockBean(name = "mainCassandraSession") +// private CassandraSession cassandraSession; +// +// @MockBean(name = "migrationCassandraSession") +// private CassandraSession migrationCassandraSession; +// +// @MockBean +// private Migrator migrator; +// +// @MockBean +// private FileStatusPersistenceService fileStatusPersistenceService; +// +// @MockBean +// private MessagingConfiguration messagingConfiguration; +// +// @MockBean +// private CleanupDownloadSchedulerConfiguration cleanupDownloadSchedulerConfiguration; +// +// @MockBean +// private DossierPersistenceService dossierPersistenceService; +// +// @MockBean +// private FileStatusService fileStatusService; +// +// @MockBean +// private DossierService dossierService; +// +// @Autowired +// private ObjectMapper objectMapper; +// +// @MockBean +// private ExcludeFromAnalysisService excludeFromAnalysisService; +// +// @Test +// public void testFileStatusResponse() throws Exception { +// +// MockHttpServletRequestBuilder request = MockMvcRequestBuilders.get(SERVICE_PATH + "/status/dossier") +// .servletPath(SERVICE_PATH); +// OffsetDateTime now = OffsetDateTime.now().withNano(0); +// File expected = File.builder() +// .dossierId("dossier") +// .fileId("file") +// .filename("filename") +// .status(Status.UNASSIGNED) +// .numberOfPages(100) +// .added(now) +// .lastUpdated(null) +// .deleted(null) +// .numberOfAnalyses(0) +// .currentReviewer(null) +// .build(); +// when(fileStatusService.getDossierStatus("dossier")).thenReturn(Collections.singletonList(expected)); +// ResultActions requestResult = mockMvc.perform(request); +// requestResult.andExpect(status().isOk()) +// .andExpect(content().contentType(MediaType.APPLICATION_JSON)) +// .andExpect(result -> { +// List dossierStatus = mapper.readValue(result.getResponse() +// .getContentAsString(), new TypeReference>() { +// }); +// assertThat(dossierStatus).containsOnly(expected); +// }); +// +// } +// +// +// @Test +// public void testFileStatus404() throws Exception { +// +// MockHttpServletRequestBuilder request = MockMvcRequestBuilders.get(SERVICE_PATH + STATUS_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, "p1", "f1") +// .servletPath(SERVICE_PATH); +// when(fileStatusService.getStatus("p1", "f1")).thenThrow(new FileNotFoundException(String.format(FILE_STATUS_NOT_FOUND_MESSAGE, +// "p1", "f1"))); +// ResultActions requestResult = mockMvc.perform(request); +// requestResult.andExpect(status().isNotFound()); +// +// } +// +// +// @Test +// public void testSetCurrentReviewer() throws Exception { +// +// MockHttpServletRequestBuilder request = MockMvcRequestBuilders.post(SERVICE_PATH + STATUS_PATH + "/reviewer" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, "p1", "f1") +// .content(objectMapper.writeValueAsString(new CurrentFileReviewerRequest("asass"))) +// .contentType(MediaType.APPLICATION_JSON) +// .servletPath(SERVICE_PATH); +// ResultActions requestResult = mockMvc.perform(request); +// requestResult.andExpect(status().isOk()); +// +// } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/controller/LicenseReportControllerTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/controller/LicenseReportControllerTest.java new file mode 100644 index 000000000..2220fe972 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/controller/LicenseReportControllerTest.java @@ -0,0 +1,63 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import org.junit.runner.RunWith; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@WebMvcTest(value = LicenseReportController.class) +public class LicenseReportControllerTest { + +// private static final String SERVICE_PATH = "/" + SERVICE_NAME; +// +// @Autowired +// private MockMvc mockMvc; +// +// @Autowired +// private ObjectMapper mapper; +// +// @MockBean +// private LicenseReportService licenseReportService; +// +// @MockBean(name = "mainCassandraSession") +// private CassandraSession cassandraSession; +// +// @MockBean(name = "migrationCassandraSession") +// private CassandraSession migrationCassandraSession; +// +// @MockBean +// private Migrator migrator; +// +// @MockBean +// private FileStatusService fileStatusService; +// +// @MockBean +// private CleanupDownloadSchedulerConfiguration cleanupDownloadSchedulerConfiguration; +// +// +// @Test +// public void testFileStatusResponse() throws Exception { +// +// LicenseReportRequest licenseReportRequest = new LicenseReportRequest(); +// String json = mapper.writeValueAsString(licenseReportRequest); +// MockHttpServletRequestBuilder request = MockMvcRequestBuilders.post(SERVICE_PATH + "/report/license") +// .param("offset", "0") +// .param("limit", "20") +// .content(json) +// .contentType(MediaType.APPLICATION_JSON) +// .servletPath(SERVICE_PATH); +// LicenseReport licenseReport = new LicenseReport(); +// licenseReport.setRequestId("Some Id!"); +// when(licenseReportService.getLicenseReport(mapper.readValue(json, LicenseReportRequest.class), 0, 20)).thenReturn(licenseReport); +// ResultActions requestResult = mockMvc.perform(request); +// requestResult.andExpect(status().isOk()) +// .andExpect(content().contentType(MediaType.APPLICATION_JSON)) +// .andExpect(result -> { +// LicenseReport actual = mapper.readValue(result.getResponse() +// .getContentAsString(), LicenseReport.class); +// assertThat(actual.getRequestId()).isEqualTo(licenseReport.getRequestId()); +// }); +// +// } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/controller/ReanalysisControllerTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/controller/ReanalysisControllerTest.java new file mode 100644 index 000000000..822a30904 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/controller/ReanalysisControllerTest.java @@ -0,0 +1,85 @@ +package com.iqser.red.service.file.management.v1.server.controller; + +import org.junit.runner.RunWith; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@WebMvcTest(value = ReanalysisController.class) +public class ReanalysisControllerTest { +// +// private static final String SERVICE_PATH = "/" + SERVICE_NAME; +// +// @Autowired +// private ObjectMapper mapper; +// +// @Autowired +// private MockMvc mockMvc; +// +// @MockBean +// private FileStatusService fileStatusService; +// +// @MockBean(name = "mainCassandraSession") +// private CassandraSession cassandraSession; +// +// @MockBean(name = "migrationCassandraSession") +// private CassandraSession migrationCassandraSession; +// +// @MockBean +// private Migrator migrator; +// +// @MockBean +// private CleanupDownloadSchedulerConfiguration cleanupDownloadSchedulerConfiguration; +// +// @MockBean +// private DossierPersistenceService dossierPersistenceService; +// +// @MockBean +// private RulesClient rulesClient; +// +// @MockBean +// private DictionaryClient dictionaryClient; +// +// @MockBean +// private FileManagementStorageService fileManagementStorageService; +// +// @MockBean +// private PDFTronRedactionClient pdfTronRedactionClient; +// +// @MockBean +// private RabbitTemplate rabbitTemplate; +// +// @MockBean +// private IndexingService indexingService; +// +// +// @Test +// public void testReanalysisController() throws Exception { +// +// String dossierId = "p1"; +// MockHttpServletRequestBuilder request = MockMvcRequestBuilders.post(SERVICE_PATH + REANALYZE_PATH + DOSSIER_ID_PATH_PARAM, dossierId) +// .servletPath(SERVICE_PATH); +// when(dossierPersistenceService.getAndValidateDossier(dossierId)).thenReturn(Dossier.builder() +// .dossierName("my dossier") +// .status(DossierStatus.ACTIVE) +// .build()); +// mockMvc.perform(request).andExpect(status().isNoContent()); +// String fileId = "f1"; +// request = MockMvcRequestBuilders.post(SERVICE_PATH + REANALYZE_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, dossierId, fileId) +// .content("[]") +// .contentType(MediaType.APPLICATION_JSON) +// .servletPath(SERVICE_PATH); +// when(fileStatusService.getDossierStatus(Mockito.any())).thenReturn(Lists.newArrayList(File.builder() +// .fileId(fileId) +// .status(Status.UNPROCESSED) +// .build())); +// mockMvc.perform(request).andExpect(status().isNoContent()); +// request = MockMvcRequestBuilders.post(SERVICE_PATH + REANALYZE_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, dossierId, fileId) +// .content("[]") +// .contentType(MediaType.APPLICATION_JSON) +// .servletPath(SERVICE_PATH); +// when(dossierPersistenceService.getAndValidateDossier(dossierId)).thenThrow(new DossierNotFoundException("Exception")); +// mockMvc.perform(request).andExpect(status().isNotFound()); +// } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/AbstractFileManagementServerServiceTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/AbstractFileManagementServerServiceTest.java new file mode 100644 index 000000000..f65678e23 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/AbstractFileManagementServerServiceTest.java @@ -0,0 +1,58 @@ +package com.iqser.red.service.file.management.v1.server.integration; + +import com.iqser.red.commons.persistence.cassandra.AbstractCassandraTest; +import com.iqser.red.service.file.management.v1.server.Application; +import com.iqser.red.service.file.management.v1.server.client.PDFTronRedactionClient; +import com.iqser.red.storage.commons.StorageAutoConfiguration; +import com.iqser.red.storage.commons.service.StorageService; +import org.junit.After; +import org.junit.runner.RunWith; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.*; +import org.springframework.test.context.junit4.SpringRunner; + + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@Import(AbstractFileManagementServerServiceTest.TestConfiguration.class) +public abstract class AbstractFileManagementServerServiceTest extends AbstractCassandraTest { +// +// @Autowired +// private StorageService storageService; +// +// @MockBean +// protected RabbitTemplate rabbitTemplate; +// +// @MockBean +// protected DossierAttributesConfigClient dossierAttributesConfigClient; +// +// @MockBean +// protected FileAttributesConfigClient fileAttributesConfigClient; +// +// @MockBean +// protected PDFTronRedactionClient pdfTronRedactionClient; +// +// +// @Configuration +// @EnableAutoConfiguration(exclude = {StorageAutoConfiguration.class, RabbitAutoConfiguration.class}) +// @ComponentScan("com.iqser.red.service.file.management.v1.server") +// public static class TestConfiguration { +// +// @Bean +// @Primary +// public StorageService inmemoryStorage() { +// return new FileSystemBackedStorageService(); +// } +// +// } +// +// @After +// public void cleanupStorage() { +// ((FileSystemBackedStorageService) this.storageService).clearStorage(); +// } +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/DossierAttributesTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/DossierAttributesTest.java new file mode 100644 index 000000000..3605e367b --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/DossierAttributesTest.java @@ -0,0 +1,147 @@ +package com.iqser.red.service.file.management.v1.server.integration; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.Dossier; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierAttribute; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierAttributePersistenceService; +import com.iqser.red.service.file.management.v1.server.controller.DossierAttributesController; +import com.iqser.red.service.file.management.v1.server.controller.DossierController; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierAttributeConfig; +import org.assertj.core.util.Sets; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +public class DossierAttributesTest extends AbstractFileManagementServerServiceTest { + +// +// @Autowired +// private DossierAttributesController dossierAttributesController; +// +// @Autowired +// private DossierAttributePersistenceService dossierAttributePersistenceService; +// +// @Autowired +// private DossierController dossierController; +// +// +// +// @Test +// public void testSetDossierAttributes() { +// DossierAttributesConfig dossierAttributesConfig = new DossierAttributesConfig(); +// +// DossierAttributeConfig dossierAttributeConfig = DossierAttributeConfig.builder().id("dossierAttributeId").label("label").editable(true).type(DossierAttributeConfig.DossierAttributeType.TEXT).placeholder("placeholder").build(); +// List dossierAttributesConfigList = new ArrayList<>(); +// dossierAttributesConfigList.add(dossierAttributeConfig); +// +// dossierAttributesConfig.setDossierAttributeConfigs(dossierAttributesConfigList); +// +// when(dossierAttributesConfigClient.getDossierAttributes("ruleSetId")).thenReturn(dossierAttributesConfig); +// +// Dossier project = dossierController.addDossier((new DossierRequest("p2", "pd1", "user", "ruleSetId", +// Collections.singleton("u1"), Collections.singleton("u1"), Sets.newHashSet(), Sets.newHashSet(), OffsetDateTime.now(), null, true))); +// +// DossierAttribute dossierAttribute = new DossierAttribute("dossierAttributeId", "dossierAttributeValue"); +// +// DossierAttributes dossierAttributes = new DossierAttributes(); +// dossierAttributes.setDossierAttributeList(Arrays.asList(dossierAttribute)); +// DossierAttributes attributes = dossierAttributesController.setDossierAttributes(project.getDossierId(), dossierAttributes); +// +// List dossierAttributeList = dossierAttributePersistenceService.getDossierAttributes(project.getDossierId()).getDossierAttributeList(); +// assertThat(dossierAttributeList.get(0).getDossierAttributeId()).isEqualTo("dossierAttributeId"); +// assertThat(dossierAttributeList.size()).isEqualTo(1); +// +// assertThat(attributes.getDossierAttributeList().get(0).getDossierAttributeId()).isEqualTo("dossierAttributeId"); +// assertThat(attributes.getDossierAttributeList().size()).isEqualTo(1); +// +// +// DossierAttributeConfig dossierAttributeConfig2 = DossierAttributeConfig.builder().id("dossierAttributeId2").label("label").editable(true).type(DossierAttributeConfig.DossierAttributeType.TEXT).placeholder("placeholder").build(); +// List dossierAttributesConfigList2 = new ArrayList<>(); +// dossierAttributesConfigList2.add(dossierAttributeConfig2); +// dossierAttributesConfig.setDossierAttributeConfigs(dossierAttributesConfigList2); +// when(dossierAttributesConfigClient.getDossierAttributes("ruleSetId")).thenReturn(dossierAttributesConfig); +// +// DossierAttribute dossierAttribute2 = new DossierAttribute("dossierAttributeId2", "dossierAttributeValue2"); +// DossierAttributes dossierAttributes2 = new DossierAttributes(); +// dossierAttributes2.setDossierAttributeList(Arrays.asList(dossierAttribute2)); +// DossierAttributes attributes2 = dossierAttributesController.setDossierAttributes(project.getDossierId(), dossierAttributes2); +// +// assertThat(attributes2.getDossierAttributeList().get(0).getDossierAttributeId()).isEqualTo("dossierAttributeId2"); +// assertThat(attributes2.getDossierAttributeList().size()).isEqualTo(1); +// +// +// } +// +// @Test +// public void testAddOrUpdateDossierAttribute() { +// DossierAttributesConfig dossierAttributesConfig = new DossierAttributesConfig(); +// +// DossierAttributeConfig dossierAttributeConfig = DossierAttributeConfig.builder().id("dossierAttributeId").label("label").editable(true).type(DossierAttributeConfig.DossierAttributeType.TEXT).placeholder("placeholder").build(); +// List dossierAttributesConfigList = new ArrayList<>(); +// dossierAttributesConfigList.add(dossierAttributeConfig); +// +// dossierAttributesConfig.setDossierAttributeConfigs(dossierAttributesConfigList); +// +// when(dossierAttributesConfigClient.getDossierAttributes("ruleSetId")).thenReturn(dossierAttributesConfig); +// +// Dossier project = dossierController.addDossier((new DossierRequest("p2", "pd1", "user", "ruleSetId", +// Collections.singleton("u1"), Collections.singleton("u1"), Sets.newHashSet(), Sets.newHashSet(), OffsetDateTime.now(), null, true))); +// +// DossierAttribute dossierAttribute = new DossierAttribute("dossierAttributeId", "dossierAttributeValue"); +// +// DossierAttributes dossierAttributes = dossierAttributesController.addOrUpdateDossierAttribute(project.getDossierId(), dossierAttribute); +// +// assertThat(dossierAttributes.getDossierAttributeList().get(0).getDossierAttributeId()).isEqualTo("dossierAttributeId"); +// assertThat(dossierAttributes.getDossierAttributeList().size()).isEqualTo(1); +// +// +// DossierAttributeConfig dossierAttributeConfigUpdate = DossierAttributeConfig.builder().id("dossierAttributeIdUpdate").label("label").editable(true).type(DossierAttributeConfig.DossierAttributeType.TEXT).placeholder("placeholder").build(); +// dossierAttributesConfigList.add(dossierAttributeConfigUpdate); +// +// dossierAttributesConfig.setDossierAttributeConfigs(dossierAttributesConfigList); +// +// when(dossierAttributesConfigClient.getDossierAttributes("ruleSetId")).thenReturn(dossierAttributesConfig); +// +// DossierAttribute dossierAttributeUpdate = new DossierAttribute("dossierAttributeIdUpdate", "dossierAttributeValueUpdate"); +// DossierAttributes dossierAttributesUpdate = dossierAttributesController.addOrUpdateDossierAttribute(project.getDossierId(), dossierAttributeUpdate); +// +// assertThat(dossierAttributesUpdate.getDossierAttributeList().get(1).getDossierAttributeId()).isEqualTo(dossierAttributeUpdate.getDossierAttributeId()); +// assertThat(dossierAttributesUpdate.getDossierAttributeList().get(1).getValue()).isEqualTo(dossierAttributeUpdate.getValue()); +// assertThat(dossierAttributesUpdate.getDossierAttributeList().size()).isEqualTo(2); +// } +// +// @Test +// public void deleteDossierAttributes() { +// DossierAttributesConfig dossierAttributesConfig = new DossierAttributesConfig(); +// +// DossierAttributeConfig dossierAttributeConfig = DossierAttributeConfig.builder().id("dossierAttributeId").label("label").editable(true).type(DossierAttributeConfig.DossierAttributeType.TEXT).placeholder("placeholder").build(); +// List dossierAttributesConfigList = new ArrayList<>(); +// dossierAttributesConfigList.add(dossierAttributeConfig); +// +// dossierAttributesConfig.setDossierAttributeConfigs(dossierAttributesConfigList); +// +// when(dossierAttributesConfigClient.getDossierAttributes("ruleSetId")).thenReturn(dossierAttributesConfig); +// +// Dossier project = dossierController.addDossier((new DossierRequest("p2", "pd1", "user", "ruleSetId", +// Collections.singleton("u1"), Collections.singleton("u1"), Sets.newHashSet(), Sets.newHashSet(), OffsetDateTime.now(), null, true))); +// +// DossierAttribute dossierAttribute = new DossierAttribute("dossierAttributeId", "dossierAttributeValue"); +// +// DossierAttributes dossierAttributes = new DossierAttributes(); +// dossierAttributes.setDossierAttributeList(Arrays.asList(dossierAttribute)); +// DossierAttributes attributes = dossierAttributesController.setDossierAttributes(project.getDossierId(), dossierAttributes); +// +// dossierAttributesController.deleteDossierAttribute(project.getDossierId(), dossierAttribute.getDossierAttributeId()); +// +// DossierAttributes attributes1 = dossierAttributesController.getDossierAttributes(project.getDossierId()); +// +// assertThat(attributes1.getDossierAttributeList()).isEmpty(); +// } +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/DossierDeleteTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/DossierDeleteTest.java new file mode 100644 index 000000000..9c25dc36a --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/DossierDeleteTest.java @@ -0,0 +1,232 @@ +package com.iqser.red.service.file.management.v1.server.integration; + +import com.amazonaws.services.s3.transfer.model.UploadResult; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.iqser.red.commons.persistence.cassandra.CassandraSession; +import com.iqser.red.service.persistence.service.v1.api.model.BinaryFileRequest; +import com.iqser.red.service.persistence.management.v1.processor.exception.DossierNotFoundException; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService; +import com.iqser.red.service.file.management.v1.server.controller.DossierController; +import com.iqser.red.service.file.management.v1.server.controller.UploadController; +import com.iqser.red.service.file.management.v1.server.service.FileStatusService; +import com.iqser.red.service.pdftron.redaction.v1.api.model.PdfTronOptimizeResponse; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.Dossier; +import org.assertj.core.util.Sets; +import org.hibernate.engine.spi.Status; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.time.OffsetDateTime; +import java.util.*; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +public class DossierDeleteTest extends AbstractFileManagementServerServiceTest { +// +// @Autowired +// private DossierController dossierController; +// +// @Autowired +// private UploadController uploadController; +// +// @Autowired +// private FileStatusPersistenceService fileStatusPersistenceService; +// +// @Autowired +// private FileStatusService fileStatusService; +// +// @Autowired +// private CassandraSession cassandraSession; +// +// @Autowired +// private ObjectMapper objectMapper; +// +// @Before +// public void before() { +// PdfTronOptimizeResponse response = new PdfTronOptimizeResponse(); +// response.setDocument(new byte[]{1, 2, 3, 4, 5}); +// when(pdfTronRedactionClient.optimize(any())).thenReturn(response); +// } +// +// @Test +// public void testUploadForDossierAndCleanup() { +// +// String u1 = "u1"; +// Set templateIds = new HashSet<>(Arrays.asList("templateId1", "templateId2")); +// Dossier dossier = dossierController.addDossier(new DossierRequest("p2", "pd1", u1, "123", Collections.singleton(u1), +// Collections.singleton(u1), +// Sets.newHashSet(), +// Sets.newHashSet(), +// OffsetDateTime +// .now(), +// templateIds, +// true)); +// UploadResult uploadResult = uploadController.upload(BinaryFileRequest.builder() +// .data(new byte[]{1, 2, 3, 4, 5}) +// .filename("f1") +// .dossierId(dossier.getDossierId()) +// .build()); +// +// assertThat(fileStatusService.getDossierStatus(dossier.getDossierId())).hasSize(1); +// assertThat(fileStatusPersistenceService.getStatus(dossier.getDossierId(), uploadResult.getFileId())).isNotNull(); +// +// dossierController.delete(dossier.getDossierId()); +// +// assertThat(fileStatusService.getDossierStatus(dossier.getDossierId())).hasSize(1); +// assertThat(Status.DELETED).isEqualTo(fileStatusService.getDossierStatus(dossier.getDossierId()) +// .get(0) +// .getStatus()); +// +// +// } +// +// @Test +// public void testRecreateDossier() { +// +// String u1 = "u1"; +// Set templateIds = new HashSet<>(Arrays.asList("templateId1", "templateId2")); +// +// Dossier dossier = dossierController.addDossier(new DossierRequest("p1", "pd1", u1, "123", +// Collections.singleton(u1), Collections.singleton(u1), Sets.newHashSet(), Sets.newHashSet(), OffsetDateTime +// .now(), templateIds, true)); +// +// dossierController.delete(dossier.getDossierId()); +// +// Dossier dossierRecreated = dossierController.addDossier(new DossierRequest("p1", "pd1", u1, "123", +// Collections.singleton(u1), Collections.singleton(u1), Sets.newHashSet(), Sets.newHashSet(), OffsetDateTime +// .now(), templateIds, true)); +// +// assertThat(dossierRecreated).isNotNull(); +// } +// +// @Test +// public void testGetSoftDeletedDossiers() { +// String u1 = "u1"; +// Set templateIds = new HashSet<>(Arrays.asList("templateId1", "templateId2")); +// +// Dossier dossier = dossierController.addDossier(new DossierRequest("p1", "pd1", u1, "123", +// Collections.singleton(u1), Collections.singleton(u1), Sets.newHashSet(), Sets.newHashSet(), OffsetDateTime +// .now(), templateIds, true)); +// +// String dossierId = dossier.getDossierId(); +// dossierController.delete(dossierId); +// +// assertThat(dossierController.getSoftDeletedDossiers().size()).isEqualTo(1); +// assertThat(dossierController.getSoftDeletedDossiers().get(0).getDossierName()).isEqualTo("p1"); +// assertThat(dossierController.getSoftDeletedDossiers().get(0).getDossierId()).isEqualTo(dossierId); +// +// } +// +// +// @Test +// public void testHardDeleteDossiers() { +// String u1 = "u1"; +// Set templateIds = new HashSet<>(Arrays.asList("templateId1", "templateId2")); +// Dossier dossier = dossierController.addDossier(new DossierRequest("p1", "pd1", u1, "123", +// Collections.singleton(u1), Collections.singleton(u1), Sets.newHashSet(), Sets.newHashSet(), OffsetDateTime +// .now(), templateIds, true)); +// +// String dossierId = dossier.getDossierId(); +// dossierController.delete(dossierId); +// +// +// String u2 = "u2"; +// Set templateIds2 = new HashSet<>(Arrays.asList("templateId3", "templateId4")); +// Dossier dossier2 = dossierController.addDossier(new DossierRequest("p2", "pd2", u2, "1234", +// Collections.singleton(u2), Collections.singleton(u2), Sets.newHashSet(), Sets.newHashSet(), OffsetDateTime +// .now(), templateIds2, true)); +// +// String dossierId2 = dossier2.getDossierId(); +// dossierController.delete(dossierId2); +// +// assertThat(dossierController.getSoftDeletedDossiers().size()).isEqualTo(2); +// +// Set dossierIdsToHardDelete = new HashSet<>(); +// dossierIdsToHardDelete.add(dossierId); +// dossierIdsToHardDelete.add(dossierId2); +// dossierController.hardDeleteDossiers(dossierIdsToHardDelete); +// +// assertThat(dossierController.getSoftDeletedDossiers().size()).isEqualTo(0); +// } +// +// @Test +// public void testUndeleteDossiers() { +// String u1 = "u1"; +// Set templateIds = new HashSet<>(Arrays.asList("templateId1", "templateId2")); +// Dossier dossier = dossierController.addDossier(new DossierRequest("p1", "pd1", u1, "123", +// Collections.singleton(u1), Collections.singleton(u1), Sets.newHashSet(), Sets.newHashSet(), OffsetDateTime +// .now(), templateIds, true)); +// +// String dossierId = dossier.getDossierId(); +// dossierController.delete(dossierId); +// +// +// String u2 = "u2"; +// Set templateIds2 = new HashSet<>(Arrays.asList("templateId3", "templateId4")); +// Dossier dossier2 = dossierController.addDossier(new DossierRequest("p2", "pd2", u2, "1234", +// Collections.singleton(u2), Collections.singleton(u2), Sets.newHashSet(), Sets.newHashSet(), OffsetDateTime +// .now(), templateIds2, true)); +// +// String dossierId2 = dossier2.getDossierId(); +// dossierController.delete(dossierId2); +// +// assertThat(dossierController.getSoftDeletedDossiers().size()).isEqualTo(2); +// +// Set dossierIdsToUndelete = new HashSet<>(); +// dossierIdsToUndelete.add(dossierId); +// dossierIdsToUndelete.add(dossierId2); +// dossierController.undeleteDossiers(dossierIdsToUndelete); +// +// assertThat(dossierController.getSoftDeletedDossiers().size()).isEqualTo(0); +// } +// +// +// @Test +// public void testSoftAndUndeleteFileAndDossier() throws InterruptedException { +// String u1 = "u1"; +// Set templateIds = new HashSet<>(Arrays.asList("templateId1", "templateId2")); +// Dossier dossier = dossierController.addDossier(new DossierRequest("p1", "pd1", u1, "123", +// Collections.singleton(u1), Collections.singleton(u1), Sets.newHashSet(), Sets.newHashSet(), OffsetDateTime +// .now(), templateIds, true)); +// +// +// FileStatusPersistenceService fileStatusPersistenceService = new FileStatusPersistenceService(cassandraSession, objectMapper); +// String dossierId = dossier.getDossierId(); +// String fileId = "fileId"; +// String fileId2 = "fileId2"; +// String fileId3 = "fileId3"; +// fileStatusPersistenceService.createStatus(dossierId, fileId, "filename", "uploader"); +// fileStatusPersistenceService.createStatus(dossierId, fileId2, "filename2", "uploader"); +// fileStatusPersistenceService.createStatus(dossierId, fileId3, "filename3", "uploader3"); +// +// OffsetDateTime now = OffsetDateTime.now().withNano(0); +// +// fileStatusPersistenceService.softDelete(dossierId, fileId, now); +// +// var fileStatus = fileStatusPersistenceService.getStatus(dossierId, fileId); +// +// Thread.sleep(1500); +// dossierController.delete(dossierId); +// +// assertThatThrownBy( () -> dossierController.getDossierById(dossierId)).isInstanceOf(DossierNotFoundException.class); +// +// List deletedDossiers = dossierController.getSoftDeletedDossiers(); +// +// assertThat(deletedDossiers.size()).isEqualTo(1); +// +// Set dossierSet = new HashSet<>(); +// dossierSet.add(dossierId); +// dossierController.undeleteDossiers(dossierSet); +// +// assertThat(dossierController.getSoftDeletedDossiers()).isEmpty(); +// assertThat(dossierController.getDossierById(dossierId)).isNotNull(); +// +// assertThat(fileStatusPersistenceService.getStatus(dossierId).size()).isEqualTo(3); +// assertThat(fileStatusPersistenceService.getStatus(dossierId, fileId).getStatus()).isEqualTo(Status.DELETED); +// +// } +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/ExcludeFromAnalysisTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/ExcludeFromAnalysisTest.java new file mode 100644 index 000000000..a2e3f71d5 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/ExcludeFromAnalysisTest.java @@ -0,0 +1,86 @@ +package com.iqser.red.service.file.management.v1.server.integration; + +import com.google.common.collect.Sets; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService; +import com.iqser.red.service.file.management.v1.server.controller.FileStatusController; +import com.iqser.red.service.file.management.v1.server.service.ExcludeFromAnalysisService; +import com.iqser.red.service.persistence.service.v1.api.model.CreateOrUpdateDossierRequest; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.Dossier; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.time.OffsetDateTime; +import java.util.List; +import java.util.Set; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +public class ExcludeFromAnalysisTest extends AbstractFileManagementServerServiceTest { + +// @Autowired +// private ExcludeFromAnalysisService excludeFromAnalysisService; +// +// @Autowired +// private FileStatusPersistenceService fileStatusPersistenceService; +// +// @Autowired +// private DossierPersistenceService dossierPersistenceService; +// +// @Autowired +// private FileStatusController fileStatusController; +// +// +// @Before +// public void before() { +// var dossier = CreateOrUpdateDossierRequest.builder() +// .dossierName("test") +// .date(OffsetDateTime.now()) +// .ownerId("123") +// .description("test") +// .dossierTemplateId("123") +// .memberIds(Sets.newHashSet("123")).build(); +// dossierPersistenceService.insert(dossier); +// +// } +// +// @Test +// public void testExclusion() { +// +// fileStatusPersistenceService.createStatus("1", "1", "test.pdf", "test"); +// fileStatusPersistenceService.setCurrentReviewer("1", "1", "test", "test"); +// fileStatusPersistenceService.updateStatus("1", "1", Status.UNDER_REVIEW); +// excludeFromAnalysisService.toggleExclusion("1", "1", true); +// +// var status = fileStatusPersistenceService.getStatus("1", "1"); +// assertThat(status.isExcluded()).isEqualTo(true); +// +// excludeFromAnalysisService.toggleExclusion("1", "1", false); +// status = fileStatusPersistenceService.getStatus("1", "1"); +// assertThat(status.isExcluded()).isEqualTo(false); +// assertThat(Status.PROCESSING).isEqualTo(status.getStatus()); +// } +// +// +// @Test +// public void testExcludePage() { +// +// fileStatusPersistenceService.createStatus("1", "1", "test.pdf", "test"); +// +// fileStatusController.excludePages("1", "1", PageExclusionRequest.builder().pageRanges(List.of( +// PageRange.builder().startPage(1).endPage(1).build() +// , PageRange.builder().startPage(3).endPage(7).build())).build()); +// +// +// var status = fileStatusPersistenceService.getStatus("1", "1"); +// assertThat(status.getExcludedPages()).isEqualTo(Set.of(1, 3, 4, 5, 6, 7)); +// +// fileStatusController.includePages("1", "1", PageExclusionRequest.builder().pageRanges(List.of( +// PageRange.builder().startPage(4).endPage(5).build() +// , PageRange.builder().startPage(19).endPage(19).build())).build()); +// status = fileStatusPersistenceService.getStatus("1", "1"); +// assertThat(status.getExcludedPages()).isEqualTo(Set.of(1, 3, 6, 7)); +// } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/FileAttributesTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/FileAttributesTest.java new file mode 100644 index 000000000..92d426738 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/FileAttributesTest.java @@ -0,0 +1,80 @@ +package com.iqser.red.service.file.management.v1.server.integration; + +public class FileAttributesTest extends AbstractFileManagementServerServiceTest { + +// @Autowired +// private FileAttributesController fileAttributesController; +// +// @Autowired +// private FileStatusPersistenceService fileStatusPersistenceService; +// +// @Autowired +// private DossierController dossierController; +// +// @Test +// public void testFileAttributes() throws IOException { +// +// FileAttributesConfig configuredFileAttributes = new FileAttributesConfig(); +// configuredFileAttributes.setDelimiter(","); +// configuredFileAttributes.setFilenameMappingColumnHeaderName("Path"); +// configuredFileAttributes.setFileAttributeConfigs((List.of( +// new FileAttributeConfig("RegulatoryUtilityId", "Regulatory Utility", "Regulatory Utility Label", true, false, FileAttributeConfig.FileAttributeType.TEXT, "placeholder"), +// new FileAttributeConfig("DataEvaluationRecordId", "Data Evaluation Record", "DataEvaluation Record Label", true, false, FileAttributeConfig.FileAttributeType.TEXT, "placeholder"), +// new FileAttributeConfig("RegulatoryReleasedId", "Regulatory Released", "Regulatory Released Label", true, false, FileAttributeConfig.FileAttributeType.TEXT, "placeholder")))); +// when(fileAttributesConfigClient.getFileAttributes("123")).thenReturn(configuredFileAttributes); +// +// Dossier dossier = dossierController.addDossier(new DossierRequest("p2", "pd1", "user", "123", Collections.singleton("u1"), +// Collections.singleton("u1"), +// Sets.newHashSet(), Sets.newHashSet(), OffsetDateTime.now(), null, true)); +// +// fileStatusPersistenceService.createStatus(dossier.getId(), "fileId1", "Lambda-cyhalothrin - EU AIR5 - Document A - Statement of the.pdf", "uploader"); +// fileStatusPersistenceService.createStatus(dossier.getId(), "fileId2", "Lambda-cyhalothrin - EU AIR5 - MCA Section 5 - Toxicology.pdf", "uploader"); +// fileStatusPersistenceService.createStatus(dossier.getId(), "fileId3", "Lambda-cyhalothrin - EU AIR5 - LCA Section 5 Reference List.pdf", "uploader"); +// fileStatusPersistenceService.createStatus(dossier.getId(), "fileId4", "Lambda-cyhalothrin - EU AIR5 - LCA Section 4 Reference List.pdf", "uploader"); +// +// ClassPathResource exportSummeryResource = new ClassPathResource("files/export_summary.csv"); +// +// ImportCsvRequest importCsvRequest = ImportCsvRequest.builder() +// .csvFile(IOUtils.toByteArray(exportSummeryResource.getInputStream())) +// .build(); +// +// ImportCsvResponse importCsvResponse = fileAttributesController.importCsv(dossier.getId(), importCsvRequest); +// +// assertThat(importCsvResponse.getAffectedFileIds().size()).isEqualTo(4); +// +// List dossierFileStatus = fileStatusPersistenceService.getStatus(dossier.getId()); +// +// dossierFileStatus.forEach(status -> { +// assertThat(status.getFileAttributes().getAttributeIdToValue().size()).isEqualTo(3); +// }); +// } +// +// +// @Test +// public void testSetFileAttributes() { +// +// FileAttributesConfig configuredFileAttributes = new FileAttributesConfig(); +// configuredFileAttributes.setDelimiter(","); +// configuredFileAttributes.setFilenameMappingColumnHeaderName("Path"); +// configuredFileAttributes.setFileAttributeConfigs((List.of(new FileAttributeConfig("RegulatoryUtilityId", "Regulatory Utility", "Regulatory Utility Label", true, false, FileAttributeConfig.FileAttributeType.TEXT, "placeholder"), +// new FileAttributeConfig("DataEvaluationRecordId", "DataEvaluation Record", "DataEvaluation Record Label", true, false, FileAttributeConfig.FileAttributeType.TEXT, "placeholder"), +// new FileAttributeConfig("RegulatoryReleasedId", "Regulatory Released", "Regulatory Released Label", true, false, FileAttributeConfig.FileAttributeType.TEXT, "placeholder")))); +// +// when(fileAttributesConfigClient.getFileAttributes("123")).thenReturn(configuredFileAttributes); +// +// Dossier dossier = dossierController.addDossier(new DossierRequest("p2", "pd1", "user", "123", +// Collections.singleton("u1"), Collections.singleton("u1"), Sets.newHashSet(), Sets.newHashSet(), OffsetDateTime.now(), null, true)); +// +// fileStatusPersistenceService.createStatus(dossier.getId(), "fileId1", "Lambda-cyhalothrin - EU AIR5 - Document A - Statement of the.pdf", "uploader"); +// +// Map attributeIdToValue = new HashMap<>(); +// attributeIdToValue.put("RegulatoryUtilityId", "Something"); +// com.iqser.red.service.file.management.v1.api.model.data.dossier.FileAttributes fileAttributes = new FileAttributes(attributeIdToValue); +// fileAttributesController.setFileAttributes(dossier.getId(), "fileId1", fileAttributes); +// +// File status = fileStatusPersistenceService.getStatus(dossier.getId(), "fileId1"); +// +// assertThat(status.getFileAttributes().getAttributeIdToValue().size()).isEqualTo(1); +// } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/FileSystemBackedStorageService.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/FileSystemBackedStorageService.java new file mode 100644 index 000000000..ac4d842cd --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/FileSystemBackedStorageService.java @@ -0,0 +1,61 @@ +package com.iqser.red.service.file.management.v1.server.integration; + +import com.iqser.red.storage.commons.exception.StorageObjectDoesNotExist; +import com.iqser.red.storage.commons.service.StorageService; +import lombok.SneakyThrows; +import org.apache.commons.io.IOUtils; +import org.springframework.core.io.InputStreamResource; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.HashMap; +import java.util.Map; + +public class FileSystemBackedStorageService extends StorageService { + + private final Map dataMap = new HashMap<>(); + + public FileSystemBackedStorageService() { + super(null, null); + } + + @SneakyThrows + @Override + public InputStreamResource getObject(String objectId) { + + var res = dataMap.get(objectId); + if (res == null) { + throw new StorageObjectDoesNotExist(new RuntimeException()); + } + return new InputStreamResource(new FileInputStream(res)); + + } + + @SneakyThrows + @Override + public void storeObject(String objectId, byte[] data) { + File tempFile = File.createTempFile("test", ".tmp"); + + IOUtils.write(data, new FileOutputStream(tempFile)); + + dataMap.put(objectId, tempFile); + } + + @SneakyThrows + @Override + public void deleteObject(String objectId) { + File file = dataMap.get(objectId); + if (file != null) { + file.delete(); + dataMap.remove(objectId); + } + } + + public void clearStorage() { + this.dataMap.forEach((k, v) -> { + v.delete(); + }); + this.dataMap.clear(); + } +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/ManualRedactionTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/ManualRedactionTest.java new file mode 100644 index 000000000..9fe6d987a --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/ManualRedactionTest.java @@ -0,0 +1,144 @@ +package com.iqser.red.service.file.management.v1.server.integration; + +import com.google.common.collect.Sets; +import com.iqser.red.service.file.management.v1.server.controller.ManualRedactionController; +import com.iqser.red.service.file.management.v1.server.service.FileService; +import com.iqser.red.service.file.management.v1.server.service.ManualRedactionService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService; +import com.iqser.red.service.persistence.service.v1.api.model.*; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.IdRemoval; +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ManualRedactionEntry; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.Dossier; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.File; +import com.iqser.red.service.redaction.v1.model.Point; +import com.iqser.red.service.redaction.v1.model.Rectangle; +import com.iqser.red.service.redaction.v1.model.Status; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.time.OffsetDateTime; +import java.util.List; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +public class ManualRedactionTest extends AbstractFileManagementServerServiceTest { + +// @Autowired +// private ManualRedactionController manualRedactionController; +// @Autowired +// private ManualRedactionService manualRedactionService; +// @Autowired +// private FileStatusPersistenceService fileStatusPersistenceService; +// @Autowired +// private DossierPersistenceService dossierPersistenceService; +// @Autowired +// private FileService fileService; +// +// @Before +// public void before() { +// var dossier = Dossier.builder() +// .dossierName("test") +// .dossierId("dossierId") +// .date(OffsetDateTime.now()) +// .ownerId("123") +// .description("test") +// .dossierTemplateId("123") +// .memberIds(Sets.newHashSet("123")).build(); +// dossierPersistenceService.insert(dossier); +// +// } +// +// @Test +// public void testAddRedaction() { +// +// String dossierId = "dossierId"; +// String fileId = "FileId"; +// +// fileStatusPersistenceService.createStatus(dossierId, fileId, "dummy.pdf", "uploader"); +// +// AddRedactionRequest addRedactionRequest = AddRedactionRequest.builder() +// .user("TEST_USER") +// .type("name") +// .value("O'Loughlin C.K.") +// .reason("Manual Redaction") +// .status(Status.REQUESTED) +// .positions(List.of(new Rectangle(new Point(375.61096f, 241.282f), 7.648041f, 43.72262f, 1), new Rectangle(new Point(384.83517f, 241.282f), 7.648041f, 17.043358f, 1))) +// .comment("This is a comment test") +// .addToDictionary(false) +// .build(); +// +// ManualAddResponse manualAddResponse = manualRedactionController.addAddRedaction(dossierId, fileId, addRedactionRequest); +// +// ManualRedactionEntry manualRedactionEntry = manualRedactionController.getAddRedaction(fileId, manualAddResponse.getAnnotationId()); +// +// assertThat(manualRedactionEntry.getStatus()).isEqualTo(Status.REQUESTED); +// +// manualRedactionController.updateAddRedactionStatus(dossierId, fileId, manualAddResponse.getAnnotationId(), new com.iqser.red.service.file.management.v1.api.model.UpdateStatusRequest(Status.APPROVED, false)); +// +// manualRedactionEntry = manualRedactionController.getAddRedaction(fileId, manualAddResponse.getAnnotationId()); +// +// assertThat(manualRedactionEntry.getStatus()).isEqualTo(Status.APPROVED); +// +// manualRedactionController.addComment(dossierId, fileId, manualAddResponse.getAnnotationId(), CommentRequest.builder() +// .text("Second") +// .user("TEST_USER") +// .build()); +// +// ManualRedactions manualRedactions = manualRedactionController.getManualRedactions(dossierId, fileId); +// +// assertThat(manualRedactions.getComments().get(manualAddResponse.getAnnotationId()).size()).isEqualTo(2); +// +// fileService.softDeleteFile(dossierId, fileId, OffsetDateTime.now()); +// +// manualRedactions = manualRedactionController.getManualRedactions(dossierId, fileId); +// +// assertThat(manualRedactions.getEntriesToAdd()).isEmpty(); +// assertThat(manualRedactions.getIdsToRemove()).isEmpty(); +// +// File fileStatus = fileStatusPersistenceService.getStatus(dossierId, fileId); +// assertThat(fileStatus.getLastManualRedaction()).isNotNull(); +// +// } +// +// @Test +// public void testRemoveRedaction() { +// +// String dossierId = "dossierId"; +// String fileId = "FileId"; +// String annotationId = "annotationId"; +// +// fileStatusPersistenceService.createStatus(dossierId, fileId, "dummy.pdf", "uploader"); +// +// RemoveRedactionRequest removeRedactionRequest = RemoveRedactionRequest.builder() +// .annotationId(annotationId) +// .user("TEST_USER") +// .comment("This is a comment test") +// .removeFromDictionary(false) +// .status(Status.REQUESTED) +// .build(); +// +// ManualAddResponse manualAddResponse = manualRedactionController.addRemoveRedaction(dossierId, fileId, removeRedactionRequest); +// +// IdRemoval idRemoval = manualRedactionController.getRemoveRedaction(fileId, manualAddResponse.getAnnotationId()); +// +// assertThat(idRemoval.getStatus()).isEqualTo(Status.REQUESTED); +// +// manualRedactionController.updateRemoveRedactionStatus(dossierId, fileId, manualAddResponse.getAnnotationId(), new com.iqser.red.service.file.management.v1.api.model.UpdateStatusRequest(Status.DECLINED, false)); +// +// manualRedactionController.addComment(dossierId, fileId, manualAddResponse.getAnnotationId(), CommentRequest.builder() +// .text("Second") +// .user("TEST_USER") +// .build()); +// +// ManualRedactions manualRedactions = manualRedactionController.getManualRedactions(dossierId, fileId); +// +// assertThat(manualRedactions.getComments().get(manualAddResponse.getAnnotationId()).size()).isEqualTo(2); +// assertThat(manualRedactions.getIdsToRemove().iterator().next().getStatus()).isEqualTo(Status.DECLINED); +// +// File fileStatus = fileStatusPersistenceService.getStatus(dossierId, fileId); +// assertThat(fileStatus.getLastManualRedaction()).isNotNull(); +// } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/ReportTemplateTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/ReportTemplateTest.java new file mode 100644 index 000000000..b2f6ecf1d --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/ReportTemplateTest.java @@ -0,0 +1,96 @@ +package com.iqser.red.service.file.management.v1.server.integration; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.ReportTemplate; +import com.iqser.red.service.persistence.service.v1.api.model.ReportTemplateDownload; +import com.iqser.red.service.persistence.service.v1.api.model.ReportTemplateUploadRequest; +import com.iqser.red.service.persistence.management.v1.processor.exception.FileNotFoundException; +import com.iqser.red.service.file.management.v1.server.controller.ReportTemplateController; +import com.iqser.red.storage.commons.service.StorageService; +import org.apache.commons.io.IOUtils; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.io.IOException; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class ReportTemplateTest extends AbstractFileManagementServerServiceTest { + +// +// @Autowired +// private StorageService storageService; +// +// +// @Autowired +// private ReportTemplateController reportTemplateController; +// +// +// @Test +// public void testReportTemplateUpload() throws IOException { +// String dossierTemplateId = "dossierTemplateId"; +// String template = "template"; +// byte[] templateByteArray = template.getBytes(); +// ReportTemplateUploadRequest reportTemplateUploadRequest = ReportTemplateUploadRequest.builder().template(templateByteArray) +// .dossierTemplateId(dossierTemplateId).fileName("templateName").build(); +// +// ReportTemplate reportTemplate = reportTemplateController.uploadTemplate(reportTemplateUploadRequest); +// +// List reportTemplates = reportTemplateController.getAvailableReportTemplates(dossierTemplateId); +// +// String storageId = reportTemplates.get(0).getStorageId(); +// +// byte[] file = IOUtils.toByteArray(storageService.getObject(storageId).getInputStream()); +// assertThat(file).isEqualTo(templateByteArray); +// assertThat(reportTemplate.getStorageId()).isEqualTo(storageId); +// } +// +// @Test +// public void testGetAvailableReportTemplates() { +// String dossierTemplateId = "dossierTemplateId"; +// String template = "template"; +// byte[] templateByteArray = template.getBytes(); +// ReportTemplateUploadRequest reportTemplateUploadRequest = ReportTemplateUploadRequest.builder().template(templateByteArray) +// .dossierTemplateId(dossierTemplateId).fileName("templateName").build(); +// +// ReportTemplate reportTemplate = reportTemplateController.uploadTemplate(reportTemplateUploadRequest); +// +// List reportTemplates = reportTemplateController.getAvailableReportTemplates(reportTemplate.getDossierTemplateId()); +// +// assertThat(reportTemplate.getTemplateId()).isEqualTo(reportTemplates.get(0).getTemplateId()); +// } +// +// @Test +// public void testDownloadReportTemplate() { +// String dossierTemplateId = "dossierTemplateId"; +// String template = "template"; +// byte[] templateByteArray = template.getBytes(); +// ReportTemplateUploadRequest reportTemplateUploadRequest = ReportTemplateUploadRequest.builder().template(templateByteArray) +// .dossierTemplateId(dossierTemplateId).fileName("templateName").build(); +// +// ReportTemplate reportTemplate = reportTemplateController.uploadTemplate(reportTemplateUploadRequest); +// +// ReportTemplateDownload reportTemplateDownload = reportTemplateController.downloadReportTemplate(reportTemplate.getDossierTemplateId(), reportTemplate.getTemplateId()); +// +// assertThat(reportTemplateDownload.getFile()).isEqualTo(templateByteArray); +// } +// +// @Test +// public void testDeleteTemplate() { +// String dossierTemplateId = "dossierTemplateId"; +// String template = "template"; +// byte[] templateByteArray = template.getBytes(); +// ReportTemplateUploadRequest reportTemplateUploadRequest = ReportTemplateUploadRequest.builder().template(templateByteArray) +// .dossierTemplateId(dossierTemplateId).fileName("templateName").build(); +// +// ReportTemplate reportTemplate = reportTemplateController.uploadTemplate(reportTemplateUploadRequest); +// +// reportTemplateController.deleteTemplate(reportTemplate.getDossierTemplateId(), reportTemplate.getTemplateId()); +// +// assertThat(reportTemplateController.getAvailableReportTemplates(reportTemplate.getDossierTemplateId())).isEmpty(); +// assertThatThrownBy(() -> reportTemplateController.downloadReportTemplate(dossierTemplateId, reportTemplate.getTemplateId())).isInstanceOf( +// FileNotFoundException.class); +// } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/ViewedPagesTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/ViewedPagesTest.java new file mode 100644 index 000000000..5fe1419e4 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/integration/ViewedPagesTest.java @@ -0,0 +1,42 @@ +package com.iqser.red.service.file.management.v1.server.integration; + +import com.iqser.red.service.persistence.service.v1.api.model.data.annotations.ViewedPage; +import com.iqser.red.service.file.management.v1.server.controller.ViewedPagesController; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.ViewedPagesPersistenceService; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; + +public class ViewedPagesTest extends AbstractFileManagementServerServiceTest { + + @Autowired + private ViewedPagesController viewedPagesController; + @Autowired + private ViewedPagesPersistenceService viewedPagesPersistenceService; + + @Test + public void testViewedPages() { + + String fileId = "fileId"; + String role = "reviewer"; + + viewedPagesController.addPage(fileId, role, 1); + viewedPagesController.addPage(fileId, role, 2); + viewedPagesController.addPage(fileId, role, 3); + + viewedPagesController.removePage(fileId, role, 1); + + List viewedPages = viewedPagesController.getViewedPages(fileId, role); + assertThat(viewedPages.stream().map(viewedPage -> viewedPage.getId().getPage())).containsExactlyInAnyOrder(2, 3); + + viewedPagesPersistenceService.deleteForFile(fileId); + viewedPages = viewedPagesController.getViewedPages(fileId, role); + assertThat(viewedPages).isEmpty(); + + } + + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/service/DossierServiceTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/service/DossierServiceTest.java new file mode 100644 index 000000000..dc9ff39d9 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/service/DossierServiceTest.java @@ -0,0 +1,66 @@ +package com.iqser.red.service.file.management.v1.server.service; + +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierPersistenceService; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.Dossier; +import org.assertj.core.util.Sets; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.time.OffsetDateTime; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class DossierServiceTest { +// +// @InjectMocks +// private DossierService dossierService; +// +// @Mock +// private DossierPersistenceService dossierPersistenceService; +// +// @Test +// public void testAddAndUpdateDossier() { +// +// String userId = "user id"; +// Set templateIds = new HashSet<>(Arrays.asList("templateId1", "templateId2", "templateId3")); +// DossierRequest dossierRequest = new DossierRequest("DossierName", +// null, +// userId, +// "123", +// Collections.singleton(userId), +// Collections.singleton(userId), +// Sets.newHashSet(), +// Sets.newHashSet(), +// OffsetDateTime.now(), +// templateIds, +// true); +// Dossier expected = Dossier.builder() +// .dossierName(dossierRequest.getDossierName()) +// .description("") +// .build(); +// when(dossierPersistenceService.findByDossierId(anyString())).thenReturn(expected); +// Dossier dossier = dossierService.addDossier(dossierRequest); +// assertThat(dossier.getDossierName()).isEqualTo(expected.getDossierName()); +// assertThat(dossier.getDescription()).isEqualTo(expected.getDescription()); +// +// String updatedName = "Updated name"; +// dossierRequest.setDossierName(updatedName); +// expected.setDossierName(updatedName); +// expected.setDossierTemplateId("123"); +// when(dossierPersistenceService.findByDossierId(any())).thenReturn(expected); +// assertThat(dossierService.updateDossier(dossierRequest, expected.getDossierId())).isEqualTo(expected); +// +// } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/service/DownloadCleanupServiceTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/service/DownloadCleanupServiceTest.java new file mode 100644 index 000000000..b6313809b --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/service/DownloadCleanupServiceTest.java @@ -0,0 +1,163 @@ +package com.iqser.red.service.file.management.v1.server.service; + +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.Dossier; +import com.iqser.red.service.persistence.service.v1.api.model.data.download.DownloadStatus; +import com.iqser.red.service.persistence.service.v1.api.model.data.dossier.DossierStatus; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DownloadStatusPersistenceService; +import com.iqser.red.service.file.management.v1.server.service.download.DownloadCleanupService; +import com.iqser.red.service.file.management.v1.server.settings.FileManagementServiceSettings; +import com.iqser.red.storage.commons.service.StorageService; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.time.OffsetDateTime; +import java.util.List; + +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.*; + +@RunWith(MockitoJUnitRunner.class) +public class DownloadCleanupServiceTest { + + +// +// @Mock +// private DossierService dossierService; +// +// @Mock +// private DownloadStatusPersistenceService downloadStatusPersistenceService; +// +// @Mock +// private StorageService storageService; +// +// @Mock +// private FileManagementServiceSettings settings; +// +// @InjectMocks +// private DownloadCleanupService downloadCleanupService; +// +// +// @Test +// public void testDeleteAfterLastDownload() { +// DownloadStatus downloadStatus = new DownloadStatus("userId", +// "storageID", +// "dossierId", +// "filename", +// "mimeType", +// DownloadStatusValue.GENERATING, +// OffsetDateTime.now().minusHours(13), +// OffsetDateTime.now().minusHours(9), +// null, +// 10); +// +// Dossier expected = Dossier.builder() +// .dossierId("p1") +// .dossierName("pName") +// .status(DossierStatus.DELETED) +// .build(); +// +// when(settings.getDownloadCleanupFetchLimit()).thenReturn(200); +// when(settings.getDownloadCleanupDownloadFilesHours()).thenReturn(8); +// +// when(downloadStatusPersistenceService.getStatus(settings.getDownloadCleanupFetchLimit())).thenReturn(List.of(downloadStatus)); +// +// downloadCleanupService.processDocuments(); +// +// verify(storageService, times(1)).deleteObject(downloadStatus.getStorageId()); +// } +// +// @Test +// public void testDeleteWithoutDownload() { +// DownloadStatus downloadStatus = new DownloadStatus("userId", +// "storageID", +// "dossierId", +// "filename", +// "mimeType", +// DownloadStatusValue.READY, +// OffsetDateTime.now().minusHours(73), +// null, +// null, +// 10); +// +// Dossier expected = Dossier.builder() +// .dossierId("p1") +// .dossierName("pName") +// .status(DossierStatus.DELETED) +// .build(); +// +// when(settings.getDownloadCleanupFetchLimit()).thenReturn(200); +// when(settings.getDownloadCleanupNotDownloadFilesHours()).thenReturn(72); +// +// when(downloadStatusPersistenceService.getStatus(settings.getDownloadCleanupFetchLimit())).thenReturn(List.of(downloadStatus)); +// +// downloadCleanupService.processDocuments(); +// +// verify(storageService, times(1)).deleteObject(downloadStatus.getStorageId()); +// } +// +// @Test +// public void testDossierNotExists() { +// +// DownloadStatus downloadStatus = new DownloadStatus("userId", +// "storageID", +// "dossierId", +// "filename", +// "mimeType", +// DownloadStatusValue.GENERATING, +// OffsetDateTime.now().minusHours(2), +// OffsetDateTime.now().minusHours(1), +// null, +// 10); +// +// Dossier expected = Dossier.builder() +// .dossierId("p1") +// .dossierName("pName") +// .status(DossierStatus.DELETED) +// .build(); +// +// when(settings.getDownloadCleanupFetchLimit()).thenReturn(200); +// when(settings.getDownloadCleanupDownloadFilesHours()).thenReturn(8); +// +// when(dossierService.getDossierById(anyString())).thenReturn(expected); +// when(downloadStatusPersistenceService.getStatus(settings.getDownloadCleanupFetchLimit())).thenReturn(List.of(downloadStatus)); +// +// downloadCleanupService.processDocuments(); +// +// verify(storageService, times(1)).deleteObject(downloadStatus.getStorageId()); +// } +// +// @Test +// public void testNoDelete() { +// +// DownloadStatus downloadStatus = new DownloadStatus("userId", +// "storageID", +// "dossierId", +// "filename", +// "mimeType", +// DownloadStatusValue.GENERATING, +// OffsetDateTime.now().minusHours(2), +// OffsetDateTime.now().minusHours(1), +// null, +// 10); +// +// Dossier expected = Dossier.builder() +// .dossierId("p1") +// .dossierName("pName") +// .status(DossierStatus.ACTIVE) +// .build(); +// +// when(settings.getDownloadCleanupFetchLimit()).thenReturn(200); +// when(settings.getDownloadCleanupDownloadFilesHours()).thenReturn(8); +// +// when(dossierService.getDossierById(anyString())).thenReturn(expected); +// when(downloadStatusPersistenceService.getStatus(settings.getDownloadCleanupFetchLimit())).thenReturn(List.of(downloadStatus)); +// +// downloadCleanupService.processDocuments(); +// +// verify(storageService, times(0)).deleteObject(downloadStatus.getStorageId()); +// } + +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/service/LicenseReportServiceTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/service/LicenseReportServiceTest.java new file mode 100644 index 000000000..e07bab322 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/service/LicenseReportServiceTest.java @@ -0,0 +1,310 @@ +package com.iqser.red.service.file.management.v1.server.service; + +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class LicenseReportServiceTest { +// +// @InjectMocks +// private LicenseReportService licenseReportService; +// +// @Mock +// private FileStatusService fileStatusService; +// +// @Mock +// private DossierService dossierService; +// +// @Test +// public void testRedactionReportService() { +// +// LicenseReportRequest licenseReportRequest = new LicenseReportRequest(); +// +// LicenseReport licenseReport = licenseReportService.getLicenseReport(licenseReportRequest, 0, 20); +// assertThat(licenseReport.getData()).hasSize(15); +// assertThat(licenseReport.getNumberOfAnalyzedFiles()).isEqualTo(15); +// assertThat(licenseReport.getNumberOfAnalyses()).isEqualTo(13); +// assertThat(licenseReport.getNumberOfAnalyzedPages()).isEqualTo(1020); +// assertThat(licenseReport.getRequestId()).isNotEmpty(); +// assertThat(licenseReport.getNumberOfDossiers()).isEqualTo(5); +// assertThat(licenseReport.getStartDate()).isEqualTo(licenseReportRequest.getStartDate()); +// assertThat(licenseReport.getEndDate()).isEqualTo(licenseReportRequest.getEndDate()); +// assertThat(licenseReport.getNumberOfOcrFiles()).isEqualTo(1); +// assertThat(licenseReport.getNumberOfOcrPages()).isEqualTo(30); +// +// } +// +// @Test +// public void testRedactionReportServiceWithPagination() { +// +// LicenseReportRequest licenseReportRequest = new LicenseReportRequest(); +// +// LicenseReport licenseReport = licenseReportService.getLicenseReport(licenseReportRequest, 0, 10); +// assertThat(licenseReport.getData()).hasSize(10); +// assertThat(licenseReport.getNumberOfAnalyzedFiles()).isEqualTo(15); +// assertThat(licenseReport.getNumberOfAnalyses()).isEqualTo(13); +// assertThat(licenseReport.getNumberOfAnalyzedPages()).isEqualTo(1020); +// assertThat(licenseReport.getRequestId()).isNotEmpty(); +// assertThat(licenseReport.getNumberOfDossiers()).isEqualTo(5); +// assertThat(licenseReport.getStartDate()).isEqualTo(licenseReportRequest.getStartDate()); +// assertThat(licenseReport.getEndDate()).isEqualTo(licenseReportRequest.getEndDate()); +// +// // make sure the service set a request id +// assertThat(licenseReportRequest.getRequestId()).isNotEmpty(); +// +// LicenseReportRequest consecutiveRequest = new LicenseReportRequest(); +// consecutiveRequest.setRequestId(licenseReportRequest.getRequestId()); +// +// licenseReport = licenseReportService.getLicenseReport(consecutiveRequest, 10, 10); +// assertThat(licenseReport.getData()).hasSize(5); +// assertThat(licenseReport.getNumberOfAnalyzedFiles()).isEqualTo(15); +// assertThat(licenseReport.getNumberOfAnalyses()).isEqualTo(13); +// assertThat(licenseReport.getNumberOfAnalyzedPages()).isEqualTo(1020); +// assertThat(licenseReport.getRequestId()).isNotEmpty(); +// assertThat(licenseReport.getNumberOfDossiers()).isEqualTo(5); +// assertThat(licenseReport.getStartDate()).isEqualTo(licenseReportRequest.getStartDate()); +// assertThat(licenseReport.getEndDate()).isEqualTo(licenseReportRequest.getEndDate()); +// +// } +// +// @Before +// public void stubTests() { +// +// List allDossiers = new ArrayList<>(); +// Dossier dossier1 = Dossier.builder() +// .dossierId("dossier1") +// .dossierName("dossier1name") +// .build(); +// Dossier dossier2 = Dossier.builder() +// .dossierId("dossier2") +// .dossierName("dossier2name") +// .build(); +// Dossier dossier3 = Dossier.builder() +// .dossierId("dossier3") +// .dossierName("dossier3name") +// .build(); +// Dossier dossier4 = Dossier.builder() +// .dossierId("dossier4") +// .dossierName("dossier4name") +// .build(); +// Dossier dossier5 = Dossier.builder() +// .dossierId("dossier5") +// .dossierName("dossier5name") +// .build(); +// allDossiers.add(dossier1); +// allDossiers.add(dossier2); +// allDossiers.add(dossier3); +// allDossiers.add(dossier4); +// allDossiers.add(dossier5); +// +// when(dossierService.getAllDossiers()).thenReturn(allDossiers); +// List dossier1Status = new ArrayList<>(); +// File fileStatus1Dossier1 = File.builder() +// .dossierId(dossier1.getDossierId()) +// .fileId("file1dossier1") +// .filename("file1dossier1.exe") +// .status(Status.UNASSIGNED) +// .numberOfPages(100) +// .added(OffsetDateTime.now().minusMinutes(2)) +// .lastUpdated(OffsetDateTime.now().minusMinutes(1)) +// .deleted(null) +// .numberOfAnalyses(2) +// .currentReviewer("reviewer1") +// .build(); +// File fileStatus2Dossier1 = File.builder() +// .dossierId(dossier1.getDossierId()) +// .fileId("file2roject1") +// .filename("file2dossier1.exe") +// .status(Status.UNASSIGNED) +// .numberOfPages(100) +// .added(OffsetDateTime.now().minusMinutes(2)) +// .lastUpdated(OffsetDateTime.now().minusMinutes(1)) +// .deleted(null) +// .numberOfAnalyses(2) +// .currentReviewer("reviewer1") +// .build(); +// File fileStatus3Dossier1 = File.builder() +// .dossierId(dossier1.getDossierId()) +// .fileId("file3dossier1") +// .filename("file3dossier1.exe") +// .status(Status.UNASSIGNED) +// .numberOfPages(100) +// .added(OffsetDateTime.now().minusMinutes(2)) +// .lastUpdated(OffsetDateTime.now().minusMinutes(1)) +// .deleted(null) +// .numberOfAnalyses(2) +// .currentReviewer("reviewer1") +// .build(); +// dossier1Status.add(fileStatus1Dossier1); +// dossier1Status.add(fileStatus2Dossier1); +// dossier1Status.add(fileStatus3Dossier1); +// List dossier2Status = new ArrayList<>(); +// File fileStatus1Dossier2 = File.builder() +// .dossierId(dossier2.getDossierId()) +// .fileId("file1dossier2") +// .filename("file1dossier2.exe") +// .status(Status.PROCESSING) +// .numberOfPages(120) +// .added(OffsetDateTime.now().minusMinutes(2)) +// .lastUpdated(OffsetDateTime.now().minusMinutes(1)) +// .deleted(null) +// .numberOfAnalyses(1) +// .currentReviewer("reviewer1") +// .build(); +// File fileStatus2Dossier2 = File.builder() +// .dossierId(dossier2.getDossierId()) +// .fileId("file2dossier2") +// .filename("file2dossier2.exe") +// .status(Status.PROCESSING) +// .numberOfPages(120) +// .added(OffsetDateTime.now().minusMinutes(2)) +// .lastUpdated(OffsetDateTime.now().minusMinutes(1)) +// .deleted(null) +// .numberOfAnalyses(1) +// .currentReviewer("reviewer1") +// .build(); +// File fileStatus3Dossier2 = File.builder() +// .dossierId(dossier2.getDossierId()) +// .fileId("file3dossier2") +// .filename("file3dossier2.exe") +// .status(Status.PROCESSING) +// .numberOfPages(120) +// .added(OffsetDateTime.now().minusMinutes(2)) +// .lastUpdated(OffsetDateTime.now().minusMinutes(1)) +// .deleted(null) +// .numberOfAnalyses(1) +// .currentReviewer("reviewer1") +// .build(); +// dossier2Status.add(fileStatus1Dossier2); +// dossier2Status.add(fileStatus2Dossier2); +// dossier2Status.add(fileStatus3Dossier2); +// List dossier3Status = new ArrayList<>(); +// File fileStatus1Dossier3 = File.builder() +// .dossierId(dossier3.getDossierId()) +// .fileId("file1dossier3") +// .filename("file1dossier3.exe") +// .status(Status.ERROR) +// .numberOfPages(60) +// .added(OffsetDateTime.now().minusMinutes(2)) +// .lastUpdated(null) +// .deleted(null) +// .numberOfAnalyses(0) +// .currentReviewer("reviewer1") +// .build(); +// File fileStatus2Dossier3 = File.builder() +// .dossierId(dossier3.getDossierId()) +// .fileId("file2dossier3") +// .filename("file2dossier3.exe") +// .status(Status.ERROR) +// .numberOfPages(60) +// .added(OffsetDateTime.now().minusMinutes(2)) +// .lastUpdated(null) +// .deleted(null) +// .numberOfAnalyses(0) +// .currentReviewer("reviewer1") +// .build(); +// File fileStatus3Dossier3 = File.builder() +// .dossierId(dossier3.getDossierId()) +// .fileId("file3dossier3") +// .filename("file3dossier3.exe") +// .status(Status.ERROR) +// .numberOfPages(60) +// .added(OffsetDateTime.now().minusMinutes(2)) +// .lastUpdated(null) +// .deleted(null) +// .numberOfAnalyses(0) +// .currentReviewer("reviewer1") +// .build(); +// dossier3Status.add(fileStatus1Dossier3); +// dossier3Status.add(fileStatus2Dossier3); +// dossier3Status.add(fileStatus3Dossier3); +// List dossier4Status = new ArrayList<>(); +// File fileStatus1Dossier4 = File.builder() +// .dossierId(dossier4.getDossierId()) +// .fileId("file1dossier4") +// .filename("file1dossier4.exe") +// .status(Status.UNPROCESSED) +// .numberOfPages(30) +// .added(OffsetDateTime.now().minusMinutes(2)) +// .lastUpdated(null) +// .deleted(null) +// .numberOfAnalyses(0) +// .currentReviewer("reviewer1") +// .build(); +// File fileStatus2Dossier4 = File.builder() +// .dossierId(dossier4.getDossierId()) +// .fileId("file2dossier4") +// .filename("file2dossier4.exe") +// .status(Status.UNPROCESSED) +// .numberOfPages(30) +// .added(OffsetDateTime.now().minusMinutes(2)) +// .lastUpdated(null) +// .deleted(null) +// .numberOfAnalyses(0) +// .currentReviewer("reviewer1") +// .build(); +// File fileStatus3Dossier4 = File.builder() +// .dossierId(dossier4.getDossierId()) +// .fileId("file3dossier4") +// .filename("file3dossier4.exe") +// .status(Status.UNPROCESSED) +// .numberOfPages(30) +// .added(OffsetDateTime.now().minusMinutes(2)) +// .lastUpdated(null) +// .deleted(null) +// .numberOfAnalyses(0) +// .currentReviewer("reviewer1") +// .build(); +// dossier4Status.add(fileStatus1Dossier4); +// dossier4Status.add(fileStatus2Dossier4); +// dossier4Status.add(fileStatus3Dossier4); +// List dossier5Status = new ArrayList<>(); +// File fileStatus1Dossier5 = File.builder() +// .dossierId(dossier5.getDossierId()) +// .fileId("file1dossier5") +// .filename("file1dossier5.exe") +// .status(Status.REPROCESS) +// .numberOfPages(30) +// .added(OffsetDateTime.now().minusMinutes(2)) +// .lastUpdated(null) +// .deleted(null) +// .numberOfAnalyses(1) +// .currentReviewer("reviewer1") +// .build(); +// File fileStatus2Dossier5 = File.builder() +// .dossierId(dossier5.getDossierId()) +// .fileId("file2dossier5") +// .filename("file2dossier5.exe") +// .status(Status.REPROCESS) +// .numberOfPages(30) +// .added(OffsetDateTime.now().minusMinutes(2)) +// .lastUpdated(null) +// .deleted(null) +// .numberOfAnalyses(1) +// .currentReviewer("reviewer1") +// .build(); +// File fileStatus3Dossier5 = File.builder() +// .dossierId(dossier5.getDossierId()) +// .fileId("file3dossier5") +// .filename("file3dossier5.exe") +// .status(Status.UNASSIGNED) +// .numberOfPages(30) +// .lastOCRTime(OffsetDateTime.now()) +// .added(OffsetDateTime.now().minusMinutes(2)) +// .lastUpdated(null) +// .deleted(null) +// .numberOfAnalyses(2) +// .currentReviewer("reviewer1") +// .build(); +// dossier5Status.add(fileStatus1Dossier5); +// dossier5Status.add(fileStatus2Dossier5); +// dossier5Status.add(fileStatus3Dossier5); +// +// when(fileStatusService.getDossierStatus(dossier1.getDossierId())).thenReturn(dossier1Status); +// when(fileStatusService.getDossierStatus(dossier2.getDossierId())).thenReturn(dossier2Status); +// when(fileStatusService.getDossierStatus(dossier3.getDossierId())).thenReturn(dossier3Status); +// when(fileStatusService.getDossierStatus(dossier4.getDossierId())).thenReturn(dossier4Status); +// when(fileStatusService.getDossierStatus(dossier5.getDossierId())).thenReturn(dossier5Status); +// +// } +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/utils/FileSystemBackArchiverTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/utils/FileSystemBackArchiverTest.java new file mode 100644 index 000000000..edbce5575 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/file/management/v1/server/utils/FileSystemBackArchiverTest.java @@ -0,0 +1,54 @@ +package com.iqser.red.service.file.management.v1.server.utils; + +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.ObjectOutputStream; +import java.util.SplittableRandom; + +import static org.assertj.core.api.Assertions.assertThat; + +@Slf4j +public class FileSystemBackArchiverTest { + + @Test + @SneakyThrows + public void testFileSystemBackedArchiver() { + + try (var fsba = new FileSystemBackedArchiver()) { + + SplittableRandom sr = new SplittableRandom(); + + for (int i = 0; i < 20; i++) { + log.info("At entry: {}, using {}MB of memory", i, (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (1024 * 1024)); + var data = sr.doubles().limit(1024 * 1024).toArray(); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(data); + byte[] bytes = bos.toByteArray(); + bos.close(); + var entry = new FileSystemBackedArchiver.ArchiveModel("folder-" + i, "file-" + i, bytes); + fsba.addEntry(entry); + } + + File f = File.createTempFile("test", ".zip"); + + var contentSize = fsba.getContentLength(); + + try (FileOutputStream fos = new FileOutputStream(f)) { + IOUtils.copy(fsba.toInputStream(), fos); + log.info("File: {}", f.getAbsolutePath()); + + assertThat(f.length()).isEqualTo(contentSize); + } + + log.info("Total File Size: {}MB", f.length() / (1024 * 1024)); + + } + } +} diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml b/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml new file mode 100644 index 000000000..e32759c83 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml @@ -0,0 +1,29 @@ +cassandra: + keyspace-name: file_management_service + migrations-location: 'classpath:cassandra/migrations/*.cql' + +spring: + rabbitmq: + host: ${RABBITMQ_HOST:localhost} + port: ${RABBITMQ_PORT:5672} + username: ${RABBITMQ_USERNAME:user} + password: ${RABBITMQ_PASSWORD:bitnami} + listener: + simple: + acknowledge-mode: AUTO + concurrency: 5 + retry: + enabled: true + max-attempts: 3 + max-interval: 5000 + test: + context: + cache: + maxSize: 60 + +redaction-service.url: "http://redaction-service-v1:8080" +configuration-service.url: "http://configuration-service-v1:8080" +pdftron-redaction-service.url: "http://pdftron-redaction-service-v1:8080" +redaction-report-service.url: "http://redaction-report-service-v1:8080" + + diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/resources/files/export_summary.csv b/persistence-service-v1/persistence-service-server-v1/src/test/resources/files/export_summary.csv new file mode 100644 index 000000000..6c2b8eb75 --- /dev/null +++ b/persistence-service-v1/persistence-service-server-v1/src/test/resources/files/export_summary.csv @@ -0,0 +1,5 @@ +PMRA Document Number,GAP Active Ingredient,Regulatory Utility,Document Comment,SIC Number,Protocol Number,Protocol Number,Data Evaluation Record,Audience,Original Retirement Date,Regulatory Released,Regulatory Authority,Regulatory Authority (legacy to remove),Source Owner,Legacy Primary OECD Code,Legacy Source Organisation,Regulator Comments,Contains Registered Composition?,File Name,FTP Source Location,Submission Format Needed,Legacy Report Number,Sales Unit,Address,ANVISA Process Number,Source Number,Legacy Migration Path,Review Completion Date,Registration Number,Agency Dossier Registration Type,Submission Version,Media Comments,Literature Citation,Document Language,Notes,Study Location,Materials,Approver,Subtype,Test Facility,Is Latest Version,Consumer,Classification,Guideline,TRP Type,Legacy System Date,Function,Artist,Document Title,PI Number,Legacy Version Description,PI Number,Incoming from,Annotations (Unresolved),Work To Date,Copyright Clearance Obtained?,Summary Type,Annotations (Claim Links),Latest Source Minor Version,Regulatory Category,SYN Letter Number,Work From Date,Product,Version Creation Date,Governance Committee,Test Facility (legacy to remove),Regulatory Finalization Date,Imported file?,Status,Information Tracking Submission Package,Approval Type,Media Description,Duration,Legacy System,Archive Date,Exporting country,Regulatory Tracking Number,Annotations (Anchors),Information Tracking,Document Number,GAP Usage Information,Report Number,Legacy Reg Document Number,Legal Representative 2,Registering Company,File Created By,Legacy EPA Decision Code,Meeting Minutes,Product Safety Finalization Date,Report Type,Archived Date,Legacy Other PMRA Data Codes,Template Document Type,Color Space,Legal Representative 1,Document Author,CrossLink,Annotations (Notes),Suggested Links,Assessment Type,Legacy Species Commodity,TK Number,Legacy Test Facilities,Planned Completion Date,PRF Number,Registration Item Country,Legacy Target Species,Legacy Owning Organisation,Archive Number,Protocol Type,Submission Output Format,Submission Date,Coordinator,Regulatory Reporting Date,Annotations (Lines),Field Trial Number,Batch Number,Legacy Version Number,External ID,Author Names,Sponsor Organisation (legacy to remove),Literature Type,Sponsor Organisation,Legacy Crop Host,Document Edition,Agreement Expiry Date,TRP Usage,Legacy EPA Submission Type,Security Classification,Source Document Name,Syngenta Address,Outgoing to (legacy to remove),Link Status,Legacy System Document ID,Copyright,PMRA Registration Number,Annotations (All),SU,Source Vault Name,Latest Source Major Version,Legacy Other OECD Codes,Version Created By,Subarea,Reviewer,Owning Organisation (legacy to remove),Dossier,Viewer,Regulatory Territory,Lifecycle,Claims,Bound Source Minor Version,Global ID,Legacy Regulatory Authorities,Outgoing to,Additional Information,Year,Organism,File Last Modified By,Requires Attachment of a Signature Page?,Source Binding Rule,Destination country,Cross-Reference Submission Number,Name,Issue Topic,Pages,Type,Reason for Retiring,Rule,Type of Review,Original Finalization Date,Trade Name,Transmittal Document,Pages OCR'ed (%),Legacy Object ID(s),Protocol Number,Last Modified By,Annotations (Approved Links),Request Type,Binder,Author,Last Modified Date,Non-English Document Title,Media Location,Created By,Editor,Owner,CRO Report Number,Format,Legacy Discipline,Major Version Number,Created From,Active Ingredients,Archive Location,EPA Registration Number,Retirement Date,Annotations (Links),TRP Document,Finalization Date,Legacy Task Number,Legal Details,OCR Requested,Global Version ID,Publicly Published,Document Date,MRID Number,Legacy Reg Topic,Requires Review and Approval?,Annotations (Auto Links),Subareas,Product Safety Reporting Date,Media Title,Minor Version Number,Legacy Primary PMRA Data Code,Requestor,Owning Organisation,Zone,File Last Modified Date,Contact Person,File Created Date,Amendment Justification,CDPR Number,Legacy EPA Submission Date,Supports Agency Dossier,Field Trial Year,Reason for Un-retiring,TRP Topic,Bound Source Major Version,Keywords,Legacy Author Name(s),Export File Name,Size,Source Link,This content is a translation?,Quality Assurance Standard,Legacy Fed Reg Number,Checksum,Created Date,Annotations (Resolved),User Task,Review Start Date,test list,Incoming from (legacy to remove),Rendition Profile,Path,URL +,,Country Specific,,,,,No,,,Yes,,,,,Syngenta,,,Lambda-cyhalothrin - EU AIR5 - Document A - Statement of the context in which the dossier is submit.doc,,,,,,,,,,,,,,,English,,,PP321,,Authority Form / Document,,TRUE,"All Internal Users, Syngenta Read Only Restricted, Syngenta Read Only Non Restricted",,,,16/07/2019,,,Lambda-cyhalothrin - EU AIR5 - Document A - Statement of the context in which the dossier is submitted,PI0015818,,,,0,,,,0,,,,,,26/03/2020 14:06 CET,,Syngenta Crop Protection AG (Switzerland),,No,Final,,,,,SmartDoc - EAME,,,,0,IT-624180,VV-731623,,N/A,PP321_12074,,,,,,,,,,,,,B Sochard,No,0,0,,,,,,,,,,,,,,,,0,,,1.0|CURRENT,090100b881afdd91,,Syngenta Crop Protection AG (Switzerland),,Syngenta Crop Protection AG,,Original,,,,Internal Use Only,,,ETL_blank,,090100b881afdd91,,,0,,,,,Berangere Sochard,,,Syngenta Crop Protection AG (Switzerland),,,European Union,General Lifecycle,,,40037_850361,,ETL_blank,,,,,,,,,Lambda-cyhalothrin - EU AIR5 - Document A - Statement of the context in which the dossier is submit,,2,Registration Supporting Documentation,,,,,,No,,090100b881afdd91 (cv),,CP Vault Support,0,,No,,24/02/2021 15:20 CET,,,Vault Migration,"Global Reg Ops, NA Reg Ops, PS Ops, EAME Reg Ops, Syngenta Business Administrator, Berangere Sochard, Simon Baker, Lily Williams, Clive Boxwell, Paul Parsons, Richard MacKenzie, Dan Pickford, Laurence Hand",Vault Migration,,application/msword,Regulatory,2,,PP321,,,,0,No,,PI0015818,,No,40037_850361_1958105,No,01/09/2020,,Regulatory,No,0,,,,0,,,Syngenta Crop Protection AG,,,,,,,,,,,,,,Sochard Berangere,,49152,,No,,,86d75e5da397fdadcd332f92234a4f62,29/11/2019 08:51 CET,0,,,,,,Lambda-cyhalothrin - EU AIR5 - Document A - Statement of the.pdf, +,,Country Specific,,,,,No,,,Yes,,,,,Syngenta,,,Lambda-cyhalothrin - EU AIR5 - MCA Section 5 - Toxicology (1).docx,,,,,,,,,,,,,,,English,,,PP321,,Summary / Overview,,TRUE,"All Internal Users, Syngenta Read Only Non Restricted, Syngenta Read Only Restricted",,,,16/07/2019,,,Lambda-cyhalothrin - EU AIR5 - MCA Section 5 - Toxicology,PI0015818,,,,0,,,OECD Tier 2 Summary,0,,,,,,17/02/2021 22:02 CET,,Syngenta Crop Protection AG (Switzerland),,Yes,Draft,,,,,SmartDoc - EAME,,,,0,IT-615930,VV-729845,,N/A,PP321_12086,,,Syngenta,,,,,,,,,,S Lloyd,No,0,0,,,,,,,,,,,,,,,,0,,,1.0|CURRENT,090100b881afde22,,Syngenta Crop Protection AG (Switzerland),,Syngenta Crop Protection AG,,Original,,,,Internal Use Only,,,,,090100b881afde22,,,0,,,,,Sonia Ellis,,,Syngenta Crop Protection AG (Switzerland),,,European Union,General Lifecycle,,,40037_848583,,,,,,Ellis Sonia (ext) GBGU,,,,,Lambda-cyhalothrin - EU AIR5 - MCA Section 5 - Toxicology,,893,Summary / Assessment,,,,,,No,,090100b881afde22 (cv),,CP Vault Support,0,,No,Syngenta,24/02/2021 15:20 CET,,,Vault Migration,"EAME Reg Ops, Syngenta Business Administrator, PS Ops, NA Reg Ops, Global Reg Ops, Berangere Sochard, Simon Baker, Lily Williams, Clive Boxwell, Paul Parsons, Richard MacKenzie, Dan Pickford, Laurence Hand, Claire McCombie, Elaine Buss",Vault Migration,,application/vnd.openxmlformats-officedocument.wordprocessingml.document,Toxicology,3,,PP321,,,,0,No,,PI0015818,,No,40037_848583_2033983,No,01/09/2020,,Tox,No,0,,,,1,,,Syngenta Crop Protection AG,,17/02/2021 21:35 CET,,04/09/2020 14:34 CEST,,,,,,,,,VV-729845,Lloyd Sara,,5089990,,No,,,3b13f57d1244e77844eba73ce0ae9813,29/11/2019 08:47 CET,0,,,,,,Lambda-cyhalothrin - EU AIR5 - MCA Section 5 - Toxicology.pdf, +,,Country Specific,,,,,No,,,Yes,,,,,Syngenta,,,Lambda-cyhalothrin - EU AIR5 - LCA Section 5 Reference List (1).doc,,,,,,,,,,,,,,,English,,,PP321,,Summary / Overview,,TRUE,"All Internal Users, Syngenta Read Only Restricted, Syngenta Read Only Non Restricted",,,,16/07/2019,,,Lambda-cyhalothrin - EU AIR5 - LCA Section 5 Reference List,PI0015818,,,,0,,,OECD Tier 1 Summary,0,,,,,,12/09/2020 15:48 CEST,,Syngenta Crop Protection AG (Switzerland),,Yes,Final,,,,,SmartDoc - EAME,,,,0,IT-615436,VV-729844,,N/A,PP321_12084,,,,,,,,,,,,,S Ellis,No,0,0,,,,,,,,,,,,,,,,0,,,1.0|CURRENT,090100b881afde20,,Syngenta Crop Protection AG (Switzerland),,Syngenta Crop Protection AG,,Original,,,,Internal Use Only,,,,,090100b881afde20,,,0,,,,,Sonia Ellis,,,Syngenta Crop Protection AG (Switzerland),,,European Union,General Lifecycle,,,40037_848582,,,,,,,,,,,Lambda-cyhalothrin - EU AIR5 - LCA Section 5 Reference List,,147,Summary / Assessment,,,,,,No,,090100b881afde20 (cv),,CP Vault Support,0,,No,,24/02/2021 15:20 CET,,,Vault Migration,"NA Reg Ops, Global Reg Ops, EAME Reg Ops, PS Ops, Syngenta Business Administrator, Berangere Sochard, Paul Parsons",Vault Migration,,application/msword,Toxicology,2,,PP321,,,,0,No,,PI0015818,,No,40037_848582_2001744,No,01/09/2020,,Tox,No,0,,,,0,,,Syngenta Crop Protection AG,,,,,,,,,,,,,,Ellis Sonia,,651264,,No,,,eb0fdf698b528b67f54635395ec7fb52,29/11/2019 08:47 CET,0,,,,,,Lambda-cyhalothrin - EU AIR5 - LCA Section 5 Reference List.pdf, +,,Country Specific,,,,,No,,,Yes,,,,,Syngenta,,,Lambda-cyhalothrin - EU AIR5 - LCA Section 4 Reference List (5).doc,,,,,,,,,,,,,,,English,,,PP321,,Summary / Overview,,TRUE,"All Internal Users, Syngenta Read Only Restricted, Syngenta Read Only Non Restricted",,,,16/07/2019,,,Lambda-cyhalothrin - EU AIR5 - LCA Section 4 Reference List,PI0015818,,,,0,,,OECD Tier 1 Summary,0,,,,,,21/09/2020 15:21 CEST,,Syngenta Crop Protection AG (Switzerland),,Yes,Final,,,,,SmartDoc - EAME,,,,0,IT-618210,VV-729843,,N/A,PP321_12083,,,,,,,,,,,,,S Ellis,No,0,0,,,,,,,,,,,,,,,,0,,,1.0|CURRENT,090100b881afde1f,,Syngenta Crop Protection AG (Switzerland),,Syngenta Crop Protection AG,,Original,,,,Internal Use Only,,,,,090100b881afde1f,,,0,,,,,Sonia Ellis,,,Syngenta Crop Protection AG (Switzerland),,,European Union,General Lifecycle,,,40037_848581,,,,,,,,,,,Lambda-cyhalothrin - EU AIR5 - LCA Section 4 Reference List,,151,Summary / Assessment,,,,,,No,,090100b881afde1f (cv),,CP Vault Support,0,,No,,24/02/2021 15:20 CET,,,Vault Migration,"EAME Reg Ops, Global Reg Ops, PS Ops, Syngenta Business Administrator, NA Reg Ops, Berangere Sochard, Melanie Bottoms, Dan Pickford, Lynda Farrelly",Vault Migration,,application/msword,Chemistry - Regulatory,2,,PP321,,,,0,No,,PI0015818,,No,40037_848581_2003177,No,01/09/2020,,Chem - Analytical Methods,No,0,,,,0,,,Syngenta Crop Protection AG,,,,,,,,,,,,,,Ellis Sonia,,699392,,No,,,2c476f477f6e2b55ecb537683f5d1cee,29/11/2019 08:47 CET,0,,,,,,Lambda-cyhalothrin - EU AIR5 - LCA Section 4 Reference List.pdf, diff --git a/persistence-service-v1/pom.xml b/persistence-service-v1/pom.xml new file mode 100755 index 000000000..b26333b18 --- /dev/null +++ b/persistence-service-v1/pom.xml @@ -0,0 +1,44 @@ + + + + + com.iqser.red + platform-dependency + 1.1.3 + + + 4.0.0 + + com.iqser.red.service + persistence-service-v1 + 1.0-SNAPSHOT + + pom + + + persistence-service-api-v1 + persistence-service-processor-v1 + persistence-service-server-v1 + + + + + + com.iqser.red + platform-commons-dependency + 1.3.6 + import + pom + + + com.iqser.red.service + redaction-service-api-v1 + 2.67.0 + + + + + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000..218958163 --- /dev/null +++ b/pom.xml @@ -0,0 +1,21 @@ + + + + 4.0.0 + + persistence-service + com.iqser.red.service + 1.0-SNAPSHOT + + + pom + + + bamboo-specs + persistence-service-v1 + persistence-service-image-v1 + + +