Skip to content

Commit

Permalink
Now sdk-api-kotlin works again with the new interface system. Fix #237
Browse files Browse the repository at this point in the history
  • Loading branch information
slinkydeveloper committed Mar 7, 2024
1 parent d2ec402 commit b29f181
Show file tree
Hide file tree
Showing 48 changed files with 907 additions and 1,090 deletions.
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import net.ltgt.gradle.errorprone.errorprone

plugins {
java
kotlin("jvm") version "1.9.20" apply false
kotlin("plugin.serialization") version "1.9.20" apply false
kotlin("jvm") version "1.9.22" apply false
kotlin("plugin.serialization") version "1.9.22" apply false

id("net.ltgt.errorprone") version "3.0.1"
id("com.github.jk1.dependency-license-report") version "2.0"
Expand Down
4 changes: 2 additions & 2 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ For a sample project configuration and more elaborated examples, check out the [
Available examples:

* [`Counter`](src/main/java/my/restate/sdk/examples/Counter.java): Shows a simple virtual object using state primitives.
* [`CounterKt`](src/main/kotlin/dev/restate/sdk/examples/CounterKt.kt): Same as `Counter` but using Kotlin.
* [`Counter`](src/main/kotlin/my/restate/sdk/examples/Counter.kt): Same as `Counter` but using Kotlin.
* [`LoanWorkflow`](src/main/java/my/restate/sdk/examples/LoanWorkflow.java): Shows a simple workflow example using the Workflow API.

## Package the examples for Lambda
Expand Down Expand Up @@ -35,7 +35,7 @@ You can run the Java Counter example via:
You can modify the class to run setting `-PmainClass=<FQCN>`, for example, in order to run the Kotlin implementation:

```shell
./gradlew :examples:run -PmainClass=dev.restate.sdk.examples.CounterKt
./gradlew :examples:run -PmainClass=my.restate.sdk.examples.CounterKt
```

## Invoking the counter bindableComponent
Expand Down
7 changes: 5 additions & 2 deletions examples/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
java
// kotlin("jvm")
kotlin("jvm")
kotlin("plugin.serialization")
application
id("com.github.johnrengelman.shadow").version("7.1.2")
}
Expand All @@ -11,7 +12,7 @@ dependencies {
implementation(project(":sdk-api"))
implementation(project(":sdk-lambda"))
implementation(project(":sdk-http-vertx"))
// implementation(project(":sdk-api-kotlin"))
implementation(project(":sdk-api-kotlin"))
implementation(project(":sdk-serde-jackson"))
implementation(project(":sdk-workflow-api"))

Expand All @@ -26,6 +27,8 @@ dependencies {
implementation(vertxLibs.vertx.kotlin.coroutines)

implementation(kotlinLibs.kotlinx.coroutines)
implementation(kotlinLibs.kotlinx.serialization.core)
implementation(kotlinLibs.kotlinx.serialization.json)

implementation(coreLibs.log4j.core)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ public void register(RestateLambdaEndpointBuilder builder) {
.split(Pattern.quote(","))) {
if (Counter.class.getCanonicalName().equals(serviceClass)) {
builder.with(new Counter());
// } else if (CounterKt.class.getCanonicalName().equals(serviceClass)) {
// builder.withService(new CounterKt());
} else if (CounterKt.class.getCanonicalName().equals(serviceClass)) {
builder.with(CounterKt.getCounter());
} else {
throw new IllegalArgumentException(
"Bad \"LAMBDA_FACTORY_SERVICE_CLASS\" env: " + serviceClass);
Expand Down
60 changes: 0 additions & 60 deletions examples/src/main/kotlin/dev/restate/sdk/examples/CounterKt.kt

This file was deleted.

40 changes: 40 additions & 0 deletions examples/src/main/kotlin/my/restate/sdk/examples/Counter.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) 2023 - Restate Software, Inc., Restate GmbH
//
// This file is part of the Restate Java SDK,
// which is released under the MIT license.
//
// You can find a copy of the license in file LICENSE in the root
// directory of this repository or package, or at
// https://github.com/restatedev/sdk-java/blob/main/LICENSE
package my.restate.sdk.examples

import dev.restate.sdk.common.StateKey
import dev.restate.sdk.http.vertx.RestateHttpEndpointBuilder
import dev.restate.sdk.kotlin.Component
import dev.restate.sdk.kotlin.KtSerdes
import kotlinx.serialization.Serializable

@Serializable data class CounterUpdate(var oldValue: Long, val newValue: Long)

private val totalKey = StateKey.of<Long>("total", KtSerdes.json())

val counter =
Component.virtualObject("Counter") {
handler("reset") { ctx, _: Unit -> ctx.clear(totalKey) }
handler("add") { ctx, value: Long ->
val currentValue = ctx.get(totalKey) ?: 0L
val newValue = currentValue + value
ctx.set(totalKey, newValue)
}
handler("get") { ctx, _: Unit -> ctx.get(totalKey) ?: 0L }
handler("getAndAdd") { ctx, value: Long ->
val currentValue = ctx.get(totalKey) ?: 0L
val newValue = currentValue + value
ctx.set(totalKey, newValue)
CounterUpdate(currentValue, newValue)
}
}

fun main() {
RestateHttpEndpointBuilder.builder().with(counter).buildAndListen()
}
42 changes: 2 additions & 40 deletions sdk-api-kotlin/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import com.google.protobuf.gradle.id

plugins {
java
kotlin("jvm")
Expand All @@ -16,50 +14,14 @@ dependencies {
implementation(kotlinLibs.kotlinx.serialization.core)
implementation(kotlinLibs.kotlinx.serialization.json)

implementation(coreLibs.log4j.api)

testImplementation(project(":sdk-core"))
testImplementation(testingLibs.junit.jupiter)
testImplementation(testingLibs.assertj)
testImplementation(coreLibs.protobuf.java)
testImplementation(coreLibs.protobuf.kotlin)
testImplementation(coreLibs.grpc.stub)
testImplementation(coreLibs.grpc.protobuf)
testImplementation(coreLibs.grpc.kotlin.stub)
testImplementation(coreLibs.log4j.core)

testImplementation(project(":sdk-core", "testArchive"))
testProtobuf(project(":sdk-core", "testArchive"))
}

val pluginJar =
file(
"${project.rootProject.rootDir}/protoc-gen-restate/build/libs/protoc-gen-restate-${project.version}-all.jar")

protobuf {
plugins {
id("grpc") { artifact = "io.grpc:protoc-gen-grpc-java:${coreLibs.versions.grpc.get()}" }
id("grpckt") {
artifact = "io.grpc:protoc-gen-grpc-kotlin:${coreLibs.versions.grpckt.get()}:jdk8@jar"
}
id("restate") {
// NOTE: This is not needed in a regular project configuration, you should rather use:
// artifact = "dev.restate.sdk:protoc-gen-restate-java-blocking:1.0-SNAPSHOT:all@jar"
path = pluginJar.path
}
}

generateProtoTasks {
ofSourceSet("test").forEach {
// Make sure we depend on shadowJar from protoc-gen-restate
it.dependsOn(":protoc-gen-restate:shadowJar")

it.plugins {
id("grpc")
id("grpckt")
id("restate") { option("kotlin") }
}
it.builtins { id("kotlin") }
}
}
}

// Generate test jar
Expand Down
44 changes: 21 additions & 23 deletions sdk-api-kotlin/src/main/kotlin/dev/restate/sdk/kotlin/Awaitables.kt
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,25 @@ internal abstract class BaseSingleMappedAwaitableImpl<T : Any, U : Any>(
}
}

// internal class SingleMappedAwaitableImpl<T: Any, U: Any>(inner: BaseAwaitableImpl<T>, private val
// mapper: suspend (res: Result<T>) -> Result<U>) : BaseSingleMappedAwaitableImpl<T, U>(inner) {
// override suspend fun map(res: Result<T>): Result<U> {
// return mapper(res)
// }
//
// }
internal open class SingleSerdeAwaitableImpl<T : Any>
internal constructor(
syscalls: Syscalls,
deferred: Deferred<ByteString>,
private val serde: Serde<T>,
) :
BaseSingleMappedAwaitableImpl<ByteString, T>(
SingleAwaitableImpl(syscalls, deferred),
) {
@Suppress("UNCHECKED_CAST")
override suspend fun map(res: Result<ByteString>): Result<T> {
return if (res.isSuccess) {
// This propagates exceptions as non-terminal
Result.success(serde.deserializeWrappingException(syscalls, res.value!!))
} else {
res as Result<T>
}
}
}

internal class UnitAwakeableImpl(syscalls: Syscalls, deferred: Deferred<Void>) :
BaseSingleMappedAwaitableImpl<Void, Unit>(SingleAwaitableImpl(syscalls, deferred)) {
Expand Down Expand Up @@ -140,23 +152,9 @@ internal class AwakeableImpl<T : Any>
internal constructor(
syscalls: Syscalls,
deferred: Deferred<ByteString>,
private val serde: Serde<T>,
serde: Serde<T>,
override val id: String
) :
BaseSingleMappedAwaitableImpl<ByteString, T>(
SingleAwaitableImpl(syscalls, deferred),
),
Awakeable<T> {

@Suppress("UNCHECKED_CAST")
override suspend fun map(res: Result<ByteString>): Result<T> {
return if (res.isSuccess) {
Result.success(serde.deserializeWrappingException(syscalls, res.value!!))
} else {
res as Result<T>
}
}
}
) : SingleSerdeAwaitableImpl<T>(syscalls, deferred, serde), Awakeable<T> {}

internal class AwakeableHandleImpl(val syscalls: Syscalls, val id: String) : AwakeableHandle {
override suspend fun <T : Any> resolve(serde: Serde<T>, payload: T) {
Expand Down
Loading

0 comments on commit b29f181

Please sign in to comment.