diff --git a/README.md b/README.md index 25fdbbf..731061c 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,32 @@ in the `pluginManagement` section of your POM to avoid repetition. ``` +Especially if you're in a multi-module configuration you should additionally include the plugin +in the regular build plugin section that contains `false`. +This assures that your submodules reflect the parent/child hierarchy of your pom. +```xml + + + + org.cyclonedx + cyclonedx-maven-plugin + + + io.github.pmckeown + dependency-track-maven-plugin + false + + + UUID_OF_PARENT_PROJECT_IN_DTRACK + + NAME_OF_PARENT_PROJECT_IN_DTRACK + VERSION_OF_PARENT_PROJECT_IN_DTRACK + + + + ``` + **IMPORTANT** Dependency Track includes a front-end and an api-server component on different ports (defaulting to 8080 and 8081 respectively). You must ensure that you target the api server component (8081) and not the front-end component URL in the `dependencyTrackBaseUrl` property. @@ -117,6 +142,8 @@ The Automation team needs the following permissions: * In Dependency Track v4.4.x and later: * BOM_UPLOAD * PORTFOLIO_MANAGEMENT + + Only when project should be automatically created. If a project exists in any version, this permission is not needed. * PROJECT_CREATION_UPLOAD * VIEW_PORTFOLIO * VIEW_VULNERABILITY @@ -206,6 +233,7 @@ Dependency-Track based on the metadata present in the BOM: **Notes:** * This requires a CycloneDX BOM using Schema 1.2 or later. +* required permission `PORTFOLIO_MANAGEMENT` if `updateProjectInfo` or `updateParent` is `true` * Not all information is visible in the Dependency-Track server UI. From Dependency-Track server 4.8.0 onwards, you can set the project parent by setting `updateParent` to `true`. The @@ -213,18 +241,20 @@ parent name will be defaulted to that POM's project parent name. If you wish to no parent set within the `pom.xml`, then explicitly set `parentName` and `parentVersion`. `projectVersion` is optional Dependency-Track, so this has no default to allow for blank values. -**Note:** If the parent cannot be found on the Dependency-Track server, the BOM upload will not be attempted in order to -prevent a project being incorrectly created or updated the server. - -| Property | Required | Default Value | Example Values | -|----------------------|----------|------------------------|---------------------------| -| bomLocation | false | target/bom.xml | target/custom-bom.xml | -| updateProjectInfo | false | false | false | -| updateParent | false | false | true | -| parentName | false | ${project.parent.name} | my-name-override | -| parentVersion | false | | ${project.parent.version} | -| isLatest | false | false | true | -| projectTags[].name | false | false | tag1 | +**Note 1:** If both `parentUuid` and `parentName` / `parentVersion` are provided in configuration `parentUuid` will take precedence. + +**Note 2:** If a non-existing parent information is provided, the plugin will fail with `404 Not found`. + +| Property | Required | Default Value | Example Values | +|--------------------|----------|------------------------|---------------------------------------| +| bomLocation | false | target/bom.xml | target/custom-bom.xml | +| updateProjectInfo | false | false | false | +| updateParent | false | false | true | +| parentUuid | false | | 628df5eb-a7fe-4c3f-831c-4536839a05ed | +| parentName | false | ${project.parent.name} | my-name-override | +| parentVersion | false | | ${project.parent.version} | +| isLatest | false | false | true | +| projectTags[].name | false | false | tag1 | The `isLatest` option sets the flag on the project to indicate that it is the latest version. diff --git a/pom.xml b/pom.xml index 5aed6fb..4a44c38 100644 --- a/pom.xml +++ b/pom.xml @@ -174,7 +174,7 @@ org.apache.maven.plugin-tools maven-plugin-annotations - 3.8.1 + 3.15.1 provided @@ -192,13 +192,13 @@ com.github.tomakehurst wiremock - 2.27.2 + 3.0.1 test org.mockito mockito-core - 4.9.0 + 5.14.2 test @@ -208,7 +208,7 @@ maven-clean-plugin - 3.3.1 + 3.4.0 @@ -227,48 +227,48 @@ maven-plugin-plugin - 3.9.0 + 3.15.1 true maven-surefire-plugin - 3.2.1 + 3.5.2 maven-jar-plugin - 3.3.0 + 3.4.2 maven-install-plugin - 3.1.1 + 3.1.3 maven-deploy-plugin - 3.1.1 + 3.1.3 maven-invoker-plugin - 3.6.0 + 3.8.1 maven-source-plugin - 3.2.1 + 3.3.1 maven-javadoc-plugin - 3.4.1 + 3.11.2 org.sonarsource.scanner.maven sonar-maven-plugin - 3.9.1.2184 + 5.0.0.4389 org.jacoco jacoco-maven-plugin - 0.8.10 + 0.8.12 true diff --git a/src/main/java/io/github/pmckeown/dependencytrack/AbstractDependencyTrackMojo.java b/src/main/java/io/github/pmckeown/dependencytrack/AbstractDependencyTrackMojo.java index b24a98f..65a4dc6 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/AbstractDependencyTrackMojo.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/AbstractDependencyTrackMojo.java @@ -13,7 +13,6 @@ import static io.github.pmckeown.dependencytrack.ObjectMapperFactory.relaxedObjectMapper; import static kong.unirest.HeaderNames.ACCEPT; import static kong.unirest.HeaderNames.ACCEPT_ENCODING; - /** * Base class for Mojos in this project. * @@ -138,8 +137,8 @@ public void setSkip(String skip) { this.skip = skip; } - public void setPollingConfig(PollingConfig commonConfig) { - this.pollingConfig = commonConfig; + public void setPollingConfig(PollingConfig pollingConfig) { + this.pollingConfig = pollingConfig; } protected void handleFailure(String message) throws MojoFailureException { diff --git a/src/main/java/io/github/pmckeown/dependencytrack/CommonConfig.java b/src/main/java/io/github/pmckeown/dependencytrack/CommonConfig.java index 0b95741..57a8a38 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/CommonConfig.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/CommonConfig.java @@ -1,6 +1,12 @@ package io.github.pmckeown.dependencytrack; +import io.github.pmckeown.util.Logger; +import java.util.Collections; +import java.util.Set; import javax.inject.Singleton; +import org.apache.commons.lang3.StringUtils; +import org.apache.maven.plugin.logging.SystemStreamLog; +import org.apache.maven.project.MavenProject; /** * Holder for common configuration supplied on Mojo execution @@ -10,15 +16,28 @@ @Singleton public class CommonConfig { - private String projectName; - private String projectVersion; + private String projectUuid=""; + private String projectName=""; + private String projectVersion=""; private String dependencyTrackBaseUrl; private String apiKey; private PollingConfig pollingConfig; + private String bomLocation; + private MavenProject mavenProject; + private boolean updateProjectInfo; + private boolean updateParent; + private String parentUuid; + private String parentName; + private String parentVersion; + private boolean isLatest; + private boolean autoCreate = true; + private Set projectTags = Collections.emptySet(); - public CommonConfig() { - // For dependency injection - } + protected Logger logger = new Logger(new SystemStreamLog()); + + public String getProjectUuid() { return projectUuid; } + + public void setProjectUuid(String projectUuid) { this.projectUuid = projectUuid; } public String getProjectName() { return projectName; @@ -59,5 +78,86 @@ public void setApiKey(String apiKey) { public void setPollingConfig(PollingConfig pollingConfig) { this.pollingConfig = pollingConfig; } + public Set getProjectTags() { + return projectTags; + } + + public void setProjectTags(Set projectTags) { + this.projectTags = projectTags; + } + + public boolean isLatest() { + return isLatest; + } + + public void setLatest(boolean latest) { + isLatest = latest; + } + + public String getParentVersion() { + return parentVersion; + } + + public void setParentVersion(String parentVersion) { + if (StringUtils.isBlank(parentUuid)) { + this.parentVersion = parentVersion; + } else if (StringUtils.isNotBlank(parentUuid)) + logger.info("parentUuid set so ignoring parentVersion: %s", parentVersion); + } + + public String getParentUuid() { return parentUuid; } + + public void setParentUuid(String parentUuid) { + this.parentUuid = parentUuid; + if (StringUtils.isNotBlank(parentUuid)) { + logger.info("parentUuid set to: %s", parentUuid); + logger.info("clearing parentName and parentVersion"); + this.setParentName(null); + this.setParentVersion(null); + } + } + public String getParentName() { + return parentName; + } + + public void setParentName(String parentName) { + if (StringUtils.isBlank(parentUuid)) { + this.parentName = parentName; + } else if (StringUtils.isNotBlank(parentUuid)) + logger.info("parentUuid set so ignoring parentName: %s", parentName); + } + + public boolean getUpdateParent() { return updateParent; } + + public void setUpdateParent(boolean updateParent) { + this.updateParent = updateParent; + } + + public boolean getUpdateProjectInfo() { return updateProjectInfo; } + + public void setUpdateProjectInfo(boolean updateProjectInfo) { this.updateProjectInfo = updateProjectInfo; } + + public MavenProject getMavenProject() { return mavenProject; } + + public void setMavenProject(MavenProject mavenProject) { + this.mavenProject = mavenProject; + } + + public void setBomLocation(String bomLocation) { + this.bomLocation = bomLocation; + } + public String getBomLocation() { + if (StringUtils.isNotBlank(bomLocation)) { + return bomLocation; + } else { + String defaultLocation = getMavenProject().getBasedir() + "/target/bom.xml"; + this.logger.debug("bomLocation not supplied so using: %s", defaultLocation); + return defaultLocation; + } + } + + public boolean isAutoCreate() { + return autoCreate; + } } diff --git a/src/main/java/io/github/pmckeown/dependencytrack/finding/FindingsMojo.java b/src/main/java/io/github/pmckeown/dependencytrack/finding/FindingsMojo.java index ead63d1..771d9ef 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/finding/FindingsMojo.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/finding/FindingsMojo.java @@ -104,7 +104,7 @@ public FindingsMojo(ProjectAction projectAction, FindingsAction findingsAction, protected void performAction() throws MojoExecutionException, MojoFailureException { List findings; try { - Project project = projectAction.getProject(commonConfig.getProjectName(), commonConfig.getProjectVersion()); + Project project = projectAction.getProject(commonConfig); findings = findingsAction.getFindings(project); findingsPrinter.printFindings(project, findings); populateThresholdFromCliOptions(); diff --git a/src/main/java/io/github/pmckeown/dependencytrack/metrics/MetricsMojo.java b/src/main/java/io/github/pmckeown/dependencytrack/metrics/MetricsMojo.java index 7b17914..8bda4f6 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/metrics/MetricsMojo.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/metrics/MetricsMojo.java @@ -75,7 +75,7 @@ public MetricsMojo(MetricsAction metricsAction, ProjectAction getProjectAction, @Override public void performAction() throws MojoExecutionException, MojoFailureException { try { - Project project = getProjectAction.getProject(projectName, projectVersion); + Project project = getProjectAction.getProject(commonConfig); logger.debug("Project Details: %s", project.toString()); Metrics metrics = getMetrics(project); diff --git a/src/main/java/io/github/pmckeown/dependencytrack/policyviolation/PolicyViolationsMojo.java b/src/main/java/io/github/pmckeown/dependencytrack/policyviolation/PolicyViolationsMojo.java index 094da98..5d6e0fa 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/policyviolation/PolicyViolationsMojo.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/policyviolation/PolicyViolationsMojo.java @@ -68,7 +68,7 @@ public PolicyViolationsMojo(ProjectAction projectAction, PolicyViolationsReportG protected void performAction() throws MojoExecutionException, MojoFailureException { List policyViolations; try { - Project project = projectAction.getProject(commonConfig.getProjectName(), commonConfig.getProjectVersion()); + Project project = projectAction.getProject(commonConfig); policyViolations = policyAction.getPolicyViolations(project); policyViolationsPrinter.printPolicyViolations(project, policyViolations); boolean policyViolationsBreached = policyAnalyser.isAnyPolicyViolationBreached(policyViolations, diff --git a/src/main/java/io/github/pmckeown/dependencytrack/project/DeleteProjectMojo.java b/src/main/java/io/github/pmckeown/dependencytrack/project/DeleteProjectMojo.java index 0182cc9..2fcaa8c 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/project/DeleteProjectMojo.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/project/DeleteProjectMojo.java @@ -31,7 +31,7 @@ public DeleteProjectMojo(ProjectAction projectAction, CommonConfig commonConfig, @Override protected void performAction() throws MojoExecutionException, MojoFailureException { try { - Project project = projectAction.getProject(projectName, projectVersion); + Project project = projectAction.getProject(commonConfig); boolean success = projectAction.deleteProject(project); diff --git a/src/main/java/io/github/pmckeown/dependencytrack/project/Project.java b/src/main/java/io/github/pmckeown/dependencytrack/project/Project.java index cb3f063..2b47dac 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/project/Project.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/project/Project.java @@ -56,9 +56,4 @@ public boolean isLatest() { public List getTags() { return tags; } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); - } } diff --git a/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectAction.java b/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectAction.java index a4dc875..70c1188 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectAction.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectAction.java @@ -1,5 +1,7 @@ package io.github.pmckeown.dependencytrack.project; +import com.networknt.schema.utils.StringUtils; +import io.github.pmckeown.dependencytrack.CommonConfig; import io.github.pmckeown.dependencytrack.DependencyTrackException; import io.github.pmckeown.dependencytrack.Item; import io.github.pmckeown.dependencytrack.Response; @@ -34,17 +36,39 @@ public ProjectAction(ProjectClient projectClient, BomParser bomParser, Logger lo this.logger = logger; } - public Project getProject(String projectName, String projectVersion) throws DependencyTrackException { + public Project getProject(CommonConfig commonConfig) throws DependencyTrackException { + return getProject( + commonConfig.getProjectUuid(), + commonConfig.getProjectName(), + commonConfig.getProjectVersion()); + } + + public Project getProject(String uuid) throws DependencyTrackException { + return getProject(uuid, "", ""); + } + + public Project getProject(String name, String version) throws DependencyTrackException { + return getProject("", name, version); + } + + public Project getProject(String uuid, String name, String version) throws DependencyTrackException { try { - Response response = projectClient.getProject(projectName, projectVersion); + Response response = projectClient.getProject(uuid, name, version); if (response.isSuccess()) { Optional body = response.getBody(); if (body.isPresent()) { return body.get(); } else { - throw new DependencyTrackException( - format("Requested project not found: %s-%s", projectName, projectVersion)); + if (StringUtils.isBlank(uuid)) { + throw new DependencyTrackException( + format("Requested project not found by UUUID: %s", uuid) + ); + } else { + throw new DependencyTrackException( + format("Requested project not found by name/version: %s-%s", name, version) + ); + } } } else { logger.error("Failed to list projects with error from server: " + response.getStatusText()); diff --git a/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectClient.java b/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectClient.java index 711c92c..25c814d 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectClient.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/project/ProjectClient.java @@ -9,6 +9,7 @@ import javax.inject.Inject; import javax.inject.Singleton; import java.util.Optional; +import org.apache.commons.lang3.StringUtils; import static io.github.pmckeown.dependencytrack.ResourceConstants.V1_PROJECT_UUID; import static io.github.pmckeown.dependencytrack.ResourceConstants.V1_PROJECT_LOOKUP; @@ -31,13 +32,13 @@ public ProjectClient(CommonConfig commonConfig) { this.commonConfig = commonConfig; } - public Response getProject(String projectName, String projectVersion) { - HttpResponse httpResponse = get(commonConfig.getDependencyTrackBaseUrl() + V1_PROJECT_LOOKUP) - .queryString("name", projectName) - .queryString("version", projectVersion) - .header(X_API_KEY, commonConfig.getApiKey()) - .asObject(new GenericType() { - }); + public Response getProject(String projectUuid, String projectName, String projectVersion) { + HttpResponse httpResponse; + if (StringUtils.isNotBlank(projectUuid)) { + httpResponse = getProjectByUuid(projectUuid); + } else { + httpResponse = getProjectByNameAndVersion(projectName, projectVersion); + } Optional body; if (httpResponse.isSuccess()) { body = Optional.of(httpResponse.getBody()); @@ -47,6 +48,23 @@ public Response getProject(String projectName, String projectVersion) { return new Response<>(httpResponse.getStatus(), httpResponse.getStatusText(), httpResponse.isSuccess(), body); } + private HttpResponse getProjectByNameAndVersion(String projectName, String projectVersion) { + return get(commonConfig.getDependencyTrackBaseUrl() + V1_PROJECT_LOOKUP) + .queryString("name", projectName) + .queryString("version", projectVersion) + .header(X_API_KEY, commonConfig.getApiKey()) + .asObject(new GenericType() { + }); + } + + private HttpResponse getProjectByUuid(String uuid) { + return get(commonConfig.getDependencyTrackBaseUrl() + V1_PROJECT_UUID) + .routeParam("uuid", uuid) + .header(X_API_KEY, commonConfig.getApiKey()) + .asObject(new GenericType() { + }); + } + Response deleteProject(Project project) { HttpResponse httpResponse = delete(commonConfig.getDependencyTrackBaseUrl() + V1_PROJECT_UUID) .routeParam("uuid", project.getUuid()) diff --git a/src/main/java/io/github/pmckeown/dependencytrack/score/ScoreAction.java b/src/main/java/io/github/pmckeown/dependencytrack/score/ScoreAction.java index b77a394..8a6e7fa 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/score/ScoreAction.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/score/ScoreAction.java @@ -26,7 +26,7 @@ class ScoreAction { private ProjectClient projectClient; private MetricsAction metricsAction; - private CommonConfig commonConfig; + private CommonConfig commonConfig = new CommonConfig(); private Logger logger; @Inject @@ -40,7 +40,7 @@ public ScoreAction(ProjectClient projectClient, MetricsAction metricsAction, Com Integer determineScore(Integer inheritedRiskScoreThreshold) throws DependencyTrackException { try { - Response response = projectClient.getProject(commonConfig.getProjectName(), commonConfig.getProjectVersion()); + Response response = projectClient.getProject(commonConfig.getProjectUuid(), commonConfig.getProjectName(), commonConfig.getProjectVersion()); Optional body = response.getBody(); if (response.isSuccess() && body.isPresent()) { @@ -89,4 +89,11 @@ private void printInheritedRiskScore(Project project, int inheritedRiskScore, In } logger.info(DELIMITER); } + + /* + * Setters for dependency injection in tests + */ + void setCommonConfig(CommonConfig commonConfig) { + this.commonConfig = commonConfig; + } } diff --git a/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomAction.java b/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomAction.java index 3e9e243..a185514 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomAction.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomAction.java @@ -11,9 +11,7 @@ import org.apache.commons.lang3.StringUtils; -import java.util.Collections; import java.util.Optional; -import java.util.Set; /** * Handles uploading BOMs @@ -39,24 +37,24 @@ public UploadBomAction(BomClient bomClient, BomEncoder bomEncoder, Poller projectTags) throws DependencyTrackException { + public boolean upload() throws DependencyTrackException { logger.info("Project Name: %s", commonConfig.getProjectName()); logger.info("Project Version: %s", commonConfig.getProjectVersion()); - logger.info("Project Tags: %s", StringUtils.join(projectTags, ",")); + logger.info("Project is latest: %s", commonConfig.isLatest()); + logger.info("Project Tags: %s", StringUtils.join(commonConfig.getProjectTags(), ",")); + logger.info("Parent UUID: %s", commonConfig.getParentUuid()); + logger.info("Parent Name: %s", commonConfig.getParentName()); + logger.info("Parent Version: %s", commonConfig.getParentVersion()); logger.info("%s", commonConfig.getPollingConfig()); - Optional encodedBomOptional = bomEncoder.encodeBom(bomLocation, logger); + Optional encodedBomOptional = bomEncoder.encodeBom(commonConfig.getBomLocation(), logger); if (!encodedBomOptional.isPresent()) { - logger.error("No bom.xml could be located at: %s", bomLocation); + logger.error("No bom.xml could be located at: %s", commonConfig.getBomLocation()); return false; } - Optional uploadBomResponse = doUpload(encodedBomOptional.get(), isLatest, projectTags); + Optional uploadBomResponse = doUpload(encodedBomOptional.get()); if (commonConfig.getPollingConfig().isEnabled() && uploadBomResponse.isPresent()) { try { @@ -85,15 +83,11 @@ private void pollUntilBomIsProcessed(UploadBomResponse uploadBomResponse) { }); } - private Optional doUpload(String encodedBom, boolean isLatest, Set projectTags) throws DependencyTrackException { + private Optional doUpload(String encodedBom) throws DependencyTrackException { try { Response response = bomClient.uploadBom( - new UploadBomRequest(commonConfig.getProjectName(), - commonConfig.getProjectVersion(), - true, - encodedBom, - isLatest, - projectTags)); + new UploadBomRequest(commonConfig, encodedBom) + ); if (response.isSuccess()) { logger.info("BOM uploaded to Dependency Track server"); diff --git a/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojo.java b/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojo.java index 956d480..7b8efe6 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojo.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojo.java @@ -49,6 +49,9 @@ public class UploadBomMojo extends AbstractDependencyTrackMojo { @Parameter(property = "dependency-track.updateParent") private boolean updateParent; + @Parameter(defaultValue = "${project.parent.uuid}", property = "dependency-track.parentUuid") + private String parentUuid; + @Parameter(defaultValue = "${project.parent.name}", property = "dependency-track.parentName") private String parentName; @@ -78,20 +81,21 @@ public UploadBomMojo(UploadBomAction uploadBomAction, MetricsAction metricsActio @Override public void performAction() throws MojoExecutionException, MojoFailureException { - logger.info("Update Project Parent : %s", updateParent); + enrichCommonConfig(); + logger.info("Update Project Parent : %s", commonConfig.getUpdateParent()); try { - if (!uploadBomAction.upload(getBomLocation(), isLatest, projectTags)) { + if (!uploadBomAction.upload()) { handleFailure("Bom upload failed"); } - Project project = projectAction.getProject(projectName, projectVersion); + Project project = projectAction.getProject(commonConfig); UpdateRequest updateReq = new UpdateRequest(); if (updateProjectInfo) { updateReq.withBomLocation(getBomLocation()); } if (updateParent) { - updateReq.withParent(getProjectParent(parentName, parentVersion)); + updateReq.withParent(getProjectParent(commonConfig)); } if (updateProjectInfo || updateParent) { boolean projectUpdated = projectAction.updateProject(project, updateReq, projectTags); @@ -107,22 +111,50 @@ public void performAction() throws MojoExecutionException, MojoFailureException } } - private Project getProjectParent(String parentName, String parentVersion) - throws DependencyTrackException { - if (StringUtils.isEmpty(parentName)) { + private void enrichCommonConfig() { + this.commonConfig.setBomLocation(getBomLocation()); + this.commonConfig.setMavenProject(mavenProject); + this.commonConfig.setUpdateProjectInfo(updateProjectInfo); + this.commonConfig.setUpdateParent(updateParent); + this.commonConfig.setParentUuid(parentUuid); + this.commonConfig.setParentName(parentName); + this.commonConfig.setParentVersion(parentVersion); + this.commonConfig.setLatest(isLatest); + this.commonConfig.setProjectTags(projectTags); + } + private Project getProjectParent(CommonConfig commonConfig) throws DependencyTrackException { + if (StringUtils.isBlank(commonConfig.getParentName()) && StringUtils.isBlank(commonConfig.getParentUuid())) { logger.error("Parent update requested but no parent found in parent maven project or provided in config"); - throw new DependencyTrackException("No parent found."); + throw new DependencyTrackException("No parent configured."); } else { - logger.info("Attempting to fetch project parent: '%s-%s'", parentName, parentVersion); - - try { - return projectAction.getProject(parentName, parentVersion); - } catch (DependencyTrackException ex) { - logger.error("Failed to find parent project with name ['%s-%s']. Check the update parent " + - "your settings for this plugin and verify if a matching parent project exists in the " + - "server.", parentName, parentVersion); - throw ex; - } + if (StringUtils.isBlank(commonConfig.getParentUuid())) + return getProjectParentByNameAndVersion(commonConfig.getParentName(), commonConfig.getParentVersion()); + else + return getProjectParentByUuid(commonConfig.getParentUuid()); + } + } + + private Project getProjectParentByUuid(String uuid) throws DependencyTrackException { + logger.info("Attempting to fetch project parent: '%s'", uuid); + try { + return projectAction.getProject(uuid); + } catch (DependencyTrackException ex) { + logger.error("Failed to find parent project with UUID ['%s']. Check the update parent " + + "your settings for this plugin and verify if a matching parent project exists in the " + + "server.", uuid); + throw ex; + } + } + + private Project getProjectParentByNameAndVersion(String name, String version) throws DependencyTrackException { + logger.info("Attempting to fetch project parent: '%s-%s'", name, version); + try { + return projectAction.getProject(name, version); + } catch (DependencyTrackException ex) { + logger.error("Failed to find parent project with name ['%s-%s']. Check the update parent " + + "your settings for this plugin and verify if a matching parent project exists in the " + + "server.", name, version); + throw ex; } } @@ -141,29 +173,52 @@ private String getBomLocation() { */ void setBomLocation(String bomLocation) { this.bomLocation = bomLocation; + commonConfig.setBomLocation(bomLocation); + } + + void setCommonConfig(CommonConfig commonConfig) { + commonConfig.setMavenProject(this.mavenProject); + this.commonConfig = commonConfig; + } + + CommonConfig getCommonConfig() { + return commonConfig; } void setMavenProject(MavenProject mp) { this.mavenProject = mp; + commonConfig.setMavenProject(mp); } void setUpdateParent(boolean updateParent) { this.updateParent = updateParent; + commonConfig.setUpdateParent(updateParent); + } + + public String getParentUuid() { return commonConfig.getParentUuid(); } + + public void setParentUuid(String parentUuid) { + this.parentUuid = parentUuid; + commonConfig.setParentUuid(parentUuid); } void setParentName(String parentName) { this.parentName = parentName; + commonConfig.setParentName(parentName); } void setParentVersion(String parentVersion) { this.parentVersion = parentVersion; + commonConfig.setParentVersion(parentVersion); } void setLatest(boolean isLatest) { this.isLatest = isLatest; + commonConfig.setLatest(isLatest); } void setProjectTags(Set projectTags) { this.projectTags = projectTags; + commonConfig.setProjectTags(projectTags); } } diff --git a/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomRequest.java b/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomRequest.java index fb7b16a..e77d275 100644 --- a/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomRequest.java +++ b/src/main/java/io/github/pmckeown/dependencytrack/upload/UploadBomRequest.java @@ -1,7 +1,7 @@ package io.github.pmckeown.dependencytrack.upload; +import io.github.pmckeown.dependencytrack.CommonConfig; import java.util.List; -import java.util.Set; import java.util.stream.Collectors; import org.apache.commons.lang3.builder.ToStringBuilder; @@ -22,18 +22,24 @@ public class UploadBomRequest { private final String base64EncodedBom; private final boolean isLatest; private final List projectTags; + private final String parentUUID; + private final String parentName; + private final String parentVersion; - UploadBomRequest(String projectName, String projectVersion, boolean autoCreate, String base64EncodedBom, boolean isLatest, Set projectTags) { - this.projectName = projectName; - this.projectVersion = projectVersion; - this.autoCreate = autoCreate; + UploadBomRequest(CommonConfig commonConfig, String base64EncodedBom) { + this.projectName = commonConfig.getProjectName(); + this.projectVersion = commonConfig.getProjectVersion(); + this.autoCreate = commonConfig.isAutoCreate(); this.base64EncodedBom = base64EncodedBom; - this.isLatest = isLatest; - if (projectTags == null) { + this.isLatest = commonConfig.isLatest(); + if (commonConfig.getProjectTags() == null) { this.projectTags = null; } else { - this.projectTags = projectTags.stream().map(ProjectTag::new).collect(Collectors.toList()); + this.projectTags = commonConfig.getProjectTags().stream().map(ProjectTag::new).collect(Collectors.toList()); } + this.parentUUID = commonConfig.getParentUuid(); + this.parentName = commonConfig.getParentName(); + this.parentVersion = commonConfig.getParentVersion(); } public String getProjectName() { @@ -65,6 +71,18 @@ public List getProjectTags() { return projectTags; } + public String getParentUUID() { + return parentUUID; + } + + public String getParentName() { + return parentName; + } + + public String getParentVersion() { + return parentVersion; + } + @Override public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); diff --git a/src/test/java/io/github/pmckeown/dependencytrack/CommonConfigTest.java b/src/test/java/io/github/pmckeown/dependencytrack/CommonConfigTest.java new file mode 100644 index 0000000..2bd2a75 --- /dev/null +++ b/src/test/java/io/github/pmckeown/dependencytrack/CommonConfigTest.java @@ -0,0 +1,43 @@ +package io.github.pmckeown.dependencytrack; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.Mockito.doReturn; + +import java.io.File; +import org.apache.maven.project.MavenProject; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class CommonConfigTest { + + private static final String PROJECT_NAME = "test"; + + private static final String PROJECT_VERSION = "1.0"; + + @Mock + private MavenProject project; + + @InjectMocks + private CommonConfig commonConfig; + + @Before + public void setup() { + commonConfig = new CommonConfig(); + commonConfig.setMavenProject(project); + } + + @Test + public void thatTheBomLocationIsDefaultedWhenNotSupplied() { + doReturn(new File(".")).when(project).getBasedir(); + + assertThat(commonConfig.getBomLocation(), is(equalTo("./target/bom.xml"))); + assertThat(commonConfig.isLatest(), is(equalTo(false))); + } +} diff --git a/src/test/java/io/github/pmckeown/dependencytrack/metrics/MetricsMojoIntegrationTest.java b/src/test/java/io/github/pmckeown/dependencytrack/metrics/MetricsMojoIntegrationTest.java index 5856b53..d6596ad 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/metrics/MetricsMojoIntegrationTest.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/metrics/MetricsMojoIntegrationTest.java @@ -3,7 +3,6 @@ import com.github.tomakehurst.wiremock.http.Fault; import io.github.pmckeown.dependencytrack.AbstractDependencyTrackMojoTest; import io.github.pmckeown.dependencytrack.PollingConfig; -import io.github.pmckeown.dependencytrack.ResourceConstants; import io.github.pmckeown.dependencytrack.project.ProjectBuilder; import org.apache.maven.plugin.MojoExecutionException; diff --git a/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectActionTest.java b/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectActionTest.java index 7ff715c..e04f72a 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectActionTest.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectActionTest.java @@ -1,5 +1,6 @@ package io.github.pmckeown.dependencytrack.project; +import io.github.pmckeown.dependencytrack.CommonConfig; import io.github.pmckeown.dependencytrack.DependencyTrackException; import io.github.pmckeown.dependencytrack.Response; import io.github.pmckeown.dependencytrack.bom.BomParser; @@ -37,9 +38,6 @@ @RunWith(MockitoJUnitRunner.class) public class ProjectActionTest { - private static final String UUID_1 = "project-uuid-1"; - private static final String PROJECT_NAME_1 = "projectName1"; - private static final String PROJECT_VERSION_1 = "projectVersion1"; private static final String UUID_2 = "project-uuid-2"; private static final String PROJECT_NAME_2 = "projectName2"; private static final String PROJECT_VERSION_2 = "projectVersion2"; @@ -47,6 +45,9 @@ public class ProjectActionTest { @InjectMocks private ProjectAction projectAction; + @Mock + private CommonConfig commonConfig1; + @Mock private ProjectClient projectClient; @@ -56,9 +57,19 @@ public class ProjectActionTest { @Mock private Logger logger; + @Test + public void thatProjectCanBeRetrievedByCommonConfig() throws Exception { + doReturn(aSuccessResponse().withBody(project2()).build()).when(projectClient).getProject(anyString(), anyString(), anyString()); + + Project project = projectAction.getProject(commonConfig1()); + + assertThat(project, is(not(nullValue()))); + assertThat(project.getUuid(), is(equalTo(UUID_2))); + } + @Test public void thatProjectCanBeRetrievedByNameAndVersion() throws Exception { - doReturn(aSuccessResponse().withBody(project2()).build()).when(projectClient).getProject(anyString(), anyString()); + doReturn(aSuccessResponse().withBody(project2()).build()).when(projectClient).getProject(anyString(), anyString(), anyString()); Project project = projectAction.getProject(PROJECT_NAME_2, PROJECT_VERSION_2); @@ -66,12 +77,22 @@ public void thatProjectCanBeRetrievedByNameAndVersion() throws Exception { assertThat(project.getUuid(), is(equalTo(UUID_2))); } + @Test + public void thatProjectCanBeRetrievedByUuid() throws Exception { + doReturn(aSuccessResponse().withBody(project2()).build()).when(projectClient).getProject(anyString(), anyString(), anyString()); + + Project project = projectAction.getProject(UUID_2); + + assertThat(project, is(not(nullValue()))); + assertThat(project.getUuid(), is(equalTo(UUID_2))); + } + @Test public void thatExceptionIsThrownWhenConnectionFails() { - doThrow(UnirestException.class).when(projectClient).getProject(anyString(), anyString()); + doThrow(UnirestException.class).when(projectClient).getProject(anyString(), anyString(), anyString()); try { - projectAction.getProject(PROJECT_NAME_2, PROJECT_VERSION_2); + projectAction.getProject(commonConfig1()); } catch (Exception ex) { assertThat(ex, is(instanceOf(DependencyTrackException.class))); } @@ -79,17 +100,17 @@ public void thatExceptionIsThrownWhenConnectionFails() { @Test(expected = DependencyTrackException.class) public void thatANotFoundResponseResultsInAnException() throws DependencyTrackException { - doReturn(aNotFoundResponse()).when(projectClient).getProject(anyString(), anyString()); + doReturn(aNotFoundResponse()).when(projectClient).getProject(anyString(), anyString(), anyString()); - projectAction.getProject(PROJECT_NAME_2, PROJECT_VERSION_2); + projectAction.getProject(commonConfig1()); } @Test public void thatNoProjectsAreFoundAnExceptionIsThrown() { - doReturn(aSuccessResponse().build()).when(projectClient).getProject(anyString(), anyString()); + doReturn(aSuccessResponse().build()).when(projectClient).getProject(anyString(), anyString(), anyString()); try { - projectAction.getProject(PROJECT_NAME_2, PROJECT_VERSION_2); + projectAction.getProject(commonConfig1()); } catch (Exception ex) { assertThat(ex, is(instanceOf(DependencyTrackException.class))); } @@ -97,9 +118,9 @@ public void thatNoProjectsAreFoundAnExceptionIsThrown() { @Test(expected = DependencyTrackException.class) public void thatRequestedProjectCannotBeFoundAnExceptionIsThrown() throws DependencyTrackException { - doReturn(aSuccessResponse().build()).when(projectClient).getProject(anyString(), anyString()); + doReturn(aSuccessResponse().build()).when(projectClient).getProject(anyString(), anyString(), anyString()); - projectAction.getProject("missing-project", "unknown-version"); + projectAction.getProject(commonConfig1()); } @Test @@ -233,4 +254,10 @@ private Project projectWithTags(List tags) { return new Project(UUID_2, PROJECT_NAME_2, PROJECT_VERSION_2, null, false, tags); } + private CommonConfig commonConfig1() { + CommonConfig commonConfig = new CommonConfig(); + commonConfig.setProjectName(PROJECT_NAME_2); + commonConfig.setProjectVersion(PROJECT_VERSION_2); + return commonConfig; + } } diff --git a/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectClientIntegrationTest.java b/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectClientIntegrationTest.java index fa0f933..8e4dd6b 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectClientIntegrationTest.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/project/ProjectClientIntegrationTest.java @@ -6,6 +6,10 @@ import kong.unirest.HttpStatus; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.exactly; @@ -24,15 +28,20 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.hasItems; import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.Mockito.doReturn; +@RunWith(MockitoJUnitRunner.class) public class ProjectClientIntegrationTest extends AbstractDependencyTrackMojoTest { + @InjectMocks private ProjectClient projectClient; + @Mock + private CommonConfig commonConfig; + @Before public void setUp() { - CommonConfig commonConfig = new CommonConfig(); - commonConfig.setDependencyTrackBaseUrl("http://localhost:" + wireMockRule.port()); + doReturn("http://localhost:" + wireMockRule.port()).when(commonConfig).getDependencyTrackBaseUrl(); projectClient = new ProjectClient(commonConfig); } @@ -48,12 +57,14 @@ public void thatProjectInfoUpdateReturnsSuccessWhenServerReturnsSuccess() { @Test public void thatProjectParsingWorks() { + doReturn("doesn't matter").when(commonConfig).getProjectName(); + doReturn("doesn't matter").when(commonConfig).getProjectVersion(); stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).willReturn( aResponse() .withStatus(HttpStatus.OK) .withBodyFile("api/v1/project/tags-project.json"))); - Response response = projectClient.getProject("doesn't matter", "doesn't matter"); + Response response = projectClient.getProject(commonConfig.getProjectUuid(), commonConfig.getProjectName(), commonConfig.getProjectVersion()); assertThat(response.isSuccess(), is(equalTo(true))); assertThat(response.getBody().isPresent(), is(equalTo(true))); Project project = response.getBody().get(); diff --git a/src/test/java/io/github/pmckeown/dependencytrack/score/ScoreActionTest.java b/src/test/java/io/github/pmckeown/dependencytrack/score/ScoreActionTest.java index 2389caf..e62bd09 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/score/ScoreActionTest.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/score/ScoreActionTest.java @@ -9,6 +9,7 @@ import io.github.pmckeown.util.Logger; import kong.unirest.UnirestException; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; @@ -44,17 +45,17 @@ public class ScoreActionTest { @Mock private MetricsAction metricsAction; - @Mock - private CommonConfig commonConfig; - @Mock private Logger logger; + @Before + public void setup() { + scoreAction.setCommonConfig(new CommonConfig()); + } + @Test(expected = DependencyTrackException.class) public void thatWhenAnExceptionOccursGettingProjectsThenAnExceptionIsThrown() throws DependencyTrackException { - doReturn("ProjectName").when(commonConfig).getProjectName(); - doReturn("ProjectVersion").when(commonConfig).getProjectVersion(); - doThrow(UnirestException.class).when(projectClient).getProject(anyString(), anyString()); + doThrow(UnirestException.class).when(projectClient).getProject(anyString(), anyString(), anyString()); scoreAction.determineScore(INHERITED_RISK_SCORE_THRESHOLD); fail("Exception expected"); @@ -62,9 +63,7 @@ public void thatWhenAnExceptionOccursGettingProjectsThenAnExceptionIsThrown() th @Test(expected = DependencyTrackException.class) public void thatWhenNoProjectsAreFoundThenAnExceptionIsThrown() throws DependencyTrackException { - doReturn("ProjectName").when(commonConfig).getProjectName(); - doReturn("ProjectVersion").when(commonConfig).getProjectVersion(); - doReturn(new Response(404, "Not Found", false)).when(projectClient).getProject(anyString(), anyString()); + doReturn(new Response(404, "Not Found", false)).when(projectClient).getProject(anyString(), anyString(), anyString()); scoreAction.determineScore(INHERITED_RISK_SCORE_THRESHOLD); fail("Exception expected"); @@ -73,9 +72,7 @@ public void thatWhenNoProjectsAreFoundThenAnExceptionIsThrown() throws Dependenc @Test public void thatWhenTheCurrentProjectHasMetricsInItThenTheScoreIsReturned() throws Exception { Project project = aProject().withMetrics(aMetrics().withInheritedRiskScore(100)).build(); - doReturn(aSuccessResponse().withBody(project).build()).when(projectClient).getProject(anyString(), anyString()); - doReturn(project.getName()).when(commonConfig).getProjectName(); - doReturn(project.getVersion()).when(commonConfig).getProjectVersion(); + doReturn(aSuccessResponse().withBody(project).build()).when(projectClient).getProject(anyString(), anyString(), anyString()); Integer score = scoreAction.determineScore(INHERITED_RISK_SCORE_THRESHOLD); assertThat(score, is(equalTo(100))); @@ -86,11 +83,9 @@ public void thatWhenTheCurrentProjectHasMetricsInItThenTheScoreIsReturned() thro @Test public void thatWhenTheCurrentProjectHasNoMetricsInItTheyAreRequestedAndThenTheScoreIsReturned() throws Exception { Project project = aProject().build(); - doReturn(aSuccessResponse().withBody(project).build()).when(projectClient).getProject(anyString(), anyString()); + doReturn(aSuccessResponse().withBody(project).build()).when(projectClient).getProject(anyString(), anyString(), anyString()); doReturn(aMetrics().withInheritedRiskScore(100).build()).when(metricsAction).getMetrics( any(Project.class)); - doReturn(project.getName()).when(commonConfig).getProjectName(); - doReturn(project.getVersion()).when(commonConfig).getProjectVersion(); Integer score = scoreAction.determineScore(INHERITED_RISK_SCORE_THRESHOLD); assertThat(score, is(equalTo(100))); @@ -101,11 +96,9 @@ public void thatWhenTheCurrentProjectHasNoMetricsInItTheyAreRequestedAndThenTheS @Test public void thatWhenTheCurrentProjectScoreIsZeroThenTheScoreIsReturned() throws Exception { Project project = aProject().build(); - doReturn(aSuccessResponse().withBody(project).build()).when(projectClient).getProject(anyString(), anyString()); + doReturn(aSuccessResponse().withBody(project).build()).when(projectClient).getProject(anyString(), anyString(), anyString()); doReturn(aMetrics().withInheritedRiskScore(0).build()).when(metricsAction).getMetrics( any(Project.class)); - doReturn(project.getName()).when(commonConfig).getProjectName(); - doReturn(project.getVersion()).when(commonConfig).getProjectVersion(); Integer score = scoreAction.determineScore(INHERITED_RISK_SCORE_THRESHOLD); assertThat(score, is(equalTo(0))); diff --git a/src/test/java/io/github/pmckeown/dependencytrack/upload/BomClientIntegrationTest.java b/src/test/java/io/github/pmckeown/dependencytrack/upload/BomClientIntegrationTest.java index 7672dea..c94aabd 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/upload/BomClientIntegrationTest.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/upload/BomClientIntegrationTest.java @@ -31,8 +31,6 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.fail; -import java.util.Collections; - public class BomClientIntegrationTest extends AbstractDependencyTrackIntegrationTest { private static final String BASE_64_ENCODED_BOM = "blah"; @@ -121,6 +119,6 @@ public void thatWhenAnErrorOccursWhileQueryingTheAUnirestExceptionIsThrown() { */ private UploadBomRequest aBom() { - return new UploadBomRequest(PROJECT_NAME, PROJECT_VERSION, false, BASE_64_ENCODED_BOM, false, Collections.emptySet()); + return new UploadBomRequest(getCommonConfig(), BASE_64_ENCODED_BOM); } } diff --git a/src/test/java/io/github/pmckeown/dependencytrack/upload/UploadBomActionTest.java b/src/test/java/io/github/pmckeown/dependencytrack/upload/UploadBomActionTest.java index 173db9a..610b384 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/upload/UploadBomActionTest.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/upload/UploadBomActionTest.java @@ -3,7 +3,6 @@ import io.github.pmckeown.dependencytrack.*; import io.github.pmckeown.util.BomEncoder; import io.github.pmckeown.util.Logger; -import kong.unirest.UnirestException; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; @@ -23,7 +22,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -52,33 +50,34 @@ public class UploadBomActionTest { @Test public void thatWhenNoBomIsFoundThenFalseIsReturned() throws Exception { - doReturn(Optional.empty()).when(bomEncoder).encodeBom(BOM_LOCATION, logger); doReturn(PollingConfig.disabled()).when(commonConfig).getPollingConfig(); - boolean success = uploadBomAction.upload(BOM_LOCATION); + boolean success = uploadBomAction.upload(); assertThat(success, is(equalTo(false))); } @Test public void thatBomCanBeUploadedSuccessfully() throws Exception { + doReturn(BOM_LOCATION).when(commonConfig).getBomLocation(); doReturn(Optional.of("encoded-bom")).when(bomEncoder).encodeBom(BOM_LOCATION, logger); doReturn(anUploadBomSuccessResponse()).when(bomClient).uploadBom(any(UploadBomRequest.class)); doReturn(PollingConfig.disabled()).when(commonConfig).getPollingConfig(); - boolean success = uploadBomAction.upload(BOM_LOCATION); + boolean success = uploadBomAction.upload(); assertThat(success, is(equalTo(true))); } @Test public void thatBomUploadFailureReturnsFalse() { + doReturn(BOM_LOCATION).when(commonConfig).getBomLocation(); doReturn(Optional.of("encoded-bom")).when(bomEncoder).encodeBom(BOM_LOCATION, logger); doReturn(aNotFoundResponse()).when(bomClient).uploadBom(any(UploadBomRequest.class)); doReturn(PollingConfig.disabled()).when(commonConfig).getPollingConfig(); try { - uploadBomAction.upload(BOM_LOCATION); + uploadBomAction.upload(); fail("DependencyTrackException expected"); } catch (Exception ex) { assertThat(ex, is(instanceOf(DependencyTrackException.class))); @@ -87,12 +86,10 @@ public void thatBomUploadFailureReturnsFalse() { @Test public void thatBomUploadExceptionResultsInException() { - doReturn(Optional.of("encoded-bom")).when(bomEncoder).encodeBom(BOM_LOCATION, logger); - doThrow(UnirestException.class).when(bomClient).uploadBom(any(UploadBomRequest.class)); doReturn(PollingConfig.disabled()).when(commonConfig).getPollingConfig(); try { - uploadBomAction.upload(BOM_LOCATION); + uploadBomAction.upload(); } catch (Exception ex) { assertThat(ex, is(instanceOf(DependencyTrackException.class))); } @@ -100,6 +97,7 @@ public void thatBomUploadExceptionResultsInException() { @Test public void thatWhenPollingIsEnabledThatTheServerIsQueriedUntilBomIsFullyProcessed() throws Exception { + doReturn(BOM_LOCATION).when(commonConfig).getBomLocation(); doReturn(Optional.of("encoded-bom")).when(bomEncoder).encodeBom(BOM_LOCATION, logger); doReturn(anUploadBomSuccessResponse()).when(bomClient).uploadBom(any(UploadBomRequest.class)); doReturn(new PollingConfig(true, 1, 3, MILLIS)).when(commonConfig).getPollingConfig(); @@ -113,7 +111,7 @@ public void thatWhenPollingIsEnabledThatTheServerIsQueriedUntilBomIsFullyProcess .doReturn(aBomProcessingResponse(false)) .when(bomClient).isBomBeingProcessed(anyString()); - uploadBomAction.upload(BOM_LOCATION); + uploadBomAction.upload(); verify(bomClient, times(3)).isBomBeingProcessed(anyString()); } @@ -133,7 +131,7 @@ private Response anUploadBomSuccessResponse() { } private Response aNotFoundResponse() { - return new Response(404, "Not Found", false); + return new Response(404, "Not Found", false, Optional.of("The parent component could not be found.")); } } diff --git a/src/test/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojoIntegrationTest.java b/src/test/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojoIntegrationTest.java index 12a1401..ff88b5e 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojoIntegrationTest.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojoIntegrationTest.java @@ -52,7 +52,7 @@ public void thatBomCanBeUploadedSuccessfully() throws Exception { } @Test - public void thatWhenFailOnErrorIsFalseAFailureFromToDependencyTrackDoesNotFailTheBuild() { + public void thatWhenFailOnErrorIsFalseAFailureFromToDependencyTrackDoesNotFailTheBuild() throws Exception { stubFor(put(urlEqualTo(ResourceConstants.V1_BOM)).willReturn(notFound())); try { @@ -88,7 +88,7 @@ public void thatWhenFailOnErrorIsTrueAFailureFromToDependencyTrackDoesFailTheBui } @Test - public void thatWhenFailOnErrorIsFalseAFailureToConnectToDependencyTrackDoesNotFailTheBuild() { + public void thatWhenFailOnErrorIsFalseAFailureToConnectToDependencyTrackDoesNotFailTheBuild() throws Exception { // No Wiremock Stubbing try { @@ -225,34 +225,6 @@ public void thatSslVerifyDefaultsToTrue() throws Exception { assertThat(Unirest.config().isVerifySsl(), is(true)); } - @Test - public void thatProjectParentNameAndVersionCanBeProvided() throws Exception { - stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)) - .withQueryParam("name", equalTo("test-parent")) - .willReturn(aResponse().withBodyFile("api/v1/project/test-parent.json"))); - stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)).atPriority(1) - .withQueryParam("name", equalTo("test-project")) - .willReturn(aResponse().withBodyFile("api/v1/project/test-project.json"))); - stubFor(get(urlPathMatching(TestResourceConstants.V1_PROJECT_UUID)).willReturn(ok())); - stubFor(patch(urlPathMatching(TestResourceConstants.V1_PROJECT_UUID)).willReturn(ok())); - stubFor(get(urlPathMatching(TestResourceConstants.V1_BOM_TOKEN_UUID)).willReturn(ok())); - stubFor(put(urlEqualTo(V1_BOM)).willReturn( - aResponse().withBodyFile("api/v1/project/upload-bom-response.json"))); - stubFor(get(urlPathMatching(TestResourceConstants.V1_METRICS_PROJECT_REFRESH)).willReturn(ok())); - - UploadBomMojo uploadBomMojo = uploadBomMojo(BOM_LOCATION); - uploadBomMojo.setProjectName("test-project"); - uploadBomMojo.setUpdateParent(true); - uploadBomMojo.setParentName("test-parent"); - uploadBomMojo.setParentVersion("1.0.0-SNAPSHOT"); - uploadBomMojo.setFailOnError(true); - uploadBomMojo.execute(); - - verify(exactly(1), patchRequestedFor(urlPathMatching(TestResourceConstants.V1_PROJECT_UUID)) - .withRequestBody( - matchingJsonPath("$.parent.uuid", equalTo("8977c66f-b310-aced-face-e63e9eb7c4cf")))); - } - @Test public void thatProjectParentNameAndVersionCanBeIgnored() throws Exception { stubFor(get(urlPathEqualTo(V1_PROJECT_LOOKUP)) diff --git a/src/test/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojoTest.java b/src/test/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojoTest.java index 09811b8..9145158 100644 --- a/src/test/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojoTest.java +++ b/src/test/java/io/github/pmckeown/dependencytrack/upload/UploadBomMojoTest.java @@ -10,23 +10,15 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; - -import java.io.File; import java.util.Collections; -import java.util.Set; -import static io.github.pmckeown.dependencytrack.project.ProjectBuilder.aProject; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anySet; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; @@ -61,28 +53,10 @@ public class UploadBomMojoTest { @Before public void setup() { + uploadBomMojo.setCommonConfig(commonConfig); uploadBomMojo.setMavenProject(project); } - @Test - public void thatTheBomLocationIsDefaultedWhenNotSupplied() throws Exception { - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(String.class); - ArgumentCaptor argumentCaptor2 = ArgumentCaptor.forClass(Boolean.class); - ArgumentCaptor> argumentCaptor3 = ArgumentCaptor.forClass(Set.class); - doReturn(new File(".")).when(project).getBasedir(); - doReturn(aProject().build()).when(projectAction).getProject(PROJECT_NAME, PROJECT_VERSION); - doReturn(true).when(uploadBomAction).upload(anyString(), anyBoolean(), anySet()); - - uploadBomMojo.setProjectName(PROJECT_NAME); - uploadBomMojo.setProjectVersion(PROJECT_VERSION); - uploadBomMojo.setProjectTags(Collections.emptySet()); - uploadBomMojo.execute(); - - verify(uploadBomAction).upload(argumentCaptor.capture(), argumentCaptor2.capture(), argumentCaptor3.capture()); - assertThat(argumentCaptor.getValue(), is(equalTo("./target/bom.xml"))); - assertThat(argumentCaptor2.getValue(), is(equalTo(false))); - } - @Test public void thatTheUploadBomIsSkippedWhenSkipIsTrue() throws Exception { uploadBomMojo.setSkip("true"); @@ -145,10 +119,14 @@ public void thatUnirestIsConfiguredWithSslVerifyOffWhenAsked() throws Exception @Test public void thatWhenUpdateParentFailsTheLoggerIsCalledAndBuildFails() throws Exception { - doReturn(true).when(uploadBomAction).upload(anyString(), anyBoolean(), anySet()); - doReturn(aProject().withName("project-parent").withVersion("1.2.3").build()) - .when(projectAction).getProject("project-parent", "1.2.3"); + doReturn(true).when(uploadBomAction).upload(); + + CommonConfig config = new CommonConfig(); + config.setProjectName("project-parent"); + config.setProjectVersion("1.2.3"); + config.setUpdateParent(true); + uploadBomMojo.setCommonConfig(config); uploadBomMojo.setParentName("project-parent"); uploadBomMojo.setParentVersion("1.2.3"); uploadBomMojo.setUpdateParent(true); @@ -166,7 +144,7 @@ public void thatWhenUpdateParentFailsTheLoggerIsCalledAndBuildFails() throws Exc @Test public void thatUpdateParentFailsWhenParentNameIsNull() throws Exception { - doReturn(true).when(uploadBomAction).upload(anyString(), anyBoolean(), anySet()); + doReturn(true).when(uploadBomAction).upload(); uploadBomMojo.setParentName(null); uploadBomMojo.setParentVersion(null); diff --git a/src/test/resources/__files/api/v1/project/test-parent.json b/src/test/resources/__files/api/v1/project/test-parent.json index 12ede75..c88761a 100644 --- a/src/test/resources/__files/api/v1/project/test-parent.json +++ b/src/test/resources/__files/api/v1/project/test-parent.json @@ -1,4 +1,3 @@ - { "name": "test-parent", "version": "1.0.0-SNAPSHOT",