Skip to content
This repository has been archived by the owner on Mar 19, 2024. It is now read-only.

Commit

Permalink
Unify storages (#134)
Browse files Browse the repository at this point in the history
  • Loading branch information
carlesarnal authored Jan 23, 2024
1 parent 77a0150 commit 2eedaff
Show file tree
Hide file tree
Showing 35 changed files with 283 additions and 523 deletions.
17 changes: 3 additions & 14 deletions .github/workflows/verify.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ jobs:
if: github.event_name == 'push'
run: echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin

- name: Build and Publish Docker Image (Mem)
- name: Build and Publish Docker Image
if: github.event_name == 'push'
uses: docker/build-push-action@v2
with:
Expand All @@ -104,20 +104,9 @@ jobs:
platforms: ${{env.PLATFORMS}}
push: true
tags: |
docker.io/${{env.IMAGE_ORG}}/apicurio-api-designer-mem:${{env.IMAGE_TAG}}
quay.io/${{env.IMAGE_ORG}}/apicurio-api-designer-mem:${{env.IMAGE_TAG}}
docker.io/${{env.IMAGE_ORG}}/apicurio-api-designer:${{env.IMAGE_TAG}}
quay.io/${{env.IMAGE_ORG}}/apicurio-api-designer:${{env.IMAGE_TAG}}
- name: Build and Publish Docker Image (SQL)
if: github.event_name == 'push'
uses: docker/build-push-action@v2
with:
context: ./dist/docker/target/docker
file: ./dist/docker/target/docker/Dockerfile.postgresql.jvm
platforms: ${{env.PLATFORMS}}
push: true
tags: |
docker.io/${{env.IMAGE_ORG}}/apicurio-api-designer-sql:${{env.IMAGE_TAG}}
quay.io/${{env.IMAGE_ORG}}/apicurio-api-designer-sql:${{env.IMAGE_TAG}}
- name: Build and Publish Docker Image (UI)
if: github.event_name == 'push'
Expand Down
19 changes: 15 additions & 4 deletions app/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,22 +96,27 @@

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-security</artifactId>
<artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-undertow</artifactId>
<artifactId>quarkus-agroal</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-oidc</artifactId>
<artifactId>quarkus-security</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-agroal</artifactId>
<artifactId>quarkus-undertow</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-oidc</artifactId>
</dependency>

<dependency>
Expand Down Expand Up @@ -169,6 +174,12 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package io.apicurio.designer.config;

import io.quarkus.runtime.configuration.ProfileManager;
import org.eclipse.microprofile.config.spi.ConfigSource;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class DesignerConfigSource implements ConfigSource {
private Map<String, String> properties;

@Override
public synchronized Map<String, String> getProperties() {
if (properties == null) {
properties = new HashMap<>();
String prefix = System.getenv("DESIGNER_PROPERTIES_PREFIX");
if (prefix != null) {
String profile = ProfileManager.getActiveProfile();
String profilePrefix = "%" + profile + ".";
Map<String, String> envMap = System.getenv();
for (Map.Entry<String, String> entry : envMap.entrySet()) {
String key = entry.getKey();
if (key.startsWith(prefix)) {
String newKey = profilePrefix + key.replace("_", ".").toLowerCase();
properties.put(newKey, entry.getValue());
}
}
}
}
return properties;
}

@Override
public Set<String> getPropertyNames() {
return new HashSet<>(properties.values());
}

@Override
public String getValue(String key) {
return getProperties().get(key);
}

@Override
public String getName() {
return "Designer properties";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package io.apicurio.designer.storage;

import io.apicurio.common.apps.config.DynamicConfigStorage;
import io.apicurio.common.apps.config.DynamicConfigStorageAccessor;
import io.apicurio.designer.spi.storage.DesignerStorage;

import jakarta.enterprise.context.ApplicationScoped;
Expand All @@ -27,13 +26,13 @@
* @author [email protected]
*/
@ApplicationScoped
public class InMemoryDynamicConfigStorageAccessor implements DynamicConfigStorageAccessor {
public class DynamicConfigStorageAccessor implements io.apicurio.common.apps.config.DynamicConfigStorageAccessor {

@Inject
DesignerStorage designerStorage;

/**
* @see DynamicConfigStorageAccessor#getConfigStorage()
* @see io.apicurio.common.apps.config.DynamicConfigStorageAccessor#getConfigStorage()
*/
@Override
public DynamicConfigStorage getConfigStorage() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@

package io.apicurio.designer.storage.common;

import io.apicurio.common.apps.storage.exceptions.StorageException;
import io.apicurio.common.apps.storage.sql.jdbi.Handle;
import io.apicurio.designer.spi.storage.DesignerSqlStatements;
import io.apicurio.designer.spi.storage.SearchQuerySpecification;

Expand All @@ -29,13 +27,6 @@ public abstract class AbstractDesignerSqlStatements implements DesignerSqlStatem

// ==================== BaseSqlStatements ====================

@Override
public boolean isDatabaseInitialized(Handle handle) throws StorageException {
int count = handle.createQuery("SELECT COUNT(*) FROM information_schema.tables WHERE table_name = 'apicurio'")
.mapTo(Integer.class).one();
return count > 0;
}

@Override
public String getStorageProperty() {
return """
Expand Down Expand Up @@ -194,4 +185,34 @@ public SearchQuerySpecification searchDesignMetadataSpecification() {
.addOrderByColumn("modifiedOn", "m")
.addOrderByColumn("createdOn", "m");
}

@Override
public String selectConfigProperties() {
return "SELECT c.* FROM config c ";
}

@Override
public String deleteConfigProperty() {
return "DELETE FROM config WHERE pname = ?";
}

@Override
public String insertConfigProperty() {
return "INSERT INTO config (pname, pvalue, modifiedOn) VALUES (?, ?, ?)";
}

@Override
public String deleteAllConfigProperties() {
return "DELETE FROM config ";
}

@Override
public String selectConfigPropertyByName() {
return "SELECT c.* FROM config c WHERE c.pname = ?";
}

@Override
public String selectTenantIdsByConfigModifiedOn() {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
import io.apicurio.common.apps.config.DynamicConfigPropertyDto;
import io.apicurio.common.apps.config.impl.storage.DynamicConfigSqlStorageComponent;
import io.apicurio.common.apps.content.handle.ContentHandle;
import io.apicurio.common.apps.logging.LoggerProducer;
import io.apicurio.common.apps.storage.exceptions.StorageException;
import io.apicurio.common.apps.storage.exceptions.StorageExceptionMapper;
import io.apicurio.common.apps.storage.sql.BaseSqlStorageComponent;
import io.apicurio.common.apps.storage.sql.SqlStorageComponent;
import io.apicurio.common.apps.storage.sql.jdbi.HandleFactory;
import io.apicurio.designer.spi.storage.DesignerSqlStatements;
import io.apicurio.designer.spi.storage.DesignerStorage;
Expand All @@ -14,12 +15,16 @@
import io.apicurio.designer.spi.storage.model.DesignDto;
import io.apicurio.designer.spi.storage.model.DesignEventDto;
import io.apicurio.designer.spi.storage.model.DesignMetadataDto;
import org.slf4j.Logger;

import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.transaction.Transactional;
import org.slf4j.Logger;

import java.time.Instant;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

import static io.apicurio.common.apps.storage.sql.jdbi.query.Sql.RESOURCE_CONTEXT_KEY;
Expand All @@ -28,7 +33,11 @@
/**
* @author Jakub Senko <em>[email protected]</em>
*/
public abstract class AbstractSqlDesignerStorage implements DesignerStorage {
@ApplicationScoped
public class SqlDesignerStorage extends SqlStorageComponent implements DesignerStorage {

@Inject
LoggerProducer loggerProducer;

protected static String CONTENT_SEQUENCE_KEY = "content";
protected static String DESIGN_EVENT_SEQUENCE_KEY = "design_event";
Expand All @@ -37,11 +46,9 @@ public abstract class AbstractSqlDesignerStorage implements DesignerStorage {
protected HandleFactory handles;

@Inject
@Named("apicurioSqlStatements")
protected DesignerSqlStatements sqlStatements;

@Inject
protected BaseSqlStorageComponent storageEngine;

@Inject
protected DynamicConfigSqlStorageComponent dynamicConfigSqlStorageComponent;

Expand All @@ -51,12 +58,22 @@ public abstract class AbstractSqlDesignerStorage implements DesignerStorage {
@Inject
Logger log;

/**
* The overriding method MUST be annotated with:
* \@PostConstruct
* \@Transactional
*/
protected abstract void init();
@PostConstruct
@Transactional
protected void init() {
start(loggerProducer, handles, SqlStorageComponent.Configuration.builder()
.sqlStatements(sqlStatements)
.supportsAtomicSequenceIncrement(!Objects.equals(sqlStatements.dbType(), "h2"))
.ddlDirRootPath("META-INF/storage/schema")
.build());

dynamicConfigSqlStorageComponent.start(loggerProducer, handles, sqlStatements);
}

@Override
public boolean isReady() {
return true;
}

@Override
@Transactional
Expand All @@ -65,7 +82,7 @@ public DesignMetadataDto createDesign(DesignMetadataDto metadata, ContentHandle
// Create Content
// TODO Deduplication
var contentId = exceptionMapper.with(() ->
storageEngine.nextSequenceValue(CONTENT_SEQUENCE_KEY)
nextSequenceValue(CONTENT_SEQUENCE_KEY)
);
handles.withHandleNoExceptionMapped(handle ->
handle.createUpdate(sqlStatements.insertDesignContent())
Expand Down Expand Up @@ -282,7 +299,7 @@ public List<DynamicConfigPropertyDto> getConfigProperties() {
@Transactional
public DesignEventDto createDesignEvent(DesignEventDto event) {
var eventId = exceptionMapper.with(() ->
storageEngine.nextSequenceValue(DESIGN_EVENT_SEQUENCE_KEY)
nextSequenceValue(DESIGN_EVENT_SEQUENCE_KEY)
);
event.setId(String.valueOf(eventId));
event.setCreatedOn(Instant.now());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package io.apicurio.designer.storage.common;

import io.apicurio.common.apps.config.Info;
import io.apicurio.common.apps.storage.sql.SqlStatements;
import io.apicurio.designer.spi.storage.DesignerSqlStatements;
import io.apicurio.designer.storage.h2.H2DesignerSqlStatements;
import io.apicurio.designer.storage.postgresql.PostgresDesignerSqlStatements;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Produces;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.slf4j.Logger;

@ApplicationScoped
public class SqlStatementsProducer {

@Inject
Logger log;

@ConfigProperty(name = "apicurio.storage.db-kind", defaultValue = "h2")
@Info(category = "storage", description = "Datasource Db kind", availableSince = "0.1.0.Final")
String databaseType;

/**
* Produces an {@link SqlStatements} instance for injection.
*/
@Produces
@ApplicationScoped
@Named("apicurioSqlStatements")
public DesignerSqlStatements createSqlStatements() {
log.debug("Creating an instance of ISqlStatements for DB: " + databaseType);
if ("h2".equals(databaseType)) {
return new H2DesignerSqlStatements();
}
if ("postgresql".equals(databaseType)) {
return new PostgresDesignerSqlStatements();
}
throw new RuntimeException("Unsupported database type: " + databaseType);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,28 @@

package io.apicurio.designer.storage.h2;

import io.apicurio.common.apps.storage.exceptions.StorageException;
import io.apicurio.common.apps.storage.sql.jdbi.Handle;
import io.apicurio.common.apps.storage.sql.jdbi.query.Update;
import io.apicurio.common.apps.storage.sql.jdbi.query.UpdateImpl;
import io.apicurio.designer.spi.storage.DesignerSqlStatements;
import io.apicurio.designer.storage.common.AbstractDesignerSqlStatements;
import io.quarkus.arc.DefaultBean;

import java.sql.SQLException;
import jakarta.enterprise.context.ApplicationScoped;

/**
* @author [email protected]
* @author Jakub Senko <em>[email protected]</em>
*/
@ApplicationScoped
@DefaultBean
public class H2DesignerSqlStatements extends AbstractDesignerSqlStatements implements DesignerSqlStatements {

@Override
public boolean isDatabaseInitialized(Handle handle) throws StorageException {
int count = handle.createQuery("SELECT COUNT(*) AS count FROM information_schema.tables WHERE table_name = 'APICURIO'")
.mapTo(Integer.class).one();
return count > 0;
}

@Override
public String dbType() {
return "h2";
Expand Down
Loading

0 comments on commit 2eedaff

Please sign in to comment.