From a862bf93a3c9608751e98e505439089e6f662d8d Mon Sep 17 00:00:00 2001 From: 444am Date: Fri, 19 Jun 2026 14:58:44 +1000 Subject: [PATCH 1/2] Add Kotlin extension for Standalone Activity Client --- .../io/temporal/client/ActivityClientExt.kt | 786 ++++++++++++++++++ .../client/ActivityClientOptionsExt.kt | 23 + .../temporal/client/ActivityClientExtTest.kt | 584 +++++++++++++ .../client/ActivityClientOptionsExtTest.kt | 41 + 4 files changed, 1434 insertions(+) create mode 100644 temporal-kotlin/src/main/kotlin/io/temporal/client/ActivityClientExt.kt create mode 100644 temporal-kotlin/src/main/kotlin/io/temporal/client/ActivityClientOptionsExt.kt create mode 100644 temporal-kotlin/src/test/kotlin/io/temporal/client/ActivityClientExtTest.kt create mode 100644 temporal-kotlin/src/test/kotlin/io/temporal/client/ActivityClientOptionsExtTest.kt 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/ActivityClientExtTest.kt b/temporal-kotlin/src/test/kotlin/io/temporal/client/ActivityClientExtTest.kt new file mode 100644 index 0000000000..d2a890659e --- /dev/null +++ b/temporal-kotlin/src/test/kotlin/io/temporal/client/ActivityClientExtTest.kt @@ -0,0 +1,584 @@ +package io.temporal.client + +import com.google.common.reflect.TypeToken +import io.temporal.workflow.Functions +import org.junit.Assert.assertEquals +import org.junit.Assert.assertSame +import org.junit.Test +import java.lang.reflect.Type +import java.time.Duration +import java.util.concurrent.CompletableFuture +import java.util.concurrent.TimeUnit +import java.util.concurrent.TimeoutException +import java.util.stream.Stream + +class ActivityClientExtTest { + + private val options = StartActivityOptions.newBuilder() + .setId("activity-id") + .setTaskQueue("task-queue") + .setStartToCloseTimeout(Duration.ofSeconds(10)) + .build() + + @Test + fun `typed start extension should pass reified activity interface`() { + val recordingClient = RecordingActivityClient() + val activity = Functions.Proc2 { _, _ -> } + + val handle = recordingClient.client.start(activity, options, "arg1") + + val call = recordingClient.lastCall() + assertEquals("start", call.methodName) + assertEquals(TestActivity::class.java, call.args[0]) + assertSame(activity, call.args[1]) + assertSame(options, call.args[2]) + assertEquals("arg1", call.args[3]) + assertSame(recordingClient.handle, handle) + } + + @Test + fun `typed start extension should pass reified activity interface for result activity`() { + val recordingClient = RecordingActivityClient() + val activity = Functions.Func1 { "result" } + + val handle = recordingClient.client.start(activity, options) + + val call = recordingClient.lastCall() + assertEquals("start", call.methodName) + assertEquals(TestActivity::class.java, call.args[0]) + assertSame(activity, call.args[1]) + assertSame(options, call.args[2]) + assertSame(recordingClient.handle, handle) + } + + @Test + fun `generic start extension should pass reified result class and result type`() { + val recordingClient = RecordingActivityClient() + val resultType = object : TypeToken>() {}.type + + val handle = recordingClient.client.start>( + "ActivityType", + resultType, + options, + "arg1", + "arg2" + ) + + val call = recordingClient.lastCall() + assertEquals("start", call.methodName) + assertEquals("ActivityType", call.args[0]) + assertEquals(List::class.java, call.args[1]) + assertSame(resultType, call.args[2]) + assertSame(options, call.args[3]) + assertEquals(listOf("arg1", "arg2"), (call.args[4] as Array<*>).toList()) + assertSame(recordingClient.handle, handle) + } + + @Test + fun `typed execute extension should pass reified activity interface`() { + val recordingClient = RecordingActivityClient() + val activity = Functions.Func2 { _, arg -> arg } + + val result = recordingClient.client.execute( + activity, + options, + "arg1" + ) + + val call = recordingClient.lastCall() + assertEquals("execute", call.methodName) + assertEquals(TestActivity::class.java, call.args[0]) + assertSame(activity, call.args[1]) + assertSame(options, call.args[2]) + assertEquals("arg1", call.args[3]) + assertEquals("execute-result", result) + } + + @Test + fun `generic execute extension should pass reified result class and result type`() { + val recordingClient = RecordingActivityClient() + val resultType = object : TypeToken>() {}.type + + val result = recordingClient.client.execute>( + "ActivityType", + resultType, + options, + "arg1" + ) + + val call = recordingClient.lastCall() + assertEquals("execute", call.methodName) + assertEquals("ActivityType", call.args[0]) + assertEquals(List::class.java, call.args[1]) + assertSame(resultType, call.args[2]) + assertSame(options, call.args[3]) + assertEquals(listOf("arg1"), (call.args[4] as Array<*>).toList()) + assertEquals(listOf("execute-result"), result) + } + + @Test + fun `typed executeAsync extension should pass reified activity interface`() { + val recordingClient = RecordingActivityClient() + val activity = Functions.Func1 { "result" } + + val result = recordingClient.client.executeAsync(activity, options) + + val call = recordingClient.lastCall() + assertEquals("executeAsync", call.methodName) + assertEquals(TestActivity::class.java, call.args[0]) + assertSame(activity, call.args[1]) + assertSame(options, call.args[2]) + assertSame(recordingClient.future, result) + } + + @Test + fun `generic executeAsync extension should pass reified result class and result type`() { + val recordingClient = RecordingActivityClient() + val resultType = object : TypeToken>() {}.type + + val result = recordingClient.client.executeAsync>( + "ActivityType", + resultType, + options, + "arg1" + ) + + val call = recordingClient.lastCall() + assertEquals("executeAsync", call.methodName) + assertEquals("ActivityType", call.args[0]) + assertEquals(List::class.java, call.args[1]) + assertSame(resultType, call.args[2]) + assertSame(options, call.args[3]) + assertEquals(listOf("arg1"), (call.args[4] as Array<*>).toList()) + assertSame(recordingClient.future, result) + } + + @Test + fun `typed getHandle extension should pass reified result class`() { + val recordingClient = RecordingActivityClient() + + val handle = recordingClient.client.getHandle("activity-id") + + val call = recordingClient.lastCall() + assertEquals("getHandle", call.methodName) + assertEquals("activity-id", call.args[0]) + assertEquals(null, call.args[1]) + assertEquals(String::class.java, call.args[2]) + assertSame(recordingClient.handle, handle) + } + + @Test + fun `generic getHandle extension should pass reified result class and result type`() { + val recordingClient = RecordingActivityClient() + val resultType = object : TypeToken>() {}.type + + val handle = recordingClient.client.getHandle>( + "activity-id", + "run-id", + resultType + ) + + val call = recordingClient.lastCall() + assertEquals("getHandle", call.methodName) + assertEquals("activity-id", call.args[0]) + assertEquals("run-id", call.args[1]) + assertEquals(List::class.java, call.args[2]) + assertSame(resultType, call.args[3]) + assertSame(recordingClient.handle, handle) + } + + interface TestActivity { + fun execute(arg: String): String + } + + private data class RecordedCall( + val methodName: String, + val args: List + ) + + @Suppress("UNCHECKED_CAST") + private class RecordingActivityClient : ActivityClient { + val calls = mutableListOf() + val handle: ActivityHandle = RecordingActivityHandle() + val future: CompletableFuture = CompletableFuture.completedFuture("async-result") + val client: ActivityClient = this + + fun lastCall(): RecordedCall = calls.last() + + private fun record(methodName: String, vararg args: Any?) { + calls += RecordedCall(methodName, args.toList()) + } + + override fun start( + activityInterface: Class, + activity: Functions.Proc1, + options: StartActivityOptions + ): ActivityHandle { + record("start", activityInterface, activity, options) + return castHandle() + } + + override fun start( + activityInterface: Class, + activity: Functions.Proc2, + options: StartActivityOptions, + arg1: A1 + ): ActivityHandle { + record("start", activityInterface, activity, options, arg1) + return castHandle() + } + + override fun start( + activityInterface: Class, + activity: Functions.Proc3, + options: StartActivityOptions, + arg1: A1, + arg2: A2 + ): ActivityHandle { + record("start", activityInterface, activity, options, arg1, arg2) + return castHandle() + } + + override fun start( + activityInterface: Class, + activity: Functions.Proc4, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3 + ): ActivityHandle { + record("start", activityInterface, activity, options, arg1, arg2, arg3) + return castHandle() + } + + override fun start( + activityInterface: Class, + activity: Functions.Proc5, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4 + ): ActivityHandle { + record("start", activityInterface, activity, options, arg1, arg2, arg3, arg4) + return castHandle() + } + + override fun start( + activityInterface: Class, + activity: Functions.Proc6, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4, + arg5: A5 + ): ActivityHandle { + record("start", activityInterface, activity, options, arg1, arg2, arg3, arg4, arg5) + return castHandle() + } + + override fun start( + activityInterface: Class, + activity: Functions.Proc7, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4, + arg5: A5, + arg6: A6 + ): ActivityHandle { + record("start", activityInterface, activity, options, arg1, arg2, arg3, arg4, arg5, arg6) + return castHandle() + } + + override fun start( + activityInterface: Class, + activity: Functions.Func1, + options: StartActivityOptions + ): ActivityHandle { + record("start", activityInterface, activity, options) + return castHandle() + } + + override fun start( + activityInterface: Class, + activity: Functions.Func2, + options: StartActivityOptions, + arg1: A1 + ): ActivityHandle { + record("start", activityInterface, activity, options, arg1) + return castHandle() + } + + override fun start( + activityInterface: Class, + activity: Functions.Func3, + options: StartActivityOptions, + arg1: A1, + arg2: A2 + ): ActivityHandle { + record("start", activityInterface, activity, options, arg1, arg2) + return castHandle() + } + + override fun start( + activityInterface: Class, + activity: Functions.Func4, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3 + ): ActivityHandle { + record("start", activityInterface, activity, options, arg1, arg2, arg3) + return castHandle() + } + + override fun start( + activityInterface: Class, + activity: Functions.Func5, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4 + ): ActivityHandle { + record("start", activityInterface, activity, options, arg1, arg2, arg3, arg4) + return castHandle() + } + + override fun start( + activityInterface: Class, + activity: Functions.Func6, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4, + arg5: A5 + ): ActivityHandle { + record("start", activityInterface, activity, options, arg1, arg2, arg3, arg4, arg5) + return castHandle() + } + + override fun start( + activityInterface: Class, + activity: Functions.Func7, + options: StartActivityOptions, + arg1: A1, + arg2: A2, + arg3: A3, + arg4: A4, + arg5: A5, + arg6: A6 + ): ActivityHandle { + record("start", activityInterface, activity, options, arg1, arg2, arg3, arg4, arg5, arg6) + return castHandle() + } + + override fun start( + activityType: String, + options: StartActivityOptions, + vararg args: Any? + ): UntypedActivityHandle { + record("start", activityType, options, args) + return handle + } + + override fun start( + activityType: String, + resultClass: Class, + options: StartActivityOptions, + vararg args: Any? + ): ActivityHandle { + record("start", activityType, resultClass, options, args) + return castHandle() + } + + override fun start( + activityType: String, + resultClass: Class, + resultType: Type, + options: StartActivityOptions, + vararg args: Any? + ): ActivityHandle { + record("start", activityType, resultClass, resultType, options, args) + return castHandle() + } + + override fun execute( + activityInterface: Class, + activity: Functions.Func2, + options: StartActivityOptions, + arg1: A1 + ): R { + record("execute", activityInterface, activity, options, arg1) + return "execute-result" as R + } + + override fun execute( + activityType: String, + resultClass: Class, + resultType: Type, + options: StartActivityOptions, + vararg args: Any? + ): R { + record("execute", activityType, resultClass, resultType, options, args) + return listOf("execute-result") as R + } + + override fun executeAsync( + activityInterface: Class, + activity: Functions.Func1, + options: StartActivityOptions + ): CompletableFuture { + record("executeAsync", activityInterface, activity, options) + return future as CompletableFuture + } + + override fun executeAsync( + activityType: String, + resultClass: Class, + resultType: Type, + options: StartActivityOptions, + vararg args: Any? + ): CompletableFuture { + record("executeAsync", activityType, resultClass, resultType, options, args) + return future as CompletableFuture + } + + override fun getHandle( + activityId: String, + activityRunId: String? + ): UntypedActivityHandle { + record("getHandle", activityId, activityRunId) + return handle + } + + override fun getHandle( + activityId: String, + activityRunId: String?, + resultClass: Class + ): ActivityHandle { + record("getHandle", activityId, activityRunId, resultClass) + return castHandle() + } + + override fun getHandle( + activityId: String, + activityRunId: String?, + resultClass: Class, + resultType: Type? + ): ActivityHandle { + record("getHandle", activityId, activityRunId, resultClass, resultType) + return castHandle() + } + + override fun listExecutions(query: String): Stream { + throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") + } + + override fun countExecutions(query: String): ActivityExecutionCount { + throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") + } + + override fun newActivityCompletionClient(): ActivityCompletionClient { + throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") + } + + private fun castHandle(): ActivityHandle { + return handle as ActivityHandle + } + } + + private class RecordingActivityHandle : ActivityHandle { + override fun getActivityId(): String = "activity-id" + + override fun getActivityRunId(): String = "activity-run-id" + + override fun getResult(): Any { + throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") + } + + override fun getResult(timeout: Long, unit: TimeUnit): Any { + throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") + } + + override fun getResultAsync(): CompletableFuture { + throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") + } + + override fun getResultAsync(timeout: Long, unit: TimeUnit): CompletableFuture { + throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") + } + + override fun getResult(resultClass: Class): R { + throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") + } + + override fun getResult(resultClass: Class, resultType: Type?): R { + throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") + } + + @Throws(TimeoutException::class) + override fun getResult(timeout: Long, unit: TimeUnit, resultClass: Class): R { + throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") + } + + @Throws(TimeoutException::class) + override fun getResult( + timeout: Long, + unit: TimeUnit, + resultClass: Class, + resultType: Type? + ): R { + throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") + } + + override fun getResultAsync(resultClass: Class): CompletableFuture { + throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") + } + + override fun getResultAsync(resultClass: Class, resultType: Type?): CompletableFuture { + throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") + } + + override fun getResultAsync( + timeout: Long, + unit: TimeUnit, + resultClass: Class + ): CompletableFuture { + throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") + } + + override fun getResultAsync( + timeout: Long, + unit: TimeUnit, + resultClass: Class, + resultType: Type? + ): CompletableFuture { + throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") + } + + override fun describe(): ActivityExecutionDescription { + throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") + } + + override fun cancel() { + throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") + } + + override fun cancel(reason: String?) { + throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") + } + + override fun terminate() { + throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") + } + + override fun terminate(reason: String?) { + throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") + } + } +} 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) + } +} From ccec476d5415eb9801b9ff570ac4f5091811e0c0 Mon Sep 17 00:00:00 2001 From: 444am Date: Fri, 19 Jun 2026 20:32:33 +1000 Subject: [PATCH 2/2] Remove ActivityClientExtTest --- .../temporal/client/ActivityClientExtTest.kt | 584 ------------------ 1 file changed, 584 deletions(-) delete mode 100644 temporal-kotlin/src/test/kotlin/io/temporal/client/ActivityClientExtTest.kt diff --git a/temporal-kotlin/src/test/kotlin/io/temporal/client/ActivityClientExtTest.kt b/temporal-kotlin/src/test/kotlin/io/temporal/client/ActivityClientExtTest.kt deleted file mode 100644 index d2a890659e..0000000000 --- a/temporal-kotlin/src/test/kotlin/io/temporal/client/ActivityClientExtTest.kt +++ /dev/null @@ -1,584 +0,0 @@ -package io.temporal.client - -import com.google.common.reflect.TypeToken -import io.temporal.workflow.Functions -import org.junit.Assert.assertEquals -import org.junit.Assert.assertSame -import org.junit.Test -import java.lang.reflect.Type -import java.time.Duration -import java.util.concurrent.CompletableFuture -import java.util.concurrent.TimeUnit -import java.util.concurrent.TimeoutException -import java.util.stream.Stream - -class ActivityClientExtTest { - - private val options = StartActivityOptions.newBuilder() - .setId("activity-id") - .setTaskQueue("task-queue") - .setStartToCloseTimeout(Duration.ofSeconds(10)) - .build() - - @Test - fun `typed start extension should pass reified activity interface`() { - val recordingClient = RecordingActivityClient() - val activity = Functions.Proc2 { _, _ -> } - - val handle = recordingClient.client.start(activity, options, "arg1") - - val call = recordingClient.lastCall() - assertEquals("start", call.methodName) - assertEquals(TestActivity::class.java, call.args[0]) - assertSame(activity, call.args[1]) - assertSame(options, call.args[2]) - assertEquals("arg1", call.args[3]) - assertSame(recordingClient.handle, handle) - } - - @Test - fun `typed start extension should pass reified activity interface for result activity`() { - val recordingClient = RecordingActivityClient() - val activity = Functions.Func1 { "result" } - - val handle = recordingClient.client.start(activity, options) - - val call = recordingClient.lastCall() - assertEquals("start", call.methodName) - assertEquals(TestActivity::class.java, call.args[0]) - assertSame(activity, call.args[1]) - assertSame(options, call.args[2]) - assertSame(recordingClient.handle, handle) - } - - @Test - fun `generic start extension should pass reified result class and result type`() { - val recordingClient = RecordingActivityClient() - val resultType = object : TypeToken>() {}.type - - val handle = recordingClient.client.start>( - "ActivityType", - resultType, - options, - "arg1", - "arg2" - ) - - val call = recordingClient.lastCall() - assertEquals("start", call.methodName) - assertEquals("ActivityType", call.args[0]) - assertEquals(List::class.java, call.args[1]) - assertSame(resultType, call.args[2]) - assertSame(options, call.args[3]) - assertEquals(listOf("arg1", "arg2"), (call.args[4] as Array<*>).toList()) - assertSame(recordingClient.handle, handle) - } - - @Test - fun `typed execute extension should pass reified activity interface`() { - val recordingClient = RecordingActivityClient() - val activity = Functions.Func2 { _, arg -> arg } - - val result = recordingClient.client.execute( - activity, - options, - "arg1" - ) - - val call = recordingClient.lastCall() - assertEquals("execute", call.methodName) - assertEquals(TestActivity::class.java, call.args[0]) - assertSame(activity, call.args[1]) - assertSame(options, call.args[2]) - assertEquals("arg1", call.args[3]) - assertEquals("execute-result", result) - } - - @Test - fun `generic execute extension should pass reified result class and result type`() { - val recordingClient = RecordingActivityClient() - val resultType = object : TypeToken>() {}.type - - val result = recordingClient.client.execute>( - "ActivityType", - resultType, - options, - "arg1" - ) - - val call = recordingClient.lastCall() - assertEquals("execute", call.methodName) - assertEquals("ActivityType", call.args[0]) - assertEquals(List::class.java, call.args[1]) - assertSame(resultType, call.args[2]) - assertSame(options, call.args[3]) - assertEquals(listOf("arg1"), (call.args[4] as Array<*>).toList()) - assertEquals(listOf("execute-result"), result) - } - - @Test - fun `typed executeAsync extension should pass reified activity interface`() { - val recordingClient = RecordingActivityClient() - val activity = Functions.Func1 { "result" } - - val result = recordingClient.client.executeAsync(activity, options) - - val call = recordingClient.lastCall() - assertEquals("executeAsync", call.methodName) - assertEquals(TestActivity::class.java, call.args[0]) - assertSame(activity, call.args[1]) - assertSame(options, call.args[2]) - assertSame(recordingClient.future, result) - } - - @Test - fun `generic executeAsync extension should pass reified result class and result type`() { - val recordingClient = RecordingActivityClient() - val resultType = object : TypeToken>() {}.type - - val result = recordingClient.client.executeAsync>( - "ActivityType", - resultType, - options, - "arg1" - ) - - val call = recordingClient.lastCall() - assertEquals("executeAsync", call.methodName) - assertEquals("ActivityType", call.args[0]) - assertEquals(List::class.java, call.args[1]) - assertSame(resultType, call.args[2]) - assertSame(options, call.args[3]) - assertEquals(listOf("arg1"), (call.args[4] as Array<*>).toList()) - assertSame(recordingClient.future, result) - } - - @Test - fun `typed getHandle extension should pass reified result class`() { - val recordingClient = RecordingActivityClient() - - val handle = recordingClient.client.getHandle("activity-id") - - val call = recordingClient.lastCall() - assertEquals("getHandle", call.methodName) - assertEquals("activity-id", call.args[0]) - assertEquals(null, call.args[1]) - assertEquals(String::class.java, call.args[2]) - assertSame(recordingClient.handle, handle) - } - - @Test - fun `generic getHandle extension should pass reified result class and result type`() { - val recordingClient = RecordingActivityClient() - val resultType = object : TypeToken>() {}.type - - val handle = recordingClient.client.getHandle>( - "activity-id", - "run-id", - resultType - ) - - val call = recordingClient.lastCall() - assertEquals("getHandle", call.methodName) - assertEquals("activity-id", call.args[0]) - assertEquals("run-id", call.args[1]) - assertEquals(List::class.java, call.args[2]) - assertSame(resultType, call.args[3]) - assertSame(recordingClient.handle, handle) - } - - interface TestActivity { - fun execute(arg: String): String - } - - private data class RecordedCall( - val methodName: String, - val args: List - ) - - @Suppress("UNCHECKED_CAST") - private class RecordingActivityClient : ActivityClient { - val calls = mutableListOf() - val handle: ActivityHandle = RecordingActivityHandle() - val future: CompletableFuture = CompletableFuture.completedFuture("async-result") - val client: ActivityClient = this - - fun lastCall(): RecordedCall = calls.last() - - private fun record(methodName: String, vararg args: Any?) { - calls += RecordedCall(methodName, args.toList()) - } - - override fun start( - activityInterface: Class, - activity: Functions.Proc1, - options: StartActivityOptions - ): ActivityHandle { - record("start", activityInterface, activity, options) - return castHandle() - } - - override fun start( - activityInterface: Class, - activity: Functions.Proc2, - options: StartActivityOptions, - arg1: A1 - ): ActivityHandle { - record("start", activityInterface, activity, options, arg1) - return castHandle() - } - - override fun start( - activityInterface: Class, - activity: Functions.Proc3, - options: StartActivityOptions, - arg1: A1, - arg2: A2 - ): ActivityHandle { - record("start", activityInterface, activity, options, arg1, arg2) - return castHandle() - } - - override fun start( - activityInterface: Class, - activity: Functions.Proc4, - options: StartActivityOptions, - arg1: A1, - arg2: A2, - arg3: A3 - ): ActivityHandle { - record("start", activityInterface, activity, options, arg1, arg2, arg3) - return castHandle() - } - - override fun start( - activityInterface: Class, - activity: Functions.Proc5, - options: StartActivityOptions, - arg1: A1, - arg2: A2, - arg3: A3, - arg4: A4 - ): ActivityHandle { - record("start", activityInterface, activity, options, arg1, arg2, arg3, arg4) - return castHandle() - } - - override fun start( - activityInterface: Class, - activity: Functions.Proc6, - options: StartActivityOptions, - arg1: A1, - arg2: A2, - arg3: A3, - arg4: A4, - arg5: A5 - ): ActivityHandle { - record("start", activityInterface, activity, options, arg1, arg2, arg3, arg4, arg5) - return castHandle() - } - - override fun start( - activityInterface: Class, - activity: Functions.Proc7, - options: StartActivityOptions, - arg1: A1, - arg2: A2, - arg3: A3, - arg4: A4, - arg5: A5, - arg6: A6 - ): ActivityHandle { - record("start", activityInterface, activity, options, arg1, arg2, arg3, arg4, arg5, arg6) - return castHandle() - } - - override fun start( - activityInterface: Class, - activity: Functions.Func1, - options: StartActivityOptions - ): ActivityHandle { - record("start", activityInterface, activity, options) - return castHandle() - } - - override fun start( - activityInterface: Class, - activity: Functions.Func2, - options: StartActivityOptions, - arg1: A1 - ): ActivityHandle { - record("start", activityInterface, activity, options, arg1) - return castHandle() - } - - override fun start( - activityInterface: Class, - activity: Functions.Func3, - options: StartActivityOptions, - arg1: A1, - arg2: A2 - ): ActivityHandle { - record("start", activityInterface, activity, options, arg1, arg2) - return castHandle() - } - - override fun start( - activityInterface: Class, - activity: Functions.Func4, - options: StartActivityOptions, - arg1: A1, - arg2: A2, - arg3: A3 - ): ActivityHandle { - record("start", activityInterface, activity, options, arg1, arg2, arg3) - return castHandle() - } - - override fun start( - activityInterface: Class, - activity: Functions.Func5, - options: StartActivityOptions, - arg1: A1, - arg2: A2, - arg3: A3, - arg4: A4 - ): ActivityHandle { - record("start", activityInterface, activity, options, arg1, arg2, arg3, arg4) - return castHandle() - } - - override fun start( - activityInterface: Class, - activity: Functions.Func6, - options: StartActivityOptions, - arg1: A1, - arg2: A2, - arg3: A3, - arg4: A4, - arg5: A5 - ): ActivityHandle { - record("start", activityInterface, activity, options, arg1, arg2, arg3, arg4, arg5) - return castHandle() - } - - override fun start( - activityInterface: Class, - activity: Functions.Func7, - options: StartActivityOptions, - arg1: A1, - arg2: A2, - arg3: A3, - arg4: A4, - arg5: A5, - arg6: A6 - ): ActivityHandle { - record("start", activityInterface, activity, options, arg1, arg2, arg3, arg4, arg5, arg6) - return castHandle() - } - - override fun start( - activityType: String, - options: StartActivityOptions, - vararg args: Any? - ): UntypedActivityHandle { - record("start", activityType, options, args) - return handle - } - - override fun start( - activityType: String, - resultClass: Class, - options: StartActivityOptions, - vararg args: Any? - ): ActivityHandle { - record("start", activityType, resultClass, options, args) - return castHandle() - } - - override fun start( - activityType: String, - resultClass: Class, - resultType: Type, - options: StartActivityOptions, - vararg args: Any? - ): ActivityHandle { - record("start", activityType, resultClass, resultType, options, args) - return castHandle() - } - - override fun execute( - activityInterface: Class, - activity: Functions.Func2, - options: StartActivityOptions, - arg1: A1 - ): R { - record("execute", activityInterface, activity, options, arg1) - return "execute-result" as R - } - - override fun execute( - activityType: String, - resultClass: Class, - resultType: Type, - options: StartActivityOptions, - vararg args: Any? - ): R { - record("execute", activityType, resultClass, resultType, options, args) - return listOf("execute-result") as R - } - - override fun executeAsync( - activityInterface: Class, - activity: Functions.Func1, - options: StartActivityOptions - ): CompletableFuture { - record("executeAsync", activityInterface, activity, options) - return future as CompletableFuture - } - - override fun executeAsync( - activityType: String, - resultClass: Class, - resultType: Type, - options: StartActivityOptions, - vararg args: Any? - ): CompletableFuture { - record("executeAsync", activityType, resultClass, resultType, options, args) - return future as CompletableFuture - } - - override fun getHandle( - activityId: String, - activityRunId: String? - ): UntypedActivityHandle { - record("getHandle", activityId, activityRunId) - return handle - } - - override fun getHandle( - activityId: String, - activityRunId: String?, - resultClass: Class - ): ActivityHandle { - record("getHandle", activityId, activityRunId, resultClass) - return castHandle() - } - - override fun getHandle( - activityId: String, - activityRunId: String?, - resultClass: Class, - resultType: Type? - ): ActivityHandle { - record("getHandle", activityId, activityRunId, resultClass, resultType) - return castHandle() - } - - override fun listExecutions(query: String): Stream { - throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") - } - - override fun countExecutions(query: String): ActivityExecutionCount { - throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") - } - - override fun newActivityCompletionClient(): ActivityCompletionClient { - throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") - } - - private fun castHandle(): ActivityHandle { - return handle as ActivityHandle - } - } - - private class RecordingActivityHandle : ActivityHandle { - override fun getActivityId(): String = "activity-id" - - override fun getActivityRunId(): String = "activity-run-id" - - override fun getResult(): Any { - throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") - } - - override fun getResult(timeout: Long, unit: TimeUnit): Any { - throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") - } - - override fun getResultAsync(): CompletableFuture { - throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") - } - - override fun getResultAsync(timeout: Long, unit: TimeUnit): CompletableFuture { - throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") - } - - override fun getResult(resultClass: Class): R { - throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") - } - - override fun getResult(resultClass: Class, resultType: Type?): R { - throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") - } - - @Throws(TimeoutException::class) - override fun getResult(timeout: Long, unit: TimeUnit, resultClass: Class): R { - throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") - } - - @Throws(TimeoutException::class) - override fun getResult( - timeout: Long, - unit: TimeUnit, - resultClass: Class, - resultType: Type? - ): R { - throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") - } - - override fun getResultAsync(resultClass: Class): CompletableFuture { - throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") - } - - override fun getResultAsync(resultClass: Class, resultType: Type?): CompletableFuture { - throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") - } - - override fun getResultAsync( - timeout: Long, - unit: TimeUnit, - resultClass: Class - ): CompletableFuture { - throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") - } - - override fun getResultAsync( - timeout: Long, - unit: TimeUnit, - resultClass: Class, - resultType: Type? - ): CompletableFuture { - throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") - } - - override fun describe(): ActivityExecutionDescription { - throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") - } - - override fun cancel() { - throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") - } - - override fun cancel(reason: String?) { - throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") - } - - override fun terminate() { - throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") - } - - override fun terminate(reason: String?) { - throw UnsupportedOperationException("Not needed by ActivityClient extension tests.") - } - } -}