diff --git a/temporal-kotlin/src/main/kotlin/io/temporal/client/ActivityClientExt.kt b/temporal-kotlin/src/main/kotlin/io/temporal/client/ActivityClientExt.kt new file mode 100644 index 0000000000..2c28a95344 --- /dev/null +++ b/temporal-kotlin/src/main/kotlin/io/temporal/client/ActivityClientExt.kt @@ -0,0 +1,786 @@ +package io.temporal.client + +import io.temporal.kotlin.TemporalDsl +import io.temporal.serviceclient.WorkflowServiceStubs +import io.temporal.workflow.Functions +import java.lang.reflect.Type +import java.util.concurrent.CompletableFuture + +/** + * Creates client for managing standalone activity executions. + * + * @see ActivityClient.newInstance + */ +fun ActivityClient( + service: WorkflowServiceStubs +): ActivityClient { + return ActivityClient.newInstance(service) +} + +/** + * Creates client for managing standalone activity executions. + * + * @see ActivityClient.newInstance + */ +inline fun ActivityClient( + service: WorkflowServiceStubs, + options: @TemporalDsl ActivityClientOptions.Builder.() -> Unit +): ActivityClient { + return ActivityClient.newInstance(service, ActivityClientOptions(options)) +} + +/** + * Starts a standalone activity using a typed interface and an unbound method reference. + * + * @param I interface that given activity implements. + * @see ActivityClient.start + */ +inline fun ActivityClient.start( + activity: Functions.Proc1, + options: StartActivityOptions +): ActivityHandle { + return start(I::class.java, activity, options) +} + +/** + * Starts a standalone activity using a typed interface and an unbound method reference. + * + * @param I interface that given activity implements. + * @see ActivityClient.start + */ +inline fun ActivityClient.start( + activity: Functions.Proc2, + options: StartActivityOptions, + arg1: A1 +): ActivityHandle { + return start(I::class.java, activity, options, arg1) +} + +/** + * Starts a standalone activity using a typed interface and an unbound method reference. + * + * @param I interface that given activity implements. + * @see ActivityClient.start + */ +inline fun ActivityClient.start( + activity: Functions.Proc3, + options: StartActivityOptions, + arg1: A1, + arg2: A2 +): ActivityHandle { + return start(I::class.java, activity, options, arg1, arg2) +} + +/** + * Starts a standalone activity using a typed interface and an unbound method reference. + * + * @param I interface that given activity implements. + * @see ActivityClient.start + */ +inline fun ActivityClient.start( + activity: Functions.Proc4, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3 +): ActivityHandle { + return start(I::class.java, activity, options, arg1, arg2, arg3) +} + +/** + * Starts a standalone activity using a typed interface and an unbound method reference. + * + * @param I interface that given activity implements. + * @see ActivityClient.start + */ +inline fun ActivityClient.start( + activity: Functions.Proc5, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4 +): ActivityHandle { + return start(I::class.java, activity, options, arg1, arg2, arg3, arg4) +} + +/** + * Starts a standalone activity using a typed interface and an unbound method reference. + * + * @param I interface that given activity implements. + * @see ActivityClient.start + */ +inline fun ActivityClient.start( + activity: Functions.Proc6, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4, + arg5: A5 +): ActivityHandle { + return start(I::class.java, activity, options, arg1, arg2, arg3, arg4, arg5) +} + +/** + * Starts a standalone activity using a typed interface and an unbound method reference. + * + * @param I interface that given activity implements. + * @see ActivityClient.start + */ +inline fun ActivityClient.start( + activity: Functions.Proc7, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4, + arg5: A5, + arg6: A6 +): ActivityHandle { + return start(I::class.java, activity, options, arg1, arg2, arg3, arg4, arg5, arg6) +} + +/** + * Starts a standalone activity using a typed interface and an unbound method reference. + * + * @param I interface that given activity implements. + * @see ActivityClient.start + */ +inline fun ActivityClient.start( + activity: Functions.Func1, + options: StartActivityOptions +): ActivityHandle { + return start(I::class.java, activity, options) +} + +/** + * Starts a standalone activity using a typed interface and an unbound method reference. + * + * @param I interface that given activity implements. + * @see ActivityClient.start + */ +inline fun ActivityClient.start( + activity: Functions.Func2, + options: StartActivityOptions, + arg1: A1 +): ActivityHandle { + return start(I::class.java, activity, options, arg1) +} + +/** + * Starts a standalone activity using a typed interface and an unbound method reference. + * + * @param I interface that given activity implements. + * @see ActivityClient.start + */ +inline fun ActivityClient.start( + activity: Functions.Func3, + options: StartActivityOptions, + arg1: A1, + arg2: A2 +): ActivityHandle { + return start(I::class.java, activity, options, arg1, arg2) +} + +/** + * Starts a standalone activity using a typed interface and an unbound method reference. + * + * @param I interface that given activity implements. + * @see ActivityClient.start + */ +inline fun ActivityClient.start( + activity: Functions.Func4, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3 +): ActivityHandle { + return start(I::class.java, activity, options, arg1, arg2, arg3) +} + +/** + * Starts a standalone activity using a typed interface and an unbound method reference. + * + * @param I interface that given activity implements. + * @see ActivityClient.start + */ +inline fun ActivityClient.start( + activity: Functions.Func5, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4 +): ActivityHandle { + return start(I::class.java, activity, options, arg1, arg2, arg3, arg4) +} + +/** + * Starts a standalone activity using a typed interface and an unbound method reference. + * + * @param I interface that given activity implements. + * @see ActivityClient.start + */ +inline fun ActivityClient.start( + activity: Functions.Func6, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4, + arg5: A5 +): ActivityHandle { + return start(I::class.java, activity, options, arg1, arg2, arg3, arg4, arg5) +} + +/** + * Starts a standalone activity using a typed interface and an unbound method reference. + * + * @param I interface that given activity implements. + * @see ActivityClient.start + */ +inline fun ActivityClient.start( + activity: Functions.Func7, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4, + arg5: A5, + arg6: A6 +): ActivityHandle { + return start(I::class.java, activity, options, arg1, arg2, arg3, arg4, arg5, arg6) +} + +/** + * Starts a standalone activity by type name and returns a typed handle. + * + * @param R activity result type. + * @see ActivityClient.start + */ +inline fun ActivityClient.start( + activityType: String, + resultType: Type, + options: StartActivityOptions, + vararg args: Any? +): ActivityHandle { + return start(activityType, R::class.java, resultType, options, *args) +} + +/** + * Starts a standalone activity using a typed interface and blocks until it completes. + * + * @param I interface that given activity implements. + * @see ActivityClient.execute + */ +inline fun ActivityClient.execute( + activity: Functions.Proc1, + options: StartActivityOptions +) { + execute(I::class.java, activity, options) +} + +/** + * Starts a standalone activity using a typed interface and blocks until it completes. + * + * @param I interface that given activity implements. + * @see ActivityClient.execute + */ +inline fun ActivityClient.execute( + activity: Functions.Proc2, + options: StartActivityOptions, + arg1: A1 +) { + execute(I::class.java, activity, options, arg1) +} + +/** + * Starts a standalone activity using a typed interface and blocks until it completes. + * + * @param I interface that given activity implements. + * @see ActivityClient.execute + */ +inline fun ActivityClient.execute( + activity: Functions.Proc3, + options: StartActivityOptions, + arg1: A1, + arg2: A2 +) { + execute(I::class.java, activity, options, arg1, arg2) +} + +/** + * Starts a standalone activity using a typed interface and blocks until it completes. + * + * @param I interface that given activity implements. + * @see ActivityClient.execute + */ +inline fun ActivityClient.execute( + activity: Functions.Proc4, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3 +) { + execute(I::class.java, activity, options, arg1, arg2, arg3) +} + +/** + * Starts a standalone activity using a typed interface and blocks until it completes. + * + * @param I interface that given activity implements. + * @see ActivityClient.execute + */ +inline fun ActivityClient.execute( + activity: Functions.Proc5, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4 +) { + execute(I::class.java, activity, options, arg1, arg2, arg3, arg4) +} + +/** + * Starts a standalone activity using a typed interface and blocks until it completes. + * + * @param I interface that given activity implements. + * @see ActivityClient.execute + */ +inline fun ActivityClient.execute( + activity: Functions.Proc6, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4, + arg5: A5 +) { + execute(I::class.java, activity, options, arg1, arg2, arg3, arg4, arg5) +} + +/** + * Starts a standalone activity using a typed interface and blocks until it completes. + * + * @param I interface that given activity implements. + * @see ActivityClient.execute + */ +inline fun ActivityClient.execute( + activity: Functions.Proc7, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4, + arg5: A5, + arg6: A6 +) { + execute(I::class.java, activity, options, arg1, arg2, arg3, arg4, arg5, arg6) +} + +/** + * Starts a standalone activity using a typed interface and blocks until it completes. + * + * @param I interface that given activity implements. + * @see ActivityClient.execute + */ +inline fun ActivityClient.execute( + activity: Functions.Func1, + options: StartActivityOptions +): R { + return execute(I::class.java, activity, options) +} + +/** + * Starts a standalone activity using a typed interface and blocks until it completes. + * + * @param I interface that given activity implements. + * @see ActivityClient.execute + */ +inline fun ActivityClient.execute( + activity: Functions.Func2, + options: StartActivityOptions, + arg1: A1 +): R { + return execute(I::class.java, activity, options, arg1) +} + +/** + * Starts a standalone activity using a typed interface and blocks until it completes. + * + * @param I interface that given activity implements. + * @see ActivityClient.execute + */ +inline fun ActivityClient.execute( + activity: Functions.Func3, + options: StartActivityOptions, + arg1: A1, + arg2: A2 +): R { + return execute(I::class.java, activity, options, arg1, arg2) +} + +/** + * Starts a standalone activity using a typed interface and blocks until it completes. + * + * @param I interface that given activity implements. + * @see ActivityClient.execute + */ +inline fun ActivityClient.execute( + activity: Functions.Func4, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3 +): R { + return execute(I::class.java, activity, options, arg1, arg2, arg3) +} + +/** + * Starts a standalone activity using a typed interface and blocks until it completes. + * + * @param I interface that given activity implements. + * @see ActivityClient.execute + */ +inline fun ActivityClient.execute( + activity: Functions.Func5, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4 +): R { + return execute(I::class.java, activity, options, arg1, arg2, arg3, arg4) +} + +/** + * Starts a standalone activity using a typed interface and blocks until it completes. + * + * @param I interface that given activity implements. + * @see ActivityClient.execute + */ +inline fun ActivityClient.execute( + activity: Functions.Func6, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4, + arg5: A5 +): R { + return execute(I::class.java, activity, options, arg1, arg2, arg3, arg4, arg5) +} + +/** + * Starts a standalone activity using a typed interface and blocks until it completes. + * + * @param I interface that given activity implements. + * @see ActivityClient.execute + */ +inline fun ActivityClient.execute( + activity: Functions.Func7, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4, + arg5: A5, + arg6: A6 +): R { + return execute(I::class.java, activity, options, arg1, arg2, arg3, arg4, arg5, arg6) +} + +/** + * Starts a standalone activity by type name and blocks until it completes. + * + * @param R activity result type. + * @see ActivityClient.execute + */ +inline fun ActivityClient.execute( + activityType: String, + resultType: Type, + options: StartActivityOptions, + vararg args: Any? +): R { + return execute(activityType, R::class.java, resultType, options, *args) +} + +/** + * Starts a standalone activity using a typed interface and returns a future. + * + * @param I interface that given activity implements. + * @see ActivityClient.executeAsync + */ +inline fun ActivityClient.executeAsync( + activity: Functions.Proc1, + options: StartActivityOptions +): CompletableFuture { + return executeAsync(I::class.java, activity, options) +} + +/** + * Starts a standalone activity using a typed interface and returns a future. + * + * @param I interface that given activity implements. + * @see ActivityClient.executeAsync + */ +inline fun ActivityClient.executeAsync( + activity: Functions.Proc2, + options: StartActivityOptions, + arg1: A1 +): CompletableFuture { + return executeAsync(I::class.java, activity, options, arg1) +} + +/** + * Starts a standalone activity using a typed interface and returns a future. + * + * @param I interface that given activity implements. + * @see ActivityClient.executeAsync + */ +inline fun ActivityClient.executeAsync( + activity: Functions.Proc3, + options: StartActivityOptions, + arg1: A1, + arg2: A2 +): CompletableFuture { + return executeAsync(I::class.java, activity, options, arg1, arg2) +} + +/** + * Starts a standalone activity using a typed interface and returns a future. + * + * @param I interface that given activity implements. + * @see ActivityClient.executeAsync + */ +inline fun ActivityClient.executeAsync( + activity: Functions.Proc4, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3 +): CompletableFuture { + return executeAsync(I::class.java, activity, options, arg1, arg2, arg3) +} + +/** + * Starts a standalone activity using a typed interface and returns a future. + * + * @param I interface that given activity implements. + * @see ActivityClient.executeAsync + */ +inline fun ActivityClient.executeAsync( + activity: Functions.Proc5, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4 +): CompletableFuture { + return executeAsync(I::class.java, activity, options, arg1, arg2, arg3, arg4) +} + +/** + * Starts a standalone activity using a typed interface and returns a future. + * + * @param I interface that given activity implements. + * @see ActivityClient.executeAsync + */ +inline fun ActivityClient.executeAsync( + activity: Functions.Proc6, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4, + arg5: A5 +): CompletableFuture { + return executeAsync(I::class.java, activity, options, arg1, arg2, arg3, arg4, arg5) +} + +/** + * Starts a standalone activity using a typed interface and returns a future. + * + * @param I interface that given activity implements. + * @see ActivityClient.executeAsync + */ +inline fun ActivityClient.executeAsync( + activity: Functions.Proc7, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4, + arg5: A5, + arg6: A6 +): CompletableFuture { + return executeAsync(I::class.java, activity, options, arg1, arg2, arg3, arg4, arg5, arg6) +} + +/** + * Starts a standalone activity using a typed interface and returns a future. + * + * @param I interface that given activity implements. + * @see ActivityClient.executeAsync + */ +inline fun ActivityClient.executeAsync( + activity: Functions.Func1, + options: StartActivityOptions +): CompletableFuture { + return executeAsync(I::class.java, activity, options) +} + +/** + * Starts a standalone activity using a typed interface and returns a future. + * + * @param I interface that given activity implements. + * @see ActivityClient.executeAsync + */ +inline fun ActivityClient.executeAsync( + activity: Functions.Func2, + options: StartActivityOptions, + arg1: A1 +): CompletableFuture { + return executeAsync(I::class.java, activity, options, arg1) +} + +/** + * Starts a standalone activity using a typed interface and returns a future. + * + * @param I interface that given activity implements. + * @see ActivityClient.executeAsync + */ +inline fun ActivityClient.executeAsync( + activity: Functions.Func3, + options: StartActivityOptions, + arg1: A1, + arg2: A2 +): CompletableFuture { + return executeAsync(I::class.java, activity, options, arg1, arg2) +} + +/** + * Starts a standalone activity using a typed interface and returns a future. + * + * @param I interface that given activity implements. + * @see ActivityClient.executeAsync + */ +inline fun ActivityClient.executeAsync( + activity: Functions.Func4, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3 +): CompletableFuture { + return executeAsync(I::class.java, activity, options, arg1, arg2, arg3) +} + +/** + * Starts a standalone activity using a typed interface and returns a future. + * + * @param I interface that given activity implements. + * @see ActivityClient.executeAsync + */ +inline fun ActivityClient.executeAsync( + activity: Functions.Func5, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4 +): CompletableFuture { + return executeAsync(I::class.java, activity, options, arg1, arg2, arg3, arg4) +} + +/** + * Starts a standalone activity using a typed interface and returns a future. + * + * @param I interface that given activity implements. + * @see ActivityClient.executeAsync + */ +inline fun ActivityClient.executeAsync( + activity: Functions.Func6, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4, + arg5: A5 +): CompletableFuture { + return executeAsync(I::class.java, activity, options, arg1, arg2, arg3, arg4, arg5) +} + +/** + * Starts a standalone activity using a typed interface and returns a future. + * + * @param I interface that given activity implements. + * @see ActivityClient.executeAsync + */ +inline fun ActivityClient.executeAsync( + activity: Functions.Func7, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4, + arg5: A5, + arg6: A6 +): CompletableFuture { + return executeAsync(I::class.java, activity, options, arg1, arg2, arg3, arg4, arg5, arg6) +} + +/** + * Starts a standalone activity by type name and returns a future. + * + * @param R activity result type. + * @see ActivityClient.executeAsync + */ +inline fun ActivityClient.executeAsync( + activityType: String, + resultType: Type, + options: StartActivityOptions, + vararg args: Any? +): CompletableFuture { + return executeAsync(activityType, R::class.java, resultType, options, *args) +} + +/** + * Returns a typed handle to an existing standalone activity execution. + * + * @param R activity result type. + * @see ActivityClient.getHandle + */ +inline fun ActivityClient.getHandle( + activityId: String +): ActivityHandle { + return getHandle(activityId, null, R::class.java) +} + +/** + * Returns a typed handle to an existing standalone activity execution. + * + * @param R activity result type. + * @see ActivityClient.getHandle + */ +inline fun ActivityClient.getHandle( + activityId: String, + resultType: Type? +): ActivityHandle { + return getHandle(activityId, null, R::class.java, resultType) +} + +/** + * Returns a typed handle to an existing standalone activity execution. + * + * @param R activity result type. + * @see ActivityClient.getHandle + */ +inline fun ActivityClient.getHandle( + activityId: String, + activityRunId: String?, + resultType: Type? +): ActivityHandle { + return getHandle(activityId, activityRunId, R::class.java, resultType) +} diff --git a/temporal-kotlin/src/main/kotlin/io/temporal/client/ActivityClientOptionsExt.kt b/temporal-kotlin/src/main/kotlin/io/temporal/client/ActivityClientOptionsExt.kt new file mode 100644 index 0000000000..ea6c3ed414 --- /dev/null +++ b/temporal-kotlin/src/main/kotlin/io/temporal/client/ActivityClientOptionsExt.kt @@ -0,0 +1,23 @@ +package io.temporal.client + +import io.temporal.kotlin.TemporalDsl + +/** + * Options for [ActivityClient] configuration. + * + * @see ActivityClientOptions + */ +inline fun ActivityClientOptions( + options: @TemporalDsl ActivityClientOptions.Builder.() -> Unit +): ActivityClientOptions { + return ActivityClientOptions.newBuilder().apply(options).build() +} + +/** + * Create a new instance of [ActivityClientOptions], optionally overriding some of its properties. + */ +inline fun ActivityClientOptions.copy( + overrides: @TemporalDsl ActivityClientOptions.Builder.() -> Unit +): ActivityClientOptions { + return toBuilder().apply(overrides).build() +} diff --git a/temporal-kotlin/src/test/kotlin/io/temporal/client/ActivityClientOptionsExtTest.kt b/temporal-kotlin/src/test/kotlin/io/temporal/client/ActivityClientOptionsExtTest.kt new file mode 100644 index 0000000000..70ae72b744 --- /dev/null +++ b/temporal-kotlin/src/test/kotlin/io/temporal/client/ActivityClientOptionsExtTest.kt @@ -0,0 +1,41 @@ +package io.temporal.client + +import org.junit.Assert.assertEquals +import org.junit.Test + +class ActivityClientOptionsExtTest { + + @Test + fun `ActivityClientOptions DSL should be equivalent to builder`() { + val dslOptions = ActivityClientOptions { + setNamespace("test") + setIdentity("identity") + } + + val builderOptions = ActivityClientOptions.newBuilder() + .setNamespace("test") + .setIdentity("identity") + .build() + + assertEquals(builderOptions, dslOptions) + } + + @Test + fun `ActivityClientOptions copy() DSL should merge override options`() { + val sourceOptions = ActivityClientOptions { + setNamespace("test") + setIdentity("identity1") + } + + val overriddenOptions = sourceOptions.copy { + setIdentity("identity2") + } + + val expectedOptions = ActivityClientOptions { + setNamespace("test") + setIdentity("identity2") + } + + assertEquals(expectedOptions, overriddenOptions) + } +}