Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Singlestore jdbc: Quarkus native support #3

Merged
merged 16 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
eb043df
Singlestore jdbc Quarkus native support
Hemantkumar-Chigadani Oct 21, 2024
1eac025
Singlestore jdbc Quarkus native support: Revert project.yml changes
Hemantkumar-Chigadani Oct 21, 2024
824dbeb
Singlestore jdbc Quarkus native support: Reverted github workflow cha…
Hemantkumar-Chigadani Oct 21, 2024
c41ad5f
Singlestore jdbc Quarkus native support: Code review comments
Hemantkumar-Chigadani Oct 21, 2024
0aacd06
Singlestore jdbc Quarkus native support: Docker file mount permission…
Hemantkumar-Chigadani Oct 21, 2024
65b1a4d
Singlestore jdbc Quarkus native support: Code formatting
Hemantkumar-Chigadani Oct 21, 2024
1a57a78
Singlestore jdbc Quarkus native support: Instead of mount, use file c…
Hemantkumar-Chigadani Oct 21, 2024
5638065
Singlestore jdbc Quarkus native support: Code formatting
Hemantkumar-Chigadani Oct 21, 2024
640ed7f
Singlestore jdbc Quarkus native support: Code formatting
Hemantkumar-Chigadani Oct 21, 2024
39ea218
Singlestore jdbc Quarkus native support: import sorting :)
Hemantkumar-Chigadani Oct 21, 2024
72d5515
Singlestore jdbc Quarkus native support: Docker with privileged mode
Hemantkumar-Chigadani Oct 21, 2024
d1f6193
Singlestore jdbc Quarkus native support: Docker with system admin cap…
Hemantkumar-Chigadani Oct 21, 2024
6447a29
Singlestore jdbc Quarkus native support: Docker with security elevated
Hemantkumar-Chigadani Oct 21, 2024
c6b3e9b
Singlestore jdbc Quarkus native support: Docker with security elevated
Hemantkumar-Chigadani Oct 21, 2024
e4f7e20
Instead of container mount, relying on sql connections
Hemantkumar-Chigadani Oct 21, 2024
3d8d798
Icon url update, code review comment
Hemantkumar-Chigadani Oct 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 44 additions & 2 deletions deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>io.quarkiverse.jdbc-singlestore</groupId>
<groupId>io.quarkiverse.jdbc</groupId>
<artifactId>quarkus-jdbc-singlestore-parent</artifactId>
<version>999-SNAPSHOT</version>
</parent>
Expand All @@ -16,7 +16,7 @@
<artifactId>quarkus-arc-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkiverse.jdbc-singlestore</groupId>
<groupId>io.quarkiverse.jdbc</groupId>
<artifactId>quarkus-jdbc-singlestore</artifactId>
<version>${project.version}</version>
</dependency>
Expand All @@ -25,6 +25,48 @@
<artifactId>quarkus-junit5-internal</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm-deployment-spi</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-devservices-common</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-devservices-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-datasource-deployment-spi</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-agroal-spi</artifactId>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
<version>${assertj-core.version}</version>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
<version>${rest-assured.version}</version>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>${testcontainers.version}</version>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>jdbc</artifactId>
<version>${testcontainers.version}</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package io.quarkiverse.jdbc.singlestore.deployment;

import static io.quarkiverse.jdbc.singlestore.runtime.SinglestoreConstants.DB_KIND;

import io.quarkiverse.jdbc.singlestore.runtime.SinglestoreAgroalConnectionConfigurer;
import io.quarkiverse.jdbc.singlestore.runtime.SinglestoreServiceBindingConverter;
import io.quarkus.agroal.spi.JdbcDriverBuildItem;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.processor.BuiltinScope;
import io.quarkus.datasource.deployment.spi.DefaultDataSourceDbKindBuildItem;
import io.quarkus.datasource.deployment.spi.DevServicesDatasourceConfigurationHandlerBuildItem;
import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.Capability;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem;
import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;

public class JDBCSinglestoreProcessor {

private static final String FEATURE = "jdbc-singlestore";

@BuildStep
FeatureBuildItem feature() {
return new FeatureBuildItem(FEATURE);
}

@BuildStep
void registerDriver(BuildProducer<JdbcDriverBuildItem> jdbcDriver, BuildProducer<DefaultDataSourceDbKindBuildItem> dbKind) {
jdbcDriver.produce(
new JdbcDriverBuildItem(DB_KIND, "com.singlestore.jdbc.Driver",
"com.singlestore.jdbc.SingleStoreDataSource"));

dbKind.produce(new DefaultDataSourceDbKindBuildItem(DB_KIND));
}

@BuildStep
DevServicesDatasourceConfigurationHandlerBuildItem devDbHandler() {
return DevServicesDatasourceConfigurationHandlerBuildItem.jdbc(DB_KIND);
}

@BuildStep
void configureAgroalConnection(BuildProducer<AdditionalBeanBuildItem> additionalBeans,
Capabilities capabilities) {
if (capabilities.isPresent(Capability.AGROAL)) {
additionalBeans
.produce(new AdditionalBeanBuildItem.Builder().addBeanClass(SinglestoreAgroalConnectionConfigurer.class)
.setDefaultScope(BuiltinScope.APPLICATION.getName())
.setUnremovable()
.build());
}
}

@BuildStep
void registerAuthenticationPlugins(BuildProducer<ServiceProviderBuildItem> serviceProvider) {
// make sure that all plugins are available
serviceProvider
.produce(
ServiceProviderBuildItem.allProvidersFromClassPath("com.singlestore.jdbc.plugin.AuthenticationPlugin"));
}

@BuildStep
void registerCodecs(BuildProducer<ServiceProviderBuildItem> serviceProvider) {
serviceProvider
.produce(ServiceProviderBuildItem.allProvidersFromClassPath("com.singlestore.jdbc.plugin.Codec"));
}

@BuildStep(onlyIf = NativeOrNativeSourcesBuild.class)
void addNativeImageResources(BuildProducer<NativeImageResourceBuildItem> resources) {
// singlestore.properties is used by com.singlestore.jdbc.util.VersionFactory and is small enough.
// driver.properties is not added because it only provides optional descriptions for
// com.singlestore.jdbc.Driver.getPropertyInfo(), which is probably not even called.
resources.produce(new NativeImageResourceBuildItem("singlestore-jdbc-client.properties"));

// necessary when jdbcUrl contains useSsl=true
resources.produce(new NativeImageResourceBuildItem("deprecated.properties"));
}

@BuildStep
void registerServiceBinding(Capabilities capabilities,
BuildProducer<ServiceProviderBuildItem> serviceProvider) {
if (capabilities.isPresent(Capability.KUBERNETES_SERVICE_BINDING)) {
serviceProvider.produce(
new ServiceProviderBuildItem("io.quarkus.kubernetes.service.binding.runtime.ServiceBindingConverter",
SinglestoreServiceBindingConverter.class.getName()));
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@

package io.quarkiverse.jdbc.singlestore.deployment;

import java.time.Duration;
import java.util.Set;

import org.testcontainers.containers.ContainerLaunchException;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.containers.startupcheck.MinimumDurationRunningStartupCheckStrategy;
import org.testcontainers.shaded.com.google.common.collect.Sets;
import org.testcontainers.utility.DockerImageName;

public class SinglestoreContainer extends JdbcDatabaseContainer<SinglestoreContainer> {
static final String FULL_IMAGE_NAME = "ghcr.io/singlestore-labs/singlestoredb-dev";
private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse(FULL_IMAGE_NAME);
static final Integer SINGLESTORE_PORT = 3306;
private String databaseName;
private final String rootUsername;
private final String rootPassword;
private static final String ROOT_USER = "root";

public SinglestoreContainer(String dockerImageName) {
this(DockerImageName.parse(dockerImageName));
}

public SinglestoreContainer(DockerImageName dockerImageName) {
super(dockerImageName);
this.rootUsername = ROOT_USER;
this.rootPassword = ROOT_USER;
dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME);
this.addExposedPort(SINGLESTORE_PORT);
}

public Set<Integer> getLivenessCheckPortNumbers() {
return Sets.newHashSet(SINGLESTORE_PORT);
}

@Override
public SinglestoreContainer withDatabaseName(String dbName) {
this.databaseName = dbName;
return this;
}

protected void configure() {
if (this.rootPassword != null && !this.rootPassword.isEmpty()) {
this.addEnv("ROOT_PASSWORD", this.rootPassword);
} else {
if (!"root".equalsIgnoreCase(this.rootUsername)) {
throw new ContainerLaunchException("Empty password can be used only with the root user");
}
}
this.setStartupCheckStrategy(new MinimumDurationRunningStartupCheckStrategy(Duration.ofSeconds(15)));
this.setStartupAttempts(3);
}

public String getDriverClassName() {
return "com.singlestore.jdbc.Driver";
}

public String getJdbcUrl() {
String additionalUrlParams = this.constructUrlParameters("?", "&");
return "jdbc:singlestore://" + this.getHost() + ":" + this.getMappedPort(SINGLESTORE_PORT) + "/" + getDatabaseName()
+ additionalUrlParams;
}

public String getUsername() {
return this.rootUsername;
}

public String getPassword() {
return this.rootPassword;
}

@Override
public String getDatabaseName() {
return databaseName;
}

public String getTestQueryString() {
return "SELECT 1";
}
}
Loading