From c6fcc90e2d7c67e89bf65b31f01ce7180ca97b42 Mon Sep 17 00:00:00 2001 From: Artsiom Chapialiou Date: Sun, 27 Mar 2022 16:08:48 +0300 Subject: [PATCH 1/3] feat: provide `analysisContext` key (`getAnalysis` request) for better tracking/logging on backend --- CHANGELOG.md | 1 + .../javaclient/DeepCodeRestApiImplTest.java | 10 ++- .../deepcode/javaclient/DeepCodeRestApi.java | 9 +- .../javaclient/DeepCodeRestApiImpl.java | 11 ++- .../javaclient/core/AnalysisDataBase.java | 5 +- .../javaclient/core/DeepCodeParamsBase.java | 7 ++ .../requests/GetAnalysisRequest.java | 88 +++++++++++++++---- .../javaclient/core/AnalysisDataTest.java | 20 ++++- .../core/mocks/DeepCodeParamsMock.java | 2 +- .../core/mocks/DeepCodeRestApiMock.java | 10 ++- 10 files changed, 137 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4f1f35..17cfbe0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - fix: avoid remove operation for empty immutable List - fix: check file in marker for nullability before proceed - feat: provide unique (per project) `shard` to getAnalysis call +- feat: provide `analysisContext` key (`getAnalysis` request) for better tracking/logging on backend - chore: reshape/refactor REST API wrapper to be replaceable through constructor base DI ## [2.2.1] - 2021-12-10 diff --git a/src/integTest/java/ai/deepcode/javaclient/DeepCodeRestApiImplTest.java b/src/integTest/java/ai/deepcode/javaclient/DeepCodeRestApiImplTest.java index ee9e95e..2cb4874 100644 --- a/src/integTest/java/ai/deepcode/javaclient/DeepCodeRestApiImplTest.java +++ b/src/integTest/java/ai/deepcode/javaclient/DeepCodeRestApiImplTest.java @@ -372,7 +372,15 @@ private GetAnalysisResponse doAnalysisAndWait(List analysedFiles, Intege throws InterruptedException { GetAnalysisResponse response = null; for (int i = 0; i < 120; i++) { - response = restApiClient.getAnalysis(loggedToken, bundleId, severity, analysedFiles, bundleId); + response = restApiClient.getAnalysis( + loggedToken, + bundleId, + severity, + analysedFiles, + bundleId, + "test-java-client-ide", + "test-java-client-org" + ); if (response.getStatus().equals("COMPLETE")) break; Thread.sleep(1000); } diff --git a/src/main/java/ai/deepcode/javaclient/DeepCodeRestApi.java b/src/main/java/ai/deepcode/javaclient/DeepCodeRestApi.java index 7a09eec..584b448 100644 --- a/src/main/java/ai/deepcode/javaclient/DeepCodeRestApi.java +++ b/src/main/java/ai/deepcode/javaclient/DeepCodeRestApi.java @@ -57,7 +57,14 @@ void setBaseUrl( * @return {@link GetAnalysisResponse} instance} */ @NotNull GetAnalysisResponse getAnalysis( - String token, String bundleId, Integer severity, List filesToAnalyse, String shard); + String token, + String bundleId, + Integer severity, + List filesToAnalyse, + String shard, + String ideProductName, + String orgDisplayName + ); /** * Requests current filtering options for uploaded bundles. diff --git a/src/main/java/ai/deepcode/javaclient/DeepCodeRestApiImpl.java b/src/main/java/ai/deepcode/javaclient/DeepCodeRestApiImpl.java index 2a2fd9b..e8ea8d8 100644 --- a/src/main/java/ai/deepcode/javaclient/DeepCodeRestApiImpl.java +++ b/src/main/java/ai/deepcode/javaclient/DeepCodeRestApiImpl.java @@ -335,12 +335,19 @@ Call doGetAnalysis( @Override @NotNull public GetAnalysisResponse getAnalysis( - String token, String bundleId, Integer severity, List filesToAnalyse, String shard) { + String token, + String bundleId, + Integer severity, + List filesToAnalyse, + String shard, + String ideProductName, + String orgDisplayName + ) { GetAnalysisCall getAnalysisCall = retrofit.create(GetAnalysisCall.class); try { Response retrofitResponse = getAnalysisCall - .doGetAnalysis(token, new GetAnalysisRequest(bundleId, filesToAnalyse, severity, shard)) + .doGetAnalysis(token, new GetAnalysisRequest(bundleId, filesToAnalyse, severity, shard, ideProductName, orgDisplayName)) .execute(); GetAnalysisResponse result = retrofitResponse.body(); if (result == null) result = new GetAnalysisResponse(); diff --git a/src/main/java/ai/deepcode/javaclient/core/AnalysisDataBase.java b/src/main/java/ai/deepcode/javaclient/core/AnalysisDataBase.java index afab58e..425063e 100644 --- a/src/main/java/ai/deepcode/javaclient/core/AnalysisDataBase.java +++ b/src/main/java/ai/deepcode/javaclient/core/AnalysisDataBase.java @@ -593,8 +593,9 @@ private GetAnalysisResponse doGetAnalysis( bundleId, deepCodeParams.getMinSeverity(), filesToAnalyse, - HashContentUtilsBase.calculateHash(pdUtils.getProjectName(project)) - ); + HashContentUtilsBase.calculateHash(pdUtils.getProjectName(project)), + deepCodeParams.getIdeProductName(), + deepCodeParams.getOrgDisplayName()); pdUtils.progressCheckCanceled(progress); dcLogger.logInfo(response.toString()); diff --git a/src/main/java/ai/deepcode/javaclient/core/DeepCodeParamsBase.java b/src/main/java/ai/deepcode/javaclient/core/DeepCodeParamsBase.java index b3bd9f2..3c129ac 100644 --- a/src/main/java/ai/deepcode/javaclient/core/DeepCodeParamsBase.java +++ b/src/main/java/ai/deepcode/javaclient/core/DeepCodeParamsBase.java @@ -18,6 +18,7 @@ public abstract class DeepCodeParamsBase { // Inner params private String loginUrl; private String ideProductName; + private String orgDisplayName; private Supplier getTimeoutForGettingAnalysesMs; private final DeepCodeRestApi restApi; @@ -30,6 +31,7 @@ protected DeepCodeParamsBase( String sessionToken, String loginUrl, String ideProductName, + String orgDisplayName, Supplier getTimeoutForGettingAnalysesMs, DeepCodeRestApi restApi ) { @@ -41,6 +43,7 @@ protected DeepCodeParamsBase( this.sessionToken = sessionToken; this.loginUrl = loginUrl; this.ideProductName = ideProductName; + this.orgDisplayName = orgDisplayName; this.getTimeoutForGettingAnalysesMs = getTimeoutForGettingAnalysesMs; this.restApi = restApi; } @@ -134,4 +137,8 @@ public String getIdeProductName() { public long getTimeoutForGettingAnalysesMs() { return getTimeoutForGettingAnalysesMs.get(); } + + public String getOrgDisplayName() { + return orgDisplayName; + } } diff --git a/src/main/java/ai/deepcode/javaclient/requests/GetAnalysisRequest.java b/src/main/java/ai/deepcode/javaclient/requests/GetAnalysisRequest.java index 30d5e35..4f43d95 100644 --- a/src/main/java/ai/deepcode/javaclient/requests/GetAnalysisRequest.java +++ b/src/main/java/ai/deepcode/javaclient/requests/GetAnalysisRequest.java @@ -5,15 +5,18 @@ public class GetAnalysisRequest { private GetAnalysisKey key; + private AnalysisContext analysisContext; private Integer severity; private boolean prioritized; private boolean legacy; /** * @param bundleHash - * @param limitToFiles list of filePath + * @param limitToFiles list of filePath * @param severity - * @param shard uniq String (hash) per Project to optimize jobs on backend (run on the same worker to reuse caches) + * @param shard uniq String (hash) per Project to optimize jobs on backend (run on the same worker to reuse caches) + * @param ideProductName specific IDE + * @param orgDisplayName client’s snyk organization name * @param prioritized * @param legacy */ @@ -22,17 +25,25 @@ public GetAnalysisRequest( List limitToFiles, Integer severity, String shard, - boolean prioritized, + String ideProductName, String orgDisplayName, boolean prioritized, boolean legacy ) { this.key = new GetAnalysisKey(bundleHash, limitToFiles, shard); + this.analysisContext = new AnalysisContext(ideProductName, orgDisplayName); this.severity = severity; this.prioritized = prioritized; this.legacy = legacy; } - public GetAnalysisRequest(String bundleHash, List limitToFiles, Integer severity, String shard) { - this(bundleHash, limitToFiles, severity, shard, false, true); + public GetAnalysisRequest( + String bundleHash, + List limitToFiles, + Integer severity, + String shard, + String ideProductName, + String orgDisplayName + ) { + this(bundleHash, limitToFiles, severity, shard, ideProductName, orgDisplayName, false, true); } private static class GetAnalysisKey { @@ -65,22 +76,22 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; GetAnalysisKey that = (GetAnalysisKey) o; return type.equals(that.type) - && hash.equals(that.hash) - && Objects.equals(limitToFiles, that.limitToFiles); + && hash.equals(that.hash) + && Objects.equals(limitToFiles, that.limitToFiles); } @Override public String toString() { return "GetAnalysisKey{" - + "type='" - + type - + '\'' - + ", hash='" - + hash - + '\'' - + ", limitToFiles=" - + limitToFiles - + '}'; + + "type='" + + type + + '\'' + + ", hash='" + + hash + + '\'' + + ", limitToFiles=" + + limitToFiles + + '}'; } @Override @@ -88,4 +99,49 @@ public int hashCode() { return Objects.hash(type, hash, limitToFiles); } } + + private static class AnalysisContext { + private final String flow; + private final String initiator = "IDE"; + private final String orgDisplayName; + + public AnalysisContext(String flow, String orgDisplayName) { + this.flow = flow; + this.orgDisplayName = orgDisplayName; + } + + public String getFlow() { + return flow; + } + + public String getOrgDisplayName() { + return orgDisplayName; + } + + public String getInitiator() { + return initiator; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + AnalysisContext that = (AnalysisContext) o; + return Objects.equals(flow, that.flow) && Objects.equals(orgDisplayName, that.orgDisplayName); + } + + @Override + public int hashCode() { + return Objects.hash(flow, orgDisplayName); + } + + @Override + public String toString() { + return "AnalysisContext{" + + "flow='" + flow + '\'' + + ", initiator='" + initiator + '\'' + + ", orgDisplayName='" + orgDisplayName + '\'' + + '}'; + } + } } diff --git a/src/test/java/ai/deepcode/javaclient/core/AnalysisDataTest.java b/src/test/java/ai/deepcode/javaclient/core/AnalysisDataTest.java index 144e313..4dca31b 100644 --- a/src/test/java/ai/deepcode/javaclient/core/AnalysisDataTest.java +++ b/src/test/java/ai/deepcode/javaclient/core/AnalysisDataTest.java @@ -104,7 +104,15 @@ public void reupload_files_if_initial_upload_does_not_succeed() { public void if_file_upload_fail_getAnalysis_should_not_be_invoked() { restApi = new RestApiMockWithBrokenFileUpload() { @Override - public @NotNull GetAnalysisResponse getAnalysis(String token, String bundleId, Integer severity, List filesToAnalyse, String shard) { + public @NotNull GetAnalysisResponse getAnalysis( + String token, + String bundleId, + Integer severity, + List filesToAnalyse, + String shard, + String ideProductName, + String orgDisplayName + ) { throw new RuntimeException("getAnalysis should NOT be invoked"); } }; @@ -158,7 +166,15 @@ public void getAnalysis_recover_during_polling_if_operation_sometimes_does_not_s } @Override - public @NotNull GetAnalysisResponse getAnalysis(String token, String bundleId, Integer severity, List filesToAnalyse, String shard) { + public @NotNull GetAnalysisResponse getAnalysis( + String token, + String bundleId, + Integer severity, + List filesToAnalyse, + String shard, + String ideProductName, + String orgDisplayName + ) { final GetAnalysisResponse response = Objects.requireNonNull(responses.poll()); if (response.getStatus().equals(COMPLETE)) { isCompleted[0] = true; diff --git a/src/test/java/ai/deepcode/javaclient/core/mocks/DeepCodeParamsMock.java b/src/test/java/ai/deepcode/javaclient/core/mocks/DeepCodeParamsMock.java index 85fb5cc..2cccac6 100644 --- a/src/test/java/ai/deepcode/javaclient/core/mocks/DeepCodeParamsMock.java +++ b/src/test/java/ai/deepcode/javaclient/core/mocks/DeepCodeParamsMock.java @@ -7,7 +7,7 @@ public class DeepCodeParamsMock extends DeepCodeParamsBase { public DeepCodeParamsMock(DeepCodeRestApi restApi) { - super(true, "", false, false, 1, "", "", "", () -> 1000L, restApi); + super(true, "", false, false, 1, "", "", "", "", () -> 1000L, restApi); } @Override diff --git a/src/test/java/ai/deepcode/javaclient/core/mocks/DeepCodeRestApiMock.java b/src/test/java/ai/deepcode/javaclient/core/mocks/DeepCodeRestApiMock.java index 4b71072..6c17749 100644 --- a/src/test/java/ai/deepcode/javaclient/core/mocks/DeepCodeRestApiMock.java +++ b/src/test/java/ai/deepcode/javaclient/core/mocks/DeepCodeRestApiMock.java @@ -36,7 +36,15 @@ public void setBaseUrl(@Nullable String baseUrl, boolean disableSslVerification, } @Override - public @NotNull GetAnalysisResponse getAnalysis(String token, String bundleId, Integer severity, List filesToAnalyse, String shard) { + public @NotNull GetAnalysisResponse getAnalysis( + String token, + String bundleId, + Integer severity, + List filesToAnalyse, + String shard, + String ideProductName, + String orgDisplayName + ) { throw new UnsupportedOperationException(); } From d8ebf32a4458f4724f1454502c9931884141440d Mon Sep 17 00:00:00 2001 From: Artsiom Chapialiou Date: Mon, 28 Mar 2022 14:15:31 +0300 Subject: [PATCH 2/3] fix: internal ConcurrentModificationException --- CHANGELOG.md | 1 + src/main/java/ai/deepcode/javaclient/core/RunUtilsBase.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17cfbe0..9d12650 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - fix: do not try to getAnalysis if `upload files` is not succeed (i.e. `missingFiles` is not empty after uploads) - fix: avoid remove operation for empty immutable List - fix: check file in marker for nullability before proceed +- fix: internal ConcurrentModificationException - feat: provide unique (per project) `shard` to getAnalysis call - feat: provide `analysisContext` key (`getAnalysis` request) for better tracking/logging on backend - chore: reshape/refactor REST API wrapper to be replaceable through constructor base DI diff --git a/src/main/java/ai/deepcode/javaclient/core/RunUtilsBase.java b/src/main/java/ai/deepcode/javaclient/core/RunUtilsBase.java index 38fc2f9..3c2114f 100644 --- a/src/main/java/ai/deepcode/javaclient/core/RunUtilsBase.java +++ b/src/main/java/ai/deepcode/javaclient/core/RunUtilsBase.java @@ -86,7 +86,7 @@ protected abstract void doBackgroundRun( private static final Map> mapProject2Progresses = new ConcurrentHashMap<>(); protected static synchronized Set getRunningProgresses(@NotNull Object project) { - return mapProject2Progresses.computeIfAbsent(project, p -> new HashSet<>()); + return mapProject2Progresses.computeIfAbsent(project, p -> ConcurrentHashMap.newKeySet()); } // ??? list of all running background tasks From 09f1370d4ec479e7eb38c2e855aeb75f9d4b4ba9 Mon Sep 17 00:00:00 2001 From: Artsiom Chapialiou Date: Mon, 28 Mar 2022 14:32:12 +0300 Subject: [PATCH 3/3] chore: formatting --- .../ai/deepcode/javaclient/requests/GetAnalysisRequest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/ai/deepcode/javaclient/requests/GetAnalysisRequest.java b/src/main/java/ai/deepcode/javaclient/requests/GetAnalysisRequest.java index 4f43d95..86638e7 100644 --- a/src/main/java/ai/deepcode/javaclient/requests/GetAnalysisRequest.java +++ b/src/main/java/ai/deepcode/javaclient/requests/GetAnalysisRequest.java @@ -25,7 +25,9 @@ public GetAnalysisRequest( List limitToFiles, Integer severity, String shard, - String ideProductName, String orgDisplayName, boolean prioritized, + String ideProductName, + String orgDisplayName, + boolean prioritized, boolean legacy ) { this.key = new GetAnalysisKey(bundleHash, limitToFiles, shard);