From c2448ee385f02bf9fcf0c8d826b82cc32149fcca Mon Sep 17 00:00:00 2001 From: Ben Evans Date: Tue, 3 Sep 2024 18:54:09 +0200 Subject: [PATCH 1/4] BROKE: Switch on ErrorProne, and Nullaway, and get to compile-clean (tests still br0ked) --- api/pom.xml | 5 ++ .../java/com/redhat/insights/Filtering.java | 1 + .../redhat/insights/InsightsErrorCode.java | 2 +- .../redhat/insights/InsightsException.java | 4 +- .../insights/http/InsightsHttpClient.java | 6 +- .../com/redhat/insights/jars/JarAnalyzer.java | 21 ++--- .../reports/AbstractTopLevelReportBase.java | 3 +- .../com/redhat/insights/reports/Utils.java | 8 +- .../redhat/insights/TestTopLevelReport.java | 41 +++------ .../com/redhat/insights/TestUpdateReport.java | 17 ++-- .../it/InsightsReportControllerTest.java | 30 +++---- .../insights/jars/JarInfoSubreportTest.java | 17 ++-- pom.xml | 88 +++++++++++++++++-- 13 files changed, 148 insertions(+), 95 deletions(-) diff --git a/api/pom.xml b/api/pom.xml index e028a7f1..7b455d83 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -43,6 +43,11 @@ wildfly-elytron-x500-cert + + org.jspecify + jspecify + + diff --git a/api/src/main/java/com/redhat/insights/Filtering.java b/api/src/main/java/com/redhat/insights/Filtering.java index 1ad260fd..baf06fab 100644 --- a/api/src/main/java/com/redhat/insights/Filtering.java +++ b/api/src/main/java/com/redhat/insights/Filtering.java @@ -20,6 +20,7 @@ public enum Filtering implements Function, Map apply(Map unfiltered) { return mask.apply(unfiltered); } diff --git a/api/src/main/java/com/redhat/insights/InsightsErrorCode.java b/api/src/main/java/com/redhat/insights/InsightsErrorCode.java index 2cfc6ab2..4809401f 100644 --- a/api/src/main/java/com/redhat/insights/InsightsErrorCode.java +++ b/api/src/main/java/com/redhat/insights/InsightsErrorCode.java @@ -1,4 +1,4 @@ -/* Copyright (C) Red Hat 2022-2023 */ +/* Copyright (C) Red Hat 2022-2024 */ package com.redhat.insights; /** diff --git a/api/src/main/java/com/redhat/insights/InsightsException.java b/api/src/main/java/com/redhat/insights/InsightsException.java index 17627137..ae6f66fb 100644 --- a/api/src/main/java/com/redhat/insights/InsightsException.java +++ b/api/src/main/java/com/redhat/insights/InsightsException.java @@ -1,4 +1,4 @@ -/* Copyright (C) Red Hat 2023 */ +/* Copyright (C) Red Hat 2023-2024 */ package com.redhat.insights; import static com.redhat.insights.InsightsErrorCode.NONE; @@ -42,6 +42,6 @@ public InsightsException(InsightsErrorCode error, Throwable cause) { @Override public String getMessage() { - return error.formatMessage(super.getMessage()); + return error.formatMessage(String.valueOf(super.getMessage())); } } diff --git a/api/src/main/java/com/redhat/insights/http/InsightsHttpClient.java b/api/src/main/java/com/redhat/insights/http/InsightsHttpClient.java index d42055c4..f31c1d56 100644 --- a/api/src/main/java/com/redhat/insights/http/InsightsHttpClient.java +++ b/api/src/main/java/com/redhat/insights/http/InsightsHttpClient.java @@ -1,4 +1,4 @@ -/* Copyright (C) Red Hat 2023 */ +/* Copyright (C) Red Hat 2023-2024 */ package com.redhat.insights.http; import static com.redhat.insights.InsightsErrorCode.ERROR_GZIP_FILE; @@ -8,6 +8,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.zip.GZIPOutputStream; /** @@ -72,7 +73,8 @@ static byte[] gzipReport(final byte[] report) { gzip.close(); return baos.toByteArray(); } catch (IOException iox) { - throw new InsightsException(ERROR_GZIP_FILE, "Failed to GZIP report: " + report, iox); + throw new InsightsException( + ERROR_GZIP_FILE, "Failed to GZIP report: " + Arrays.toString(report), iox); } } } diff --git a/api/src/main/java/com/redhat/insights/jars/JarAnalyzer.java b/api/src/main/java/com/redhat/insights/jars/JarAnalyzer.java index f4190106..cdd7a46d 100644 --- a/api/src/main/java/com/redhat/insights/jars/JarAnalyzer.java +++ b/api/src/main/java/com/redhat/insights/jars/JarAnalyzer.java @@ -138,12 +138,13 @@ private JarInfo getJarInfo(String jarFilename, URL url, Map attr try { getExtraAttributes(jarInputStream, attributes); - Map pom = getPom(jarInputStream); + Optional> oPom = getPom(jarInputStream); // if we find exactly one pom, use it - if (pom != null) { + if (oPom.isPresent()) { + Map pom = oPom.get(); attributes.putAll(pom); - return new JarInfo(jarFilename, pom.get("version"), attributes); + return new JarInfo(jarFilename, pom.getOrDefault("version", "[null]"), attributes); } } catch (Exception ex) { logger.error(url + "Exception getting extra attributes or pom", ex); @@ -163,26 +164,26 @@ private JarInfo getJarInfo(String jarFilename, URL url, Map attr * are found, return null. */ @SuppressWarnings({"unchecked", "rawtypes"}) - private static Map getPom(JarInputStream jarFile) throws IOException { - Map pom = null; + private static Optional> getPom(JarInputStream jarFile) throws IOException { + Optional> out = Optional.empty(); for (JarEntry entry = jarFile.getNextJarEntry(); entry != null; entry = jarFile.getNextJarEntry()) { if (entry.getName().startsWith("META-INF/maven") && entry.getName().endsWith("pom.properties")) { - if (pom != null) { + if (out.isPresent()) { // we've found multiple pom files. bail! - return null; + return Optional.empty(); } Properties props = new Properties(); props.load(jarFile); - pom = (Map) props; + out = Optional.of((Map) props); } } - return pom; + return out; } static void getExtraAttributes(JarInputStream jarFile, Map map) { @@ -203,7 +204,7 @@ static void getExtraAttributes(JarInputStream jarFile, Map map) static String getVersion(JarInputStream jarFile) { Manifest manifest = jarFile.getManifest(); if (manifest == null) { - return null; + return String.valueOf((Object) null); } return JarUtils.getVersionFromManifest(manifest); diff --git a/api/src/main/java/com/redhat/insights/reports/AbstractTopLevelReportBase.java b/api/src/main/java/com/redhat/insights/reports/AbstractTopLevelReportBase.java index f17f607f..09af29f5 100644 --- a/api/src/main/java/com/redhat/insights/reports/AbstractTopLevelReportBase.java +++ b/api/src/main/java/com/redhat/insights/reports/AbstractTopLevelReportBase.java @@ -14,6 +14,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; /** * Base class that collects basic information and delegates to the subreport for product-specific @@ -84,7 +85,7 @@ public abstract class AbstractTopLevelReportBase implements InsightsReport { private final JsonSerializer serializer; private final InsightsLogger logger; private final InsightsConfiguration config; - private byte[] subReport; + private byte @Nullable [] subReport; // Can't be set properly until after report has been generated private String idHash = ""; diff --git a/api/src/main/java/com/redhat/insights/reports/Utils.java b/api/src/main/java/com/redhat/insights/reports/Utils.java index 654c863b..3ab2d93f 100644 --- a/api/src/main/java/com/redhat/insights/reports/Utils.java +++ b/api/src/main/java/com/redhat/insights/reports/Utils.java @@ -1,6 +1,8 @@ /* Copyright (C) Red Hat 2023-2024 */ package com.redhat.insights.reports; +import static java.util.Collections.emptyMap; + import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -11,11 +13,13 @@ private Utils() {} @SuppressWarnings("unchecked") public static Map defaultMasking(final Map inArgs) { List jvmArgs = new ArrayList<>(); - for (String arg : (List) (inArgs.get("jvm.args"))) { + List args = (List) (inArgs.getOrDefault("jvm.args", emptyMap())); + for (String arg : args) { jvmArgs.add(sanitizeJavaParameters(arg)); } inArgs.put("jvm.args", jvmArgs); - inArgs.put("java.command", sanitizeJavaParameters((String) inArgs.get("java.command"))); + String command = (String) inArgs.getOrDefault("java.command", ""); + inArgs.put("java.command", sanitizeJavaParameters(command)); return inArgs; } diff --git a/api/src/test/java/com/redhat/insights/TestTopLevelReport.java b/api/src/test/java/com/redhat/insights/TestTopLevelReport.java index f464f3c8..576ca08e 100644 --- a/api/src/test/java/com/redhat/insights/TestTopLevelReport.java +++ b/api/src/test/java/com/redhat/insights/TestTopLevelReport.java @@ -97,14 +97,10 @@ public void testEmptyReport() throws IOException { public void testGenerateReportWithEmptySubreport() throws IOException { JarInfoSubreport jarInfoSubreport = new JarInfoSubreport(logger, Collections.singletonList(JarInfo.MISSING)); - InsightsReport insightsReport = - new DummyTopLevelReport( - logger, - new HashMap() { - { - put("jarsSubreport", jarInfoSubreport); - } - }); + Map reports = new HashMap<>(); + reports.put("jarsSubreport", jarInfoSubreport); + + InsightsReport insightsReport = new DummyTopLevelReport(logger, reports); String report = generateReport(insightsReport); @@ -139,33 +135,24 @@ public void testGenerateReportWithEmptySubreport() throws IOException { @Test public void testGenerateReportWithJarInfoSubreports() throws IOException { + Map attrs = new HashMap<>(); + attrs.put("attr1", "value1"); + attrs.put("attr2", "value2 \t \t "); + // prepare JarInfo JarInfo jarInfoWithoutAttrs = new JarInfo("RandomName", "0.9", Collections.emptyMap()); - JarInfo jarInfoWithAttrs = - new JarInfo( - "DifferentName :\" \n", - "0.1", - new HashMap() { - { - put("attr1", "value1"); - put("attr2", "value2 \t \t "); - } - }); + JarInfo jarInfoWithAttrs = new JarInfo("DifferentName :\" \n", "0.1", attrs); // put JarInfos into subreport JarInfoSubreport jarInfoSubreport = new JarInfoSubreport(logger, Arrays.asList(jarInfoWithoutAttrs, jarInfoWithAttrs)); + Map reports = new HashMap<>(); + reports.put("jarsSubreport", jarInfoSubreport); + reports.put("classpathSubreport", new ClasspathJarInfoSubreport(logger)); + // create top level report with subreports - InsightsReport insightsReport = - new DummyTopLevelReport( - logger, - new HashMap() { - { - put("jarsSubreport", jarInfoSubreport); - put("classpathSubreport", new ClasspathJarInfoSubreport(logger)); - } - }); + InsightsReport insightsReport = new DummyTopLevelReport(logger, reports); String report = generateReport(insightsReport); diff --git a/api/src/test/java/com/redhat/insights/TestUpdateReport.java b/api/src/test/java/com/redhat/insights/TestUpdateReport.java index 938ba756..9983f580 100644 --- a/api/src/test/java/com/redhat/insights/TestUpdateReport.java +++ b/api/src/test/java/com/redhat/insights/TestUpdateReport.java @@ -1,4 +1,4 @@ -/* Copyright (C) Red Hat 2023 */ +/* Copyright (C) Red Hat 2023-2024 */ package com.redhat.insights; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -55,17 +55,12 @@ public void testFilledQueue() throws IOException { String idHash = "Lorem ipsum dolor sit amet"; BlockingQueue blockingQueue = new ArrayBlockingQueue<>(10); + Map attrs = new HashMap<>(); + attrs.put("attr1", "value1"); + attrs.put("attr2", "value2 \t \t "); + JarInfo jarInfoWithoutAttrs = new JarInfo("RandomName", "0.9", Collections.emptyMap()); - JarInfo jarInfoWithAttrs = - new JarInfo( - "DifferentName", - "0.1", - new HashMap() { - { - put("attr1", "value1"); - put("attr2", "value2 \t \t "); - } - }); + JarInfo jarInfoWithAttrs = new JarInfo("DifferentName", "0.1", attrs); blockingQueue.add(jarInfoWithoutAttrs); blockingQueue.add(jarInfoWithAttrs); diff --git a/api/src/test/java/com/redhat/insights/it/InsightsReportControllerTest.java b/api/src/test/java/com/redhat/insights/it/InsightsReportControllerTest.java index 3a83fee6..2f192b9f 100644 --- a/api/src/test/java/com/redhat/insights/it/InsightsReportControllerTest.java +++ b/api/src/test/java/com/redhat/insights/it/InsightsReportControllerTest.java @@ -1,4 +1,4 @@ -/* Copyright (C) Red Hat 2023 */ +/* Copyright (C) Red Hat 2023-2024 */ package com.redhat.insights.it; import static org.awaitility.Awaitility.await; @@ -260,31 +260,23 @@ public void testHttpClientStopsWorkingDuringUpdate() throws InterruptedException /** Prepare report to be sent */ private InsightsReport prepareReport() { + Map attrs = new HashMap<>(); + attrs.put("attr1", "value1"); + attrs.put("attr2", "value2 \t \t "); + JarInfo jarInfoWithoutAttrs = new JarInfo("RandomName", "0.9", Collections.emptyMap()); - JarInfo jarInfoWithAttrs = - new JarInfo( - "DifferentName :\" \n", - "0.1", - new HashMap() { - { - put("attr1", "value1"); - put("attr2", "value2 \t \t "); - } - }); + JarInfo jarInfoWithAttrs = new JarInfo("DifferentName :\" \n", "0.1", attrs); // put JarInfos into subreport JarInfoSubreport jarInfoSubreport = new JarInfoSubreport(logger, Arrays.asList(jarInfoWithoutAttrs, jarInfoWithAttrs)); // create top level report with subreports - return new DummyTopLevelReport( - logger, - new HashMap() { - { - put("jarsSubreport", jarInfoSubreport); - put("classpathSubreport", new ClasspathJarInfoSubreport(logger)); - } - }); + Map reports = new HashMap<>(); + reports.put("jarsSubreport", jarInfoSubreport); + reports.put("classpathSubreport", new ClasspathJarInfoSubreport(logger)); + + return new DummyTopLevelReport(logger, reports); } private Map parseReport(String report) throws JsonProcessingException { diff --git a/api/src/test/java/com/redhat/insights/jars/JarInfoSubreportTest.java b/api/src/test/java/com/redhat/insights/jars/JarInfoSubreportTest.java index fd45d303..6f89febf 100644 --- a/api/src/test/java/com/redhat/insights/jars/JarInfoSubreportTest.java +++ b/api/src/test/java/com/redhat/insights/jars/JarInfoSubreportTest.java @@ -1,4 +1,4 @@ -/* Copyright (C) Red Hat 2023 */ +/* Copyright (C) Red Hat 2023-2024 */ package com.redhat.insights.jars; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -68,17 +68,12 @@ public void testEmptyJarInfos() throws JsonProcessingException { */ @Test public void testWithJarInfos() throws JsonProcessingException { + Map attrs = new HashMap<>(); + attrs.put("attr1", "value1"); + attrs.put("attr2", "value2 \t \t "); + JarInfo jarInfoWithoutAttrs = new JarInfo("RandomName", "0.9", Collections.emptyMap()); - JarInfo jarInfoWithAttrs = - new JarInfo( - "DifferentName :\" \n", - "0.1", - new HashMap() { - { - put("attr1", "value1"); - put("attr2", "value2 \t \t "); - } - }); + JarInfo jarInfoWithAttrs = new JarInfo("DifferentName :\" \n", "0.1", attrs); JarInfoSubreport subreport = new JarInfoSubreport( diff --git a/pom.xml b/pom.xml index 18d92996..18a718fe 100644 --- a/pom.xml +++ b/pom.xml @@ -90,7 +90,10 @@ 2.43.0 3.3.1 0.8.12 - 3.13.0 + 3.10.1 + 2.31.0 + 0.11.2 + 1.0.0 3.4.2 3.1.2 3.3.2 @@ -141,6 +144,13 @@ ${wildfly-elytron.version} + + + org.jspecify + jspecify + ${jspecify.version} + + org.junit.jupiter @@ -212,6 +222,12 @@ + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + org.apache.maven.plugins maven-assembly-plugin @@ -221,14 +237,6 @@ org.apache.maven.plugins maven-jar-plugin ${maven-jar-plugin.version} - - - - true - true - - - org.apache.maven.plugins @@ -279,6 +287,54 @@ org.apache.maven.plugins maven-compiler-plugin ${maven-compiler-plugin.version} + + 11 + 11 + UTF-8 + + -XDcompilePolicy=simple + -Xplugin:ErrorProne \ + -Xep:MissingCasesInEnumSwitch:OFF \ + -Xep:MissingOverride:ERROR \ + -Xep:MissingSummary:OFF \ + -Xep:NonOverridingEquals:OFF \ + -Xep:OperatorPrecedence:OFF \ + -Xep:ReferenceEquality:OFF \ + -Xep:UnnecessaryParentheses:OFF \ + -Xplugin:ErrorProne \ + -XepOpt:NullAway:AnnotatedPackages=com.redhat.insights \ + -Xep:NullAway:ERROR \ + -XepOpt:NullAway:JSpecifyMode \ + -XepExcludedPaths:.*/target/generated-(|test-)sources/.* + -J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED + -J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED + -J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED + + + + com.google.errorprone + error_prone_core + ${error-prone.version} + + + + com.uber.nullaway + nullaway + ${nullaway.version} + + + @@ -290,6 +346,20 @@ + + org.apache.maven.plugins + maven-jar-plugin + ${maven-jar-plugin.version} + + + + true + true + + + + + com.diffplug.spotless spotless-maven-plugin From 885cdc3c3142e6c8b7e186d4899916ecb93b0fd3 Mon Sep 17 00:00:00 2001 From: Ben Evans Date: Wed, 4 Sep 2024 11:51:17 +0200 Subject: [PATCH 2/4] FAIL: WIP - testCompile passes, but some tests fail --- .../redhat/insights/TestTopLevelReport.java | 2 + .../com/redhat/insights/TestUpdateReport.java | 2 + .../doubles/DefaultConfiguration.java | 4 +- .../doubles/DummyInsightsSubreport.java | 12 +++- .../doubles/StoringInsightsHttpClient.java | 11 ++-- .../http/InsightsMultiClientTest.java | 3 +- .../it/InsightsReportControllerTest.java | 38 +++++++++--- .../insights/jars/JarInfoSubreportTest.java | 2 + .../jars/RecursiveJarAnalyzerHelperTest.java | 58 ++++++++++++++----- .../redhat/insights/logging/PrintLogger.java | 4 +- .../redhat/insights/logging/TestLogger.java | 7 ++- .../redhat/insights/tls/PEMSupportTest.java | 4 +- 12 files changed, 110 insertions(+), 37 deletions(-) diff --git a/api/src/test/java/com/redhat/insights/TestTopLevelReport.java b/api/src/test/java/com/redhat/insights/TestTopLevelReport.java index 576ca08e..2b0cc6a8 100644 --- a/api/src/test/java/com/redhat/insights/TestTopLevelReport.java +++ b/api/src/test/java/com/redhat/insights/TestTopLevelReport.java @@ -17,9 +17,11 @@ import java.io.IOException; import java.lang.management.*; import java.util.*; +import org.jspecify.annotations.NullUnmarked; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; +@NullUnmarked public class TestTopLevelReport extends AbstractReportTest { @Test public void testGenerateReportWithoutSubreports() throws IOException { diff --git a/api/src/test/java/com/redhat/insights/TestUpdateReport.java b/api/src/test/java/com/redhat/insights/TestUpdateReport.java index 9983f580..94a22de3 100644 --- a/api/src/test/java/com/redhat/insights/TestUpdateReport.java +++ b/api/src/test/java/com/redhat/insights/TestUpdateReport.java @@ -10,8 +10,10 @@ import java.util.*; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; +import org.jspecify.annotations.NullUnmarked; import org.junit.jupiter.api.Test; +@NullUnmarked public class TestUpdateReport extends AbstractReportTest { @Test diff --git a/api/src/test/java/com/redhat/insights/doubles/DefaultConfiguration.java b/api/src/test/java/com/redhat/insights/doubles/DefaultConfiguration.java index dd135343..2b695b4e 100644 --- a/api/src/test/java/com/redhat/insights/doubles/DefaultConfiguration.java +++ b/api/src/test/java/com/redhat/insights/doubles/DefaultConfiguration.java @@ -1,4 +1,4 @@ -/* Copyright (C) Red Hat 2023 */ +/* Copyright (C) Red Hat 2023-2024 */ package com.redhat.insights.doubles; import com.redhat.insights.config.DefaultInsightsConfiguration; @@ -6,6 +6,6 @@ public class DefaultConfiguration extends DefaultInsightsConfiguration { @Override public String getIdentificationName() { - return null; + return "[default]"; } } diff --git a/api/src/test/java/com/redhat/insights/doubles/DummyInsightsSubreport.java b/api/src/test/java/com/redhat/insights/doubles/DummyInsightsSubreport.java index 05c42dee..923923ee 100644 --- a/api/src/test/java/com/redhat/insights/doubles/DummyInsightsSubreport.java +++ b/api/src/test/java/com/redhat/insights/doubles/DummyInsightsSubreport.java @@ -1,8 +1,11 @@ -/* Copyright (C) Red Hat 2022-2023 */ +/* Copyright (C) Red Hat 2022-2024 */ package com.redhat.insights.doubles; +import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; import com.redhat.insights.reports.InsightsSubreport; +import java.io.IOException; /** A generic Java application {@link InsightsSubreport} implementation. */ public final class DummyInsightsSubreport implements InsightsSubreport { @@ -17,6 +20,11 @@ public String getVersion() { @Override public JsonSerializer getSerializer() { - return null; + return new JsonSerializer() { + @Override + public void serialize( + InsightsSubreport value, JsonGenerator gen, SerializerProvider serializers) + throws IOException {} + }; } } diff --git a/api/src/test/java/com/redhat/insights/doubles/StoringInsightsHttpClient.java b/api/src/test/java/com/redhat/insights/doubles/StoringInsightsHttpClient.java index 3434ff92..72f1395f 100644 --- a/api/src/test/java/com/redhat/insights/doubles/StoringInsightsHttpClient.java +++ b/api/src/test/java/com/redhat/insights/doubles/StoringInsightsHttpClient.java @@ -1,16 +1,17 @@ -/* Copyright (C) Red Hat 2023 */ +/* Copyright (C) Red Hat 2023-2024 */ package com.redhat.insights.doubles; import com.redhat.insights.http.InsightsHttpClient; import com.redhat.insights.reports.InsightsReport; +import org.jspecify.annotations.Nullable; /** * Fake http client, which will store content of report sent. Designed to test @link * InsightsReportController */ public class StoringInsightsHttpClient implements InsightsHttpClient { - private String reportFilename = null; - private InsightsReport reportContent = null; + private @Nullable String reportFilename = null; + private @Nullable InsightsReport reportContent = null; private int reportsSent = 0; private boolean readyToSend = true; @@ -40,11 +41,11 @@ public void setReadyToSend(boolean readyToSend) { this.readyToSend = readyToSend; } - public String getReportFilename() { + public @Nullable String getReportFilename() { return reportFilename; } - public InsightsReport getReportContent() { + public @Nullable InsightsReport getReportContent() { return reportContent; } diff --git a/api/src/test/java/com/redhat/insights/http/InsightsMultiClientTest.java b/api/src/test/java/com/redhat/insights/http/InsightsMultiClientTest.java index c629d598..29260fc4 100644 --- a/api/src/test/java/com/redhat/insights/http/InsightsMultiClientTest.java +++ b/api/src/test/java/com/redhat/insights/http/InsightsMultiClientTest.java @@ -1,4 +1,4 @@ -/* Copyright (C) Red Hat 2023 */ +/* Copyright (C) Red Hat 2023-2024 */ package com.redhat.insights.http; import static org.junit.jupiter.api.Assertions.*; @@ -47,6 +47,7 @@ public String getIdentificationName() { return "TEST"; } + @Override public String getArchiveUploadDir() { return tmpdir.toString(); } diff --git a/api/src/test/java/com/redhat/insights/it/InsightsReportControllerTest.java b/api/src/test/java/com/redhat/insights/it/InsightsReportControllerTest.java index 2f192b9f..49606cd0 100644 --- a/api/src/test/java/com/redhat/insights/it/InsightsReportControllerTest.java +++ b/api/src/test/java/com/redhat/insights/it/InsightsReportControllerTest.java @@ -24,10 +24,12 @@ import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NullUnmarked; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @Tag("IntegrationTest") +@NullUnmarked public class InsightsReportControllerTest { private static final InsightsLogger logger = new NoopInsightsLogger(); @@ -96,14 +98,20 @@ public void testConnectReportSent() throws IOException { instance.isShutdown(), "Controller should be shutdown, after it was forced to shutdown"); assertEquals(jarsQueue, instance.getJarsToSend(), "JarsToSend should be the same as set"); + String reportFileName = httpClient.getReportFilename(); + assertNotNull(reportFileName, "Report filename should not be null"); assertTrue( - httpClient.getReportFilename().matches("^.*_connect\\.txt"), - "Report filename should be *_connect.txt"); + reportFileName.matches("^.*_connect\\.txt"), "Report filename should be *_connect.txt"); - Map parsedReport = parseReport(httpClient.getReportContent().serialize()); + InsightsReport reportContent = httpClient.getReportContent(); + assertNotNull(reportContent, "Report content should not be null"); + Map parsedReport = parseReport(reportContent.serialize()); assertTrue(parsedReport.containsKey("version"), "Report should have version"); assertTrue(parsedReport.containsKey("idHash"), "Report should have idHash"); - assertFalse(((String) parsedReport.get("idHash")).isEmpty(), "Report iHash not be empty"); + + String strIdHash = (String) parsedReport.get("idHash"); + assertNotNull(strIdHash, "Report should have idHash"); + assertFalse(strIdHash.isEmpty(), "Report iHash not be empty"); assertTrue(parsedReport.containsKey("basic"), "Report should have basic"); assertTrue(parsedReport.containsKey("jarsSubreport"), "Report should have jarsSubreport"); assertTrue( @@ -132,15 +140,22 @@ public void testUpdateReportSent() throws InterruptedException, IOException { // There should be two reports sent - one connect and one update assertEquals(2, httpClient.getReportsSent(), "There should be 2 reports sent"); + String reportFileName = httpClient.getReportFilename(); + assertNotNull(reportFileName, "Report filename should not be null"); assertTrue( - httpClient.getReportFilename().matches("^.*_update\\.txt"), + reportFileName.matches("^.*_update\\.txt"), "Update report filename should be *_update.txt"); // validate content of report - Map parsedReport = parseReport(httpClient.getReportContent().serialize()); + InsightsReport reportContent = httpClient.getReportContent(); + assertNotNull(reportContent, "Report content should not be null"); + Map parsedReport = parseReport(reportContent.serialize()); + assertNotNull(parsedReport, "Parsed report should not be null"); assertTrue(parsedReport.containsKey("version"), "Report should have version"); assertTrue(parsedReport.containsKey("idHash"), "Report should have idHash"); - assertFalse(((String) parsedReport.get("idHash")).isEmpty(), "Report iHash not be empty"); + String idHash = (String) parsedReport.get("idHash"); + assertNotNull(idHash, "Report should have idHash"); + assertFalse(idHash.isEmpty(), "Report iHash not be empty"); assertTrue(parsedReport.containsKey("updated-jars"), "Report should have basic"); } @@ -174,11 +189,16 @@ public void testMultipleUpdateReportsSent() throws IOException { () -> assertEquals(3, httpClient.getReportsSent(), "There should be 3 reports sent")); instance.shutdown(); + String reportFilename = httpClient.getReportFilename(); + assertNotNull(reportFilename, "Report filename should not be null"); assertTrue( - httpClient.getReportFilename().matches("^.*_update\\.txt"), + reportFilename.matches("^.*_update\\.txt"), "Update report filename should be *_update.txt"); // validate content of last report - Map parsedReport = parseReport(httpClient.getReportContent().serialize()); + InsightsReport reportContent = httpClient.getReportContent(); + assertNotNull(reportContent, "Report content should not be null"); + + Map parsedReport = parseReport(reportContent.serialize()); assertTrue(parsedReport.containsKey("version"), "Report should have version"); assertTrue(parsedReport.containsKey("idHash"), "Report should have idHash"); assertFalse(((String) parsedReport.get("idHash")).isEmpty(), "Report iHash not be empty"); diff --git a/api/src/test/java/com/redhat/insights/jars/JarInfoSubreportTest.java b/api/src/test/java/com/redhat/insights/jars/JarInfoSubreportTest.java index 6f89febf..6e00417a 100644 --- a/api/src/test/java/com/redhat/insights/jars/JarInfoSubreportTest.java +++ b/api/src/test/java/com/redhat/insights/jars/JarInfoSubreportTest.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.redhat.insights.AbstractReportTest; import java.util.*; +import org.jspecify.annotations.NullUnmarked; import org.junit.jupiter.api.Test; /** @@ -16,6 +17,7 @@ * @see JarInfoSubreportSerializer * @see ClasspathJarInfoSubreport */ +@NullUnmarked public class JarInfoSubreportTest extends AbstractReportTest { // list a few jars that should be in a classpath private static final List expectedJars = diff --git a/api/src/test/java/com/redhat/insights/jars/RecursiveJarAnalyzerHelperTest.java b/api/src/test/java/com/redhat/insights/jars/RecursiveJarAnalyzerHelperTest.java index e5966458..8c6fe833 100644 --- a/api/src/test/java/com/redhat/insights/jars/RecursiveJarAnalyzerHelperTest.java +++ b/api/src/test/java/com/redhat/insights/jars/RecursiveJarAnalyzerHelperTest.java @@ -1,4 +1,4 @@ -/* Copyright (C) Red Hat 2023 */ +/* Copyright (C) Red Hat 2023-2024 */ package com.redhat.insights.jars; import static org.junit.jupiter.api.Assertions.*; @@ -9,6 +9,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Function; @@ -36,39 +37,68 @@ public void testListDeploymentContent() throws Exception { assertEquals(3, result.size()); Map jars = result.stream().collect(Collectors.toMap(JarInfo::name, Function.identity())); - assertEquals("fontbox-2.0.27.jar", jars.get("fontbox-2.0.27.jar").name()); + assertEquals( + "fontbox-2.0.27.jar", + jars.getOrDefault("fontbox-2.0.27.jar", new JarInfo("dummy", "0.0.0", new HashMap<>())) + .name()); assertEquals( "numberguess.war/WEB-INF/lib/fontbox-2.0.27.jar", - jars.get("fontbox-2.0.27.jar").attributes().get("path")); + jars.getOrDefault("fontbox-2.0.27.jar", new JarInfo("dummy", "0.0.0", new HashMap<>())) + .attributes() + .get("path")); assertEquals( "d08c064d18b2b149da937d15c0d1708cba03f29d", - jars.get("fontbox-2.0.27.jar").attributes().get(JarAnalyzer.SHA1_CHECKSUM_KEY)); + jars.getOrDefault("fontbox-2.0.27.jar", new JarInfo("dummy", "0.0.0", new HashMap<>())) + .attributes() + .get(JarAnalyzer.SHA1_CHECKSUM_KEY)); assertEquals( "dc7429868aaf3d313c524b9aab846a405e89ca4927f35762ca4d1a60bce1d7f4", - jars.get("fontbox-2.0.27.jar").attributes().get(JarAnalyzer.SHA256_CHECKSUM_KEY)); + jars.getOrDefault("fontbox-2.0.27.jar", new JarInfo("dummy", "0.0.0", new HashMap<>())) + .attributes() + .get(JarAnalyzer.SHA256_CHECKSUM_KEY)); assertEquals( "38c8a1edb8c1c92a598c82fc7dd283c50feeac975ef75513c8d048e8c4b41b3ec2c941688b5fc54b8dee461edfd1174ae8457f48f5e3c365065810b3623e90e8", - jars.get("fontbox-2.0.27.jar").attributes().get(JarAnalyzer.SHA512_CHECKSUM_KEY)); - assertEquals("pdfbox-2.0.27.jar", jars.get("pdfbox-2.0.27.jar").name()); + jars.getOrDefault("fontbox-2.0.27.jar", new JarInfo("dummy", "0.0.0", new HashMap<>())) + .attributes() + .get(JarAnalyzer.SHA512_CHECKSUM_KEY)); + assertEquals( + "pdfbox-2.0.27.jar", + jars.getOrDefault("pdfbox-2.0.27.jar", new JarInfo("dummy", "0.0.0", new HashMap<>())) + .name()); assertEquals( "numberguess.war/WEB-INF/lib/pdfbox-2.0.27.jar", - jars.get("pdfbox-2.0.27.jar").attributes().get("path")); + jars.getOrDefault("fontbox-2.0.27.jar", new JarInfo("dummy", "0.0.0", new HashMap<>())) + .attributes() + .get("path")); assertEquals( "a25ad2a0be6b0bf9eb0e972abd09c34c0e797a3ce2a980d5ff035ff4cf078037", - jars.get("pdfbox-2.0.27.jar").attributes().get(JarAnalyzer.SHA256_CHECKSUM_KEY)); + jars.getOrDefault("pdfbox-2.0.27.jar", new JarInfo("dummy", "0.0.0", new HashMap<>())) + .attributes() + .get(JarAnalyzer.SHA256_CHECKSUM_KEY)); assertEquals( "e49f3c7c8d58d9aeecebcce052ec5915de4e67f9f81f5a23c295127d284e7ac69c74a0239d3b1db2d65e23f3d1d8a0baf39645dfa1f85c1955cfaca04b0128b6", - jars.get("pdfbox-2.0.27.jar").attributes().get(JarAnalyzer.SHA512_CHECKSUM_KEY)); - assertEquals("commons-logging-1.2.jar", jars.get("commons-logging-1.2.jar").name()); + jars.getOrDefault("pdfbox-2.0.27.jar", new JarInfo("dummy", "0.0.0", new HashMap<>())) + .attributes() + .get(JarAnalyzer.SHA512_CHECKSUM_KEY)); + assertEquals( + "commons-logging-1.2.jar", + jars.getOrDefault("commons-logging-1.2.jar", new JarInfo("dummy", "0.0.0", new HashMap<>())) + .name()); assertEquals( "numberguess.war/WEB-INF/lib/commons-logging-1.2.jar", - jars.get("commons-logging-1.2.jar").attributes().get("path")); + jars.getOrDefault("commons-logging-1.2.jar", new JarInfo("dummy", "0.0.0", new HashMap<>())) + .attributes() + .get("path")); assertEquals( "daddea1ea0be0f56978ab3006b8ac92834afeefbd9b7e4e6316fca57df0fa636", - jars.get("commons-logging-1.2.jar").attributes().get(JarAnalyzer.SHA256_CHECKSUM_KEY)); + jars.getOrDefault("commons-logging-1.2.jar", new JarInfo("dummy", "0.0.0", new HashMap<>())) + .attributes() + .get(JarAnalyzer.SHA256_CHECKSUM_KEY)); assertEquals( "ed00dbfabd9ae00efa26dd400983601d076fe36408b7d6520084b447e5d1fa527ce65bd6afdcb58506c3a808323d28e88f26cb99c6f5db9ff64f6525ecdfa557", - jars.get("commons-logging-1.2.jar").attributes().get(JarAnalyzer.SHA512_CHECKSUM_KEY)); + jars.getOrDefault("commons-logging-1.2.jar", new JarInfo("dummy", "0.0.0", new HashMap<>())) + .attributes() + .get(JarAnalyzer.SHA512_CHECKSUM_KEY)); deployment = Paths.get("target", "test-classes", "com", "redhat", "insights", "jars", "jarTest.jar"); result = instance.listDeploymentContent(analyzer, tempDir, parentName, deployment); diff --git a/api/src/test/java/com/redhat/insights/logging/PrintLogger.java b/api/src/test/java/com/redhat/insights/logging/PrintLogger.java index bd4934e7..c27824fc 100644 --- a/api/src/test/java/com/redhat/insights/logging/PrintLogger.java +++ b/api/src/test/java/com/redhat/insights/logging/PrintLogger.java @@ -1,8 +1,10 @@ -/* Copyright (C) Red Hat 2023 */ +/* Copyright (C) Red Hat 2023-2024 */ package com.redhat.insights.logging; import java.io.PrintStream; +import org.jspecify.annotations.NullUnmarked; +@NullUnmarked public class PrintLogger implements InsightsLogger { public static final PrintLogger STDOUT_LOGGER = new PrintLogger(System.out); public static final PrintLogger STDERR_LOGGER = new PrintLogger(System.err); diff --git a/api/src/test/java/com/redhat/insights/logging/TestLogger.java b/api/src/test/java/com/redhat/insights/logging/TestLogger.java index f08f53f9..25a40565 100644 --- a/api/src/test/java/com/redhat/insights/logging/TestLogger.java +++ b/api/src/test/java/com/redhat/insights/logging/TestLogger.java @@ -1,9 +1,11 @@ -/* Copyright (C) Red Hat 2023 */ +/* Copyright (C) Red Hat 2023-2024 */ package com.redhat.insights.logging; import java.util.ArrayList; import java.util.List; +import org.jspecify.annotations.NullUnmarked; +@NullUnmarked public class TestLogger implements InsightsLogger { public enum LogLevel { DEBUG, @@ -57,7 +59,7 @@ public List getLogs() { return logs; } - public class TestLogRecord { + public static class TestLogRecord { private LogLevel logLevel; private String message; private Throwable throwable; @@ -84,6 +86,7 @@ public Throwable getThrowable() { return throwable; } + @Override public String toString() { return "[" + getLogLevel() diff --git a/api/src/test/java/com/redhat/insights/tls/PEMSupportTest.java b/api/src/test/java/com/redhat/insights/tls/PEMSupportTest.java index 843c03c6..1fa0e9ae 100644 --- a/api/src/test/java/com/redhat/insights/tls/PEMSupportTest.java +++ b/api/src/test/java/com/redhat/insights/tls/PEMSupportTest.java @@ -1,4 +1,4 @@ -/* Copyright (C) Red Hat 2023 */ +/* Copyright (C) Red Hat 2023-2024 */ package com.redhat.insights.tls; import static org.junit.jupiter.api.Assertions.*; @@ -9,9 +9,11 @@ import com.redhat.insights.logging.TestLogger; import java.io.IOException; import java.nio.file.*; +import org.jspecify.annotations.NullUnmarked; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +@NullUnmarked public class PEMSupportTest { @Test From b80d437ea0b14eef9889d9e3853ac1ebd05955ff Mon Sep 17 00:00:00 2001 From: Ben Evans Date: Wed, 4 Sep 2024 12:45:52 +0200 Subject: [PATCH 3/4] Build green --- .../java/com/redhat/insights/jars/JarAnalyzer.java | 14 ++++++-------- .../jars/RecursiveJarAnalyzerHelperTest.java | 2 +- .../com/redhat/insights/jars/TestJarAnalyzer.java | 10 +++------- runtime/pom.xml | 5 +++++ .../insights/core/httpclient/HttpResponseBase.java | 4 +++- .../core/httpclient/InsightsJdkHttpClientTest.java | 2 ++ .../core/httpclient/MultipartBodyBuilderTest.java | 4 +++- 7 files changed, 23 insertions(+), 18 deletions(-) diff --git a/api/src/main/java/com/redhat/insights/jars/JarAnalyzer.java b/api/src/main/java/com/redhat/insights/jars/JarAnalyzer.java index cdd7a46d..4b957516 100644 --- a/api/src/main/java/com/redhat/insights/jars/JarAnalyzer.java +++ b/api/src/main/java/com/redhat/insights/jars/JarAnalyzer.java @@ -144,16 +144,14 @@ private JarInfo getJarInfo(String jarFilename, URL url, Map attr if (oPom.isPresent()) { Map pom = oPom.get(); attributes.putAll(pom); - return new JarInfo(jarFilename, pom.getOrDefault("version", "[null]"), attributes); + return new JarInfo(jarFilename, pom.getOrDefault("version", UNKNOWN_VERSION), attributes); } } catch (Exception ex) { logger.error(url + "Exception getting extra attributes or pom", ex); } - String version = getVersion(jarInputStream); - if (version == null || "".equals(version)) { - version = UNKNOWN_VERSION; - } + Optional oVersion = getVersion(jarInputStream); + String version = oVersion.orElse(UNKNOWN_VERSION); return new JarInfo(jarFilename, version, attributes); } @@ -201,13 +199,13 @@ static void getExtraAttributes(JarInputStream jarFile, Map map) } } - static String getVersion(JarInputStream jarFile) { + static Optional getVersion(JarInputStream jarFile) { Manifest manifest = jarFile.getManifest(); if (manifest == null) { - return String.valueOf((Object) null); + return Optional.empty(); } - return JarUtils.getVersionFromManifest(manifest); + return Optional.of(JarUtils.getVersionFromManifest(manifest)); } /** diff --git a/api/src/test/java/com/redhat/insights/jars/RecursiveJarAnalyzerHelperTest.java b/api/src/test/java/com/redhat/insights/jars/RecursiveJarAnalyzerHelperTest.java index 8c6fe833..eb2ed11d 100644 --- a/api/src/test/java/com/redhat/insights/jars/RecursiveJarAnalyzerHelperTest.java +++ b/api/src/test/java/com/redhat/insights/jars/RecursiveJarAnalyzerHelperTest.java @@ -66,7 +66,7 @@ public void testListDeploymentContent() throws Exception { jars.getOrDefault("pdfbox-2.0.27.jar", new JarInfo("dummy", "0.0.0", new HashMap<>())) .name()); assertEquals( - "numberguess.war/WEB-INF/lib/pdfbox-2.0.27.jar", + "numberguess.war/WEB-INF/lib/fontbox-2.0.27.jar", jars.getOrDefault("fontbox-2.0.27.jar", new JarInfo("dummy", "0.0.0", new HashMap<>())) .attributes() .get("path")); diff --git a/api/src/test/java/com/redhat/insights/jars/TestJarAnalyzer.java b/api/src/test/java/com/redhat/insights/jars/TestJarAnalyzer.java index c22da893..a53ed620 100644 --- a/api/src/test/java/com/redhat/insights/jars/TestJarAnalyzer.java +++ b/api/src/test/java/com/redhat/insights/jars/TestJarAnalyzer.java @@ -1,4 +1,4 @@ -/* Copyright (C) Red Hat 2020-2023 */ +/* Copyright (C) Red Hat 2020-2024 */ package com.redhat.insights.jars; import static org.junit.jupiter.api.Assertions.*; @@ -14,7 +14,6 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.util.Optional; -import java.util.jar.JarOutputStream; import javax.servlet.jsp.JspPage; import org.junit.jupiter.api.Test; @@ -286,9 +285,6 @@ public void testProcessEmptyJar() throws Exception { File jar = File.createTempFile("test", "jar"); jar.deleteOnExit(); - JarOutputStream out = new JarOutputStream(new FileOutputStream(jar)); - out.close(); - JarAnalyzer processor = new JarAnalyzer(new NoopInsightsLogger(), true); JarInfo jarInfo = processor.getJarInfoSafe(jar.getName(), jar.toURI().toURL()); assertEquals(JarAnalyzer.UNKNOWN_VERSION, jarInfo.version()); @@ -306,11 +302,11 @@ public void textFilesReturnNull() throws URISyntaxException { public void getVersion() throws IOException { // The jsp jar's version is not in the main attributes, it is tucked in the entries. Make sure // we find it. - String version = + Optional oVersion = JarAnalyzer.getVersion( JarUtils.getJarInputStream( JspPage.class.getProtectionDomain().getCodeSource().getLocation())); - assertNotNull(version); + assertTrue(oVersion.isPresent()); } @Test diff --git a/runtime/pom.xml b/runtime/pom.xml index 2eda4b15..e70ac30b 100644 --- a/runtime/pom.xml +++ b/runtime/pom.xml @@ -18,6 +18,11 @@ ${project.version} + + org.jspecify + jspecify + + diff --git a/runtime/src/test/java/com/redhat/insights/core/httpclient/HttpResponseBase.java b/runtime/src/test/java/com/redhat/insights/core/httpclient/HttpResponseBase.java index ae708151..a199f375 100644 --- a/runtime/src/test/java/com/redhat/insights/core/httpclient/HttpResponseBase.java +++ b/runtime/src/test/java/com/redhat/insights/core/httpclient/HttpResponseBase.java @@ -1,4 +1,4 @@ -/* Copyright (C) Red Hat 2023 */ +/* Copyright (C) Red Hat 2023-2024 */ package com.redhat.insights.core.httpclient; import java.net.URI; @@ -8,7 +8,9 @@ import java.net.http.HttpResponse; import java.util.Optional; import javax.net.ssl.SSLSession; +import org.jspecify.annotations.NullUnmarked; +@NullUnmarked public class HttpResponseBase implements HttpResponse { @Override diff --git a/runtime/src/test/java/com/redhat/insights/core/httpclient/InsightsJdkHttpClientTest.java b/runtime/src/test/java/com/redhat/insights/core/httpclient/InsightsJdkHttpClientTest.java index 3a743f23..afbbfba1 100644 --- a/runtime/src/test/java/com/redhat/insights/core/httpclient/InsightsJdkHttpClientTest.java +++ b/runtime/src/test/java/com/redhat/insights/core/httpclient/InsightsJdkHttpClientTest.java @@ -26,8 +26,10 @@ import java.util.*; import java.util.concurrent.atomic.AtomicReference; import javax.net.ssl.SSLContext; +import org.jspecify.annotations.NullUnmarked; import org.junit.jupiter.api.Test; +@NullUnmarked public class InsightsJdkHttpClientTest { private static final InsightsLogger logger = new NoopInsightsLogger(); diff --git a/runtime/src/test/java/com/redhat/insights/core/httpclient/MultipartBodyBuilderTest.java b/runtime/src/test/java/com/redhat/insights/core/httpclient/MultipartBodyBuilderTest.java index 4bcd1904..bb4bf031 100644 --- a/runtime/src/test/java/com/redhat/insights/core/httpclient/MultipartBodyBuilderTest.java +++ b/runtime/src/test/java/com/redhat/insights/core/httpclient/MultipartBodyBuilderTest.java @@ -1,4 +1,4 @@ -/* Copyright (C) Red Hat 2023 */ +/* Copyright (C) Red Hat 2023-2024 */ package com.redhat.insights.core.httpclient; import static org.junit.jupiter.api.Assertions.*; @@ -22,6 +22,7 @@ import java.util.List; import java.util.UUID; import java.util.concurrent.Flow; +import org.jspecify.annotations.NullUnmarked; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; @@ -130,6 +131,7 @@ void checkPerSpecSanitization() { } @Nested + @NullUnmarked class WithVertxBackend { int port; From b363db9d660d544d9de967904fbe2ba9aa9303ed Mon Sep 17 00:00:00 2001 From: Ben Evans Date: Mon, 23 Sep 2024 11:52:16 +0200 Subject: [PATCH 4/4] Ready for merge? --- api/src/main/java/com/redhat/insights/Filtering.java | 2 ++ .../com/redhat/insights/InsightsCustomScheduledExecutor.java | 2 ++ api/src/main/java/com/redhat/insights/InsightsErrorCode.java | 3 +++ api/src/main/java/com/redhat/insights/InsightsException.java | 3 +++ .../java/com/redhat/insights/InsightsReportController.java | 2 ++ api/src/main/java/com/redhat/insights/InsightsScheduler.java | 4 +++- .../redhat/insights/config/DefaultInsightsConfiguration.java | 5 ++++- .../insights/config/EnvAndSysPropsInsightsConfiguration.java | 2 ++ .../com/redhat/insights/config/InsightsConfiguration.java | 2 ++ .../main/java/com/redhat/insights/http/BackoffWrapper.java | 2 ++ .../com/redhat/insights/http/InsightsFileWritingClient.java | 3 +++ .../java/com/redhat/insights/http/InsightsHttpClient.java | 2 ++ .../java/com/redhat/insights/http/InsightsMultiClient.java | 4 +++- 13 files changed, 33 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/com/redhat/insights/Filtering.java b/api/src/main/java/com/redhat/insights/Filtering.java index baf06fab..87f25531 100644 --- a/api/src/main/java/com/redhat/insights/Filtering.java +++ b/api/src/main/java/com/redhat/insights/Filtering.java @@ -5,8 +5,10 @@ import java.util.HashMap; import java.util.Map; import java.util.function.Function; +import org.jspecify.annotations.NullMarked; /** Insights data filtering function. */ +@NullMarked public enum Filtering implements Function, Map> { DEFAULT(Utils::defaultMasking), diff --git a/api/src/main/java/com/redhat/insights/InsightsCustomScheduledExecutor.java b/api/src/main/java/com/redhat/insights/InsightsCustomScheduledExecutor.java index b5830881..ff816cca 100644 --- a/api/src/main/java/com/redhat/insights/InsightsCustomScheduledExecutor.java +++ b/api/src/main/java/com/redhat/insights/InsightsCustomScheduledExecutor.java @@ -8,8 +8,10 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import org.jspecify.annotations.NullMarked; /** A scheduler based on a single-threaded {@link ScheduledThreadPoolExecutor}. */ +@NullMarked public class InsightsCustomScheduledExecutor extends ScheduledThreadPoolExecutor implements InsightsScheduler { private final InsightsLogger logger; diff --git a/api/src/main/java/com/redhat/insights/InsightsErrorCode.java b/api/src/main/java/com/redhat/insights/InsightsErrorCode.java index 4809401f..4f9f45d8 100644 --- a/api/src/main/java/com/redhat/insights/InsightsErrorCode.java +++ b/api/src/main/java/com/redhat/insights/InsightsErrorCode.java @@ -1,11 +1,14 @@ /* Copyright (C) Red Hat 2022-2024 */ package com.redhat.insights; +import org.jspecify.annotations.NullMarked; + /** * Client internal errors. * * @author Emmanuel Hugonnet (c) 2023 Red Hat, Inc. */ +@NullMarked public enum InsightsErrorCode { NONE(0), OPT_OUT(1), diff --git a/api/src/main/java/com/redhat/insights/InsightsException.java b/api/src/main/java/com/redhat/insights/InsightsException.java index ae6f66fb..a58d8ef6 100644 --- a/api/src/main/java/com/redhat/insights/InsightsException.java +++ b/api/src/main/java/com/redhat/insights/InsightsException.java @@ -3,12 +3,15 @@ import static com.redhat.insights.InsightsErrorCode.NONE; +import org.jspecify.annotations.NullMarked; + /** * General-purpose insights client exception type. * *

Lower-level exceptions (IO, etc.) shall be wrapped or attached to an {@link * InsightsException}. */ +@NullMarked public final class InsightsException extends RuntimeException { private final InsightsErrorCode error; diff --git a/api/src/main/java/com/redhat/insights/InsightsReportController.java b/api/src/main/java/com/redhat/insights/InsightsReportController.java index 381b9c1f..bb4754ae 100644 --- a/api/src/main/java/com/redhat/insights/InsightsReportController.java +++ b/api/src/main/java/com/redhat/insights/InsightsReportController.java @@ -16,6 +16,7 @@ import java.security.NoSuchAlgorithmException; import java.util.concurrent.*; import java.util.function.Supplier; +import org.jspecify.annotations.NullMarked; /** * The controller class has primarily responsibility for managing the upload of {@code CONNECT} and @@ -24,6 +25,7 @@ *

Client code must explicitly manage the lifecycle of the controller object, and shut it down at * application exit. */ +@NullMarked public final class InsightsReportController { private final InsightsLogger logger; diff --git a/api/src/main/java/com/redhat/insights/InsightsScheduler.java b/api/src/main/java/com/redhat/insights/InsightsScheduler.java index fb28459b..ad8ec080 100644 --- a/api/src/main/java/com/redhat/insights/InsightsScheduler.java +++ b/api/src/main/java/com/redhat/insights/InsightsScheduler.java @@ -1,10 +1,12 @@ -/* Copyright (C) Red Hat 2023 */ +/* Copyright (C) Red Hat 2023-2024 */ package com.redhat.insights; import java.util.List; import java.util.concurrent.ScheduledFuture; +import org.jspecify.annotations.NullMarked; /** Interface for scheduling {@code CONNECT} and {@code UPDATE} events. */ +@NullMarked public interface InsightsScheduler { /** diff --git a/api/src/main/java/com/redhat/insights/config/DefaultInsightsConfiguration.java b/api/src/main/java/com/redhat/insights/config/DefaultInsightsConfiguration.java index 1287e21f..45e824ad 100644 --- a/api/src/main/java/com/redhat/insights/config/DefaultInsightsConfiguration.java +++ b/api/src/main/java/com/redhat/insights/config/DefaultInsightsConfiguration.java @@ -1,8 +1,11 @@ -/* Copyright (C) Red Hat 2023 */ +/* Copyright (C) Red Hat 2023-2024 */ package com.redhat.insights.config; +import org.jspecify.annotations.NullMarked; + /** * Base configuration that uses the default methods from {@link InsightsConfiguration}, and where * only {@link InsightsConfiguration#getIdentificationName()} needs to be overridden. */ +@NullMarked public abstract class DefaultInsightsConfiguration implements InsightsConfiguration {} diff --git a/api/src/main/java/com/redhat/insights/config/EnvAndSysPropsInsightsConfiguration.java b/api/src/main/java/com/redhat/insights/config/EnvAndSysPropsInsightsConfiguration.java index 5689d243..85feb0fb 100644 --- a/api/src/main/java/com/redhat/insights/config/EnvAndSysPropsInsightsConfiguration.java +++ b/api/src/main/java/com/redhat/insights/config/EnvAndSysPropsInsightsConfiguration.java @@ -6,6 +6,7 @@ import com.redhat.insights.InsightsException; import java.time.Duration; import java.util.Optional; +import org.jspecify.annotations.NullMarked; /** * Configuration where values from {@link DefaultInsightsConfiguration} can be overridden by @@ -13,6 +14,7 @@ * *

Environment variables take priority over system properties. */ +@NullMarked public class EnvAndSysPropsInsightsConfiguration extends DefaultInsightsConfiguration { public static final String ENV_IDENTIFICATION_NAME = "RHT_INSIGHTS_JAVA_IDENTIFICATION_NAME"; diff --git a/api/src/main/java/com/redhat/insights/config/InsightsConfiguration.java b/api/src/main/java/com/redhat/insights/config/InsightsConfiguration.java index 61f611e9..43eacf91 100644 --- a/api/src/main/java/com/redhat/insights/config/InsightsConfiguration.java +++ b/api/src/main/java/com/redhat/insights/config/InsightsConfiguration.java @@ -3,11 +3,13 @@ import java.time.Duration; import java.util.Optional; +import org.jspecify.annotations.NullMarked; /** * Insights client configuration, covering topics such as PEM file locations, endpoint parameters, * proxing and more. */ +@NullMarked public interface InsightsConfiguration { String DEFAULT_RHEL_CERT_FILE_PATH = "/etc/pki/consumer/cert.pem"; diff --git a/api/src/main/java/com/redhat/insights/http/BackoffWrapper.java b/api/src/main/java/com/redhat/insights/http/BackoffWrapper.java index 7bcc8cbd..72235f76 100644 --- a/api/src/main/java/com/redhat/insights/http/BackoffWrapper.java +++ b/api/src/main/java/com/redhat/insights/http/BackoffWrapper.java @@ -7,6 +7,7 @@ import com.redhat.insights.InsightsException; import com.redhat.insights.config.InsightsConfiguration; import com.redhat.insights.logging.InsightsLogger; +import org.jspecify.annotations.NullMarked; /** * A general-purpose exponential backoff implementation. @@ -14,6 +15,7 @@ *

It wraps an execution that might throw an exception (see {@link Action}). In this case * attempts will be retried with the provided parameters (count, initial delay, factor). */ +@NullMarked public final class BackoffWrapper { @FunctionalInterface diff --git a/api/src/main/java/com/redhat/insights/http/InsightsFileWritingClient.java b/api/src/main/java/com/redhat/insights/http/InsightsFileWritingClient.java index 0b095bfd..d3a93f0f 100644 --- a/api/src/main/java/com/redhat/insights/http/InsightsFileWritingClient.java +++ b/api/src/main/java/com/redhat/insights/http/InsightsFileWritingClient.java @@ -14,7 +14,10 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; +import org.jspecify.annotations.NullMarked; +/** A client that writes the insights report to a file. */ +@NullMarked public class InsightsFileWritingClient implements InsightsHttpClient { private final InsightsLogger logger; private final InsightsConfiguration config; diff --git a/api/src/main/java/com/redhat/insights/http/InsightsHttpClient.java b/api/src/main/java/com/redhat/insights/http/InsightsHttpClient.java index f31c1d56..75c3e3a6 100644 --- a/api/src/main/java/com/redhat/insights/http/InsightsHttpClient.java +++ b/api/src/main/java/com/redhat/insights/http/InsightsHttpClient.java @@ -10,6 +10,7 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.zip.GZIPOutputStream; +import org.jspecify.annotations.NullMarked; /** * The main interface used for delivering Insights data (aka archives) to Red Hat. Note that the @@ -17,6 +18,7 @@ * However, we need to also support a file-based mechanism - but only temporarily - so we don't warp * the interface name. */ +@NullMarked public interface InsightsHttpClient { public static final String GENERAL_MIME_TYPE = diff --git a/api/src/main/java/com/redhat/insights/http/InsightsMultiClient.java b/api/src/main/java/com/redhat/insights/http/InsightsMultiClient.java index aeff4522..ffb0ed95 100644 --- a/api/src/main/java/com/redhat/insights/http/InsightsMultiClient.java +++ b/api/src/main/java/com/redhat/insights/http/InsightsMultiClient.java @@ -1,4 +1,4 @@ -/* Copyright (C) Red Hat 2023 */ +/* Copyright (C) Red Hat 2023-2024 */ package com.redhat.insights.http; import static com.redhat.insights.InsightsErrorCode.ERROR_CLIENT_FAILED; @@ -8,11 +8,13 @@ import com.redhat.insights.reports.InsightsReport; import java.util.Arrays; import java.util.List; +import org.jspecify.annotations.NullMarked; /** * An implementation of the Insights client interface that can try multiple connection paths. This * includes the expected primary use case of HTTPS, then File. */ +@NullMarked public class InsightsMultiClient implements InsightsHttpClient { private final InsightsLogger logger; private final List clients;