Skip to content

Commit

Permalink
kotlin
Browse files Browse the repository at this point in the history
  • Loading branch information
stuartwdouglas committed Nov 27, 2024
1 parent e31d24d commit 44dfa04
Show file tree
Hide file tree
Showing 11 changed files with 172 additions and 11 deletions.
5 changes: 3 additions & 2 deletions backend/controller/pubsub/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@ import (
"testing"
"time"

"github.com/alecthomas/assert/v2"

"github.com/TBD54566975/ftl/backend/controller/async"
in "github.com/TBD54566975/ftl/internal/integration"
"github.com/TBD54566975/ftl/internal/schema"
"github.com/alecthomas/assert/v2"
)

func TestPubSub(t *testing.T) {
calls := 20
events := calls * 10
in.Run(t,
in.WithLanguages("java", "go"),
in.WithLanguages("java", "go", "kotlin"),
in.CopyModule("publisher"),
in.CopyModule("subscriber"),
in.Deploy("publisher"),
Expand Down
2 changes: 2 additions & 0 deletions backend/controller/pubsub/testdata/kotlin/publisher/ftl.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module = "publisher"
language = "java"
14 changes: 14 additions & 0 deletions backend/controller/pubsub/testdata/kotlin/publisher/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?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>publisher</artifactId>
<version>1.0-SNAPSHOT</version>

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

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

import java.time.ZonedDateTime
class PubSubEvent(var time: ZonedDateTime) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package xyz.block.ftl.java.test.publisher

import io.quarkus.logging.Log
import xyz.block.ftl.*
import java.time.ZonedDateTime

class Publisher {
@Export
@Topic("testTopic")
interface TestTopic : WriteableTopic<PubSubEvent?>

@Topic("localTopic")
interface LocalTopic : WriteableTopic<PubSubEvent?>

@Export
@Topic("topic2")
interface Topic2 : WriteableTopic<PubSubEvent?>

@Verb
@Throws(Exception::class)
fun publishTen(testTopic: LocalTopic) {
for (i in 0..9) {
val t = ZonedDateTime.now()
Log.infof("Publishing %s", t)
testTopic.publish(PubSubEvent(t))
}
}

@Verb
@Throws(Exception::class)
fun publishOne(testTopic: TestTopic) {
val t = ZonedDateTime.now()
Log.infof("Publishing %s", t)
testTopic.publish(PubSubEvent(t))
}

@Verb
@Throws(Exception::class)
fun publishOneToTopic2(topic2: Topic2) {
val t = ZonedDateTime.now()
Log.infof("Publishing %s", t)
topic2.publish(PubSubEvent(t))
}

@Subscription(topic = LocalTopic::class, from = FromOffset.LATEST)
fun local(testTopic: TestTopic, event: PubSubEvent) {
testTopic.publish(event)
}
}
2 changes: 2 additions & 0 deletions backend/controller/pubsub/testdata/kotlin/subscriber/ftl.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module = "subscriber"
language = "java"
14 changes: 14 additions & 0 deletions backend/controller/pubsub/testdata/kotlin/subscriber/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?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>subscriber</artifactId>
<version>1.0-SNAPSHOT</version>

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

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

import ftl.builtin.CatchRequest
import ftl.publisher.PubSubEvent
import ftl.publisher.TestTopicTopic
import ftl.publisher.Topic2Topic
import io.quarkus.logging.Log
import xyz.block.ftl.*
import java.util.concurrent.atomic.AtomicInteger

class Subscriber {
@Subscription(topic = TestTopicTopic::class, from = FromOffset.BEGINNING)
@Throws(
Exception::class
)
fun consume(event: PubSubEvent) {
Log.infof("Subscriber is consuming %s", event.time)
}

@Subscription(topic = Topic2Topic::class, from = FromOffset.BEGINNING)
@Retry(count = 2, minBackoff = "1s", maxBackoff = "1s", catchVerb = "catch")
fun consumeButFailAndRetry(event: PubSubEvent) {
throw RuntimeException("always error: event " + event.time)
}

@Subscription(topic = Topic2Topic::class, from = FromOffset.BEGINNING)
@Retry(count = 1, minBackoff = "1s", maxBackoff = "1s", catchVerb = "catchAny")
fun consumeButFailAndCatchAny(event: PubSubEvent) {
throw RuntimeException("always error: event " + event.time)
}

@Verb
@VerbName("catch")
fun catchVerb(req: CatchRequest<PubSubEvent?>) {
if (!req.error.contains("always error: event")) {
throw RuntimeException("unexpected error: " + req.error)
}
if (catchCount.incrementAndGet() == 1) {
throw RuntimeException("catching error")
}
}

@Verb
fun catchAny(req: CatchRequest<Any>) {
require("subscriber" == req.verb.module) { String.format("unexpected verb module: %s", req.verb.module) }
require("consumeButFailAndCatchAny" == req.verb.name) {
String.format(
"unexpected verb name: %s",
req.verb.name
)
}
require("publisher.PubSubEvent" == req.requestType) {
String.format(
"unexpected request type: %s",
req.requestType
)
}
require(req.request is Map<*, *>) {
String.format(
"expected request to be a Map: %s",
req.request.javaClass.name
)
}
val request = req.request as Map<*, *>
val time = request["time"]
requireNotNull(time) { "expected request to have a time key" }
require(time is String) { "expected request to have a time value of type string" }
}

companion object {
private val catchCount = AtomicInteger()
}
}
2 changes: 1 addition & 1 deletion docs/content/docs/reference/pubsub.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ fun publishInvoice(request: InvoiceRequest, topic: InvoiceTopic) {
To subscribe to a topic use the `@Subscription` annotation, referencing the topic class and providing a method to consume the event:

```kotlin
@Subscription(topic = InvoiceTopic, from = FromOffset.LATEST)
@Subscription(topic = InvoiceTopic::class, from = FromOffset.LATEST)
fun consumeInvoice(event: Invoice) {
// ...
}
Expand Down
8 changes: 4 additions & 4 deletions jvm-runtime/plugin/common/java_plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ func TestJavaConfigDefaults(t *testing.T) {
language: "kotlin",
dir: "testdata/kotlin/echo",
expected: moduleconfig.CustomDefaults{
Build: optional.Some("mvn -B package"),
DevModeBuild: optional.Some("mvn quarkus:dev"),
Build: optional.Some("mvn -B clean package"),
DevModeBuild: optional.Some("mvn clean quarkus:dev"),
DeployDir: "target",
GeneratedSchemaDir: optional.Some("src/main/ftl-module-schema"),
LanguageConfig: map[string]any{
Expand All @@ -49,8 +49,8 @@ func TestJavaConfigDefaults(t *testing.T) {
language: "kotlin",
dir: "testdata/kotlin/external",
expected: moduleconfig.CustomDefaults{
Build: optional.Some("mvn -B package"),
DevModeBuild: optional.Some("mvn quarkus:dev"),
Build: optional.Some("mvn -B clean package"),
DevModeBuild: optional.Some("mvn clean quarkus:dev"),
DeployDir: "target",
GeneratedSchemaDir: optional.Some("src/main/ftl-module-schema"),
LanguageConfig: map[string]any{
Expand Down
8 changes: 4 additions & 4 deletions jvm-runtime/plugin/common/jvmcommon.go
Original file line number Diff line number Diff line change
Expand Up @@ -581,13 +581,13 @@ func (s *Service) ModuleConfigDefaults(ctx context.Context, req *connect.Request
buildGradleKts := filepath.Join(dir, "build.gradle.kts")
if fileExists(pom) {
defaults.LanguageConfig.Fields["build-tool"] = structpb.NewStringValue(JavaBuildToolMaven)
defaults.DevModeBuild = ptr("mvn quarkus:dev")
defaults.Build = ptr("mvn -B package")
defaults.DevModeBuild = ptr("mvn clean quarkus:dev")
defaults.Build = ptr("mvn -B clean package")
defaults.DeployDir = "target"
} else if fileExists(buildGradle) || fileExists(buildGradleKts) {
defaults.LanguageConfig.Fields["build-tool"] = structpb.NewStringValue(JavaBuildToolGradle)
defaults.DevModeBuild = ptr("gradle quarkusDev")
defaults.Build = ptr("gradle build")
defaults.DevModeBuild = ptr("gradle clean quarkusDev")
defaults.Build = ptr("gradle clean build")
defaults.DeployDir = "build"
} else {
return nil, fmt.Errorf("could not find JVM build file in %s", dir)
Expand Down

0 comments on commit 44dfa04

Please sign in to comment.