diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ExcelReportGenerationService.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ExcelReportGenerationService.java index ff8e6e9..d2f9793 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ExcelReportGenerationService.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ExcelReportGenerationService.java @@ -150,7 +150,6 @@ public class ExcelReportGenerationService { @SneakyThrows - @Timed("redactmanager_excel-addRows") private void addRows(SXSSFWorkbook workbook, Sheet sheet, Map copiedCells, @@ -309,7 +308,6 @@ public class ExcelReportGenerationService { } - @Timed("redactmanager_excel-addRedactionEntryRows") private void addRedactionEntryRows(Sheet sheet, List reportEntries, String filename, ExcelModel excelModel, PlaceholderModel placeholderModel) { long start = System.currentTimeMillis(); diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/RedactionLogConverterService.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/RedactionLogConverterService.java index 41d2825..95d95e0 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/RedactionLogConverterService.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/RedactionLogConverterService.java @@ -1,6 +1,7 @@ package com.iqser.red.service.redaction.report.v1.server.service; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -12,16 +13,70 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import com.iqser.red.service.persistence.service.v1.api.model.annotations.AnnotationStatus; +import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.type.Type; +import com.iqser.red.service.redaction.report.v1.server.client.DictionaryClient; +import com.iqser.red.service.redaction.report.v1.server.client.DossierClient; +import com.iqser.red.service.redaction.report.v1.server.client.RedactionLogClient; import com.iqser.red.service.redaction.report.v1.server.model.ReportRedactionEntry; import com.iqser.red.service.redaction.v1.model.ManualRedactionType; import com.iqser.red.service.redaction.v1.model.Rectangle; import com.iqser.red.service.redaction.v1.model.RedactionLog; import com.iqser.red.service.redaction.v1.model.RedactionLogEntry; import com.iqser.red.service.redaction.v1.model.RedactionLogLegalBasis; +import com.iqser.red.storage.commons.exception.StorageObjectDoesNotExist; + +import io.micrometer.core.annotation.Timed; +import lombok.RequiredArgsConstructor; @Service +@RequiredArgsConstructor public class RedactionLogConverterService { + private final RedactionLogClient redactionLogClient; + + private final DossierClient dossierClient; + + private final DictionaryClient dictionaryClient; + + + @Timed("redactmanager_getReportEntries") + public List getReportEntries(String dossierId, String fileId, boolean isExcluded) { + + if (isExcluded) { + return new ArrayList<>(); + } + + RedactionLog redactionLog; + Map mapOfEntityDisplayName; + try { + redactionLog = redactionLogClient.getRedactionLog(dossierId, fileId, new ArrayList<>(), true, false); + mapOfEntityDisplayName = fillMapOfTypeAndEntityDisplayName(dossierId); + } catch (StorageObjectDoesNotExist e) { + return new ArrayList<>(); + } + var legalBasisMappings = redactionLog.getLegalBasis(); + + return convertAndSort(redactionLog, legalBasisMappings, mapOfEntityDisplayName); + } + + + private Map fillMapOfTypeAndEntityDisplayName(String dossierId) { + + List typeList = new ArrayList<>(); + typeList.addAll(dictionaryClient.getAllTypesForDossier(dossierId, false)); + typeList.addAll(dictionaryClient.getAllTypesForDossierTemplate(dossierClient.getDossierById(dossierId, true, false).getDossierTemplateId(), false)); + + Map mapOfEntityDisplayName = new HashMap<>(); + + for (var type : typeList) { + mapOfEntityDisplayName.put(type.getType(), type.getLabel()); + } + mapOfEntityDisplayName.put("manual", "Manual"); + + return mapOfEntityDisplayName; + } + + public List convertAndSort(RedactionLog redactionLog, List legalBasisMappings, Map mapOfEntityDisplayName) { List reportEntries = new ArrayList<>(); diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ReportGenerationService.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ReportGenerationService.java index a66b887..67572d3 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ReportGenerationService.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ReportGenerationService.java @@ -56,10 +56,8 @@ public class ReportGenerationService { private final FileStatusClient fileStatusClient; private final DossierClient dossierClient; private final ReportTemplateClient reportTemplateClient; - private final RedactionLogClient redactionLogClient; private final ExcelReportGenerationService excelTemplateReportGenerationService; private final GeneratePlaceholderService generatePlaceholderService; - private final DictionaryClient dictionaryClient; private final ReportTemplateSettings reportTemplateSettings; private final RSSService rSSService; @@ -90,7 +88,7 @@ public class ReportGenerationService { var fileStatus = fileStatusClient.getFileStatus(dossierId, fileId); generatePlaceholderService.resolveFileAttributeValues(fileStatus, placeholderModel); - List reportEntries = getReportEntries(dossierId, fileId, fileStatus.isExcluded()); + List reportEntries = redactionLogConverterService.getReportEntries(dossierId, fileId, fileStatus.isExcluded()); generateMultiFileExcelReports(reportTemplates.multiFileWorkbookReportTemplates, placeholderModel, fileStatus, isLastFile, dossierName, reportEntries); @@ -301,42 +299,9 @@ public class ReportGenerationService { } - @Timed("redactmanager_getReportEntries") - private List getReportEntries(String dossierId, String fileId, boolean isExcluded) { - - if (isExcluded) { - return new ArrayList<>(); - } - - RedactionLog redactionLog; - Map mapOfEntityDisplayName; - try { - redactionLog = redactionLogClient.getRedactionLog(dossierId, fileId, new ArrayList<>(), true, false); - mapOfEntityDisplayName = fillMapOfTypeAndEntityDisplayName(dossierId); - } catch (StorageObjectDoesNotExist e) { - return new ArrayList<>(); - } - var legalBasisMappings = redactionLog.getLegalBasis(); - - return redactionLogConverterService.convertAndSort(redactionLog, legalBasisMappings, mapOfEntityDisplayName); - } - private Map fillMapOfTypeAndEntityDisplayName(String dossierId) { - List typeList = new ArrayList<>(); - typeList.addAll(dictionaryClient.getAllTypesForDossier(dossierId, false)); - typeList.addAll(dictionaryClient.getAllTypesForDossierTemplate(dossierClient.getDossierById(dossierId, true, false).getDossierTemplateId(), false)); - - Map mapOfEntityDisplayName = new HashMap<>(); - - for (var type : typeList) { - mapOfEntityDisplayName.put(type.getType(), type.getLabel()); - } - mapOfEntityDisplayName.put("manual", "Manual"); - - return mapOfEntityDisplayName; - } @FieldDefaults(makeFinal = true, level = AccessLevel.PUBLIC) diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/WordReportGenerationService.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/WordReportGenerationService.java index d3deb98..2bfa3df 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/WordReportGenerationService.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/WordReportGenerationService.java @@ -222,8 +222,7 @@ public class WordReportGenerationService { } - @Timed("redactmanager_word-replaceTextPlaceholders") - public int replaceTextPlaceholders(XWPFDocument doc, + private int replaceTextPlaceholders(XWPFDocument doc, PlaceholderModel placeholderModel, String dossierName, String fileName, @@ -335,7 +334,6 @@ public class WordReportGenerationService { } - @Timed("redactmanager_word-computePlaceholderPos") private PlaceHolderFunctions computePlaceholderPos(XWPFTable table, PlaceholderModel placeholderModel) { Set foundPlaceHolder = new HashSet<>(); @@ -357,7 +355,6 @@ public class WordReportGenerationService { } - @Timed("redactmanager_word-addRedactionEntryRows") private int addRedactionEntryRows(XWPFTable table, List reportEntries, String filename, diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/PlaceholderTest.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/PlaceholderTest.java index d9008aa..f94f21d 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/PlaceholderTest.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/PlaceholderTest.java @@ -11,7 +11,10 @@ import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Test; 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.core.io.ClassPathResource; @@ -27,10 +30,12 @@ import com.iqser.red.service.redaction.report.v1.server.client.FileAttributesCon import com.iqser.red.service.redaction.report.v1.server.client.ReportTemplateClient; import com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService; import com.iqser.red.service.redaction.report.v1.server.storage.ReportStorageService; +import com.iqser.red.storage.commons.StorageAutoConfiguration; import com.iqser.red.storage.commons.service.StorageService; @RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT) +@EnableAutoConfiguration(exclude = {StorageAutoConfiguration.class, RabbitAutoConfiguration.class}) +@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class PlaceholderTest { @Autowired @@ -39,6 +44,9 @@ public class PlaceholderTest { @MockBean private StorageService storageService; + @MockBean + private RabbitTemplate rabbitTemplate; + @MockBean private AmazonS3 s3Client; diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportIntegrationTest.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportIntegrationTest.java index b0c4861..0a46f7b 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportIntegrationTest.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportIntegrationTest.java @@ -20,15 +20,21 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import org.apache.commons.io.IOUtils; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.junit.After; import org.junit.Test; +import org.junit.jupiter.api.AfterEach; import org.junit.runner.RunWith; import org.mockito.Mockito; +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.core.io.ClassPathResource; @@ -56,12 +62,15 @@ import com.iqser.red.service.redaction.report.v1.server.service.WordReportGenera import com.iqser.red.service.redaction.report.v1.server.storage.ReportStorageService; import com.iqser.red.service.redaction.v1.model.RedactionLog; import com.iqser.red.service.redaction.v1.model.RedactionLogLegalBasis; +import com.iqser.red.storage.commons.StorageAutoConfiguration; import com.iqser.red.storage.commons.service.StorageService; +import io.micrometer.prometheus.PrometheusMeterRegistry; import lombok.SneakyThrows; @RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT) +@EnableAutoConfiguration(exclude = {StorageAutoConfiguration.class, RabbitAutoConfiguration.class}) +@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class RedactionReportIntegrationTest { @Autowired @@ -70,6 +79,9 @@ public class RedactionReportIntegrationTest { @MockBean private StorageService storageService; + @MockBean + private RabbitTemplate rabbitTemplate; + @MockBean private ReportStorageService reportStorageService; diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportV2IntegrationTest.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportV2IntegrationTest.java index 51e102c..6ff97b1 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportV2IntegrationTest.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportV2IntegrationTest.java @@ -9,9 +9,12 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import org.apache.commons.io.IOUtils; +import org.junit.After; import org.junit.Test; +import org.junit.jupiter.api.AfterEach; import org.junit.runner.RunWith; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; @@ -52,10 +55,12 @@ import com.iqser.red.service.redaction.report.v1.server.client.ReportTemplateCli import com.iqser.red.service.redaction.report.v1.server.configuration.MessagingConfiguration; import com.iqser.red.service.redaction.report.v1.server.service.ReportGenerationService; import com.iqser.red.service.redaction.report.v1.server.utils.FileSystemBackedStorageService; +import com.iqser.red.service.redaction.report.v1.server.utils.MetricValidationUtils; import com.iqser.red.service.redaction.v1.model.RedactionLog; import com.iqser.red.storage.commons.StorageAutoConfiguration; import com.iqser.red.storage.commons.service.StorageService; +import io.micrometer.prometheus.PrometheusMeterRegistry; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -107,6 +112,9 @@ public class RedactionReportV2IntegrationTest { @Autowired private FileSystemBackedStorageService fileSystemBackedStorageService; + @Autowired + private PrometheusMeterRegistry prometheusMeterRegistry; + @SneakyThrows private ReportRequestMessage prepareFlow(int numOfFiles, String... templates) { @@ -210,6 +218,11 @@ public class RedactionReportV2IntegrationTest { var reportRequestMessage = prepareFlow(1, "templates/Excel Report.xlsx"); processRequest(reportRequestMessage, ".xlsx"); + + MetricValidationUtils.validateMetric(prometheusMeterRegistry, "redactmanager_generateReports", 1, null); + MetricValidationUtils.validateMetric(prometheusMeterRegistry, "redactmanager_generateExcelReport", 1, null); + MetricValidationUtils.validateMetric(prometheusMeterRegistry, "redactmanager_calculateExcelModel", 1, null); + MetricValidationUtils.validateMetric(prometheusMeterRegistry, "redactmanager_getReportEntries", 1, null); } @@ -219,6 +232,13 @@ public class RedactionReportV2IntegrationTest { var reportRequestMessage = prepareFlow(2, "templates/Justification Appendix A1.docx"); processRequest(reportRequestMessage, ".docx"); + + MetricValidationUtils.validateMetric(prometheusMeterRegistry, "redactmanager_generateReports", 1, null); + MetricValidationUtils.validateMetric(prometheusMeterRegistry, "redactmanager_generateWordReport", 1, null); + MetricValidationUtils.validateMetric(prometheusMeterRegistry, "redactmanager_computeIuclidFunction", 1, null); + MetricValidationUtils.validateMetric(prometheusMeterRegistry, "redactmanager_generateExcelReport", 1, null); + MetricValidationUtils.validateMetric(prometheusMeterRegistry, "redactmanager_calculateExcelModel", 1, null); + MetricValidationUtils.validateMetric(prometheusMeterRegistry, "redactmanager_getReportEntries", 1, null); } @@ -228,6 +248,11 @@ public class RedactionReportV2IntegrationTest { var reportRequestMessage = prepareFlow(1, "templates/report.xlsx", "templates/report-advanced.xlsx"); processRequest(reportRequestMessage, ".xlsx"); + + MetricValidationUtils.validateMetric(prometheusMeterRegistry, "redactmanager_generateReports", 1, null); + MetricValidationUtils.validateMetric(prometheusMeterRegistry, "redactmanager_generateExcelReport", 1, null); + MetricValidationUtils.validateMetric(prometheusMeterRegistry, "redactmanager_calculateExcelModel", 1, null); + MetricValidationUtils.validateMetric(prometheusMeterRegistry, "redactmanager_getReportEntries", 1, null); } diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/utils/MetricValidationUtils.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/utils/MetricValidationUtils.java new file mode 100644 index 0000000..01e0e1b --- /dev/null +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/utils/MetricValidationUtils.java @@ -0,0 +1,29 @@ +package com.iqser.red.service.redaction.report.v1.server.utils; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import java.util.concurrent.TimeUnit; + +import io.micrometer.prometheus.PrometheusMeterRegistry; +import io.micrometer.prometheus.PrometheusTimer; +import lombok.experimental.UtilityClass; + +@UtilityClass +public class MetricValidationUtils { + + public static void validateMetric(PrometheusMeterRegistry registry, String name, int invocationCount, Integer time) { + + var metricOptional = registry.getMeters().stream().filter(m -> m.getId().getName().equalsIgnoreCase(name)).findAny(); + assertThat(metricOptional.isPresent()).isTrue(); + PrometheusTimer metric = (PrometheusTimer) metricOptional.get(); + assertThat(metric.count()).isGreaterThanOrEqualTo(invocationCount); + if (time != null) { + // for actually timing the method ... + assertThat(metric.mean(TimeUnit.MILLISECONDS)).isGreaterThan(time); + } else { + // everything takes at least one nano-second - test the meter is correctly initialized + assertThat(metric.mean(TimeUnit.NANOSECONDS)).isGreaterThan(1); + } + } + +} diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/resources/application.yml b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/resources/application.yml new file mode 100644 index 0000000..dfd0ed5 --- /dev/null +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/resources/application.yml @@ -0,0 +1,14 @@ +management: + endpoint: + metrics.enabled: true + prometheus.enabled: true + health.enabled: true + endpoints.web.exposure.include: prometheus, health, metrics + metrics.export.prometheus.enabled: true + +spring: + main: + allow-circular-references: true + + +persistence-service.url: "http://mock.url"