From 88d4a61a2e6f364a0497e0415a0e51be0c8207bd Mon Sep 17 00:00:00 2001 From: Richard Panman Date: Fri, 11 Nov 2022 10:50:05 +0000 Subject: [PATCH 1/3] Add check that dates are in the correct format --- .../service/NexusIQSuccessMetrics.java | 17 ++++++++++ .../cs/getmetrics/util/DateCheck.java | 32 +++++++++++++++++++ .../cs/getmetrics/util/DateCheckTest.java | 27 ++++++++++++++++ 3 files changed, 76 insertions(+) create mode 100644 get-metrics/src/main/java/org/sonatype/cs/getmetrics/util/DateCheck.java create mode 100644 get-metrics/src/test/java/org/sonatype/cs/getmetrics/util/DateCheckTest.java diff --git a/get-metrics/src/main/java/org/sonatype/cs/getmetrics/service/NexusIQSuccessMetrics.java b/get-metrics/src/main/java/org/sonatype/cs/getmetrics/service/NexusIQSuccessMetrics.java index 53adfe8..6a25e28 100644 --- a/get-metrics/src/main/java/org/sonatype/cs/getmetrics/service/NexusIQSuccessMetrics.java +++ b/get-metrics/src/main/java/org/sonatype/cs/getmetrics/service/NexusIQSuccessMetrics.java @@ -8,6 +8,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonatype.cs.getmetrics.model.PayloadItem; +import org.sonatype.cs.getmetrics.util.DateCheck; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -61,6 +62,22 @@ public NexusIQSuccessMetrics( } public void createSuccessMetricsCsvFile() throws IOException, JSONException, HttpException { + try { + DateCheck.checkDateFormat(iqSmPeriod, iqApiFirstTimePeriod); + } catch (Exception e) { + throw new IllegalArgumentException( + "Please check iq.api.sm.period and iq.api.sm.payload.timeperiod.first", e); + } + + try { + if (!iqApiLastTimePeriod.equals("")) { + DateCheck.checkDateFormat(iqSmPeriod, iqApiLastTimePeriod); + } + } catch (Exception e) { + throw new IllegalArgumentException( + "Please check iq.api.sm.period and iq.api.sm.payload.timeperiod.last", e); + } + String apiPayload = getPayload(); String content = diff --git a/get-metrics/src/main/java/org/sonatype/cs/getmetrics/util/DateCheck.java b/get-metrics/src/main/java/org/sonatype/cs/getmetrics/util/DateCheck.java new file mode 100644 index 0000000..371a460 --- /dev/null +++ b/get-metrics/src/main/java/org/sonatype/cs/getmetrics/util/DateCheck.java @@ -0,0 +1,32 @@ +package org.sonatype.cs.getmetrics.util; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class DateCheck { + public static boolean checkDateFormat(String period, String date) { + if (!period.toUpperCase().equals("MONTH") && !period.toUpperCase().equals("WEEK")) { + throw new IllegalArgumentException("The period must be either MONTH or WEEK"); + } + if (period.toUpperCase().equals("MONTH")) { + Pattern pattern = Pattern.compile("^\\d{4}-\\d{2}$", Pattern.CASE_INSENSITIVE); + Matcher matcher = pattern.matcher(date); + if (matcher.find()) { + return true; + } else { + throw new IllegalArgumentException( + "iq.api.sm.period is set to MONTH but the dates prodived are not in 2022-01" + + " format. Perhaps there is a W in there for week format?"); + } + } + Pattern pattern = Pattern.compile("^\\d{4}-W\\d{2}$", Pattern.CASE_INSENSITIVE); + Matcher matcher = pattern.matcher(date); + if (matcher.find()) { + return true; + } else { + throw new IllegalArgumentException( + "iq.api.sm.period is set to WEEK but the dates prodived are not in 2022-W01" + + " format. Perhaps you've missed out the W?"); + } + } +} diff --git a/get-metrics/src/test/java/org/sonatype/cs/getmetrics/util/DateCheckTest.java b/get-metrics/src/test/java/org/sonatype/cs/getmetrics/util/DateCheckTest.java new file mode 100644 index 0000000..e94c6e3 --- /dev/null +++ b/get-metrics/src/test/java/org/sonatype/cs/getmetrics/util/DateCheckTest.java @@ -0,0 +1,27 @@ +package org.sonatype.cs.getmetrics.util; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class DateCheckTest { + @Test + void testValidDates() { + Assertions.assertTrue(DateCheck.checkDateFormat("MONTH", "2022-01")); + Assertions.assertTrue(DateCheck.checkDateFormat("WEEK", "2022-W01")); + Assertions.assertTrue(DateCheck.checkDateFormat("month", "2022-01")); + Assertions.assertTrue(DateCheck.checkDateFormat("week", "2022-w01")); + Assertions.assertTrue(DateCheck.checkDateFormat("week", "2022-W01")); + } + + @Test + void testInvalidDates() { + Assertions.assertThrows( + IllegalArgumentException.class, + () -> DateCheck.checkDateFormat("MONTH", "2022-W01"), + "Expected checkDateFormat() to throw, but it didn't"); + Assertions.assertThrows( + IllegalArgumentException.class, + () -> DateCheck.checkDateFormat("WEEK", "2022-01"), + "Expected checkDateFormat() to throw, but it didn't"); + } +} From 31d668f00aa4cc67ae5517e33097d3cbd0bd1f36 Mon Sep 17 00:00:00 2001 From: Richard Panman Date: Sat, 11 Feb 2023 11:01:08 +0000 Subject: [PATCH 2/3] Fix error with multiple Firewall requests --- .../cs/getmetrics/service/FileIoService.java | 13 ++++++++++++- .../sonatype/cs/getmetrics/util/ParseReasons.java | 10 ++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/get-metrics/src/main/java/org/sonatype/cs/getmetrics/service/FileIoService.java b/get-metrics/src/main/java/org/sonatype/cs/getmetrics/service/FileIoService.java index ac67952..bb3f002 100644 --- a/get-metrics/src/main/java/org/sonatype/cs/getmetrics/service/FileIoService.java +++ b/get-metrics/src/main/java/org/sonatype/cs/getmetrics/service/FileIoService.java @@ -18,6 +18,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; +import java.nio.file.StandardOpenOption; import java.util.List; import java.util.stream.Stream; @@ -35,8 +36,18 @@ public void writeCsvFile(String filename, List data) { String metricsFile = metricsDir + "/" + filename; - try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(metricsFile))) { + File f = new File(metricsFile); + Boolean first_time_writing_to_file = !(f.exists() && !f.isDirectory()); + + try (BufferedWriter writer = + Files.newBufferedWriter( + Paths.get(metricsFile), + StandardOpenOption.CREATE, + StandardOpenOption.APPEND)) { CSVWriter csvWriter = new CSVWriter(writer); + if (!first_time_writing_to_file) { + data.remove(0); + } csvWriter.writeAll(data); csvWriter.flush(); csvWriter.close(); diff --git a/get-metrics/src/main/java/org/sonatype/cs/getmetrics/util/ParseReasons.java b/get-metrics/src/main/java/org/sonatype/cs/getmetrics/util/ParseReasons.java index f912b05..d32aba6 100644 --- a/get-metrics/src/main/java/org/sonatype/cs/getmetrics/util/ParseReasons.java +++ b/get-metrics/src/main/java/org/sonatype/cs/getmetrics/util/ParseReasons.java @@ -33,11 +33,13 @@ private static String getCVE(JsonArray reasons) { List cves = new ArrayList<>(); for (JsonObject reason : reasons.getValuesAs(JsonObject.class)) { - JsonObject reference = reason.getJsonObject("reference"); - String cve = reference.getString("value"); + if (!reason.isNull("reference")) { + JsonObject reference = reason.getJsonObject("reference"); + String cve = reference.getString("value"); - if (!cves.contains(cve)) { - cves.add(cve); + if (!cves.contains(cve)) { + cves.add(cve); + } } } From 1bbf1e335f8ad01bf0826460d6c281d5a558978b Mon Sep 17 00:00:00 2001 From: Richard Panman Date: Sat, 11 Feb 2023 11:43:36 +0000 Subject: [PATCH 3/3] Remove requirement for success metrics in web view --- README.md | 6 +-- .../cs/metrics/SuccessMetricsApplication.java | 28 ++++++------ .../src/main/resources/templates/home.html | 43 ++++++++----------- ...onTest.checkPageContents.home.approved.txt | 41 ++++++++---------- 4 files changed, 51 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index 57610ce..d050ceb 100644 --- a/README.md +++ b/README.md @@ -132,11 +132,9 @@ There are two modes to the application. The view-metrics script processes metrics stored in the `./nexusiq` directory and presents them as detailed aggregated charts in a web view or in data files in the `./datafiles` directory. -⚠ There must be a `successmetrics.csv` in the `./iqmetrics` directory. +⚠ In order to aggregate and process success metrics a minimum of three data points (weeks or months) are needed. -⚠ In order to aggregate and process metrics a minimum of three data points (weeks or months) are needed. - -⚠ Only fully completed months (or weeks) are included in the data extract. +⚠ Only fully completed months (or weeks) are included in the success metrics data extract. ### View-metrics configuration diff --git a/view-metrics/src/main/java/org/sonatype/cs/metrics/SuccessMetricsApplication.java b/view-metrics/src/main/java/org/sonatype/cs/metrics/SuccessMetricsApplication.java index 7a0e6e4..0bb77f3 100644 --- a/view-metrics/src/main/java/org/sonatype/cs/metrics/SuccessMetricsApplication.java +++ b/view-metrics/src/main/java/org/sonatype/cs/metrics/SuccessMetricsApplication.java @@ -18,6 +18,7 @@ import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; +import java.util.Objects; @SpringBootApplication @EnableJpaRepositories @@ -78,24 +79,19 @@ public void run(String... args) throws Exception { successMetricsFileLoaded = loaderService.loadAllMetrics(activeProfile); - if (isSuccessMetricsFileLoaded()) { - if (runMode.contains("SERVLET")) { - // web app - this.startUp(); + if (runMode.contains("SERVLET")) { + // web app + this.startUp(); + } else { + // non-interactive mode + this.timestamp = + DateTimeFormatter.ofPattern("ddMMyy_HHmm") + .format(LocalDateTime.now(ZoneId.systemDefault())); + if (Objects.equals(activeProfile, "data")) { + createDataFiles(); } else { - // non-interactive mode - this.timestamp = - DateTimeFormatter.ofPattern("ddMMyy_HHmm") - .format(LocalDateTime.now(ZoneId.systemDefault())); - if ("data".equals(activeProfile)) { - createDataFiles(); - } else { - log.error("unknown profile"); - } + log.error("unknown profile"); } - } else { - log.error("No data files found"); - System.exit(-1); } } diff --git a/view-metrics/src/main/resources/templates/home.html b/view-metrics/src/main/resources/templates/home.html index fc8fa2e..e721df1 100644 --- a/view-metrics/src/main/resources/templates/home.html +++ b/view-metrics/src/main/resources/templates/home.html @@ -12,33 +12,29 @@ diff --git a/view-metrics/src/test/resources/org/sonatype/cs/metrics/SuccessMetricsWebApplicationTest.checkPageContents.home.approved.txt b/view-metrics/src/test/resources/org/sonatype/cs/metrics/SuccessMetricsWebApplicationTest.checkPageContents.home.approved.txt index e7aeb0e..6298a84 100644 --- a/view-metrics/src/test/resources/org/sonatype/cs/metrics/SuccessMetricsWebApplicationTest.checkPageContents.home.approved.txt +++ b/view-metrics/src/test/resources/org/sonatype/cs/metrics/SuccessMetricsWebApplicationTest.checkPageContents.home.approved.txt @@ -154,33 +154,29 @@ - \ No newline at end of file +