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

feat: initial Java database work #2399

Merged
merged 1 commit into from
Aug 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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
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
4 changes: 3 additions & 1 deletion internal/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 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