Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize how detect project clone categories are sent #955

Draft
wants to merge 10 commits into
base: master
Choose a base branch
from
Expand Up @@ -84,4 +84,20 @@ public Set<B> representedValueSet() {
public List<ExtendedEnumValue<E, B>> toProvidedValues() {
return providedValues;
}

/**
* This returns null if the properties' value is set to ALL values of the Enum.
* It returns an empty array if the value is set to NONE.
* This streamlines things for newer 2023.10.0 and later endpoints.
* Older endpoints should use representedValues.
*/
public List<B> representedValuesStreamlined() {
if (containsNone()) {
return new ArrayList<>();
} else if (containsAll()) {
return null;
} else {
return toPresentValues();
}
}
}
2 changes: 1 addition & 1 deletion shared-version.properties
@@ -1,3 +1,3 @@
// ALSO CHANGE integration-common version in src/main/resources/create-gradle-airgap-script.ft
gradle.ext.blackDuckCommonVersion='66.2.9'
gradle.ext.blackDuckCommonVersion='66.2.10'
gradle.ext.springBootVersion='2.7.12'
Expand Up @@ -25,6 +25,7 @@
import com.synopsys.integration.blackduck.codelocation.signaturescanner.command.ReducedPersistence;
import com.synopsys.integration.blackduck.codelocation.signaturescanner.command.SnippetMatching;
import com.synopsys.integration.blackduck.configuration.BlackDuckServerConfig;
import com.synopsys.integration.blackduck.version.BlackDuckVersion;
import com.synopsys.integration.configuration.property.types.enumallnone.list.AllEnumList;
import com.synopsys.integration.configuration.property.types.enumallnone.list.AllNoneEnumCollection;
import com.synopsys.integration.configuration.property.types.enumallnone.list.AllNoneEnumList;
Expand All @@ -40,7 +41,10 @@
import com.synopsys.integration.detect.configuration.enumeration.RapidCompareMode;
import com.synopsys.integration.detect.lifecycle.boot.decision.BlackDuckDecision;
import com.synopsys.integration.detect.lifecycle.boot.decision.RunDecision;
import com.synopsys.integration.detect.lifecycle.boot.product.BlackDuckConnectivityResult;
import com.synopsys.integration.detect.lifecycle.boot.product.ProductBootOptions;
import com.synopsys.integration.detect.lifecycle.boot.product.version.BlackDuckVersionParser;
import com.synopsys.integration.detect.lifecycle.run.data.BlackDuckRunData;
import com.synopsys.integration.detect.tool.binaryscanner.BinaryScanOptions;
import com.synopsys.integration.detect.tool.detector.executable.DetectExecutableOptions;
import com.synopsys.integration.detect.tool.iac.IacScanOptions;
Expand Down Expand Up @@ -314,13 +318,22 @@ public CustomFieldDocument createCustomFieldDocument() throws DetectUserFriendly
return parser.parseCustomFieldDocument(detectConfiguration.getRaw());
}

public ProjectSyncOptions createDetectProjectServiceOptions() {
public ProjectSyncOptions createDetectProjectServiceOptions(Optional<BlackDuckVersion> blackDuckServerVersion) {
ProjectVersionPhaseType projectVersionPhase = detectConfiguration.getValue(DetectProperties.DETECT_PROJECT_VERSION_PHASE);
ProjectVersionDistributionType projectVersionDistribution = detectConfiguration.getValue(DetectProperties.DETECT_PROJECT_VERSION_DISTRIBUTION);
Integer projectTier = detectConfiguration.getNullableValue(DetectProperties.DETECT_PROJECT_TIER);
String projectDescription = detectConfiguration.getNullableValue(DetectProperties.DETECT_PROJECT_DESCRIPTION);
String projectVersionNotes = detectConfiguration.getNullableValue(DetectProperties.DETECT_PROJECT_VERSION_NOTES);
List<ProjectCloneCategoriesType> cloneCategories = detectConfiguration.getValue(DetectProperties.DETECT_PROJECT_CLONE_CATEGORIES).representedValues();

List<ProjectCloneCategoriesType> cloneCategories;
AllNoneEnumList<ProjectCloneCategoriesType> categoriesEnum = detectConfiguration.getValue(DetectProperties.DETECT_PROJECT_CLONE_CATEGORIES);

if (canSendSummaryData(blackDuckServerVersion)) {
cloneCategories = categoriesEnum.representedValuesStreamlined();
} else {
cloneCategories = categoriesEnum.representedValues();
}

Boolean projectLevelAdjustments = detectConfiguration.getValue(DetectProperties.DETECT_PROJECT_LEVEL_ADJUSTMENTS);
Boolean forceProjectVersionUpdate = detectConfiguration.getValue(DetectProperties.DETECT_PROJECT_VERSION_UPDATE);
String projectVersionNickname = detectConfiguration.getNullableValue(DetectProperties.DETECT_PROJECT_VERSION_NICKNAME);
Expand Down Expand Up @@ -520,6 +533,27 @@ private List<String> collectDirectoryExclusions(@NotNull List<String> givenExclu

return directoryExclusionPatterns;
}

/**
* Newer BlackDuck servers allow us to send ALL and null values for project categories. BlackDuck will then
* determine the appropriate values to display in the UI. For older servers we have to send all the values that we know
* about, for all, which can cause problems if we send a value Detect knows about but an older BlackDuck server does not.
* Eventually we can pull this code once all servers we support are 2023.10.0 or higher.
*
* @param blackDuckServerVersion the version of the BlackDuck server specified in blackduck.url
* @return true if we can optimize the categories argument, false otherwise
*/
private boolean canSendSummaryData(Optional<BlackDuckVersion> blackDuckServerVersion) {
boolean canSendSummaryData = false;

BlackDuckVersion minVersion = new BlackDuckVersion(2023, 10, 0);

if (blackDuckServerVersion.isPresent() && blackDuckServerVersion.get().isAtLeast(minVersion)) {
canSendSummaryData = true;
}

return canSendSummaryData;
}

public Optional<String> getContainerScanFilePath() {
return Optional.ofNullable(detectConfiguration.getNullableValue(DetectProperties.DETECT_CONTAINER_SCAN_FILE));
Expand Down
Expand Up @@ -30,7 +30,6 @@ protected BlackDuckRunData(
this.blackDuckServicesFactory = blackDuckServicesFactory;
this.scanMode = scanMode;
this.waitAtScanLevel = waitAtScanLevel;

determineBlackDuckServerVersion(blackDuckConnectivityResult);
}

Expand Down
Expand Up @@ -30,7 +30,7 @@
import com.synopsys.integration.blackduck.api.generated.discovery.ApiDiscovery;
import com.synopsys.integration.blackduck.api.generated.enumeration.PolicyRuleSeverityType;
import com.synopsys.integration.blackduck.api.generated.view.BomStatusScanView;
import com.synopsys.integration.blackduck.api.generated.view.DeveloperScansScanView;
import com.synopsys.integration.blackduck.api.manual.view.DeveloperScansScanView;
import com.synopsys.integration.blackduck.api.generated.view.ProjectVersionView;
import com.synopsys.integration.blackduck.bdio2.model.GitInfo;
import com.synopsys.integration.blackduck.bdio2.util.Bdio2Factory;
Expand Down Expand Up @@ -1161,7 +1161,7 @@ public ProjectVersionWrapper syncProjectVersion(
projectGroupFindResult,
cloneFindResult,
projectVersionLicensesFindResult,
detectConfigurationFactory.createDetectProjectServiceOptions()
detectConfigurationFactory.createDetectProjectServiceOptions(blackDuckRunData.getBlackDuckServerVersion())
)
);
}
Expand Down
Expand Up @@ -7,19 +7,17 @@
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.Set;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.synopsys.integration.blackduck.api.generated.view.DeveloperScansScanView;
import com.synopsys.integration.blackduck.api.manual.view.DeveloperScansScanView;
import com.synopsys.integration.blackduck.codelocation.Result;
import com.synopsys.integration.blackduck.codelocation.signaturescanner.ScanBatchOutput;
import com.synopsys.integration.blackduck.codelocation.signaturescanner.command.ScanCommandOutput;
import com.synopsys.integration.detect.configuration.DetectUserFriendlyException;
import com.synopsys.integration.detect.configuration.enumeration.BlackduckScanMode;
Expand Down
Expand Up @@ -9,7 +9,7 @@
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.synopsys.integration.blackduck.api.generated.view.DeveloperScansScanView;
import com.synopsys.integration.blackduck.api.manual.view.DeveloperScansScanView;
import com.synopsys.integration.detect.configuration.DetectUserFriendlyException;
import com.synopsys.integration.detect.configuration.enumeration.ExitCodeType;
import com.synopsys.integration.detect.workflow.file.DetectFileUtils;
Expand Down
Expand Up @@ -6,7 +6,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.synopsys.integration.blackduck.api.generated.view.DeveloperScansScanView;
import com.synopsys.integration.blackduck.api.manual.view.DeveloperScansScanView;
import com.synopsys.integration.detect.configuration.DetectUserFriendlyException;
import com.synopsys.integration.detect.configuration.enumeration.BlackduckScanMode;
import com.synopsys.integration.detect.configuration.enumeration.ExitCodeType;
Expand Down
Expand Up @@ -5,7 +5,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.synopsys.integration.blackduck.api.generated.view.DeveloperScansScanView;
import com.synopsys.integration.blackduck.api.manual.view.DeveloperScansScanView;
import com.synopsys.integration.blackduck.service.BlackDuckApiClient;
import com.synopsys.integration.detect.configuration.enumeration.BlackduckScanMode;
import com.synopsys.integration.detect.workflow.blackduck.developer.blackduck.DetectRapidScanWaitJobFull;
Expand Down
Expand Up @@ -11,7 +11,7 @@
import com.synopsys.integration.blackduck.api.generated.component.DeveloperScansScanItemsPolicyViolationLicensesViolatingPoliciesView;
import com.synopsys.integration.blackduck.api.generated.component.DeveloperScansScanItemsPolicyViolationVulnerabilitiesView;
import com.synopsys.integration.blackduck.api.generated.component.DeveloperScansScanItemsPolicyViolationVulnerabilitiesViolatingPoliciesView;
import com.synopsys.integration.blackduck.api.generated.view.DeveloperScansScanView;
import com.synopsys.integration.blackduck.api.manual.view.DeveloperScansScanView;

public class RapidScanComponentGroupDetail {

Expand Down
Expand Up @@ -22,7 +22,7 @@
import com.synopsys.integration.blackduck.api.generated.component.DeveloperScansScanItemsTransitiveUpgradeGuidanceLongTermUpgradeGuidanceView;
import com.synopsys.integration.blackduck.api.generated.component.DeveloperScansScanItemsTransitiveUpgradeGuidanceShortTermUpgradeGuidanceView;
import com.synopsys.integration.blackduck.api.generated.component.DeveloperScansScanItemsTransitiveUpgradeGuidanceView;
import com.synopsys.integration.blackduck.api.generated.view.DeveloperScansScanView;
import com.synopsys.integration.blackduck.api.manual.view.DeveloperScansScanView;

public class RapidScanResultAggregator {

Expand Down
@@ -1,7 +1,7 @@
package com.synopsys.integration.detect.workflow.blackduck.developer.blackduck;

import com.synopsys.integration.blackduck.api.core.response.UrlMultipleResponses;
import com.synopsys.integration.blackduck.api.generated.view.DeveloperScansScanView;
import com.synopsys.integration.blackduck.api.manual.view.DeveloperScansScanView;
import com.synopsys.integration.blackduck.http.BlackDuckRequestBuilder;
import com.synopsys.integration.blackduck.service.request.BlackDuckMultipleRequest;
import com.synopsys.integration.blackduck.service.request.BlackDuckResponseRequest;
Expand Down
Expand Up @@ -6,7 +6,7 @@

import org.apache.http.HttpStatus;

import com.synopsys.integration.blackduck.api.generated.view.DeveloperScansScanView;
import com.synopsys.integration.blackduck.api.manual.view.DeveloperScansScanView;
import com.synopsys.integration.blackduck.exception.BlackDuckIntegrationException;
import com.synopsys.integration.blackduck.service.BlackDuckApiClient;
import com.synopsys.integration.blackduck.service.request.BlackDuckMultipleRequest;
Expand Down
Expand Up @@ -8,7 +8,7 @@

import com.synopsys.integration.blackduck.api.core.BlackDuckPath;
import com.synopsys.integration.blackduck.api.generated.discovery.ApiDiscovery;
import com.synopsys.integration.blackduck.api.generated.view.DeveloperScansScanView;
import com.synopsys.integration.blackduck.api.manual.view.DeveloperScansScanView;
import com.synopsys.integration.blackduck.bdio2.model.BdioFileContent;
import com.synopsys.integration.blackduck.exception.BlackDuckIntegrationException;
import com.synopsys.integration.blackduck.http.BlackDuckRequestBuilder;
Expand Down
Expand Up @@ -3,7 +3,7 @@
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.synopsys.integration.blackduck.api.generated.view.DeveloperScansScanView;
import com.synopsys.integration.blackduck.api.manual.view.DeveloperScansScanView;
import com.synopsys.integration.componentlocator.beans.Component;
import java.util.HashMap;
import java.util.LinkedHashSet;
Expand Down
Expand Up @@ -11,12 +11,15 @@
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import com.synopsys.integration.blackduck.api.generated.enumeration.ProjectCloneCategoriesType;
import com.synopsys.integration.blackduck.version.BlackDuckVersion;
import com.synopsys.integration.common.util.Bdo;
import com.synopsys.integration.detect.configuration.enumeration.BlackduckScanMode;
import com.synopsys.integration.detect.configuration.enumeration.DefaultDetectorSearchExcludedDirectories;
import com.synopsys.integration.detect.configuration.enumeration.DetectTool;
import com.synopsys.integration.detect.configuration.enumeration.RapidCompareMode;
import com.synopsys.integration.detect.tool.signaturescanner.BlackDuckSignatureScannerOptions;
import com.synopsys.integration.detect.workflow.blackduck.project.options.ProjectSyncOptions;
import com.synopsys.integration.rest.credentials.Credentials;

public class DetectConfigurationFactoryTests {
Expand Down Expand Up @@ -117,4 +120,52 @@ public void testGetContainerScanFilePathIfLocalPathProvided() {
Assertions.assertFalse(containerScanFilePath.toString().startsWith("/"));
Assertions.assertFalse(containerScanFilePath.toString().endsWith("/"));
}

@Test
public void testAllCloneCategories() {
DetectConfigurationFactory factory = factoryOf(Pair.of(DetectProperties.DETECT_PROJECT_CLONE_CATEGORIES, "ALL"));

BlackDuckVersion minVersion = new BlackDuckVersion(2023, 10, 0);
Optional<BlackDuckVersion> serverVersion = Optional.of(minVersion);

ProjectSyncOptions projectSyncOptions = factory.createDetectProjectServiceOptions(serverVersion);

List<ProjectCloneCategoriesType> cloneCategories = projectSyncOptions.getCloneCategories();

Assertions.assertTrue(cloneCategories == null);
}

@Test
public void testNoCloneCategories() {
DetectConfigurationFactory factory = factoryOf(Pair.of(DetectProperties.DETECT_PROJECT_CLONE_CATEGORIES, "NONE"));

BlackDuckVersion minVersion = new BlackDuckVersion(2023, 10, 0);
Optional<BlackDuckVersion> serverVersion = Optional.of(minVersion);

ProjectSyncOptions projectSyncOptions = factory.createDetectProjectServiceOptions(serverVersion);

List<ProjectCloneCategoriesType> cloneCategories = projectSyncOptions.getCloneCategories();

Assertions.assertTrue(cloneCategories.isEmpty());
}

@Test
public void testSpecificCloneCategories() {
DetectConfigurationFactory factory = factoryOf(
Pair.of(DetectProperties.DETECT_PROJECT_CLONE_CATEGORIES,
ProjectCloneCategoriesType.CUSTOM_FIELD_DATA.toString()
+ ","
+ ProjectCloneCategoriesType.DEEP_LICENSE.toString()
));

BlackDuckVersion minVersion = new BlackDuckVersion(2023, 10, 0);
Optional<BlackDuckVersion> serverVersion = Optional.of(minVersion);

ProjectSyncOptions projectSyncOptions = factory.createDetectProjectServiceOptions(serverVersion);

List<ProjectCloneCategoriesType> cloneCategories = projectSyncOptions.getCloneCategories();

Assertions.assertTrue(cloneCategories.contains(ProjectCloneCategoriesType.CUSTOM_FIELD_DATA));
Assertions.assertTrue(cloneCategories.contains(ProjectCloneCategoriesType.DEEP_LICENSE));
}
}
Expand Up @@ -14,7 +14,7 @@
import org.zeroturnaround.zip.commons.FileUtils;

import com.google.gson.Gson;
import com.synopsys.integration.blackduck.api.generated.view.DeveloperScansScanView;
import com.synopsys.integration.blackduck.api.manual.view.DeveloperScansScanView;
import com.synopsys.integration.detect.configuration.DetectUserFriendlyException;
import com.synopsys.integration.detect.workflow.DetectRunId;
import com.synopsys.integration.detect.workflow.file.DirectoryManager;
Expand Down
Expand Up @@ -10,7 +10,7 @@
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import com.synopsys.integration.blackduck.api.generated.view.DeveloperScansScanView;
import com.synopsys.integration.blackduck.api.manual.view.DeveloperScansScanView;
import com.synopsys.integration.detect.configuration.DetectUserFriendlyException;
import com.synopsys.integration.detect.configuration.enumeration.BlackduckScanMode;
import com.synopsys.integration.detect.configuration.enumeration.ExitCodeType;
Expand Down
Expand Up @@ -15,7 +15,7 @@
import com.synopsys.integration.blackduck.api.generated.component.DeveloperScansScanItemsPolicyViolationVulnerabilitiesView;
import com.synopsys.integration.blackduck.api.generated.component.DeveloperScansScanItemsPolicyViolationVulnerabilitiesViolatingPoliciesView;
import com.synopsys.integration.blackduck.api.generated.component.DeveloperScansScanItemsViolatingPoliciesView;
import com.synopsys.integration.blackduck.api.generated.view.DeveloperScansScanView;
import com.synopsys.integration.blackduck.api.manual.view.DeveloperScansScanView;
import com.synopsys.integration.detect.workflow.blackduck.developer.aggregate.RapidScanAggregateResult;
import com.synopsys.integration.detect.workflow.blackduck.developer.aggregate.RapidScanResultAggregator;
import com.synopsys.integration.detect.workflow.blackduck.developer.aggregate.RapidScanResultSummary;
Expand Down