From 699a451f2985dd62ecdd7beb9c18bdf4c3aea5de Mon Sep 17 00:00:00 2001 From: deiflaender Date: Thu, 15 Jun 2023 16:48:42 +0200 Subject: [PATCH] RED-6543: Changed license report to new storage logic --- .../controller/LicenseReportController.java | 7 +- .../resource/LicenseReportResource.java | 5 +- .../processor/service/FileStatusService.java | 7 +- .../service/LicenseReportService.java | 234 ++++++++++-------- .../FileStatusPersistenceService.java | 4 +- .../repository/FileRepository.java | 3 +- .../integration/tests/LicenseReportTest.java | 112 +++++++-- .../shared/model/license/LicenseReport.java | 21 +- .../model/license/LicenseReportRequest.java | 10 - .../model/license/MonthlyReportData.java | 21 ++ .../api/shared/model/license/ReportData.java | 28 --- 11 files changed, 253 insertions(+), 199 deletions(-) create mode 100644 persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/license/MonthlyReportData.java delete mode 100644 persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/license/ReportData.java diff --git a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/LicenseReportController.java b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/LicenseReportController.java index 9c5eae9aa..d55efcd2c 100644 --- a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/LicenseReportController.java +++ b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/LicenseReportController.java @@ -4,7 +4,6 @@ import static com.iqser.red.keycloak.commons.roles.ActionRoles.READ_LICENSE_REPO import org.springframework.security.access.prepost.PreAuthorize; 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.keycloak.commons.KeycloakSecurity; @@ -30,11 +29,9 @@ public class LicenseReportController implements LicenseReportResource { @Override @PreAuthorize("hasAuthority('" + READ_LICENSE_REPORT + "')") - public LicenseReport getReport(@RequestBody LicenseReportRequest reportRequest, - @RequestParam(value = "offset", defaultValue = "0") int offset, - @RequestParam(value = "limit", defaultValue = "20") int limit) { + public LicenseReport getReport(@RequestBody LicenseReportRequest reportRequest) { - LicenseReport licenseReport = licenseReportService.getLicenseReport(reportRequest, offset, limit); + LicenseReport licenseReport = licenseReportService.getLicenseReport(reportRequest); auditPersistenceService.audit(AuditRequest.builder() .userId(KeycloakSecurity.getUserId()) .objectId(LICENSE_AUDIT_KEY) diff --git a/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/LicenseReportResource.java b/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/LicenseReportResource.java index 00054b7d5..be3afeb49 100644 --- a/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/LicenseReportResource.java +++ b/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/LicenseReportResource.java @@ -4,7 +4,6 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; @@ -25,8 +24,6 @@ public interface LicenseReportResource { @PostMapping(value = LICENSE_REPORT_PATH, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(summary = "Creates and serves license report.", description = "None") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Successfully created and served a license report.")}) - LicenseReport getReport(@RequestBody LicenseReportRequest reportRequest, - @RequestParam(value = "offset", defaultValue = "0") int offset, - @RequestParam(value = "limit", defaultValue = "20") int limit); + LicenseReport getReport(@RequestBody LicenseReportRequest reportRequest); } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileStatusService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileStatusService.java index 69032d0d5..7da56b821 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileStatusService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/FileStatusService.java @@ -106,11 +106,10 @@ public class FileStatusService { @Transactional - public List getStatusesForDossiersAndTimePeriod(Set dossierIds, OffsetDateTime start, OffsetDateTime end) { + public List getStatusesAddedBefore(OffsetDateTime end) { - var fileEntities = fileStatusPersistenceService.getStatusesForDossiersAndTimePeriod(dossierIds, start, end); - var convertedList = MagicConverter.convert(fileEntities, FileModel.class, new FileModelMapper()); - return reanalysisRequiredStatusService.enhanceFileStatusWithAnalysisRequirements(convertedList); + var fileEntities = fileStatusPersistenceService.getStatusesAddedBefore(end); + return MagicConverter.convert(fileEntities, FileModel.class, new FileModelMapper()); } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/LicenseReportService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/LicenseReportService.java index 954c29d1f..f41527da2 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/LicenseReportService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/LicenseReportService.java @@ -1,27 +1,24 @@ package com.iqser.red.service.persistence.management.v1.processor.service; -import java.time.Duration; -import java.time.Instant; import java.time.OffsetDateTime; +import java.time.YearMonth; import java.time.ZoneId; -import java.util.HashSet; -import java.util.LinkedList; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; import java.util.List; -import java.util.Set; -import java.util.UUID; +import java.util.Map; +import java.util.function.Function; import java.util.stream.Collectors; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierEntity; +import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileModel; import com.iqser.red.service.persistence.service.v1.api.shared.model.license.LicenseReport; import com.iqser.red.service.persistence.service.v1.api.shared.model.license.LicenseReportRequest; -import com.iqser.red.service.persistence.service.v1.api.shared.model.license.ReportData; +import com.iqser.red.service.persistence.service.v1.api.shared.model.license.MonthlyReportData; -import lombok.AllArgsConstructor; -import lombok.Data; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -35,106 +32,133 @@ public class LicenseReportService { private final DossierService dossierService; - public LicenseReport getLicenseReport(LicenseReportRequest licenseReportRequest, int offset, int limit) { + public LicenseReport getLicenseReport(LicenseReportRequest licenseReportRequest) { - log.info("Generating licence-report"); + var files = fileStatusService.getStatusesAddedBefore(OffsetDateTime.ofInstant(licenseReportRequest.getEndDate(), UTC_ZONE_ID)); + files.sort(Comparator.comparing(FileModel::getAdded)); - Instant start = null; - if (log.isInfoEnabled()) { - start = Instant.now(); + var addDossiers = dossierService.getAllDossiers(); + var dossiersById = addDossiers.stream().collect(Collectors.toMap(DossierEntity::getId, Function.identity())); + + Map> adds = new HashMap<>(); + Map> softDeletes = new HashMap<>(); + Map> archives = new HashMap<>(); + Map> hardDeletes = new HashMap<>(); + Map> ocrs = new HashMap<>(); + + for (var file : files) { + + adds.computeIfAbsent(YearMonth.from(file.getAdded()), entry -> new ArrayList<>()).add(file); + + if (file.getDeleted() != null) { + softDeletes.computeIfAbsent(YearMonth.from(file.getDeleted()), entry -> new ArrayList<>()).add(file); + } + if (file.getHardDeletedTime() != null) { + hardDeletes.computeIfAbsent(YearMonth.from(file.getHardDeletedTime()), entry -> new ArrayList<>()).add(file); + } + if (dossiersById.get(file.getDossierId()).getArchivedTime() != null) { + archives.computeIfAbsent(YearMonth.from(dossiersById.get(file.getDossierId()).getArchivedTime()), entry -> new ArrayList<>()).add(file); + } + if (file.getOcrStartTime() != null) { + ocrs.computeIfAbsent(YearMonth.from(file.getOcrStartTime()), entry -> new ArrayList<>()).add(file); + } } - if (StringUtils.isEmpty(licenseReportRequest.getRequestId())) { - licenseReportRequest.setRequestId(UUID.randomUUID().toString()); + YearMonth currentMonth = YearMonth.from(files.get(0).getAdded()); + YearMonth endMonth = YearMonth.from(licenseReportRequest.getEndDate().atZone(UTC_ZONE_ID).toLocalDate()); + YearMonth reportStartMonth = YearMonth.from(licenseReportRequest.getStartDate().atZone(UTC_ZONE_ID).toLocalDate()); + + List monthlyData = new ArrayList<>(); + + long activeFilesUploadedBytes = 0; + long trashFilesUploadedBytes = 0; + long archivedFilesUploadedBytes = 0; + int numberOfAnalyzedPages = 0; + int numberOfOcrPages = 0; + int numberOfAnalyzedFiles = 0; + int numberOfAnalyses = 0; + int numberOfOcrFiles = 0; + + while (!currentMonth.isAfter(endMonth)) { + + var addedFilesInMonth = adds.get(currentMonth); + if (addedFilesInMonth != null) { + for (var add : addedFilesInMonth) { + activeFilesUploadedBytes += add.getFileSize(); + numberOfAnalyzedPages += add.getNumberOfPages(); + numberOfAnalyzedFiles++; + numberOfAnalyses += add.getNumberOfAnalyses(); + } + } + + var softDeletedFilesInMonth = softDeletes.get(currentMonth); + if (softDeletedFilesInMonth != null) { + for (var softDeleted : softDeletedFilesInMonth) { + activeFilesUploadedBytes -= softDeleted.getFileSize(); + trashFilesUploadedBytes += softDeleted.getFileSize(); + } + } + + var archivedFilesInMonth = archives.get(currentMonth); + if (archivedFilesInMonth != null) { + for (var archived : archivedFilesInMonth) { + activeFilesUploadedBytes -= archived.getFileSize(); + archivedFilesUploadedBytes += archived.getFileSize(); + } + } + + var hardDeletedFilesInMonth = hardDeletes.get(currentMonth); + if (hardDeletedFilesInMonth != null) { + for (var hardDeleted : hardDeletedFilesInMonth) { + if (hardDeleted.getDeleted() != null) { + trashFilesUploadedBytes -= hardDeleted.getFileSize(); + } else { + activeFilesUploadedBytes -= hardDeleted.getFileSize(); + } + } + } + + var ocrFilesInMonth = ocrs.get(currentMonth); + if (ocrFilesInMonth != null) { + for (var ocrFile : ocrFilesInMonth) { + numberOfOcrPages += ocrFile.getNumberOfPages(); // We count the entire document if ocr is performed. + numberOfOcrFiles++; + } + } + + if (currentMonth.equals(reportStartMonth) || currentMonth.isAfter(reportStartMonth)) { + monthlyData.add(MonthlyReportData.builder() + .activeFilesUploadedBytes(activeFilesUploadedBytes) + .trashFilesUploadedBytes(trashFilesUploadedBytes) + .archivedFilesUploadedBytes(archivedFilesUploadedBytes) + .totalFilesUploadedBytes(activeFilesUploadedBytes + trashFilesUploadedBytes + archivedFilesUploadedBytes) + .numberOfAnalyzedPages(numberOfAnalyzedPages) + .numberOfOcrPages(numberOfOcrPages) + .build()); + } + + currentMonth = currentMonth.plusMonths(1); } - DetailedReportData detailedReportData = loadDetailedReportData(licenseReportRequest); - - LicenseReport licenseReport = new LicenseReport(); - licenseReport.setNumberOfAnalyzedPages(detailedReportData.getTotalPagesAnalyzed()); - licenseReport.setNumberOfAnalyzedFiles(detailedReportData.getData().size()); - licenseReport.setNumberOfOcrFiles((int) detailedReportData.getData().stream().filter(reportData -> reportData.getNumberOfOcrPages() > 0).count()); - licenseReport.setNumberOfOcrPages(detailedReportData.getTotalOcrPages()); - licenseReport.setNumberOfDossiers(detailedReportData.getNumberOfDossiers()); - licenseReport.setNumberOfAnalyses(detailedReportData.getTotalNumberOfAnalyses()); - licenseReport.setData(detailedReportData.getData().subList(offset, Math.min(offset + limit, detailedReportData.getData().size()))); - licenseReport.setOffset(offset); - licenseReport.setLimit(limit); - licenseReport.setStartDate(detailedReportData.getStartDate()); - licenseReport.setEndDate(detailedReportData.getEndDate()); - licenseReport.setRequestId(licenseReportRequest.getRequestId()); - - if (start != null) { - log.info("getLicenceReport took {} to process", Duration.between(start, Instant.now()).toString()); - } - - return licenseReport; - - } - - - private DetailedReportData loadDetailedReportData(LicenseReportRequest licenseReportRequest) { - - log.debug("No licence-report found in cache, generating new report"); - Instant start = null; - if (log.isInfoEnabled()) { - start = Instant.now(); - } - - final Set dossierIds; - if (CollectionUtils.isEmpty(licenseReportRequest.getDossierIds())) { - dossierIds = dossierService.getAllDossiers().stream().map(DossierEntity::getId).collect(Collectors.toSet()); - } else { - dossierIds = new HashSet<>(licenseReportRequest.getDossierIds()); - } - - var result = new DetailedReportData(new LinkedList<>(), dossierIds.size(), 0, 0, 0, licenseReportRequest.getStartDate(), licenseReportRequest.getEndDate()); - - fileStatusService.getStatusesForDossiersAndTimePeriod( // - dossierIds, // - OffsetDateTime.ofInstant(licenseReportRequest.getStartDate(), UTC_ZONE_ID), // - OffsetDateTime.ofInstant(licenseReportRequest.getEndDate(), UTC_ZONE_ID)) // - .forEach(fileStatus -> { - ReportData reportData = new ReportData(); - reportData.setDossier(fileStatus.getDossierId()); - 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.setWorkflowStatus(fileStatus.getWorkflowStatus()); - reportData.setNumberOfAnalyzedPages(fileStatus.getNumberOfPages()); - reportData.setNumberOfOcrPages(fileStatus.getOcrStartTime() != null ? fileStatus.getNumberOfPages() : 0); - reportData.setAnalysisCount(fileStatus.getNumberOfAnalyses()); - result.totalPagesAnalyzed += fileStatus.getNumberOfPages(); - result.totalOcrPages += fileStatus.getOcrStartTime() != null ? fileStatus.getNumberOfPages() : 0; - result.totalNumberOfAnalyses += fileStatus.getNumberOfAnalyses(); - result.data.add(reportData); - }); - - if (start != null) { - log.info("loadReport took {} to process", Duration.between(start, Instant.now()).toString()); - } - - return result; - - } - - - // This was also used to cache results so that subsequent pagination works faster. - // Currently, pagination is unused, and it is unclear, if caching is needed. - // This intermediate object may be re-used for caching and pagination, if needed. - @Data - @AllArgsConstructor - private static class DetailedReportData { - - List data; - int numberOfDossiers; - int totalNumberOfAnalyses; - int totalPagesAnalyzed; - int totalOcrPages; - Instant startDate; - Instant endDate; - + return LicenseReport.builder() + .totalFilesUploadedBytes(activeFilesUploadedBytes + trashFilesUploadedBytes + archivedFilesUploadedBytes) + .activeFilesUploadedBytes(activeFilesUploadedBytes) + .trashFilesUploadedBytes(trashFilesUploadedBytes) + .archivedFilesUploadedBytes(archivedFilesUploadedBytes) + .numberOfAnalyzedPages(numberOfAnalyzedPages) + .numberOfOcrPages(numberOfOcrPages) + .numberOfAnalyzedFiles(numberOfAnalyzedFiles) + .numberOfAnalyses(numberOfAnalyses) + .numberOfOcrFiles(numberOfOcrFiles) + .numberOfDossiers(addDossiers.stream() + .filter(dossier -> dossier.getHardDeletedTime() == null || dossier.getHardDeletedTime() + .isAfter(OffsetDateTime.ofInstant(licenseReportRequest.getEndDate(), UTC_ZONE_ID))) + .collect(Collectors.toSet()) + .size()) + .startDate(licenseReportRequest.getStartDate()) + .endDate(licenseReportRequest.getEndDate()) + .monthlyData(monthlyData) + .build(); } } 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 index 6ce2b39f2..8df7c94fc 100644 --- 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 @@ -339,9 +339,9 @@ public class FileStatusPersistenceService { } - public List getStatusesForDossiersAndTimePeriod(Set dossierIds, OffsetDateTime start, OffsetDateTime end) { + public List getStatusesAddedBefore(OffsetDateTime end) { - return fileRepository.findByDossierIdInAndAddedBetween(dossierIds, start, end); + return fileRepository.findByAddedBefore(end); } 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 index ec35e591b..a63858bfc 100644 --- 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 @@ -2,7 +2,6 @@ package com.iqser.red.service.persistence.management.v1.processor.service.persis import java.time.OffsetDateTime; import java.util.List; -import java.util.Set; import javax.transaction.Transactional; @@ -25,7 +24,7 @@ public interface FileRepository extends JpaRepository { List findByDossierId(String dossierId); - List findByDossierIdInAndAddedBetween(Set dossierIds, OffsetDateTime start, OffsetDateTime end); + List findByAddedBefore(OffsetDateTime end); @Modifying diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/LicenseReportTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/LicenseReportTest.java index 6bfb20355..9c83d96f0 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/LicenseReportTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/LicenseReportTest.java @@ -2,11 +2,10 @@ package com.iqser.red.service.peristence.v1.server.integration.tests; import static org.assertj.core.api.Assertions.assertThat; +import java.time.Instant; import java.time.OffsetDateTime; -import java.time.temporal.ChronoUnit; -import java.util.stream.Collectors; +import java.time.ZoneId; -import org.assertj.core.util.Lists; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -15,6 +14,9 @@ import com.iqser.red.service.peristence.v1.server.integration.service.DossierTem import com.iqser.red.service.peristence.v1.server.integration.service.DossierTesterAndProvider; import com.iqser.red.service.peristence.v1.server.integration.service.FileTesterAndProvider; import com.iqser.red.service.peristence.v1.server.integration.utils.AbstractPersistenceServerServiceTest; +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 com.iqser.red.service.persistence.service.v1.api.shared.model.FileStatus; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.Dossier; import com.iqser.red.service.persistence.service.v1.api.shared.model.license.LicenseReport; import com.iqser.red.service.persistence.service.v1.api.shared.model.license.LicenseReportRequest; @@ -35,44 +37,104 @@ public class LicenseReportTest extends AbstractPersistenceServerServiceTest { @Autowired private DossierTesterAndProvider dossierTesterAndProvider; + @Autowired + private FileRepository fileRepository; + + @Autowired + private DossierRepository dossierRepository; + @Test public void testLicenseReport() { var template = dossierTemplateTesterAndProvider.provideTestTemplate(); - var dossier1 = dossierTesterAndProvider.provideTestDossier(template, "Dossier1"); + var lastYearDossier = dossierTesterAndProvider.provideTestDossier(template, "lastYearDossier"); + var lastYearFile1 = addFileOnDate(lastYearDossier, "2022-01-01T10:00:00Z"); + var lastYearFile2 = addFileOnDate(lastYearDossier, "2022-01-02T10:00:00Z"); - var file1 = fileTesterAndProvider.testAndProvideFile(dossier1, "test1.pdf"); - var file2 = fileTesterAndProvider.testAndProvideFile(dossier1, "test2.pdf"); + var januaryDossier = dossierTesterAndProvider.provideTestDossier(template, "januaryDossier"); + var januaryFile1 = addFileOnDate(januaryDossier, "2023-01-01T10:00:00Z"); + var januaryFile2 = addFileOnDate(januaryDossier, "2023-01-02T10:00:00Z"); - var dossier2 = dossierTesterAndProvider.provideTestDossier(template, "Dossier2"); + var februaryDossier = dossierTesterAndProvider.provideTestDossier(template, "februaryDossier"); + var februaryFile1 = addFileOnDate(februaryDossier, "2023-02-01T10:00:00Z"); + var februaryFile2 = addFileOnDate(februaryDossier, "2023-02-02T10:00:00Z"); - var file3 = fileTesterAndProvider.testAndProvideFile(dossier2, "test3.pdf"); - var file4 = fileTesterAndProvider.testAndProvideFile(dossier2, "test4.pdf"); + var marchDossier = dossierTesterAndProvider.provideTestDossier(template, "marchDossier"); + var marchFile1 = addFileOnDate(marchDossier, "2023-03-01T10:00:00Z"); + var marchFile2 = addFileOnDate(marchDossier, "2023-03-02T10:00:00Z"); - var dossiers = Lists.newArrayList(dossier1, dossier2); - var files = Lists.newArrayList(file1, file2, file3, file4); + var aprilDossier = dossierTesterAndProvider.provideTestDossier(template, "aprilDossier"); + var aprilFile1 = addFileOnDate(aprilDossier, "2023-04-01T10:00:00Z"); + var aprilFile2 = addFileOnDate(aprilDossier, "2023-04-02T10:00:00Z"); - LicenseReportRequest request = new LicenseReportRequest(); - request.setDossierIds(dossiers.stream().map(Dossier::getId).collect(Collectors.toList())); + softDeleteFile(januaryFile1.getFileId(), "2023-02-01T10:00:00Z"); - var startDate = OffsetDateTime.now().minusHours(10).toInstant().truncatedTo(ChronoUnit.MILLIS); - request.setStartDate(startDate); + hardDeleteFile(januaryFile1.getFileId(), "2023-03-01T10:00:00Z"); - var endDate = OffsetDateTime.now().plusHours(10).toInstant().truncatedTo(ChronoUnit.MILLIS); - request.setEndDate(endDate); + archiveDossier(februaryDossier.getDossierId(), "2023-05-01T10:00:00Z"); - String requestId = "123"; - request.setRequestId(requestId); + LicenseReport licenseReport = licenseReportClient.getReport(LicenseReportRequest.builder() + .startDate(Instant.parse("2023-01-01T10:00:00Z")) + .endDate(Instant.parse("2023-05-01T10:00:00Z")) + .build()); - LicenseReport licenseReport = licenseReportClient.getReport(request, 0, 20); + assertThat(licenseReport.getTotalFilesUploadedBytes()).isEqualTo(900L); + assertThat(licenseReport.getActiveFilesUploadedBytes()).isEqualTo(700L); + assertThat(licenseReport.getArchivedFilesUploadedBytes()).isEqualTo(200L); + assertThat(licenseReport.getTrashFilesUploadedBytes()).isEqualTo(0L); - assertThat(licenseReport.getNumberOfDossiers()).isEqualTo(dossiers.size()); - assertThat(licenseReport.getNumberOfAnalyzedFiles()).isEqualTo(files.size()); - assertThat(licenseReport.getRequestId()).isEqualTo(requestId); - assertThat(licenseReport.getStartDate()).isEqualTo(startDate); - assertThat(licenseReport.getEndDate()).isEqualTo(endDate); + assertThat(licenseReport.getMonthlyData().size()).isEqualTo(5); + assertThat(licenseReport.getMonthlyData().get(1).getTrashFilesUploadedBytes()).isEqualTo(100L); + assertThat(licenseReport.getMonthlyData().get(2).getTrashFilesUploadedBytes()).isEqualTo(0L); + } + + + private FileStatus addFileOnDate(Dossier dossier, String date) { + + var file = fileTesterAndProvider.testAndProvideFile(dossier, date + ".pdf"); + setAdded(file.getId(), date); + return file; + } + + + private void setAdded(String fileId, String date) { + + fileRepository.findById(fileId).ifPresent((file) -> { + + file.setAdded(OffsetDateTime.ofInstant(Instant.parse(date), ZoneId.of("Z"))); + file.setFileSize(100L); + fileRepository.saveAndFlush(file); + + }); + } + + + private void archiveDossier(String dossierId, String date) { + + dossierRepository.findById(dossierId).ifPresent((dossier) -> { + dossier.setArchivedTime(OffsetDateTime.ofInstant(Instant.parse(date), ZoneId.of("Z"))); + dossierRepository.saveAndFlush(dossier); + }); + } + + + private void softDeleteFile(String fileId, String date) { + + fileRepository.findById(fileId).ifPresent((file) -> { + file.setDeleted(OffsetDateTime.ofInstant(Instant.parse(date), ZoneId.of("Z"))); + fileRepository.saveAndFlush(file); + }); + } + + + private void hardDeleteFile(String fileId, String date) { + + fileRepository.findById(fileId).ifPresent((file) -> { + file.setHardDeletedTime(OffsetDateTime.ofInstant(Instant.parse(date), ZoneId.of("Z"))); + fileRepository.saveAndFlush(file); + }); } } diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/license/LicenseReport.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/license/LicenseReport.java index 72002e6c5..f3ba0f0a3 100644 --- a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/license/LicenseReport.java +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/license/LicenseReport.java @@ -15,28 +15,21 @@ import lombok.NoArgsConstructor; @NoArgsConstructor public class LicenseReport { + private long totalFilesUploadedBytes; + private long activeFilesUploadedBytes; + private long trashFilesUploadedBytes; + private long archivedFilesUploadedBytes; private int numberOfAnalyzedFiles; private int numberOfOcrFiles; - private int numberOfDossiers; - private int numberOfAnalyzedPages; private int numberOfOcrPages; - - private int numberOfAnalyses; // includes reanalysis counts - + private int numberOfAnalyses; 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; + @Builder.Default + private List monthlyData = new ArrayList<>(); } diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/license/LicenseReportRequest.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/license/LicenseReportRequest.java index 740e69b01..9d0c25709 100644 --- a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/license/LicenseReportRequest.java +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/license/LicenseReportRequest.java @@ -3,31 +3,21 @@ package com.iqser.red.service.persistence.service.v1.api.shared.model.license; import java.time.Instant; import java.time.Year; import java.time.ZoneOffset; -import java.util.ArrayList; -import java.util.List; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; -import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @Data @Builder @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) { diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/license/MonthlyReportData.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/license/MonthlyReportData.java new file mode 100644 index 000000000..a13e3127a --- /dev/null +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/license/MonthlyReportData.java @@ -0,0 +1,21 @@ +package com.iqser.red.service.persistence.service.v1.api.shared.model.license; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class MonthlyReportData { + + private long totalFilesUploadedBytes; + private long activeFilesUploadedBytes; + private long trashFilesUploadedBytes; + private long archivedFilesUploadedBytes; + private int numberOfAnalyzedPages; + private int numberOfOcrPages; + +} diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/license/ReportData.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/license/ReportData.java deleted file mode 100644 index 4f990159a..000000000 --- a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/license/ReportData.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.iqser.red.service.persistence.service.v1.api.shared.model.license; - -import java.time.Instant; - -import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.WorkflowStatus; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -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 WorkflowStatus workflowStatus; - private int analysisCount; - -} -- 2.47.2