From 220b3156c23183a3a68f0e476f921b7bb747293b Mon Sep 17 00:00:00 2001 From: nscuro Date: Thu, 26 Sep 2024 15:14:19 +0200 Subject: [PATCH] Fix `authors` column failing to be mapped for `/api/v1/component/project/{uuid}` endpoint This is just a simple fix to resolve the issue. But really this logic should be moved to a JDBI DAO, which is where we maintain our SQL queries now. Fixes https://github.com/DependencyTrack/hyades/issues/1536 Signed-off-by: nscuro --- .../model/ComponentMetaInformation.java | 11 ++++-- .../model/sqlmapping/ComponentProjection.java | 25 ++++++++---- .../v1/ComponentResourcePostgresTest.java | 38 +++++++++++++++++++ 3 files changed, 64 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/dependencytrack/model/ComponentMetaInformation.java b/src/main/java/org/dependencytrack/model/ComponentMetaInformation.java index d0f3b4449..0360e22d0 100644 --- a/src/main/java/org/dependencytrack/model/ComponentMetaInformation.java +++ b/src/main/java/org/dependencytrack/model/ComponentMetaInformation.java @@ -18,9 +18,14 @@ */ package org.dependencytrack.model; +import com.fasterxml.jackson.annotation.JsonInclude; + import java.util.Date; -public record ComponentMetaInformation(Date publishedDate, IntegrityMatchStatus integrityMatchStatus, - Date lastFetched, - String integrityRepoUrl) { +@JsonInclude(JsonInclude.Include.NON_NULL) +public record ComponentMetaInformation( + Date publishedDate, + IntegrityMatchStatus integrityMatchStatus, + Date lastFetched, + String integrityRepoUrl) { } diff --git a/src/main/java/org/dependencytrack/model/sqlmapping/ComponentProjection.java b/src/main/java/org/dependencytrack/model/sqlmapping/ComponentProjection.java index ce8ad2314..c8cc65eb4 100644 --- a/src/main/java/org/dependencytrack/model/sqlmapping/ComponentProjection.java +++ b/src/main/java/org/dependencytrack/model/sqlmapping/ComponentProjection.java @@ -24,8 +24,9 @@ import org.dependencytrack.model.ComponentMetaInformation; import org.dependencytrack.model.IntegrityMatchStatus; import org.dependencytrack.model.License; -import org.dependencytrack.model.Project; import org.dependencytrack.model.OrganizationalContact; +import org.dependencytrack.model.Project; +import org.dependencytrack.persistence.converter.OrganizationalContactsJsonConverter; import java.util.Date; import java.util.List; @@ -37,7 +38,7 @@ public class ComponentProjection { public String uuid; - public List authors; + public String authors; public String group; @@ -164,7 +165,10 @@ public class ComponentProjection { public static Component mapToComponent(ComponentProjection result) { Component componentPersistent = new Component(); - componentPersistent.setAuthors(result.authors); + if (result.authors != null) { + final var converter = new OrganizationalContactsJsonConverter(); + componentPersistent.setAuthors(converter.convertToAttribute(result.authors)); + } componentPersistent.setBlake2b_256(result.blake2b_256); componentPersistent.setBlake2b_384(result.blake2b_384); componentPersistent.setBlake2b_512(result.blake2b_512); @@ -230,6 +234,7 @@ public static Component mapToComponent(ComponentProjection result) { project.setDirectDependencies(result.projectDirectDependencies); project.setLastBomImport(result.lastBomImport); project.setLastBomImportFormat(result.lastBomImportFormat); + project.setGroup(result.projectGroup); project.setName(result.projectName); if (result.projectUuid != null) { project.setUuid(UUID.fromString(result.projectUuid)); @@ -254,10 +259,16 @@ public static Component mapToComponent(ComponentProjection result) { componentPersistent.setResolvedLicense(license); } - var componentMetaInformation = new ComponentMetaInformation(result.publishedAt, - result.integrityCheckStatus != null ? IntegrityMatchStatus.valueOf(result.integrityCheckStatus) : null, - result.lastFetch, result.integrityRepoUrl); - componentPersistent.setComponentMetaInformation(componentMetaInformation); + if (result.publishedAt != null + || result.integrityCheckStatus != null + || result.lastFetch != null + || result.integrityRepoUrl != null) { + componentPersistent.setComponentMetaInformation(new ComponentMetaInformation( + result.publishedAt, + result.integrityCheckStatus != null ? IntegrityMatchStatus.valueOf(result.integrityCheckStatus) : null, + result.lastFetch, + result.integrityRepoUrl)); + } return componentPersistent; } diff --git a/src/test/java/org/dependencytrack/resources/v1/ComponentResourcePostgresTest.java b/src/test/java/org/dependencytrack/resources/v1/ComponentResourcePostgresTest.java index 6f6a79f1f..e2f3c8b01 100644 --- a/src/test/java/org/dependencytrack/resources/v1/ComponentResourcePostgresTest.java +++ b/src/test/java/org/dependencytrack/resources/v1/ComponentResourcePostgresTest.java @@ -26,6 +26,7 @@ import org.dependencytrack.JerseyTestRule; import org.dependencytrack.ResourceTest; import org.dependencytrack.model.Component; +import org.dependencytrack.model.OrganizationalContact; import org.dependencytrack.model.Project; import org.dependencytrack.model.RepositoryMetaComponent; import org.dependencytrack.model.RepositoryType; @@ -42,7 +43,9 @@ import java.util.Date; import java.util.List; +import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.equalTo; public class ComponentResourcePostgresTest extends ResourceTest { @@ -65,6 +68,37 @@ public void getAllComponentsTest() throws MalformedPackageURLException { final JsonArray json = parseJsonArray(response); assertThat(json).hasSize(100); // Default page size is 100 + assertThatJson(json.getFirst().toString()) + .withMatcher("projectUuid", equalTo(project.getUuid().toString())) + .isEqualTo(""" + { + "authors": [ + { + "name": "author-0" + } + ], + "group": "component-group", + "name": "component-name-0", + "version": "0.0", + "purl": "pkg:maven/component-group/component-name-0@0.0", + "project": { + "name": "Acme Application", + "directDependencies": "${json-unit.any-string}", + "uuid": "${json-unit.matches:projectUuid}", + "active": true + }, + "uuid": "${json-unit.any-string}", + "repositoryMeta": { + "repositoryType": "MAVEN", + "namespace": "component-group", + "name": "component-name-0", + "latestVersion": "0.0", + "lastCheck": "${json-unit.any-number}" + }, + "expandDependencyGraph": false, + "isInternal": false + } + """); } @Test @@ -188,8 +222,12 @@ private Project prepareProject() throws MalformedPackageURLException { final List directDepencencies = new ArrayList<>(); // Generate 1000 dependencies for (int i = 0; i < 1000; i++) { + final var author = new OrganizationalContact(); + author.setName("author-" + i); + Component component = new Component(); component.setProject(project); + component.setAuthors(List.of(author)); component.setGroup("component-group"); component.setName("component-name-" + i); component.setVersion(String.valueOf(i) + ".0");