Skip to content

Commit

Permalink
feat: Java database support
Browse files Browse the repository at this point in the history
Fixes: 2392
  • Loading branch information
stuartwdouglas committed Aug 17, 2024
1 parent f661854 commit 87c85dd
Show file tree
Hide file tree
Showing 28 changed files with 499 additions and 143 deletions.
3 changes: 2 additions & 1 deletion backend/controller/sql/database_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

func TestDatabase(t *testing.T) {
in.Run(t,
in.WithLanguages("go", "java"),
in.WithFTLConfig("database/ftl-project.toml"),
// deploy real module against "testdb"
in.CopyModule("database"),
Expand All @@ -21,7 +22,7 @@ func TestDatabase(t *testing.T) {

// run tests which should only affect "testdb_test"
in.CreateDBAction("database", "testdb", true),
in.ExecModuleTest("database"),
in.IfLanguage("go", in.ExecModuleTest("database")),
in.QueryRow("testdb", "SELECT data FROM requests", "hello"),
)
}
Expand Down
2 changes: 2 additions & 0 deletions backend/controller/sql/testdata/java/database/ftl.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module = "database"
language = "java"
25 changes: 25 additions & 0 deletions backend/controller/sql/testdata/java/database/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>xyz.block.ftl.examples</groupId>
<artifactId>database</artifactId>
<version>1.0-SNAPSHOT</version>

<parent>
<groupId>xyz.block.ftl</groupId>
<artifactId>ftl-build-parent-java</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm-panache</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package xyz.block.ftl.java.test.database;

import jakarta.transaction.Transactional;

import xyz.block.ftl.Verb;

public class Database {

@Verb
@Transactional
public InsertResponse insert(InsertRequest insertRequest) {
Request request = new Request();
request.data = insertRequest.getData();
request.persist();
return new InsertResponse();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package xyz.block.ftl.java.test.database;

public class InsertRequest {
private String data;

public String getData() {
return data;
}

public InsertRequest setData(String data) {
this.data = data;
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package xyz.block.ftl.java.test.database;

public class InsertResponse {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package xyz.block.ftl.java.test.database;

import java.sql.Timestamp;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;

import io.quarkus.hibernate.orm.panache.PanacheEntity;

@Entity
@Table(name = "requests")
public class Request extends PanacheEntity {
public String data;

@Column(name = "created_at")
public Timestamp createdAt;

@Column(name = "updated_at")
public Timestamp updatedAt;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
quarkus.hibernate-orm.database.generation=drop-and-create
quarkus.datasource.testdb.db-kind=postgresql
quarkus.hibernate-orm.datasource=testdb
4 changes: 3 additions & 1 deletion buildengine/build_java.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ func buildJavaModule(ctx context.Context, module Module) error {
logger.Warnf("unable to update ftl.version in %s: %s", module.Config.Dir, err.Error())
}
logger.Infof("Using build command '%s'", module.Config.Build)
err := exec.Command(ctx, log.Debug, module.Config.Dir, "bash", "-c", module.Config.Build).RunBuffered(ctx)
command := exec.Command(ctx, log.Debug, module.Config.Dir, "bash", "-c", module.Config.Build)
command.Env = append(command.Env, "FTL_MODULE_NAME="+module.Config.Module)
err := command.RunBuffered(ctx)
if err != nil {
return fmt.Errorf("failed to build module %q: %w", module.Config.Module, err)
}
Expand Down
2 changes: 1 addition & 1 deletion docs/content/docs/reference/matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ top = false
| | Config | ✔️ | ✔️ | |
| | Secrets | ✔️ | ✔️ | |
| | HTTP Ingress | ✔️ | ✔️ | |
| **Resources** | PostgreSQL | ✔️ | | |
| **Resources** | PostgreSQL | ✔️ | ✔️ | |
| | MySQL | | | |
| | Kafka | | | |
| **PubSub** | Declaring Topic | ✔️ | ✔️ | |
Expand Down
2 changes: 1 addition & 1 deletion jvm-runtime/ftl-runtime/common/build-parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
<quarkus.platform.version>3.12.3</quarkus.platform.version>
<quarkus.platform.version>3.13.2</quarkus.platform.version>
<skipITs>true</skipITs>
<surefire-plugin.version>3.2.5</surefire-plugin.version>
</properties>
Expand Down
8 changes: 8 additions & 0 deletions jvm-runtime/ftl-runtime/common/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest-jackson-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-agroal-spi</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-credentials-deployment</artifactId>
</dependency>

<dependency>
<groupId>xyz.block.ftl</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package xyz.block.ftl.deployment;

import java.util.Optional;

import io.quarkus.runtime.annotations.ConfigItem;
import io.quarkus.runtime.annotations.ConfigRoot;

@ConfigRoot(name = "ftl")
public class FTLBuildTimeConfig {

/**
* The FTL module name, should be set automatically during build
*/
@ConfigItem
public Optional<String> moduleName;
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

import com.fasterxml.jackson.databind.ObjectMapper;

import io.quarkus.agroal.spi.JdbcDataSourceBuildItem;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.processor.DotNames;
import io.quarkus.deployment.Capabilities;
Expand All @@ -51,7 +52,9 @@
import io.quarkus.deployment.builditem.ApplicationStartBuildItem;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.GeneratedResourceBuildItem;
import io.quarkus.deployment.builditem.LaunchModeBuildItem;
import io.quarkus.deployment.builditem.RunTimeConfigBuilderBuildItem;
import io.quarkus.deployment.builditem.ShutdownContextBuildItem;
import io.quarkus.deployment.builditem.SystemPropertyBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
Expand All @@ -76,7 +79,7 @@
import xyz.block.ftl.Subscription;
import xyz.block.ftl.Verb;
import xyz.block.ftl.VerbName;
import xyz.block.ftl.runtime.FTLController;
import xyz.block.ftl.runtime.FTLDatasourceCredentials;
import xyz.block.ftl.runtime.FTLHttpHandler;
import xyz.block.ftl.runtime.FTLRecorder;
import xyz.block.ftl.runtime.JsonSerializationConfig;
Expand All @@ -86,11 +89,14 @@
import xyz.block.ftl.runtime.VerbRegistry;
import xyz.block.ftl.runtime.builtin.HttpRequest;
import xyz.block.ftl.runtime.builtin.HttpResponse;
import xyz.block.ftl.runtime.config.FTLConfigSource;
import xyz.block.ftl.runtime.config.FTLConfigSourceFactoryBuilder;
import xyz.block.ftl.v1.CallRequest;
import xyz.block.ftl.v1.schema.Array;
import xyz.block.ftl.v1.schema.Bool;
import xyz.block.ftl.v1.schema.Bytes;
import xyz.block.ftl.v1.schema.Data;
import xyz.block.ftl.v1.schema.Database;
import xyz.block.ftl.v1.schema.Decl;
import xyz.block.ftl.v1.schema.Field;
import xyz.block.ftl.v1.schema.Float;
Expand Down Expand Up @@ -133,9 +139,13 @@ class FtlProcessor {
public static final DotName NOT_NULL = DotName.createSimple(NotNull.class);

@BuildStep
ModuleNameBuildItem moduleName(ApplicationInfoBuildItem applicationInfoBuildItem) {
return new ModuleNameBuildItem(applicationInfoBuildItem.getName());
ModuleNameBuildItem moduleName(ApplicationInfoBuildItem applicationInfoBuildItem, FTLBuildTimeConfig buildTimeConfig) {
return new ModuleNameBuildItem(buildTimeConfig.moduleName.orElse(applicationInfoBuildItem.getName()));
}

@BuildStep
RunTimeConfigBuilderBuildItem runTimeConfigBuilderBuildItem() {
return new RunTimeConfigBuilderBuildItem(FTLConfigSourceFactoryBuilder.class.getName());
}

@BuildStep
Expand All @@ -159,8 +169,9 @@ BindableServiceBuildItem verbService() {
AdditionalBeanBuildItem beans() {
return AdditionalBeanBuildItem.builder()
.addBeanClasses(VerbHandler.class,
VerbRegistry.class, FTLHttpHandler.class, FTLController.class,
TopicHelper.class, VerbClientHelper.class, JsonSerializationConfig.class)
VerbRegistry.class, FTLHttpHandler.class,
TopicHelper.class, VerbClientHelper.class, JsonSerializationConfig.class,
FTLDatasourceCredentials.class)
.setUnremovable().build();
}

Expand Down Expand Up @@ -223,7 +234,10 @@ public void registerVerbs(CombinedIndexBuildItem index,
TopicsBuildItem topics,
VerbClientBuildItem verbClients,
ModuleNameBuildItem moduleNameBuildItem,
SubscriptionMetaAnnotationsBuildItem subscriptionMetaAnnotationsBuildItem) throws Exception {
SubscriptionMetaAnnotationsBuildItem subscriptionMetaAnnotationsBuildItem,
List<JdbcDataSourceBuildItem> datasources,
BuildProducer<SystemPropertyBuildItem> systemPropProducer,
BuildProducer<GeneratedResourceBuildItem> generatedResourceBuildItemBuildProducer) throws Exception {
String moduleName = moduleNameBuildItem.getModuleName();
Module.Builder moduleBuilder = Module.newBuilder()
.setName(moduleName)
Expand All @@ -233,8 +247,36 @@ public void registerVerbs(CombinedIndexBuildItem index,
new HashSet<>(), new HashSet<>(), topics.getTopics(), verbClients.getVerbClients());
var beans = AdditionalBeanBuildItem.builder().setUnremovable();

//register all the topics we are defining in the module definition
List<String> namedDatasources = new ArrayList<>();
for (var ds : datasources) {
if (!ds.getDbKind().equals("postgresql")) {
throw new RuntimeException("only postgresql is supported not " + ds.getDbKind());
}
//default name is <default> which is not a valid name
String sanitisedName = ds.getName().replace("<", "").replace(">", "");
//we use a dynamic credentials provider
if (ds.isDefault()) {
systemPropProducer
.produce(new SystemPropertyBuildItem("quarkus.datasource.credentials-provider", sanitisedName));
systemPropProducer
.produce(new SystemPropertyBuildItem("quarkus.datasource.credentials-provider-name",
FTLDatasourceCredentials.NAME));
} else {
namedDatasources.add(ds.getName());
systemPropProducer.produce(new SystemPropertyBuildItem(
"quarkus.datasource." + ds.getName() + ".credentials-provider", sanitisedName));
systemPropProducer.produce(new SystemPropertyBuildItem(
"quarkus.datasource." + ds.getName() + ".credentials-provider-name", FTLDatasourceCredentials.NAME));
}
moduleBuilder.addDecls(
Decl.newBuilder().setDatabase(
Database.newBuilder().setType("postgres").setName(sanitisedName))
.build());
}
generatedResourceBuildItemBuildProducer.produce(new GeneratedResourceBuildItem(FTLConfigSource.DATASOURCE_NAMES,
String.join("\n", namedDatasources).getBytes(StandardCharsets.UTF_8)));

//register all the topics we are defining in the module definition
for (var topic : topics.getTopics().values()) {
extractionContext.moduleBuilder.addDecls(Decl.newBuilder().setTopic(xyz.block.ftl.v1.schema.Topic.newBuilder()
.setExport(topic.exported())
Expand Down
4 changes: 4 additions & 0 deletions jvm-runtime/ftl-runtime/common/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-credentials</artifactId>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
Expand Down

This file was deleted.

Loading

0 comments on commit 87c85dd

Please sign in to comment.