diff --git a/docs/_posts/2024-xx-xx-v4.11.0.md b/docs/_posts/2024-xx-xx-v4.11.0.md index 4077ff63c5..7c91914d7d 100644 --- a/docs/_posts/2024-xx-xx-v4.11.0.md +++ b/docs/_posts/2024-xx-xx-v4.11.0.md @@ -80,6 +80,7 @@ environment variable `BOM_VALIDATION_ENABLED` to `false`. * Fix `bom` and `vex` request fields not being visible in OpenAPI spec - [apiserver/#3557] * Fix unclear error response when base64 encoded `bom` and `vex` values exceed character limit - [apiserver/#3558] * Fix unhandled `NotFoundException`s causing a `HTTP 500` response - [apiserver/#3559] +* Fix inability to store PURLs longer than 255 characters - [apiserver/#3560] * Fix `VUE_APP_SERVER_URL` being ignored - [frontend/#682] * Fix visibility of "Vulnerabilities" and "Policy Violations" columns not being toggle-able individually - [frontend/#686] * Fix finding search routes - [frontend/#689] @@ -112,6 +113,11 @@ and updated automatically upon upgrade, based on CVSSv2, CVSSv3, and OWASP Risk * The following default values for configuration properties have changed: * `ossindex.retry.backoff.max.duration.ms`: 600000ms (10min) → 60000ms (1min) * The `name` tag of the `resilience4j_retry_calls_total` for OSS Index has changed from `ossIndexRetryer` to `ossindex-api` +* The types of the following columns are changed from `VARCHAR(255)` to `VARCHAR(786)` automatically upon upgrade: + * `COMPONENT.PURL` + * `COMPONENT.PURLCOORDINATES` + * `COMPONENTANALYSISCACHE.TARGET` + * `PROJECT.PURL` For a complete list of changes, refer to the respective GitHub milestones: @@ -184,6 +190,7 @@ Special thanks to everyone who contributed code to implement enhancements and fi [apiserver/#3557]: https://github.com/DependencyTrack/dependency-track/pull/3557 [apiserver/#3558]: https://github.com/DependencyTrack/dependency-track/pull/3558 [apiserver/#3559]: https://github.com/DependencyTrack/dependency-track/pull/3559 +[apiserver/#3560]: https://github.com/DependencyTrack/dependency-track/pull/3560 [frontend/#682]: https://github.com/DependencyTrack/frontend/pull/682 [frontend/#683]: https://github.com/DependencyTrack/frontend/pull/683 diff --git a/src/main/java/org/dependencytrack/model/Component.java b/src/main/java/org/dependencytrack/model/Component.java index fcba320057..efe02b6149 100644 --- a/src/main/java/org/dependencytrack/model/Component.java +++ b/src/main/java/org/dependencytrack/model/Component.java @@ -248,7 +248,8 @@ public enum FetchGroup { @Persistent(defaultFetchGroup = "true") @Index(name = "COMPONENT_PURL_IDX") - @Size(max = 255) + @Column(name = "PURL", length = 786) + @Size(max = 786) @com.github.packageurl.validator.PackageURL @JsonDeserialize(using = TrimmedStringDeserializer.class) @ApiModelProperty(dataType = "string") @@ -256,7 +257,8 @@ public enum FetchGroup { @Persistent(defaultFetchGroup = "true") @Index(name = "COMPONENT_PURL_COORDINATES_IDX") - @Size(max = 255) + @Column(name = "PURLCOORDINATES", length = 786) + @Size(max = 786) @com.github.packageurl.validator.PackageURL @JsonDeserialize(using = TrimmedStringDeserializer.class) private String purlCoordinates; // Field should contain only type, namespace, name, and version. Everything up to the qualifiers diff --git a/src/main/java/org/dependencytrack/model/ComponentAnalysisCache.java b/src/main/java/org/dependencytrack/model/ComponentAnalysisCache.java index f935eb0ad3..96e7383d32 100644 --- a/src/main/java/org/dependencytrack/model/ComponentAnalysisCache.java +++ b/src/main/java/org/dependencytrack/model/ComponentAnalysisCache.java @@ -84,7 +84,7 @@ public enum CacheType { private String targetType; @Persistent - @Column(name = "TARGET", allowsNull = "false") + @Column(name = "TARGET", allowsNull = "false", length = 786) @NotNull private String target; diff --git a/src/main/java/org/dependencytrack/model/Project.java b/src/main/java/org/dependencytrack/model/Project.java index 1f8964b9b4..b234845f10 100644 --- a/src/main/java/org/dependencytrack/model/Project.java +++ b/src/main/java/org/dependencytrack/model/Project.java @@ -195,7 +195,8 @@ public enum FetchGroup { @Persistent @Index(name = "PROJECT_PURL_IDX") - @Size(max = 255) + @Column(name = "PURL", length = 786) + @Size(max = 786) @com.github.packageurl.validator.PackageURL @JsonDeserialize(using = TrimmedStringDeserializer.class) @ApiModelProperty(dataType = "string") diff --git a/src/main/java/org/dependencytrack/upgrade/v4110/v4110Updater.java b/src/main/java/org/dependencytrack/upgrade/v4110/v4110Updater.java index aed0b8c6a8..66ee37efc3 100644 --- a/src/main/java/org/dependencytrack/upgrade/v4110/v4110Updater.java +++ b/src/main/java/org/dependencytrack/upgrade/v4110/v4110Updater.java @@ -21,6 +21,7 @@ import alpine.common.logging.Logger; import alpine.persistence.AlpineQueryManager; import alpine.server.upgrade.AbstractUpgradeItem; +import alpine.server.util.DbUtil; import org.dependencytrack.model.Severity; import org.dependencytrack.util.VulnerabilityUtil; @@ -42,6 +43,7 @@ public String getSchemaVersion() { public void executeUpgrade(final AlpineQueryManager qm, final Connection connection) throws Exception { dropCweTable(connection); computeVulnerabilitySeverities(connection); + extendPurlColumnLengths(connection); } private static void dropCweTable(final Connection connection) throws Exception { @@ -59,10 +61,17 @@ private static void dropCweTable(final Connection connection) throws Exception { ALTER TABLE "VULNERABILITY" DROP CONSTRAINT IF EXISTS "VULNERABILITY_FK1" """); - LOGGER.info("Dropping index \"VULNERABILITY\".\"VULNERABILITY_CWE_IDX\""); - stmt.executeUpdate(""" + if (DbUtil.isH2()) { + LOGGER.info("Dropping index \"VULNERABILITY_CWE_IDX\""); + stmt.executeUpdate(""" + DROP INDEX IF EXISTS "VULNERABILITY_CWE_IDX" + """); + } else { + LOGGER.info("Dropping index \"VULNERABILITY\".\"VULNERABILITY_CWE_IDX\""); + stmt.executeUpdate(""" DROP INDEX IF EXISTS "VULNERABILITY"."VULNERABILITY_CWE_IDX" """); + } LOGGER.info("Dropping column \"VULNERABILITY\".\"CWE\""); stmt.executeUpdate(""" @@ -139,4 +148,47 @@ private static void computeVulnerabilitySeverities(final Connection connection) } } + private static void extendPurlColumnLengths(final Connection connection) throws Exception { + LOGGER.info("Extending length of PURL and PURLCOORDINATES columns from 255 to 786"); + if (DbUtil.isH2() || DbUtil.isPostgreSQL()) { + try (final Statement statement = connection.createStatement()) { + statement.addBatch(""" + ALTER TABLE "COMPONENT" ALTER COLUMN "PURL" SET DATA TYPE VARCHAR(786)"""); + statement.addBatch(""" + ALTER TABLE "COMPONENT" ALTER COLUMN "PURLCOORDINATES" SET DATA TYPE VARCHAR(786)"""); + statement.addBatch(""" + ALTER TABLE "COMPONENTANALYSISCACHE" ALTER COLUMN "TARGET" SET DATA TYPE VARCHAR(786)"""); + statement.addBatch(""" + ALTER TABLE "PROJECT" ALTER COLUMN "PURL" SET DATA TYPE VARCHAR(786)"""); + statement.executeBatch(); + } + } else if (DbUtil.isMssql()) { + try (final Statement statement = connection.createStatement()) { + statement.addBatch(""" + ALTER TABLE "COMPONENT" ALTER COLUMN "PURL" VARCHAR(786) NULL"""); + statement.addBatch(""" + ALTER TABLE "COMPONENT" ALTER COLUMN "PURLCOORDINATES" VARCHAR(786) NULL"""); + statement.addBatch(""" + ALTER TABLE "COMPONENTANALYSISCACHE" ALTER COLUMN "TARGET" VARCHAR(786) NOT NULL"""); + statement.addBatch(""" + ALTER TABLE "PROJECT" ALTER COLUMN "PURL" VARCHAR(786) NULL"""); + statement.executeBatch(); + } + } else if (DbUtil.isMysql()) { + try (final Statement statement = connection.createStatement()) { + statement.addBatch(""" + ALTER TABLE "COMPONENT" MODIFY COLUMN "PURL" VARCHAR(786)"""); + statement.addBatch(""" + ALTER TABLE "COMPONENT" MODIFY COLUMN "PURLCOORDINATES" VARCHAR(786)"""); + statement.addBatch(""" + ALTER TABLE "COMPONENTANALYSISCACHE" MODIFY COLUMN "TARGET" VARCHAR(786)"""); + statement.addBatch(""" + ALTER TABLE "PROJECT" MODIFY COLUMN "PURL" VARCHAR(786)"""); + statement.executeBatch(); + } + } else { + throw new IllegalStateException("Unrecognized database type"); + } + } + }