Repository: Apicurio/apicurio-registry (language: python)

Issue:
Restore storage test



Discussion / hints:

Fix patch:
diff --git a/app/src/main/java/io/apicurio/registry/storage/impl/sql/AbstractSqlRegistryStorage.java b/app/src/main/java/io/apicurio/registry/storage/impl/sql/AbstractSqlRegistryStorage.java
index de31495217..93401300a0 100644
--- a/app/src/main/java/io/apicurio/registry/storage/impl/sql/AbstractSqlRegistryStorage.java
+++ b/app/src/main/java/io/apicurio/registry/storage/impl/sql/AbstractSqlRegistryStorage.java
@@ -1681,6 +1681,9 @@ public VersionSearchResultsDto searchVersions(Set<SearchFilter> filters, OrderBy
                 case globalId:
                     orderByQuery.append(" ORDER BY v.globalId");
                     break;
+                case groupId:
+                    orderByQuery.append(" ORDER BY v.groupId");
+                    break;
                 case version:
                     orderByQuery.append(" ORDER BY v.version");
                     break;
@@ -2686,6 +2689,8 @@ public void deleteAllUserData() {
 
             handle.createUpdate(sqlStatements.deleteAllVersionComments()).execute();
 
+            handle.createUpdate(sqlStatements.deleteAllBranchVersions()).execute();
+
             handle.createUpdate(sqlStatements.deleteAllBranches()).execute();
 
             handle.createUpdate(sqlStatements.deleteAllVersions()).execute();
@@ -2849,6 +2854,7 @@ public GroupSearchResultsDto searchGroups(Set<SearchFilter> filters, OrderBy ord
                         where.append(" AND l.groupId = g.groupId)");
                         break;
                     default:
+
                         break;
                 }
                 where.append(")");
@@ -3689,6 +3695,12 @@ public void deleteBranch(GA ga, BranchId branchId) {
         }
 
         handles.withHandleNoException(handle -> {
+            // First delete all branch versions (only needed for "mssql" due to cascade limitations there).
+            if (isMssql()) {
+                handle.createUpdate(sqlStatements.deleteBranchVersions()).bind(0, ga.getRawGroupId())
+                        .bind(1, ga.getRawArtifactId()).bind(2, branchId.getRawBranchId()).execute();
+            }
+
             var affected = handle.createUpdate(sqlStatements.deleteBranch()).bind(0, ga.getRawGroupId())
                     .bind(1, ga.getRawArtifactId()).bind(2, branchId.getRawBranchId()).execute();
 
diff --git a/app/src/main/java/io/apicurio/registry/storage/impl/sql/CommonSqlStatements.java b/app/src/main/java/io/apicurio/registry/storage/impl/sql/CommonSqlStatements.java
index 28546af1c7..7a3ecdb7e7 100644
--- a/app/src/main/java/io/apicurio/registry/storage/impl/sql/CommonSqlStatements.java
+++ b/app/src/main/java/io/apicurio/registry/storage/impl/sql/CommonSqlStatements.java
@@ -1161,6 +1161,11 @@ public String deleteBranch() {
         return "DELETE FROM branches WHERE groupId = ? AND artifactId = ? AND branchId = ?";
     }
 
+    @Override
+    public String deleteAllBranchVersions() {
+        return "DELETE FROM branch_versions";
+    }
+
     @Override
     public String deleteAllBranches() {
         return "DELETE FROM branches";
@@ -1198,17 +1203,11 @@ public String deleteGroupRules() {
 
     @Override
     public String createOutboxEvent() {
-        return """
-                INSERT INTO outbox (id, aggregatetype, aggregateid, type, payload) \
-                VALUES (?, ?, ?, ?, ?::jsonb)\
-                """;
+        return "INSERT INTO outbox (id, aggregatetype, aggregateid, type, payload) VALUES (?, ?, ?, ?, ?)";
     }
 
     @Override
     public String deleteOutboxEvent() {
-        return """
-                DELETE FROM outbox o \
-                WHERE o.id= ?\
-                """;
+        return "DELETE FROM outbox WHERE id = ?";
     }
 }
diff --git a/app/src/main/java/io/apicurio/registry/storage/impl/sql/PostgreSQLSqlStatements.java b/app/src/main/java/io/apicurio/registry/storage/impl/sql/PostgreSQLSqlStatements.java
index 648671f95d..f9827f2fd6 100644
--- a/app/src/main/java/io/apicurio/registry/storage/impl/sql/PostgreSQLSqlStatements.java
+++ b/app/src/main/java/io/apicurio/registry/storage/impl/sql/PostgreSQLSqlStatements.java
@@ -78,4 +78,13 @@ public String createDataSnapshot() {
     public String restoreFromSnapshot() {
         throw new IllegalStateException("Restoring from snapshot is not supported for Postgresql storage");
     }
+
+    @Override
+    public String createOutboxEvent() {
+        return """
+                INSERT INTO outbox (id, aggregatetype, aggregateid, type, payload)
+                VALUES (?, ?, ?, ?, ?::jsonb)
+                """;
+    }
+
 }
\ No newline at end of file
diff --git a/app/src/main/java/io/apicurio/registry/storage/impl/sql/SQLServerSqlStatements.java b/app/src/main/java/io/apicurio/registry/storage/impl/sql/SQLServerSqlStatements.java
index 3f2e0bd6f6..d1e39213cb 100644
--- a/app/src/main/java/io/apicurio/registry/storage/impl/sql/SQLServerSqlStatements.java
+++ b/app/src/main/java/io/apicurio/registry/storage/impl/sql/SQLServerSqlStatements.java
@@ -25,7 +25,8 @@ public String dbType() {
      */
     @Override
     public boolean isPrimaryKeyViolation(Exception error) {
-        return error.getMessage().contains("Violation of PRIMARY KEY constraint");
+        return error.getMessage().contains("Violation of PRIMARY KEY constraint")
+                || error.getMessage().contains("Violation of UNIQUE KEY constraint");
     }
 
     /**
@@ -52,7 +53,7 @@ public String upsertBranch() {
                 ON (target.groupId = source.groupId AND target.artifactId = source.artifactId AND target.branchId = source.branchId)
                 WHEN NOT MATCHED THEN
                 INSERT (groupId, artifactId, branchId, description, systemDefined, owner, createdOn, modifiedBy, modifiedOn)
-                VALUES (source.groupId, source.artifactId, source.branchId, source.description, source.systemDefined, source.owner, source.createdOn, source.modifiedBy, source.modifiedOn)
+                VALUES (source.groupId, source.artifactId, source.branchId, source.description, source.systemDefined, source.owner, source.createdOn, source.modifiedBy, source.modifiedOn);
                 """;
     }
 
@@ -70,7 +71,7 @@ public String getNextSequenceValue() {
                 WHEN NOT MATCHED THEN
                 INSERT (seqName, seqValue)
                 VALUES (source.seqName, 1)
-                OUTPUT INSERTED.seqValue
+                OUTPUT INSERTED.seqValue;
                 """;
     }
 
@@ -88,7 +89,7 @@ public String resetSequenceValue() {
                 WHEN NOT MATCHED THEN
                 INSERT (seqName, seqValue)
                 VALUES (source.seqName, source.seqValue)
-                OUTPUT INSERTED.seqValue
+                OUTPUT INSERTED.seqValue;
                 """;
     }
 
@@ -111,17 +112,17 @@ public String selectGroups() {
 
     @Override
     public String selectBranchTip() {
-        return "SELECT ab.groupId, ab.artifactId, ab.version FROM artifact_branches ab "
-                + "WHERE ab.groupId = ? AND ab.artifactId = ? AND ab.branchId = ? "
-                + "ORDER BY ab.branchOrder DESC OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY";
+        return "SELECT bv.groupId, bv.artifactId, bv.version FROM branch_versions bv "
+                + "WHERE bv.groupId = ? AND bv.artifactId = ? AND bv.branchId = ? "
+                + "ORDER BY bv.branchOrder DESC OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY";
     }
 
     @Override
     public String selectBranchTipFilteredByState() {
-        return "SELECT ab.groupId, ab.artifactId, ab.version FROM artifact_branches ab "
-                + "JOIN versions v ON ab.groupId = v.groupId AND ab.artifactId = v.artifactId AND ab.version = v.version "
-                + "WHERE ab.groupId = ? AND ab.artifactId = ? AND ab.branchId = ? AND v.state IN (?) "
-                + "ORDER BY ab.branchOrder DESC OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY";
+        return "SELECT bv.groupId, bv.artifactId, bv.version FROM branch_versions bv "
+                + "JOIN versions v ON bv.groupId = v.groupId AND bv.artifactId = v.artifactId AND bv.version = v.version "
+                + "WHERE bv.groupId = ? AND bv.artifactId = ? AND bv.branchId = ? AND v.state IN (?) "
+                + "ORDER BY bv.branchOrder DESC OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY";
     }
 
     @Override
diff --git a/app/src/main/java/io/apicurio/registry/storage/impl/sql/SqlStatements.java b/app/src/main/java/io/apicurio/registry/storage/impl/sql/SqlStatements.java
index f329a51d75..74ac6c65ed 100644
--- a/app/src/main/java/io/apicurio/registry/storage/impl/sql/SqlStatements.java
+++ b/app/src/main/java/io/apicurio/registry/storage/impl/sql/SqlStatements.java
@@ -634,6 +634,8 @@ public interface SqlStatements {
 
     public String deleteBranch();
 
+    public String deleteAllBranchVersions();
+
     public String deleteAllBranches();
 
     public String deleteVersionFromBranch();
diff --git a/app/src/main/resources/io/apicurio/registry/storage/impl/sql/mssql.ddl b/app/src/main/resources/io/apicurio/registry/storage/impl/sql/mssql.ddl
index b9a312f593..b1d9a95013 100644
--- a/app/src/main/resources/io/apicurio/registry/storage/impl/sql/mssql.ddl
+++ b/app/src/main/resources/io/apicurio/registry/storage/impl/sql/mssql.ddl
@@ -97,11 +97,11 @@ ALTER TABLE branches ADD CONSTRAINT FK_branches_1 FOREIGN KEY (groupId, artifact
 
 CREATE TABLE branch_versions (groupId NVARCHAR(512) NOT NULL, artifactId NVARCHAR(512) NOT NULL, branchId NVARCHAR(256) NOT NULL, branchOrder INT NOT NULL, version NVARCHAR(256) NOT NULL);
 ALTER TABLE branch_versions ADD PRIMARY KEY (groupId, artifactId, branchId, version);
-ALTER TABLE branch_versions ADD CONSTRAINT FK_branch_versions_1 FOREIGN KEY (groupId, artifactId, branchId) REFERENCES branches(groupId, artifactId, branchId) ON DELETE CASCADE;
+ALTER TABLE branch_versions ADD CONSTRAINT FK_branch_versions_1 FOREIGN KEY (groupId, artifactId, branchId) REFERENCES branches(groupId, artifactId, branchId);
 ALTER TABLE branch_versions ADD CONSTRAINT FK_branch_versions_2 FOREIGN KEY (groupId, artifactId, version) REFERENCES versions(groupId, artifactId, version) ON DELETE CASCADE;
 CREATE INDEX IDX_branch_versions_1 ON branch_versions(groupId, artifactId, branchId, branchOrder);
 CREATE INDEX IDX_branch_versions_2 ON branch_versions(branchId);
 CREATE INDEX IDX_branch_versions_3 ON branch_versions(branchOrder);
 
-CREATE TABLE outbox (id VARCHAR(128) NOT NULL, aggregatetype VARCHAR(255) NOT NULL, aggregateid VARCHAR(255) NOT NULL, type VARCHAR(255) NOT NULL, payload JSONB NOT NULL);
+CREATE TABLE outbox (id VARCHAR(128) NOT NULL, aggregatetype VARCHAR(255) NOT NULL, aggregateid VARCHAR(255) NOT NULL, type VARCHAR(255) NOT NULL, payload TEXT NOT NULL);
 ALTER TABLE outbox ADD PRIMARY KEY (id);
diff --git a/app/src/main/resources/io/apicurio/registry/storage/impl/sql/upgrades/101/h2.upgrade.ddl b/app/src/main/resources/io/apicurio/registry/storage/impl/sql/upgrades/101/h2.upgrade.ddl
index a80c75332e..55abd6725c 100644
--- a/app/src/main/resources/io/apicurio/registry/storage/impl/sql/upgrades/101/h2.upgrade.ddl
+++ b/app/src/main/resources/io/apicurio/registry/storage/impl/sql/upgrades/101/h2.upgrade.ddl
@@ -1,4 +1,6 @@
 -- *********************************************************************
 -- DDL for the Apicurio Registry - Database: H2
 -- Upgrade Script from 100 to 101
--- *********************************************************************
\ No newline at end of file
+-- *********************************************************************
+
+UPDATE apicurio SET propValue = 101 WHERE propName = 'db_version';
diff --git a/app/src/main/resources/io/apicurio/registry/storage/impl/sql/upgrades/101/mssql.upgrade.ddl b/app/src/main/resources/io/apicurio/registry/storage/impl/sql/upgrades/101/mssql.upgrade.ddl
index 462f77ee3b..45544737ad 100644
--- a/app/src/main/resources/io/apicurio/registry/storage/impl/sql/upgrades/101/mssql.upgrade.ddl
+++ b/app/src/main/resources/io/apicurio/registry/storage/impl/sql/upgrades/101/mssql.upgrade.ddl
@@ -3,5 +3,7 @@
 -- Upgrade Script from 100 to 101
 -- *********************************************************************
 
-CREATE TABLE outbox (id VARCHAR(128) NOT NULL, aggregatetype VARCHAR(255) NOT NULL, aggregateid VARCHAR(255) NOT NULL, type VARCHAR(255) NOT NULL, payload JSONB NOT NULL);
-ALTER TABLE outbox ADD PRIMARY KEY (id);
\ No newline at end of file
+UPDATE apicurio SET propValue = 101 WHERE propName = 'db_version';
+
+CREATE TABLE outbox (id VARCHAR(128) NOT NULL, aggregatetype VARCHAR(255) NOT NULL, aggregateid VARCHAR(255) NOT NULL, type VARCHAR(255) NOT NULL, payload TEXT NOT NULL);
+ALTER TABLE outbox ADD PRIMARY KEY (id);
diff --git a/app/src/main/resources/io/apicurio/registry/storage/impl/sql/upgrades/101/postgresql.upgrade.ddl b/app/src/main/resources/io/apicurio/registry/storage/impl/sql/upgrades/101/postgresql.upgrade.ddl
index 9b4e1c929a..2903602e6b 100644
--- a/app/src/main/resources/io/apicurio/registry/storage/impl/sql/upgrades/101/postgresql.upgrade.ddl
+++ b/app/src/main/resources/io/apicurio/registry/storage/impl/sql/upgrades/101/postgresql.upgrade.ddl
@@ -3,5 +3,7 @@
 -- Upgrade Script from 100 to 101
 -- *********************************************************************
 
+UPDATE apicurio SET propValue = 101 WHERE propName = 'db_version';
+
 CREATE TABLE outbox (id VARCHAR(128) NOT NULL, aggregatetype VARCHAR(255) NOT NULL, aggregateid VARCHAR(255) NOT NULL, type VARCHAR(255) NOT NULL, payload JSONB NOT NULL);
-ALTER TABLE outbox ADD PRIMARY KEY (id);
\ No newline at end of file
+ALTER TABLE outbox ADD PRIMARY KEY (id);


Test patch:
diff --git a/app/src/test/java/io/apicurio/registry/noprofile/storage/AbstractRegistryStorageTest.java b/app/src/test/java/io/apicurio/registry/noprofile/storage/AbstractRegistryStorageTest.java
index 7451b29ef7..b08a9ae0ab 100644
--- a/app/src/test/java/io/apicurio/registry/noprofile/storage/AbstractRegistryStorageTest.java
+++ b/app/src/test/java/io/apicurio/registry/noprofile/storage/AbstractRegistryStorageTest.java
@@ -1,10 +1,37 @@
 package io.apicurio.registry.noprofile.storage;
 
+import io.apicurio.common.apps.config.DynamicConfigPropertyDto;
 import io.apicurio.registry.AbstractResourceTestBase;
+import io.apicurio.registry.content.ContentHandle;
+import io.apicurio.registry.model.BranchId;
+import io.apicurio.registry.model.GA;
+import io.apicurio.registry.model.GAV;
 import io.apicurio.registry.storage.RegistryStorage;
+import io.apicurio.registry.storage.RegistryStorage.RetrievalBehavior;
+import io.apicurio.registry.storage.dto.*;
+import io.apicurio.registry.storage.error.ArtifactAlreadyExistsException;
+import io.apicurio.registry.storage.error.ArtifactNotFoundException;
+import io.apicurio.registry.storage.error.RuleAlreadyExistsException;
+import io.apicurio.registry.storage.error.RuleNotFoundException;
+import io.apicurio.registry.storage.error.VersionNotFoundException;
+import io.apicurio.registry.types.ArtifactType;
+import io.apicurio.registry.types.ContentTypes;
+import io.apicurio.registry.types.RuleType;
+import io.apicurio.registry.types.VersionState;
+import io.apicurio.registry.utils.impexp.EntityType;
+import io.apicurio.registry.utils.tests.TestUtils;
 import jakarta.inject.Inject;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
 import org.slf4j.Logger;
 
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
 public abstract class AbstractRegistryStorageTest extends AbstractResourceTestBase {
 
     private static final String GROUP_ID = AbstractRegistryStorageTest.class.getSimpleName();
@@ -26,1100 +53,1259 @@ public abstract class AbstractRegistryStorageTest extends AbstractResourceTestBa
      * Gets the artifactStore to use. Subclasses must provide this.
      */
     protected abstract RegistryStorage storage();
-    //
-    // @Test
-    // public void testGetArtifactIds() throws Exception {
-    //
-    // int size = storage().getArtifactIds(null).size();
-    //
-    // String artifactIdPrefix = "testGetArtifactIds-";
-    // for (int idx = 1; idx <= 10; idx++) {
-    // String artifactId = artifactIdPrefix + idx;
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    // ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dto);
-    // Assertions.assertEquals(GROUP_ID, dto.getGroupId());
-    // Assertions.assertEquals(artifactId, dto.getArtifactId());
-    //
-    // //Verify group metadata is also created
-    // GroupMetaDataDto groupMetaDataDto = storage().getGroupMetaData(GROUP_ID);
-    // Assertions.assertNotNull(groupMetaDataDto);
-    // Assertions.assertEquals(GROUP_ID, groupMetaDataDto.getGroupId());
-    // }
-    //
-    // int newsize = storage().getArtifactIds(null).size();
-    // int newids = newsize - size;
-    // Assertions.assertEquals(10, newids);
-    // }
-    //
-    // @Test
-    // public void testCreateArtifact() throws Exception {
-    // String artifactId = "testCreateArtifact-1";
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    // ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dto);
-    // Assertions.assertEquals(GROUP_ID, dto.getGroupId());
-    // Assertions.assertEquals(artifactId, dto.getArtifactId());
-    // Assertions.assertEquals("Empty API", dto.getName());
-    // Assertions.assertEquals("An example API design using OpenAPI.", dto.getDescription());
-    // Assertions.assertNull(dto.getLabels());
-    // Assertions.assertEquals("1", dto.getVersion());
-    //
-    // StoredArtifactVersionDto storedArtifact = storage().getArtifactVersionContent(GROUP_ID, artifactId,
-    // dto.getVersion());
-    // Assertions.assertNotNull(storedArtifact);
-    // Assertions.assertEquals(OPENAPI_CONTENT, storedArtifact.getContent().content());
-    // Assertions.assertEquals(dto.getGlobalId(), storedArtifact.getGlobalId());
-    // Assertions.assertEquals(dto.getVersion(), storedArtifact.getVersion());
-    //
-    // ArtifactMetaDataDto amdDto = storage().getArtifactMetaData(GROUP_ID, artifactId);
-    // Assertions.assertNotNull(amdDto);
-    // Assertions.assertEquals("Empty API", amdDto.getName());
-    // Assertions.assertEquals("An example API design using OpenAPI.", amdDto.getDescription());
-    // Assertions.assertNull(amdDto.getLabels());
-    //
-    // ArtifactVersionMetaDataDto versionMetaDataDto = storage().getArtifactVersionMetaData(GROUP_ID,
-    // artifactId, "1");
-    // Assertions.assertNotNull(versionMetaDataDto);
-    // Assertions.assertEquals(dto.getGlobalId(), versionMetaDataDto.getGlobalId());
-    // Assertions.assertEquals("Empty API", versionMetaDataDto.getName());
-    // Assertions.assertEquals("An example API design using OpenAPI.", versionMetaDataDto.getDescription());
-    // Assertions.assertEquals(VersionState.ENABLED, versionMetaDataDto.getState());
-    // Assertions.assertEquals("1", versionMetaDataDto.getVersion());
-    //
-    // StoredArtifactVersionDto storedVersion = storage().getArtifactVersionContent(dto.getGlobalId());
-    // Assertions.assertNotNull(storedVersion);
-    // Assertions.assertEquals(OPENAPI_CONTENT, storedVersion.getContent().content());
-    // Assertions.assertEquals(dto.getGlobalId(), storedVersion.getGlobalId());
-    // Assertions.assertEquals(dto.getVersion(), storedVersion.getVersion());
-    //
-    // storedVersion = storage().getArtifactVersionContent(GROUP_ID, artifactId, "1");
-    // Assertions.assertNotNull(storedVersion);
-    // Assertions.assertEquals(OPENAPI_CONTENT, storedVersion.getContent().content());
-    // Assertions.assertEquals(dto.getGlobalId(), storedVersion.getGlobalId());
-    // Assertions.assertEquals(dto.getVersion(), storedVersion.getVersion());
-    //
-    // List<String> versions = storage().getArtifactVersions(GROUP_ID, artifactId);
-    // Assertions.assertNotNull(versions);
-    // Assertions.assertEquals("1", versions.iterator().next());
-    // }
-    //
-    // @Test
-    // public void testCreateArtifactWithMetaData() throws Exception {
-    // String artifactId = "testCreateArtifactWithMetaData-1";
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    // EditableArtifactMetaDataDto metaData = new EditableArtifactMetaDataDto(
-    // "NAME", "DESCRIPTION", null, Collections.singletonMap("KEY", "VALUE")
-    // );
-    // ArtifactVersionMetaDataDto dto = storage().createArtifactWithMetadata(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, content, metaData, null);
-    // Assertions.assertNotNull(dto);
-    // Assertions.assertEquals(GROUP_ID, dto.getGroupId());
-    // Assertions.assertEquals(artifactId, dto.getArtifactId());
-    // Assertions.assertEquals("NAME", dto.getName());
-    // Assertions.assertEquals("DESCRIPTION", dto.getDescription());
-    // Assertions.assertNotNull(dto.getLabels());
-    // Assertions.assertEquals(metaData.getLabels(), dto.getLabels());
-    // Assertions.assertEquals("1", dto.getVersion());
-    //
-    // StoredArtifactVersionDto storedArtifact = storage().getArtifactVersionContent(GROUP_ID, artifactId,
-    // "1");
-    // Assertions.assertNotNull(storedArtifact);
-    // Assertions.assertEquals(OPENAPI_CONTENT, storedArtifact.getContent().content());
-    // Assertions.assertEquals(dto.getGlobalId(), storedArtifact.getGlobalId());
-    // Assertions.assertEquals(dto.getVersion(), storedArtifact.getVersion());
-    //
-    // ArtifactMetaDataDto amdDto = storage().getArtifactMetaData(GROUP_ID, artifactId);
-    // Assertions.assertNotNull(amdDto);
-    // Assertions.assertEquals("NAME", amdDto.getName());
-    // Assertions.assertEquals("DESCRIPTION", amdDto.getDescription());
-    // Assertions.assertEquals(metaData.getLabels(), amdDto.getLabels());
-    // }
-    //
-    // @Test
-    // public void testCreateArtifactWithLargeMetaData() throws Exception {
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    //
-    // // Test creating an artifact with meta-data that is too large for the DB
-    // String artifactId = "testCreateArtifactWithLargeMetaData";
-    // EditableArtifactMetaDataDto metaData = new EditableArtifactMetaDataDto();
-    // metaData.setName(generateString(600));
-    // metaData.setDescription(generateString(2000));
-    // metaData.setLabels(new HashMap<>());
-    // metaData.getLabels().put("key-" + generateString(300), "value-" + generateString(2000));
-    // ArtifactVersionMetaDataDto dto = storage().createArtifactWithMetadata(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, content, metaData, null);
-    //
-    // dto = storage().getArtifactVersionMetaData(dto.getGlobalId());
-    // Assertions.assertNotNull(dto);
-    // Assertions.assertEquals(GROUP_ID, dto.getGroupId());
-    // Assertions.assertEquals(artifactId, dto.getArtifactId());
-    // Assertions.assertEquals(512, dto.getName().length());
-    // Assertions.assertEquals(1024, dto.getDescription().length());
-    // Assertions.assertTrue(dto.getDescription().endsWith("..."));
-    // Assertions.assertNotNull(dto.getLabels());
-    // Assertions.assertEquals(1, dto.getLabels().size());
-    // }
-    //
-    // @Test
-    // public void testCreateDuplicateArtifact() throws Exception {
-    // String artifactId = "testCreateDuplicateArtifact-1";
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    // ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dto);
-    //
-    // // Should throw error for duplicate artifact.
-    // Assertions.assertThrows(ArtifactAlreadyExistsException.class, () -> {
-    // storage().createArtifact(GROUP_ID, artifactId, null, ArtifactType.OPENAPI, content, null);
-    // });
-    // }
-    //
-    // @Test
-    // public void testArtifactNotFound() throws Exception {
-    // String artifactId = "testArtifactNotFound-1";
-    //
-    // Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
-    // storage().getArtifactVersionContent(GROUP_ID, artifactId, "1");
-    // });
-    //
-    // Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
-    // storage().getArtifactMetaData(GROUP_ID, artifactId);
-    // });
-    //
-    // Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
-    // storage().getArtifactVersionContent(GROUP_ID, artifactId, "1");
-    // });
-    //
-    // Assertions.assertThrows(VersionNotFoundException.class, () -> {
-    // storage().getArtifactVersionMetaData(GROUP_ID, artifactId, "1");
-    // });
-    // }
-    //
-    // @Test
-    // public void testCreateArtifactVersion() throws Exception {
-    // String artifactId = "testCreateArtifactVersion-1";
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    // ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dto);
-    // Assertions.assertEquals(GROUP_ID, dto.getGroupId());
-    // Assertions.assertEquals(artifactId, dto.getArtifactId());
-    //
-    // List<String> versions = storage().getArtifactVersions(GROUP_ID, artifactId);
-    // Assertions.assertNotNull(versions);
-    // Assertions.assertFalse(versions.isEmpty());
-    // Assertions.assertEquals(1, versions.size());
-    //
-    // ContentHandle contentv2 = ContentHandle.create(OPENAPI_CONTENT_V2);
-    // ArtifactVersionMetaDataDto dtov2 = storage().createArtifactVersion(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, contentv2, null);
-    // Assertions.assertNotNull(dtov2);
-    // Assertions.assertEquals(GROUP_ID, dtov2.getGroupId());
-    // Assertions.assertEquals(artifactId, dtov2.getArtifactId());
-    // Assertions.assertEquals("2", dtov2.getVersion());
-    //
-    // versions = storage().getArtifactVersions(GROUP_ID, artifactId);
-    // Assertions.assertNotNull(versions);
-    // Assertions.assertFalse(versions.isEmpty());
-    // Assertions.assertEquals(2, versions.size());
-    // }
-    //
-    // @Test
-    // public void testGetArtifactVersions() throws Exception {
-    // String artifactId = "testGetArtifactVersions";
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    // ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dto);
-    // Assertions.assertEquals(GROUP_ID, dto.getGroupId());
-    // Assertions.assertEquals(artifactId, dto.getArtifactId());
-    //
-    // StoredArtifactVersionDto storedArtifact = storage().getArtifactVersionContent(GROUP_ID, artifactId,
-    // "1");
-    // verifyArtifact(storedArtifact, OPENAPI_CONTENT, dto);
-    //
-    // storedArtifact = storage().getArtifactVersionContent(GROUP_ID, artifactId, "1");
-    // verifyArtifact(storedArtifact, OPENAPI_CONTENT, dto);
-    //
-    // storedArtifact = storage().getArtifactVersionContent(dto.getGlobalId());
-    // verifyArtifact(storedArtifact, OPENAPI_CONTENT, dto);
-    //
-    // ArtifactVersionMetaDataDto dtov1 = storage().getArtifactVersionMetaData(dto.getGlobalId());
-    // verifyArtifactMetadata(dtov1, dto);
-    //
-    // List<String> versions = storage().getArtifactVersions(GROUP_ID, artifactId);
-    // Assertions.assertNotNull(versions);
-    // Assertions.assertFalse(versions.isEmpty());
-    // Assertions.assertEquals(1, versions.size());
-    //
-    // ContentHandle contentv2 = ContentHandle.create(OPENAPI_CONTENT_V2);
-    // ArtifactVersionMetaDataDto dtov2 = storage().createArtifactVersion(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, contentv2, null);
-    // Assertions.assertNotNull(dtov2);
-    // Assertions.assertEquals(GROUP_ID, dtov2.getGroupId());
-    // Assertions.assertEquals(artifactId, dtov2.getArtifactId());
-    // Assertions.assertEquals("2", dtov2.getVersion());
-    //
-    // versions = storage().getArtifactVersions(GROUP_ID, artifactId);
-    // Assertions.assertNotNull(versions);
-    // Assertions.assertFalse(versions.isEmpty());
-    // Assertions.assertEquals(2, versions.size());
-    //
-    // //verify version 2
-    //
-    // storedArtifact = storage().getArtifactVersionContent(GROUP_ID, artifactId, "2");
-    // verifyArtifact(storedArtifact, OPENAPI_CONTENT_V2, dtov2);
-    //
-    // storedArtifact = storage().getArtifactVersionContent(dtov2.getGlobalId());
-    // verifyArtifact(storedArtifact, OPENAPI_CONTENT_V2, dtov2);
-    //
-    // ArtifactVersionMetaDataDto dtov2Stored = storage().getArtifactVersionMetaData(dtov2.getGlobalId());
-    // verifyArtifactMetadata(dtov2Stored, dtov2);
-    //
-    // // verify version 1 again
-    //
-    // storedArtifact = storage().getArtifactVersionContent(GROUP_ID, artifactId, "1");
-    // verifyArtifact(storedArtifact, OPENAPI_CONTENT, dto);
-    //
-    // storedArtifact = storage().getArtifactVersionContent(dto.getGlobalId());
-    // verifyArtifact(storedArtifact, OPENAPI_CONTENT, dto);
-    //
-    // dtov1 = storage().getArtifactVersionMetaData(dto.getGlobalId());
-    // verifyArtifactMetadata(dtov1, dto);
-    //
-    // }
-    //
-    // private void verifyArtifact(StoredArtifactVersionDto storedArtifact, String content,
-    // ArtifactVersionMetaDataDto expectedMetadata) {
-    // Assertions.assertNotNull(storedArtifact);
-    // Assertions.assertEquals(content, storedArtifact.getContent().content());
-    // Assertions.assertEquals(expectedMetadata.getGlobalId(), storedArtifact.getGlobalId());
-    // Assertions.assertEquals(expectedMetadata.getVersion(), storedArtifact.getVersion());
-    // }
-    //
-    // private void verifyArtifactMetadata(ArtifactVersionMetaDataDto actualMetadata,
-    // ArtifactVersionMetaDataDto expectedMetadata) {
-    // Assertions.assertNotNull(actualMetadata);
-    // Assertions.assertNotNull(expectedMetadata);
-    // Assertions.assertEquals(expectedMetadata.getName(), actualMetadata.getName());
-    // Assertions.assertEquals(expectedMetadata.getDescription(), actualMetadata.getDescription());
-    // }
-    //
-    // @Test
-    // public void testCreateArtifactVersionWithMetaData() throws Exception {
-    // String artifactId = "testCreateArtifactVersionWithMetaData-1";
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    // ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dto);
-    // Assertions.assertEquals(GROUP_ID, dto.getGroupId());
-    // Assertions.assertEquals(artifactId, dto.getArtifactId());
-    //
-    // List<String> versions = storage().getArtifactVersions(GROUP_ID, artifactId);
-    // Assertions.assertNotNull(versions);
-    // Assertions.assertFalse(versions.isEmpty());
-    // Assertions.assertEquals(1, versions.size());
-    //
-    // ContentHandle contentv2 = ContentHandle.create(OPENAPI_CONTENT_V2);
-    // EditableVersionMetaDataDto metaData = new EditableVersionMetaDataDto("NAME", "DESC", null,
-    // Collections.singletonMap("K", "V"));
-    // ArtifactVersionMetaDataDto dtov2 = storage().createArtifactVersionWithMetadata(GROUP_ID, artifactId,
-    // null, ArtifactType.OPENAPI,
-    // contentv2, metaData, null);
-    // Assertions.assertNotNull(dtov2);
-    // Assertions.assertEquals(GROUP_ID, dtov2.getGroupId());
-    // Assertions.assertEquals(artifactId, dtov2.getArtifactId());
-    // Assertions.assertEquals("2", dtov2.getVersion());
-    // Assertions.assertEquals("NAME", dtov2.getName());
-    // Assertions.assertEquals("DESC", dtov2.getDescription());
-    // Assertions.assertEquals(metaData.getLabels(), dtov2.getLabels());
-    //
-    // versions = storage().getArtifactVersions(GROUP_ID, artifactId);
-    // Assertions.assertNotNull(versions);
-    // Assertions.assertFalse(versions.isEmpty());
-    // Assertions.assertEquals(2, versions.size());
-    //
-    // ArtifactVersionMetaDataDto vmd = storage().getArtifactVersionMetaData(GROUP_ID, artifactId, "2");
-    // Assertions.assertNotNull(vmd);
-    // Assertions.assertEquals("NAME", vmd.getName());
-    // Assertions.assertEquals("DESC", vmd.getDescription());
-    // }
-    //
-    // @Test
-    // public void testGetArtifactMetaDataByGlobalId() throws Exception {
-    // String artifactId = "testGetArtifactMetaDataByGlobalId-1";
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    // ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dto);
-    // Assertions.assertEquals(GROUP_ID, dto.getGroupId());
-    // Assertions.assertEquals(artifactId, dto.getArtifactId());
-    // Assertions.assertEquals("Empty API", dto.getName());
-    // Assertions.assertEquals("An example API design using OpenAPI.", dto.getDescription());
-    // Assertions.assertNull(dto.getLabels());
-    // Assertions.assertEquals("1", dto.getVersion());
-    //
-    // long globalId = dto.getGlobalId();
-    //
-    // dto = storage().getArtifactVersionMetaData(globalId);
-    // Assertions.assertNotNull(dto);
-    // Assertions.assertEquals(GROUP_ID, dto.getGroupId());
-    // Assertions.assertEquals(artifactId, dto.getArtifactId());
-    // Assertions.assertEquals("Empty API", dto.getName());
-    // Assertions.assertEquals("An example API design using OpenAPI.", dto.getDescription());
-    // Assertions.assertNull(dto.getLabels());
-    // Assertions.assertEquals("1", dto.getVersion());
-    // }
-    //
-    // @Test
-    // public void testUpdateArtifactMetaData() throws Exception {
-    // String artifactId = "testUpdateArtifactMetaData-1";
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    // ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dto);
-    // Assertions.assertEquals(GROUP_ID, dto.getGroupId());
-    // Assertions.assertEquals(artifactId, dto.getArtifactId());
-    // Assertions.assertEquals("Empty API", dto.getName());
-    // Assertions.assertEquals("An example API design using OpenAPI.", dto.getDescription());
-    // Assertions.assertNull(dto.getLabels());
-    // Assertions.assertEquals("1", dto.getVersion());
-    //
-    // String newName = "Updated Name";
-    // String newDescription = "Updated description.";
-    // Map<String, String> newLabels = new HashMap<>();
-    // newLabels.put("foo", "bar");
-    // newLabels.put("ting", "bin");
-    // EditableArtifactMetaDataDto emd = new EditableArtifactMetaDataDto(newName, newDescription, null,
-    // newLabels);
-    // storage().updateArtifactMetaData(GROUP_ID, artifactId, emd);
-    //
-    // ArtifactMetaDataDto metaData = storage().getArtifactMetaData(GROUP_ID, artifactId);
-    // Assertions.assertNotNull(metaData);
-    // Assertions.assertEquals(newName, metaData.getName());
-    // Assertions.assertEquals(newDescription, metaData.getDescription());
-    // }
-    //
-    // @Test
-    // public void testUpdateArtifactVersionState() throws Exception {
-    // String artifactId = "testUpdateArtifactVersionState-1";
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    // ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dto);
-    //
-    // ContentHandle contentv2 = ContentHandle.create(OPENAPI_CONTENT_V2);
-    // ArtifactVersionMetaDataDto dtov2 = storage().createArtifactVersion(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, contentv2, null);
-    // Assertions.assertNotNull(dtov2);
-    // Assertions.assertEquals(GROUP_ID, dtov2.getGroupId());
-    // Assertions.assertEquals(artifactId, dtov2.getArtifactId());
-    // Assertions.assertEquals("2", dtov2.getVersion());
-    //
-    // updateVersionState(GROUP_ID, artifactId, "1", VersionState.DISABLED);
-    // updateVersionState(GROUP_ID, artifactId, "2", VersionState.DEPRECATED);
-    //
-    // ArtifactVersionMetaDataDto v1 = storage().getArtifactVersionMetaData(GROUP_ID, artifactId, "1");
-    // ArtifactVersionMetaDataDto v2 = storage().getArtifactVersionMetaData(GROUP_ID, artifactId, "2");
-    // Assertions.assertNotNull(v1);
-    // Assertions.assertNotNull(v2);
-    // Assertions.assertEquals(VersionState.DISABLED, v1.getState());
-    // Assertions.assertEquals(VersionState.DEPRECATED, v2.getState());
-    // }
-    //
-    // @Test
-    // public void testUpdateArtifactVersionMetaData() throws Exception {
-    // String artifactId = "testUpdateArtifactVersionMetaData-1";
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    // ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dto);
-    // Assertions.assertEquals(GROUP_ID, dto.getGroupId());
-    // Assertions.assertEquals(artifactId, dto.getArtifactId());
-    // Assertions.assertEquals("Empty API", dto.getName());
-    // Assertions.assertEquals("An example API design using OpenAPI.", dto.getDescription());
-    // Assertions.assertNull(dto.getLabels());
-    // Assertions.assertEquals("1", dto.getVersion());
-    //
-    // String newName = "Updated Name";
-    // String newDescription = "Updated description.";
-    // Map<String, String> newLabels = new HashMap<>();
-    // newLabels.put("foo", "bar");
-    // newLabels.put("ting", "bin");
-    // EditableVersionMetaDataDto emd = new EditableVersionMetaDataDto(newName, newDescription, null,
-    // newLabels);
-    // storage().updateArtifactVersionMetaData(GROUP_ID, artifactId, "1", emd);
-    //
-    // ArtifactVersionMetaDataDto metaData = storage().getArtifactVersionMetaData(GROUP_ID, artifactId, "1");
-    // Assertions.assertNotNull(metaData);
-    // Assertions.assertEquals(newName, metaData.getName());
-    // Assertions.assertEquals(newDescription, metaData.getDescription());
-    // }
-    //
-    // @Test
-    // public void testDeleteArtifact() throws Exception {
-    // String artifactId = "testDeleteArtifact-1";
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    // ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dto);
-    // Assertions.assertEquals(GROUP_ID, dto.getGroupId());
-    // Assertions.assertEquals(artifactId, dto.getArtifactId());
-    // Assertions.assertEquals("Empty API", dto.getName());
-    // Assertions.assertEquals("An example API design using OpenAPI.", dto.getDescription());
-    // Assertions.assertNull(dto.getLabels());
-    // Assertions.assertEquals("1", dto.getVersion());
-    //
-    // storage().getArtifactVersionContent(GROUP_ID, artifactId, "1");
-    //
-    // storage().deleteArtifact(GROUP_ID, artifactId);
-    //
-    // Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
-    // storage().getArtifactVersionContent(GROUP_ID, artifactId, "1");
-    // });
-    // Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
-    // storage().getArtifactMetaData(GROUP_ID, artifactId);
-    // });
-    // Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
-    // storage().getArtifactVersionContent(GROUP_ID, artifactId, "1");
-    // });
-    // Assertions.assertThrows(VersionNotFoundException.class, () -> {
-    // storage().getArtifactVersionMetaData(GROUP_ID, artifactId, "1");
-    // });
-    // }
-    //
-    // @Test
-    // public void testDeleteArtifactVersion() throws Exception {
-    // // Delete the only version
-    // ////////////////////////////
-    // String artifactId = "testDeleteArtifactVersion-1";
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    // ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dto);
-    // Assertions.assertEquals("1", dto.getVersion());
-    //
-    // storage().deleteArtifactVersion(GROUP_ID, artifactId, "1");
-    //
-    // final String aid1 = artifactId;
-    // Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
-    // storage().getArtifactVersionContent(GROUP_ID, aid1, "1");
-    // });
-    // Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
-    // storage().getArtifactMetaData(GROUP_ID, aid1);
-    // });
-    // Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
-    // storage().getArtifactVersionContent(GROUP_ID, aid1, "1");
-    // });
-    // Assertions.assertThrows(VersionNotFoundException.class, () -> {
-    // storage().getArtifactVersionMetaData(GROUP_ID, aid1, "1");
-    // });
-    //
-    // // Delete one of multiple versions
-    // artifactId = "testDeleteArtifactVersion-2";
-    // content = ContentHandle.create(OPENAPI_CONTENT);
-    // dto = storage().createArtifact(GROUP_ID, artifactId, null, ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dto);
-    // Assertions.assertEquals("1", dto.getVersion());
-    //
-    // ContentHandle contentv2 = ContentHandle.create(OPENAPI_CONTENT_V2);
-    // ArtifactVersionMetaDataDto dtov2 = storage().createArtifactVersion(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, contentv2, null);
-    // Assertions.assertNotNull(dtov2);
-    // Assertions.assertEquals("2", dtov2.getVersion());
-    //
-    // storage().deleteArtifactVersion(GROUP_ID, artifactId, "1");
-    //
-    // final String aid2 = artifactId;
-    //
-    // storage().getArtifactMetaData(GROUP_ID, aid2);
-    // storage().getArtifactVersionContent(GROUP_ID, aid2, "2");
-    // storage().getArtifactVersionMetaData(GROUP_ID, aid2, "2");
-    // Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
-    // storage().getArtifactVersionContent(GROUP_ID, aid2, "1");
-    // });
-    // Assertions.assertThrows(VersionNotFoundException.class, () -> {
-    // storage().getArtifactVersionMetaData(GROUP_ID, aid2, "1");
-    // });
-    //
-    // ArtifactVersionMetaDataDto dtov3 = storage().createArtifactVersion(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dtov3);
-    // Assertions.assertEquals("3", dtov3.getVersion());
-    //
-    // // Update version 2 to DISABLED state and delete latest version
-    // updateVersionState(GROUP_ID, artifactId, "2", VersionState.DISABLED);
-    // storage().deleteArtifactVersion(GROUP_ID, artifactId, "3");
-    //
-    // GAV latestGAV = storage().getBranchTip(new GA(GROUP_ID, artifactId), BranchId.LATEST, DEFAULT);
-    // ArtifactVersionMetaDataDto artifactMetaData = storage().getArtifactVersionMetaData(GROUP_ID, aid2,
-    // latestGAV.getRawVersionId());
-    // Assertions.assertNotNull(artifactMetaData);
-    // Assertions.assertEquals("2", artifactMetaData.getVersion());
-    // Assertions.assertEquals(aid2, artifactMetaData.getArtifactId());
-    //
-    // // Delete the latest version
-    // artifactId = "testDeleteArtifactVersion-3";
-    // content = ContentHandle.create(OPENAPI_CONTENT);
-    // dto = storage().createArtifact(GROUP_ID, artifactId, null, ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dto);
-    // Assertions.assertEquals("1", dto.getVersion());
-    //
-    // contentv2 = ContentHandle.create(OPENAPI_CONTENT_V2);
-    // dtov2 = storage().createArtifactVersion(GROUP_ID, artifactId, null, ArtifactType.OPENAPI, contentv2,
-    // null);
-    // Assertions.assertNotNull(dtov2);
-    //
-    // final String aid3 = artifactId;
-    // storage().deleteArtifactVersion(GROUP_ID, aid3, "2");
-    // List<String> versions = storage().getArtifactVersions(GROUP_ID, aid3);
-    // Assertions.assertNotNull(versions);
-    // Assertions.assertFalse(versions.isEmpty());
-    // Assertions.assertEquals(1, versions.size());
-    // Assertions.assertEquals("1", versions.iterator().next());
-    //
-    // VersionSearchResultsDto result = storage().searchVersions(GROUP_ID, aid3, 0, 10);
-    // Assertions.assertNotNull(result);
-    // Assertions.assertEquals(1, result.getCount());
-    // Assertions.assertEquals("1", result.getVersions().iterator().next().getVersion());
-    //
-    // artifactMetaData = storage().getArtifactVersionMetaData(GROUP_ID, aid3, "1");
-    // Assertions.assertNotNull(artifactMetaData);
-    // Assertions.assertEquals("1", artifactMetaData.getVersion());
-    // Assertions.assertEquals(aid3, artifactMetaData.getArtifactId());
-    //
-    // storage().getArtifactVersionContent(GROUP_ID, aid3, "1");
-    // ArtifactVersionMetaDataDto metaData = storage().getArtifactVersionMetaData(GROUP_ID, aid3, "1");
-    // Assertions.assertNotNull(metaData);
-    // Assertions.assertEquals("1", metaData.getVersion());
-    // Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
-    // storage().getArtifactVersionContent(GROUP_ID, aid3, "2");
-    // });
-    // Assertions.assertThrows(VersionNotFoundException.class, () -> {
-    // storage().getArtifactVersionMetaData(GROUP_ID, aid3, "2");
-    // });
-    //
-    // // Delete the only artifact version left - same as deleting the whole artifact
-    // storage().deleteArtifactVersion(GROUP_ID, aid3, "1");
-    // Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
-    // storage().getArtifactMetaData(GROUP_ID, aid3);
-    // });
-    // }
-    //
-    // @Test
-    // public void testCreateArtifactRule() throws Exception {
-    // String artifactId = "testCreateArtifactRule-1";
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    // ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dto);
-    // Assertions.assertEquals(GROUP_ID, dto.getGroupId());
-    // Assertions.assertEquals(artifactId, dto.getArtifactId());
-    //
-    // List<RuleType> artifactRules = storage().getArtifactRules(GROUP_ID, artifactId);
-    // Assertions.assertNotNull(artifactRules);
-    // Assertions.assertTrue(artifactRules.isEmpty());
-    //
-    // RuleConfigurationDto configDto = new RuleConfigurationDto("FULL");
-    // storage().createArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY, configDto);
-    //
-    // artifactRules = storage().getArtifactRules(GROUP_ID, artifactId);
-    // Assertions.assertNotNull(artifactRules);
-    // Assertions.assertFalse(artifactRules.isEmpty());
-    // Assertions.assertEquals(1, artifactRules.size());
-    // Assertions.assertEquals(RuleType.VALIDITY, artifactRules.get(0));
-    // }
-    //
-    // @Test
-    // public void testUpdateArtifactRule() throws Exception {
-    // String artifactId = "testUpdateArtifactRule-1";
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    // ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dto);
-    // Assertions.assertEquals(GROUP_ID, dto.getGroupId());
-    // Assertions.assertEquals(artifactId, dto.getArtifactId());
-    //
-    // RuleConfigurationDto configDto = new RuleConfigurationDto("FULL");
-    // storage().createArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY, configDto);
-    //
-    // RuleConfigurationDto rule = storage().getArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY);
-    // Assertions.assertNotNull(rule);
-    // Assertions.assertEquals("FULL", rule.getConfiguration());
-    //
-    // RuleConfigurationDto updatedConfig = new RuleConfigurationDto("NONE");
-    // storage().updateArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY, updatedConfig);
-    //
-    // rule = storage().getArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY);
-    // Assertions.assertNotNull(rule);
-    // Assertions.assertEquals("NONE", rule.getConfiguration());
-    // }
-    //
-    // @Test
-    // public void testDeleteArtifactRule() throws Exception {
-    // String artifactId = "testDeleteArtifactRule-1";
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    // ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dto);
-    // Assertions.assertEquals(GROUP_ID, dto.getGroupId());
-    // Assertions.assertEquals(artifactId, dto.getArtifactId());
-    //
-    // RuleConfigurationDto configDto = new RuleConfigurationDto("FULL");
-    // storage().createArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY, configDto);
-    //
-    // RuleConfigurationDto rule = storage().getArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY);
-    // Assertions.assertNotNull(rule);
-    // Assertions.assertEquals("FULL", rule.getConfiguration());
-    //
-    // storage().deleteArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY);
-    //
-    // Assertions.assertThrows(RuleNotFoundException.class, () -> {
-    // storage().getArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY);
-    // });
-    // }
-    //
-    // @Test
-    // public void testDeleteAllArtifactRules() throws Exception {
-    // String artifactId = "testDeleteAllArtifactRulse-1";
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    // ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dto);
-    // Assertions.assertEquals(GROUP_ID, dto.getGroupId());
-    // Assertions.assertEquals(artifactId, dto.getArtifactId());
-    //
-    // RuleConfigurationDto configDto = new RuleConfigurationDto("FULL");
-    // storage().createArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY, configDto);
-    // storage().createArtifactRule(GROUP_ID, artifactId, RuleType.COMPATIBILITY, configDto);
-    //
-    // List<RuleType> rules = storage().getArtifactRules(GROUP_ID, artifactId);
-    // Assertions.assertEquals(2, rules.size());
-    //
-    // storage().deleteArtifactRules(GROUP_ID, artifactId);
-    //
-    // Assertions.assertThrows(RuleNotFoundException.class, () -> {
-    // storage().getArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY);
-    // });
-    // Assertions.assertThrows(RuleNotFoundException.class, () -> {
-    // storage().getArtifactRule(GROUP_ID, artifactId, RuleType.COMPATIBILITY);
-    // });
-    // }
-    //
-    // @Test
-    // public void testGlobalRules() {
-    // List<RuleType> globalRules = storage().getGlobalRules();
-    // Assertions.assertNotNull(globalRules);
-    // Assertions.assertTrue(globalRules.isEmpty());
-    //
-    // RuleConfigurationDto config = new RuleConfigurationDto();
-    // config.setConfiguration("FULL");
-    // storage().createGlobalRule(RuleType.COMPATIBILITY, config);
-    //
-    // RuleConfigurationDto rule = storage().getGlobalRule(RuleType.COMPATIBILITY);
-    // Assertions.assertEquals(rule.getConfiguration(), config.getConfiguration());
-    //
-    // globalRules = storage().getGlobalRules();
-    // Assertions.assertNotNull(globalRules);
-    // Assertions.assertFalse(globalRules.isEmpty());
-    // Assertions.assertEquals(globalRules.size(), 1);
-    // Assertions.assertEquals(globalRules.get(0), RuleType.COMPATIBILITY);
-    //
-    // Assertions.assertThrows(RuleAlreadyExistsException.class, () -> {
-    // storage().createGlobalRule(RuleType.COMPATIBILITY, config);
-    // });
-    //
-    // RuleConfigurationDto updatedConfig = new RuleConfigurationDto("FORWARD");
-    // storage().updateGlobalRule(RuleType.COMPATIBILITY, updatedConfig);
-    //
-    // rule = storage().getGlobalRule(RuleType.COMPATIBILITY);
-    // Assertions.assertEquals(rule.getConfiguration(), updatedConfig.getConfiguration());
-    //
-    // Assertions.assertThrows(RuleNotFoundException.class, () -> {
-    // storage().updateGlobalRule(RuleType.VALIDITY, config);
-    // });
-    //
-    // storage().deleteGlobalRules();
-    // globalRules = storage().getGlobalRules();
-    // Assertions.assertNotNull(globalRules);
-    // Assertions.assertTrue(globalRules.isEmpty());
-    //
-    // storage().createGlobalRule(RuleType.COMPATIBILITY, config);
-    // storage().deleteGlobalRule(RuleType.COMPATIBILITY);
-    // globalRules = storage().getGlobalRules();
-    // Assertions.assertNotNull(globalRules);
-    // Assertions.assertTrue(globalRules.isEmpty());
-    // }
-    //
-    // @Test
-    // public void testSearchArtifacts() throws Exception {
-    // String artifactIdPrefix = "testSearchArtifacts-";
-    // for (int idx = 1; idx <= 50; idx++) {
-    // String idxs = (idx < 10 ? "0" : "") + idx;
-    // String artifactId = artifactIdPrefix + idxs;
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    // Map<String, String> labels = Collections.singletonMap("key", "value-" + idx);
-    // EditableArtifactMetaDataDto metaData = new EditableArtifactMetaDataDto(
-    // artifactId + "-name",
-    // artifactId + "-description",
-    // null,
-    // labels);
-    // storage().createArtifactWithMetadata(GROUP_ID, artifactId, null, ArtifactType.OPENAPI, content,
-    // metaData, null);
-    // }
-    //
-    // long start = System.currentTimeMillis();
-    //
-    // Set<SearchFilter> filters = Collections.singleton(SearchFilter.ofName("testSearchArtifacts"));
-    // ArtifactSearchResultsDto results = storage().searchArtifacts(filters, OrderBy.name, OrderDirection.asc,
-    // 0, 10);
-    // Assertions.assertNotNull(results);
-    // Assertions.assertEquals(50, results.getCount());
-    // Assertions.assertNotNull(results.getArtifacts());
-    // Assertions.assertEquals(10, results.getArtifacts().size());
-    //
-    //
-    // filters = Collections.singleton(SearchFilter.ofName("testSearchArtifacts-19-name"));
-    // results = storage().searchArtifacts(filters, OrderBy.name, OrderDirection.asc, 0, 10);
-    // Assertions.assertNotNull(results);
-    // Assertions.assertEquals(1, results.getCount());
-    // Assertions.assertNotNull(results.getArtifacts());
-    // Assertions.assertEquals(1, results.getArtifacts().size());
-    // Assertions.assertEquals("testSearchArtifacts-19-name", results.getArtifacts().get(0).getName());
-    //
-    //
-    // filters = Collections.singleton(SearchFilter.ofDescription("testSearchArtifacts-33-description"));
-    // results = storage().searchArtifacts(filters, OrderBy.name, OrderDirection.asc, 0, 10);
-    // Assertions.assertNotNull(results);
-    // Assertions.assertEquals(1, results.getCount());
-    // Assertions.assertNotNull(results.getArtifacts());
-    // Assertions.assertEquals(1, results.getArtifacts().size());
-    // Assertions.assertEquals("testSearchArtifacts-33-name", results.getArtifacts().get(0).getName());
-    //
-    //
-    // filters = Collections.emptySet();
-    // results = storage().searchArtifacts(filters, OrderBy.name, OrderDirection.asc, 0, 10);
-    // Assertions.assertNotNull(results);
-    // Assertions.assertNotNull(results.getArtifacts());
-    // Assertions.assertEquals(10, results.getArtifacts().size());
-    //
-    //
-    // filters = Collections.singleton(SearchFilter.ofEverything("testSearchArtifacts"));
-    // results = storage().searchArtifacts(filters, OrderBy.name, OrderDirection.asc, 0, 1000);
-    // Assertions.assertNotNull(results);
-    // Assertions.assertEquals(50, results.getCount());
-    // Assertions.assertNotNull(results.getArtifacts());
-    // Assertions.assertEquals(50, results.getArtifacts().size());
-    // Assertions.assertEquals("testSearchArtifacts-01-name", results.getArtifacts().get(0).getName());
-    // Assertions.assertEquals("testSearchArtifacts-02-name", results.getArtifacts().get(1).getName());
-    //
-    //
-    // filters = Collections.singleton(SearchFilter.ofLabel("key", "value-17"));
-    // results = storage().searchArtifacts(filters, OrderBy.name, OrderDirection.asc, 0, 10);
-    // Assertions.assertNotNull(results);
-    // Assertions.assertEquals(1, results.getCount());
-    // Assertions.assertNotNull(results.getArtifacts());
-    // Assertions.assertEquals(1, results.getArtifacts().size());
-    // Assertions.assertEquals("testSearchArtifacts-17-name", results.getArtifacts().get(0).getName());
-    //
-    //
-    // long end = System.currentTimeMillis();
-    // System.out.println("Search time: " + (end - start) + "ms");
-    // }
-    //
-    // @Test
-    // public void testSearchVersions() throws Exception {
-    // String artifactId = "testSearchVersions-1";
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    // ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dto);
-    // Assertions.assertEquals(GROUP_ID, dto.getGroupId());
-    // Assertions.assertEquals(artifactId, dto.getArtifactId());
-    //
-    // // Add more versions
-    // for (int idx = 2; idx <= 50; idx++) {
-    // content = ContentHandle.create(OPENAPI_CONTENT_TEMPLATE.replaceAll("VERSION", "1.0." + idx));
-    // EditableVersionMetaDataDto metaData = new EditableVersionMetaDataDto(
-    // artifactId + "-name-" + idx,
-    // artifactId + "-description-" + idx,
-    // null, null);
-    // storage().createArtifactVersionWithMetadata(GROUP_ID, artifactId, null, ArtifactType.OPENAPI, content,
-    // metaData, null);
-    // }
-    //
-    // TestUtils.retry(() -> {
-    // VersionSearchResultsDto results = storage().searchVersions(GROUP_ID, artifactId, 0, 10);
-    // Assertions.assertNotNull(results);
-    // Assertions.assertEquals(50, results.getCount());
-    // Assertions.assertEquals(10, results.getVersions().size());
-    //
-    // results = storage().searchVersions(GROUP_ID, artifactId, 0, 1000);
-    // Assertions.assertNotNull(results);
-    // Assertions.assertEquals(50, results.getCount());
-    // Assertions.assertEquals(50, results.getVersions().size());
-    // });
-    // }
-    //
-    // private void createSomeUserData() {
-    // final String group1 = "testGroup-1";
-    // final String group2 = "testGroup-2";
-    // final String artifactId1 = "testArtifact-1";
-    // final String artifactId2 = "testArtifact-2";
-    // final String principal = "testPrincipal";
-    // final String role = "testRole";
-    //
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    // // storage().createGroup(GroupMetaDataDto.builder().groupId(group1).build());
-    // // ^ TODO Uncomment after https://github.com/Apicurio/apicurio-registry/issues/1721
-    // ArtifactVersionMetaDataDto artifactDto1 = storage().createArtifact(group1, artifactId1, null,
-    // ArtifactType.OPENAPI, content, null);
-    // storage().createArtifactRule(group1, artifactId1, RuleType.VALIDITY,
-    // RuleConfigurationDto.builder().configuration("FULL").build());
-    // ArtifactVersionMetaDataDto artifactDto2 = storage().createArtifactWithMetadata(
-    // group2, artifactId2, null, ArtifactType.OPENAPI, content,
-    // EditableArtifactMetaDataDto.builder().name("test").build(), null);
-    // storage().createGlobalRule(RuleType.VALIDITY,
-    // RuleConfigurationDto.builder().configuration("FULL").build());
-    // storage().createRoleMapping(principal, role, null);
-    //
-    // // Verify data exists
-    //
-    // Assertions.assertNotNull(storage().getArtifactVersionContent(group1, artifactId1,
-    // artifactDto1.getVersion()));
-    // Assertions.assertEquals(1, storage().getArtifactRules(group1, artifactId1).size());
-    // Assertions.assertNotNull(storage().getArtifactVersionContent(group2, artifactId2,
-    // artifactDto2.getVersion()));
-    // Assertions.assertEquals(1, storage().getGlobalRules().size());
-    // Assertions.assertEquals(role, storage().getRoleForPrincipal(principal));
-    // }
-    //
-    // private int countStorageEntities() {
-    // // We don't need thread safety, but it's simpler to use this when effectively final counter is needed
-    // final AtomicInteger count = new AtomicInteger(0);
-    // storage().exportData(e -> {
-    // if (e.getEntityType() != EntityType.Manifest) {
-    // log.debug("Counting from export: {}", e);
-    // count.incrementAndGet();
-    // }
-    // return null;
-    // });
-    // int res = count.get();
-    // // Count data that is not exported
-    // res += storage().getRoleMappings().size();
-    // return res;
-    // }
-    //
-    // @Test
-    // public void testDeleteAllUserData() {
-    // // Delete first to cleanup after other tests
-    // storage().deleteAllUserData();
-    // createSomeUserData();
-    // Assertions.assertEquals(10, countStorageEntities());
-    // // ^ TODO Change to 9 after https://github.com/Apicurio/apicurio-registry/issues/1721
-    // // Delete all
-    // storage().deleteAllUserData();
-    // Assertions.assertEquals(0, countStorageEntities());
-    // }
-    //
-    // @Test
-    // public void testConfigProperties() throws Exception {
-    // List<DynamicConfigPropertyDto> properties = storage().getConfigProperties();
-    // Assertions.assertNotNull(properties);
-    // Assertions.assertTrue(properties.isEmpty());
-    //
-    // storage().setConfigProperty(new DynamicConfigPropertyDto("apicurio.test.property-string",
-    // "test-value"));
-    // storage().setConfigProperty(new DynamicConfigPropertyDto("apicurio.test.property-boolean", "true"));
-    // storage().setConfigProperty(new DynamicConfigPropertyDto("apicurio.test.property-long", "12345"));
-    //
-    // properties = storage().getConfigProperties();
-    // Assertions.assertNotNull(properties);
-    // Assertions.assertFalse(properties.isEmpty());
-    // Assertions.assertEquals(3, properties.size());
-    //
-    // DynamicConfigPropertyDto stringProp = getProperty(properties, "apicurio.test.property-string");
-    // DynamicConfigPropertyDto boolProp = getProperty(properties, "apicurio.test.property-boolean");
-    // DynamicConfigPropertyDto longProp = getProperty(properties, "apicurio.test.property-long");
-    //
-    // Assertions.assertNotNull(stringProp);
-    // Assertions.assertNotNull(boolProp);
-    // Assertions.assertNotNull(longProp);
-    //
-    // Assertions.assertEquals("test-value", stringProp.getValue());
-    // Assertions.assertEquals("true", boolProp.getValue());
-    // Assertions.assertEquals("12345", longProp.getValue());
-    // }
-    //
-    // private DynamicConfigPropertyDto getProperty(List<DynamicConfigPropertyDto> properties, String
-    // propertyName) {
-    // for (DynamicConfigPropertyDto prop : properties) {
-    // if (prop.getName().equals(propertyName)) {
-    // return prop;
-    // }
-    // }
-    // return null;
-    // }
-    //
-    //
-    // @Test
-    // public void testComments() {
-    // String artifactId = "testComments-1";
-    // ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
-    // ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, null,
-    // ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dto);
-    // Assertions.assertEquals(GROUP_ID, dto.getGroupId());
-    // Assertions.assertEquals(artifactId, dto.getArtifactId());
-    //
-    // List<CommentDto> comments = storage().getArtifactVersionComments(GROUP_ID, artifactId,
-    // dto.getVersion());
-    // Assertions.assertTrue(comments.isEmpty());
-    //
-    // storage().createArtifactVersionComment(GROUP_ID, artifactId, dto.getVersion(), "TEST_COMMENT_1");
-    // storage().createArtifactVersionComment(GROUP_ID, artifactId, dto.getVersion(), "TEST_COMMENT_2");
-    // storage().createArtifactVersionComment(GROUP_ID, artifactId, dto.getVersion(), "TEST_COMMENT_3");
-    //
-    // comments = storage().getArtifactVersionComments(GROUP_ID, artifactId, dto.getVersion());
-    // Assertions.assertEquals(3, comments.size());
-    //
-    // storage().deleteArtifactVersionComment(GROUP_ID, artifactId, dto.getVersion(),
-    // comments.get(1).getCommentId());
-    //
-    // comments = storage().getArtifactVersionComments(GROUP_ID, artifactId, dto.getVersion());
-    // Assertions.assertEquals(2, comments.size());
-    //
-    // storage().updateArtifactVersionComment(GROUP_ID, artifactId, dto.getVersion(),
-    // comments.get(0).getCommentId(), "TEST_COMMENT_4");
-    //
-    // comments = storage().getArtifactVersionComments(GROUP_ID, artifactId, dto.getVersion());
-    // Assertions.assertEquals(2, comments.size());
-    // Assertions.assertEquals("TEST_COMMENT_4", comments.get(0).getValue());
-    // }
-    //
-    //
-    // @Test
-    // public void testBranches() {
-    //
-    // var ga = new GA(GROUP_ID, "foo");
-    //
-    // Assertions.assertThrows(ArtifactNotFoundException.class, () -> storage().getBranches(ga));
-    //
-    // var content = ContentHandle.create(OPENAPI_CONTENT);
-    // ArtifactVersionMetaDataDto dtoV1 = storage().createArtifact(GROUP_ID, ga.getRawArtifactId(), null,
-    // ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dtoV1);
-    // Assertions.assertEquals(ga.getRawGroupIdWithDefaultString(), dtoV1.getGroupId());
-    // Assertions.assertEquals(ga.getRawArtifactId(), dtoV1.getArtifactId());
-    //
-    // var branches = storage().getBranches(ga);
-    // Assertions.assertEquals(Map.of(BranchId.LATEST, List.of(new GAV(ga, dtoV1.getVersion()))), branches);
-    //
-    // var latestBranch = storage().getBranch(ga, BranchId.LATEST, DEFAULT);
-    // Assertions.assertEquals(List.of(new GAV(ga, dtoV1.getVersion())), latestBranch);
-    //
-    // var gavV1 = storage().getBranchTip(ga, BranchId.LATEST, DEFAULT);
-    // Assertions.assertNotNull(gavV1);
-    // Assertions.assertEquals(gavV1.getRawGroupIdWithDefaultString(), dtoV1.getGroupId());
-    // Assertions.assertEquals(gavV1.getRawArtifactId(), dtoV1.getArtifactId());
-    // Assertions.assertEquals(gavV1.getRawVersionId(), dtoV1.getVersion());
-    //
-    // var otherBranchId = new BranchId("other");
-    // storage().createOrUpdateBranch(gavV1, otherBranchId);
-    //
-    // content = ContentHandle.create(OPENAPI_CONTENT_V2);
-    // var dtoV2 = storage().createArtifactVersion(ga.getRawGroupIdWithDefaultString(), ga.getRawArtifactId(),
-    // null, ArtifactType.OPENAPI, content, null);
-    // Assertions.assertNotNull(dtoV2);
-    // Assertions.assertEquals(ga.getRawGroupIdWithDefaultString(), dtoV2.getGroupId());
-    // Assertions.assertEquals(ga.getRawArtifactId(), dtoV2.getArtifactId());
-    //
-    // branches = storage().getBranches(ga);
-    // Assertions.assertEquals(Map.of(
-    // BranchId.LATEST, List.of(new GAV(ga, dtoV2.getVersion()), new GAV(ga, dtoV1.getVersion())),
-    // otherBranchId, List.of(new GAV(ga, dtoV1.getVersion()))
-    // ), branches);
-    //
-    // latestBranch = storage().getBranch(ga, BranchId.LATEST, DEFAULT);
-    // Assertions.assertEquals(List.of(new GAV(ga, dtoV2.getVersion()), new GAV(ga, dtoV1.getVersion())),
-    // latestBranch);
-    //
-    // var otherBranch = storage().getBranch(ga, otherBranchId, DEFAULT);
-    // Assertions.assertEquals(List.of(new GAV(ga, dtoV1.getVersion())), otherBranch);
-    //
-    // var gavV2 = storage().getBranchTip(ga, BranchId.LATEST, DEFAULT);
-    // Assertions.assertNotNull(gavV2);
-    // Assertions.assertEquals(gavV2.getRawGroupIdWithDefaultString(), dtoV2.getGroupId());
-    // Assertions.assertEquals(gavV2.getRawArtifactId(), dtoV2.getArtifactId());
-    // Assertions.assertEquals(gavV2.getRawVersionId(), dtoV2.getVersion());
-    //
-    // gavV1 = storage().getBranchTip(ga, otherBranchId, DEFAULT);
-    // Assertions.assertNotNull(gavV1);
-    // Assertions.assertEquals(gavV1.getRawGroupIdWithDefaultString(), dtoV1.getGroupId());
-    // Assertions.assertEquals(gavV1.getRawArtifactId(), dtoV1.getArtifactId());
-    // Assertions.assertEquals(gavV1.getRawVersionId(), dtoV1.getVersion());
-    //
-    // storage().createOrUpdateBranch(gavV2, otherBranchId);
-    //
-    // branches = storage().getBranches(ga);
-    // Assertions.assertEquals(Map.of(
-    // BranchId.LATEST, List.of(new GAV(ga, dtoV2.getVersion()), new GAV(ga, dtoV1.getVersion())),
-    // otherBranchId, List.of(new GAV(ga, dtoV2.getVersion()), new GAV(ga, dtoV1.getVersion()))
-    // ), branches);
-    //
-    // Assertions.assertEquals(storage().getBranch(ga, BranchId.LATEST, DEFAULT), storage().getBranch(ga,
-    // otherBranchId, DEFAULT));
-    // Assertions.assertEquals(storage().getBranchTip(ga, BranchId.LATEST, DEFAULT),
-    // storage().getBranchTip(ga, otherBranchId, DEFAULT));
-    //
-    // updateVersionState(gavV2.getRawGroupIdWithDefaultString(), gavV2.getRawArtifactId(),
-    // gavV2.getRawVersionId(), VersionState.DISABLED);
-    // Assertions.assertEquals(List.of(gavV1), storage().getBranch(ga, BranchId.LATEST,
-    // SKIP_DISABLED_LATEST));
-    // Assertions.assertEquals(gavV1, storage().getBranchTip(ga, BranchId.LATEST,
-    // ArtifactRetrievalBehavior.SKIP_DISABLED_LATEST));
-    //
-    // updateVersionState(gavV2.getRawGroupIdWithDefaultString(), gavV2.getRawArtifactId(),
-    // gavV2.getRawVersionId(), VersionState.ENABLED);
-    // Assertions.assertEquals(List.of(gavV2, gavV1), storage().getBranch(ga, BranchId.LATEST,
-    // SKIP_DISABLED_LATEST));
-    // Assertions.assertEquals(gavV2, storage().getBranchTip(ga, BranchId.LATEST,
-    // ArtifactRetrievalBehavior.SKIP_DISABLED_LATEST));
-    //
-    // storage().deleteArtifactVersion(gavV1.getRawGroupIdWithDefaultString(), gavV1.getRawArtifactId(),
-    // gavV1.getRawVersionId());
-    //
-    // Assertions.assertEquals(List.of(gavV2), storage().getBranch(ga, BranchId.LATEST, DEFAULT));
-    // Assertions.assertEquals(List.of(gavV2), storage().getBranch(ga, otherBranchId, DEFAULT));
-    //
-    // storage().deleteBranch(ga, otherBranchId);
-    //
-    // Assertions.assertThrows(BranchNotFoundException.class, () -> storage().getBranch(ga, otherBranchId,
-    // DEFAULT));
-    // Assertions.assertThrows(VersionNotFoundException.class, () -> storage().getBranchTip(ga, otherBranchId,
-    // DEFAULT));
-    //
-    // Assertions.assertThrows(NotAllowedException.class, () -> storage().deleteBranch(ga, BranchId.LATEST));
-    // }
-    //
-    // private void updateVersionState(String groupId, String artifactId, String version, VersionState
-    // newState) {
-    // storage().updateArtifactVersionMetaData(groupId, artifactId, version,
-    // EditableVersionMetaDataDto.builder()
-    // .state(newState)
-    // .build());
-    // }
-    //
-    // private static String generateString(int size) {
-    // StringBuilder builder = new StringBuilder();
-    // for (int i = 0; i < size; i++) {
-    // builder.append("a");
-    // }
-    // Assertions.assertEquals(size, builder.toString().length());
-    // return builder.toString();
-    // }
+
+    @Test
+    public void testGetArtifactIds() throws Exception {
+
+        int size = storage().getArtifactIds(null).size();
+
+        String artifactIdPrefix = "testGetArtifactIds-";
+        for (int idx = 1; idx <= 10; idx++) {
+            String artifactId = artifactIdPrefix + idx;
+            ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+            ArtifactVersionMetaDataDto dto = storage()
+                    .createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI, null, null,
+                            ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                    .content(content).build(),
+                            null, Collections.emptyList(), false, false)
+                    .getValue();
+            Assertions.assertNotNull(dto);
+            Assertions.assertEquals(GROUP_ID, dto.getGroupId());
+            Assertions.assertEquals(artifactId, dto.getArtifactId());
+
+            // Verify group metadata is also created
+            GroupMetaDataDto groupMetaDataDto = storage().getGroupMetaData(GROUP_ID);
+            Assertions.assertNotNull(groupMetaDataDto);
+            Assertions.assertEquals(GROUP_ID, groupMetaDataDto.getGroupId());
+        }
+
+        int newsize = storage().getArtifactIds(null).size();
+        int newids = newsize - size;
+        Assertions.assertEquals(10, newids);
+    }
+
+    @Test
+    public void testCreateArtifact() throws Exception {
+        String artifactId = "testCreateArtifact-1";
+        ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+        EditableVersionMetaDataDto versionMetaDataDto = EditableVersionMetaDataDto.builder().name("Empty API")
+                .description("An example API design using OpenAPI.").build();
+
+        EditableArtifactMetaDataDto artifactMetaDataDto = EditableArtifactMetaDataDto.builder()
+                .name("Empty API").description("An example API design using OpenAPI.").build();
+        ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI,
+                artifactMetaDataDto, null, ContentWrapperDto.builder()
+                        .contentType(ContentTypes.APPLICATION_JSON).content(content).build(),
+                versionMetaDataDto, Collections.emptyList(), false, false).getValue();
+        Assertions.assertNotNull(dto);
+        Assertions.assertEquals(GROUP_ID, dto.getGroupId());
+        Assertions.assertEquals(artifactId, dto.getArtifactId());
+        Assertions.assertEquals("Empty API", dto.getName());
+        Assertions.assertEquals("An example API design using OpenAPI.", dto.getDescription());
+        Assertions.assertNull(dto.getLabels());
+        Assertions.assertEquals("1", dto.getVersion());
+
+        StoredArtifactVersionDto storedArtifact = storage().getArtifactVersionContent(GROUP_ID, artifactId,
+                dto.getVersion());
+        Assertions.assertNotNull(storedArtifact);
+        Assertions.assertEquals(OPENAPI_CONTENT, storedArtifact.getContent().content());
+        Assertions.assertEquals(dto.getGlobalId(), storedArtifact.getGlobalId());
+        Assertions.assertEquals(dto.getVersion(), storedArtifact.getVersion());
+
+        ArtifactMetaDataDto amdDto = storage().getArtifactMetaData(GROUP_ID, artifactId);
+        Assertions.assertNotNull(amdDto);
+        Assertions.assertEquals("Empty API", amdDto.getName());
+        Assertions.assertEquals("An example API design using OpenAPI.", amdDto.getDescription());
+        Assertions.assertNull(amdDto.getLabels());
+
+        ArtifactVersionMetaDataDto versionMetaDataDto1 = storage().getArtifactVersionMetaData(GROUP_ID,
+                artifactId, "1");
+        Assertions.assertNotNull(versionMetaDataDto1);
+        Assertions.assertEquals(dto.getGlobalId(), versionMetaDataDto1.getGlobalId());
+        Assertions.assertEquals("Empty API", versionMetaDataDto1.getName());
+        Assertions.assertEquals("An example API design using OpenAPI.", versionMetaDataDto1.getDescription());
+        Assertions.assertEquals(VersionState.ENABLED, versionMetaDataDto1.getState());
+        Assertions.assertEquals("1", versionMetaDataDto1.getVersion());
+
+        StoredArtifactVersionDto storedVersion = storage().getArtifactVersionContent(dto.getGlobalId());
+        Assertions.assertNotNull(storedVersion);
+        Assertions.assertEquals(OPENAPI_CONTENT, storedVersion.getContent().content());
+        Assertions.assertEquals(dto.getGlobalId(), storedVersion.getGlobalId());
+        Assertions.assertEquals(dto.getVersion(), storedVersion.getVersion());
+
+        storedVersion = storage().getArtifactVersionContent(GROUP_ID, artifactId, "1");
+        Assertions.assertNotNull(storedVersion);
+        Assertions.assertEquals(OPENAPI_CONTENT, storedVersion.getContent().content());
+        Assertions.assertEquals(dto.getGlobalId(), storedVersion.getGlobalId());
+        Assertions.assertEquals(dto.getVersion(), storedVersion.getVersion());
+
+        List<String> versions = storage().getArtifactVersions(GROUP_ID, artifactId);
+        Assertions.assertNotNull(versions);
+        Assertions.assertEquals("1", versions.iterator().next());
+    }
+
+    @Test
+    public void testCreateArtifactWithMetaData() throws Exception {
+        String artifactId = "testCreateArtifactWithMetaData-1";
+        ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+        EditableVersionMetaDataDto metaData = EditableVersionMetaDataDto.builder().name("NAME")
+                .description("DESCRIPTION").labels(Collections.singletonMap("KEY", "VALUE")).build();
+
+        EditableArtifactMetaDataDto artifactMetaDataDto = new EditableArtifactMetaDataDto("NAME",
+                "DESCRIPTION", null, Collections.singletonMap("KEY", "VALUE"));
+
+        ArtifactVersionMetaDataDto dto = storage()
+                .createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI, artifactMetaDataDto, null,
+                        ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                .content(content).build(),
+                        metaData, Collections.emptyList(), false, false)
+                .getValue();
+        Assertions.assertNotNull(dto);
+        Assertions.assertEquals(GROUP_ID, dto.getGroupId());
+        Assertions.assertEquals(artifactId, dto.getArtifactId());
+        Assertions.assertEquals("NAME", dto.getName());
+        Assertions.assertEquals("DESCRIPTION", dto.getDescription());
+        Assertions.assertNotNull(dto.getLabels());
+        Assertions.assertEquals(metaData.getLabels(), dto.getLabels());
+        Assertions.assertEquals("1", dto.getVersion());
+
+        StoredArtifactVersionDto storedArtifact = storage().getArtifactVersionContent(GROUP_ID, artifactId,
+                "1");
+        Assertions.assertNotNull(storedArtifact);
+        Assertions.assertEquals(OPENAPI_CONTENT, storedArtifact.getContent().content());
+        Assertions.assertEquals(dto.getGlobalId(), storedArtifact.getGlobalId());
+        Assertions.assertEquals(dto.getVersion(), storedArtifact.getVersion());
+
+        ArtifactMetaDataDto amdDto = storage().getArtifactMetaData(GROUP_ID, artifactId);
+        Assertions.assertNotNull(amdDto);
+        Assertions.assertEquals("NAME", amdDto.getName());
+        Assertions.assertEquals("DESCRIPTION", amdDto.getDescription());
+        Assertions.assertEquals(metaData.getLabels(), amdDto.getLabels());
+    }
+
+    @Test
+    public void testCreateArtifactWithLargeMetaData() throws Exception {
+        ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+
+        // Test creating an artifact with meta-data that is too large for the DB
+        String artifactId = "testCreateArtifactWithLargeMetaData";
+        EditableVersionMetaDataDto metaData = new EditableVersionMetaDataDto();
+        metaData.setName(generateString(600));
+        metaData.setDescription(generateString(2000));
+        metaData.setLabels(new HashMap<>());
+        metaData.getLabels().put("key-" + generateString(300), "value-" + generateString(2000));
+        ArtifactVersionMetaDataDto dto = storage()
+                .createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI, null, null,
+                        ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                .content(content).build(),
+                        metaData, Collections.emptyList(), false, false)
+                .getValue();
+        dto = storage().getArtifactVersionMetaData(dto.getGlobalId());
+        Assertions.assertNotNull(dto);
+        Assertions.assertEquals(GROUP_ID, dto.getGroupId());
+        Assertions.assertEquals(artifactId, dto.getArtifactId());
+        Assertions.assertEquals(512, dto.getName().length());
+        Assertions.assertEquals(1024, dto.getDescription().length());
+        Assertions.assertTrue(dto.getDescription().endsWith("..."));
+        Assertions.assertNotNull(dto.getLabels());
+        Assertions.assertEquals(1, dto.getLabels().size());
+    }
+
+    @Test
+    public void testCreateDuplicateArtifact() throws Exception {
+        String artifactId = "testCreateDuplicateArtifact-1";
+        ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+        ArtifactVersionMetaDataDto dto = storage()
+                .createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI, null, null,
+                        ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                .content(content).build(),
+                        null, Collections.emptyList(), false, false)
+                .getValue();
+        Assertions.assertNotNull(dto);
+
+        // Should throw error for duplicate artifact.
+        Assertions.assertThrows(ArtifactAlreadyExistsException.class, () -> {
+            storage()
+                    .createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI, null, null,
+                            ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                    .content(content).build(),
+                            null, Collections.emptyList(), false, false)
+                    .getValue();
+
+        });
+    }
+
+    @Test
+    public void testArtifactNotFound() throws Exception {
+        String artifactId = "testArtifactNotFound-1";
+
+        Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
+            storage().getArtifactVersionContent(GROUP_ID, artifactId, "1");
+        });
+
+        Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
+            storage().getArtifactMetaData(GROUP_ID, artifactId);
+        });
+
+        Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
+            storage().getArtifactVersionContent(GROUP_ID, artifactId, "1");
+        });
+
+        Assertions.assertThrows(VersionNotFoundException.class, () -> {
+            storage().getArtifactVersionMetaData(GROUP_ID, artifactId, "1");
+        });
+    }
+
+    @Test
+    public void testCreateArtifactVersion() throws Exception {
+        String artifactId = "testCreateArtifactVersion-1";
+        ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+        ArtifactVersionMetaDataDto dto = storage()
+                .createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI, null, null,
+                        ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                .content(content).build(),
+                        null, Collections.emptyList(), false, false)
+                .getValue();
+        Assertions.assertNotNull(dto);
+        Assertions.assertEquals(GROUP_ID, dto.getGroupId());
+        Assertions.assertEquals(artifactId, dto.getArtifactId());
+
+        List<String> versions = storage().getArtifactVersions(GROUP_ID, artifactId);
+        Assertions.assertNotNull(versions);
+        Assertions.assertFalse(versions.isEmpty());
+        Assertions.assertEquals(1, versions.size());
+
+        ContentHandle contentv2 = ContentHandle.create(OPENAPI_CONTENT_V2);
+        ArtifactVersionMetaDataDto dtov2 = storage().createArtifactVersion(
+                GROUP_ID, artifactId, null, ArtifactType.OPENAPI, ContentWrapperDto.builder()
+                        .contentType(ContentTypes.APPLICATION_JSON).content(contentv2).build(),
+                null, Collections.emptyList(), false, false);
+        Assertions.assertNotNull(dtov2);
+        Assertions.assertEquals(GROUP_ID, dtov2.getGroupId());
+        Assertions.assertEquals(artifactId, dtov2.getArtifactId());
+        Assertions.assertEquals("2", dtov2.getVersion());
+
+        versions = storage().getArtifactVersions(GROUP_ID, artifactId);
+        Assertions.assertNotNull(versions);
+        Assertions.assertFalse(versions.isEmpty());
+        Assertions.assertEquals(2, versions.size());
+    }
+
+    @Test
+    public void testGetArtifactVersions() throws Exception {
+        String artifactId = "testGetArtifactVersions";
+        ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+        ArtifactVersionMetaDataDto dto = storage()
+                .createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI, null, null,
+                        ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                .content(content).build(),
+                        null, Collections.emptyList(), false, false)
+                .getValue();
+        Assertions.assertNotNull(dto);
+        Assertions.assertEquals(GROUP_ID, dto.getGroupId());
+        Assertions.assertEquals(artifactId, dto.getArtifactId());
+
+        StoredArtifactVersionDto storedArtifact = storage().getArtifactVersionContent(GROUP_ID, artifactId,
+                "1");
+        verifyArtifact(storedArtifact, OPENAPI_CONTENT, dto);
+
+        storedArtifact = storage().getArtifactVersionContent(GROUP_ID, artifactId, "1");
+        verifyArtifact(storedArtifact, OPENAPI_CONTENT, dto);
+
+        storedArtifact = storage().getArtifactVersionContent(dto.getGlobalId());
+        verifyArtifact(storedArtifact, OPENAPI_CONTENT, dto);
+
+        ArtifactVersionMetaDataDto dtov1 = storage().getArtifactVersionMetaData(dto.getGlobalId());
+        verifyArtifactMetadata(dtov1, dto);
+
+        List<String> versions = storage().getArtifactVersions(GROUP_ID, artifactId);
+        Assertions.assertNotNull(versions);
+        Assertions.assertFalse(versions.isEmpty());
+        Assertions.assertEquals(1, versions.size());
+
+        ContentHandle contentv2 = ContentHandle.create(OPENAPI_CONTENT_V2);
+        ArtifactVersionMetaDataDto dtov2 = storage().createArtifactVersion(
+                GROUP_ID, artifactId, null, ArtifactType.OPENAPI, ContentWrapperDto.builder()
+                        .contentType(ContentTypes.APPLICATION_JSON).content(contentv2).build(),
+                null, Collections.emptyList(), false, false);
+        Assertions.assertNotNull(dtov2);
+        Assertions.assertEquals(GROUP_ID, dtov2.getGroupId());
+        Assertions.assertEquals(artifactId, dtov2.getArtifactId());
+        Assertions.assertEquals("2", dtov2.getVersion());
+
+        versions = storage().getArtifactVersions(GROUP_ID, artifactId);
+        Assertions.assertNotNull(versions);
+        Assertions.assertFalse(versions.isEmpty());
+        Assertions.assertEquals(2, versions.size());
+
+        // verify version 2
+
+        storedArtifact = storage().getArtifactVersionContent(GROUP_ID, artifactId, "2");
+        verifyArtifact(storedArtifact, OPENAPI_CONTENT_V2, dtov2);
+
+        storedArtifact = storage().getArtifactVersionContent(dtov2.getGlobalId());
+        verifyArtifact(storedArtifact, OPENAPI_CONTENT_V2, dtov2);
+
+        ArtifactVersionMetaDataDto dtov2Stored = storage().getArtifactVersionMetaData(dtov2.getGlobalId());
+        verifyArtifactMetadata(dtov2Stored, dtov2);
+
+        // verify version 1 again
+
+        storedArtifact = storage().getArtifactVersionContent(GROUP_ID, artifactId, "1");
+        verifyArtifact(storedArtifact, OPENAPI_CONTENT, dto);
+
+        storedArtifact = storage().getArtifactVersionContent(dto.getGlobalId());
+        verifyArtifact(storedArtifact, OPENAPI_CONTENT, dto);
+
+        dtov1 = storage().getArtifactVersionMetaData(dto.getGlobalId());
+        verifyArtifactMetadata(dtov1, dto);
+
+    }
+
+    private void verifyArtifact(StoredArtifactVersionDto storedArtifact, String content,
+            ArtifactVersionMetaDataDto expectedMetadata) {
+        Assertions.assertNotNull(storedArtifact);
+        Assertions.assertEquals(content, storedArtifact.getContent().content());
+        Assertions.assertEquals(expectedMetadata.getGlobalId(), storedArtifact.getGlobalId());
+        Assertions.assertEquals(expectedMetadata.getVersion(), storedArtifact.getVersion());
+    }
+
+    private void verifyArtifactMetadata(ArtifactVersionMetaDataDto actualMetadata,
+            ArtifactVersionMetaDataDto expectedMetadata) {
+        Assertions.assertNotNull(actualMetadata);
+        Assertions.assertNotNull(expectedMetadata);
+        Assertions.assertEquals(expectedMetadata.getName(), actualMetadata.getName());
+        Assertions.assertEquals(expectedMetadata.getDescription(), actualMetadata.getDescription());
+    }
+
+    @Test
+    public void testCreateArtifactVersionWithMetaData() throws Exception {
+        String artifactId = "testCreateArtifactVersionWithMetaData-2";
+        ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+        ArtifactVersionMetaDataDto dto = storage()
+                .createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI, null, null,
+                        ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                .content(content).build(),
+                        null, Collections.emptyList(), false, false)
+                .getValue();
+        Assertions.assertNotNull(dto);
+        Assertions.assertEquals(GROUP_ID, dto.getGroupId());
+        Assertions.assertEquals(artifactId, dto.getArtifactId());
+
+        List<String> versions = storage().getArtifactVersions(GROUP_ID, artifactId);
+        Assertions.assertNotNull(versions);
+        Assertions.assertFalse(versions.isEmpty());
+        Assertions.assertEquals(1, versions.size());
+
+        ContentHandle contentv2 = ContentHandle.create(OPENAPI_CONTENT_V2);
+        EditableVersionMetaDataDto metaData = EditableVersionMetaDataDto.builder().name("NAME")
+                .description("DESCRIPTION").labels(Collections.singletonMap("K", "V")).build();
+        ArtifactVersionMetaDataDto dtov2 = storage().createArtifactVersion(
+                GROUP_ID, artifactId, "2", ArtifactType.OPENAPI, ContentWrapperDto.builder()
+                        .contentType(ContentTypes.APPLICATION_JSON).content(contentv2).build(),
+                metaData, Collections.emptyList(), false, false);
+        Assertions.assertNotNull(dtov2);
+        Assertions.assertEquals(GROUP_ID, dtov2.getGroupId());
+        Assertions.assertEquals(artifactId, dtov2.getArtifactId());
+        Assertions.assertEquals("2", dtov2.getVersion());
+        Assertions.assertEquals("NAME", dtov2.getName());
+        Assertions.assertEquals("DESCRIPTION", dtov2.getDescription());
+        Assertions.assertEquals(metaData.getLabels(), dtov2.getLabels());
+
+        versions = storage().getArtifactVersions(GROUP_ID, artifactId);
+        Assertions.assertNotNull(versions);
+        Assertions.assertFalse(versions.isEmpty());
+        Assertions.assertEquals(2, versions.size());
+
+        ArtifactVersionMetaDataDto vmd = storage().getArtifactVersionMetaData(GROUP_ID, artifactId, "2");
+        Assertions.assertNotNull(vmd);
+        Assertions.assertEquals("NAME", vmd.getName());
+        Assertions.assertEquals("DESCRIPTION", vmd.getDescription());
+    }
+
+    @Test
+    public void testGetArtifactMetaDataByGlobalId() throws Exception {
+        String artifactId = "testGetArtifactMetaDataByGlobalId-1";
+        ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+        EditableVersionMetaDataDto versionMetaDataDto = EditableVersionMetaDataDto.builder().name("Empty API")
+                .description("An example API design using OpenAPI.").build();
+        ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI,
+                null, null, ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                        .content(content).build(),
+                versionMetaDataDto, Collections.emptyList(), false, false).getValue();
+        Assertions.assertNotNull(dto);
+        Assertions.assertEquals(GROUP_ID, dto.getGroupId());
+        Assertions.assertEquals(artifactId, dto.getArtifactId());
+        Assertions.assertEquals("Empty API", dto.getName());
+        Assertions.assertEquals("An example API design using OpenAPI.", dto.getDescription());
+        Assertions.assertNull(dto.getLabels());
+        Assertions.assertEquals("1", dto.getVersion());
+
+        long globalId = dto.getGlobalId();
+
+        dto = storage().getArtifactVersionMetaData(globalId);
+        Assertions.assertNotNull(dto);
+        Assertions.assertEquals(GROUP_ID, dto.getGroupId());
+        Assertions.assertEquals(artifactId, dto.getArtifactId());
+        Assertions.assertEquals("Empty API", dto.getName());
+        Assertions.assertEquals("An example API design using OpenAPI.", dto.getDescription());
+        Assertions.assertNull(dto.getLabels());
+        Assertions.assertEquals("1", dto.getVersion());
+    }
+
+    @Test
+    public void testUpdateArtifactMetaData() throws Exception {
+        String artifactId = "testUpdateArtifactMetaData-1";
+        ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+        EditableVersionMetaDataDto versionMetaDataDto = EditableVersionMetaDataDto.builder().name("Empty API")
+                .description("An example API design using OpenAPI.").build();
+        ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI,
+                null, null, ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                        .content(content).build(),
+                versionMetaDataDto, Collections.emptyList(), false, false).getValue();
+        Assertions.assertNotNull(dto);
+        Assertions.assertEquals(GROUP_ID, dto.getGroupId());
+        Assertions.assertEquals(artifactId, dto.getArtifactId());
+        Assertions.assertEquals("Empty API", dto.getName());
+        Assertions.assertEquals("An example API design using OpenAPI.", dto.getDescription());
+        Assertions.assertNull(dto.getLabels());
+        Assertions.assertEquals("1", dto.getVersion());
+
+        String newName = "Updated Name";
+        String newDescription = "Updated description.";
+        Map<String, String> newLabels = new HashMap<>();
+        newLabels.put("foo", "bar");
+        newLabels.put("ting", "bin");
+        EditableArtifactMetaDataDto emd = new EditableArtifactMetaDataDto(newName, newDescription, null,
+                newLabels);
+        storage().updateArtifactMetaData(GROUP_ID, artifactId, emd);
+
+        ArtifactMetaDataDto metaData = storage().getArtifactMetaData(GROUP_ID, artifactId);
+        Assertions.assertNotNull(metaData);
+        Assertions.assertEquals(newName, metaData.getName());
+        Assertions.assertEquals(newDescription, metaData.getDescription());
+    }
+
+    @Test
+    public void testUpdateArtifactVersionState() throws Exception {
+        String artifactId = "testUpdateArtifactVersionState-1";
+        ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+        ArtifactVersionMetaDataDto dto = storage()
+                .createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI, null, null,
+                        ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                .content(content).build(),
+                        null, Collections.emptyList(), false, false)
+                .getValue();
+        Assertions.assertNotNull(dto);
+
+        ContentHandle contentv2 = ContentHandle.create(OPENAPI_CONTENT_V2);
+        ArtifactVersionMetaDataDto dtov2 = storage().createArtifactVersion(
+                GROUP_ID, artifactId, null, ArtifactType.OPENAPI, ContentWrapperDto.builder()
+                        .contentType(ContentTypes.APPLICATION_JSON).content(contentv2).build(),
+                null, Collections.emptyList(), false, false);
+        ;
+        Assertions.assertNotNull(dtov2);
+        Assertions.assertEquals(GROUP_ID, dtov2.getGroupId());
+        Assertions.assertEquals(artifactId, dtov2.getArtifactId());
+        Assertions.assertEquals("2", dtov2.getVersion());
+
+        updateVersionState(GROUP_ID, artifactId, "1", VersionState.DISABLED);
+        updateVersionState(GROUP_ID, artifactId, "2", VersionState.DEPRECATED);
+
+        ArtifactVersionMetaDataDto v1 = storage().getArtifactVersionMetaData(GROUP_ID, artifactId, "1");
+        ArtifactVersionMetaDataDto v2 = storage().getArtifactVersionMetaData(GROUP_ID, artifactId, "2");
+        Assertions.assertNotNull(v1);
+        Assertions.assertNotNull(v2);
+        Assertions.assertEquals(VersionState.DISABLED, v1.getState());
+        Assertions.assertEquals(VersionState.DEPRECATED, v2.getState());
+    }
+
+    @Test
+    public void testUpdateArtifactVersionMetaData() throws Exception {
+        String artifactId = "testUpdateArtifactVersionMetaData-1";
+        ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+        EditableVersionMetaDataDto versionMetaDataDto = EditableVersionMetaDataDto.builder().name("Empty API")
+                .description("An example API design using OpenAPI.").build();
+        ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI,
+                null, null, ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                        .content(content).build(),
+                versionMetaDataDto, Collections.emptyList(), false, false).getValue();
+        Assertions.assertNotNull(dto);
+        Assertions.assertEquals(GROUP_ID, dto.getGroupId());
+        Assertions.assertEquals(artifactId, dto.getArtifactId());
+        Assertions.assertEquals("Empty API", dto.getName());
+        Assertions.assertEquals("An example API design using OpenAPI.", dto.getDescription());
+        Assertions.assertNull(dto.getLabels());
+        Assertions.assertEquals("1", dto.getVersion());
+
+        String newName = "Updated Name";
+        String newDescription = "Updated description.";
+        Map<String, String> newLabels = new HashMap<>();
+        newLabels.put("foo", "bar");
+        newLabels.put("ting", "bin");
+        EditableVersionMetaDataDto emd = new EditableVersionMetaDataDto(newName, newDescription, newLabels);
+        storage().updateArtifactVersionMetaData(GROUP_ID, artifactId, "1", emd);
+
+        ArtifactVersionMetaDataDto metaData = storage().getArtifactVersionMetaData(GROUP_ID, artifactId, "1");
+        Assertions.assertNotNull(metaData);
+        Assertions.assertEquals(newName, metaData.getName());
+        Assertions.assertEquals(newDescription, metaData.getDescription());
+    }
+
+    @Test
+    public void testDeleteArtifact() throws Exception {
+        String artifactId = "testDeleteArtifact-1";
+        ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+        EditableVersionMetaDataDto versionMetaDataDto = EditableVersionMetaDataDto.builder().name("Empty API")
+                .description("An example API design using OpenAPI.").build();
+        ArtifactVersionMetaDataDto dto = storage().createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI,
+                null, null, ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                        .content(content).build(),
+                versionMetaDataDto, Collections.emptyList(), false, false).getValue();
+        Assertions.assertNotNull(dto);
+        Assertions.assertEquals(GROUP_ID, dto.getGroupId());
+        Assertions.assertEquals(artifactId, dto.getArtifactId());
+        Assertions.assertEquals("Empty API", dto.getName());
+        Assertions.assertEquals("An example API design using OpenAPI.", dto.getDescription());
+        Assertions.assertNull(dto.getLabels());
+        Assertions.assertEquals("1", dto.getVersion());
+
+        storage().getArtifactVersionContent(GROUP_ID, artifactId, "1");
+
+        storage().deleteArtifact(GROUP_ID, artifactId);
+
+        Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
+            storage().getArtifactVersionContent(GROUP_ID, artifactId, "1");
+        });
+        Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
+            storage().getArtifactMetaData(GROUP_ID, artifactId);
+        });
+        Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
+            storage().getArtifactVersionContent(GROUP_ID, artifactId, "1");
+        });
+        Assertions.assertThrows(VersionNotFoundException.class, () -> {
+            storage().getArtifactVersionMetaData(GROUP_ID, artifactId, "1");
+        });
+    }
+
+    @Test
+    public void testDeleteArtifactVersion() throws Exception {
+        // Delete the only version
+        ////////////////////////////
+        String artifactId = "testDeleteArtifactVersion-1";
+        ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+        ArtifactVersionMetaDataDto dto = storage()
+                .createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI, null, null,
+                        ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                .content(content).build(),
+                        null, Collections.emptyList(), false, false)
+                .getValue();
+        Assertions.assertNotNull(dto);
+        Assertions.assertEquals("1", dto.getVersion());
+
+        storage().deleteArtifactVersion(GROUP_ID, artifactId, "1");
+
+        final String aid1 = artifactId;
+        Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
+            storage().getArtifactVersionContent(GROUP_ID, aid1, "1");
+        });
+
+        Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
+            storage().getArtifactVersionContent(GROUP_ID, aid1, "1");
+        });
+        Assertions.assertThrows(VersionNotFoundException.class, () -> {
+            storage().getArtifactVersionMetaData(GROUP_ID, aid1, "1");
+        });
+
+        // Delete one of multiple versions
+        artifactId = "testDeleteArtifactVersion-2";
+        content = ContentHandle.create(OPENAPI_CONTENT);
+        dto = storage()
+                .createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI, null, null,
+                        ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                .content(content).build(),
+                        null, Collections.emptyList(), false, false)
+                .getValue();
+        Assertions.assertNotNull(dto);
+        Assertions.assertEquals("1", dto.getVersion());
+
+        ContentHandle contentv2 = ContentHandle.create(OPENAPI_CONTENT_V2);
+        ArtifactVersionMetaDataDto dtov2 = storage().createArtifactVersion(
+                GROUP_ID, artifactId, null, ArtifactType.OPENAPI, ContentWrapperDto.builder()
+                        .contentType(ContentTypes.APPLICATION_JSON).content(contentv2).build(),
+                null, Collections.emptyList(), false, false);
+        Assertions.assertNotNull(dtov2);
+        Assertions.assertEquals("2", dtov2.getVersion());
+
+        storage().deleteArtifactVersion(GROUP_ID, artifactId, "1");
+
+        final String aid2 = artifactId;
+
+        storage().getArtifactMetaData(GROUP_ID, aid2);
+        storage().getArtifactVersionContent(GROUP_ID, aid2, "2");
+        storage().getArtifactVersionMetaData(GROUP_ID, aid2, "2");
+        Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
+            storage().getArtifactVersionContent(GROUP_ID, aid2, "1");
+        });
+        Assertions.assertThrows(VersionNotFoundException.class, () -> {
+            storage().getArtifactVersionMetaData(GROUP_ID, aid2, "1");
+        });
+
+        ArtifactVersionMetaDataDto dtov3 = storage().createArtifactVersion(
+                GROUP_ID, artifactId, null, ArtifactType.OPENAPI, ContentWrapperDto.builder()
+                        .contentType(ContentTypes.APPLICATION_JSON).content(content).build(),
+                null, Collections.emptyList(), false, false);
+        Assertions.assertNotNull(dtov3);
+        Assertions.assertEquals("3", dtov3.getVersion());
+
+        // Update version 2 to DISABLED state and delete latest version
+        updateVersionState(GROUP_ID, artifactId, "2", VersionState.DISABLED);
+        storage().deleteArtifactVersion(GROUP_ID, artifactId, "3");
+
+        GAV latestGAV = storage().getBranchTip(new GA(GROUP_ID, artifactId), BranchId.LATEST,
+                RetrievalBehavior.ALL_STATES);
+        ArtifactVersionMetaDataDto artifactMetaData = storage().getArtifactVersionMetaData(GROUP_ID, aid2,
+                latestGAV.getRawVersionId());
+        Assertions.assertNotNull(artifactMetaData);
+        Assertions.assertEquals("2", artifactMetaData.getVersion());
+        Assertions.assertEquals(aid2, artifactMetaData.getArtifactId());
+
+        // Delete the latest version
+        artifactId = "testDeleteArtifactVersion-3";
+        content = ContentHandle.create(OPENAPI_CONTENT);
+        dto = storage()
+                .createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI, null, null,
+                        ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                .content(contentv2).build(),
+                        null, Collections.emptyList(), false, false)
+                .getValue();
+
+        Assertions.assertNotNull(dto);
+        Assertions.assertEquals("1", dto.getVersion());
+
+        contentv2 = ContentHandle.create(OPENAPI_CONTENT_V2);
+        dtov2 = storage().createArtifactVersion(
+                GROUP_ID, artifactId, null, ArtifactType.OPENAPI, ContentWrapperDto.builder()
+                        .contentType(ContentTypes.APPLICATION_JSON).content(contentv2).build(),
+                null, Collections.emptyList(), false, false);
+        Assertions.assertNotNull(dtov2);
+
+        final String aid3 = artifactId;
+        storage().deleteArtifactVersion(GROUP_ID, aid3, "2");
+        List<String> versions = storage().getArtifactVersions(GROUP_ID, aid3);
+        Assertions.assertNotNull(versions);
+        Assertions.assertFalse(versions.isEmpty());
+        Assertions.assertEquals(1, versions.size());
+        Assertions.assertEquals("1", versions.iterator().next());
+
+        VersionSearchResultsDto result = storage().searchVersions(
+                Set.of(SearchFilter.ofGroupId(GROUP_ID), SearchFilter.ofArtifactId(aid3)), OrderBy.groupId,
+                OrderDirection.asc, 0, 10);
+        Assertions.assertNotNull(result);
+        Assertions.assertEquals(1, result.getCount());
+        Assertions.assertEquals("1", result.getVersions().iterator().next().getVersion());
+
+        artifactMetaData = storage().getArtifactVersionMetaData(GROUP_ID, aid3, "1");
+        Assertions.assertNotNull(artifactMetaData);
+        Assertions.assertEquals("1", artifactMetaData.getVersion());
+        Assertions.assertEquals(aid3, artifactMetaData.getArtifactId());
+
+        storage().getArtifactVersionContent(GROUP_ID, aid3, "1");
+        ArtifactVersionMetaDataDto metaData = storage().getArtifactVersionMetaData(GROUP_ID, aid3, "1");
+        Assertions.assertNotNull(metaData);
+        Assertions.assertEquals("1", metaData.getVersion());
+        Assertions.assertThrows(ArtifactNotFoundException.class, () -> {
+            storage().getArtifactVersionContent(GROUP_ID, aid3, "2");
+        });
+        Assertions.assertThrows(VersionNotFoundException.class, () -> {
+            storage().getArtifactVersionMetaData(GROUP_ID, aid3, "2");
+        });
+    }
+
+    @Test
+    public void testCreateArtifactRule() throws Exception {
+        String artifactId = "testCreateArtifactRule-1";
+        ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+        ArtifactVersionMetaDataDto dto = storage()
+                .createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI, null, null,
+                        ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                .content(content).build(),
+                        null, Collections.emptyList(), false, false)
+                .getValue();
+        Assertions.assertNotNull(dto);
+        Assertions.assertEquals(GROUP_ID, dto.getGroupId());
+        Assertions.assertEquals(artifactId, dto.getArtifactId());
+
+        List<RuleType> artifactRules = storage().getArtifactRules(GROUP_ID, artifactId);
+        Assertions.assertNotNull(artifactRules);
+        Assertions.assertTrue(artifactRules.isEmpty());
+
+        RuleConfigurationDto configDto = new RuleConfigurationDto("FULL");
+        storage().createArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY, configDto);
+
+        artifactRules = storage().getArtifactRules(GROUP_ID, artifactId);
+        Assertions.assertNotNull(artifactRules);
+        Assertions.assertFalse(artifactRules.isEmpty());
+        Assertions.assertEquals(1, artifactRules.size());
+        Assertions.assertEquals(RuleType.VALIDITY, artifactRules.get(0));
+    }
+
+    @Test
+    public void testUpdateArtifactRule() throws Exception {
+        String artifactId = "testUpdateArtifactRule-1";
+        ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+        ArtifactVersionMetaDataDto dto = storage()
+                .createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI, null, null,
+                        ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                .content(content).build(),
+                        null, Collections.emptyList(), false, false)
+                .getValue();
+        Assertions.assertNotNull(dto);
+        Assertions.assertEquals(GROUP_ID, dto.getGroupId());
+        Assertions.assertEquals(artifactId, dto.getArtifactId());
+
+        RuleConfigurationDto configDto = new RuleConfigurationDto("FULL");
+        storage().createArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY, configDto);
+
+        RuleConfigurationDto rule = storage().getArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY);
+        Assertions.assertNotNull(rule);
+        Assertions.assertEquals("FULL", rule.getConfiguration());
+
+        RuleConfigurationDto updatedConfig = new RuleConfigurationDto("NONE");
+        storage().updateArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY, updatedConfig);
+
+        rule = storage().getArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY);
+        Assertions.assertNotNull(rule);
+        Assertions.assertEquals("NONE", rule.getConfiguration());
+    }
+
+    @Test
+    public void testDeleteArtifactRule() throws Exception {
+        String artifactId = "testDeleteArtifactRule-1";
+        ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+        ArtifactVersionMetaDataDto dto = storage()
+                .createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI, null, null,
+                        ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                .content(content).build(),
+                        null, Collections.emptyList(), false, false)
+                .getValue();
+        Assertions.assertNotNull(dto);
+        Assertions.assertEquals(GROUP_ID, dto.getGroupId());
+        Assertions.assertEquals(artifactId, dto.getArtifactId());
+
+        RuleConfigurationDto configDto = new RuleConfigurationDto("FULL");
+        storage().createArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY, configDto);
+
+        RuleConfigurationDto rule = storage().getArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY);
+        Assertions.assertNotNull(rule);
+        Assertions.assertEquals("FULL", rule.getConfiguration());
+
+        storage().deleteArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY);
+
+        Assertions.assertThrows(RuleNotFoundException.class, () -> {
+            storage().getArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY);
+        });
+    }
+
+    @Test
+    public void testDeleteAllArtifactRules() throws Exception {
+        String artifactId = "testDeleteAllArtifactRulse-1";
+        ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+        ArtifactVersionMetaDataDto dto = storage()
+                .createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI, null, null,
+                        ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                .content(content).build(),
+                        null, Collections.emptyList(), false, false)
+                .getValue();
+        Assertions.assertNotNull(dto);
+        Assertions.assertEquals(GROUP_ID, dto.getGroupId());
+        Assertions.assertEquals(artifactId, dto.getArtifactId());
+
+        RuleConfigurationDto configDto = new RuleConfigurationDto("FULL");
+        storage().createArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY, configDto);
+        storage().createArtifactRule(GROUP_ID, artifactId, RuleType.COMPATIBILITY, configDto);
+
+        List<RuleType> rules = storage().getArtifactRules(GROUP_ID, artifactId);
+        Assertions.assertEquals(2, rules.size());
+
+        storage().deleteArtifactRules(GROUP_ID, artifactId);
+
+        Assertions.assertThrows(RuleNotFoundException.class, () -> {
+            storage().getArtifactRule(GROUP_ID, artifactId, RuleType.VALIDITY);
+        });
+        Assertions.assertThrows(RuleNotFoundException.class, () -> {
+            storage().getArtifactRule(GROUP_ID, artifactId, RuleType.COMPATIBILITY);
+        });
+    }
+
+    @Test
+    public void testGlobalRules() {
+        List<RuleType> globalRules = storage().getGlobalRules();
+        Assertions.assertNotNull(globalRules);
+        Assertions.assertTrue(globalRules.isEmpty());
+
+        RuleConfigurationDto config = new RuleConfigurationDto();
+        config.setConfiguration("FULL");
+        storage().createGlobalRule(RuleType.COMPATIBILITY, config);
+
+        RuleConfigurationDto rule = storage().getGlobalRule(RuleType.COMPATIBILITY);
+        Assertions.assertEquals(rule.getConfiguration(), config.getConfiguration());
+
+        globalRules = storage().getGlobalRules();
+        Assertions.assertNotNull(globalRules);
+        Assertions.assertFalse(globalRules.isEmpty());
+        Assertions.assertEquals(globalRules.size(), 1);
+        Assertions.assertEquals(globalRules.get(0), RuleType.COMPATIBILITY);
+
+        Assertions.assertThrows(RuleAlreadyExistsException.class, () -> {
+            storage().createGlobalRule(RuleType.COMPATIBILITY, config);
+        });
+
+        RuleConfigurationDto updatedConfig = new RuleConfigurationDto("FORWARD");
+        storage().updateGlobalRule(RuleType.COMPATIBILITY, updatedConfig);
+
+        rule = storage().getGlobalRule(RuleType.COMPATIBILITY);
+        Assertions.assertEquals(rule.getConfiguration(), updatedConfig.getConfiguration());
+
+        Assertions.assertThrows(RuleNotFoundException.class, () -> {
+            storage().updateGlobalRule(RuleType.VALIDITY, config);
+        });
+
+        storage().deleteGlobalRules();
+        globalRules = storage().getGlobalRules();
+        Assertions.assertNotNull(globalRules);
+        Assertions.assertTrue(globalRules.isEmpty());
+
+        storage().createGlobalRule(RuleType.COMPATIBILITY, config);
+        storage().deleteGlobalRule(RuleType.COMPATIBILITY);
+        globalRules = storage().getGlobalRules();
+        Assertions.assertNotNull(globalRules);
+        Assertions.assertTrue(globalRules.isEmpty());
+    }
+
+    @Test
+    public void testSearchGroups() throws Exception {
+        String groupIdPrefix = "testSearchGroups-";
+        for (int idx = 1; idx <= 50; idx++) {
+            String idxs = (idx < 10 ? "0" : "") + idx;
+            String groupId = groupIdPrefix + idxs;
+            Map<String, String> labels = Collections.singletonMap("key", "value-" + idx);
+
+            GroupMetaDataDto groupMetaDataDto = GroupMetaDataDto.builder()
+                    .description(groupId + "-description").groupId(groupId).labels(labels).build();
+
+            storage().createGroup(groupMetaDataDto);
+        }
+
+        long start = System.currentTimeMillis();
+
+        Set<SearchFilter> filters = Collections.emptySet();
+        GroupSearchResultsDto results = storage().searchGroups(filters, OrderBy.groupId, OrderDirection.asc,
+                0, 10);
+        Assertions.assertNotNull(results);
+        Assertions.assertEquals(51, results.getCount());
+        Assertions.assertNotNull(results.getGroups());
+        Assertions.assertEquals(10, results.getGroups().size());
+
+        filters = Collections.singleton(SearchFilter.ofDescription("testSearchGroups-33-description"));
+        results = storage().searchGroups(filters, OrderBy.groupId, OrderDirection.asc, 0, 10);
+        Assertions.assertNotNull(results);
+        Assertions.assertEquals(1, results.getCount());
+        Assertions.assertNotNull(results.getGroups());
+        Assertions.assertEquals(1, results.getGroups().size());
+
+        filters = Collections.emptySet();
+        results = storage().searchGroups(filters, OrderBy.groupId, OrderDirection.asc, 0, 10);
+        Assertions.assertNotNull(results);
+        Assertions.assertNotNull(results.getGroups());
+        Assertions.assertEquals(10, results.getGroups().size());
+
+        filters = Collections.singleton(SearchFilter.ofLabel("key", "value-17"));
+        results = storage().searchGroups(filters, OrderBy.groupId, OrderDirection.asc, 0, 10);
+        Assertions.assertNotNull(results);
+        Assertions.assertEquals(1, results.getCount());
+        Assertions.assertNotNull(results.getGroups());
+        Assertions.assertEquals(1, results.getGroups().size());
+
+        long end = System.currentTimeMillis();
+        System.out.println("Search time: " + (end - start) + "ms");
+    }
+
+    @Test
+    public void testSearchArtifacts() throws Exception {
+        String artifactIdPrefix = "testSearchArtifacts-";
+        for (int idx = 1; idx <= 50; idx++) {
+            String idxs = (idx < 10 ? "0" : "") + idx;
+            String artifactId = artifactIdPrefix + idxs;
+            ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+            Map<String, String> labels = Collections.singletonMap("key", "value-" + idx);
+            EditableArtifactMetaDataDto metaData = new EditableArtifactMetaDataDto(artifactId + "-name",
+                    artifactId + "-description", null, labels);
+            storage()
+                    .createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI, metaData, null,
+                            ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                    .content(content).build(),
+                            null, Collections.emptyList(), false, false)
+                    .getValue();
+
+        }
+
+        long start = System.currentTimeMillis();
+
+        Set<SearchFilter> filters = Collections.singleton(SearchFilter.ofName("testSearchArtifacts"));
+        ArtifactSearchResultsDto results = storage().searchArtifacts(filters, OrderBy.name,
+                OrderDirection.asc, 0, 10);
+        Assertions.assertNotNull(results);
+        Assertions.assertEquals(50, results.getCount());
+        Assertions.assertNotNull(results.getArtifacts());
+        Assertions.assertEquals(10, results.getArtifacts().size());
+
+        filters = Collections.singleton(SearchFilter.ofName("testSearchArtifacts-19-name"));
+        results = storage().searchArtifacts(filters, OrderBy.name, OrderDirection.asc, 0, 10);
+        Assertions.assertNotNull(results);
+        Assertions.assertEquals(1, results.getCount());
+        Assertions.assertNotNull(results.getArtifacts());
+        Assertions.assertEquals(1, results.getArtifacts().size());
+        Assertions.assertEquals("testSearchArtifacts-19-name", results.getArtifacts().get(0).getName());
+
+        filters = Collections.singleton(SearchFilter.ofDescription("testSearchArtifacts-33-description"));
+        results = storage().searchArtifacts(filters, OrderBy.name, OrderDirection.asc, 0, 10);
+        Assertions.assertNotNull(results);
+        Assertions.assertEquals(1, results.getCount());
+        Assertions.assertNotNull(results.getArtifacts());
+        Assertions.assertEquals(1, results.getArtifacts().size());
+        Assertions.assertEquals("testSearchArtifacts-33-name", results.getArtifacts().get(0).getName());
+
+        filters = Collections.emptySet();
+        results = storage().searchArtifacts(filters, OrderBy.name, OrderDirection.asc, 0, 10);
+        Assertions.assertNotNull(results);
+        Assertions.assertNotNull(results.getArtifacts());
+        Assertions.assertEquals(10, results.getArtifacts().size());
+
+        filters = Collections.singleton(SearchFilter.ofLabel("key", "value-17"));
+        results = storage().searchArtifacts(filters, OrderBy.name, OrderDirection.asc, 0, 10);
+        Assertions.assertNotNull(results);
+        Assertions.assertEquals(1, results.getCount());
+        Assertions.assertNotNull(results.getArtifacts());
+        Assertions.assertEquals(1, results.getArtifacts().size());
+        Assertions.assertEquals("testSearchArtifacts-17-name", results.getArtifacts().get(0).getName());
+
+        long end = System.currentTimeMillis();
+        System.out.println("Search time: " + (end - start) + "ms");
+    }
+
+    @Test
+    public void testSearchVersions() throws Exception {
+        String artifactId = "testSearchVersions-1";
+        ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+        ArtifactVersionMetaDataDto dto = storage()
+                .createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI, null, null,
+                        ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                .content(content).build(),
+                        null, Collections.emptyList(), false, false)
+                .getValue();
+        Assertions.assertNotNull(dto);
+        Assertions.assertEquals(GROUP_ID, dto.getGroupId());
+        Assertions.assertEquals(artifactId, dto.getArtifactId());
+
+        // Add more versions
+        for (int idx = 2; idx <= 50; idx++) {
+            content = ContentHandle.create(OPENAPI_CONTENT_TEMPLATE.replaceAll("VERSION", "1.0." + idx));
+            EditableVersionMetaDataDto metaData = new EditableVersionMetaDataDto(artifactId + "-name-" + idx,
+                    artifactId + "-description-" + idx, null);
+            storage().createArtifactVersion(
+                    GROUP_ID, artifactId, null, ArtifactType.OPENAPI, ContentWrapperDto.builder()
+                            .contentType(ContentTypes.APPLICATION_JSON).content(content).build(),
+                    metaData, Collections.emptyList(), false, false);
+
+        }
+
+        TestUtils.retry(() -> {
+            VersionSearchResultsDto results = storage().searchVersions(
+                    Set.of(SearchFilter.ofGroupId(GROUP_ID), SearchFilter.ofArtifactId(artifactId)),
+                    OrderBy.groupId, OrderDirection.asc, 0, 10);
+            Assertions.assertNotNull(results);
+            Assertions.assertEquals(50, results.getCount());
+            Assertions.assertEquals(10, results.getVersions().size());
+
+            results = storage().searchVersions(
+                    Set.of(SearchFilter.ofGroupId(GROUP_ID), SearchFilter.ofArtifactId(artifactId)),
+                    OrderBy.groupId, OrderDirection.asc, 0, 50);
+            Assertions.assertNotNull(results);
+            Assertions.assertEquals(50, results.getCount());
+            Assertions.assertEquals(50, results.getVersions().size());
+        });
+    }
+
+    private void createSomeUserData() {
+        final String group1 = "testGroup-1";
+        final String group2 = "testGroup-2";
+        final String artifactId1 = "testArtifact-1";
+        final String artifactId2 = "testArtifact-2";
+        final String principal = "testPrincipal";
+        final String role = "testRole";
+
+        ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+        storage().createGroup(GroupMetaDataDto.builder().groupId(group1).build());
+        ArtifactVersionMetaDataDto artifactDto1 = storage()
+                .createArtifact(group1, artifactId1, ArtifactType.OPENAPI, null, null,
+                        ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                .contentType(ContentTypes.APPLICATION_JSON).content(content).build(),
+                        null, Collections.emptyList(), false, false)
+                .getValue();
+        storage().createArtifactRule(group1, artifactId1, RuleType.VALIDITY,
+                RuleConfigurationDto.builder().configuration("FULL").build());
+        ArtifactVersionMetaDataDto artifactDto2 = storage()
+                .createArtifact(group2, artifactId2, ArtifactType.OPENAPI,
+                        EditableArtifactMetaDataDto.builder().name("test").build(), null,
+                        ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                .content(content).build(),
+                        null, Collections.emptyList(), false, false)
+                .getValue();
+
+        storage().createGlobalRule(RuleType.VALIDITY,
+                RuleConfigurationDto.builder().configuration("FULL").build());
+        storage().createRoleMapping(principal, role, null);
+
+        // Verify data exists
+
+        Assertions.assertNotNull(
+                storage().getArtifactVersionContent(group1, artifactId1, artifactDto1.getVersion()));
+        Assertions.assertEquals(1, storage().getArtifactRules(group1, artifactId1).size());
+        Assertions.assertNotNull(
+                storage().getArtifactVersionContent(group2, artifactId2, artifactDto2.getVersion()));
+        Assertions.assertEquals(1, storage().getGlobalRules().size());
+        Assertions.assertEquals(role, storage().getRoleForPrincipal(principal));
+    }
+
+    private int countStorageEntities() {
+        // We don't need thread safety, but it's simpler to use this when effectively final counter is needed
+        final AtomicInteger count = new AtomicInteger(0);
+        storage().exportData(e -> {
+            if (e.getEntityType() != EntityType.Manifest) {
+                log.debug("Counting from export: {}", e);
+                count.incrementAndGet();
+            }
+            return null;
+        });
+        int res = count.get();
+        // Count data that is not exported
+        res += storage().getRoleMappings().size();
+        return res;
+    }
+
+    @Test
+    public void testDeleteAllUserData() {
+        // Delete first to cleanup after other tests
+        storage().deleteAllUserData();
+        createSomeUserData();
+        Assertions.assertEquals(12, countStorageEntities());
+        storage().deleteAllUserData();
+        Assertions.assertEquals(0, countStorageEntities());
+    }
+
+    @Test
+    public void testConfigProperties() throws Exception {
+        List<DynamicConfigPropertyDto> properties = storage().getConfigProperties();
+        Assertions.assertNotNull(properties);
+        Assertions.assertTrue(properties.isEmpty());
+
+        storage().setConfigProperty(
+                new DynamicConfigPropertyDto("apicurio.test.property-string", "test-value"));
+        storage().setConfigProperty(new DynamicConfigPropertyDto("apicurio.test.property-boolean", "true"));
+        storage().setConfigProperty(new DynamicConfigPropertyDto("apicurio.test.property-long", "12345"));
+
+        properties = storage().getConfigProperties();
+        Assertions.assertNotNull(properties);
+        Assertions.assertFalse(properties.isEmpty());
+        Assertions.assertEquals(3, properties.size());
+
+        DynamicConfigPropertyDto stringProp = getProperty(properties, "apicurio.test.property-string");
+        DynamicConfigPropertyDto boolProp = getProperty(properties, "apicurio.test.property-boolean");
+        DynamicConfigPropertyDto longProp = getProperty(properties, "apicurio.test.property-long");
+
+        Assertions.assertNotNull(stringProp);
+        Assertions.assertNotNull(boolProp);
+        Assertions.assertNotNull(longProp);
+
+        Assertions.assertEquals("test-value", stringProp.getValue());
+        Assertions.assertEquals("true", boolProp.getValue());
+        Assertions.assertEquals("12345", longProp.getValue());
+    }
+
+    private DynamicConfigPropertyDto getProperty(List<DynamicConfigPropertyDto> properties,
+            String propertyName) {
+        for (DynamicConfigPropertyDto prop : properties) {
+            if (prop.getName().equals(propertyName)) {
+                return prop;
+            }
+        }
+        return null;
+    }
+
+    @Test
+    public void testComments() {
+        String artifactId = "testComments-1";
+        ContentHandle content = ContentHandle.create(OPENAPI_CONTENT);
+        ArtifactVersionMetaDataDto dto = storage()
+                .createArtifact(GROUP_ID, artifactId, ArtifactType.OPENAPI, null, null,
+                        ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                .content(content).build(),
+                        null, Collections.emptyList(), false, false)
+                .getValue();
+        Assertions.assertNotNull(dto);
+        Assertions.assertEquals(GROUP_ID, dto.getGroupId());
+        Assertions.assertEquals(artifactId, dto.getArtifactId());
+
+        List<CommentDto> comments = storage().getArtifactVersionComments(GROUP_ID, artifactId,
+                dto.getVersion());
+        Assertions.assertTrue(comments.isEmpty());
+
+        storage().createArtifactVersionComment(GROUP_ID, artifactId, dto.getVersion(), "TEST_COMMENT_1");
+        storage().createArtifactVersionComment(GROUP_ID, artifactId, dto.getVersion(), "TEST_COMMENT_2");
+        storage().createArtifactVersionComment(GROUP_ID, artifactId, dto.getVersion(), "TEST_COMMENT_3");
+
+        comments = storage().getArtifactVersionComments(GROUP_ID, artifactId, dto.getVersion());
+        Assertions.assertEquals(3, comments.size());
+
+        storage().deleteArtifactVersionComment(GROUP_ID, artifactId, dto.getVersion(),
+                comments.get(1).getCommentId());
+
+        comments = storage().getArtifactVersionComments(GROUP_ID, artifactId, dto.getVersion());
+        Assertions.assertEquals(2, comments.size());
+
+        storage().updateArtifactVersionComment(GROUP_ID, artifactId, dto.getVersion(),
+                comments.get(0).getCommentId(), "TEST_COMMENT_4");
+
+        comments = storage().getArtifactVersionComments(GROUP_ID, artifactId, dto.getVersion());
+        Assertions.assertEquals(2, comments.size());
+        Assertions.assertEquals("TEST_COMMENT_4", comments.get(0).getValue());
+    }
+
+    @Test
+    public void testBranches() {
+
+        var ga = new GA(GROUP_ID, "foo");
+
+        Assertions.assertThrows(ArtifactNotFoundException.class, () -> storage().getBranches(ga, 0, 100));
+
+        var content = ContentHandle.create(OPENAPI_CONTENT);
+        ArtifactVersionMetaDataDto dtoV1 = storage()
+                .createArtifact(GROUP_ID, ga.getRawArtifactId(), ArtifactType.OPENAPI, null, null,
+                        ContentWrapperDto.builder().contentType(ContentTypes.APPLICATION_JSON)
+                                .content(content).build(),
+                        null, Collections.emptyList(), false, false)
+                .getValue();
+
+        Assertions.assertNotNull(dtoV1);
+        Assertions.assertEquals(ga.getRawGroupIdWithDefaultString(), dtoV1.getGroupId());
+        Assertions.assertEquals(ga.getRawArtifactId(), dtoV1.getArtifactId());
+
+        var branches = storage().getBranches(ga, 0, 100);
+        SearchedBranchDto branch = branches.getBranches().get(0);
+        Assertions.assertEquals(BranchId.LATEST.getRawBranchId(), branch.getBranchId());
+        Assertions.assertEquals(ga.getRawGroupIdWithDefaultString(), branch.getGroupId());
+        Assertions.assertEquals(ga.getRawArtifactId(), branch.getArtifactId());
+
+        var latestBranch = storage().getBranchTip(ga, BranchId.LATEST, RetrievalBehavior.ALL_STATES);
+        Assertions.assertEquals(new GAV(ga, dtoV1.getVersion()), latestBranch);
+
+        var gavV1 = storage().getBranchTip(ga, BranchId.LATEST, RetrievalBehavior.ALL_STATES);
+        Assertions.assertNotNull(gavV1);
+        Assertions.assertEquals(gavV1.getRawGroupIdWithDefaultString(), dtoV1.getGroupId());
+        Assertions.assertEquals(gavV1.getRawArtifactId(), dtoV1.getArtifactId());
+        Assertions.assertEquals(gavV1.getRawVersionId(), dtoV1.getVersion());
+
+        var otherBranchId = new BranchId("other");
+        storage().createBranch(gavV1, otherBranchId, "", Collections.emptyList());
+
+        content = ContentHandle.create(OPENAPI_CONTENT_V2);
+        var dtoV2 = storage().createArtifactVersion(ga.getRawGroupIdWithDefaultString(),
+                ga.getRawArtifactId(), null, ArtifactType.OPENAPI, ContentWrapperDto.builder()
+                        .contentType(ContentTypes.APPLICATION_JSON).content(content).build(),
+                null, Collections.emptyList(), false, false);
+        Assertions.assertNotNull(dtoV2);
+        Assertions.assertEquals(ga.getRawGroupIdWithDefaultString(), dtoV2.getGroupId());
+        Assertions.assertEquals(ga.getRawArtifactId(), dtoV2.getArtifactId());
+        // TODO update branches test
+        /*
+         * branches = storage().getBranches(ga, 0, 100);
+         * Assertions.assertTrue(branches.getBranches().containsAll(List.of(SearchedBranchDto.builder().
+         * branchId(BranchId.LATEST).build(), SearchedBranchDto.builder().build(),
+         * SearchedBranchDto.builder().build())));
+         * 
+         * Map.of( BranchId.LATEST, List.of(new GAV(ga, dtoV2.getVersion()), new GAV(ga, dtoV1.getVersion())),
+         * otherBranchId, List.of(new GAV(ga, dtoV1.getVersion())) ), branches);
+         * 
+         * latestBranch = storage().getBranchTip(ga, BranchId.LATEST, RetrievalBehavior.ALL_STATES);
+         * Assertions.assertEquals(List.of(new GAV(ga, dtoV2.getVersion()), new GAV(ga, dtoV1.getVersion())),
+         * latestBranch);
+         * 
+         * var otherBranch = storage().getBranchTip(ga, otherBranchId, RetrievalBehavior.ALL_STATES);
+         * Assertions.assertEquals(List.of(new GAV(ga, dtoV1.getVersion())), otherBranch);
+         * 
+         * var gavV2 = storage().getBranchTip(ga, BranchId.LATEST, RetrievalBehavior.ALL_STATES);
+         * Assertions.assertNotNull(gavV2); Assertions.assertEquals(gavV2.getRawGroupIdWithDefaultString(),
+         * dtoV2.getGroupId()); Assertions.assertEquals(gavV2.getRawArtifactId(), dtoV2.getArtifactId());
+         * Assertions.assertEquals(gavV2.getRawVersionId(), dtoV2.getVersion());
+         * 
+         * gavV1 = storage().getBranchTip(ga, otherBranchId, RetrievalBehavior.ALL_STATES);
+         * Assertions.assertNotNull(gavV1); Assertions.assertEquals(gavV1.getRawGroupIdWithDefaultString(),
+         * dtoV1.getGroupId()); Assertions.assertEquals(gavV1.getRawArtifactId(), dtoV1.getArtifactId());
+         * Assertions.assertEquals(gavV1.getRawVersionId(), dtoV1.getVersion());
+         * 
+         * storage().createBranch(gavV2, otherBranchId, "", Collections.emptyList());
+         * 
+         * branches = storage().getBranches(ga, 0, 100); Assertions.assertEquals(Map.of( BranchId.LATEST,
+         * List.of(new GAV(ga, dtoV2.getVersion()), new GAV(ga, dtoV1.getVersion())), otherBranchId,
+         * List.of(new GAV(ga, dtoV2.getVersion()), new GAV(ga, dtoV1.getVersion())) ), branches);
+         * 
+         * Assertions.assertEquals(storage().getBranchTip(ga, BranchId.LATEST, RetrievalBehavior.ALL_STATES),
+         * storage().getBranchTip(ga, otherBranchId, RetrievalBehavior.ALL_STATES));
+         * Assertions.assertEquals(storage().getBranchTip(ga, BranchId.LATEST, RetrievalBehavior.ALL_STATES),
+         * storage().getBranchTip(ga, otherBranchId, RetrievalBehavior.ALL_STATES));
+         * 
+         * updateVersionState(gavV2.getRawGroupIdWithDefaultString(), gavV2.getRawArtifactId(),
+         * gavV2.getRawVersionId(), VersionState.DISABLED); Assertions.assertEquals(List.of(gavV1),
+         * storage().getBranchTip(ga, BranchId.LATEST, SKIP_DISABLED_LATEST)); Assertions.assertEquals(gavV1,
+         * storage().getBranchTip(ga, BranchId.LATEST, SKIP_DISABLED_LATEST));
+         * 
+         * updateVersionState(gavV2.getRawGroupIdWithDefaultString(), gavV2.getRawArtifactId(),
+         * gavV2.getRawVersionId(), VersionState.ENABLED); Assertions.assertEquals(List.of(gavV2, gavV1),
+         * storage().getBranchTip(ga, BranchId.LATEST, SKIP_DISABLED_LATEST)); Assertions.assertEquals(gavV2,
+         * storage().getBranchTip(ga, BranchId.LATEST, SKIP_DISABLED_LATEST));
+         * 
+         * storage().deleteArtifactVersion(gavV1.getRawGroupIdWithDefaultString(), gavV1.getRawArtifactId(),
+         * gavV1.getRawVersionId());
+         * 
+         * Assertions.assertEquals(List.of(gavV2), storage().getBranchTip(ga, BranchId.LATEST,
+         * RetrievalBehavior.ALL_STATES)); Assertions.assertEquals(List.of(gavV2), storage().getBranchTip(ga,
+         * otherBranchId, RetrievalBehavior.ALL_STATES));
+         * 
+         * storage().deleteBranch(ga, otherBranchId);
+         * 
+         * Assertions.assertThrows(BranchNotFoundException.class, () -> storage().getBranchTip(ga,
+         * otherBranchId, RetrievalBehavior.ALL_STATES));
+         * Assertions.assertThrows(VersionNotFoundException.class, () -> storage().getBranchTip(ga,
+         * otherBranchId, RetrievalBehavior.ALL_STATES));
+         * 
+         * Assertions.assertThrows(NotAllowedException.class, () -> storage().deleteBranch(ga,
+         * BranchId.LATEST));
+         */
+    }
+
+    private void updateVersionState(String groupId, String artifactId, String version,
+            VersionState newState) {
+        storage().updateArtifactVersionState(groupId, artifactId, version, newState, false);
+    }
+
+    private static String generateString(int size) {
+        StringBuilder builder = new StringBuilder();
+        for (int i = 0; i < size; i++) {
+            builder.append("a");
+        }
+        Assertions.assertEquals(size, builder.toString().length());
+        return builder.toString();
+    }
 
 }
diff --git a/app/src/test/java/io/apicurio/registry/storage/impl/sql/DefaultRegistryStorageTest.java b/app/src/test/java/io/apicurio/registry/storage/impl/sql/DefaultRegistryStorageTest.java
index a76c2ad998..e60a38d36e 100644
--- a/app/src/test/java/io/apicurio/registry/storage/impl/sql/DefaultRegistryStorageTest.java
+++ b/app/src/test/java/io/apicurio/registry/storage/impl/sql/DefaultRegistryStorageTest.java
@@ -14,7 +14,7 @@ public class DefaultRegistryStorageTest extends AbstractRegistryStorageTest {
     RegistryStorage storage;
 
     /**
-     * @see io.apicurio.registry.storage.AbstractRegistryStorageTest#storage()
+     * @see AbstractRegistryStorageTest#storage()
      */
     @Override
     protected RegistryStorage storage() {