├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── dependabot.yml └── workflows │ ├── README.md │ ├── ci.yml │ ├── coverage.yml │ ├── features.yml │ ├── gradle-wrapper-validation.yml │ ├── omes.yml │ ├── prepare-release.yml │ └── publish-snapshot.yml ├── .gitignore ├── .gitmodules ├── .whitesource ├── AGENTS.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── build.gradle ├── docker ├── github │ ├── docker-compose.yaml │ └── dynamicconfig │ │ └── development.yaml └── native-image │ └── dockerfile ├── docs └── AOT-native-image.md ├── gradle ├── dependencyManagement.gradle ├── errorprone.gradle ├── gatherDependencies.gradle ├── jacoco.gradle ├── java.gradle ├── linting.gradle ├── publishing.gradle ├── versioning.gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── releases ├── v0.0.1-test ├── v1.0.4 ├── v1.0.5 ├── v1.0.6 ├── v1.0.7 ├── v1.0.8 ├── v1.0.9 ├── v1.1.0 ├── v1.10.0 ├── v1.11.0 ├── v1.12.0 ├── v1.13.0 ├── v1.14.0 ├── v1.15.0 ├── v1.15.1 ├── v1.16.0 ├── v1.17.0 ├── v1.17.0-RC1 ├── v1.18.0 ├── v1.18.0-RC1 ├── v1.18.1 ├── v1.18.2 ├── v1.19.0 ├── v1.19.1 ├── v1.2.0 ├── v1.20.0 ├── v1.20.1 ├── v1.21.0 ├── v1.21.1 ├── v1.21.2 ├── v1.22.0 ├── v1.22.1 ├── v1.22.2 ├── v1.22.3 ├── v1.23.0 ├── v1.23.1 ├── v1.24.0 ├── v1.24.1 ├── v1.24.2 ├── v1.25.0 ├── v1.25.1 ├── v1.26.0 ├── v1.26.1 ├── v1.27.0 ├── v1.28.0 ├── v1.28.1 ├── v1.29.0 ├── v1.3.0 ├── v1.3.1 ├── v1.4.0 ├── v1.5.0 ├── v1.6.0 ├── v1.7.0 ├── v1.7.1 ├── v1.8.0 ├── v1.8.1 ├── v1.9.0 └── v1.9.1 ├── settings.gradle ├── temporal-bom └── build.gradle ├── temporal-kotlin ├── .editorconfig ├── AGENTS.md ├── README.md ├── build.gradle └── src │ ├── main │ ├── kotlin │ │ └── io │ │ │ └── temporal │ │ │ ├── activity │ │ │ ├── ActivityExecutionContextExt.kt │ │ │ ├── ActivityOptionsExt.kt │ │ │ └── LocalActivityOptionsExt.kt │ │ │ ├── client │ │ │ ├── WorkflowClientExt.kt │ │ │ ├── WorkflowClientOptionsExt.kt │ │ │ ├── WorkflowOptionsExt.kt │ │ │ └── WorkflowStubExt.kt │ │ │ ├── common │ │ │ ├── RetryOptionsExt.kt │ │ │ ├── converter │ │ │ │ ├── DataConverterExt.kt │ │ │ │ └── KotlinObjectMapperFactory.kt │ │ │ └── metadata │ │ │ │ ├── ActivityMetadata.kt │ │ │ │ └── WorkflowMetadata.kt │ │ │ ├── internal │ │ │ └── async │ │ │ │ └── KotlinMethodReferenceDisassemblyService.kt │ │ │ ├── kotlin │ │ │ └── TemporalDsl.kt │ │ │ ├── serviceclient │ │ │ ├── RpcRetryOptionsExt.kt │ │ │ ├── WorkflowServiceStubsExt.kt │ │ │ └── WorkflowServiceStubsOptionsExt.kt │ │ │ ├── worker │ │ │ ├── WorkerExt.kt │ │ │ ├── WorkerFactoryExt.kt │ │ │ ├── WorkerFactoryOptionsExt.kt │ │ │ ├── WorkerOptionsExt.kt │ │ │ └── WorkflowImplementationOptionsExt.kt │ │ │ └── workflow │ │ │ ├── ActivityStubExt.kt │ │ │ ├── ChildWorkflowOptionsExt.kt │ │ │ ├── ChildWorkflowStubExt.kt │ │ │ ├── ContinueAsNewOptionsExt.kt │ │ │ ├── NexusOperationOptionsExt.kt │ │ │ ├── NexusServiceOptionsExt.kt │ │ │ └── SagaExt.kt │ └── resources │ │ └── META-INF │ │ └── services │ │ └── io.temporal.internal.async.spi.MethodReferenceDisassemblyService │ └── test │ ├── java │ └── io │ │ └── temporal │ │ └── internal │ │ └── async │ │ └── FunctionWrappingUtil.java │ ├── kotlin │ └── io │ │ └── temporal │ │ ├── activity │ │ ├── ActivityExecutionContextExtTest.kt │ │ ├── ActivityOptionsExtTest.kt │ │ └── LocalActivityOptionsExtTest.kt │ │ ├── client │ │ ├── WorkflowClientExtTest.kt │ │ ├── WorkflowClientOptionsExtTest.kt │ │ └── WorkflowOptionsExtTest.kt │ │ ├── common │ │ ├── RetryOptionsExtTest.kt │ │ ├── converter │ │ │ └── DataConverterExtTest.kt │ │ └── metadata │ │ │ ├── ActivityNameTest.kt │ │ │ ├── WorkflowMethodNameTest.kt │ │ │ └── WorkflowNameTest.kt │ │ ├── nexus │ │ ├── NexusOperationOptionsExtTest.kt │ │ └── NexusServiceOptionsExtTest.kt │ │ └── workflow │ │ ├── KotlinActivityStubExtTest.kt │ │ ├── KotlinAsyncChildWorkflowTest.kt │ │ ├── KotlinAsyncCompanionFunctionTest.kt │ │ ├── KotlinAsyncLambdaTest.kt │ │ ├── KotlinAsyncNexusTest.kt │ │ └── KotlinChildWorkflowStubExtTest.kt │ └── resources │ └── logback-test.xml ├── temporal-opentracing ├── README.md ├── build.gradle └── src │ ├── main │ └── java │ │ └── io │ │ └── temporal │ │ └── opentracing │ │ ├── OpenTracingClientInterceptor.java │ │ ├── OpenTracingOptions.java │ │ ├── OpenTracingSpanContextCodec.java │ │ ├── OpenTracingWorkerInterceptor.java │ │ ├── SpanBuilderProvider.java │ │ ├── SpanCreationContext.java │ │ ├── SpanOperationType.java │ │ ├── StandardTagNames.java │ │ ├── codec │ │ ├── TextMapCodec.java │ │ └── TextMapInjectExtractCodec.java │ │ ├── internal │ │ ├── ActionTypeAndNameSpanBuilderProvider.java │ │ ├── ContextAccessor.java │ │ ├── OpenTracingActivityInboundCallsInterceptor.java │ │ ├── OpenTracingNexusOperationInboundCallsInterceptor.java │ │ ├── OpenTracingWorkflowClientCallsInterceptor.java │ │ ├── OpenTracingWorkflowInboundCallsInterceptor.java │ │ ├── OpenTracingWorkflowOutboundCallsInterceptor.java │ │ └── SpanFactory.java │ │ └── provider │ │ └── DataDogOpenTracingSpanBuilderProvider.java │ └── test │ ├── java │ └── io │ │ └── temporal │ │ ├── opentracing │ │ ├── ActivityFailureTest.java │ │ ├── AsyncChildWorkflowTest.java │ │ ├── AsyncLambdaTest.java │ │ ├── CallbackContextTest.java │ │ ├── ContinueAsNewTest.java │ │ ├── CustomSpanNamingTest.java │ │ ├── ExceptionIgnoredTest.java │ │ ├── GlobalTracerTest.java │ │ ├── LocalActivityTest.java │ │ ├── NexusOperationTest.java │ │ ├── NoClientSpanTest.java │ │ ├── OpenTracingSpansHelper.java │ │ ├── SignalWithStartTest.java │ │ ├── SpanContextPropagationTest.java │ │ ├── WorkflowReplayTest.java │ │ ├── WorkflowRetryTest.java │ │ └── integration │ │ │ └── JaegerTest.java │ │ └── worker │ │ └── WorkflowEvictionTest.java │ └── resources │ └── logback-test.xml ├── temporal-remote-data-encoder ├── README.md ├── build.gradle └── src │ ├── main │ └── java │ │ └── io │ │ └── temporal │ │ ├── payload │ │ └── codec │ │ │ ├── AbstractRemoteDataEncoderCodec.java │ │ │ └── OkHttpRemoteDataEncoderCodec.java │ │ └── rde │ │ ├── httpserver │ │ ├── DataEncoderHandler.java │ │ └── RDEHttpServer.java │ │ └── servlet │ │ └── RDEServlet4.java │ └── test │ ├── java │ └── io │ │ └── temporal │ │ ├── ActivityImpl.java │ │ ├── ActivityWorkflow.java │ │ ├── PortUtils.java │ │ ├── RDEHttpServerFunctionalTest.java │ │ ├── RDEServlet4FunctionalTest.java │ │ ├── TestActivityArgs.java │ │ └── TestWorkflowStringArg.java │ └── resources │ └── logback-test.xml ├── temporal-sdk ├── .gitignore ├── AGENTS.md ├── build.gradle └── src │ ├── main │ ├── java │ │ └── io │ │ │ └── temporal │ │ │ ├── activity │ │ │ ├── Activity.java │ │ │ ├── ActivityCancellationType.java │ │ │ ├── ActivityExecutionContext.java │ │ │ ├── ActivityInfo.java │ │ │ ├── ActivityInterface.java │ │ │ ├── ActivityMethod.java │ │ │ ├── ActivityOptions.java │ │ │ ├── DynamicActivity.java │ │ │ ├── LocalActivityOptions.java │ │ │ └── ManualActivityCompletionClient.java │ │ │ ├── client │ │ │ ├── ActivityCanceledException.java │ │ │ ├── ActivityCompletionClient.java │ │ │ ├── ActivityCompletionClientImpl.java │ │ │ ├── ActivityCompletionException.java │ │ │ ├── ActivityCompletionFailureException.java │ │ │ ├── ActivityNotExistsException.java │ │ │ ├── ActivityPausedException.java │ │ │ ├── ActivityWorkerShutdownException.java │ │ │ ├── BatchRequest.java │ │ │ ├── BuildIdOperation.java │ │ │ ├── BuildIdReachability.java │ │ │ ├── CloudOperationsClient.java │ │ │ ├── CloudOperationsClientImpl.java │ │ │ ├── GetWorkflowExecutionHistoryIterator.java │ │ │ ├── ListScheduleListDescriptionIterator.java │ │ │ ├── OnConflictOptions.java │ │ │ ├── SignalWithStartBatchRequest.java │ │ │ ├── UpdateOptions.java │ │ │ ├── WithStartWorkflowOperation.java │ │ │ ├── WorkerBuildIdVersionSets.java │ │ │ ├── WorkerTaskReachability.java │ │ │ ├── WorkflowClient.java │ │ │ ├── WorkflowClientInternalImpl.java │ │ │ ├── WorkflowClientOptions.java │ │ │ ├── WorkflowException.java │ │ │ ├── WorkflowExecutionAlreadyStarted.java │ │ │ ├── WorkflowExecutionCount.java │ │ │ ├── WorkflowExecutionDescription.java │ │ │ ├── WorkflowExecutionMetadata.java │ │ │ ├── WorkflowFailedException.java │ │ │ ├── WorkflowInvocationHandler.java │ │ │ ├── WorkflowNotFoundException.java │ │ │ ├── WorkflowOptions.java │ │ │ ├── WorkflowQueryConditionallyRejectedException.java │ │ │ ├── WorkflowQueryException.java │ │ │ ├── WorkflowQueryRejectedException.java │ │ │ ├── WorkflowServiceException.java │ │ │ ├── WorkflowStub.java │ │ │ ├── WorkflowStubImpl.java │ │ │ ├── WorkflowUpdateException.java │ │ │ ├── WorkflowUpdateHandle.java │ │ │ ├── WorkflowUpdateStage.java │ │ │ ├── WorkflowUpdateTimeoutOrCancelledException.java │ │ │ └── schedules │ │ │ │ ├── Schedule.java │ │ │ │ ├── ScheduleAction.java │ │ │ │ ├── ScheduleActionExecution.java │ │ │ │ ├── ScheduleActionExecutionStartWorkflow.java │ │ │ │ ├── ScheduleActionResult.java │ │ │ │ ├── ScheduleActionStartWorkflow.java │ │ │ │ ├── ScheduleAlreadyRunningException.java │ │ │ │ ├── ScheduleBackfill.java │ │ │ │ ├── ScheduleCalendarSpec.java │ │ │ │ ├── ScheduleClient.java │ │ │ │ ├── ScheduleClientImpl.java │ │ │ │ ├── ScheduleClientOptions.java │ │ │ │ ├── ScheduleDescription.java │ │ │ │ ├── ScheduleException.java │ │ │ │ ├── ScheduleHandle.java │ │ │ │ ├── ScheduleHandleImpl.java │ │ │ │ ├── ScheduleInfo.java │ │ │ │ ├── ScheduleIntervalSpec.java │ │ │ │ ├── ScheduleListAction.java │ │ │ │ ├── ScheduleListActionStartWorkflow.java │ │ │ │ ├── ScheduleListDescription.java │ │ │ │ ├── ScheduleListInfo.java │ │ │ │ ├── ScheduleListSchedule.java │ │ │ │ ├── ScheduleListState.java │ │ │ │ ├── ScheduleOptions.java │ │ │ │ ├── SchedulePolicy.java │ │ │ │ ├── ScheduleRange.java │ │ │ │ ├── ScheduleSpec.java │ │ │ │ ├── ScheduleState.java │ │ │ │ ├── ScheduleUpdate.java │ │ │ │ └── ScheduleUpdateInput.java │ │ │ ├── common │ │ │ ├── CronSchedule.java │ │ │ ├── Experimental.java │ │ │ ├── MethodRetry.java │ │ │ ├── Priority.java │ │ │ ├── RetryOptions.java │ │ │ ├── SearchAttribute.java │ │ │ ├── SearchAttributeKey.java │ │ │ ├── SearchAttributeUpdate.java │ │ │ ├── SearchAttributes.java │ │ │ ├── VersioningBehavior.java │ │ │ ├── VersioningIntent.java │ │ │ ├── VersioningOverride.java │ │ │ ├── WorkerDeploymentVersion.java │ │ │ ├── WorkflowExecutionHistory.java │ │ │ ├── context │ │ │ │ └── ContextPropagator.java │ │ │ ├── converter │ │ │ │ ├── AbstractProtobufPayloadConverter.java │ │ │ │ ├── ByteArrayPayloadConverter.java │ │ │ │ ├── CodecDataConverter.java │ │ │ │ ├── ConverterUtils.java │ │ │ │ ├── DataConverter.java │ │ │ │ ├── DataConverterException.java │ │ │ │ ├── DefaultDataConverter.java │ │ │ │ ├── EncodedValues.java │ │ │ │ ├── EncodingKeys.java │ │ │ │ ├── FailureConverter.java │ │ │ │ ├── GlobalDataConverter.java │ │ │ │ ├── GsonJsonPayloadConverter.java │ │ │ │ ├── JacksonJsonPayloadConverter.java │ │ │ │ ├── NullPayloadConverter.java │ │ │ │ ├── PayloadAndFailureDataConverter.java │ │ │ │ ├── PayloadConverter.java │ │ │ │ ├── ProtobufJsonPayloadConverter.java │ │ │ │ ├── ProtobufPayloadConverter.java │ │ │ │ ├── RawValue.java │ │ │ │ ├── StdConverterBackwardsCompatAdapter.java │ │ │ │ └── Values.java │ │ │ ├── interceptors │ │ │ │ ├── ActivityExecutionContextBase.java │ │ │ │ ├── ActivityInboundCallsInterceptor.java │ │ │ │ ├── ActivityInboundCallsInterceptorBase.java │ │ │ │ ├── Header.java │ │ │ │ ├── NexusOperationInboundCallsInterceptor.java │ │ │ │ ├── NexusOperationInboundCallsInterceptorBase.java │ │ │ │ ├── NexusOperationOutboundCallsInterceptor.java │ │ │ │ ├── NexusOperationOutboundCallsInterceptorBase.java │ │ │ │ ├── ScheduleClientCallsInterceptor.java │ │ │ │ ├── ScheduleClientCallsInterceptorBase.java │ │ │ │ ├── ScheduleClientInterceptor.java │ │ │ │ ├── ScheduleClientInterceptorBase.java │ │ │ │ ├── WorkerInterceptor.java │ │ │ │ ├── WorkerInterceptorBase.java │ │ │ │ ├── WorkflowClientCallsInterceptor.java │ │ │ │ ├── WorkflowClientCallsInterceptorBase.java │ │ │ │ ├── WorkflowClientInterceptor.java │ │ │ │ ├── WorkflowClientInterceptorBase.java │ │ │ │ ├── WorkflowInboundCallsInterceptor.java │ │ │ │ ├── WorkflowInboundCallsInterceptorBase.java │ │ │ │ ├── WorkflowOutboundCallsInterceptor.java │ │ │ │ └── WorkflowOutboundCallsInterceptorBase.java │ │ │ ├── metadata │ │ │ │ ├── POJOActivityImplMetadata.java │ │ │ │ ├── POJOActivityInterfaceMetadata.java │ │ │ │ ├── POJOActivityMethodMetadata.java │ │ │ │ ├── POJOReflectionUtils.java │ │ │ │ ├── POJOWorkflowImplMetadata.java │ │ │ │ ├── POJOWorkflowInterfaceMetadata.java │ │ │ │ ├── POJOWorkflowMethod.java │ │ │ │ ├── POJOWorkflowMethodMetadata.java │ │ │ │ └── WorkflowMethodType.java │ │ │ └── reporter │ │ │ │ └── MicrometerClientStatsReporter.java │ │ │ ├── failure │ │ │ ├── ActivityFailure.java │ │ │ ├── ApplicationErrorCategory.java │ │ │ ├── ApplicationFailure.java │ │ │ ├── CanceledFailure.java │ │ │ ├── ChildWorkflowFailure.java │ │ │ ├── DefaultFailureConverter.java │ │ │ ├── NexusOperationFailure.java │ │ │ ├── ServerFailure.java │ │ │ ├── TemporalException.java │ │ │ ├── TemporalFailure.java │ │ │ ├── TerminatedFailure.java │ │ │ └── TimeoutFailure.java │ │ │ ├── internal │ │ │ ├── AGENTS.md │ │ │ ├── Config.java │ │ │ ├── activity │ │ │ │ ├── ActivityExecutionContextFactory.java │ │ │ │ ├── ActivityExecutionContextFactoryImpl.java │ │ │ │ ├── ActivityExecutionContextImpl.java │ │ │ │ ├── ActivityInfoImpl.java │ │ │ │ ├── ActivityInfoInternal.java │ │ │ │ ├── ActivityInternal.java │ │ │ │ ├── ActivityPollResponseToInfo.java │ │ │ │ ├── ActivityTaskExecutors.java │ │ │ │ ├── ActivityTaskHandlerImpl.java │ │ │ │ ├── CompletionAwareManualCompletionClient.java │ │ │ │ ├── CurrentActivityExecutionContext.java │ │ │ │ ├── HeartbeatContext.java │ │ │ │ ├── HeartbeatContextImpl.java │ │ │ │ ├── InternalActivityExecutionContext.java │ │ │ │ ├── LocalActivityExecutionContextFactoryImpl.java │ │ │ │ ├── LocalActivityExecutionContextImpl.java │ │ │ │ └── RootActivityInboundCallsInterceptor.java │ │ │ ├── async │ │ │ │ ├── MethodReferenceDisassembler.java │ │ │ │ └── spi │ │ │ │ │ └── MethodReferenceDisassemblyService.java │ │ │ ├── client │ │ │ │ ├── ActivityClientHelper.java │ │ │ │ ├── CompletedWorkflowUpdateHandleImpl.java │ │ │ │ ├── EagerPaginator.java │ │ │ │ ├── EagerWorkflowTaskDispatcher.java │ │ │ │ ├── LazyWorkflowUpdateHandleImpl.java │ │ │ │ ├── ListWorkflowExecutionIterator.java │ │ │ │ ├── NamespaceInjectWorkflowServiceStubs.java │ │ │ │ ├── NexusStartWorkflowRequest.java │ │ │ │ ├── RootScheduleClientInvoker.java │ │ │ │ ├── RootWorkflowClientInvoker.java │ │ │ │ ├── ScheduleProtoUtil.java │ │ │ │ ├── WorkerFactoryRegistry.java │ │ │ │ ├── WorkflowClientHelper.java │ │ │ │ ├── WorkflowClientInternal.java │ │ │ │ ├── WorkflowClientLongPollAsyncHelper.java │ │ │ │ ├── WorkflowClientLongPollHelper.java │ │ │ │ ├── WorkflowClientRequestFactory.java │ │ │ │ └── external │ │ │ │ │ ├── GenericWorkflowClient.java │ │ │ │ │ ├── GenericWorkflowClientImpl.java │ │ │ │ │ ├── ManualActivityCompletionClientFactory.java │ │ │ │ │ ├── ManualActivityCompletionClientFactoryImpl.java │ │ │ │ │ ├── ManualActivityCompletionClientImpl.java │ │ │ │ │ └── package-info.java │ │ │ ├── common │ │ │ │ ├── ActivityOptionUtils.java │ │ │ │ ├── FailureUtils.java │ │ │ │ ├── GrpcUtils.java │ │ │ │ ├── HeaderUtils.java │ │ │ │ ├── HistoryJsonUtils.java │ │ │ │ ├── HistoryProtoTextUtils.java │ │ │ │ ├── InternalUtils.java │ │ │ │ ├── JavaLambdaUtils.java │ │ │ │ ├── LinkConverter.java │ │ │ │ ├── NexusUtil.java │ │ │ │ ├── NonIdempotentHandle.java │ │ │ │ ├── ProtoConverters.java │ │ │ │ ├── ProtoEnumNameUtils.java │ │ │ │ ├── ProtobufTimeUtils.java │ │ │ │ ├── ProtocolType.java │ │ │ │ ├── ProtocolUtils.java │ │ │ │ ├── RetryOptionsUtils.java │ │ │ │ ├── SdkFlag.java │ │ │ │ ├── SdkFlags.java │ │ │ │ ├── SearchAttributePayloadConverter.java │ │ │ │ ├── SearchAttributesUtil.java │ │ │ │ ├── ShadingHelpers.java │ │ │ │ ├── ThrowableFunc1.java │ │ │ │ ├── UpdateMessage.java │ │ │ │ ├── WorkflowExecutionHistory.java │ │ │ │ ├── WorkflowExecutionUtils.java │ │ │ │ ├── env │ │ │ │ │ ├── DebugModeUtils.java │ │ │ │ │ ├── EnvironmentVariableUtils.java │ │ │ │ │ ├── EnvironmentVariablesProvider.java │ │ │ │ │ ├── ReflectionUtils.java │ │ │ │ │ └── SystemEnvironmentVariablesProvider.java │ │ │ │ └── kotlin │ │ │ │ │ └── KotlinDetector.java │ │ │ ├── context │ │ │ │ └── ContextThreadLocal.java │ │ │ ├── history │ │ │ │ ├── LocalActivityMarkerMetadata.java │ │ │ │ ├── LocalActivityMarkerUtils.java │ │ │ │ ├── MarkerUtils.java │ │ │ │ └── VersionMarkerUtils.java │ │ │ ├── logging │ │ │ │ ├── LoggerTag.java │ │ │ │ └── ReplayAwareLogger.java │ │ │ ├── nexus │ │ │ │ ├── CurrentNexusOperationContext.java │ │ │ │ ├── InternalNexusOperationContext.java │ │ │ │ ├── NexusInternal.java │ │ │ │ ├── NexusTaskHandlerImpl.java │ │ │ │ ├── OperationTokenType.java │ │ │ │ ├── OperationTokenUtil.java │ │ │ │ ├── PayloadSerializer.java │ │ │ │ ├── RootNexusOperationInboundCallsInterceptor.java │ │ │ │ ├── RootNexusOperationOutboundCallsInterceptor.java │ │ │ │ ├── TemporalInterceptorMiddleware.java │ │ │ │ └── WorkflowRunOperationToken.java │ │ │ ├── package-info.java │ │ │ ├── replay │ │ │ │ ├── BasicWorkflowContext.java │ │ │ │ ├── ChildWorkflowTaskFailedException.java │ │ │ │ ├── QueryResult.java │ │ │ │ ├── ReplayAware.java │ │ │ │ ├── ReplayAwareScope.java │ │ │ │ ├── ReplayWorkflow.java │ │ │ │ ├── ReplayWorkflowContext.java │ │ │ │ ├── ReplayWorkflowContextImpl.java │ │ │ │ ├── ReplayWorkflowExecutor.java │ │ │ │ ├── ReplayWorkflowFactory.java │ │ │ │ ├── ReplayWorkflowRunTaskHandler.java │ │ │ │ ├── ReplayWorkflowTaskHandler.java │ │ │ │ ├── ServiceWorkflowHistoryIterator.java │ │ │ │ ├── WorkflowContext.java │ │ │ │ ├── WorkflowHistoryIterator.java │ │ │ │ ├── WorkflowMutableState.java │ │ │ │ ├── WorkflowRunTaskHandler.java │ │ │ │ └── WorkflowTaskResult.java │ │ │ ├── statemachines │ │ │ │ ├── ActivityStateMachine.java │ │ │ │ ├── ActivityStateMachine.puml │ │ │ │ ├── CancelExternalStateMachine.java │ │ │ │ ├── CancelExternalStateMachine.puml │ │ │ │ ├── CancelNexusOperationStateMachine.java │ │ │ │ ├── CancelWorkflowStateMachine.java │ │ │ │ ├── CancelWorkflowStateMachine.puml │ │ │ │ ├── CancellableCommand.java │ │ │ │ ├── ChildWorkflowStateMachine.java │ │ │ │ ├── ChildWorkflowStateMachine.puml │ │ │ │ ├── CompleteWorkflowStateMachine.java │ │ │ │ ├── CompleteWorkflowStateMachine.puml │ │ │ │ ├── ContinueAsNewWorkflowStateMachine.java │ │ │ │ ├── ContinueAsNewWorkflowStateMachine.puml │ │ │ │ ├── DynamicCallback.java │ │ │ │ ├── DynamicTransitionAction.java │ │ │ │ ├── EntityStateMachine.java │ │ │ │ ├── EntityStateMachineBase.java │ │ │ │ ├── EntityStateMachineInitialCommand.java │ │ │ │ ├── ExecuteActivityParameters.java │ │ │ │ ├── ExecuteLocalActivityParameters.java │ │ │ │ ├── FailWorkflowStateMachine.java │ │ │ │ ├── FailWorkflowStateMachine.puml │ │ │ │ ├── FixedTransitionAction.java │ │ │ │ ├── InternalWorkflowTaskException.java │ │ │ │ ├── LocalActivityCallback.java │ │ │ │ ├── LocalActivityStateMachine.java │ │ │ │ ├── LocalActivityStateMachine.puml │ │ │ │ ├── MutableSideEffectStateMachine.java │ │ │ │ ├── MutableSideEffectStateMachine.puml │ │ │ │ ├── NexusOperationStateMachine.java │ │ │ │ ├── SideEffectStateMachine.java │ │ │ │ ├── SideEffectStateMachine.puml │ │ │ │ ├── SignalExternalStateMachine.java │ │ │ │ ├── SignalExternalStateMachine.puml │ │ │ │ ├── StartChildWorkflowExecutionParameters.java │ │ │ │ ├── StateMachine.java │ │ │ │ ├── StateMachineCommandUtils.java │ │ │ │ ├── StateMachineDefinition.java │ │ │ │ ├── StatesMachinesCallback.java │ │ │ │ ├── TimerStateMachine.java │ │ │ │ ├── TimerStateMachine.puml │ │ │ │ ├── Transition.java │ │ │ │ ├── TransitionAction.java │ │ │ │ ├── TransitionEvent.java │ │ │ │ ├── UnsupportedContinueAsNewRequest.java │ │ │ │ ├── UnsupportedVersion.java │ │ │ │ ├── UpdateProtocolCallback.java │ │ │ │ ├── UpdateProtocolStateMachine.java │ │ │ │ ├── UpdateProtocolStateMachine.puml │ │ │ │ ├── UpsertSearchAttributesStateMachine.java │ │ │ │ ├── UpsertSearchAttributesStateMachine.puml │ │ │ │ ├── VersionStateMachine.java │ │ │ │ ├── VersionStateMachine.puml │ │ │ │ ├── WFTBuffer.java │ │ │ │ ├── WorkflowPropertiesModifiedStateMachine.java │ │ │ │ ├── WorkflowStateMachines.java │ │ │ │ ├── WorkflowTaskStateMachine.java │ │ │ │ └── WorkflowTaskStateMachine.puml │ │ │ ├── sync │ │ │ │ ├── ActivityInvocationHandler.java │ │ │ │ ├── ActivityInvocationHandlerBase.java │ │ │ │ ├── ActivityStubBase.java │ │ │ │ ├── ActivityStubImpl.java │ │ │ │ ├── AllOfPromise.java │ │ │ │ ├── AsyncInternal.java │ │ │ │ ├── BaseRootWorkflowInboundCallsInterceptor.java │ │ │ │ ├── CancellationScopeImpl.java │ │ │ │ ├── ChildWorkflowInvocationHandler.java │ │ │ │ ├── ChildWorkflowStubImpl.java │ │ │ │ ├── CompletablePromiseImpl.java │ │ │ │ ├── ContinueAsNewWorkflowInvocationHandler.java │ │ │ │ ├── DestroyWorkflowThreadError.java │ │ │ │ ├── DeterministicRunner.java │ │ │ │ ├── DeterministicRunnerImpl.java │ │ │ │ ├── DynamicSyncWorkflowDefinition.java │ │ │ │ ├── ExecutionInfoStrategy.java │ │ │ │ ├── ExternalWorkflowInvocationHandler.java │ │ │ │ ├── ExternalWorkflowStubImpl.java │ │ │ │ ├── LocalActivityInvocationHandler.java │ │ │ │ ├── LocalActivityStubImpl.java │ │ │ │ ├── NexusOperationExecutionImpl.java │ │ │ │ ├── NexusOperationHandleImpl.java │ │ │ │ ├── NexusServiceInvocationHandler.java │ │ │ │ ├── NexusServiceStubImpl.java │ │ │ │ ├── POJOWorkflowImplementationFactory.java │ │ │ │ ├── PotentialDeadlockException.java │ │ │ │ ├── QueryDispatcher.java │ │ │ │ ├── ReadOnlyException.java │ │ │ │ ├── RootWorkflowThreadImpl.java │ │ │ │ ├── RunnerLocalInternal.java │ │ │ │ ├── SignalDispatcher.java │ │ │ │ ├── SignalHandlerInfo.java │ │ │ │ ├── StartNexusCallInternal.java │ │ │ │ ├── Status.java │ │ │ │ ├── StubMarker.java │ │ │ │ ├── SyncWorkflow.java │ │ │ │ ├── SyncWorkflowContext.java │ │ │ │ ├── SyncWorkflowDefinition.java │ │ │ │ ├── UpdateDispatcher.java │ │ │ │ ├── UpdateHandlerInfo.java │ │ │ │ ├── UpdateInfoImpl.java │ │ │ │ ├── WorkflowExecutionHandler.java │ │ │ │ ├── WorkflowInfoImpl.java │ │ │ │ ├── WorkflowInternal.java │ │ │ │ ├── WorkflowLockImpl.java │ │ │ │ ├── WorkflowMethodThreadNameStrategy.java │ │ │ │ ├── WorkflowQueueDeprecatedImpl.java │ │ │ │ ├── WorkflowQueueImpl.java │ │ │ │ ├── WorkflowRejectedExecutionError.java │ │ │ │ ├── WorkflowRetryerInternal.java │ │ │ │ ├── WorkflowSemaphoreImpl.java │ │ │ │ ├── WorkflowThread.java │ │ │ │ ├── WorkflowThreadContext.java │ │ │ │ ├── WorkflowThreadExecutor.java │ │ │ │ ├── WorkflowThreadImpl.java │ │ │ │ ├── WorkflowThreadLocalInternal.java │ │ │ │ └── WorkflowThreadScheduler.java │ │ │ ├── task │ │ │ │ ├── ThreadConfigurator.java │ │ │ │ └── VirtualThreadDelegate.java │ │ │ └── worker │ │ │ │ ├── ActivityPollTask.java │ │ │ │ ├── ActivityTask.java │ │ │ │ ├── ActivityTaskHandler.java │ │ │ │ ├── ActivityWorker.java │ │ │ │ ├── BlockCallerPolicy.java │ │ │ │ ├── CircularLongBuffer.java │ │ │ │ ├── EagerActivityDispatcher.java │ │ │ │ ├── EagerActivitySlotsReservation.java │ │ │ │ ├── ExecutorThreadFactory.java │ │ │ │ ├── LocalActivityAttemptTask.java │ │ │ │ ├── LocalActivityDispatcher.java │ │ │ │ ├── LocalActivityExecutionContext.java │ │ │ │ ├── LocalActivityResult.java │ │ │ │ ├── LocalActivitySlotSupplierQueue.java │ │ │ │ ├── LocalActivityWorker.java │ │ │ │ ├── NexusPollTask.java │ │ │ │ ├── NexusTask.java │ │ │ │ ├── NexusTaskHandler.java │ │ │ │ ├── NexusWorker.java │ │ │ │ ├── NoopWorker.java │ │ │ │ ├── PollTaskExecutor.java │ │ │ │ ├── Poller.java │ │ │ │ ├── PollerOptions.java │ │ │ │ ├── QueryReplayHelper.java │ │ │ │ ├── ShutdownManager.java │ │ │ │ ├── Shutdownable.java │ │ │ │ ├── ShutdownableTaskExecutor.java │ │ │ │ ├── SingleWorkerOptions.java │ │ │ │ ├── SlotReservationData.java │ │ │ │ ├── Startable.java │ │ │ │ ├── StickyQueueBalancer.java │ │ │ │ ├── Suspendable.java │ │ │ │ ├── SuspendableWorker.java │ │ │ │ ├── SyncActivityWorker.java │ │ │ │ ├── SyncNexusWorker.java │ │ │ │ ├── SyncWorkflowWorker.java │ │ │ │ ├── TaskExecutor.java │ │ │ │ ├── Throttler.java │ │ │ │ ├── TrackingSlotSupplier.java │ │ │ │ ├── UnableToAcquireLockException.java │ │ │ │ ├── WorkerLifecycleState.java │ │ │ │ ├── WorkerThreadsNameHelper.java │ │ │ │ ├── WorkerVersioningOptions.java │ │ │ │ ├── WorkerVersioningProtoUtils.java │ │ │ │ ├── WorkerWithLifecycle.java │ │ │ │ ├── WorkflowExecutionException.java │ │ │ │ ├── WorkflowExecutorCache.java │ │ │ │ ├── WorkflowPollTask.java │ │ │ │ ├── WorkflowRunLockManager.java │ │ │ │ ├── WorkflowTask.java │ │ │ │ ├── WorkflowTaskHandler.java │ │ │ │ └── WorkflowWorker.java │ │ │ ├── nexus │ │ │ ├── Nexus.java │ │ │ ├── NexusOperationContext.java │ │ │ ├── WorkflowHandle.java │ │ │ ├── WorkflowHandleFactory.java │ │ │ ├── WorkflowHandleInvoker.java │ │ │ ├── WorkflowMethodFactory.java │ │ │ ├── WorkflowMethodMethodInvoker.java │ │ │ ├── WorkflowRunOperation.java │ │ │ ├── WorkflowRunOperationImpl.java │ │ │ └── WorkflowStubHandleInvoker.java │ │ │ ├── payload │ │ │ ├── codec │ │ │ │ ├── ChainCodec.java │ │ │ │ ├── PayloadCodec.java │ │ │ │ ├── PayloadCodecException.java │ │ │ │ └── ZlibPayloadCodec.java │ │ │ └── context │ │ │ │ ├── ActivitySerializationContext.java │ │ │ │ ├── HasWorkflowSerializationContext.java │ │ │ │ ├── SerializationContext.java │ │ │ │ └── WorkflowSerializationContext.java │ │ │ ├── worker │ │ │ ├── ActiveThreadReportingExecutor.java │ │ │ ├── MetricsType.java │ │ │ ├── NonDeterministicException.java │ │ │ ├── PollerTypeMetricsTag.java │ │ │ ├── TypeAlreadyRegisteredException.java │ │ │ ├── Worker.java │ │ │ ├── WorkerDeploymentOptions.java │ │ │ ├── WorkerFactory.java │ │ │ ├── WorkerFactoryOptions.java │ │ │ ├── WorkerMetricsTag.java │ │ │ ├── WorkerOptions.java │ │ │ ├── WorkflowImplementationOptions.java │ │ │ ├── WorkflowTaskDispatchHandle.java │ │ │ └── tuning │ │ │ │ ├── ActivitySlotInfo.java │ │ │ │ ├── CompositeTuner.java │ │ │ │ ├── FixedSizeSlotSupplier.java │ │ │ │ ├── JVMSystemResourceInfo.java │ │ │ │ ├── LocalActivitySlotInfo.java │ │ │ │ ├── NexusSlotInfo.java │ │ │ │ ├── PIDController.java │ │ │ │ ├── ResourceBasedController.java │ │ │ │ ├── ResourceBasedControllerOptions.java │ │ │ │ ├── ResourceBasedSlotOptions.java │ │ │ │ ├── ResourceBasedSlotSupplier.java │ │ │ │ ├── ResourceBasedTuner.java │ │ │ │ ├── SlotInfo.java │ │ │ │ ├── SlotMarkUsedContext.java │ │ │ │ ├── SlotPermit.java │ │ │ │ ├── SlotReleaseContext.java │ │ │ │ ├── SlotReleaseReason.java │ │ │ │ ├── SlotReserveContext.java │ │ │ │ ├── SlotSupplier.java │ │ │ │ ├── SlotSupplierFuture.java │ │ │ │ ├── SystemResourceInfo.java │ │ │ │ ├── WorkerTuner.java │ │ │ │ └── WorkflowSlotInfo.java │ │ │ └── workflow │ │ │ ├── ActivityStub.java │ │ │ ├── Async.java │ │ │ ├── CancelExternalWorkflowException.java │ │ │ ├── CancellationScope.java │ │ │ ├── ChildWorkflowCancellationType.java │ │ │ ├── ChildWorkflowOptions.java │ │ │ ├── ChildWorkflowStub.java │ │ │ ├── CompletablePromise.java │ │ │ ├── ContinueAsNewOptions.java │ │ │ ├── DynamicQueryHandler.java │ │ │ ├── DynamicSignalHandler.java │ │ │ ├── DynamicUpdateHandler.java │ │ │ ├── DynamicWorkflow.java │ │ │ ├── ExternalWorkflowStub.java │ │ │ ├── Functions.java │ │ │ ├── HandlerUnfinishedPolicy.java │ │ │ ├── NexusOperationExecution.java │ │ │ ├── NexusOperationHandle.java │ │ │ ├── NexusOperationOptions.java │ │ │ ├── NexusServiceOptions.java │ │ │ ├── NexusServiceStub.java │ │ │ ├── Promise.java │ │ │ ├── QueryMethod.java │ │ │ ├── QueueConsumer.java │ │ │ ├── QueueProducer.java │ │ │ ├── Saga.java │ │ │ ├── SignalExternalWorkflowException.java │ │ │ ├── SignalMethod.java │ │ │ ├── TimerOptions.java │ │ │ ├── UpdateInfo.java │ │ │ ├── UpdateMethod.java │ │ │ ├── UpdateValidatorMethod.java │ │ │ ├── Workflow.java │ │ │ ├── WorkflowInfo.java │ │ │ ├── WorkflowInit.java │ │ │ ├── WorkflowInterface.java │ │ │ ├── WorkflowLocal.java │ │ │ ├── WorkflowLock.java │ │ │ ├── WorkflowMethod.java │ │ │ ├── WorkflowQueue.java │ │ │ ├── WorkflowSemaphore.java │ │ │ ├── WorkflowThreadLocal.java │ │ │ ├── WorkflowVersioningBehavior.java │ │ │ ├── package-info.java │ │ │ └── unsafe │ │ │ └── WorkflowUnsafe.java │ ├── java21 │ │ └── io │ │ │ └── temporal │ │ │ └── internal │ │ │ └── task │ │ │ └── VirtualThreadDelegate.java │ └── resources │ │ └── META-INF │ │ └── native-image │ │ └── io │ │ └── temporal │ │ └── temporal-sdk │ │ ├── jni-config.json │ │ ├── native-image.properties │ │ ├── proxy-config.json │ │ ├── reflect-config.json │ │ ├── resource-config.json │ │ └── serialization-config.json │ ├── test │ ├── java │ │ └── io │ │ │ └── temporal │ │ │ ├── activity │ │ │ ├── ActivityHeartbeatSentOnFailureTest.java │ │ │ ├── ActivityHeartbeatThrottlingTest.java │ │ │ ├── ActivityNextRetryDelayTest.java │ │ │ ├── ActivityOptionsTest.java │ │ │ ├── ActivityPauseTest.java │ │ │ ├── ActivityTestOptions.java │ │ │ ├── DefaultActivityOptionsOnWorkflowNotSetTest.java │ │ │ ├── DefaultActivityOptionsSetOnWorkflowTest.java │ │ │ └── LocalActivityMethodOptionsTest.java │ │ │ ├── authorization │ │ │ └── AuthorizationTokenTest.java │ │ │ ├── client │ │ │ ├── CloudOperationsClientTest.java │ │ │ ├── CountWorkflowsTest.java │ │ │ ├── ListWorkflowExecutionsInterceptorTest.java │ │ │ ├── ListWorkflowExecutionsTest.java │ │ │ ├── WorkflowOptionsTest.java │ │ │ ├── functional │ │ │ │ ├── BuildIdVersionSetsTest.java │ │ │ │ ├── CancelTest.java │ │ │ │ ├── GetExecutionAfterStartTest.java │ │ │ │ ├── GetResultsAsyncOverMaximumLongPollWaitTest.java │ │ │ │ ├── GetResultsOverLongPollTimeoutTest.java │ │ │ │ ├── GetResultsSyncOverMaximumLongPollWaitTest.java │ │ │ │ ├── GetResultsTimeoutTest.java │ │ │ │ ├── MetricsTest.java │ │ │ │ ├── QueryAfterStartFollowsRunsChainTest.java │ │ │ │ ├── SignalTest.java │ │ │ │ ├── StartDelayTest.java │ │ │ │ ├── StartTest.java │ │ │ │ ├── TerminateTest.java │ │ │ │ ├── UpdateLongPollTest.java │ │ │ │ ├── UpdateTest.java │ │ │ │ ├── UpdateTestTimeout.java │ │ │ │ └── WorkflowIdConflictPolicyTest.java │ │ │ └── schedules │ │ │ │ ├── ScheduleTest.java │ │ │ │ ├── ScheduleWithTypedSearchAttributesTest.java │ │ │ │ └── TracingScheduleInterceptor.java │ │ │ ├── common │ │ │ ├── RetryOptionsTest.java │ │ │ ├── converter │ │ │ │ ├── CodecDataConverterTest.java │ │ │ │ ├── EncodedValuesTest.java │ │ │ │ ├── JacksonJsonPayloadConverterTest.java │ │ │ │ ├── JsonDataConverterTest.java │ │ │ │ └── ProtoPayloadConverterTest.java │ │ │ ├── metadata │ │ │ │ ├── POJOActivityImplMetadataTest.java │ │ │ │ ├── POJOActivityInterfaceMetadataTest.java │ │ │ │ ├── POJOWorkflowImplMetadataTest.java │ │ │ │ ├── POJOWorkflowInterfaceMetadataTest.java │ │ │ │ └── testclasses │ │ │ │ │ ├── ActivityInterfaceWithOneNonAnnotatedMethod.java │ │ │ │ │ └── WorkflowInterfaceWithOneWorkflowMethod.java │ │ │ └── reporter │ │ │ │ ├── MicrometerClientStatsReporterTest.java │ │ │ │ └── TestStatsReporter.java │ │ │ ├── failure │ │ │ └── ApplicationFailureTest.java │ │ │ ├── functional │ │ │ └── serialization │ │ │ │ ├── OptionalJsonSerializationTest.java │ │ │ │ └── WorkflowIdSignedPayloadsTest.java │ │ │ ├── internal │ │ │ ├── client │ │ │ │ └── WorkerFactoryRegistryTest.java │ │ │ ├── common │ │ │ │ ├── LinkConverterTest.java │ │ │ │ ├── NexusUtilTest.java │ │ │ │ ├── ProtobufTimeUtilsTest.java │ │ │ │ ├── RetryOptionsUtilsTest.java │ │ │ │ └── WorkflowExecutionHistoryTest.java │ │ │ ├── nexus │ │ │ │ ├── NexusTaskHandlerImplTest.java │ │ │ │ ├── PayloadSerializerTest.java │ │ │ │ └── WorkflowRunTokenTest.java │ │ │ ├── replay │ │ │ │ ├── FullHistoryIterator.java │ │ │ │ ├── OutdatedDirectQueryReplayWorkflowRunTaskHandlerTest.java │ │ │ │ ├── ReplayAwareScopeTest.java │ │ │ │ ├── ReplayWorkflowRunTaskHandlerCacheTests.java │ │ │ │ ├── ReplayWorkflowRunTaskHandlerTaskHandlerTests.java │ │ │ │ ├── ServiceWorkflowHistoryIteratorTest.java │ │ │ │ ├── UnknownHistoryEventReplayerTest.java │ │ │ │ ├── WarnUnfinishedHandlers.java │ │ │ │ └── WorkflowMutableStateTest.java │ │ │ ├── statemachines │ │ │ │ ├── ActivityStateMachineTest.java │ │ │ │ ├── AsyncWorkflowBuilder.java │ │ │ │ ├── AsyncWorkflowBuilderImpl.java │ │ │ │ ├── CancelNexusOperationStateMachineTest.java │ │ │ │ ├── CommandsGeneratePlantUMLStateDiagrams.java │ │ │ │ ├── LocalActivityStateMachineTest.java │ │ │ │ ├── MutableSideEffectStateMachineTest.java │ │ │ │ ├── NexusOperationStateMachineTest.java │ │ │ │ ├── SideEffectStateMachineTest.java │ │ │ │ ├── TestEntityManagerListenerBase.java │ │ │ │ ├── TestHistoryBuilder.java │ │ │ │ ├── TimerStateMachineTest.java │ │ │ │ ├── UpdateProtocolStateMachineTest.java │ │ │ │ ├── VersionStateMachineTest.java │ │ │ │ └── WorkflowStateMachinesTest.java │ │ │ ├── sync │ │ │ │ ├── CheckedExceptionWrapperTest.java │ │ │ │ ├── DeterministicRunnerTest.java │ │ │ │ ├── PromiseTest.java │ │ │ │ ├── QueryDispatcherTest.java │ │ │ │ ├── SyncWorkflowContextTest.java │ │ │ │ ├── Tracer.java │ │ │ │ ├── WorkflowInternalDeprecatedQueueTest.java │ │ │ │ ├── WorkflowInternalLockTest.java │ │ │ │ ├── WorkflowInternalQueueTest.java │ │ │ │ └── WorkflowInternalSemaphoreTest.java │ │ │ ├── testing │ │ │ │ ├── ActivityTestingTest.java │ │ │ │ ├── WorkflowReplayerTest.java │ │ │ │ └── WorkflowTestingTest.java │ │ │ └── worker │ │ │ │ ├── ActivityFailedMetricsTests.java │ │ │ │ ├── SlotSupplierTest.java │ │ │ │ ├── StickyQueueBacklogTest.java │ │ │ │ ├── WorkflowFailedMetricsTests.java │ │ │ │ ├── WorkflowRunLockManagerTest.java │ │ │ │ ├── WorkflowSlotGrpcInterceptedTests.java │ │ │ │ ├── WorkflowSlotMaxConcurrentTests.java │ │ │ │ ├── WorkflowSlotTests.java │ │ │ │ ├── WorkflowSlotsSmallSizeTests.java │ │ │ │ └── WorkflowWorkerTest.java │ │ │ ├── payload │ │ │ └── codec │ │ │ │ └── ZlibPayloadCodecTest.java │ │ │ ├── testUtils │ │ │ ├── CountingSlotSupplier.java │ │ │ ├── Eventually.java │ │ │ └── HistoryUtils.java │ │ │ ├── worker │ │ │ ├── BuildIdVersioningTest.java │ │ │ ├── IndependentResourceBasedTests.java │ │ │ ├── LocalActivitySlotThreadPoolTests.java │ │ │ ├── LocalActivityWorkerNoneRegisteredNotStartedTest.java │ │ │ ├── LocalActivityWorkerNotStartedTest.java │ │ │ ├── LocalActivityWorkerOnlyTest.java │ │ │ ├── MdcClearedBetweenTasksTest.java │ │ │ ├── ResourceBasedTunerTests.java │ │ │ ├── StickyWorkerTest.java │ │ │ ├── WorkerIsNotGettingStartedTest.java │ │ │ ├── WorkerOptionsTest.java │ │ │ ├── WorkerPollerThreadCountTest.java │ │ │ ├── WorkerRegistrationTest.java │ │ │ ├── WorkerStressTests.java │ │ │ ├── WorkerSuspendTest.java │ │ │ ├── WorkerVersioningTest.java │ │ │ ├── shutdown │ │ │ │ ├── CleanActivityWorkerShutdownTest.java │ │ │ │ ├── CleanNexusWorkerShutdownTest.java │ │ │ │ ├── CleanWorkerShutdownHeartBeatingActivityTest.java │ │ │ │ ├── CleanWorkerShutdownInvalidatesWorkflowCacheTest.java │ │ │ │ └── StickyWorkflowDrainShutdownTest.java │ │ │ └── tuning │ │ │ │ └── FixedSizeSlotSupplierTest.java │ │ │ ├── workerFactory │ │ │ └── WorkerFactoryTests.java │ │ │ └── workflow │ │ │ ├── AGENTS.md │ │ │ ├── AwaitTest.java │ │ │ ├── BadAwaitTest.java │ │ │ ├── BadMutableSideEffectTest.java │ │ │ ├── BadSideEffectTest.java │ │ │ ├── BinaryChecksumSetWhenTaskCompletedTest.java │ │ │ ├── CommandInTheLastWorkflowTaskTest.java │ │ │ ├── ContextPropagationTest.java │ │ │ ├── ContinueAsNewNoArgsTest.java │ │ │ ├── ContinueAsNewTest.java │ │ │ ├── DetachedScopeTest.java │ │ │ ├── DynamicWorkflowInitTest.java │ │ │ ├── DynamicWorkflowTest.java │ │ │ ├── EagerWorkflowTaskDispatchTest.java │ │ │ ├── ExceptionPropagationTest.java │ │ │ ├── ExecuteTest.java │ │ │ ├── ExternalWorkflowGetExecutionTest.java │ │ │ ├── ExternalWorkflowInterfaceInheritanceTest.java │ │ │ ├── GenericParametersWorkflowTest.java │ │ │ ├── GetAttemptFromWorkflowInfoTest.java │ │ │ ├── GetCronScheduleFromWorkflowInfoTest.java │ │ │ ├── GetHistoryLengthTest.java │ │ │ ├── GetHistorySizeTest.java │ │ │ ├── GetInstanceTest.java │ │ │ ├── GetRootWorkflowExecutionTest.java │ │ │ ├── GrpcRetryerFunctionalTest.java │ │ │ ├── LargeHistoryTest.java │ │ │ ├── LocalAsyncCompletionWorkflowTest.java │ │ │ ├── LoggerTest.java │ │ │ ├── LongRunningWorkflowTest.java │ │ │ ├── LongWorkflowHistoryServerPaginationTest.java │ │ │ ├── MemoTest.java │ │ │ ├── MetricsTest.java │ │ │ ├── MultipleTimersTest.java │ │ │ ├── MutableSideEffectTest.java │ │ │ ├── NoQueryThreadLeakTest.java │ │ │ ├── ParentContinueAsNewTest.java │ │ │ ├── PolymorphicStartTest.java │ │ │ ├── PriorityInfoTest.java │ │ │ ├── ProhibitedCallsFromWorkflowTest.java │ │ │ ├── PromiseAllowsBlockingTemporalCodeTest.java │ │ │ ├── SagaTest.java │ │ │ ├── SideEffectRaceConditionTest.java │ │ │ ├── SideEffectTest.java │ │ │ ├── SyncTest.java │ │ │ ├── TerminatedWorkflowTest.java │ │ │ ├── TestEnvironmentCloseTest.java │ │ │ ├── TimerCallbackBlockedTest.java │ │ │ ├── TimerTest.java │ │ │ ├── UUIDAndRandomTest.java │ │ │ ├── WorkflowCancellationScopePromiseTest.java │ │ │ ├── WorkflowDescribe.java │ │ │ ├── WorkflowIdReusePolicyTest.java │ │ │ ├── WorkflowInitConstructorTest.java │ │ │ ├── WorkflowInitRetryTest.java │ │ │ ├── WorkflowInitTest.java │ │ │ ├── WorkflowLocalsTest.java │ │ │ ├── WorkflowMetadataTest.java │ │ │ ├── WorkflowRestrictedNameTest.java │ │ │ ├── WorkflowRetryAfterActivityFailureTest.java │ │ │ ├── WorkflowRetryDoNotRetryExceptionTest.java │ │ │ ├── WorkflowRetryTest.java │ │ │ ├── WorkflowRetryWithMethodRetryDoNotRetryExceptionTest.java │ │ │ ├── WorkflowTaskFailureBackoffTest.java │ │ │ ├── WorkflowTaskNPEBackoffTest.java │ │ │ ├── WorkflowTaskTimeoutWorkflowTest.java │ │ │ ├── WorkflowWithCronScheduleTest.java │ │ │ ├── WorkflowsWithFailedPromisesCanBeCanceledTest.java │ │ │ ├── WritesSDKNameVersionTest.java │ │ │ ├── activityTests │ │ │ ├── ActivityApplicationFailureNonRetryableTest.java │ │ │ ├── ActivityApplicationFailureRetryTest.java │ │ │ ├── ActivityApplicationNoSpecifiedRetryTest.java │ │ │ ├── ActivityApplicationOptOutOfRetryTest.java │ │ │ ├── ActivityClientTest.java │ │ │ ├── ActivityInTheLastWorkflowTaskTest.java │ │ │ ├── ActivityMetadataTest.java │ │ │ ├── ActivityPollerPrefetchingTest.java │ │ │ ├── ActivityRestrictedNameTest.java │ │ │ ├── ActivityRetryAnnotatedTest.java │ │ │ ├── ActivityRetryOnTimeoutTest.java │ │ │ ├── ActivityRetryOptionsChangeTest.java │ │ │ ├── ActivityRetryWithExpirationTest.java │ │ │ ├── ActivityRetryWithMaxAttemptsTest.java │ │ │ ├── ActivityThrowingApplicationFailureTest.java │ │ │ ├── ActivityTimeoutTest.java │ │ │ ├── AsyncActivityCompleteWithErrorTest.java │ │ │ ├── AsyncActivityRetryOptionsChangeTest.java │ │ │ ├── AsyncActivityRetryTest.java │ │ │ ├── AsyncActivityTest.java │ │ │ ├── AsyncActivityWithCompletionClientTest.java │ │ │ ├── AsyncRetryOptionsChangeTest.java │ │ │ ├── AsyncRetryTest.java │ │ │ ├── AsyncUsingActivityStubUntypedActivityTest.java │ │ │ ├── AsyncUsingAsyncUntypedActivityTest.java │ │ │ ├── CancelActivityDeadlockTest.java │ │ │ ├── EagerActivityDispatchingTest.java │ │ │ ├── LocalActivitiesWorkflowTaskHeartbeatTest.java │ │ │ ├── LocalActivityAfterCancelTest.java │ │ │ ├── LocalActivityGettingScheduledRightBeforeWorkflowTaskHeartbeatTest.java │ │ │ ├── LocalActivityInTheLastWorkflowTaskTest.java │ │ │ ├── LocalActivityIsNotRegisteredTest.java │ │ │ ├── LocalActivityManyWorkflowsTest.java │ │ │ ├── LocalActivityMetadataTest.java │ │ │ ├── LocalActivityRetriesAndFailsTest.java │ │ │ ├── LocalActivityRetryOverLocalBackoffThresholdTest.java │ │ │ ├── LocalActivitySuccessfulCompletionTest.java │ │ │ ├── LocalActivityThrowingApplicationFailureTest.java │ │ │ ├── LocalActivityThrowingErrorTest.java │ │ │ ├── LocalActivityWorkflowTimeUpdateTest.java │ │ │ ├── LongLocalActivityFailsWhileHeartbeatingMeteringTest.java │ │ │ ├── LongLocalActivityWorkflowTaskHeartbeatBufferedEventTest.java │ │ │ ├── LongLocalActivityWorkflowTaskHeartbeatFailureTest.java │ │ │ ├── LongLocalActivityWorkflowTaskHeartbeatTest.java │ │ │ ├── NonSerializableArgumentsInActivityTest.java │ │ │ ├── NonSerializableExceptionInActivityWorkflowTest.java │ │ │ ├── ParallelLocalActivitiesTest.java │ │ │ ├── ParallelLocalActivityExecutionWorkflowTest.java │ │ │ ├── TestLocalActivity.java │ │ │ ├── TestRawValueActivity.java │ │ │ ├── TryCancelActivityTest.java │ │ │ ├── UntypedActivityRetryTest.java │ │ │ └── cancellation │ │ │ │ ├── AbandonActivityFinishesAfterCancellingTest.java │ │ │ │ ├── AbandonOnCancelActivityTest.java │ │ │ │ ├── ActivityCancellationEventReplayTest.java │ │ │ │ ├── CancellingScheduledActivityTest.java │ │ │ │ └── WorkflowClosedRunningActivityTest.java │ │ │ ├── cancellationTests │ │ │ ├── ExternalWorkflowCancelTest.java │ │ │ ├── WorkflowAwaitCancellationTest.java │ │ │ ├── WorkflowAwaitWithDurationCancellationTest.java │ │ │ └── WorkflowCancellationScopeDeterminism.java │ │ │ ├── childWorkflowTests │ │ │ ├── ChildAsyncLambdaWorkflowTest.java │ │ │ ├── ChildAsyncWorkflowTest.java │ │ │ ├── ChildWorkflowAsyncRetryTest.java │ │ │ ├── ChildWorkflowCancellationTest.java │ │ │ ├── ChildWorkflowExecutionPromiseHandlerTest.java │ │ │ ├── ChildWorkflowImmediateCancellationTest.java │ │ │ ├── ChildWorkflowMetadataTest.java │ │ │ ├── ChildWorkflowRetryTest.java │ │ │ ├── ChildWorkflowStartFailureTest.java │ │ │ ├── ChildWorkflowStartInCancelledScopeTest.java │ │ │ ├── ChildWorkflowTest.java │ │ │ ├── ChildWorkflowTimeoutTest.java │ │ │ ├── ChildWorkflowWithCronScheduleTest.java │ │ │ ├── NamedChildTest.java │ │ │ ├── NonSerializableExceptionInChildWorkflowTest.java │ │ │ ├── ParentWorkflowInfoInChildWorkflowsTest.java │ │ │ ├── StartChildWorkflowWithCancellationScopeAndCancelParentTest.java │ │ │ ├── UntypedChildStubWorkflowAsyncInvokeTest.java │ │ │ ├── UntypedChildStubWorkflowAsyncTest.java │ │ │ └── UntypedChildStubWorkflowTest.java │ │ │ ├── deadlockdetector │ │ │ ├── DeadlockBeforeActivityCallTest.java │ │ │ ├── DeadlockDetectorTest.java │ │ │ └── PayloadConverterEscapingDeadlockDetectionTest.java │ │ │ ├── determinism │ │ │ ├── DeterminismFailingWorkflowImpl.java │ │ │ ├── NonDeterministicWorkflowPolicyBlockWorkflowTest.java │ │ │ └── NonDeterministicWorkflowPolicyFailWorkflowTest.java │ │ │ ├── failure │ │ │ ├── FailureEncodingTest.java │ │ │ ├── WorkflowFailureNonRetryableFlagTest.java │ │ │ └── WorkflowFailureNonStandardThrowableTest.java │ │ │ ├── interceptorsTests │ │ │ └── InterceptorExceptionTests.java │ │ │ ├── nexus │ │ │ ├── AsyncWorkflowOperationTest.java │ │ │ ├── BaseNexusTest.java │ │ │ ├── GenericListOperationTest.java │ │ │ ├── HeaderTest.java │ │ │ ├── NexusOperationMetadataTest.java │ │ │ ├── OperationFailMetricTest.java │ │ │ ├── OperationFailureConversionTest.java │ │ │ ├── ParallelWorkflowOperationTest.java │ │ │ ├── ProtoOperationTest.java │ │ │ ├── SyncClientOperationTest.java │ │ │ ├── SyncOperationCancelledTest.java │ │ │ ├── SyncOperationFailTest.java │ │ │ ├── SyncOperationStubTest.java │ │ │ ├── SyncOperationTimeoutTest.java │ │ │ ├── TerminateWorkflowAsyncOperationTest.java │ │ │ ├── UntypedSyncOperationStubTest.java │ │ │ ├── VoidOperationTest.java │ │ │ ├── WorkflowHandleFailOnConflictTest.java │ │ │ ├── WorkflowHandleFuncTest.java │ │ │ ├── WorkflowHandleProcTest.java │ │ │ ├── WorkflowHandleStubTest.java │ │ │ ├── WorkflowHandleUseExistingOnConflictCancelTest.java │ │ │ ├── WorkflowHandleUseExistingOnConflictTest.java │ │ │ └── WorkflowOperationLinkingTest.java │ │ │ ├── queryTests │ │ │ ├── DirectQueryReplaysDontSpamLogWithWorkflowExecutionExceptionsTest.java │ │ │ ├── LocalActivityAndQueryTest.java │ │ │ ├── QueryCausingReplayWithLocalActivityInLastWFTTest.java │ │ │ ├── QueryRestrictedNameTest.java │ │ │ ├── WaitingWorkflowQueryTest.java │ │ │ └── WorkflowInfoAndLocalInQueryTest.java │ │ │ ├── sdkTestWorkflowRuleTests │ │ │ ├── SDKWorkflowRuleInterceptorTest1.java │ │ │ ├── SDKWorkflowRuleInterceptorTest2.java │ │ │ └── SDKWorkflowRuleInterceptorTest3.java │ │ │ ├── searchattributes │ │ │ ├── SearchAttributesTest.java │ │ │ ├── TypedSearchAttributesTest.java │ │ │ ├── UpsertSearchAttributeTest.java │ │ │ └── UpsertTypedSearchAttributeTest.java │ │ │ ├── shared │ │ │ ├── ApplicationFailureActivity.java │ │ │ ├── ControlledActivityImpl.java │ │ │ ├── NonSerializableException.java │ │ │ ├── TestActivities.java │ │ │ ├── TestMultiArgWorkflowFunctions.java │ │ │ ├── TestMultiArgWorkflowUpdateFunctions.java │ │ │ ├── TestNexusServices.java │ │ │ ├── TestNoArgsWorkflowFuncParent.java │ │ │ ├── TestWorkflowWithCronScheduleImpl.java │ │ │ └── TestWorkflows.java │ │ │ ├── signalTests │ │ │ ├── ExceptionInSignalTest.java │ │ │ ├── SignalAllHandlersFinished.java │ │ │ ├── SignalAndQueryInterfaceTest.java │ │ │ ├── SignalAndQueryListenerTest.java │ │ │ ├── SignalContinueAsNewNonDeterminism.java │ │ │ ├── SignalContinueAsNewWFTFailure.java │ │ │ ├── SignalDuringLastWorkflowTaskTest.java │ │ │ ├── SignalExternalWorkflowFailureTest.java │ │ │ ├── SignalExternalWorkflowImmediateCancellationTest.java │ │ │ ├── SignalExternalWorkflowTest.java │ │ │ ├── SignalMethodOverloadTest.java │ │ │ ├── SignalOrderingWorkflowTest.java │ │ │ ├── SignalRestrictedNameTest.java │ │ │ ├── SignalTest.java │ │ │ ├── SignalWithLocalActivityInTheLastWorkflowTaskTest.java │ │ │ └── UntypedSignalExternalWorkflowTest.java │ │ │ ├── updateTest │ │ │ ├── DynamicUpdateTest.java │ │ │ ├── SpeculativeUpdateTest.java │ │ │ ├── TypedUpdateTest.java │ │ │ ├── UpdateAllHandlersFinished.java │ │ │ ├── UpdateAnnotationTest.java │ │ │ ├── UpdateBadValidator.java │ │ │ ├── UpdateContinueAsNewInHandlerTest.java │ │ │ ├── UpdateExceptionWrapped.java │ │ │ ├── UpdateInfoTest.java │ │ │ ├── UpdateRestrictedNameTest.java │ │ │ ├── UpdateRetryException.java │ │ │ ├── UpdateTest.java │ │ │ ├── UpdateWithLocalActivity.java │ │ │ ├── UpdateWithLocalActivityInTheLastWorkflowTaskTest.java │ │ │ ├── UpdateWithSignalAndQuery.java │ │ │ └── UpdateWithStartTest.java │ │ │ ├── upsertMemoTests │ │ │ └── UpsertMemoTest.java │ │ │ └── versionTests │ │ │ ├── BaseVersionTest.java │ │ │ ├── DefaultVersionNotSupportedDuringReplayTest.java │ │ │ ├── GetVersionAddNewBeforeTest.java │ │ │ ├── GetVersionAfterScopeCancellationInMainWorkflowMethodTest.java │ │ │ ├── GetVersionAfterScopeCancellationTest.java │ │ │ ├── GetVersionAndTimerTest.java │ │ │ ├── GetVersionContinueAsNewTest.java │ │ │ ├── GetVersionDefaultInSignalTest.java │ │ │ ├── GetVersionInSignalOnReplayTest.java │ │ │ ├── GetVersionInSignalTest.java │ │ │ ├── GetVersionMultipleCallsDefaultTest.java │ │ │ ├── GetVersionMultipleCallsInSignalTest.java │ │ │ ├── GetVersionMultipleCallsTest.java │ │ │ ├── GetVersionMultithreadingRemoveTest.java │ │ │ ├── GetVersionMultithreadingTest.java │ │ │ ├── GetVersionOutOfOrderFailTest.java │ │ │ ├── GetVersionRemovalBeforeMarkerTest.java │ │ │ ├── GetVersionRemovedBeforeTest.java │ │ │ ├── GetVersionRemovedInReplayTest.java │ │ │ ├── GetVersionSameIdOnReplayTest.java │ │ │ ├── GetVersionSameIdTest.java │ │ │ ├── GetVersionTest.java │ │ │ ├── GetVersionUpsertSATest.java │ │ │ ├── GetVersionWithoutCommandEventTest.java │ │ │ ├── GetVersionWorkflowRemoveTest.java │ │ │ ├── GetVersionWorkflowReplaceCompletelyTest.java │ │ │ ├── GetVersionWorkflowReplaceGetVersionIdTest.java │ │ │ └── VersionNotSupportedWithConflictingRangesExecutionTest.java │ └── resources │ │ ├── cancellationScopeDeterminism.json │ │ ├── complexHistory1.json │ │ ├── get_version_after_scope_cancellation.json │ │ ├── laRetriesAndFails_1_17.json │ │ ├── laSuccessfulCompletion_1_17.json │ │ ├── logback-test.xml │ │ ├── simpleHistory1.json │ │ ├── simpleHistory1_withAddedNewRandomField.json │ │ ├── testAsyncActivityRetryHistory.json │ │ ├── testAsyncWorkflowOperationTestHistory.json │ │ ├── testChildWorkflowRetryHistory.json │ │ ├── testGetHistoryLength.json │ │ ├── testGetHistorySize.json │ │ ├── testGetVersionDefaultMultithreadingHistory.json │ │ ├── testGetVersionHistory.json │ │ ├── testGetVersionHistoryUpsertSA.json │ │ ├── testGetVersionInSignalHistory.json │ │ ├── testGetVersionMultipleCallsHistory.json │ │ ├── testGetVersionMultipleCallsHistoryDefault.json │ │ ├── testGetVersionMultithreadingRemoveHistory.json │ │ ├── testGetVersionOutOfOrderFail.json │ │ ├── testLocalActivityAfterCancelTest.json │ │ ├── testMultipleLargeGetVersionInSignalsHistory.json │ │ ├── testMultipleLargeGetVersionInSignalsUpsertSAHistory.json │ │ ├── testParallelWorkflowOperationTestHistory.json │ │ ├── testUnknownHistoryEventClean.json │ │ ├── testUnknownHistoryEventMayIgnore.json │ │ └── testUnknownHistoryEventMayNotIgnore.json │ └── virtualThreadTests │ └── java │ └── io │ └── temporal │ └── worker │ └── WorkerWithVirtualThreadsStressTests.java ├── temporal-serviceclient ├── .gitignore ├── build.gradle └── src │ ├── main │ ├── java │ │ └── io │ │ │ └── temporal │ │ │ ├── authorization │ │ │ ├── AuthorizationGrpcMetadataProvider.java │ │ │ └── AuthorizationTokenSupplier.java │ │ │ ├── conf │ │ │ └── EnvironmentVariableNames.java │ │ │ ├── internal │ │ │ ├── BackoffThrottler.java │ │ │ ├── WorkflowThreadMarker.java │ │ │ ├── common │ │ │ │ ├── OptionsUtils.java │ │ │ │ └── ProtoUtils.java │ │ │ ├── retryer │ │ │ │ ├── GrpcAsyncRetryer.java │ │ │ │ ├── GrpcRetryer.java │ │ │ │ ├── GrpcRetryerUtils.java │ │ │ │ └── GrpcSyncRetryer.java │ │ │ └── testservice │ │ │ │ ├── GRPCServerHelper.java │ │ │ │ └── InProcessGRPCServer.java │ │ │ └── serviceclient │ │ │ ├── ChannelManager.java │ │ │ ├── CheckedExceptionWrapper.java │ │ │ ├── CloudServiceStubs.java │ │ │ ├── CloudServiceStubsImpl.java │ │ │ ├── CloudServiceStubsOptions.java │ │ │ ├── GrpcDeadlineInterceptor.java │ │ │ ├── GrpcMetadataProvider.java │ │ │ ├── GrpcMetadataProviderInterceptor.java │ │ │ ├── GrpcMetricsInterceptor.java │ │ │ ├── GrpcTracingInterceptor.java │ │ │ ├── LongPollUtil.java │ │ │ ├── MetricsTag.java │ │ │ ├── MetricsType.java │ │ │ ├── OperatorServiceStubs.java │ │ │ ├── OperatorServiceStubsImpl.java │ │ │ ├── OperatorServiceStubsOptions.java │ │ │ ├── RpcRetryOptions.java │ │ │ ├── ServiceStubs.java │ │ │ ├── ServiceStubsOptions.java │ │ │ ├── SimpleSslContextBuilder.java │ │ │ ├── StatusUtils.java │ │ │ ├── SystemInfoInterceptor.java │ │ │ ├── Version.java │ │ │ ├── WorkflowServiceStubs.java │ │ │ ├── WorkflowServiceStubsImpl.java │ │ │ ├── WorkflowServiceStubsOptions.java │ │ │ └── rpcretry │ │ │ ├── DefaultStubLongPollRpcRetryOptions.java │ │ │ └── DefaultStubServiceOperationRpcRetryOptions.java │ └── resources │ │ └── META-INF │ │ └── native-image │ │ └── io │ │ └── temporal │ │ └── temporal-serviceclient │ │ ├── jni-config.json │ │ ├── native-image.properties │ │ ├── proxy-config.json │ │ ├── reflect-config.json │ │ ├── resource-config.json │ │ └── serialization-config.json │ └── test │ ├── java │ └── io │ │ └── temporal │ │ ├── internal │ │ └── retryer │ │ │ ├── GrpcAsyncRetryerTest.java │ │ │ └── GrpcSyncRetryerTest.java │ │ └── serviceclient │ │ ├── ChannelManagerTest.java │ │ ├── SimpleSslContextBuilderTest.java │ │ ├── SystemInfoTimeoutTest.java │ │ └── functional │ │ ├── GetServerCapabilitiesTest.java │ │ ├── HealthCheckTest.java │ │ └── KeepAliveTest.java │ └── resources │ ├── logback-test.xml │ ├── pkcs12-key.pfx │ ├── pkcs8-crt-chain.pem │ └── pkcs8-pk.pem ├── temporal-shaded ├── README.md └── build.gradle ├── temporal-spring-boot-autoconfigure ├── README.md ├── build.gradle └── src │ ├── main │ ├── java │ │ └── io │ │ │ └── temporal │ │ │ └── spring │ │ │ └── boot │ │ │ ├── ActivityImpl.java │ │ │ ├── NexusServiceImpl.java │ │ │ ├── TemporalOptionsCustomizer.java │ │ │ ├── WorkerOptionsCustomizer.java │ │ │ ├── WorkflowImpl.java │ │ │ ├── WorkflowImplementationOptionsCustomizer.java │ │ │ └── autoconfigure │ │ │ ├── AutoConfigurationUtils.java │ │ │ ├── MetricsScopeAutoConfiguration.java │ │ │ ├── NonRootBeanPostProcessor.java │ │ │ ├── NonRootNamespaceAutoConfiguration.java │ │ │ ├── OpenTracingAutoConfiguration.java │ │ │ ├── RootNamespaceAutoConfiguration.java │ │ │ ├── ServiceStubsAutoConfiguration.java │ │ │ ├── TestServerAutoConfiguration.java │ │ │ ├── TestWorkflowEnvironmentAdapterImpl.java │ │ │ ├── WorkersPresentCondition.java │ │ │ ├── properties │ │ │ ├── ConnectionProperties.java │ │ │ ├── NamespaceProperties.java │ │ │ ├── NonRootNamespaceProperties.java │ │ │ ├── TemporalProperties.java │ │ │ ├── TestServerProperties.java │ │ │ ├── WorkerProperties.java │ │ │ └── WorkersAutoDiscoveryProperties.java │ │ │ └── template │ │ │ ├── ClientTemplate.java │ │ │ ├── NamespaceTemplate.java │ │ │ ├── NonRootNamespaceTemplate.java │ │ │ ├── ServiceStubOptionsTemplate.java │ │ │ ├── ServiceStubsTemplate.java │ │ │ ├── TestWorkflowEnvironmentAdapter.java │ │ │ ├── WorkerFactoryOptionsTemplate.java │ │ │ ├── WorkerOptionsTemplate.java │ │ │ ├── WorkersTemplate.java │ │ │ ├── WorkflowClientOptionsTemplate.java │ │ │ └── WorkflowImplementationOptionsTemplate.java │ └── resources │ │ └── META-INF │ │ ├── spring.factories │ │ └── spring │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ └── test │ ├── java │ └── io │ │ └── temporal │ │ └── spring │ │ └── boot │ │ └── autoconfigure │ │ ├── ApiKeyAuthTest.java │ │ ├── AutoDiscoveryByTaskQueueResolverTest.java │ │ ├── AutoDiscoveryByTaskQueueTest.java │ │ ├── AutoDiscoveryByWorkerNameTest.java │ │ ├── AutoDiscoveryWithProfileTest.java │ │ ├── ClientOnlyTest.java │ │ ├── CustomClientConfigTest.java │ │ ├── CustomDataConverterTest.java │ │ ├── ExplicitConfigTest.java │ │ ├── InterceptorsTest.java │ │ ├── MTLSWithServerNameOverrideTest.java │ │ ├── MultiNamespaceTest.java │ │ ├── OptionalWorkerOptionsTest.java │ │ ├── OptionsCustomizersTest.java │ │ ├── RegisteredInfoTest.java │ │ ├── ServiceStubsAutoConfigurationTest.java │ │ ├── StartWorkersTest.java │ │ ├── WorkerVersioningMissingAnnotationTest.java │ │ ├── WorkerVersioningTest.java │ │ ├── bytaskqueue │ │ ├── TestActivity.java │ │ ├── TestActivityImpl.java │ │ ├── TestNexusService.java │ │ ├── TestNexusServiceImpl.java │ │ ├── TestWorkflow.java │ │ └── TestWorkflowImpl.java │ │ ├── byworkername │ │ ├── OtherTestActivityImpl.java │ │ ├── OtherTestWorkflowImpl.java │ │ ├── TestActivity.java │ │ ├── TestActivityImpl.java │ │ ├── TestDynamicWorkflowImpl.java │ │ ├── TestNexusService.java │ │ ├── TestNexusServiceImpl.java │ │ ├── TestWorkflow.java │ │ └── TestWorkflowImpl.java │ │ └── workerversioning │ │ ├── TestWorkflow.java │ │ ├── TestWorkflow2.java │ │ └── TestWorkflowImpl.java │ └── resources │ ├── application-custom-namespace.yml │ ├── application-multi-namespaces.yml │ ├── application.yml │ ├── logback-test.xml │ ├── pkcs12-key.pfx │ ├── pkcs8-crt-chain.pem │ └── pkcs8-pk.pem ├── temporal-spring-boot-starter └── build.gradle ├── temporal-test-server ├── Dockerfile ├── README.md ├── build.gradle └── src │ ├── main │ ├── java │ │ └── io │ │ │ └── temporal │ │ │ ├── internal │ │ │ └── testservice │ │ │ │ ├── ActivityTaskToken.java │ │ │ │ ├── CommandVerifier.java │ │ │ │ ├── CronUtils.java │ │ │ │ ├── ExecutionId.java │ │ │ │ ├── NexusOperationRef.java │ │ │ │ ├── NexusTaskToken.java │ │ │ │ ├── QueryId.java │ │ │ │ ├── RequestContext.java │ │ │ │ ├── SelfAdvancingTimer.java │ │ │ │ ├── SelfAdvancingTimerImpl.java │ │ │ │ ├── StateMachine.java │ │ │ │ ├── StateMachines.java │ │ │ │ ├── StateUtils.java │ │ │ │ ├── TaskQueue.java │ │ │ │ ├── TestNexusEndpointStore.java │ │ │ │ ├── TestNexusEndpointStoreImpl.java │ │ │ │ ├── TestOperatorService.java │ │ │ │ ├── TestService.java │ │ │ │ ├── TestServiceRetryState.java │ │ │ │ ├── TestServiceServer.java │ │ │ │ ├── TestServicesStarter.java │ │ │ │ ├── TestVisibilityStore.java │ │ │ │ ├── TestVisibilityStoreImpl.java │ │ │ │ ├── TestWorkflowMutableState.java │ │ │ │ ├── TestWorkflowMutableStateImpl.java │ │ │ │ ├── TestWorkflowService.java │ │ │ │ ├── TestWorkflowStore.java │ │ │ │ ├── TestWorkflowStoreImpl.java │ │ │ │ ├── WorkflowId.java │ │ │ │ └── WorkflowTaskToken.java │ │ │ ├── serviceclient │ │ │ ├── TestServiceStubs.java │ │ │ ├── TestServiceStubsImpl.java │ │ │ └── TestServiceStubsOptions.java │ │ │ └── testserver │ │ │ └── TestServer.java │ ├── proto │ │ ├── Makefile │ │ ├── api-linter.yaml │ │ ├── buf.yaml │ │ └── temporal │ │ │ └── api │ │ │ └── testservice │ │ │ └── v1 │ │ │ ├── request_response.proto │ │ │ └── service.proto │ └── resources │ │ └── META-INF │ │ └── native-image │ │ └── io.temporal │ │ └── temporal-test-server │ │ ├── jni-config.json │ │ ├── native-image.properties │ │ ├── predefined-classes-config.json │ │ ├── proxy-config.json │ │ ├── reflect-config.json │ │ ├── resource-config.json │ │ └── serialization-config.json │ └── test │ ├── java │ └── io │ │ └── temporal │ │ ├── internal │ │ └── testservice │ │ │ └── SelfAdvancingTimerImplTest.java │ │ └── testserver │ │ ├── TestServicesStarterAccessor.java │ │ └── functional │ │ ├── ChildLivesLongerThanParentTest.java │ │ ├── ContinueAsNewTest.java │ │ ├── DescribeNamespaceTest.java │ │ ├── DescribeWorkflowAsserter.java │ │ ├── DescribeWorkflowExecutionTest.java │ │ ├── MultiOperationTest.java │ │ ├── NexusEndpointTest.java │ │ ├── NexusWorkflowTest.java │ │ ├── RepeatedWorkflowTaskFailuresTest.java │ │ ├── SignalLinksTest.java │ │ ├── WorkflowCachingTest.java │ │ ├── WorkflowIdConflictPolicyTest.java │ │ ├── WorkflowIdReusePolicyTest.java │ │ ├── WorkflowUpdateTest.java │ │ ├── activity │ │ ├── ActivityHeartbeat.java │ │ └── ActivityWithAnOutdatedTaskTokenTest.java │ │ ├── common │ │ ├── TestActivities.java │ │ └── TestWorkflows.java │ │ ├── searchattributes │ │ ├── IncorrectStartWorkflowSearchAttributesTest.java │ │ └── IncorrectUpsertSearchAttributesTest.java │ │ └── timeskipping │ │ ├── SleepingActivity.java │ │ └── TimeSkippingFromAnActivityTest.java │ └── resources │ └── logback-test.xml ├── temporal-testing ├── README.md ├── build.gradle └── src │ ├── main │ └── java │ │ └── io │ │ └── temporal │ │ ├── internal │ │ ├── Issue.java │ │ ├── Signal.java │ │ ├── docker │ │ │ └── RegisterTestNamespace.java │ │ └── sync │ │ │ ├── DeterministicRunnerWrapper.java │ │ │ └── DummySyncWorkflowContext.java │ │ └── testing │ │ ├── ActivityRequestedAsyncCompletion.java │ │ ├── IdempotentTimeLocker.java │ │ ├── ReplayResults.java │ │ ├── TestActivityEnvironment.java │ │ ├── TestActivityEnvironmentInternal.java │ │ ├── TestActivityExtension.java │ │ ├── TestEnvironmentOptions.java │ │ ├── TestWorkflowEnvironment.java │ │ ├── TestWorkflowEnvironmentInternal.java │ │ ├── TestWorkflowExtension.java │ │ ├── TestWorkflowRule.java │ │ ├── TimeLockingInterceptor.java │ │ ├── WorkflowHistoryLoader.java │ │ ├── WorkflowInitialTime.java │ │ ├── WorkflowReplayer.java │ │ └── internal │ │ ├── ExternalServiceTestConfigurator.java │ │ ├── SDKTestOptions.java │ │ ├── SDKTestWorkflowRule.java │ │ ├── TestServiceUtils.java │ │ └── TracingWorkerInterceptor.java │ └── test │ ├── java │ └── io │ │ └── temporal │ │ └── testing │ │ ├── TestActivityEnvironmentHeartbeat.java │ │ ├── TestEnvToleratesLongTestServerCalls.java │ │ ├── TestWorkflowEnvironmentCreationTest.java │ │ ├── TestWorkflowEnvironmentInitialTimeTest.java │ │ ├── TestWorkflowEnvironmentSleepTest.java │ │ ├── TestWorkflowEnvironmentTest.java │ │ ├── TestWorkflowExtensionTimeSkippingTest.java │ │ ├── TestWorkflowRuleTimeSkippingTest.java │ │ ├── functional │ │ └── TimeLockingInterceptorAsyncTest.java │ │ └── junit5 │ │ ├── TestActivityExtensionDynamicTest.java │ │ ├── TestActivityExtensionTest.java │ │ ├── TestWorkflowExtensionDynamicTest.java │ │ ├── TestWorkflowExtensionTest.java │ │ └── testWorkflowImplementationOptions │ │ ├── TestWorkflowImplementationOptionsCommon.java │ │ ├── TestWorkflowImplementationOptionsMain.java │ │ └── TestWorkflowImplementationOptionsViceVersa.java │ └── resources │ └── logback-test.xml └── whitesource.config /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax 2 | 3 | # These owners will be the default owners for everything in 4 | # the repo. Unless a later match takes precedence, 5 | # @temporalio/sdk will be requested for review when 6 | # someone opens a pull request. 7 | * @temporalio/sdk 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Report a bug or unexpected behavior with Temporal Java SDK 4 | title: '' 5 | labels: potential-bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Expected Behavior 11 | 12 | 13 | ## Actual Behavior 14 | 15 | 16 | ## Steps to Reproduce the Problem 17 | 18 | 1. 19 | 1. 20 | 1. 21 | 22 | ## Specifications 23 | 24 | - Version: 25 | - Platform: 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for the Temporal Java SDK 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "gradle" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | - package-ecosystem: "github-actions" 8 | directory: "/" 9 | schedule: 10 | interval: "weekly" 11 | -------------------------------------------------------------------------------- /.github/workflows/coverage.yml: -------------------------------------------------------------------------------- 1 | name: Code Coverage 2 | on: 3 | push: 4 | branches: 5 | - master 6 | 7 | jobs: 8 | code-coverage: 9 | runs-on: ubuntu-latest-16-cores 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v4 13 | with: 14 | fetch-depth: 0 15 | 16 | - name: Set up Java 17 | uses: actions/setup-java@v4 18 | with: 19 | java-version: '11' 20 | distribution: 'temurin' 21 | 22 | - name: Set up Gradle 23 | uses: gradle/actions/setup-gradle@v4 24 | 25 | - name: Run Tests 26 | run: ./gradlew test -x spotlessCheck -x spotlessApply -Pjacoco 27 | continue-on-error: true 28 | 29 | - name: Run Test Coverage 30 | run: ./gradlew testCodeCoverageReport -Pjacoco 31 | 32 | - name: Publish Coverage 33 | env: 34 | COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} 35 | run: ./gradlew coverallsJacoco -Pjacoco 36 | -------------------------------------------------------------------------------- /.github/workflows/features.yml: -------------------------------------------------------------------------------- 1 | name: "Features Integration Tests" 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | features-test: 6 | uses: temporalio/features/.github/workflows/java.yaml@main 7 | with: 8 | java-repo-path: ${{github.event.pull_request.head.repo.full_name}} 9 | version: ${{github.event.pull_request.head.ref}} 10 | version-is-repo-ref: true -------------------------------------------------------------------------------- /.github/workflows/gradle-wrapper-validation.yml: -------------------------------------------------------------------------------- 1 | name: "Validate Gradle Wrapper" 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | validation: 6 | name: "Gradle wrapper validation" 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v4 10 | - uses: gradle/actions/wrapper-validation@v3 11 | -------------------------------------------------------------------------------- /.github/workflows/omes.yml: -------------------------------------------------------------------------------- 1 | name: Omes testing 2 | on: 3 | push: 4 | branches: 5 | - master 6 | 7 | jobs: 8 | omes-image-build: 9 | uses: temporalio/omes/.github/workflows/docker-images.yml@main 10 | secrets: inherit 11 | with: 12 | lang: java 13 | sdk-repo-url: ${{ github.event.pull_request.head.repo.full_name || 'temporalio/sdk-java' }} 14 | sdk-repo-ref: ${{ github.event.pull_request.head.ref || github.ref }} 15 | # TODO: Remove once we have a good way of cleaning up sha-based pushed images 16 | docker-tag-ext: ci-latest 17 | do-push: true 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .*.swp 3 | .*.swo 4 | *.iml 5 | .DS_Store 6 | .idea 7 | .gradle 8 | /build 9 | /*/build 10 | **/out 11 | /lib 12 | dummy 13 | $buildDir 14 | src/main/idls/* 15 | /bin 16 | .classpath 17 | .project 18 | .settings 19 | .vscode/ 20 | */bin -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "temporal-serviceclient/src/main/proto"] 2 | path = temporal-serviceclient/src/main/proto 3 | url = https://github.com/temporalio/api.git 4 | [submodule "temporal-serviceclient/src/main/protocloud"] 5 | path = temporal-serviceclient/src/main/protocloud 6 | url = https://github.com/temporalio/api-cloud.git 7 | -------------------------------------------------------------------------------- /.whitesource: -------------------------------------------------------------------------------- 1 | { 2 | "settingsInheritedFrom": "temporalio/whitesource-config@main", 3 | "scanSettings": { 4 | "configMode": "EXTERNAL", 5 | "configExternalURL": "https://raw.githubusercontent.com/temporalio/sdk-java/master/whitesource.config" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /docker/github/dynamicconfig/development.yaml: -------------------------------------------------------------------------------- 1 | system.forceSearchAttributesCacheRefreshOnRead: 2 | - value: true 3 | system.enableActivityEagerExecution: 4 | - value: true 5 | system.enableEagerWorkflowStart: 6 | - value: true 7 | frontend.enableExecuteMultiOperation: 8 | - value: true 9 | frontend.enableUpdateWorkflowExecution: 10 | - value: true 11 | frontend.enableUpdateWorkflowExecutionAsyncAccepted: 12 | - value: true 13 | frontend.workerVersioningWorkflowAPIs: 14 | - value: true 15 | frontend.workerVersioningDataAPIs: 16 | - value: true 17 | history.MaxBufferedQueryCount: 18 | - value: 100000 19 | worker.buildIdScavengerEnabled: 20 | - value: true 21 | worker.removableBuildIdDurationSinceDefault: 22 | - value: 1 23 | system.enableNexus: 24 | - value: true 25 | component.nexusoperations.callback.endpoint.template: 26 | - value: http://localhost:7243/namespaces/{{.NamespaceName}}/nexus/callback 27 | component.callbacks.allowedAddresses: 28 | - value: 29 | - Pattern: "localhost:7243" 30 | AllowInsecure: true 31 | system.refreshNexusEndpointsMinWait: 32 | - value: 1ms -------------------------------------------------------------------------------- /docker/native-image/dockerfile: -------------------------------------------------------------------------------- 1 | # Use an old version of Ubuntu to build the test server to maintain compatibility with 2 | # older versions of glibc, specifically glib 2.17. 3 | FROM ubuntu:18.04 4 | ENV JAVA_HOME=/usr/lib64/graalvm/graalvm-community-java21 5 | COPY --from=ghcr.io/graalvm/jdk-community:21 $JAVA_HOME $JAVA_HOME 6 | ENV PATH="${JAVA_HOME}/bin:${PATH}" 7 | RUN apt-get update 8 | RUN apt-get install -y git build-essential zlib1g-dev 9 | # Avoid errors like: "fatal: detected dubious ownership in repository" 10 | RUN git config --global --add safe.directory '*' -------------------------------------------------------------------------------- /gradle/dependencyManagement.gradle: -------------------------------------------------------------------------------- 1 | subprojects { 2 | if (name == 'temporal-bom') { 3 | return 4 | } 5 | configurations.implementation { 6 | // add global exclusions here if needed 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /gradle/errorprone.gradle: -------------------------------------------------------------------------------- 1 | subprojects { 2 | //https://github.com/tbroyer/gradle-errorprone-plugin 3 | apply plugin: 'net.ltgt.errorprone' 4 | 5 | dependencies { 6 | errorproneJavac('com.google.errorprone:javac:9+181-r4173-1') 7 | if (JavaVersion.current().isJava11Compatible()) { 8 | errorprone('com.google.errorprone:error_prone_core:2.31.0') 9 | } else { 10 | errorprone('com.google.errorprone:error_prone_core:2.10.0') 11 | } 12 | } 13 | 14 | tasks.withType(JavaCompile).configureEach { 15 | options.errorprone.disableWarningsInGeneratedCode = true 16 | options.errorprone.excludedPaths = '.*/build/generated/.*' 17 | } 18 | } -------------------------------------------------------------------------------- /gradle/gatherDependencies.gradle: -------------------------------------------------------------------------------- 1 | subprojects { 2 | if (name == 'temporal-bom') { 3 | return 4 | } 5 | // Creates build/runtimeDeps folder in each module that contains all the dependencies 6 | // that need to be in the runtime classpath of the module 7 | task gatherRuntimeDeps(type: Copy) { 8 | from configurations.runtimeClasspath 9 | into "${buildDir}/runtimeDeps" 10 | } 11 | } -------------------------------------------------------------------------------- /gradle/linting.gradle: -------------------------------------------------------------------------------- 1 | subprojects { 2 | if (name == 'temporal-bom') { 3 | return 4 | } 5 | apply plugin: 'com.diffplug.spotless' 6 | 7 | spotless { 8 | java { 9 | target 'src/*/java/**/*.java' 10 | targetExclude '**/generated/*' 11 | targetExclude '**/.idea/**' 12 | googleJavaFormat('1.24.0') 13 | } 14 | 15 | kotlin { 16 | ktlint('0.48.2') 17 | } 18 | } 19 | 20 | classes.dependsOn 'spotlessApply' 21 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/temporalio/sdk-java/35386dae38bf40b7434e426258178b6fad4d5e68/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /releases/v0.0.1-test: -------------------------------------------------------------------------------- 1 | Highlights: 2 | 3 | This is not a real release. 4 | 5 | This is a set of release notes used exclusively for testing internal release 6 | processes. 7 | 8 | If you are reading these words as part of a Github release (as opposed 9 | to as a file in the sdk-java repository) then an error has been made in the 10 | release process. Please notify the owners of https://github.com/temporalio/sdk-java. 11 | -------------------------------------------------------------------------------- /releases/v1.0.9: -------------------------------------------------------------------------------- 1 | 2021-06-01 - a25cafa5 - Fix health check attributes (#519) 2 | -------------------------------------------------------------------------------- /releases/v1.1.0: -------------------------------------------------------------------------------- 1 | 2021-06-04 - 0727c950 - Add getWorker method to TestWorkflowRule (#528) 2 | 2021-06-04 - c09e03c9 - Avoid throwing IllegalStateException in NoopSuspendableWorker (#527) 3 | 2021-06-09 - a6ade139 - Implement configurable DEFAULT_DEADLOCK_DETECTION_TIMEOUT (#524) 4 | 2021-06-10 - 2b51430e - Added exclusion of GRPC wrapped InterruptedExceptions logging in Poller during shutdown (#536) 5 | 2021-06-11 - 1be5b7df - Pluggable span naming (#511) 6 | 2021-06-21 - 37401492 - Cancel child fix (#542) 7 | 2021-07-01 - 36fea93e - Allow zero value on some worker options values (#563) 8 | -------------------------------------------------------------------------------- /releases/v1.10.0: -------------------------------------------------------------------------------- 1 | Highlights: 2 | 3 | This release contains fixes for performance and stability issues 4 | 5 | Changeset: 6 | 2022-04-18 - 6a1dfb8c - Refactor and cleanup exception to failure conversion code (#1148) 7 | 2022-04-18 - b00561f6 - Make WorkflowThreadContext#destroy non-blocking and remove deadlock detector from the call (#1151) 8 | 2022-04-18 - bd3ae1b7 - Moved NO_COMPLETION counter reporting to handle all cases (#1149) 9 | 2022-04-19 - 397b7785 - Fix for Worker#isSuspended not returning correct state (#1155) 10 | 2022-04-19 - 48bdd4d7 - Reimplemented WorkflowRunLockManager to fix design flaw with an unsafe unlock (#1147) 11 | 2022-04-19 - b12df1f1 - Rework PotentialDeadlockException to don't override the original stacktrace (#1152) 12 | -------------------------------------------------------------------------------- /releases/v1.14.0: -------------------------------------------------------------------------------- 1 | Highlights: 2 | 3 | This release fixes a bug that may lead to workflows being stuck when sequential synchronous calls of local activities are present. 4 | See https://github.com/temporalio/sdk-java/issues/1262 for more details. 5 | 6 | Changeset: 7 | 2022-07-01 - 9e78e8a2 - Fix erroneous closing of workflow tasks instead of heartbeating in some edge cases (#1295) 8 | -------------------------------------------------------------------------------- /releases/v1.15.1: -------------------------------------------------------------------------------- 1 | Highlights: 2 | This release fixes native distribution of test server, no changes for java users. 3 | 4 | Changeset: 5 | 2022-08-10 - 15df866f - Fix graal reflection config for new protobuf version (#1359) 6 | -------------------------------------------------------------------------------- /releases/v1.18.1: -------------------------------------------------------------------------------- 1 | # Highlights 2 | 3 | Fixes a CRITICAL issue with uninitialized issue in history iterator. 4 | Upgrade to this version instead of 1.18.0 5 | 6 | # Changeset 7 | 8 | 2023-02-02 - 2cbefc8 - Fix WorkflowHistoryIterator issue with uninitialized field (#1636) 9 | -------------------------------------------------------------------------------- /releases/v1.18.2: -------------------------------------------------------------------------------- 1 | # Highlights 2 | 3 | Fixes an issue with WorkflowStub#getExecution not returning an execution started by `signalWithStart`. 4 | 5 | # Changeset 6 | 7 | 2023-02-23 - 3a6e2428 - Fix WorkflowStub#getExecution returning null after signalWithStart (#1670) -------------------------------------------------------------------------------- /releases/v1.19.1: -------------------------------------------------------------------------------- 1 | # Highlights 2 | 3 | Fixes native test server distribution not working correctly if search attributes are used. 4 | JavaSDK users don't need to upgrade to this release until they build their own native test server distribution. 5 | 6 | # Changeset 7 | 8 | 2023-03-23 - 5d980b3b - Fix location of graal descriptors and a missing reflection reference for temporal-sdk module (#1713) 9 | -------------------------------------------------------------------------------- /releases/v1.2.0: -------------------------------------------------------------------------------- 1 | 2021-07-02 - 02d37a51 - ProtobufJsonPayloadConverter is fixed to use custom printer provided in constructor (#552) 2 | 2021-07-05 - 177b8958 - Expose a fixed implementation of WorkflowQueue as a new method of Workflow class (#572) 3 | 2021-07-07 - 9a0a9391 - Forbid the usage of WorkflowClient, ActivityCompletionClient, and WorkflowServiceStubs from workflow code (#556) 4 | 2021-07-27 - 99e71037 - Polish JUnit5 extension: per-test initial time, dynamic workflows and activities (#581) 5 | -------------------------------------------------------------------------------- /releases/v1.20.1: -------------------------------------------------------------------------------- 1 | # Highlights 2 | 3 | Default implementation for exceptionToFailure and failureToException to fix an unintentional breaking change 4 | in the DataConverter interface. 5 | 6 | # Changeset 7 | 8 | 2023-06-27 - 57cb086f - Add support for SDK metadata to test server (#1800) 9 | 2023-06-27 - c6aadda8 - Expose started time in ActivityInfo (#1798) 10 | 2023-06-29 - 9a457157 - Generate bom using java-platform plugin (#1796) 11 | 2023-07-03 - 15337d9a - Add Semgrep scanning (#1775) 12 | 2023-07-10 - 25387be8 - Add default methods for exceptionToFailure and failureToException (#1809) 13 | 2023-07-13 - f30d3496 - Add description to bom project (#1813) -------------------------------------------------------------------------------- /releases/v1.21.1: -------------------------------------------------------------------------------- 1 | # Highlights 2 | 3 | ## Bugfixes 4 | 5 | - Fixes a CRITICAL issue with `GetVersion` returning the wrong version on replay. 6 | Upgrade to this version instead of 1.21.0 7 | 8 | # Changeset 9 | 10 | 2023-08-04 - 5ce6f10f - Replace interpolated variables (#1834) 11 | 2023-08-14 - 622edc05 - Build test server on ubuntu 18 (#1836) 12 | 2023-08-16 - f922c065 - Fix bug in VersionStateMachine causing wrong version to get returned (#1841) 13 | -------------------------------------------------------------------------------- /releases/v1.21.2: -------------------------------------------------------------------------------- 1 | # Highlights 2 | 3 | ## Bugfixes 4 | 5 | Fixes a bug where after a server failure a worker could end up only polling on the sticky task queue and 6 | never poll on the normal task queue 7 | 8 | # Changeset 9 | 10 | 2023-09-27 - 67a5afb3 - Remove unbound variable (#1846) 11 | 2023-09-27 - d4671e3e - Reset sticky queue backlog on empty response (#1859) 12 | 2023-09-27 - d8091d15 - Release WF slot on UnableToAcquireLockException (#1871) -------------------------------------------------------------------------------- /releases/v1.22.1: -------------------------------------------------------------------------------- 1 | # Highlights 2 | 3 | ## Bugfixes 4 | 5 | Add `WorkflowContext` more consistently in the SDK. `WorkflowContext` will now also be added in: 6 | 7 | * Memo 8 | * Last failure 9 | * Schedules (Note: The `workflowId` in `WorkflowContext` may differ on serialization and deserialization.) 10 | 11 | ## (Experimental) Start delay 12 | 13 | Added `StartDelay` option to `WorkflowOptions`. `StartDelay` will cause Temporal to wait before dispatching the first workflow task. 14 | If the workflow gets a signal before the delay, a workflow task will be dispatched and the rest 15 | of the delay will be ignored. 16 | 17 | # Changeset 18 | 19 | 20 | 2023-10-11 - 06ef0df6 - Add identity to Terminate call (#1894) 21 | 2023-10-16 - 4fe296e1 - Add start delay (#1897) 22 | 2023-10-16 - 538508be - Apply data converter context in more places (#1896) 23 | -------------------------------------------------------------------------------- /releases/v1.22.2: -------------------------------------------------------------------------------- 1 | # Highlights 2 | 3 | ## Bugfixes 4 | * Add TemporalChangeVersion search attribute to test server. 5 | * Fix race condition in test server search attribute. 6 | 7 | # Changeset 8 | 2023-10-23 - 02bb1adb - Fix race condition in test server SA (#1905) 9 | -------------------------------------------------------------------------------- /releases/v1.22.3: -------------------------------------------------------------------------------- 1 | # Highlights 2 | 3 | ## Bugfixes 4 | - Fixes a rare bug that could cause the SDK to not fully replay histories on server version pre 1.21 5 | - Fixes a bug causing workflow task failure if a local activity was scheduled on the same workflow task 6 | the workflow tried to continue as new. 7 | 8 | # Changeset 9 | 10 | 2023-10-25 - 8b3be3bb - Don't schedule local activities on a completed workflow (#1908) 11 | 2023-10-30 - 2f5fdf1a - Test continue as new in an update (#1917) 12 | 2023-10-30 - 503cae76 - Verify history is replayed up to StartedEventId (#1916) 13 | 2023-10-30 - 8af4a264 - ReadOnly Exception in update validator fail WFT (#1918) 14 | 2023-10-30 - abb1deb8 - Add proto-google-common-protos to temporal-shaded (#1912) 15 | 2023-11-03 - 7077b54f - Add getWorkerTaskReachability API (#1919) 16 | 2023-11-06 - 5d1bbbe3 - Test continue as new with local activities (#1922) 17 | -------------------------------------------------------------------------------- /releases/v1.23.1: -------------------------------------------------------------------------------- 1 | # Highlights 2 | 3 | Fixed an issue where serialization context may not be applied when serializing failures in certain scenarios. 4 | 5 | # Changeset 6 | 7 | 2024-03-11 - a64b6e51 - Replace buildkite with github actions (#2004) 8 | 2024-03-13 - abea3189 - Switch build status badge to GH action (#2005) 9 | 2024-03-25 - f205d1c5 - Remove experimental flag from StartDelay (#2015) 10 | 2024-03-28 - 0c6c566a - Add StickyTaskQueueDrainTimeout (#2019) 11 | 2024-03-31 - 29d23d06 - Make sure task failures use a serialization context (#2022) 12 | -------------------------------------------------------------------------------- /releases/v1.24.1: -------------------------------------------------------------------------------- 1 | ## Breaking Changes 2 | 3 | This patch release reverts "Slot Auto-Tuning" support as it was causing a regression in local activity slot management 4 | and metrics. 5 | 6 | # Changeset 7 | 8 | 2024-06-27 - abd9f2d1 - Point feature repo back to main (#2130) 9 | 2024-07-08 - 46b239d4 - Revert configurable slot provider (#2134) 10 | 2024-07-08 - 99585c14 - Change build_native_images mac runner to macos-13 (#2135) 11 | -------------------------------------------------------------------------------- /releases/v1.24.2: -------------------------------------------------------------------------------- 1 | # Highlights 2 | 3 | ## Bugfixes 4 | 5 | Fixes a bug where `workflow_failed` metric may not be incremented if the workflow fails do to a `NonDeterministicException`. 6 | 7 | # Changeset 8 | 2024-07-09 - 3b26db7b - Make sure workflow_failed is incremented on NonDeterministicException (#2141) 9 | -------------------------------------------------------------------------------- /releases/v1.25.1: -------------------------------------------------------------------------------- 1 | # Highlights 2 | 3 | ## Bugfixes 4 | Fixes a bug where workers may not properly shutdown if awaitTermination was not called. 5 | 6 | # Changeset 7 | 8 | 2024-08-15 - 448f2644 - Fix workflow start delay docs to say signal does not interrupt delay (#2190) 9 | 2024-08-16 - 0c135d67 - Remove feature repo tag (#2191) 10 | 2024-08-20 - 4eaeb9ed - Fix shutdown behavior of unstarted LA slot queue (#2196) 11 | 2024-08-20 - f2e113a4 - Adding attempt number into MDC context for better diagnosing (#2193) 12 | -------------------------------------------------------------------------------- /releases/v1.3.1: -------------------------------------------------------------------------------- 1 | 2021-09-11 - 0da3149c - GrpcRetryer now retries underlying DEADLINE_EXCEEDED if the root gRPC context deadline is not expired (#709) 2 | 2021-09-13 - d19bdcdb - Test service now enforces 1 Minute timeout on long polls (#713) 3 | -------------------------------------------------------------------------------- /releases/v1.7.1: -------------------------------------------------------------------------------- 1 | Highlights: 2 | 3 | It's a patch release for 1.7.0 containing a fix for SimpleSslContextBuilder 4 | throwing exception when provided with a certificate chain or a private key. 5 | 6 | Changeset: 7 | 2022-01-12 - 53a638d0 - Fix SimpleSslContextBuilderTest not testing anything by not loading keys correctly (#970) 8 | 2022-01-12 - 7373d360 - Fix bug where TLS certificate streams are read twice (#968) 9 | -------------------------------------------------------------------------------- /releases/v1.9.1: -------------------------------------------------------------------------------- 1 | Highlights: 2 | 3 | Test server not timing out workflow task in case of subsequent "unhandled command" failures anymore fixing the 4 | behavior introduced in Test Server 1.9.0 and Temporal Server 1.16 5 | 6 | Changeset: 7 | 2022-04-13 - 3a5ffb77 - Don't time out WFT in case of subsequent UNHANDLED_COMMAND failures (#1140) 8 | 2022-04-14 - 1816ad24 - Align Test Server describeWorkflowExecution message with Temporal Server (#1142) 9 | 2022-04-14 - 823c6e6c - Fix workflow thread name strategy to append a clear marker of truncation (#1144) 10 | 2022-04-15 - f35a0971 - setMetricsScope is wired into test rules (#1143) 11 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name='temporal-java-sdk' 2 | include 'temporal-bom' 3 | include 'temporal-serviceclient' 4 | include 'temporal-sdk' 5 | include 'temporal-testing' 6 | include 'temporal-test-server' 7 | include 'temporal-opentracing' 8 | include 'temporal-kotlin' 9 | include 'temporal-spring-boot-autoconfigure' 10 | include 'temporal-spring-boot-starter' 11 | include 'temporal-remote-data-encoder' 12 | include 'temporal-shaded' -------------------------------------------------------------------------------- /temporal-bom/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java-platform' 3 | } 4 | 5 | description = '''Temporal Java BOM''' 6 | 7 | dependencies { 8 | constraints { 9 | api project(':temporal-kotlin') 10 | api project(':temporal-opentracing') 11 | api project(':temporal-remote-data-encoder') 12 | api project(':temporal-sdk') 13 | api project(':temporal-serviceclient') 14 | api project(':temporal-shaded') 15 | api project(':temporal-spring-boot-autoconfigure') 16 | api project(':temporal-spring-boot-starter') 17 | api project(':temporal-test-server') 18 | api project(':temporal-testing') 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /temporal-kotlin/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*.{kt,kts}] 4 | indent_size = 2 5 | 6 | ij_kotlin_allow_trailing_comma = false 7 | ij_kotlin_allow_trailing_comma_on_call_site = false 8 | -------------------------------------------------------------------------------- /temporal-kotlin/AGENTS.md: -------------------------------------------------------------------------------- 1 | Unlike the rest of this repository, this directory is for the Kotlin SDK so most of the code here is written in Kotlin, not Java. 2 | -------------------------------------------------------------------------------- /temporal-kotlin/src/main/kotlin/io/temporal/activity/ActivityExecutionContextExt.kt: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.activity 3 | 4 | import kotlin.reflect.javaType 5 | import kotlin.reflect.typeOf 6 | 7 | /** 8 | * Extracts heartbeat details from the last heartbeat of the current activity attempt or from the 9 | * last failed attempt if no heartbeats were sent yet. 10 | * 11 | * @param T type of the Heartbeat details 12 | * @see ActivityExecutionContext.getHeartbeatDetails 13 | */ 14 | @OptIn(ExperimentalStdlibApi::class) 15 | inline fun ActivityExecutionContext.getHeartbeatDetailsOrNull(): T? { 16 | return getHeartbeatDetails(T::class.java, typeOf().javaType).orElse(null) 17 | } 18 | -------------------------------------------------------------------------------- /temporal-kotlin/src/main/kotlin/io/temporal/activity/ActivityOptionsExt.kt: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.activity 3 | 4 | import io.temporal.common.RetryOptions 5 | import io.temporal.kotlin.TemporalDsl 6 | 7 | /** 8 | * Options used to configure how an Activity is invoked. 9 | * 10 | * @see ActivityOptions 11 | */ 12 | inline fun ActivityOptions( 13 | options: @TemporalDsl ActivityOptions.Builder.() -> Unit 14 | ): ActivityOptions { 15 | return ActivityOptions.newBuilder().apply(options).build() 16 | } 17 | 18 | /** 19 | * Create a new instance of [ActivityOptions], optionally overriding some of its properties. 20 | */ 21 | inline fun ActivityOptions.copy( 22 | overrides: @TemporalDsl ActivityOptions.Builder.() -> Unit 23 | ): ActivityOptions { 24 | return toBuilder().apply(overrides).build() 25 | } 26 | 27 | /** 28 | * @see ActivityOptions.Builder.setRetryOptions 29 | * @see ActivityOptions.getRetryOptions 30 | */ 31 | inline fun ActivityOptions.Builder.setRetryOptions( 32 | retryOptions: @TemporalDsl RetryOptions.Builder.() -> Unit 33 | ) { 34 | setRetryOptions(RetryOptions(retryOptions)) 35 | } 36 | -------------------------------------------------------------------------------- /temporal-kotlin/src/main/kotlin/io/temporal/client/WorkflowClientOptionsExt.kt: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.client 3 | 4 | import io.temporal.kotlin.TemporalDsl 5 | 6 | /** 7 | * Options for [WorkflowClient] configuration. 8 | * 9 | * @see WorkflowClientOptions 10 | */ 11 | inline fun WorkflowClientOptions( 12 | options: @TemporalDsl WorkflowClientOptions.Builder.() -> Unit 13 | ): WorkflowClientOptions { 14 | return WorkflowClientOptions.newBuilder().apply(options).build() 15 | } 16 | 17 | /** 18 | * Create a new instance of [WorkflowClientOptions], optionally overriding some of its properties. 19 | */ 20 | inline fun WorkflowClientOptions.copy( 21 | overrides: @TemporalDsl WorkflowClientOptions.Builder.() -> Unit 22 | ): WorkflowClientOptions { 23 | return toBuilder().apply(overrides).build() 24 | } 25 | -------------------------------------------------------------------------------- /temporal-kotlin/src/main/kotlin/io/temporal/client/WorkflowOptionsExt.kt: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.client 3 | 4 | import io.temporal.common.RetryOptions 5 | import io.temporal.kotlin.TemporalDsl 6 | 7 | /** 8 | * @see WorkflowOptions 9 | */ 10 | inline fun WorkflowOptions( 11 | options: @TemporalDsl WorkflowOptions.Builder.() -> Unit 12 | ): WorkflowOptions { 13 | return WorkflowOptions.newBuilder().apply(options).build() 14 | } 15 | 16 | /** 17 | * Create a new instance of [WorkflowOptions], optionally overriding some of its properties. 18 | */ 19 | inline fun WorkflowOptions.copy( 20 | overrides: @TemporalDsl WorkflowOptions.Builder.() -> Unit 21 | ): WorkflowOptions { 22 | return toBuilder().apply(overrides).build() 23 | } 24 | 25 | /** 26 | * @see WorkflowOptions.Builder.setRetryOptions 27 | * @see WorkflowOptions.getRetryOptions 28 | */ 29 | inline fun WorkflowOptions.Builder.setRetryOptions( 30 | retryOptions: @TemporalDsl RetryOptions.Builder.() -> Unit 31 | ) { 32 | setRetryOptions(RetryOptions(retryOptions)) 33 | } 34 | -------------------------------------------------------------------------------- /temporal-kotlin/src/main/kotlin/io/temporal/client/WorkflowStubExt.kt: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.client 3 | 4 | import java.util.concurrent.CompletableFuture 5 | import kotlin.reflect.javaType 6 | import kotlin.reflect.typeOf 7 | 8 | /** 9 | * Returns workflow result potentially waiting for workflow to complete. 10 | * 11 | * @param T type of the workflow return value 12 | * @see WorkflowStub.getResult 13 | */ 14 | @OptIn(ExperimentalStdlibApi::class) 15 | inline fun WorkflowStub.getResult(): T { 16 | return getResult(T::class.java, typeOf().javaType) 17 | } 18 | 19 | /** 20 | * @see WorkflowStub.getResultAsync 21 | */ 22 | @OptIn(ExperimentalStdlibApi::class) 23 | inline fun WorkflowStub.getResultAsync(): CompletableFuture { 24 | return getResultAsync(T::class.java, typeOf().javaType) 25 | } 26 | -------------------------------------------------------------------------------- /temporal-kotlin/src/main/kotlin/io/temporal/common/RetryOptionsExt.kt: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.common 3 | 4 | import io.temporal.kotlin.TemporalDsl 5 | 6 | /** 7 | * @see RetryOptions 8 | */ 9 | inline fun RetryOptions( 10 | options: @TemporalDsl RetryOptions.Builder.() -> Unit 11 | ): RetryOptions { 12 | return RetryOptions.newBuilder().apply(options).build() 13 | } 14 | 15 | /** 16 | * Create a new instance of [RetryOptions], optionally overriding some of its properties. 17 | */ 18 | inline fun RetryOptions.copy( 19 | overrides: @TemporalDsl RetryOptions.Builder.() -> Unit 20 | ): RetryOptions { 21 | return toBuilder().apply(overrides).build() 22 | } 23 | -------------------------------------------------------------------------------- /temporal-kotlin/src/main/kotlin/io/temporal/common/converter/KotlinObjectMapperFactory.kt: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.common.converter 3 | 4 | import com.fasterxml.jackson.databind.ObjectMapper 5 | import com.fasterxml.jackson.module.kotlin.KotlinModule 6 | 7 | class KotlinObjectMapperFactory { 8 | companion object { 9 | @JvmStatic 10 | fun new(): ObjectMapper { 11 | val mapper = JacksonJsonPayloadConverter.newDefaultObjectMapper() 12 | 13 | // use deprecated constructor instead of builder to maintain compatibility with old jackson versions 14 | @Suppress("deprecation") 15 | val km = KotlinModule() 16 | mapper.registerModule(km) 17 | return mapper 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /temporal-kotlin/src/main/kotlin/io/temporal/common/metadata/ActivityMetadata.kt: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.common.metadata 3 | 4 | import kotlin.reflect.KFunction 5 | import kotlin.reflect.jvm.javaMethod 6 | 7 | /** 8 | * Resolves activity name by the activity method reference. 9 | * 10 | * ```kotlin 11 | * val activityName = activityName(ActivityInterface::activityMethod) 12 | * ``` 13 | */ 14 | fun activityName(method: KFunction<*>): String { 15 | val javaMethod = method.javaMethod 16 | ?: throw IllegalArgumentException("Invalid method reference $method") 17 | val interfaceMetadata = POJOActivityInterfaceMetadata.newInstance(javaMethod.declaringClass) 18 | val methodMetadata = interfaceMetadata.methodsMetadata.find { it.method == javaMethod } 19 | ?: throw IllegalArgumentException("Not an activity method reference $method") 20 | return methodMetadata.activityTypeName 21 | } 22 | -------------------------------------------------------------------------------- /temporal-kotlin/src/main/kotlin/io/temporal/kotlin/TemporalDsl.kt: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.kotlin 3 | 4 | /** 5 | * [Scope control](https://kotlinlang.org/docs/type-safe-builders.html#scope-control-dslmarker) 6 | * marker annotation for DSL-like code blocks that target Temporal SDK classes. 7 | */ 8 | @DslMarker 9 | @Target(AnnotationTarget.TYPE, AnnotationTarget.CLASS) 10 | @Retention(AnnotationRetention.SOURCE) 11 | annotation class TemporalDsl 12 | -------------------------------------------------------------------------------- /temporal-kotlin/src/main/kotlin/io/temporal/serviceclient/RpcRetryOptionsExt.kt: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.serviceclient 3 | 4 | import io.temporal.kotlin.TemporalDsl 5 | 6 | /** 7 | * @see RpcRetryOptions 8 | */ 9 | inline fun RpcRetryOptions( 10 | options: @TemporalDsl RpcRetryOptions.Builder.() -> Unit 11 | ): RpcRetryOptions { 12 | return RpcRetryOptions.newBuilder().apply(options).build() 13 | } 14 | 15 | /** 16 | * Create a new instance of [RpcRetryOptions], optionally overriding some of its properties. 17 | */ 18 | inline fun RpcRetryOptions.copy( 19 | overrides: @TemporalDsl RpcRetryOptions.Builder.() -> Unit 20 | ): RpcRetryOptions { 21 | return RpcRetryOptions.newBuilder(this).apply(overrides).build() 22 | } 23 | -------------------------------------------------------------------------------- /temporal-kotlin/src/main/kotlin/io/temporal/serviceclient/WorkflowServiceStubsOptionsExt.kt: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.serviceclient 3 | 4 | import io.temporal.kotlin.TemporalDsl 5 | 6 | /** 7 | * @see WorkflowServiceStubsOptions 8 | */ 9 | inline fun WorkflowServiceStubsOptions( 10 | options: @TemporalDsl WorkflowServiceStubsOptions.Builder.() -> Unit 11 | ): WorkflowServiceStubsOptions { 12 | return WorkflowServiceStubsOptions.newBuilder().apply(options).build() 13 | } 14 | 15 | /** 16 | * Create a new instance of [WorkflowServiceStubsOptions], optionally overriding some of its properties. 17 | */ 18 | inline fun WorkflowServiceStubsOptions.copy( 19 | overrides: @TemporalDsl WorkflowServiceStubsOptions.Builder.() -> Unit 20 | ): WorkflowServiceStubsOptions { 21 | return WorkflowServiceStubsOptions.newBuilder(this).apply(overrides).build() 22 | } 23 | -------------------------------------------------------------------------------- /temporal-kotlin/src/main/kotlin/io/temporal/worker/WorkerFactoryExt.kt: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.worker 3 | 4 | import io.temporal.client.WorkflowClient 5 | import io.temporal.kotlin.TemporalDsl 6 | 7 | /** 8 | * @see WorkerFactory 9 | */ 10 | fun WorkerFactory( 11 | workflowClient: WorkflowClient 12 | ): WorkerFactory { 13 | return WorkerFactory.newInstance(workflowClient) 14 | } 15 | 16 | /** 17 | * @see WorkerFactory 18 | */ 19 | fun WorkerFactory( 20 | workflowClient: WorkflowClient, 21 | options: @TemporalDsl WorkerFactoryOptions.Builder.() -> Unit 22 | ): WorkerFactory { 23 | return WorkerFactory.newInstance(workflowClient, WorkerFactoryOptions(options)) 24 | } 25 | 26 | /** 27 | * Creates worker that connects to an instance of the Temporal Service. 28 | * 29 | * @see WorkerFactory.newWorker 30 | */ 31 | inline fun WorkerFactory.newWorker( 32 | taskQueue: String, 33 | options: @TemporalDsl WorkerOptions.Builder.() -> Unit 34 | ): Worker { 35 | return newWorker(taskQueue, WorkerOptions(options)) 36 | } 37 | -------------------------------------------------------------------------------- /temporal-kotlin/src/main/kotlin/io/temporal/worker/WorkerFactoryOptionsExt.kt: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.worker 3 | 4 | import io.temporal.kotlin.TemporalDsl 5 | 6 | /** 7 | * @see WorkerFactoryOptions 8 | */ 9 | inline fun WorkerFactoryOptions( 10 | options: @TemporalDsl WorkerFactoryOptions.Builder.() -> Unit 11 | ): WorkerFactoryOptions { 12 | return WorkerFactoryOptions.newBuilder().apply(options).build() 13 | } 14 | 15 | /** 16 | * Create a new instance of [WorkerFactoryOptions], optionally overriding some of its properties. 17 | */ 18 | inline fun WorkerFactoryOptions.copy( 19 | overrides: @TemporalDsl WorkerFactoryOptions.Builder.() -> Unit 20 | ): WorkerFactoryOptions { 21 | return toBuilder().apply(overrides).build() 22 | } 23 | -------------------------------------------------------------------------------- /temporal-kotlin/src/main/kotlin/io/temporal/worker/WorkerOptionsExt.kt: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.worker 3 | 4 | import io.temporal.kotlin.TemporalDsl 5 | 6 | /** 7 | * @see WorkerOptions 8 | */ 9 | inline fun WorkerOptions( 10 | options: @TemporalDsl WorkerOptions.Builder.() -> Unit 11 | ): WorkerOptions { 12 | return WorkerOptions.newBuilder().apply(options).build() 13 | } 14 | 15 | /** 16 | * Create a new instance of [WorkerOptions], optionally overriding some of its properties. 17 | */ 18 | inline fun WorkerOptions.copy( 19 | overrides: @TemporalDsl WorkerOptions.Builder.() -> Unit 20 | ): WorkerOptions { 21 | return WorkerOptions.newBuilder(this).apply(overrides).build() 22 | } 23 | -------------------------------------------------------------------------------- /temporal-kotlin/src/main/kotlin/io/temporal/workflow/ChildWorkflowOptionsExt.kt: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.workflow 3 | 4 | import io.temporal.common.RetryOptions 5 | import io.temporal.kotlin.TemporalDsl 6 | 7 | /** 8 | * @see ChildWorkflowOptions 9 | */ 10 | inline fun ChildWorkflowOptions( 11 | options: @TemporalDsl ChildWorkflowOptions.Builder.() -> Unit 12 | ): ChildWorkflowOptions { 13 | return ChildWorkflowOptions.newBuilder().apply(options).build() 14 | } 15 | 16 | /** 17 | * Create a new instance of [ChildWorkflowOptions], optionally overriding some of its properties. 18 | */ 19 | inline fun ChildWorkflowOptions.copy( 20 | overrides: @TemporalDsl ChildWorkflowOptions.Builder.() -> Unit 21 | ): ChildWorkflowOptions { 22 | return toBuilder().apply(overrides).build() 23 | } 24 | 25 | /** 26 | * @see ChildWorkflowOptions.Builder.setRetryOptions 27 | * @see ChildWorkflowOptions.getRetryOptions 28 | */ 29 | inline fun ChildWorkflowOptions.Builder.setRetryOptions( 30 | retryOptions: @TemporalDsl RetryOptions.Builder.() -> Unit 31 | ) { 32 | setRetryOptions(RetryOptions(retryOptions)) 33 | } 34 | -------------------------------------------------------------------------------- /temporal-kotlin/src/main/kotlin/io/temporal/workflow/ChildWorkflowStubExt.kt: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.workflow 3 | 4 | import kotlin.reflect.javaType 5 | import kotlin.reflect.typeOf 6 | 7 | /** 8 | * @see ChildWorkflowStub.execute 9 | */ 10 | @OptIn(ExperimentalStdlibApi::class) 11 | inline fun ChildWorkflowStub.execute(vararg args: Any?): T { 12 | return execute(T::class.java, typeOf().javaType, *args) 13 | } 14 | 15 | /** 16 | * @see ChildWorkflowStub.executeAsync 17 | */ 18 | @OptIn(ExperimentalStdlibApi::class) 19 | inline fun ChildWorkflowStub.executeAsync(vararg args: Any?): Promise { 20 | return executeAsync(T::class.java, typeOf().javaType, *args) 21 | } 22 | -------------------------------------------------------------------------------- /temporal-kotlin/src/main/kotlin/io/temporal/workflow/ContinueAsNewOptionsExt.kt: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.workflow 3 | 4 | import io.temporal.kotlin.TemporalDsl 5 | 6 | /** 7 | * @see ContinueAsNewOptions 8 | */ 9 | inline fun ContinueAsNewOptions( 10 | options: @TemporalDsl ContinueAsNewOptions.Builder.() -> Unit 11 | ): ContinueAsNewOptions { 12 | return ContinueAsNewOptions.newBuilder().apply(options).build() 13 | } 14 | 15 | /** 16 | * Create a new instance of [ContinueAsNewOptions], optionally overriding some of its properties. 17 | */ 18 | inline fun ContinueAsNewOptions.copy( 19 | overrides: @TemporalDsl ContinueAsNewOptions.Builder.() -> Unit 20 | ): ContinueAsNewOptions { 21 | return ContinueAsNewOptions.newBuilder(this).apply(overrides).build() 22 | } 23 | -------------------------------------------------------------------------------- /temporal-kotlin/src/main/kotlin/io/temporal/workflow/NexusOperationOptionsExt.kt: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.workflow 3 | 4 | import io.temporal.kotlin.TemporalDsl 5 | 6 | /** 7 | * @see NexusOperationOptions 8 | */ 9 | inline fun NexusOperationOptions( 10 | options: @TemporalDsl NexusOperationOptions.Builder.() -> Unit 11 | ): NexusOperationOptions { 12 | return NexusOperationOptions.newBuilder().apply(options).build() 13 | } 14 | 15 | /** 16 | * Create a new instance of [NexusOperationOptions], optionally overriding some of its properties. 17 | */ 18 | inline fun NexusOperationOptions.copy( 19 | overrides: @TemporalDsl NexusOperationOptions.Builder.() -> Unit 20 | ): NexusOperationOptions { 21 | return toBuilder().apply(overrides).build() 22 | } 23 | -------------------------------------------------------------------------------- /temporal-kotlin/src/main/kotlin/io/temporal/workflow/NexusServiceOptionsExt.kt: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.workflow 3 | 4 | import io.temporal.kotlin.TemporalDsl 5 | 6 | /** 7 | * @see NexusServiceOptions 8 | */ 9 | inline fun NexusServiceOptions( 10 | options: @TemporalDsl NexusServiceOptions.Builder.() -> Unit 11 | ): NexusServiceOptions { 12 | return NexusServiceOptions.newBuilder().apply(options).build() 13 | } 14 | 15 | /** 16 | * Create a new instance of [NexusServiceOptions], optionally overriding some of its properties. 17 | */ 18 | inline fun NexusServiceOptions.copy( 19 | overrides: @TemporalDsl NexusServiceOptions.Builder.() -> Unit 20 | ): NexusServiceOptions { 21 | return toBuilder().apply(overrides).build() 22 | } 23 | -------------------------------------------------------------------------------- /temporal-kotlin/src/main/kotlin/io/temporal/workflow/SagaExt.kt: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.workflow 3 | 4 | import io.temporal.kotlin.TemporalDsl 5 | 6 | /** 7 | * Builds an instance of [Saga]. 8 | * 9 | * ```kotlin 10 | * val saga = Saga { 11 | * // saga options 12 | * } 13 | * try { 14 | * val r = activity.foo() 15 | * saga.addCompensation { activity.cleanupFoo(arg2, r) } 16 | * val r2 = Async.function { activity.bar() } 17 | * r2.thenApply { r2result -> 18 | * saga.addCompensation { activity.cleanupBar(r2result) } 19 | * } 20 | * // ... 21 | * useR2(r2.get()) 22 | * } catch (Exception e) { 23 | * saga.compensate() 24 | * // Other error handling if needed. 25 | * } 26 | * ``` 27 | * 28 | * @see Saga 29 | * @see Saga.Options 30 | */ 31 | inline fun Saga(options: @TemporalDsl Saga.Options.Builder.() -> Unit = {}): Saga { 32 | return Saga(Saga.Options.Builder().apply(options).build()) 33 | } 34 | -------------------------------------------------------------------------------- /temporal-kotlin/src/main/resources/META-INF/services/io.temporal.internal.async.spi.MethodReferenceDisassemblyService: -------------------------------------------------------------------------------- 1 | io.temporal.internal.async.KotlinMethodReferenceDisassemblyService -------------------------------------------------------------------------------- /temporal-kotlin/src/test/java/io/temporal/internal/async/FunctionWrappingUtil.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.async; 2 | 3 | import io.temporal.workflow.Functions; 4 | 5 | public class FunctionWrappingUtil { 6 | /** 7 | * We emulate here what happens in Async/AsyncInternal when {@link 8 | * io.temporal.workflow.Async#function(Functions.Func)} accepts {@link Functions.Func} as a 9 | * parameter and kotlin method reference is getting wrapped into {@link Functions.Func} 10 | */ 11 | public static Functions.Func temporalJavaFunctionalWrapper(Functions.Func function) { 12 | return function; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /temporal-kotlin/src/test/kotlin/io/temporal/nexus/NexusOperationOptionsExtTest.kt: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.nexus 3 | 4 | import io.temporal.workflow.NexusOperationOptions 5 | import org.junit.Assert.assertEquals 6 | import org.junit.Test 7 | import java.time.Duration 8 | 9 | class NexusOperationOptionsExtTest { 10 | 11 | @Test 12 | fun `OperationOptions DSL should be equivalent to builder`() { 13 | val dslOperationOptions = NexusOperationOptions { 14 | setScheduleToCloseTimeout(Duration.ofMinutes(1)) 15 | } 16 | 17 | val builderOperationOptions = NexusOperationOptions.newBuilder() 18 | .setScheduleToCloseTimeout(Duration.ofMinutes(1)) 19 | .build() 20 | 21 | assertEquals(builderOperationOptions, dslOperationOptions) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /temporal-opentracing/build.gradle: -------------------------------------------------------------------------------- 1 | description = '''Temporal Java SDK OpenTracing Support Module''' 2 | 3 | ext { 4 | opentracingVersion = '0.33.0' 5 | } 6 | 7 | dependencies { 8 | // this module shouldn't carry temporal-sdk with it, especially for situations when users may be using a shaded artifact 9 | compileOnly project(':temporal-sdk') 10 | api group: 'io.opentracing', name: 'opentracing-api', version: "$opentracingVersion" 11 | 12 | implementation "com.google.guava:guava:$guavaVersion" 13 | implementation group: 'io.opentracing', name: 'opentracing-util', version: "$opentracingVersion" 14 | 15 | testImplementation project(":temporal-testing") 16 | testImplementation "junit:junit:${junitVersion}" 17 | testImplementation "org.mockito:mockito-core:${mockitoVersion}" 18 | testImplementation group: 'io.opentracing', name: 'opentracing-mock', version: "$opentracingVersion" 19 | testImplementation group: 'io.jaegertracing', name: 'jaeger-client', version: '1.8.1' 20 | 21 | testRuntimeOnly group: 'ch.qos.logback', name: 'logback-classic', version: "${logbackVersion}" 22 | } -------------------------------------------------------------------------------- /temporal-opentracing/src/main/java/io/temporal/opentracing/OpenTracingSpanContextCodec.java: -------------------------------------------------------------------------------- 1 | package io.temporal.opentracing; 2 | 3 | import io.opentracing.SpanContext; 4 | import io.opentracing.Tracer; 5 | import io.temporal.opentracing.codec.TextMapCodec; 6 | import io.temporal.opentracing.codec.TextMapInjectExtractCodec; 7 | import java.util.Map; 8 | 9 | /** 10 | * Provides an interface for pluggable implementations that provide encoding/decoding of OpenTracing 11 | * {@link SpanContext}s back and forth to {@code Map} that can be transported inside 12 | * Temporal Headers 13 | */ 14 | public interface OpenTracingSpanContextCodec { 15 | // default implementation 16 | OpenTracingSpanContextCodec TEXT_MAP_INJECT_EXTRACT_CODEC = TextMapInjectExtractCodec.INSTANCE; 17 | OpenTracingSpanContextCodec TEXT_MAP_CODEC = TextMapCodec.INSTANCE; 18 | 19 | Map encode(SpanContext spanContext, Tracer tracer); 20 | 21 | SpanContext decode(Map serializedSpanContext, Tracer tracer); 22 | } 23 | -------------------------------------------------------------------------------- /temporal-opentracing/src/main/java/io/temporal/opentracing/SpanBuilderProvider.java: -------------------------------------------------------------------------------- 1 | package io.temporal.opentracing; 2 | 3 | import io.opentracing.Tracer; 4 | 5 | /** 6 | * Fully pluggable strategy for creating OpenTracing spans based on content from the {@link 7 | * SpanCreationContext} 8 | */ 9 | public interface SpanBuilderProvider { 10 | Tracer.SpanBuilder createSpanBuilder(Tracer tracer, SpanCreationContext spanCreationContext); 11 | } 12 | -------------------------------------------------------------------------------- /temporal-opentracing/src/main/java/io/temporal/opentracing/StandardTagNames.java: -------------------------------------------------------------------------------- 1 | package io.temporal.opentracing; 2 | 3 | public class StandardTagNames { 4 | public static final String WORKFLOW_ID = "workflowId"; 5 | public static final String RUN_ID = "runId"; 6 | public static final String PARENT_WORKFLOW_ID = "parentWorkflowId"; 7 | public static final String PARENT_RUN_ID = "parentRunId"; 8 | 9 | /** 10 | * @deprecated use {@link io.opentracing.tag.Tags#ERROR} 11 | */ 12 | @Deprecated public static final String FAILED = "failed"; 13 | 14 | public static final String EVICTED = "evicted"; 15 | } 16 | -------------------------------------------------------------------------------- /temporal-remote-data-encoder/src/test/java/io/temporal/ActivityImpl.java: -------------------------------------------------------------------------------- 1 | package io.temporal; 2 | 3 | public class ActivityImpl implements TestActivityArgs { 4 | public static final int ACTIVITY_RESULT = 500; 5 | 6 | @Override 7 | public int execute(String arg1, boolean arg2) { 8 | return ACTIVITY_RESULT; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /temporal-remote-data-encoder/src/test/java/io/temporal/ActivityWorkflow.java: -------------------------------------------------------------------------------- 1 | package io.temporal; 2 | 3 | import io.temporal.activity.ActivityOptions; 4 | import io.temporal.failure.ActivityFailure; 5 | import io.temporal.workflow.Workflow; 6 | import java.time.Duration; 7 | 8 | public class ActivityWorkflow implements TestWorkflowStringArg { 9 | private final TestActivityArgs activity = 10 | Workflow.newActivityStub( 11 | TestActivityArgs.class, 12 | ActivityOptions.newBuilder().setScheduleToCloseTimeout(Duration.ofSeconds(2)).build()); 13 | 14 | @Override 15 | public int execute(String input) { 16 | try { 17 | return activity.execute(input, true); 18 | } catch (ActivityFailure e) { 19 | throw e; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /temporal-remote-data-encoder/src/test/java/io/temporal/PortUtils.java: -------------------------------------------------------------------------------- 1 | package io.temporal; 2 | 3 | import java.io.IOException; 4 | import java.net.ServerSocket; 5 | 6 | class PortUtils { 7 | static int getFreePort() { 8 | try (ServerSocket socket = new ServerSocket(0)) { 9 | socket.setReuseAddress(true); 10 | return socket.getLocalPort(); 11 | } catch (IOException e) { 12 | throw new RuntimeException(e); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /temporal-remote-data-encoder/src/test/java/io/temporal/TestActivityArgs.java: -------------------------------------------------------------------------------- 1 | package io.temporal; 2 | 3 | import io.temporal.activity.ActivityInterface; 4 | import io.temporal.activity.ActivityMethod; 5 | 6 | @ActivityInterface 7 | public interface TestActivityArgs { 8 | @ActivityMethod 9 | int execute(String arg1, boolean arg2); 10 | } 11 | -------------------------------------------------------------------------------- /temporal-remote-data-encoder/src/test/java/io/temporal/TestWorkflowStringArg.java: -------------------------------------------------------------------------------- 1 | package io.temporal; 2 | 3 | import io.temporal.workflow.WorkflowInterface; 4 | import io.temporal.workflow.WorkflowMethod; 5 | 6 | @WorkflowInterface 7 | public interface TestWorkflowStringArg { 8 | @WorkflowMethod 9 | int execute(String arg); 10 | } 11 | -------------------------------------------------------------------------------- /temporal-sdk/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .*.swp 3 | .*.swo 4 | *.iml 5 | .DS_Store 6 | .idea 7 | .gradle 8 | /build 9 | /out 10 | /lib 11 | dummy 12 | $buildDir 13 | src/main/idls/* 14 | /bin 15 | .classpath 16 | .project 17 | .settings 18 | .vscode/ 19 | -------------------------------------------------------------------------------- /temporal-sdk/AGENTS.md: -------------------------------------------------------------------------------- 1 | This directory contains the core Temporal SDK code, which is used to build Temporal applications. The SDK provides a set of APIs and libraries that allow developers to create, manage, and execute workflows and activities in a distributed environment. The SDK is designed to be easy to use and provides a high-level abstraction over the underlying Temporal service. 2 | 3 | The SDK is written in Java and is designed to be used with the Temporal service. It provides a set of APIs for defining workflows and activities, as well as for managing the execution of those workflows and activities. 4 | 5 | # Testing 6 | 7 | All tests are written using JUnit4. 8 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/activity/DynamicActivity.java: -------------------------------------------------------------------------------- 1 | package io.temporal.activity; 2 | 3 | import io.temporal.common.converter.EncodedValues; 4 | 5 | /** 6 | * Use DynamicActivity to implement any number of activity types dynamically. When an activity 7 | * implementation that extends DynamicActivity is registered it is called for any activity type 8 | * invocation that doesn't have an explicitly registered handler. Only one instance that implements 9 | * DynamicActivity per {@link io.temporal.worker.Worker} is allowed. 10 | * 11 | *

The DynamicActivity can be useful for integrations with existing libraries. For example, it 12 | * can be used to call some external HTTP API with each function exposed as a different activity 13 | * type. 14 | * 15 | *

Use {@link Activity#getExecutionContext()} to query information about the activity type that 16 | * should be implemented dynamically. 17 | * 18 | * @see io.temporal.workflow.DynamicWorkflow 19 | */ 20 | public interface DynamicActivity { 21 | Object execute(EncodedValues args); 22 | } 23 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/client/ActivityCompletionFailureException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.client; 2 | 3 | import io.temporal.activity.ActivityInfo; 4 | 5 | /** Unexpected failure when completing an activity. */ 6 | public final class ActivityCompletionFailureException extends ActivityCompletionException { 7 | 8 | public ActivityCompletionFailureException(Throwable cause) { 9 | super(cause); 10 | } 11 | 12 | public ActivityCompletionFailureException(ActivityInfo info, Throwable cause) { 13 | super(info, cause); 14 | } 15 | 16 | public ActivityCompletionFailureException(String activityId, Throwable cause) { 17 | super(activityId, cause); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/client/ActivityNotExistsException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.client; 2 | 3 | import io.temporal.activity.ActivityInfo; 4 | 5 | /** 6 | * Usually indicates that activity was already completed (duplicated request to complete) or timed 7 | * out or workflow execution is closed (cancelled, terminated or timed out). 8 | */ 9 | public final class ActivityNotExistsException extends ActivityCompletionException { 10 | 11 | public ActivityNotExistsException(Throwable cause) { 12 | super(cause); 13 | } 14 | 15 | public ActivityNotExistsException(ActivityInfo info, Throwable cause) { 16 | super(info, cause); 17 | } 18 | 19 | public ActivityNotExistsException(String activityId, Throwable cause) { 20 | super(activityId, cause); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/client/ActivityPausedException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.client; 2 | 3 | import io.temporal.activity.ActivityInfo; 4 | 5 | /*** 6 | * Indicates that the activity was paused by the user. 7 | * 8 | *

Catching this exception directly is discouraged and catching the parent class {@link ActivityCompletionException} is recommended instead.
9 | */ 10 | public final class ActivityPausedException extends ActivityCompletionException { 11 | public ActivityPausedException(ActivityInfo info) { 12 | super(info); 13 | } 14 | 15 | public ActivityPausedException() { 16 | super(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/client/ActivityWorkerShutdownException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.client; 2 | 3 | import io.temporal.activity.ActivityInfo; 4 | import io.temporal.worker.WorkerFactory; 5 | import java.util.concurrent.TimeUnit; 6 | 7 | /** 8 | * Indicates that {@link WorkerFactory#shutdown()} or {@link WorkerFactory#shutdownNow()} was 9 | * called. It is OK to ignore the exception to let the activity complete. It assumes that {@link 10 | * WorkerFactory#awaitTermination(long, TimeUnit)} is called with a timeout larger than the activity 11 | * execution time. 12 | */ 13 | public final class ActivityWorkerShutdownException extends ActivityCompletionException { 14 | 15 | public ActivityWorkerShutdownException(ActivityInfo info) { 16 | super(info); 17 | } 18 | 19 | public ActivityWorkerShutdownException() { 20 | super(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/client/CloudOperationsClient.java: -------------------------------------------------------------------------------- 1 | package io.temporal.client; 2 | 3 | import io.temporal.common.Experimental; 4 | import io.temporal.serviceclient.CloudServiceStubs; 5 | 6 | /** Client to the Temporal Cloud operations service for performing cloud operations. */ 7 | @Experimental 8 | public interface CloudOperationsClient { 9 | @Experimental 10 | static CloudOperationsClient newInstance(CloudServiceStubs service) { 11 | return new CloudOperationsClientImpl(service); 12 | } 13 | 14 | /** Get the raw cloud service stubs. */ 15 | @Experimental 16 | CloudServiceStubs getCloudServiceStubs(); 17 | } 18 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/client/CloudOperationsClientImpl.java: -------------------------------------------------------------------------------- 1 | package io.temporal.client; 2 | 3 | import io.temporal.serviceclient.CloudServiceStubs; 4 | 5 | class CloudOperationsClientImpl implements CloudOperationsClient { 6 | private final CloudServiceStubs cloudServiceStubs; 7 | 8 | CloudOperationsClientImpl(CloudServiceStubs cloudServiceStubs) { 9 | this.cloudServiceStubs = cloudServiceStubs; 10 | } 11 | 12 | @Override 13 | public CloudServiceStubs getCloudServiceStubs() { 14 | return cloudServiceStubs; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/client/WorkflowNotFoundException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.client; 2 | 3 | import io.temporal.api.common.v1.WorkflowExecution; 4 | 5 | /** 6 | * Thrown when a workflow with the given id is not known to the Temporal service or in an incorrect 7 | * state to perform the operation. 8 | * 9 | *

Examples of possible causes: 10 | * 11 | *

    12 | *
  • workflow id doesn't exist 13 | *
  • workflow was purged from the service after reaching its retention limit 14 | *
  • attempt to signal a workflow that is completed 15 | *
16 | */ 17 | public final class WorkflowNotFoundException extends WorkflowException { 18 | 19 | public WorkflowNotFoundException( 20 | WorkflowExecution execution, String workflowType, Throwable cause) { 21 | super(execution, workflowType, cause); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/client/WorkflowQueryException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.client; 2 | 3 | import io.temporal.api.common.v1.WorkflowExecution; 4 | 5 | public class WorkflowQueryException extends WorkflowException { 6 | 7 | public WorkflowQueryException(WorkflowExecution execution, String workflowType, Throwable cause) { 8 | super(execution, workflowType, cause); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/client/WorkflowQueryRejectedException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.client; 2 | 3 | import io.temporal.api.common.v1.WorkflowExecution; 4 | 5 | public class WorkflowQueryRejectedException extends WorkflowQueryException { 6 | 7 | public WorkflowQueryRejectedException( 8 | WorkflowExecution execution, String workflowType, Throwable cause) { 9 | super(execution, workflowType, cause); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/client/WorkflowServiceException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.client; 2 | 3 | import io.temporal.api.common.v1.WorkflowExecution; 4 | import javax.annotation.Nonnull; 5 | 6 | public class WorkflowServiceException extends WorkflowException { 7 | public WorkflowServiceException( 8 | @Nonnull WorkflowExecution execution, String workflowType, Throwable cause) { 9 | super(execution, workflowType, cause); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/client/WorkflowUpdateException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.client; 2 | 3 | import io.temporal.api.common.v1.WorkflowExecution; 4 | 5 | /** Exception used to communicate failure of an update workflow execution request. */ 6 | public final class WorkflowUpdateException extends WorkflowException { 7 | 8 | private final String updateId; 9 | private final String updateName; 10 | 11 | public WorkflowUpdateException( 12 | WorkflowExecution execution, String updateId, String updateName, Throwable cause) { 13 | super(execution, null, cause); 14 | this.updateName = updateName; 15 | this.updateId = updateId; 16 | } 17 | 18 | public String GetUpdateId() { 19 | return updateId; 20 | } 21 | 22 | public String GetUpdateName() { 23 | return updateName; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/client/WorkflowUpdateTimeoutOrCancelledException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.client; 2 | 3 | import io.temporal.api.common.v1.WorkflowExecution; 4 | 5 | /** 6 | * Error that occurs when an update call times out or is cancelled. 7 | * 8 | *

Note, this is not related to any general concept of timing out or cancelling a running update, 9 | * this is only related to the client call itself. 10 | */ 11 | public class WorkflowUpdateTimeoutOrCancelledException extends WorkflowServiceException { 12 | public WorkflowUpdateTimeoutOrCancelledException( 13 | WorkflowExecution execution, String updateId, String updateName, Throwable cause) { 14 | super(execution, "", cause); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/client/schedules/ScheduleAction.java: -------------------------------------------------------------------------------- 1 | package io.temporal.client.schedules; 2 | 3 | /** 4 | * Base class for an action a schedule can take. See ScheduleActionStartWorkflow for the most 5 | * commonly used implementation. 6 | * 7 | * @see ScheduleActionStartWorkflow 8 | */ 9 | public abstract class ScheduleAction { 10 | ScheduleAction() {} 11 | } 12 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/client/schedules/ScheduleActionExecution.java: -------------------------------------------------------------------------------- 1 | package io.temporal.client.schedules; 2 | 3 | /** 4 | * Base class for an action execution. 5 | * 6 | * @see ScheduleActionExecutionStartWorkflow 7 | */ 8 | public abstract class ScheduleActionExecution { 9 | ScheduleActionExecution() {} 10 | } 11 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/client/schedules/ScheduleAlreadyRunningException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.client.schedules; 2 | 3 | import io.temporal.failure.TemporalException; 4 | 5 | /** Exception thrown by client when attempting to create a schedule that was already created. */ 6 | public final class ScheduleAlreadyRunningException extends TemporalException { 7 | public ScheduleAlreadyRunningException(Throwable cause) { 8 | super("Schedule already running", cause); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/client/schedules/ScheduleException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.client.schedules; 2 | 3 | import io.temporal.failure.TemporalException; 4 | 5 | /** Exception thrown by client when attempting to create a schedule. */ 6 | public final class ScheduleException extends TemporalException { 7 | public ScheduleException(Throwable cause) { 8 | super("Schedule exception", cause); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/client/schedules/ScheduleListAction.java: -------------------------------------------------------------------------------- 1 | package io.temporal.client.schedules; 2 | 3 | /** Base class for an action a listed schedule can take. */ 4 | public abstract class ScheduleListAction { 5 | ScheduleListAction() {} 6 | } 7 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/client/schedules/ScheduleUpdateInput.java: -------------------------------------------------------------------------------- 1 | package io.temporal.client.schedules; 2 | 3 | /** Parameter passed to a schedule updater. */ 4 | public final class ScheduleUpdateInput { 5 | private final ScheduleDescription description; 6 | 7 | public ScheduleUpdateInput(ScheduleDescription description) { 8 | this.description = description; 9 | } 10 | 11 | /** 12 | * Description fetched from the server before this update. 13 | * 14 | * @return description of schedule to be updated 15 | */ 16 | public ScheduleDescription getDescription() { 17 | return this.description; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/common/CronSchedule.java: -------------------------------------------------------------------------------- 1 | package io.temporal.common; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * CronSchedule - Optional cron schedule for workflow. If a cron schedule is specified, the workflow 10 | * will run as a cron based on the schedule. The scheduling will be based on UTC time. Schedule for 11 | * next run only happen after the current run is completed/failed/timeout. If a RetryPolicy is also 12 | * supplied, and the workflow failed or timeout, the workflow will be retried based on the retry 13 | * policy. While the workflow is retrying, it won't schedule its next run. If next schedule is due 14 | * while workflow is running (or retrying), then it will skip that schedule. Cron workflow will not 15 | * stop until it is terminated or canceled. 16 | */ 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target(ElementType.METHOD) 19 | public @interface CronSchedule { 20 | String value(); 21 | } 22 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/common/Experimental.java: -------------------------------------------------------------------------------- 1 | package io.temporal.common; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * Annotation that specifies that an element is experimental, has unstable API or may change without 7 | * notice. This annotation is inherited. 8 | */ 9 | @Inherited 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Target({ElementType.FIELD, ElementType.TYPE, ElementType.METHOD}) 12 | public @interface Experimental {} 13 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/common/SearchAttribute.java: -------------------------------------------------------------------------------- 1 | package io.temporal.common; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | /** 8 | * @deprecated typed search attributes should be used instead. 9 | */ 10 | @Deprecated 11 | public class SearchAttribute { 12 | /** 13 | * Passing this value as a search attribute value into {@link 14 | * io.temporal.workflow.Workflow#upsertSearchAttributes(Map)} will lead to unsetting the search 15 | * attribute with the corresponded name if any present. 16 | */ 17 | public static final List UNSET_VALUE = Collections.emptyList(); 18 | } 19 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/common/VersioningBehavior.java: -------------------------------------------------------------------------------- 1 | package io.temporal.common; 2 | 3 | import io.temporal.worker.WorkerDeploymentOptions; 4 | 5 | /** Specifies when a workflow might move from a worker of one Build Id to another. */ 6 | @Experimental 7 | public enum VersioningBehavior { 8 | /** 9 | * An unspecified versioning behavior. By default, workers opting into worker versioning will be 10 | * required to specify a behavior. See {@link 11 | * io.temporal.worker.WorkerOptions.Builder#setDeploymentOptions(WorkerDeploymentOptions)}. 12 | */ 13 | UNSPECIFIED, 14 | /** The workflow will be pinned to the current Build ID unless manually moved. */ 15 | PINNED, 16 | /** 17 | * The workflow will automatically move to the latest version (default Build ID of the task queue) 18 | * when the next task is dispatched. 19 | */ 20 | AUTO_UPGRADE 21 | } 22 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/common/converter/ConverterUtils.java: -------------------------------------------------------------------------------- 1 | package io.temporal.common.converter; 2 | 3 | import io.temporal.payload.codec.PayloadCodec; 4 | import io.temporal.payload.context.SerializationContext; 5 | import javax.annotation.Nonnull; 6 | import javax.annotation.Nullable; 7 | 8 | class ConverterUtils { 9 | static DataConverter withContext( 10 | @Nonnull DataConverter converter, @Nullable SerializationContext context) { 11 | return context != null ? converter.withContext(context) : converter; 12 | } 13 | 14 | static PayloadCodec withContext( 15 | @Nonnull PayloadCodec codec, @Nullable SerializationContext context) { 16 | return context != null ? codec.withContext(context) : codec; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/common/converter/GlobalDataConverter.java: -------------------------------------------------------------------------------- 1 | package io.temporal.common.converter; 2 | 3 | import java.util.concurrent.atomic.AtomicReference; 4 | 5 | public class GlobalDataConverter { 6 | private GlobalDataConverter() {} 7 | 8 | private static final AtomicReference globalDataConverterInstance = 9 | new AtomicReference<>(DefaultDataConverter.STANDARD_INSTANCE); 10 | 11 | /** 12 | * Override the global data converter default. 13 | * 14 | *

Consider using {@link 15 | * io.temporal.client.WorkflowClientOptions.Builder#setDataConverter(DataConverter)} to set data 16 | * converter per client / worker instance to avoid conflicts if your setup requires different 17 | * converters for different clients / workers. 18 | */ 19 | public static void register(DataConverter converter) { 20 | globalDataConverterInstance.set(converter); 21 | } 22 | 23 | public static DataConverter get() { 24 | return globalDataConverterInstance.get(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/common/converter/NullPayloadConverter.java: -------------------------------------------------------------------------------- 1 | package io.temporal.common.converter; 2 | 3 | import io.temporal.api.common.v1.Payload; 4 | import java.lang.reflect.Type; 5 | import java.util.Optional; 6 | 7 | /** Encodes and decodes null values. */ 8 | public final class NullPayloadConverter implements PayloadConverter { 9 | @Override 10 | public String getEncodingType() { 11 | return EncodingKeys.METADATA_ENCODING_NULL_NAME; 12 | } 13 | 14 | @Override 15 | public Optional toData(Object value) throws DataConverterException { 16 | if (value == null) { 17 | return Optional.of( 18 | Payload.newBuilder() 19 | .putMetadata(EncodingKeys.METADATA_ENCODING_KEY, EncodingKeys.METADATA_ENCODING_NULL) 20 | .build()); 21 | } 22 | return Optional.empty(); 23 | } 24 | 25 | @Override 26 | public T fromData(Payload content, Class valueClass, Type valueType) 27 | throws DataConverterException { 28 | return null; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/common/interceptors/ActivityInboundCallsInterceptorBase.java: -------------------------------------------------------------------------------- 1 | package io.temporal.common.interceptors; 2 | 3 | import io.temporal.activity.ActivityExecutionContext; 4 | 5 | public class ActivityInboundCallsInterceptorBase implements ActivityInboundCallsInterceptor { 6 | private final ActivityInboundCallsInterceptor next; 7 | 8 | public ActivityInboundCallsInterceptorBase(ActivityInboundCallsInterceptor next) { 9 | this.next = next; 10 | } 11 | 12 | @Override 13 | public void init(ActivityExecutionContext context) { 14 | next.init(context); 15 | } 16 | 17 | @Override 18 | public ActivityOutput execute(ActivityInput input) { 19 | return next.execute(input); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/common/interceptors/Header.java: -------------------------------------------------------------------------------- 1 | package io.temporal.common.interceptors; 2 | 3 | import io.temporal.api.common.v1.Payload; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | import javax.annotation.Nonnull; 7 | 8 | public class Header { 9 | private final Map values; 10 | 11 | public Header(@Nonnull io.temporal.api.common.v1.Header header) { 12 | values = header.getFieldsMap(); 13 | } 14 | 15 | public static Header empty() { 16 | return new Header(new HashMap<>()); 17 | } 18 | 19 | public Header(Map values) { 20 | this.values = values; 21 | } 22 | 23 | public Map getValues() { 24 | return values; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/common/interceptors/NexusOperationOutboundCallsInterceptorBase.java: -------------------------------------------------------------------------------- 1 | package io.temporal.common.interceptors; 2 | 3 | import com.uber.m3.tally.Scope; 4 | import io.temporal.client.WorkflowClient; 5 | import io.temporal.common.Experimental; 6 | 7 | /** Convenience base class for {@link NexusOperationOutboundCallsInterceptor} implementations. */ 8 | @Experimental 9 | public class NexusOperationOutboundCallsInterceptorBase 10 | implements NexusOperationOutboundCallsInterceptor { 11 | private final NexusOperationOutboundCallsInterceptor next; 12 | 13 | public NexusOperationOutboundCallsInterceptorBase(NexusOperationOutboundCallsInterceptor next) { 14 | this.next = next; 15 | } 16 | 17 | @Override 18 | public Scope getMetricsScope() { 19 | return next.getMetricsScope(); 20 | } 21 | 22 | @Override 23 | public WorkflowClient getWorkflowClient() { 24 | return next.getWorkflowClient(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/common/interceptors/ScheduleClientInterceptor.java: -------------------------------------------------------------------------------- 1 | package io.temporal.common.interceptors; 2 | 3 | import io.temporal.client.schedules.ScheduleClient; 4 | import io.temporal.client.schedules.ScheduleHandle; 5 | import io.temporal.common.Experimental; 6 | 7 | /** 8 | * Intercepts calls to the {@link ScheduleClient} and {@link ScheduleHandle} related to the 9 | * lifecycle of a Schedule. 10 | */ 11 | @Experimental 12 | public interface ScheduleClientInterceptor { 13 | 14 | /** 15 | * Called once during creation of ScheduleClient to create a chain of ScheduleClient Interceptors 16 | * 17 | * @param next next schedule client interceptor in the chain of interceptors 18 | * @return new interceptor that should decorate calls to {@code next} 19 | */ 20 | ScheduleClientCallsInterceptor scheduleClientCallsInterceptor( 21 | ScheduleClientCallsInterceptor next); 22 | } 23 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/common/interceptors/ScheduleClientInterceptorBase.java: -------------------------------------------------------------------------------- 1 | package io.temporal.common.interceptors; 2 | 3 | import io.temporal.common.Experimental; 4 | 5 | /** Convenience base class for ScheduleClientInterceptor implementations. */ 6 | @Experimental 7 | public class ScheduleClientInterceptorBase implements ScheduleClientInterceptor { 8 | 9 | @Override 10 | public ScheduleClientCallsInterceptor scheduleClientCallsInterceptor( 11 | ScheduleClientCallsInterceptor next) { 12 | return next; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/common/interceptors/WorkerInterceptorBase.java: -------------------------------------------------------------------------------- 1 | package io.temporal.common.interceptors; 2 | 3 | import io.nexusrpc.handler.OperationContext; 4 | 5 | public class WorkerInterceptorBase implements WorkerInterceptor { 6 | @Override 7 | public WorkflowInboundCallsInterceptor interceptWorkflow(WorkflowInboundCallsInterceptor next) { 8 | return next; 9 | } 10 | 11 | @Override 12 | public ActivityInboundCallsInterceptor interceptActivity(ActivityInboundCallsInterceptor next) { 13 | return next; 14 | } 15 | 16 | @Override 17 | public NexusOperationInboundCallsInterceptor interceptNexusOperation( 18 | OperationContext context, NexusOperationInboundCallsInterceptor next) { 19 | return next; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/common/metadata/WorkflowMethodType.java: -------------------------------------------------------------------------------- 1 | package io.temporal.common.metadata; 2 | 3 | public enum WorkflowMethodType { 4 | NONE, 5 | WORKFLOW, 6 | SIGNAL, 7 | QUERY, 8 | UPDATE, 9 | UPDATE_VALIDATOR 10 | } 11 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/failure/ApplicationErrorCategory.java: -------------------------------------------------------------------------------- 1 | package io.temporal.failure; 2 | 3 | /** 4 | * Used to categorize application failures, for example, to distinguish benign errors from others. 5 | * 6 | * @see io.temporal.api.enums.v1.ApplicationErrorCategory 7 | */ 8 | public enum ApplicationErrorCategory { 9 | UNSPECIFIED, 10 | /** Expected application error with little/no severity. */ 11 | BENIGN, 12 | } 13 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/failure/ServerFailure.java: -------------------------------------------------------------------------------- 1 | package io.temporal.failure; 2 | 3 | import javax.annotation.Nullable; 4 | 5 | /** 6 | * Exceptions originated at the Temporal service. 7 | * 8 | *

This exception is expected to be thrown only by the Temporal framework code. 9 | */ 10 | public final class ServerFailure extends TemporalFailure { 11 | private final boolean nonRetryable; 12 | 13 | public ServerFailure(String message, boolean nonRetryable) { 14 | this(message, nonRetryable, null); 15 | } 16 | 17 | public ServerFailure(String message, boolean nonRetryable, @Nullable Throwable cause) { 18 | super(message, message, cause); 19 | this.nonRetryable = nonRetryable; 20 | } 21 | 22 | public boolean isNonRetryable() { 23 | return nonRetryable; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/failure/TemporalException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.failure; 2 | 3 | /** 4 | * Base class for all exceptions thrown by Temporal SDK. 5 | * 6 | *

Do not extend by the application code. 7 | */ 8 | public class TemporalException extends RuntimeException { 9 | protected TemporalException(String message, Throwable cause) { 10 | super(message, cause, false, true); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/failure/TerminatedFailure.java: -------------------------------------------------------------------------------- 1 | package io.temporal.failure; 2 | 3 | /** This exception is expected to be thrown only by the Temporal framework code. */ 4 | public final class TerminatedFailure extends TemporalFailure { 5 | 6 | public TerminatedFailure(String message, Throwable cause) { 7 | super(message, message, cause); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/AGENTS.md: -------------------------------------------------------------------------------- 1 | All files in this directory and subdirectory are intended to be internal to the SDK and should not be used by external users. They do not have the same backwards compatibility guarantees as our other APIS -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/Config.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal; 2 | 3 | public final class Config { 4 | private Config() {} 5 | 6 | /** Force new workflow task after workflow task timeout multiplied by this coefficient. */ 7 | public static final double WORKFLOW_TASK_HEARTBEAT_COEFFICIENT = 4d / 5d; 8 | 9 | /** 10 | * Limit how many eager activities can be requested by the SDK in one workflow task completion 11 | * response. 12 | */ 13 | public static int EAGER_ACTIVITIES_LIMIT = 3; 14 | } 15 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/activity/ActivityExecutionContextFactory.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.activity; 2 | 3 | import com.uber.m3.tally.Scope; 4 | 5 | public interface ActivityExecutionContextFactory { 6 | InternalActivityExecutionContext createContext( 7 | ActivityInfoInternal info, Object activity, Scope metricsScope); 8 | } 9 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/activity/ActivityInfoInternal.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.activity; 2 | 3 | import io.temporal.activity.ActivityInfo; 4 | import io.temporal.api.common.v1.Header; 5 | import io.temporal.api.common.v1.Payloads; 6 | import io.temporal.workflow.Functions; 7 | import java.util.Optional; 8 | 9 | /** 10 | * An extension for {@link ActivityInfo} with information about the activity task that the current 11 | * activity is handling that should be available for Temporal SDK, but shouldn't be available or 12 | * exposed to Activity implementation code. 13 | */ 14 | interface ActivityInfoInternal extends ActivityInfo { 15 | /** 16 | * @return function shat should be triggered after activity completion with any outcome (success, 17 | * failure, cancelling) 18 | */ 19 | Functions.Proc getCompletionHandle(); 20 | 21 | /** 22 | * @return input parameters of the activity execution 23 | */ 24 | Optional getInput(); 25 | 26 | /** 27 | * @return header that is passed with the activity execution 28 | */ 29 | Optional

getHeader(); 30 | } 31 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/activity/ActivityInternal.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.activity; 2 | 3 | import io.temporal.activity.ActivityExecutionContext; 4 | 5 | public final class ActivityInternal { 6 | 7 | private ActivityInternal() {} 8 | 9 | public static ActivityExecutionContext getExecutionContext() { 10 | return CurrentActivityExecutionContext.get(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/activity/ActivityPollResponseToInfo.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.activity; 2 | 3 | import io.temporal.activity.ActivityInfo; 4 | import io.temporal.api.workflowservice.v1.PollActivityTaskQueueResponseOrBuilder; 5 | 6 | public class ActivityPollResponseToInfo { 7 | public static ActivityInfo toActivityInfoImpl( 8 | PollActivityTaskQueueResponseOrBuilder response, 9 | String namespace, 10 | String activityTaskQueue, 11 | boolean local) { 12 | return new ActivityInfoImpl(response, namespace, activityTaskQueue, local, null); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/activity/HeartbeatContext.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.activity; 2 | 3 | import io.temporal.client.ActivityCompletionException; 4 | import java.lang.reflect.Type; 5 | import java.util.Optional; 6 | 7 | interface HeartbeatContext { 8 | 9 | /** 10 | * @see io.temporal.activity.ActivityExecutionContext#heartbeat(Object) 11 | */ 12 | void heartbeat(V details) throws ActivityCompletionException; 13 | 14 | /** 15 | * @see io.temporal.activity.ActivityExecutionContext#getHeartbeatDetails(Class, Type) 16 | */ 17 | Optional getHeartbeatDetails(Class detailsClass, Type detailsGenericType); 18 | 19 | /** 20 | * @see io.temporal.activity.ActivityExecutionContext#getLastHeartbeatDetails(Class) 21 | */ 22 | Optional getLastHeartbeatDetails(Class detailsClass, Type detailsGenericType); 23 | 24 | Object getLatestHeartbeatDetails(); 25 | 26 | /** Cancel any pending heartbeat and discard cached heartbeat details. */ 27 | void cancelOutstandingHeartbeat(); 28 | } 29 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/activity/InternalActivityExecutionContext.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.activity; 2 | 3 | import io.temporal.activity.ActivityExecutionContext; 4 | 5 | /** 6 | * Internal context object passed to an Activity implementation, providing more internal details 7 | * than the user facing {@link ActivityExecutionContext}. 8 | */ 9 | public interface InternalActivityExecutionContext extends ActivityExecutionContext { 10 | /** Get the latest value of {@link ActivityExecutionContext#heartbeat(Object)}. */ 11 | Object getLastHeartbeatValue(); 12 | 13 | /** Cancel any pending heartbeat and discard cached heartbeat details. */ 14 | void cancelOutstandingHeartbeat(); 15 | } 16 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/activity/LocalActivityExecutionContextFactoryImpl.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.activity; 2 | 3 | import com.uber.m3.tally.Scope; 4 | import io.temporal.client.WorkflowClient; 5 | 6 | public class LocalActivityExecutionContextFactoryImpl implements ActivityExecutionContextFactory { 7 | private final WorkflowClient client; 8 | 9 | public LocalActivityExecutionContextFactoryImpl(WorkflowClient client) { 10 | this.client = client; 11 | } 12 | 13 | @Override 14 | public InternalActivityExecutionContext createContext( 15 | ActivityInfoInternal info, Object activity, Scope metricsScope) { 16 | return new LocalActivityExecutionContextImpl(client, activity, info, metricsScope); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/client/WorkerFactoryRegistry.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.client; 2 | 3 | import io.temporal.worker.WorkerFactory; 4 | import java.util.ArrayList; 5 | import java.util.Collections; 6 | import java.util.concurrent.CopyOnWriteArrayList; 7 | 8 | public class WorkerFactoryRegistry { 9 | private final CopyOnWriteArrayList workerFactories = new CopyOnWriteArrayList<>(); 10 | 11 | public Iterable workerFactoriesRandomOrder() { 12 | int count = workerFactories.size(); 13 | if (count > 1) { 14 | ArrayList result = new ArrayList<>(workerFactories); 15 | Collections.shuffle(result); 16 | return result; 17 | } else { 18 | return workerFactories; 19 | } 20 | } 21 | 22 | public void register(WorkerFactory workerFactory) { 23 | workerFactories.addIfAbsent(workerFactory); 24 | } 25 | 26 | public void deregister(WorkerFactory workerFactory) { 27 | workerFactories.remove(workerFactory); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/client/external/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package contains implementation of "external" client code that can be used outside of any 3 | * Temporal context, like Workflow or Activity 4 | */ 5 | package io.temporal.internal.client.external; 6 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/common/ActivityOptionUtils.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.common; 2 | 3 | import io.temporal.activity.ActivityOptions; 4 | import io.temporal.activity.LocalActivityOptions; 5 | import java.util.Map; 6 | import javax.annotation.Nonnull; 7 | 8 | public class ActivityOptionUtils { 9 | public static void mergePredefinedActivityOptions( 10 | @Nonnull Map mergeTo, 11 | @Nonnull Map override) { 12 | override.forEach( 13 | (key, value) -> 14 | mergeTo.merge(key, value, (o1, o2) -> o1.toBuilder().mergeActivityOptions(o2).build())); 15 | } 16 | 17 | public static void mergePredefinedLocalActivityOptions( 18 | @Nonnull Map mergeTo, 19 | @Nonnull Map override) { 20 | override.forEach( 21 | (key, value) -> 22 | mergeTo.merge(key, value, (o1, o2) -> o1.toBuilder().mergeActivityOptions(o2).build())); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/common/GrpcUtils.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.common; 2 | 3 | import io.grpc.Status; 4 | import io.grpc.StatusRuntimeException; 5 | 6 | public class GrpcUtils { 7 | /** 8 | * @return true if {@code ex} is a gRPC exception about a channel shutdown 9 | */ 10 | public static boolean isChannelShutdownException(StatusRuntimeException ex) { 11 | String description = ex.getStatus().getDescription(); 12 | return (Status.Code.UNAVAILABLE.equals(ex.getStatus().getCode()) 13 | && description != null 14 | && (description.startsWith("Channel shutdown") 15 | || description.startsWith("Subchannel shutdown"))); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/common/NonIdempotentHandle.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.common; 2 | 3 | /** 4 | * This interface signifies that the implementation of {@link #close()} method may and likely is not 5 | * idempotent, which is in agreement with {@link AutoCloseable#close()} contract. It also narrows 6 | * {@link AutoCloseable#close()} contract to not throw any checked exceptions, making it more 7 | * convenient to use in try-with-resources blocks. 8 | */ 9 | public interface NonIdempotentHandle extends AutoCloseable { 10 | @Override 11 | void close(); 12 | } 13 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/common/ProtocolType.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.common; 2 | 3 | import java.util.Arrays; 4 | import java.util.Optional; 5 | 6 | public enum ProtocolType { 7 | UPDATE_V1("temporal.api.update.v1"); 8 | 9 | private String type; 10 | 11 | ProtocolType(String type) { 12 | this.type = type; 13 | } 14 | 15 | public String getType() { 16 | return type; 17 | } 18 | 19 | public static Optional get(String type) { 20 | return Arrays.stream(ProtocolType.values()) 21 | .filter(proto -> proto.type.equals(type)) 22 | .findFirst(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/common/ProtocolUtils.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.common; 2 | 3 | import io.temporal.api.protocol.v1.Message; 4 | 5 | public class ProtocolUtils { 6 | public static String getProtocol(Message message) { 7 | String typeUrl = message.getBody().getTypeUrl(); 8 | int slashIndex = typeUrl.lastIndexOf("/"); 9 | if (slashIndex == -1) { 10 | throw new IllegalArgumentException("Message body type URL invalid"); 11 | } 12 | String typeName = typeUrl.substring(slashIndex + 1, typeUrl.length()); 13 | String protocolName = typeName; 14 | int dotIndex = typeName.lastIndexOf("."); 15 | if (dotIndex != -1) { 16 | protocolName = protocolName.substring(0, dotIndex); 17 | } 18 | return protocolName; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/common/ShadingHelpers.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.common; 2 | 3 | import io.temporal.serviceclient.ServiceStubsOptions; 4 | import io.temporal.serviceclient.SimpleSslContextBuilder; 5 | import javax.net.ssl.SSLException; 6 | 7 | /** 8 | * This class provides shading-safe utils that don't return classes that we relocate during shading 9 | * to the caller. These tools help modules like spring boot stay not shaded and still be compatible 10 | * with our shaded artifact 11 | */ 12 | public final class ShadingHelpers { 13 | private ShadingHelpers() {} 14 | 15 | public static void buildSslContextAndPublishIntoStubOptions( 16 | SimpleSslContextBuilder sslContextBuilder, ServiceStubsOptions.Builder optionsBuilder) 17 | throws SSLException { 18 | optionsBuilder.setSslContext(sslContextBuilder.build()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/common/ThrowableFunc1.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.common; 2 | 3 | public interface ThrowableFunc1 { 4 | R apply(T t) throws E; 5 | } 6 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/common/UpdateMessage.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.common; 2 | 3 | import io.temporal.api.protocol.v1.Message; 4 | import io.temporal.internal.statemachines.UpdateProtocolCallback; 5 | 6 | public class UpdateMessage { 7 | private final Message message; 8 | private final UpdateProtocolCallback callbacks; 9 | 10 | public UpdateMessage(Message message, UpdateProtocolCallback callbacks) { 11 | this.message = message; 12 | this.callbacks = callbacks; 13 | } 14 | 15 | public Message getMessage() { 16 | return message; 17 | } 18 | 19 | public UpdateProtocolCallback getCallbacks() { 20 | return this.callbacks; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/common/env/DebugModeUtils.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.common.env; 2 | 3 | import com.google.common.annotations.VisibleForTesting; 4 | import io.temporal.conf.EnvironmentVariableNames; 5 | 6 | public final class DebugModeUtils { 7 | private static boolean TEMPORAL_DEBUG_MODE = 8 | EnvironmentVariableUtils.readBooleanFlag(EnvironmentVariableNames.TEMPORAL_DEBUG); 9 | 10 | private DebugModeUtils() {} 11 | 12 | public static boolean isTemporalDebugModeOn() { 13 | return TEMPORAL_DEBUG_MODE; 14 | } 15 | 16 | @VisibleForTesting 17 | public static void override(boolean debugMode) { 18 | TEMPORAL_DEBUG_MODE = debugMode; 19 | } 20 | 21 | @VisibleForTesting 22 | public static void reset() { 23 | TEMPORAL_DEBUG_MODE = 24 | EnvironmentVariableUtils.readBooleanFlag(EnvironmentVariableNames.TEMPORAL_DEBUG); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/common/env/EnvironmentVariableUtils.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.common.env; 2 | 3 | import javax.annotation.Nullable; 4 | 5 | public final class EnvironmentVariableUtils { 6 | private EnvironmentVariableUtils() {} 7 | 8 | /** 9 | * @return false if the environment variable is not set, "false" or "0". Otherwise, returns true. 10 | */ 11 | public static boolean readBooleanFlag(String variableName) { 12 | String variableValue = SystemEnvironmentVariablesProvider.INSTANCE.getenv(variableName); 13 | if (variableValue == null) { 14 | return false; 15 | } 16 | variableValue = variableValue.trim(); 17 | return (!Boolean.FALSE.toString().equalsIgnoreCase(variableValue) 18 | && !"0".equals(variableValue)); 19 | } 20 | 21 | @Nullable 22 | public static String readString(String variableName) { 23 | return SystemEnvironmentVariablesProvider.INSTANCE.getenv(variableName); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/common/env/EnvironmentVariablesProvider.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.common.env; 2 | 3 | /** 4 | * Same contract as {@link System#getenv(String)} This class exists only to allow overriding 5 | * environment variables for tests 6 | */ 7 | interface EnvironmentVariablesProvider { 8 | String getenv(String name); 9 | } 10 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/common/env/SystemEnvironmentVariablesProvider.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.common.env; 2 | 3 | class SystemEnvironmentVariablesProvider implements EnvironmentVariablesProvider { 4 | public static final EnvironmentVariablesProvider INSTANCE = 5 | new SystemEnvironmentVariablesProvider(); 6 | 7 | @Override 8 | public String getenv(String name) { 9 | return System.getenv(name); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/nexus/NexusInternal.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.nexus; 2 | 3 | import io.temporal.nexus.NexusOperationContext; 4 | 5 | public final class NexusInternal { 6 | private NexusInternal() {} 7 | 8 | public static NexusOperationContext getOperationContext() { 9 | return CurrentNexusOperationContext.get().getUserFacingContext(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/nexus/OperationTokenType.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.nexus; 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator; 4 | import com.fasterxml.jackson.annotation.JsonValue; 5 | 6 | public enum OperationTokenType { 7 | UNKNOWN(0), 8 | WORKFLOW_RUN(1); 9 | 10 | private final int value; 11 | 12 | OperationTokenType(int i) { 13 | this.value = i; 14 | } 15 | 16 | @JsonValue 17 | public int toValue() { 18 | return value; 19 | } 20 | 21 | @JsonCreator 22 | public static OperationTokenType fromValue(Integer value) { 23 | if (value == null) { 24 | return UNKNOWN; 25 | } 26 | for (OperationTokenType b : OperationTokenType.values()) { 27 | if (b.value == value) { 28 | return b; 29 | } 30 | } 31 | return UNKNOWN; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/nexus/RootNexusOperationOutboundCallsInterceptor.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.nexus; 2 | 3 | import com.uber.m3.tally.Scope; 4 | import io.temporal.client.WorkflowClient; 5 | import io.temporal.common.interceptors.NexusOperationOutboundCallsInterceptor; 6 | 7 | public class RootNexusOperationOutboundCallsInterceptor 8 | implements NexusOperationOutboundCallsInterceptor { 9 | private final Scope scope; 10 | private final WorkflowClient client; 11 | 12 | RootNexusOperationOutboundCallsInterceptor(Scope scope, WorkflowClient client) { 13 | this.scope = scope; 14 | this.client = client; 15 | } 16 | 17 | @Override 18 | public Scope getMetricsScope() { 19 | return scope; 20 | } 21 | 22 | @Override 23 | public WorkflowClient getWorkflowClient() { 24 | return client; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package and its subpackages contain implementation classes of the Temporal SDK. 3 | * 4 | *

Do not use them directly in any application code! There is absolutely no 5 | * guarantee about backwards compatibility of APIs in the internal packages. 6 | */ 7 | package io.temporal.internal; 8 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/replay/QueryResult.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.replay; 2 | 3 | import io.temporal.api.common.v1.Payloads; 4 | import java.util.Optional; 5 | 6 | public class QueryResult { 7 | private final Optional responsePayloads; 8 | private final boolean workflowMethodCompleted; 9 | 10 | public QueryResult(Optional responsePayloads, boolean workflowMethodCompleted) { 11 | this.responsePayloads = responsePayloads; 12 | this.workflowMethodCompleted = workflowMethodCompleted; 13 | } 14 | 15 | public Optional getResponsePayloads() { 16 | return responsePayloads; 17 | } 18 | 19 | public boolean isWorkflowMethodCompleted() { 20 | return workflowMethodCompleted; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/replay/ReplayAware.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.replay; 2 | 3 | public interface ReplayAware { 4 | /** 5 | * true indicates if workflow is replaying already processed events to reconstruct it 6 | * state. false indicates that code is making forward process for the first time. For 7 | * example can be used to avoid duplicating log records due to replay. 8 | */ 9 | boolean isReplaying(); 10 | } 11 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/replay/ReplayWorkflowFactory.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.replay; 2 | 3 | import io.temporal.api.common.v1.WorkflowExecution; 4 | import io.temporal.api.common.v1.WorkflowType; 5 | 6 | public interface ReplayWorkflowFactory { 7 | ReplayWorkflow getWorkflow(WorkflowType workflowType, WorkflowExecution workflowExecution) 8 | throws Exception; 9 | 10 | boolean isAnyTypeSupported(); 11 | } 12 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/replay/WorkflowHistoryIterator.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.replay; 2 | 3 | import io.grpc.Deadline; 4 | import io.temporal.api.history.v1.HistoryEvent; 5 | import java.util.Iterator; 6 | 7 | public interface WorkflowHistoryIterator extends Iterator { 8 | void initDeadline(Deadline deadline); 9 | } 10 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/statemachines/CancelWorkflowStateMachine.puml: -------------------------------------------------------------------------------- 1 | ` PlantUML State Diagram. 2 | ` Generated from src/main/java/io/temporal/internal/statemachines/CancelWorkflowStateMachine.java 3 | ` by io.temporal.internal.statemachines.CommandsGeneratePlantUMLStateDiagrams. 4 | 5 | 6 | @startuml 7 | title CancelWorkflow State Transitions 8 | 9 | [*] --> CREATED 10 | CANCEL_WORKFLOW_COMMAND_CREATED --> CANCEL_WORKFLOW_COMMAND_CREATED: CANCEL_WORKFLOW_EXECUTION 11 | CANCEL_WORKFLOW_COMMAND_CREATED --> CANCEL_WORKFLOW_COMMAND_RECORDED: WORKFLOW_EXECUTION_CANCELED 12 | CREATED --> CANCEL_WORKFLOW_COMMAND_CREATED: SCHEDULE 13 | CANCEL_WORKFLOW_COMMAND_RECORDED --> [*] 14 | center footer Copyright (C) 2020 Temporal Technologies, Inc. All Rights Reserved. 15 | @enduml 16 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/statemachines/CompleteWorkflowStateMachine.puml: -------------------------------------------------------------------------------- 1 | ` PlantUML State Diagram. 2 | ` Generated from src/main/java/io/temporal/internal/statemachines/CompleteWorkflowStateMachine.java 3 | ` by io.temporal.internal.statemachines.CommandsGeneratePlantUMLStateDiagrams. 4 | 5 | 6 | @startuml 7 | title CompleteWorkflow State Transitions 8 | 9 | [*] --> CREATED 10 | COMPLETE_WORKFLOW_COMMAND_CREATED --> COMPLETE_WORKFLOW_COMMAND_CREATED: COMPLETE_WORKFLOW_EXECUTION 11 | COMPLETE_WORKFLOW_COMMAND_CREATED --> COMPLETE_WORKFLOW_COMMAND_RECORDED: WORKFLOW_EXECUTION_COMPLETED 12 | CREATED --> COMPLETE_WORKFLOW_COMMAND_CREATED: SCHEDULE 13 | COMPLETE_WORKFLOW_COMMAND_RECORDED --> [*] 14 | center footer Copyright (C) 2020 Temporal Technologies, Inc. All Rights Reserved. 15 | @enduml 16 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/statemachines/ContinueAsNewWorkflowStateMachine.puml: -------------------------------------------------------------------------------- 1 | ` PlantUML State Diagram. 2 | ` Generated from src/main/java/io/temporal/internal/statemachines/ContinueAsNewWorkflowStateMachine.java 3 | ` by io.temporal.internal.statemachines.CommandsGeneratePlantUMLStateDiagrams. 4 | 5 | 6 | @startuml 7 | title ContinueAsNewWorkflow State Transitions 8 | 9 | [*] --> CREATED 10 | CONTINUE_AS_NEW_WORKFLOW_COMMAND_CREATED --> CONTINUE_AS_NEW_WORKFLOW_COMMAND_CREATED: CONTINUE_AS_NEW_WORKFLOW_EXECUTION 11 | CONTINUE_AS_NEW_WORKFLOW_COMMAND_CREATED --> CONTINUE_AS_NEW_WORKFLOW_COMMAND_RECORDED: WORKFLOW_EXECUTION_CONTINUED_AS_NEW 12 | CREATED --> CONTINUE_AS_NEW_WORKFLOW_COMMAND_CREATED: SCHEDULE 13 | CONTINUE_AS_NEW_WORKFLOW_COMMAND_RECORDED --> [*] 14 | center footer Copyright (C) 2020 Temporal Technologies, Inc. All Rights Reserved. 15 | @enduml 16 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/statemachines/DynamicCallback.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.statemachines; 2 | 3 | /** 4 | * Function invoked when an explicitEvent happens in a given state. Returns the next state. Used 5 | * when the next state depends not only on the current state and explicitEvent, but also on the 6 | * data. 7 | */ 8 | @FunctionalInterface 9 | interface DynamicCallback { 10 | 11 | /** 12 | * @return state after the explicitEvent 13 | */ 14 | State apply(Data data); 15 | } 16 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/statemachines/EntityStateMachine.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.statemachines; 2 | 3 | import io.temporal.api.enums.v1.CommandType; 4 | import io.temporal.api.history.v1.HistoryEvent; 5 | import io.temporal.api.protocol.v1.Message; 6 | 7 | interface EntityStateMachine { 8 | 9 | void handleCommand(CommandType commandType); 10 | 11 | void handleMessage(Message message); 12 | 13 | WorkflowStateMachines.HandleEventStatus handleEvent(HistoryEvent event, boolean hasNextEvent); 14 | 15 | void handleWorkflowTaskStarted(); 16 | 17 | boolean isFinalState(); 18 | } 19 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/statemachines/FailWorkflowStateMachine.puml: -------------------------------------------------------------------------------- 1 | ` PlantUML State Diagram. 2 | ` Generated from src/main/java/io/temporal/internal/statemachines/FailWorkflowStateMachine.java 3 | ` by io.temporal.internal.statemachines.CommandsGeneratePlantUMLStateDiagrams. 4 | 5 | 6 | @startuml 7 | title FailWorkflow State Transitions 8 | 9 | [*] --> CREATED 10 | CREATED --> FAIL_WORKFLOW_COMMAND_CREATED: SCHEDULE 11 | FAIL_WORKFLOW_COMMAND_CREATED --> FAIL_WORKFLOW_COMMAND_CREATED: FAIL_WORKFLOW_EXECUTION 12 | FAIL_WORKFLOW_COMMAND_CREATED --> FAIL_WORKFLOW_COMMAND_RECORDED: WORKFLOW_EXECUTION_FAILED 13 | FAIL_WORKFLOW_COMMAND_RECORDED --> [*] 14 | center footer Copyright (C) 2020 Temporal Technologies, Inc. All Rights Reserved. 15 | @enduml 16 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/statemachines/FixedTransitionAction.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.statemachines; 2 | 3 | import io.temporal.workflow.Functions; 4 | import java.util.Collections; 5 | import java.util.List; 6 | 7 | /** Action that can transition to exactly one state. */ 8 | class FixedTransitionAction implements TransitionAction { 9 | 10 | final State state; 11 | 12 | final Functions.Proc1 action; 13 | 14 | FixedTransitionAction(State state, Functions.Proc1 action) { 15 | this.state = state; 16 | this.action = action; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return "FixedTransitionAction{" + "toState=" + state + "}"; 22 | } 23 | 24 | @Override 25 | public State apply(Data data) { 26 | action.apply(data); 27 | return state; 28 | } 29 | 30 | @Override 31 | public List getAllowedStates() { 32 | return Collections.singletonList(state); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/statemachines/InternalWorkflowTaskException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.statemachines; 2 | 3 | /** 4 | * Originated by Temporal State Machines and happens during application of the events inside 5 | * #handleEvent call. 6 | */ 7 | final class InternalWorkflowTaskException extends RuntimeException { 8 | 9 | public InternalWorkflowTaskException(String message, Throwable cause) { 10 | super(message, cause); 11 | } 12 | 13 | public InternalWorkflowTaskException(Throwable cause) { 14 | super(cause); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/statemachines/SideEffectStateMachine.puml: -------------------------------------------------------------------------------- 1 | ` PlantUML State Diagram. 2 | ` Generated from src/main/java/io/temporal/internal/statemachines/SideEffectStateMachine.java 3 | ` by io.temporal.internal.statemachines.CommandsGeneratePlantUMLStateDiagrams. 4 | 5 | 6 | @startuml 7 | title SideEffect State Transitions 8 | 9 | [*] --> CREATED 10 | CREATED --> MARKER_COMMAND_CREATED: SCHEDULE 11 | CREATED --> MARKER_COMMAND_CREATED_REPLAYING: SCHEDULE 12 | MARKER_COMMAND_CREATED --> RESULT_NOTIFIED: RECORD_MARKER 13 | MARKER_COMMAND_CREATED_REPLAYING --> RESULT_NOTIFIED_REPLAYING: RECORD_MARKER 14 | RESULT_NOTIFIED --> MARKER_COMMAND_RECORDED: MARKER_RECORDED 15 | RESULT_NOTIFIED_REPLAYING --> MARKER_COMMAND_RECORDED: MARKER_RECORDED 16 | MARKER_COMMAND_RECORDED --> [*] 17 | center footer Copyright (C) 2020 Temporal Technologies, Inc. All Rights Reserved. 18 | @enduml 19 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/statemachines/StateMachineCommandUtils.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.statemachines; 2 | 3 | import io.temporal.api.command.v1.Command; 4 | import io.temporal.api.command.v1.RecordMarkerCommandAttributes; 5 | import io.temporal.api.enums.v1.CommandType; 6 | 7 | class StateMachineCommandUtils { 8 | public static final Command RECORD_MARKER_FAKE_COMMAND = 9 | createRecordMarker(RecordMarkerCommandAttributes.getDefaultInstance()); 10 | 11 | public static Command createRecordMarker(RecordMarkerCommandAttributes attributes) { 12 | return Command.newBuilder() 13 | .setCommandType(CommandType.COMMAND_TYPE_RECORD_MARKER) 14 | .setRecordMarkerCommandAttributes(attributes) 15 | .build(); 16 | } 17 | 18 | public static Command createFakeMarkerCommand(String markerName) { 19 | return createRecordMarker( 20 | RecordMarkerCommandAttributes.newBuilder().setMarkerName(markerName).build()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/statemachines/StatesMachinesCallback.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.statemachines; 2 | 3 | import io.temporal.api.history.v1.HistoryEvent; 4 | import io.temporal.internal.common.UpdateMessage; 5 | 6 | public interface StatesMachinesCallback { 7 | 8 | void start(HistoryEvent startWorkflowEvent); 9 | 10 | void signal(HistoryEvent signalEvent); 11 | 12 | void update(UpdateMessage message); 13 | 14 | void cancel(HistoryEvent cancelEvent); 15 | 16 | void eventLoop(); 17 | } 18 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/statemachines/TimerStateMachine.puml: -------------------------------------------------------------------------------- 1 | ` PlantUML State Diagram. 2 | ` Generated from src/main/java/io/temporal/internal/statemachines/TimerStateMachine.java 3 | ` by io.temporal.internal.statemachines.CommandsGeneratePlantUMLStateDiagrams. 4 | 5 | 6 | @startuml 7 | title Timer State Transitions 8 | 9 | [*] --> CREATED 10 | CANCEL_TIMER_COMMAND_CREATED --> CANCEL_TIMER_COMMAND_CREATED: CANCEL 11 | CANCEL_TIMER_COMMAND_CREATED --> CANCEL_TIMER_COMMAND_SENT: CANCEL_TIMER 12 | CANCEL_TIMER_COMMAND_SENT --> CANCELED: TIMER_CANCELED 13 | CREATED --> START_COMMAND_CREATED: SCHEDULE 14 | START_COMMAND_CREATED --> START_COMMAND_CREATED: START_TIMER 15 | START_COMMAND_CREATED --> START_COMMAND_RECORDED: TIMER_STARTED 16 | START_COMMAND_CREATED --> CANCELED: CANCEL 17 | START_COMMAND_RECORDED --> FIRED: TIMER_FIRED 18 | START_COMMAND_RECORDED --> CANCEL_TIMER_COMMAND_CREATED: CANCEL 19 | FIRED --> [*] 20 | CANCELED --> [*] 21 | center footer Copyright (C) 2020 Temporal Technologies, Inc. All Rights Reserved. 22 | @enduml 23 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/statemachines/TransitionAction.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.statemachines; 2 | 3 | import java.util.List; 4 | 5 | /** When an event happens it causes a transition. This class represents the transition action. */ 6 | interface TransitionAction { 7 | 8 | /** 9 | * Executes action returning the new state the state machine should transition to. 10 | * 11 | * @param data data that action applies to 12 | */ 13 | State apply(Data data); 14 | 15 | /** List of states the apply operation can return. */ 16 | List getAllowedStates(); 17 | } 18 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/statemachines/UnsupportedContinueAsNewRequest.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.statemachines; 2 | 3 | /** 4 | * Thrown when {@link io.temporal.workflow.Workflow#continueAsNew} is called from an unsupported 5 | * location. 6 | * 7 | *

The reason this class extends Error is for application workflow code to not catch it by 8 | * mistake. The default behavior of the SDK is to block workflow execution while Error is thrown. 9 | */ 10 | public class UnsupportedContinueAsNewRequest extends Error { 11 | public UnsupportedContinueAsNewRequest(String message) { 12 | super(message); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/statemachines/UnsupportedVersion.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.statemachines; 2 | 3 | /** 4 | * Thrown when {@link io.temporal.workflow.Workflow#getVersion(String, int, int)} detects that the 5 | * workflow history was generated by a code that doesn't comply with specified min and max versions. 6 | * 7 | *

The reason this class extends Error is for application workflow code to not catch it by 8 | * mistake. The default behavior of the SDK is to block workflow execution while Error is thrown. 9 | */ 10 | public class UnsupportedVersion extends Error { 11 | public UnsupportedVersion(String message) { 12 | super(message); 13 | } 14 | 15 | public UnsupportedVersion(UnsupportedVersionException e) { 16 | super(e.getMessage(), e); 17 | } 18 | 19 | public static class UnsupportedVersionException extends RuntimeException { 20 | public UnsupportedVersionException(String message) { 21 | super(message); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/statemachines/UpdateProtocolCallback.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.statemachines; 2 | 3 | import io.temporal.api.common.v1.Payloads; 4 | import io.temporal.api.failure.v1.Failure; 5 | import java.util.Optional; 6 | 7 | public interface UpdateProtocolCallback { 8 | void accept(); 9 | 10 | void reject(Failure failure); 11 | 12 | void complete(Optional result, Failure failure); 13 | 14 | boolean isReplaying(); 15 | } 16 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/statemachines/UpsertSearchAttributesStateMachine.puml: -------------------------------------------------------------------------------- 1 | ` PlantUML State Diagram. 2 | ` Generated from src/main/java/io/temporal/internal/statemachines/UpsertSearchAttributesStateMachine.java 3 | ` by io.temporal.internal.statemachines.CommandsGeneratePlantUMLStateDiagrams. 4 | 5 | 6 | @startuml 7 | title UpsertSearchAttributes State Transitions 8 | 9 | [*] --> CREATED 10 | CREATED --> UPSERT_COMMAND_CREATED: SCHEDULE 11 | UPSERT_COMMAND_CREATED --> UPSERT_COMMAND_CREATED: UPSERT_WORKFLOW_SEARCH_ATTRIBUTES 12 | UPSERT_COMMAND_CREATED --> UPSERT_COMMAND_RECORDED: UPSERT_WORKFLOW_SEARCH_ATTRIBUTES 13 | UPSERT_COMMAND_RECORDED --> [*] 14 | center footer Copyright (C) 2020 Temporal Technologies, Inc. All Rights Reserved. 15 | @enduml 16 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/statemachines/WorkflowTaskStateMachine.puml: -------------------------------------------------------------------------------- 1 | ` PlantUML State Diagram. 2 | ` Generated from src/main/java/io/temporal/internal/statemachines/WorkflowTaskStateMachine.java 3 | ` by io.temporal.internal.statemachines.CommandsGeneratePlantUMLStateDiagrams. 4 | 5 | 6 | @startuml 7 | title WorkflowTask State Transitions 8 | 9 | [*] --> CREATED 10 | CREATED --> SCHEDULED: WORKFLOW_TASK_SCHEDULED 11 | SCHEDULED --> STARTED: WORKFLOW_TASK_STARTED 12 | SCHEDULED --> TIMED_OUT: WORKFLOW_TASK_TIMED_OUT 13 | STARTED --> COMPLETED: WORKFLOW_TASK_COMPLETED 14 | STARTED --> FAILED: WORKFLOW_TASK_FAILED 15 | STARTED --> TIMED_OUT: WORKFLOW_TASK_TIMED_OUT 16 | COMPLETED --> [*] 17 | TIMED_OUT --> [*] 18 | FAILED --> [*] 19 | center footer Copyright (C) 2020 Temporal Technologies, Inc. All Rights Reserved. 20 | @enduml 21 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/sync/DestroyWorkflowThreadError.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.sync; 2 | 3 | /** 4 | * Used to interrupt deterministic thread execution. Assumption is that none of the code that thread 5 | * executes catches it. 6 | */ 7 | public final class DestroyWorkflowThreadError extends Error { 8 | 9 | DestroyWorkflowThreadError() {} 10 | 11 | DestroyWorkflowThreadError(String message) { 12 | super(message); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/sync/NexusOperationExecutionImpl.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.sync; 2 | 3 | import io.temporal.workflow.NexusOperationExecution; 4 | import java.util.Optional; 5 | 6 | public class NexusOperationExecutionImpl implements NexusOperationExecution { 7 | 8 | private final Optional operationToken; 9 | 10 | public NexusOperationExecutionImpl(Optional operationToken) { 11 | this.operationToken = operationToken; 12 | } 13 | 14 | @Override 15 | public Optional getOperationToken() { 16 | return operationToken; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/sync/NexusOperationHandleImpl.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.sync; 2 | 3 | import io.temporal.workflow.NexusOperationExecution; 4 | import io.temporal.workflow.NexusOperationHandle; 5 | import io.temporal.workflow.Promise; 6 | 7 | public class NexusOperationHandleImpl implements NexusOperationHandle { 8 | Promise operationExecution; 9 | Promise result; 10 | 11 | public NexusOperationHandleImpl( 12 | Promise operationExecution, Promise result) { 13 | this.operationExecution = operationExecution; 14 | this.result = result; 15 | } 16 | 17 | @Override 18 | public Promise getExecution() { 19 | return operationExecution; 20 | } 21 | 22 | @Override 23 | public Promise getResult() { 24 | return result; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/sync/ReadOnlyException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.sync; 2 | 3 | /** 4 | * This exception is thrown when a workflow tries to perform an operation that could generate a new 5 | * command while it is in a read only context. 6 | */ 7 | public class ReadOnlyException extends IllegalStateException { 8 | public ReadOnlyException(String action) { 9 | super("While in read-only function, action attempted: " + action); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/sync/SignalHandlerInfo.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.sync; 2 | 3 | import io.temporal.workflow.HandlerUnfinishedPolicy; 4 | 5 | public class SignalHandlerInfo { 6 | private final long eventId; 7 | private final String name; 8 | private final HandlerUnfinishedPolicy policy; 9 | 10 | public SignalHandlerInfo(long eventId, String name, HandlerUnfinishedPolicy policy) { 11 | this.eventId = eventId; 12 | this.name = name; 13 | this.policy = policy; 14 | } 15 | 16 | public String getName() { 17 | return name; 18 | } 19 | 20 | public HandlerUnfinishedPolicy getPolicy() { 21 | return policy; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "SignalHandlerInfo{" 27 | + "eventId=" 28 | + eventId 29 | + ", name='" 30 | + name 31 | + '\'' 32 | + ", policy=" 33 | + policy 34 | + '}'; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/sync/Status.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.sync; 2 | 3 | enum Status { 4 | CREATED, 5 | RUNNING, 6 | YIELDED, 7 | EVALUATING, 8 | DONE 9 | } 10 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/sync/StubMarker.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.sync; 2 | 3 | import io.temporal.api.common.v1.WorkflowExecution; 4 | 5 | /** 6 | * Interface that stub created through {@link 7 | * io.temporal.workflow.Workflow#newChildWorkflowStub(Class)} implements. Do not implement or use 8 | * this interface in any application code. Use {@link 9 | * io.temporal.workflow.Workflow#getWorkflowExecution(Object)} to access {@link WorkflowExecution} 10 | * out of a workflow stub. 11 | */ 12 | public interface StubMarker { 13 | String GET_UNTYPED_STUB_METHOD = "__getUntypedStub"; 14 | 15 | Object __getUntypedStub(); 16 | } 17 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/sync/SyncWorkflowDefinition.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.sync; 2 | 3 | import io.temporal.api.common.v1.Payloads; 4 | import io.temporal.common.VersioningBehavior; 5 | import io.temporal.common.interceptors.Header; 6 | import java.util.Optional; 7 | import javax.annotation.Nullable; 8 | 9 | /** Workflow wrapper used by the workflow thread to start a workflow */ 10 | interface SyncWorkflowDefinition { 11 | 12 | /** Always called first. */ 13 | void initialize(Optional input); 14 | 15 | /** 16 | * Returns the workflow instance that is executing this code. Must be called after {@link 17 | * #initialize(Optional)}. 18 | */ 19 | @Nullable 20 | Object getInstance(); 21 | 22 | Optional execute(Header header, Optional input); 23 | 24 | /** 25 | * @return The versioning behavior for this workflow as defined by the attached annotation, 26 | * otherwise {@link VersioningBehavior#UNSPECIFIED}. 27 | */ 28 | VersioningBehavior getVersioningBehavior(); 29 | } 30 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/sync/UpdateHandlerInfo.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.sync; 2 | 3 | import io.temporal.workflow.HandlerUnfinishedPolicy; 4 | 5 | public class UpdateHandlerInfo { 6 | private String updateId; 7 | private String name; 8 | private HandlerUnfinishedPolicy policy; 9 | 10 | public UpdateHandlerInfo(String updateId, String name, HandlerUnfinishedPolicy policy) { 11 | this.updateId = updateId; 12 | this.name = name; 13 | this.policy = policy; 14 | } 15 | 16 | public String getName() { 17 | return name; 18 | } 19 | 20 | public HandlerUnfinishedPolicy getPolicy() { 21 | return policy; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "UpdateHandlerInfo{" 27 | + "updateId='" 28 | + updateId 29 | + '\'' 30 | + ", name='" 31 | + name 32 | + '\'' 33 | + ", policy=" 34 | + policy 35 | + '}'; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/sync/UpdateInfoImpl.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.sync; 2 | 3 | import io.temporal.workflow.UpdateInfo; 4 | 5 | public final class UpdateInfoImpl implements UpdateInfo { 6 | final String updateName; 7 | final String updateId; 8 | 9 | UpdateInfoImpl(String updateName, String updateId) { 10 | this.updateName = updateName; 11 | this.updateId = updateId; 12 | } 13 | 14 | @Override 15 | public String getUpdateName() { 16 | return updateName; 17 | } 18 | 19 | @Override 20 | public String getUpdateId() { 21 | return updateId; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "UpdateInfoImpl{" 27 | + "updateName='" 28 | + updateName 29 | + '\'' 30 | + ", updateId='" 31 | + updateId 32 | + '\'' 33 | + '}'; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/sync/WorkflowMethodThreadNameStrategy.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.sync; 2 | 3 | import io.temporal.api.common.v1.WorkflowExecution; 4 | import javax.annotation.Nonnull; 5 | 6 | public interface WorkflowMethodThreadNameStrategy { 7 | String WORKFLOW_MAIN_THREAD_PREFIX = "workflow-method"; 8 | 9 | @Nonnull 10 | String createThreadName(@Nonnull WorkflowExecution workflowExecution); 11 | } 12 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/sync/WorkflowRejectedExecutionError.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.sync; 2 | 3 | public class WorkflowRejectedExecutionError extends Error { 4 | 5 | WorkflowRejectedExecutionError(Throwable cause) { 6 | super(cause); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/sync/WorkflowThreadLocalInternal.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.sync; 2 | 3 | import java.util.Optional; 4 | import java.util.function.Supplier; 5 | 6 | public final class WorkflowThreadLocalInternal { 7 | 8 | private final boolean useCaching; 9 | 10 | public WorkflowThreadLocalInternal() { 11 | this(false); 12 | } 13 | 14 | public WorkflowThreadLocalInternal(boolean useCaching) { 15 | this.useCaching = useCaching; 16 | } 17 | 18 | public T get(Supplier supplier) { 19 | Optional> result = 20 | DeterministicRunnerImpl.currentThreadInternal().getThreadLocal(this); 21 | T out = result.orElseGet(() -> Optional.ofNullable(supplier.get())).orElse(null); 22 | if (!result.isPresent() && useCaching) { 23 | // This is the first time we've tried fetching this, and caching is enabled. Store it. 24 | set(out); 25 | } 26 | return out; 27 | } 28 | 29 | public void set(T value) { 30 | DeterministicRunnerImpl.currentThreadInternal().setThreadLocal(this, value); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/task/ThreadConfigurator.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.task; 2 | 3 | /** 4 | * Function interface for {@link VirtualThreadDelegate#newVirtualThreadExecutor(ThreadConfigurator)} 5 | * called for every thread created. 6 | */ 7 | @FunctionalInterface 8 | public interface ThreadConfigurator { 9 | /** Invoked for every thread created by {@link VirtualThreadDelegate#newVirtualThreadExecutor}. */ 10 | void configure(Thread t); 11 | } 12 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/task/VirtualThreadDelegate.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.task; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | 5 | /** 6 | * Internal delegate for virtual thread handling on JDK 21. This is a dummy version for reachability 7 | * on JDK <21. 8 | */ 9 | public final class VirtualThreadDelegate { 10 | public static ExecutorService newVirtualThreadExecutor(ThreadConfigurator configurator) { 11 | throw new UnsupportedOperationException("Virtual threads not supported on JDK <21"); 12 | } 13 | 14 | private VirtualThreadDelegate() {} 15 | } 16 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/worker/BlockCallerPolicy.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.worker; 2 | 3 | import java.util.concurrent.RejectedExecutionException; 4 | import java.util.concurrent.RejectedExecutionHandler; 5 | import java.util.concurrent.ThreadPoolExecutor; 6 | 7 | class BlockCallerPolicy implements RejectedExecutionHandler { 8 | 9 | @Override 10 | public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { 11 | // Without this check the call hangs forever on the queue put. 12 | if (executor.isShutdown()) { 13 | throw new RejectedExecutionException("Executor is shutdown"); 14 | } 15 | try { 16 | // block until there's room 17 | executor.getQueue().put(r); 18 | } catch (InterruptedException e) { 19 | Thread.currentThread().interrupt(); 20 | throw new RejectedExecutionException("Unexpected InterruptedException", e); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/worker/ExecutorThreadFactory.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.worker; 2 | 3 | import java.util.concurrent.ThreadFactory; 4 | import java.util.concurrent.atomic.AtomicInteger; 5 | 6 | class ExecutorThreadFactory implements ThreadFactory { 7 | private final String threadPrefix; 8 | 9 | private final Thread.UncaughtExceptionHandler uncaughtExceptionHandler; 10 | private final AtomicInteger threadIndex = new AtomicInteger(); 11 | 12 | public ExecutorThreadFactory(String threadPrefix, Thread.UncaughtExceptionHandler eh) { 13 | this.threadPrefix = threadPrefix; 14 | this.uncaughtExceptionHandler = eh; 15 | } 16 | 17 | @Override 18 | public Thread newThread(Runnable r) { 19 | Thread result = new Thread(r); 20 | result.setName(threadPrefix + ": " + threadIndex.incrementAndGet()); 21 | result.setUncaughtExceptionHandler(uncaughtExceptionHandler); 22 | return result; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/worker/LocalActivityDispatcher.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.worker; 2 | 3 | import io.grpc.Deadline; 4 | import io.temporal.internal.statemachines.ExecuteLocalActivityParameters; 5 | import io.temporal.workflow.Functions; 6 | import javax.annotation.Nonnull; 7 | import javax.annotation.Nullable; 8 | 9 | public interface LocalActivityDispatcher { 10 | /** 11 | * Synchronously dispatches the local activity to the local activity worker. 12 | * 13 | * @return true if the local activity was accepted, false if it was rejected 14 | * @throws IllegalStateException if the local activity worker was not started 15 | * @throws IllegalArgumentException if the local activity type is not supported 16 | */ 17 | boolean dispatch( 18 | @Nonnull ExecuteLocalActivityParameters params, 19 | @Nonnull Functions.Proc1 resultCallback, 20 | @Nullable Deadline acceptanceDeadline); 21 | } 22 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/worker/ShutdownableTaskExecutor.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.worker; 2 | 3 | public interface ShutdownableTaskExecutor extends TaskExecutor, Shutdownable {} 4 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/worker/SlotReservationData.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.worker; 2 | 3 | public class SlotReservationData { 4 | public final String taskQueue; 5 | public final String workerIdentity; 6 | public final String workerBuildId; 7 | 8 | public SlotReservationData(String taskQueue, String workerIdentity, String workerBuildId) { 9 | this.taskQueue = taskQueue; 10 | this.workerIdentity = workerIdentity; 11 | this.workerBuildId = workerBuildId; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/worker/Startable.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.worker; 2 | 3 | public interface Startable extends WorkerWithLifecycle { 4 | /** 5 | * This method is not required to be idempotent. It is expected to be called only once. 6 | * 7 | * @return true if the start was successful, false if the worker configuration renders the start 8 | * obsolete (like no types are registered) 9 | */ 10 | boolean start(); 11 | } 12 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/worker/Suspendable.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.worker; 2 | 3 | public interface Suspendable extends WorkerWithLifecycle { 4 | 5 | /** 6 | * Do not make new poll requests. Outstanding long polls still can return tasks after this method 7 | * was called. 8 | */ 9 | void suspendPolling(); 10 | 11 | /** Allow new poll requests. */ 12 | void resumePolling(); 13 | 14 | boolean isSuspended(); 15 | } 16 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/worker/SuspendableWorker.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.worker; 2 | 3 | public interface SuspendableWorker extends Suspendable, Startable, Shutdownable {} 4 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/worker/TaskExecutor.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.worker; 2 | 3 | import java.util.concurrent.RejectedExecutionException; 4 | import javax.annotation.Nonnull; 5 | 6 | interface TaskExecutor { 7 | /** 8 | * @param task to be processed 9 | * @throws RejectedExecutionException at discretion of {@code RejectedExecutionHandler}, if the 10 | * task cannot be accepted for execution 11 | * @throws NullPointerException if {@code command} is null 12 | */ 13 | void process(@Nonnull T task); 14 | } 15 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/worker/UnableToAcquireLockException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.worker; 2 | 3 | /** Internal. Do not throw or catch in application level code. */ 4 | public final class UnableToAcquireLockException extends RuntimeException { 5 | 6 | public UnableToAcquireLockException(String message) { 7 | super(message); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/worker/WorkerLifecycleState.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.worker; 2 | 3 | public enum WorkerLifecycleState { 4 | /** The worker was created but never started */ 5 | NOT_STARTED, 6 | /** Ready to accept and process tasks */ 7 | ACTIVE, 8 | /** May be absent from a worker state machine is the worker is not {@link Suspendable} */ 9 | SUSPENDED, 10 | /** 11 | * Shutdown is requested on the worker, and it is completing with the outstanding tasks before 12 | * being {@link #TERMINATED}. The worker MAY reject new tasks to be processed if any internals are 13 | * already being released. 14 | */ 15 | SHUTDOWN, 16 | /** 17 | * The final state of the worker, all internal resources are released, the worker SHOULD reject 18 | * any new tasks to be processed 19 | */ 20 | TERMINATED 21 | } 22 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/worker/WorkerWithLifecycle.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.worker; 2 | 3 | public interface WorkerWithLifecycle { 4 | WorkerLifecycleState getLifecycleState(); 5 | } 6 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/internal/worker/WorkflowExecutionException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.worker; 2 | 3 | import io.temporal.api.enums.v1.CommandType; 4 | import io.temporal.api.failure.v1.Failure; 5 | 6 | /** 7 | * Internal. Do not throw or catch in application level code. 8 | * 9 | *

This exception is used to signal that the workflow execution should be failed with {@link 10 | * CommandType#COMMAND_TYPE_FAIL_WORKFLOW_EXECUTION} 11 | */ 12 | public final class WorkflowExecutionException extends RuntimeException { 13 | private final Failure failure; 14 | 15 | public WorkflowExecutionException(Failure failure) { 16 | super(failure.getMessage()); 17 | this.failure = failure; 18 | } 19 | 20 | public Failure getFailure() { 21 | return failure; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/nexus/Nexus.java: -------------------------------------------------------------------------------- 1 | package io.temporal.nexus; 2 | 3 | import io.temporal.internal.nexus.NexusInternal; 4 | import io.temporal.internal.sync.WorkflowInternal; 5 | 6 | /** This class contains methods exposing Temporal APIs for Nexus Operations */ 7 | public final class Nexus { 8 | /** 9 | * Can be used to get information about a Nexus Operation. This static method relies on a 10 | * thread-local variable and works only in the original Nexus thread. 11 | */ 12 | public static NexusOperationContext getOperationContext() { 13 | return NexusInternal.getOperationContext(); 14 | } 15 | 16 | /** 17 | * Use this to rethrow a checked exception from a Nexus Operation instead of adding the exception 18 | * to a method signature. 19 | * 20 | * @return Never returns; always throws. Throws original exception if e is {@link 21 | * RuntimeException} or {@link Error}. 22 | */ 23 | public static RuntimeException wrap(Throwable e) { 24 | return WorkflowInternal.wrap(e); 25 | } 26 | 27 | /** Prohibits instantiation. */ 28 | private Nexus() {} 29 | } 30 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/nexus/NexusOperationContext.java: -------------------------------------------------------------------------------- 1 | package io.temporal.nexus; 2 | 3 | import com.uber.m3.tally.Scope; 4 | import io.temporal.client.WorkflowClient; 5 | import io.temporal.serviceclient.WorkflowServiceStubsOptions; 6 | 7 | /** 8 | * Context object passed to a Nexus operation implementation. Use {@link 9 | * Nexus#getOperationContext()} from a Nexus Operation implementation to access. 10 | */ 11 | public interface NexusOperationContext { 12 | 13 | /** 14 | * Get scope for reporting business metrics in a nexus handler. This scope is tagged with the 15 | * service and operation. 16 | * 17 | *

The original metrics scope is set through {@link 18 | * WorkflowServiceStubsOptions.Builder#setMetricsScope(Scope)} when a worker starts up. 19 | */ 20 | Scope getMetricsScope(); 21 | 22 | /** 23 | * Get a {@link WorkflowClient} that can be used to start interact with the Temporal service from 24 | * a Nexus handler. 25 | */ 26 | WorkflowClient getWorkflowClient(); 27 | } 28 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/nexus/WorkflowHandleFactory.java: -------------------------------------------------------------------------------- 1 | package io.temporal.nexus; 2 | 3 | import io.nexusrpc.handler.OperationContext; 4 | import io.nexusrpc.handler.OperationStartDetails; 5 | import io.temporal.client.WorkflowClient; 6 | import javax.annotation.Nullable; 7 | 8 | /** 9 | * Function interface for {@link WorkflowRunOperation#fromWorkflowHandle(WorkflowHandleFactory)} 10 | * representing the workflow to associate with each operation call. 11 | */ 12 | @FunctionalInterface 13 | public interface WorkflowHandleFactory { 14 | /** 15 | * Invoked every operation start call and expected to return a workflow handle to a workflow stub 16 | * created with the {@link WorkflowClient} provided by {@link 17 | * NexusOperationContext#getWorkflowClient()}. 18 | */ 19 | @Nullable 20 | WorkflowHandle apply(OperationContext context, OperationStartDetails details, T input); 21 | } 22 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/nexus/WorkflowHandleInvoker.java: -------------------------------------------------------------------------------- 1 | package io.temporal.nexus; 2 | 3 | import io.temporal.api.common.v1.WorkflowExecution; 4 | import io.temporal.internal.client.NexusStartWorkflowRequest; 5 | 6 | interface WorkflowHandleInvoker { 7 | WorkflowExecution invoke(NexusStartWorkflowRequest request); 8 | } 9 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/nexus/WorkflowMethodFactory.java: -------------------------------------------------------------------------------- 1 | package io.temporal.nexus; 2 | 3 | import io.nexusrpc.handler.OperationContext; 4 | import io.nexusrpc.handler.OperationStartDetails; 5 | import io.temporal.client.WorkflowClient; 6 | import io.temporal.client.WorkflowOptions; 7 | import io.temporal.workflow.Functions; 8 | import javax.annotation.Nullable; 9 | 10 | /** 11 | * Function interface for {@link WorkflowRunOperation#fromWorkflowMethod(WorkflowMethodFactory)} 12 | * representing the workflow method to invoke for every operation call. 13 | */ 14 | @FunctionalInterface 15 | public interface WorkflowMethodFactory { 16 | /** 17 | * Invoked every operation start call and expected to return a workflow method reference to a 18 | * proxy created through {@link WorkflowClient#newWorkflowStub(Class, WorkflowOptions)} using the 19 | * provided {@link WorkflowClient} form {@link Nexus#getOperationContext()}. 20 | */ 21 | @Nullable 22 | Functions.Func1 apply(OperationContext context, OperationStartDetails details, T input); 23 | } 24 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/nexus/WorkflowMethodMethodInvoker.java: -------------------------------------------------------------------------------- 1 | package io.temporal.nexus; 2 | 3 | import io.temporal.api.common.v1.WorkflowExecution; 4 | import io.temporal.internal.client.NexusStartWorkflowRequest; 5 | import io.temporal.internal.client.WorkflowClientInternal; 6 | import io.temporal.internal.nexus.CurrentNexusOperationContext; 7 | import io.temporal.internal.nexus.InternalNexusOperationContext; 8 | import io.temporal.workflow.Functions; 9 | 10 | class WorkflowMethodMethodInvoker implements WorkflowHandleInvoker { 11 | private Functions.Proc workflow; 12 | 13 | public WorkflowMethodMethodInvoker(Functions.Proc workflow) { 14 | this.workflow = workflow; 15 | } 16 | 17 | @Override 18 | public WorkflowExecution invoke(NexusStartWorkflowRequest request) { 19 | InternalNexusOperationContext nexusCtx = CurrentNexusOperationContext.get(); 20 | return ((WorkflowClientInternal) nexusCtx.getWorkflowClient().getInternal()) 21 | .startNexus(request, workflow); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/nexus/WorkflowStubHandleInvoker.java: -------------------------------------------------------------------------------- 1 | package io.temporal.nexus; 2 | 3 | import static io.temporal.internal.common.InternalUtils.createNexusBoundStub; 4 | 5 | import io.temporal.api.common.v1.WorkflowExecution; 6 | import io.temporal.client.WorkflowStub; 7 | import io.temporal.internal.client.NexusStartWorkflowRequest; 8 | 9 | class WorkflowStubHandleInvoker implements WorkflowHandleInvoker { 10 | final Object[] args; 11 | final WorkflowStub stub; 12 | 13 | WorkflowStubHandleInvoker(WorkflowStub stub, Object[] args) { 14 | this.args = args; 15 | this.stub = stub; 16 | } 17 | 18 | @Override 19 | public WorkflowExecution invoke(NexusStartWorkflowRequest request) { 20 | return createNexusBoundStub(stub, request).start(args); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/payload/codec/PayloadCodecException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.payload.codec; 2 | 3 | public class PayloadCodecException extends RuntimeException { 4 | public PayloadCodecException(String message) { 5 | super(message); 6 | } 7 | 8 | public PayloadCodecException(String message, Throwable cause) { 9 | super(message, cause); 10 | } 11 | 12 | public PayloadCodecException(Throwable cause) { 13 | super(cause); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/worker/PollerTypeMetricsTag.java: -------------------------------------------------------------------------------- 1 | package io.temporal.worker; 2 | 3 | import io.temporal.serviceclient.MetricsTag; 4 | 5 | public class PollerTypeMetricsTag { 6 | public enum PollerType implements MetricsTag.TagValue { 7 | WORKFLOW_TASK("workflow_task"), 8 | WORKFLOW_STICKY_TASK("workflow_sticky_task"), 9 | ACTIVITY_TASK("activity_task"), 10 | NEXUS_TASK("nexus_task"), 11 | ; 12 | 13 | PollerType(String value) { 14 | this.value = value; 15 | } 16 | 17 | private final String value; 18 | 19 | @Override 20 | public String getTag() { 21 | return MetricsTag.POLLER_TYPE; 22 | } 23 | 24 | public String getValue() { 25 | return value; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/worker/TypeAlreadyRegisteredException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.worker; 2 | 3 | /** 4 | * This exception is thrown when worker has 5 | * 6 | *

    7 | *
  • an activity instance for the activity type 8 | *
  • a workflow type or factory for the workflow type 9 | *
10 | * 11 | * already registered. 12 | */ 13 | public class TypeAlreadyRegisteredException extends IllegalStateException { 14 | private final String registeredTypeName; 15 | 16 | public TypeAlreadyRegisteredException(String registeredTypeName, String message) { 17 | super(message); 18 | this.registeredTypeName = registeredTypeName; 19 | } 20 | 21 | /** Workflow or Activity type that is already registered */ 22 | public String getRegisteredTypeName() { 23 | return registeredTypeName; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/worker/WorkerMetricsTag.java: -------------------------------------------------------------------------------- 1 | package io.temporal.worker; 2 | 3 | import io.temporal.serviceclient.MetricsTag; 4 | 5 | public class WorkerMetricsTag { 6 | public enum WorkerType implements MetricsTag.TagValue { 7 | WORKFLOW_WORKER("WorkflowWorker"), 8 | ACTIVITY_WORKER("ActivityWorker"), 9 | LOCAL_ACTIVITY_WORKER("LocalActivityWorker"), 10 | NEXUS_WORKER("NexusWorker"); 11 | 12 | WorkerType(String value) { 13 | this.value = value; 14 | } 15 | 16 | private final String value; 17 | 18 | @Override 19 | public String getTag() { 20 | return MetricsTag.WORKER_TYPE; 21 | } 22 | 23 | public String getValue() { 24 | return value; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/worker/tuning/SlotInfo.java: -------------------------------------------------------------------------------- 1 | package io.temporal.worker.tuning; 2 | 3 | import io.temporal.common.Experimental; 4 | 5 | /** The base class that all slot info types used by {@link SlotSupplier} extend. */ 6 | @Experimental 7 | public abstract class SlotInfo { 8 | SlotInfo() {} 9 | } 10 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/worker/tuning/SlotMarkUsedContext.java: -------------------------------------------------------------------------------- 1 | package io.temporal.worker.tuning; 2 | 3 | import io.temporal.common.Experimental; 4 | 5 | @Experimental 6 | public interface SlotMarkUsedContext { 7 | /** 8 | * @return The information associated with the slot that is being marked as used. 9 | */ 10 | SI getSlotInfo(); 11 | 12 | /** 13 | * @return The previously reserved permit that is being used with this slot. 14 | */ 15 | SlotPermit getSlotPermit(); 16 | } 17 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/worker/tuning/SlotPermit.java: -------------------------------------------------------------------------------- 1 | package io.temporal.worker.tuning; 2 | 3 | import io.temporal.common.Experimental; 4 | 5 | /** 6 | * This class is handed out by implementations of {@link SlotSupplier}. Permits are held until the 7 | * tasks they are associated with (if any) are finished processing, or if the reservation is no 8 | * longer needed. Your supplier implementation may store additional data in the permit, if desired. 9 | * 10 | *

When {@link SlotSupplier#releaseSlot(SlotReleaseContext)} is called, the exact same instance 11 | * of the permit is passed back to the supplier. 12 | */ 13 | @Experimental 14 | public final class SlotPermit { 15 | public final Object userData; 16 | 17 | public SlotPermit() { 18 | this.userData = null; 19 | } 20 | 21 | public SlotPermit(Object userData) { 22 | this.userData = userData; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/worker/tuning/SlotReleaseContext.java: -------------------------------------------------------------------------------- 1 | package io.temporal.worker.tuning; 2 | 3 | import io.temporal.common.Experimental; 4 | import javax.annotation.Nullable; 5 | 6 | @Experimental 7 | public interface SlotReleaseContext { 8 | /** 9 | * @return The reason the slot is being released. 10 | */ 11 | SlotReleaseReason getSlotReleaseReason(); 12 | 13 | /** 14 | * @return The permit the slot was using that is now being released. 15 | */ 16 | SlotPermit getSlotPermit(); 17 | 18 | /** 19 | * @return The information associated with the slot that is being released. May be null if the 20 | * slot was never marked as used. 21 | */ 22 | @Nullable 23 | SI getSlotInfo(); 24 | } 25 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/worker/tuning/SystemResourceInfo.java: -------------------------------------------------------------------------------- 1 | package io.temporal.worker.tuning; 2 | 3 | import io.temporal.common.Experimental; 4 | 5 | /** Implementors determine how resource usage is measured. */ 6 | @Experimental 7 | public interface SystemResourceInfo { 8 | /** 9 | * @return System-wide CPU usage as a percentage [0.0, 1.0] 10 | */ 11 | double getCPUUsagePercent(); 12 | 13 | /** 14 | * @return Memory usage as a percentage [0.0, 1.0]. Memory usage should reflect either system-wide 15 | * usage or JVM-specific usage, whichever is higher, to avoid running out of memory in either 16 | * way. 17 | */ 18 | double getMemoryUsagePercent(); 19 | } 20 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/worker/tuning/WorkerTuner.java: -------------------------------------------------------------------------------- 1 | package io.temporal.worker.tuning; 2 | 3 | import io.temporal.common.Experimental; 4 | import javax.annotation.Nonnull; 5 | 6 | /** WorkerTuners allow for the dynamic customization of some aspects of worker configuration. */ 7 | @Experimental 8 | public interface WorkerTuner { 9 | /** 10 | * @return A {@link SlotSupplier} for workflow tasks. 11 | */ 12 | @Nonnull 13 | SlotSupplier getWorkflowTaskSlotSupplier(); 14 | 15 | /** 16 | * @return A {@link SlotSupplier} for activity tasks. 17 | */ 18 | @Nonnull 19 | SlotSupplier getActivityTaskSlotSupplier(); 20 | 21 | /** 22 | * @return A {@link SlotSupplier} for local activities. 23 | */ 24 | @Nonnull 25 | SlotSupplier getLocalActivitySlotSupplier(); 26 | 27 | /** 28 | * @return A {@link SlotSupplier} for nexus tasks. 29 | */ 30 | @Nonnull 31 | SlotSupplier getNexusSlotSupplier(); 32 | } 33 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/workflow/CancelExternalWorkflowException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.workflow; 2 | 3 | import io.temporal.api.common.v1.WorkflowExecution; 4 | import io.temporal.client.WorkflowException; 5 | 6 | /** 7 | * Exception used to communicate failure of a request to cancel an external workflow. 8 | * 9 | *

TODO: Hook it up with RequestCancelExternalWorkflowExecutionFailed and 10 | * WorkflowExecutionCancelRequested 11 | */ 12 | @SuppressWarnings("serial") 13 | public final class CancelExternalWorkflowException extends WorkflowException { 14 | 15 | public CancelExternalWorkflowException( 16 | String message, WorkflowExecution execution, String workflowType, Throwable cause) { 17 | super(message, execution, workflowType, cause); 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return "CancelExternalWorkflowException{" 23 | + "execution=" 24 | + getExecution() 25 | + ", workflowType='" 26 | + getWorkflowType() 27 | + '\'' 28 | + '}'; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/workflow/DynamicQueryHandler.java: -------------------------------------------------------------------------------- 1 | package io.temporal.workflow; 2 | 3 | import io.temporal.common.converter.EncodedValues; 4 | 5 | /** 6 | * Use DynamicQueryHandler to process any query dynamically. This is useful for a library level code 7 | * and implementation of DSLs. 8 | * 9 | *

Use {@link Workflow#registerListener(Object)} to register an implementation of the 10 | * DynamicQueryListener. Only one such listener can be registered per workflow execution. 11 | * 12 | *

When registered any queries which don't have a specific handler will be delivered to it. 13 | * 14 | * @see DynamicSignalHandler 15 | * @see DynamicWorkflow 16 | * @see DynamicUpdateHandler 17 | */ 18 | public interface DynamicQueryHandler { 19 | Object handle(String queryType, EncodedValues args); 20 | 21 | /** Short description of the Query handler. */ 22 | default String getDescription() { 23 | return "Dynamic query handler"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/workflow/HandlerUnfinishedPolicy.java: -------------------------------------------------------------------------------- 1 | package io.temporal.workflow; 2 | 3 | /** 4 | * Actions taken if a workflow terminates with running handlers. 5 | * 6 | *

Policy defining actions taken when a workflow exits while update or signal handlers are 7 | * running. The workflow exit may be due to successful return, failure, cancellation, or 8 | * continue-as-new. 9 | */ 10 | public enum HandlerUnfinishedPolicy { 11 | /** Issue a warning in addition to abandon. */ 12 | WARN_AND_ABANDON, 13 | /** 14 | * Abandon the handler. 15 | * 16 | *

In the case of an update handler this means that the client will receive an error rather 17 | * than the update result. 18 | */ 19 | ABANDON, 20 | } 21 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/workflow/NexusOperationExecution.java: -------------------------------------------------------------------------------- 1 | package io.temporal.workflow; 2 | 3 | import java.util.Optional; 4 | 5 | /** NexusOperationExecution identifies a specific Nexus operation execution. */ 6 | public interface NexusOperationExecution { 7 | /** 8 | * @return the Operation token as set by the Operation's handler. May be empty if the operation 9 | * hasn't started yet or completed synchronously. 10 | */ 11 | Optional getOperationToken(); 12 | } 13 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/workflow/SignalExternalWorkflowException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.workflow; 2 | 3 | import io.temporal.api.common.v1.WorkflowExecution; 4 | import io.temporal.client.WorkflowException; 5 | 6 | /** Exception used to communicate failure of a request to signal an external workflow. */ 7 | @SuppressWarnings("serial") 8 | public final class SignalExternalWorkflowException extends WorkflowException { 9 | 10 | public SignalExternalWorkflowException(WorkflowExecution execution, String workflowType) { 11 | super(getMessage(execution, workflowType), execution, workflowType, null); 12 | } 13 | 14 | public static String getMessage(WorkflowExecution execution, String workflowType) { 15 | return "message='Open execution not found', workflowId='" 16 | + execution.getWorkflowId() 17 | + "', runId='" 18 | + execution.getRunId() 19 | + "'" 20 | + (workflowType == null ? "" : "', workflowType='" + workflowType + '\''); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/workflow/UpdateInfo.java: -------------------------------------------------------------------------------- 1 | package io.temporal.workflow; 2 | 3 | /** Provides information about the current workflow Update. */ 4 | public interface UpdateInfo { 5 | /** 6 | * @return Update name 7 | */ 8 | String getUpdateName(); 9 | 10 | /** 11 | * @return Update ID 12 | */ 13 | String getUpdateId(); 14 | } 15 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/workflow/WorkflowMethod.java: -------------------------------------------------------------------------------- 1 | package io.temporal.workflow; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Indicates that the method is a workflow method. Workflow method is executed when workflow is 10 | * started. Workflow completes when workflow method returns. This annotation applies only to 11 | * workflow interface methods. 12 | */ 13 | @Retention(RetentionPolicy.RUNTIME) 14 | @Target(ElementType.METHOD) 15 | public @interface WorkflowMethod { 16 | /** 17 | * Name of the workflow type. Default is {short class name}. 18 | * 19 | *

Be careful with names that contain special characters, as these names can be used as metric 20 | * tags. Systems like Prometheus ignore metrics which have tags with unsupported characters. 21 | * 22 | *

Name cannot start with __temporal_ as it is reserved for internal use. 23 | */ 24 | String name() default ""; 25 | } 26 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/workflow/WorkflowQueue.java: -------------------------------------------------------------------------------- 1 | package io.temporal.workflow; 2 | 3 | public interface WorkflowQueue extends QueueConsumer, QueueProducer {} 4 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java/io/temporal/workflow/WorkflowVersioningBehavior.java: -------------------------------------------------------------------------------- 1 | package io.temporal.workflow; 2 | 3 | import io.temporal.common.Experimental; 4 | import io.temporal.common.VersioningBehavior; 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * Indicates the versioning behavior of this workflow. May only be applied to workflow 12 | * implementations, not interfaces. 13 | */ 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target(ElementType.METHOD) 16 | @Experimental 17 | public @interface WorkflowVersioningBehavior { 18 | /** 19 | * The behavior to apply to this workflow. See {@link VersioningBehavior} for more information. 20 | */ 21 | VersioningBehavior value(); 22 | } 23 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/java21/io/temporal/internal/task/VirtualThreadDelegate.java: -------------------------------------------------------------------------------- 1 | 2 | package io.temporal.internal.task; 3 | 4 | import java.util.concurrent.ExecutorService; 5 | import java.util.concurrent.Executors; 6 | import java.util.concurrent.ThreadFactory; 7 | 8 | /** 9 | * Internal delegate for virtual thread handling on JDK 21. 10 | * This is the actual version compiled against JDK 21. 11 | */ 12 | public final class VirtualThreadDelegate { 13 | 14 | public static ExecutorService newVirtualThreadExecutor(ThreadConfigurator configurator) { 15 | 16 | return Executors.newThreadPerTaskExecutor( 17 | r -> { 18 | Thread.Builder threadBuilder = Thread.ofVirtual(); 19 | Thread t = threadBuilder.unstarted(r); 20 | configurator.configure(t); 21 | return t; 22 | }); 23 | } 24 | 25 | private VirtualThreadDelegate() { 26 | } 27 | } -------------------------------------------------------------------------------- /temporal-sdk/src/main/resources/META-INF/native-image/io/temporal/temporal-sdk/jni-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | ] 3 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/resources/META-INF/native-image/io/temporal/temporal-sdk/proxy-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | ] 3 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/resources/META-INF/native-image/io/temporal/temporal-sdk/resource-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "resources":{ 3 | "includes":[ 4 | ]}, 5 | "bundles":[] 6 | } 7 | -------------------------------------------------------------------------------- /temporal-sdk/src/main/resources/META-INF/native-image/io/temporal/temporal-sdk/serialization-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "types":[ 3 | ], 4 | "lambdaCapturingTypes":[ 5 | ], 6 | "proxies":[ 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /temporal-sdk/src/test/java/io/temporal/common/RetryOptionsTest.java: -------------------------------------------------------------------------------- 1 | package io.temporal.common; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.time.Duration; 6 | import org.junit.Test; 7 | 8 | public class RetryOptionsTest { 9 | 10 | @Test 11 | public void mergePrefersTheParameter() { 12 | RetryOptions o1 = 13 | RetryOptions.newBuilder() 14 | .setInitialInterval(Duration.ofSeconds(1)) 15 | .validateBuildWithDefaults(); 16 | RetryOptions o2 = 17 | RetryOptions.newBuilder() 18 | .setInitialInterval(Duration.ofSeconds(2)) 19 | .validateBuildWithDefaults(); 20 | 21 | assertEquals(Duration.ofSeconds(2), o1.merge(o2).getInitialInterval()); 22 | } 23 | 24 | @Test(expected = IllegalStateException.class) 25 | public void maximumIntervalCantBeLessThanInitial() { 26 | RetryOptions.newBuilder() 27 | .setInitialInterval(Duration.ofSeconds(5)) 28 | .setMaximumInterval(Duration.ofSeconds(1)) 29 | .validateBuildWithDefaults(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /temporal-sdk/src/test/java/io/temporal/common/metadata/testclasses/ActivityInterfaceWithOneNonAnnotatedMethod.java: -------------------------------------------------------------------------------- 1 | package io.temporal.common.metadata.testclasses; 2 | 3 | import io.temporal.activity.ActivityInterface; 4 | 5 | @ActivityInterface 6 | public interface ActivityInterfaceWithOneNonAnnotatedMethod { 7 | boolean activityMethod(); 8 | } 9 | -------------------------------------------------------------------------------- /temporal-sdk/src/test/java/io/temporal/common/metadata/testclasses/WorkflowInterfaceWithOneWorkflowMethod.java: -------------------------------------------------------------------------------- 1 | package io.temporal.common.metadata.testclasses; 2 | 3 | import io.temporal.workflow.WorkflowInterface; 4 | import io.temporal.workflow.WorkflowMethod; 5 | 6 | @WorkflowInterface 7 | public interface WorkflowInterfaceWithOneWorkflowMethod { 8 | @WorkflowMethod 9 | boolean workflowMethod(); 10 | } 11 | -------------------------------------------------------------------------------- /temporal-sdk/src/test/java/io/temporal/failure/ApplicationFailureTest.java: -------------------------------------------------------------------------------- 1 | package io.temporal.failure; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | public class ApplicationFailureTest { 7 | 8 | @Test 9 | public void applicationFailureCopy() { 10 | ApplicationFailure originalAppFailure = 11 | ApplicationFailure.newBuilder().setType("TestType").setMessage("test message").build(); 12 | ApplicationFailure newAppFailure = 13 | ApplicationFailure.newBuilder(originalAppFailure).setNonRetryable(true).build(); 14 | Assert.assertEquals(originalAppFailure.getType(), newAppFailure.getType()); 15 | Assert.assertEquals( 16 | originalAppFailure.getOriginalMessage(), newAppFailure.getOriginalMessage()); 17 | Assert.assertNotEquals(originalAppFailure.isNonRetryable(), newAppFailure.isNonRetryable()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /temporal-sdk/src/test/java/io/temporal/internal/common/NexusUtilTest.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.common; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | public class NexusUtilTest { 7 | @Test 8 | public void testParseRequestTimeout() { 9 | Assert.assertThrows( 10 | IllegalArgumentException.class, () -> NexusUtil.parseRequestTimeout("invalid")); 11 | Assert.assertThrows(IllegalArgumentException.class, () -> NexusUtil.parseRequestTimeout("1h")); 12 | Assert.assertEquals(java.time.Duration.ofMillis(10), NexusUtil.parseRequestTimeout("10ms")); 13 | Assert.assertEquals(java.time.Duration.ofMillis(10), NexusUtil.parseRequestTimeout("10.1ms")); 14 | Assert.assertEquals(java.time.Duration.ofSeconds(1), NexusUtil.parseRequestTimeout("1s")); 15 | Assert.assertEquals(java.time.Duration.ofMinutes(999), NexusUtil.parseRequestTimeout("999m")); 16 | Assert.assertEquals(java.time.Duration.ofMillis(1300), NexusUtil.parseRequestTimeout("1.3s")); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /temporal-sdk/src/test/java/io/temporal/internal/replay/FullHistoryIterator.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.replay; 2 | 3 | import io.grpc.Deadline; 4 | import io.temporal.api.history.v1.HistoryEvent; 5 | import java.util.Iterator; 6 | 7 | class FullHistoryIterator implements WorkflowHistoryIterator { 8 | private final Iterator iterator; 9 | 10 | FullHistoryIterator(Iterable iterable) { 11 | this.iterator = iterable.iterator(); 12 | } 13 | 14 | @Override 15 | public void initDeadline(Deadline deadline) {} 16 | 17 | @Override 18 | public boolean hasNext() { 19 | return iterator.hasNext(); 20 | } 21 | 22 | @Override 23 | public HistoryEvent next() { 24 | return iterator.next(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /temporal-sdk/src/test/java/io/temporal/worker/IndependentResourceBasedTests.java: -------------------------------------------------------------------------------- 1 | package io.temporal.worker; 2 | 3 | interface IndependentResourceBasedTests {} 4 | -------------------------------------------------------------------------------- /temporal-sdk/src/test/java/io/temporal/worker/WorkerSuspendTest.java: -------------------------------------------------------------------------------- 1 | package io.temporal.worker; 2 | 3 | import static org.junit.Assert.assertFalse; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import io.temporal.testing.internal.SDKTestWorkflowRule; 7 | import io.temporal.workflow.shared.TestWorkflows.TestWorkflow1; 8 | import org.junit.Rule; 9 | import org.junit.Test; 10 | 11 | public class WorkerSuspendTest { 12 | 13 | @Rule 14 | public SDKTestWorkflowRule testWorkflowRule = 15 | SDKTestWorkflowRule.newBuilder().setWorkflowTypes(TestWorkflowImpl.class).build(); 16 | 17 | @Test 18 | public void testSuspendResume() { 19 | Worker worker = testWorkflowRule.getWorker(); 20 | assertFalse(worker.isSuspended()); 21 | worker.suspendPolling(); 22 | assertTrue(worker.isSuspended()); 23 | worker.resumePolling(); 24 | assertFalse(worker.isSuspended()); 25 | } 26 | 27 | public static class TestWorkflowImpl implements TestWorkflow1 { 28 | @Override 29 | public String execute(String now) { 30 | return ""; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /temporal-sdk/src/test/java/io/temporal/workflow/AGENTS.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | This directory and sub directory contain tests for workflow APIs. 4 | 5 | # Testing 6 | 7 | Tests should use the `SDKTestWorkflowRule` to create a worker, register workflows, activities and nexus services. -------------------------------------------------------------------------------- /temporal-sdk/src/test/java/io/temporal/workflow/determinism/DeterminismFailingWorkflowImpl.java: -------------------------------------------------------------------------------- 1 | package io.temporal.workflow.determinism; 2 | 3 | import io.temporal.testing.internal.SDKTestOptions; 4 | import io.temporal.workflow.Workflow; 5 | import io.temporal.workflow.shared.TestActivities; 6 | import io.temporal.workflow.shared.TestWorkflows; 7 | import io.temporal.workflow.unsafe.WorkflowUnsafe; 8 | 9 | public class DeterminismFailingWorkflowImpl implements TestWorkflows.TestWorkflowStringArg { 10 | 11 | @Override 12 | public void execute(String taskQueue) { 13 | TestActivities.VariousTestActivities activities = 14 | Workflow.newActivityStub( 15 | TestActivities.VariousTestActivities.class, 16 | SDKTestOptions.newActivityOptionsForTaskQueue(taskQueue)); 17 | if (!WorkflowUnsafe.isReplaying()) { 18 | activities.activity1(1); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /temporal-sdk/src/test/java/io/temporal/workflow/sdkTestWorkflowRuleTests/SDKWorkflowRuleInterceptorTest1.java: -------------------------------------------------------------------------------- 1 | package io.temporal.workflow.sdkTestWorkflowRuleTests; 2 | 3 | import io.temporal.testing.internal.SDKTestWorkflowRule; 4 | import io.temporal.testing.internal.TracingWorkerInterceptor; 5 | import org.junit.Assert; 6 | import org.junit.Rule; 7 | import org.junit.Test; 8 | 9 | public class SDKWorkflowRuleInterceptorTest1 { 10 | 11 | @Rule public SDKTestWorkflowRule testWorkflowRule = SDKTestWorkflowRule.newBuilder().build(); 12 | 13 | @Test 14 | public void testWorkerInterceptorWorkerFactoryOptionsNotSet() { 15 | Assert.assertNotNull(testWorkflowRule.getInterceptor(TracingWorkerInterceptor.class)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /temporal-sdk/src/test/java/io/temporal/workflow/sdkTestWorkflowRuleTests/SDKWorkflowRuleInterceptorTest2.java: -------------------------------------------------------------------------------- 1 | package io.temporal.workflow.sdkTestWorkflowRuleTests; 2 | 3 | import io.temporal.testing.internal.SDKTestWorkflowRule; 4 | import io.temporal.testing.internal.TracingWorkerInterceptor; 5 | import io.temporal.worker.WorkerFactoryOptions; 6 | import org.junit.Assert; 7 | import org.junit.Rule; 8 | import org.junit.Test; 9 | 10 | public class SDKWorkflowRuleInterceptorTest2 { 11 | 12 | @Rule 13 | public SDKTestWorkflowRule testWorkflowRule = 14 | SDKTestWorkflowRule.newBuilder() 15 | .setWorkerFactoryOptions(WorkerFactoryOptions.getDefaultInstance()) 16 | .build(); 17 | 18 | @Test 19 | public void testWorkerInterceptorWorkerFactoryOptionsSet() { 20 | Assert.assertNotNull(testWorkflowRule.getInterceptor(TracingWorkerInterceptor.class)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /temporal-sdk/src/test/java/io/temporal/workflow/shared/NonSerializableException.java: -------------------------------------------------------------------------------- 1 | package io.temporal.workflow.shared; 2 | 3 | import io.temporal.activity.Activity; 4 | import java.io.File; 5 | import java.io.FileInputStream; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | 9 | public class NonSerializableException extends RuntimeException { 10 | @SuppressWarnings("unused") 11 | private final InputStream file; // gson chokes on this field 12 | 13 | public NonSerializableException() { 14 | try { 15 | file = new FileInputStream(File.createTempFile("foo", "bar")); 16 | } catch (IOException e) { 17 | throw Activity.wrap(e); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /temporal-sdk/src/test/java/io/temporal/workflow/shared/TestNexusServices.java: -------------------------------------------------------------------------------- 1 | package io.temporal.workflow.shared; 2 | 3 | import io.nexusrpc.Operation; 4 | import io.nexusrpc.Service; 5 | 6 | /** Common set of Nexus Service interfaces for use in tests. */ 7 | public class TestNexusServices { 8 | @Service 9 | public interface TestNexusService1 { 10 | @Operation 11 | String operation(String input); 12 | } 13 | 14 | @Service 15 | public interface TestNexusService2 { 16 | @Operation 17 | Integer operation(Integer input); 18 | } 19 | 20 | @Service 21 | public interface TestNexusServiceVoid { 22 | @Operation 23 | Void operation(); 24 | } 25 | 26 | @Service 27 | public interface TestNexusServiceVoidInput { 28 | @Operation 29 | String operation(); 30 | } 31 | 32 | @Service 33 | public interface TestNexusServiceVoidReturn { 34 | @Operation 35 | Void operation(String input); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /temporal-sdk/src/test/resources/simpleHistory1.json: -------------------------------------------------------------------------------- 1 | { 2 | "events": [ 3 | { 4 | "eventId": "1", 5 | "eventTime": "2020-07-30T00:30:03.082421843Z", 6 | "eventType": "WorkflowExecutionStarted", 7 | "version": "-24", 8 | "taskId": "5242897", 9 | "workflowExecutionStartedEventAttributes": { 10 | "workflowType": { 11 | "name": "SomeName" 12 | }, 13 | "taskQueue": { 14 | "name": "SomeQueueName", 15 | "kind": "Normal" 16 | }, 17 | "workflowExecutionTimeout": "300s", 18 | "workflowTaskTimeout": "60s", 19 | "originalExecutionRunId": "1fd5d4c8-1590-4a0a-8027-535e8729de8e", 20 | "firstExecutionRunId": "1fd5d4c8-1590-4a0a-8027-535e8729de8e", 21 | "attempt": 1, 22 | "firstWorkflowTaskBackoff": "0s" 23 | } 24 | } 25 | ] 26 | } -------------------------------------------------------------------------------- /temporal-sdk/src/test/resources/simpleHistory1_withAddedNewRandomField.json: -------------------------------------------------------------------------------- 1 | { 2 | "events": [ 3 | { 4 | "eventId": "1", 5 | "eventTime": "2020-07-30T00:30:03.082421843Z", 6 | "eventType": "WorkflowExecutionStarted", 7 | "version": "-24", 8 | "taskId": "5242897", 9 | "someNewFieldThatIsAbsentFromTheCurrentProtoSchema": "100500", 10 | "workflowExecutionStartedEventAttributes": { 11 | "someNewFieldThatIsAbsentFromTheCurrentProtoSchema": "100500", 12 | "workflowType": { 13 | "name": "SomeName" 14 | }, 15 | "taskQueue": { 16 | "name": "SomeQueueName", 17 | "kind": "Normal" 18 | }, 19 | "workflowExecutionTimeout": "300s", 20 | "workflowTaskTimeout": "60s", 21 | "originalExecutionRunId": "1fd5d4c8-1590-4a0a-8027-535e8729de8e", 22 | "firstExecutionRunId": "1fd5d4c8-1590-4a0a-8027-535e8729de8e", 23 | "attempt": 1, 24 | "firstWorkflowTaskBackoff": "0s" 25 | } 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /temporal-serviceclient/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .*.swp 3 | .*.swo 4 | *.iml 5 | .DS_Store 6 | .idea 7 | .gradle 8 | /build 9 | /out 10 | /lib 11 | dummy 12 | $buildDir 13 | src/main/idls/* 14 | /bin 15 | .classpath 16 | .project 17 | .settings 18 | .vscode/ 19 | -------------------------------------------------------------------------------- /temporal-serviceclient/src/main/java/io/temporal/authorization/AuthorizationGrpcMetadataProvider.java: -------------------------------------------------------------------------------- 1 | package io.temporal.authorization; 2 | 3 | import io.grpc.Metadata; 4 | import io.temporal.serviceclient.GrpcMetadataProvider; 5 | 6 | public class AuthorizationGrpcMetadataProvider implements GrpcMetadataProvider { 7 | public static final Metadata.Key AUTHORIZATION_HEADER_KEY = 8 | Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER); 9 | 10 | private final AuthorizationTokenSupplier authorizationTokenSupplier; 11 | 12 | public AuthorizationGrpcMetadataProvider(AuthorizationTokenSupplier authorizationTokenSupplier) { 13 | this.authorizationTokenSupplier = authorizationTokenSupplier; 14 | } 15 | 16 | @Override 17 | public Metadata getMetadata() { 18 | Metadata metadata = new Metadata(); 19 | metadata.put(AUTHORIZATION_HEADER_KEY, authorizationTokenSupplier.supply()); 20 | return metadata; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /temporal-serviceclient/src/main/java/io/temporal/authorization/AuthorizationTokenSupplier.java: -------------------------------------------------------------------------------- 1 | package io.temporal.authorization; 2 | 3 | /** 4 | * Supplies tokens that will be sent to the Temporal server to perform authorization. 5 | * Implementations have to be thread-safe. 6 | * 7 | *

The default JWT ClaimMapper expects authorization tokens to be in the following format: 8 | * 9 | *

{@code Bearer } 10 | * 11 | *

{@code } Must be the Base64 url-encoded value of the token. 12 | * 13 | * @see Format of 14 | * JWT 15 | */ 16 | public interface AuthorizationTokenSupplier { 17 | /** 18 | * @return token to be passed in authorization header 19 | */ 20 | String supply(); 21 | } 22 | -------------------------------------------------------------------------------- /temporal-serviceclient/src/main/java/io/temporal/conf/EnvironmentVariableNames.java: -------------------------------------------------------------------------------- 1 | package io.temporal.conf; 2 | 3 | public final class EnvironmentVariableNames { 4 | /** 5 | * Specify this env variable to disable checks and enforcement for classes that are not intended 6 | * to be accessed from workflow code. 7 | * 8 | *

Not specifying it or setting it to "false" (case insensitive) leaves the checks enforced. 9 | * 10 | *

This option is exposed for backwards compatibility only and should never be enabled for any 11 | * new code or application. 12 | */ 13 | public static final String DISABLE_NON_WORKFLOW_CODE_ENFORCEMENTS = 14 | "TEMPORAL_DISABLE_NON_WORKFLOW_CODE_ENFORCEMENTS"; 15 | 16 | public static final String TEMPORAL_DEBUG = "TEMPORAL_DEBUG"; 17 | 18 | private EnvironmentVariableNames() {} 19 | } 20 | -------------------------------------------------------------------------------- /temporal-serviceclient/src/main/java/io/temporal/internal/common/ProtoUtils.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.common; 2 | 3 | import com.google.protobuf.*; 4 | 5 | public class ProtoUtils { 6 | 7 | /** 8 | * This method does exactly what {@link Any#pack(Message)} does. But it doesn't go into reflection 9 | * to fetch the {@code descriptor}, which allows us to avoid a bunch of Graal reflection configs. 10 | */ 11 | public static Any packAny(T details, Descriptors.Descriptor descriptor) { 12 | return Any.newBuilder() 13 | .setTypeUrl("type.googleapis.com/" + descriptor.getFullName()) 14 | .setValue(details.toByteString()) 15 | .build(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /temporal-serviceclient/src/main/java/io/temporal/serviceclient/GrpcMetadataProvider.java: -------------------------------------------------------------------------------- 1 | package io.temporal.serviceclient; 2 | 3 | import io.grpc.Metadata; 4 | 5 | /** Provides additional Metadata (gRPC Headers) that should be used on every request. */ 6 | public interface GrpcMetadataProvider { 7 | Metadata getMetadata(); 8 | } 9 | -------------------------------------------------------------------------------- /temporal-serviceclient/src/main/java/io/temporal/serviceclient/MetricsType.java: -------------------------------------------------------------------------------- 1 | package io.temporal.serviceclient; 2 | 3 | public final class MetricsType { 4 | private MetricsType() {} 5 | 6 | public static final String TEMPORAL_METRICS_PREFIX = "temporal_"; 7 | 8 | public static final String TEMPORAL_REQUEST = TEMPORAL_METRICS_PREFIX + "request"; 9 | public static final String TEMPORAL_REQUEST_FAILURE = TEMPORAL_REQUEST + "_failure"; 10 | public static final String TEMPORAL_REQUEST_LATENCY = TEMPORAL_REQUEST + "_latency"; 11 | public static final String TEMPORAL_LONG_REQUEST = TEMPORAL_METRICS_PREFIX + "long_request"; 12 | public static final String TEMPORAL_LONG_REQUEST_FAILURE = TEMPORAL_LONG_REQUEST + "_failure"; 13 | public static final String TEMPORAL_LONG_REQUEST_LATENCY = TEMPORAL_LONG_REQUEST + "_latency"; 14 | } 15 | -------------------------------------------------------------------------------- /temporal-serviceclient/src/main/resources/META-INF/native-image/io/temporal/temporal-serviceclient/jni-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name":"java.lang.ClassLoader", 4 | "methods":[ 5 | {"name":"getPlatformClassLoader","parameterTypes":[] }, 6 | {"name":"loadClass","parameterTypes":["java.lang.String"] } 7 | ] 8 | }, 9 | { 10 | "name":"jdk.internal.loader.ClassLoaders$PlatformClassLoader" 11 | }, 12 | { 13 | "name":"sun.management.VMManagementImpl", 14 | "fields":[ 15 | {"name":"compTimeMonitoringSupport"}, 16 | {"name":"currentThreadCpuTimeSupport"}, 17 | {"name":"objectMonitorUsageSupport"}, 18 | {"name":"otherThreadCpuTimeSupport"}, 19 | {"name":"remoteDiagnosticCommandsSupport"}, 20 | {"name":"synchronizerUsageSupport"}, 21 | {"name":"threadAllocatedMemorySupport"}, 22 | {"name":"threadContentionMonitoringSupport"} 23 | ] 24 | } 25 | ] 26 | -------------------------------------------------------------------------------- /temporal-serviceclient/src/main/resources/META-INF/native-image/io/temporal/temporal-serviceclient/proxy-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "interfaces":["io.temporal.client.WorkflowClient"] 4 | } 5 | ] 6 | -------------------------------------------------------------------------------- /temporal-serviceclient/src/main/resources/META-INF/native-image/io/temporal/temporal-serviceclient/resource-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "resources":{ 3 | "includes":[ 4 | {"pattern":"\\QMETA-INF/native/libio_grpc_netty_shaded_netty_transport_native_epoll_x86_64.so\\E"}, 5 | {"pattern":"\\QMETA-INF/services/io.grpc.LoadBalancerProvider\\E"}, 6 | {"pattern":"\\QMETA-INF/services/io.grpc.NameResolverProvider\\E"}, 7 | {"pattern":"\\QMETA-INF/services/org.slf4j.spi.SLF4JServiceProvider\\E"}, 8 | {"pattern":"\\Qio/temporal/version.properties\\E"} 9 | ]}, 10 | "bundles":[] 11 | } 12 | -------------------------------------------------------------------------------- /temporal-serviceclient/src/main/resources/META-INF/native-image/io/temporal/temporal-serviceclient/serialization-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "types":[ 3 | ], 4 | "lambdaCapturingTypes":[ 5 | ], 6 | "proxies":[ 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /temporal-serviceclient/src/test/java/io/temporal/serviceclient/functional/GetServerCapabilitiesTest.java: -------------------------------------------------------------------------------- 1 | package io.temporal.serviceclient.functional; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import io.temporal.api.workflowservice.v1.GetSystemInfoResponse; 6 | import io.temporal.testing.internal.SDKTestWorkflowRule; 7 | import org.junit.Rule; 8 | import org.junit.Test; 9 | 10 | public class GetServerCapabilitiesTest { 11 | 12 | @Rule public SDKTestWorkflowRule testWorkflowRule = SDKTestWorkflowRule.newBuilder().build(); 13 | 14 | @Test 15 | public void trivial() { 16 | GetSystemInfoResponse.Capabilities capabilities = 17 | testWorkflowRule.getWorkflowServiceStubs().getServerCapabilities().get(); 18 | assertNotNull(capabilities); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /temporal-serviceclient/src/test/java/io/temporal/serviceclient/functional/KeepAliveTest.java: -------------------------------------------------------------------------------- 1 | package io.temporal.serviceclient.functional; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import io.temporal.serviceclient.WorkflowServiceStubsOptions; 6 | import io.temporal.testing.internal.SDKTestWorkflowRule; 7 | import java.time.Duration; 8 | import org.junit.Rule; 9 | import org.junit.Test; 10 | 11 | public class KeepAliveTest { 12 | @Rule public SDKTestWorkflowRule testWorkflowRule = SDKTestWorkflowRule.newBuilder().build(); 13 | 14 | @Test 15 | public void testKeepAliveOnByDefault() { 16 | WorkflowServiceStubsOptions options = testWorkflowRule.getWorkflowServiceStubs().getOptions(); 17 | assertEquals(true, options.getEnableKeepAlive()); 18 | assertEquals(true, options.getKeepAlivePermitWithoutStream()); 19 | assertEquals(Duration.ofSeconds(30), options.getKeepAliveTime()); 20 | assertEquals(Duration.ofSeconds(15), options.getKeepAliveTimeout()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /temporal-serviceclient/src/test/resources/pkcs12-key.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/temporalio/sdk-java/35386dae38bf40b7434e426258178b6fad4d5e68/temporal-serviceclient/src/test/resources/pkcs12-key.pfx -------------------------------------------------------------------------------- /temporal-shaded/README.md: -------------------------------------------------------------------------------- 1 | # Temporal Java SDK and Testing Framework with shaded dependencies 2 | 3 | This module provides a single temporal-sdk, temporal-testing, temporal-test-server, temporal-serviceclient modules 4 | with shaded Protobuf 3, gRPC and Guava. 5 | 6 | Usage of this module is not recommended, but may be necessary for users with outdated dependencies who can't upgrade for compatibility reasons. 7 | gRPC/netty, Guava and Proto3 are common culprits of such conflicts. 8 | 9 | If you are not struggling with dependencies hell, please stick to the regular temporal-sdk and temporal-testing modules. 10 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/main/java/io/temporal/spring/boot/autoconfigure/TestWorkflowEnvironmentAdapterImpl.java: -------------------------------------------------------------------------------- 1 | package io.temporal.spring.boot.autoconfigure; 2 | 3 | import io.temporal.client.WorkflowClient; 4 | import io.temporal.spring.boot.autoconfigure.template.TestWorkflowEnvironmentAdapter; 5 | import io.temporal.testing.TestWorkflowEnvironment; 6 | import io.temporal.worker.WorkerFactory; 7 | 8 | class TestWorkflowEnvironmentAdapterImpl implements TestWorkflowEnvironmentAdapter { 9 | private final TestWorkflowEnvironment delegate; 10 | 11 | TestWorkflowEnvironmentAdapterImpl(TestWorkflowEnvironment testWorkflowEnvironment) { 12 | this.delegate = testWorkflowEnvironment; 13 | } 14 | 15 | @Override 16 | public WorkflowClient getWorkflowClient() { 17 | return delegate.getWorkflowClient(); 18 | } 19 | 20 | @Override 21 | public WorkerFactory getWorkerFactory() { 22 | return delegate.getWorkerFactory(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/main/java/io/temporal/spring/boot/autoconfigure/properties/TestServerProperties.java: -------------------------------------------------------------------------------- 1 | package io.temporal.spring.boot.autoconfigure.properties; 2 | 3 | import javax.annotation.Nullable; 4 | import org.springframework.boot.context.properties.ConstructorBinding; 5 | 6 | public class TestServerProperties { 7 | private final @Nullable Boolean enabled; 8 | 9 | @ConstructorBinding 10 | public TestServerProperties(@Nullable Boolean enabled) { 11 | this.enabled = enabled; 12 | } 13 | 14 | @Nullable 15 | public Boolean getEnabled() { 16 | return enabled; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/main/java/io/temporal/spring/boot/autoconfigure/properties/WorkersAutoDiscoveryProperties.java: -------------------------------------------------------------------------------- 1 | package io.temporal.spring.boot.autoconfigure.properties; 2 | 3 | import java.util.List; 4 | import javax.annotation.Nullable; 5 | import org.springframework.boot.context.properties.ConstructorBinding; 6 | 7 | public class WorkersAutoDiscoveryProperties { 8 | private final @Nullable List packages; 9 | 10 | @ConstructorBinding 11 | public WorkersAutoDiscoveryProperties(@Nullable List packages) { 12 | this.packages = packages; 13 | } 14 | 15 | @Nullable 16 | public List getPackages() { 17 | return packages; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/main/java/io/temporal/spring/boot/autoconfigure/template/TestWorkflowEnvironmentAdapter.java: -------------------------------------------------------------------------------- 1 | package io.temporal.spring.boot.autoconfigure.template; 2 | 3 | import io.temporal.client.WorkflowClient; 4 | import io.temporal.testing.TestWorkflowEnvironment; 5 | import io.temporal.worker.WorkerFactory; 6 | 7 | /** 8 | * Creates a level of indirection over the {@link TestWorkflowEnvironment} that allows the 9 | * AutoConfiguration and Starter to work with temporal-testing dependency in classpath. Otherwise, 10 | * users face {@link java.lang.NoClassDefFoundError} for {@link TestWorkflowEnvironment}. 11 | */ 12 | public interface TestWorkflowEnvironmentAdapter { 13 | 14 | WorkflowClient getWorkflowClient(); 15 | 16 | WorkerFactory getWorkerFactory(); 17 | } 18 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | io.temporal.spring.boot.autoconfigure.MetricsScopeAutoConfiguration,\ 3 | io.temporal.spring.boot.autoconfigure.OpenTracingAutoConfiguration,\ 4 | io.temporal.spring.boot.autoconfigure.TestServerAutoConfiguration,\ 5 | io.temporal.spring.boot.autoconfigure.ServiceStubsAutoConfiguration,\ 6 | io.temporal.spring.boot.autoconfigure.RootNamespaceAutoConfiguration,\ 7 | io.temporal.spring.boot.autoconfigure.NonRootNamespaceAutoConfiguration 8 | 9 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | io.temporal.spring.boot.autoconfigure.MetricsScopeAutoConfiguration 2 | io.temporal.spring.boot.autoconfigure.OpenTracingAutoConfiguration 3 | io.temporal.spring.boot.autoconfigure.TestServerAutoConfiguration 4 | io.temporal.spring.boot.autoconfigure.ServiceStubsAutoConfiguration 5 | io.temporal.spring.boot.autoconfigure.RootNamespaceAutoConfiguration 6 | io.temporal.spring.boot.autoconfigure.NonRootNamespaceAutoConfiguration 7 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/bytaskqueue/TestActivity.java: -------------------------------------------------------------------------------- 1 | package io.temporal.spring.boot.autoconfigure.bytaskqueue; 2 | 3 | import io.temporal.activity.ActivityInterface; 4 | 5 | @ActivityInterface 6 | public interface TestActivity { 7 | String execute(String input); 8 | } 9 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/bytaskqueue/TestActivityImpl.java: -------------------------------------------------------------------------------- 1 | package io.temporal.spring.boot.autoconfigure.bytaskqueue; 2 | 3 | import io.temporal.spring.boot.ActivityImpl; 4 | import org.springframework.stereotype.Component; 5 | 6 | @Component("TestActivityImpl") 7 | @ActivityImpl(taskQueues = "${default-queue.name:UnitTest}") 8 | public class TestActivityImpl implements TestActivity { 9 | @Override 10 | public String execute(String input) { 11 | return input; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/bytaskqueue/TestNexusService.java: -------------------------------------------------------------------------------- 1 | package io.temporal.spring.boot.autoconfigure.bytaskqueue; 2 | 3 | import io.nexusrpc.Operation; 4 | import io.nexusrpc.Service; 5 | 6 | @Service 7 | public interface TestNexusService { 8 | @Operation 9 | String operation(String input); 10 | } 11 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/bytaskqueue/TestNexusServiceImpl.java: -------------------------------------------------------------------------------- 1 | package io.temporal.spring.boot.autoconfigure.bytaskqueue; 2 | 3 | import io.nexusrpc.handler.OperationHandler; 4 | import io.nexusrpc.handler.OperationImpl; 5 | import io.nexusrpc.handler.ServiceImpl; 6 | import io.temporal.spring.boot.NexusServiceImpl; 7 | import org.springframework.stereotype.Component; 8 | 9 | @Component("TestNexusServiceImpl") 10 | @NexusServiceImpl(taskQueues = "${default-queue.name:UnitTest}") 11 | @ServiceImpl(service = TestNexusService.class) 12 | public class TestNexusServiceImpl { 13 | @OperationImpl 14 | public OperationHandler operation() { 15 | // Implemented inline 16 | return OperationHandler.sync((ctx, details, name) -> "Hello, " + name + "!"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/bytaskqueue/TestWorkflow.java: -------------------------------------------------------------------------------- 1 | package io.temporal.spring.boot.autoconfigure.bytaskqueue; 2 | 3 | import io.temporal.workflow.WorkflowInterface; 4 | import io.temporal.workflow.WorkflowMethod; 5 | 6 | @WorkflowInterface 7 | public interface TestWorkflow { 8 | 9 | @WorkflowMethod(name = "testWorkflow1") 10 | String execute(String input); 11 | } 12 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/byworkername/OtherTestActivityImpl.java: -------------------------------------------------------------------------------- 1 | package io.temporal.spring.boot.autoconfigure.byworkername; 2 | 3 | import io.temporal.spring.boot.ActivityImpl; 4 | import org.springframework.context.annotation.Profile; 5 | import org.springframework.stereotype.Component; 6 | 7 | @Component("TestActivityImpl") 8 | @ActivityImpl(workers = "mainWorker") 9 | @Profile("auto-discovery-with-profile") 10 | public class OtherTestActivityImpl implements TestActivity { 11 | @Override 12 | public String execute(String input) { 13 | return "other workflow " + input; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/byworkername/TestActivity.java: -------------------------------------------------------------------------------- 1 | package io.temporal.spring.boot.autoconfigure.byworkername; 2 | 3 | import io.temporal.activity.ActivityInterface; 4 | 5 | @ActivityInterface 6 | public interface TestActivity { 7 | String execute(String input); 8 | } 9 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/byworkername/TestActivityImpl.java: -------------------------------------------------------------------------------- 1 | package io.temporal.spring.boot.autoconfigure.byworkername; 2 | 3 | import io.temporal.spring.boot.ActivityImpl; 4 | import org.springframework.context.annotation.Profile; 5 | import org.springframework.stereotype.Component; 6 | 7 | @Component("TestActivityImpl") 8 | @ActivityImpl(workers = "mainWorker") 9 | @Profile("!auto-discovery-with-profile") 10 | public class TestActivityImpl implements TestActivity { 11 | @Override 12 | public String execute(String input) { 13 | return input; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/byworkername/TestDynamicWorkflowImpl.java: -------------------------------------------------------------------------------- 1 | package io.temporal.spring.boot.autoconfigure.byworkername; 2 | 3 | import io.temporal.common.converter.EncodedValues; 4 | import io.temporal.spring.boot.WorkflowImpl; 5 | import io.temporal.workflow.DynamicWorkflow; 6 | 7 | @WorkflowImpl(workers = "mainWorker") 8 | public class TestDynamicWorkflowImpl implements DynamicWorkflow { 9 | @Override 10 | public Object execute(EncodedValues args) { 11 | return "hello from dynamic workflow"; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/byworkername/TestNexusService.java: -------------------------------------------------------------------------------- 1 | package io.temporal.spring.boot.autoconfigure.byworkername; 2 | 3 | import io.nexusrpc.Operation; 4 | import io.nexusrpc.Service; 5 | 6 | @Service 7 | public interface TestNexusService { 8 | @Operation 9 | String operation(String input); 10 | } 11 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/byworkername/TestNexusServiceImpl.java: -------------------------------------------------------------------------------- 1 | package io.temporal.spring.boot.autoconfigure.byworkername; 2 | 3 | import io.nexusrpc.handler.OperationHandler; 4 | import io.nexusrpc.handler.OperationImpl; 5 | import io.nexusrpc.handler.ServiceImpl; 6 | import io.temporal.spring.boot.NexusServiceImpl; 7 | import io.temporal.spring.boot.autoconfigure.bytaskqueue.TestNexusService; 8 | import org.springframework.stereotype.Component; 9 | 10 | @Component("TestNexusServiceImpl") 11 | @NexusServiceImpl(workers = "mainWorker") 12 | @ServiceImpl(service = TestNexusService.class) 13 | public class TestNexusServiceImpl { 14 | @OperationImpl 15 | public OperationHandler operation() { 16 | // Implemented inline 17 | return OperationHandler.sync((ctx, details, name) -> "Hello, " + name + "!"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/byworkername/TestWorkflow.java: -------------------------------------------------------------------------------- 1 | package io.temporal.spring.boot.autoconfigure.byworkername; 2 | 3 | import io.temporal.workflow.WorkflowInterface; 4 | import io.temporal.workflow.WorkflowMethod; 5 | 6 | @WorkflowInterface 7 | public interface TestWorkflow { 8 | 9 | @WorkflowMethod(name = "testWorkflow1") 10 | String execute(String input); 11 | } 12 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/workerversioning/TestWorkflow.java: -------------------------------------------------------------------------------- 1 | package io.temporal.spring.boot.autoconfigure.workerversioning; 2 | 3 | import io.temporal.workflow.WorkflowInterface; 4 | import io.temporal.workflow.WorkflowMethod; 5 | 6 | @WorkflowInterface 7 | public interface TestWorkflow { 8 | 9 | @WorkflowMethod(name = "testWorkflow1") 10 | String execute(String input); 11 | } 12 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/workerversioning/TestWorkflow2.java: -------------------------------------------------------------------------------- 1 | package io.temporal.spring.boot.autoconfigure.workerversioning; 2 | 3 | import io.temporal.workflow.WorkflowInterface; 4 | import io.temporal.workflow.WorkflowMethod; 5 | 6 | @WorkflowInterface 7 | public interface TestWorkflow2 { 8 | 9 | @WorkflowMethod(name = "testWorkflow2") 10 | String tw2(String input); 11 | } 12 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/test/java/io/temporal/spring/boot/autoconfigure/workerversioning/TestWorkflowImpl.java: -------------------------------------------------------------------------------- 1 | package io.temporal.spring.boot.autoconfigure.workerversioning; 2 | 3 | import io.temporal.common.VersioningBehavior; 4 | import io.temporal.spring.boot.WorkflowImpl; 5 | import io.temporal.workflow.WorkflowVersioningBehavior; 6 | import org.springframework.context.ConfigurableApplicationContext; 7 | 8 | @WorkflowImpl(workers = "mainWorker") 9 | public class TestWorkflowImpl implements TestWorkflow, TestWorkflow2 { 10 | 11 | // Test auto-wiring of the application context works, this is not indicative of a real-world use 12 | // case as the workflow implementation should be stateless. 13 | public TestWorkflowImpl(ConfigurableApplicationContext applicationContext) {} 14 | 15 | @Override 16 | public String execute(String input) { 17 | return input; 18 | } 19 | 20 | @Override 21 | @WorkflowVersioningBehavior(VersioningBehavior.AUTO_UPGRADE) 22 | public String tw2(String input) { 23 | return input; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/test/resources/application-custom-namespace.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2022 Temporal Technologies, Inc. All Rights Reserved. 3 | # 4 | # Copyright (C) 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 5 | # 6 | # Modifications copyright (C) 2017 Uber Technologies, Inc. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this material except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | spring.temporal: 22 | connection: 23 | target: local 24 | namespace: custom 25 | start-workers: false 26 | test-server: 27 | enabled: false 28 | 29 | 30 | -------------------------------------------------------------------------------- /temporal-spring-boot-autoconfigure/src/test/resources/pkcs12-key.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/temporalio/sdk-java/35386dae38bf40b7434e426258178b6fad4d5e68/temporal-spring-boot-autoconfigure/src/test/resources/pkcs12-key.pfx -------------------------------------------------------------------------------- /temporal-spring-boot-starter/build.gradle: -------------------------------------------------------------------------------- 1 | description = '''Spring Boot Starter for Temporal Java SDK''' 2 | 3 | dependencies { 4 | // This platform is the same defined in temporal-spring-boot-autoconfigure and it doesn't need to be here 5 | // for gradle, but it is needed for maven and maven pom. Looks like Maven doesn't transitively propagate BOMs. 6 | // https://github.com/temporalio/sdk-java/issues/1479 7 | api(platform("org.springframework.boot:spring-boot-dependencies:$springBootVersion")) 8 | implementation "org.springframework.boot:spring-boot-starter" 9 | 10 | api project(':temporal-spring-boot-autoconfigure') 11 | api project(':temporal-sdk') 12 | api project(':temporal-testing') 13 | } -------------------------------------------------------------------------------- /temporal-test-server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM gcr.io/distroless/base 2 | COPY temporal-test-server ./ 3 | EXPOSE 7233 4 | ENTRYPOINT ["./temporal-test-server", "7233"] 5 | -------------------------------------------------------------------------------- /temporal-test-server/src/main/java/io/temporal/internal/testservice/TestNexusEndpointStore.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.testservice; 2 | 3 | import io.temporal.api.nexus.v1.Endpoint; 4 | import io.temporal.api.nexus.v1.EndpointSpec; 5 | import java.io.Closeable; 6 | import java.util.List; 7 | 8 | public interface TestNexusEndpointStore extends Closeable { 9 | 10 | Endpoint createEndpoint(EndpointSpec spec); 11 | 12 | Endpoint updateEndpoint(String id, long version, EndpointSpec spec); 13 | 14 | void deleteEndpoint(String id, long version); 15 | 16 | Endpoint getEndpoint(String id); 17 | 18 | Endpoint getEndpointByName(String name); 19 | 20 | List listEndpoints(long pageSize, byte[] nextPageToken, String name); 21 | 22 | void validateEndpointSpec(EndpointSpec spec); 23 | 24 | @Override 25 | void close(); 26 | } 27 | -------------------------------------------------------------------------------- /temporal-test-server/src/main/java/io/temporal/internal/testservice/TestServiceServer.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.testservice; 2 | 3 | import io.temporal.testserver.TestServer; 4 | 5 | /** 6 | * @deprecated use {@link TestServer#main(String[])} with {@code --enable-time-skipping} to get the 7 | * behavior of this starter method 8 | */ 9 | @Deprecated 10 | public class TestServiceServer { 11 | 12 | public static void main(String[] args) { 13 | if (args.length != 1) { 14 | System.err.println("Usage: "); 15 | } 16 | Integer port = Integer.parseInt(args[0]); 17 | 18 | TestServer.createPortBoundServer(port, false); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /temporal-test-server/src/main/java/io/temporal/internal/testservice/TestVisibilityStore.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal.testservice; 2 | 3 | import io.temporal.api.common.v1.SearchAttributes; 4 | import io.temporal.api.enums.v1.IndexedValueType; 5 | import java.io.Closeable; 6 | import java.util.Map; 7 | import javax.annotation.Nonnull; 8 | 9 | public interface TestVisibilityStore extends Closeable { 10 | void addSearchAttribute(String name, IndexedValueType type); 11 | 12 | void removeSearchAttribute(String name); 13 | 14 | Map getRegisteredSearchAttributes(); 15 | 16 | SearchAttributes getSearchAttributesForExecution(ExecutionId executionId); 17 | 18 | SearchAttributes upsertSearchAttributesForExecution( 19 | ExecutionId executionId, @Nonnull SearchAttributes searchAttributes); 20 | 21 | void validateSearchAttributes(SearchAttributes searchAttributes); 22 | 23 | @Override 24 | void close(); 25 | } 26 | -------------------------------------------------------------------------------- /temporal-test-server/src/main/java/io/temporal/serviceclient/TestServiceStubs.java: -------------------------------------------------------------------------------- 1 | package io.temporal.serviceclient; 2 | 3 | import static io.temporal.internal.WorkflowThreadMarker.enforceNonWorkflowThread; 4 | 5 | import io.temporal.api.testservice.v1.TestServiceGrpc; 6 | import io.temporal.internal.WorkflowThreadMarker; 7 | 8 | public interface TestServiceStubs 9 | extends ServiceStubs< 10 | TestServiceGrpc.TestServiceBlockingStub, TestServiceGrpc.TestServiceFutureStub> { 11 | String HEALTH_CHECK_SERVICE_NAME = "temporal.api.testservice.v1.TestService"; 12 | 13 | static TestServiceStubs newServiceStubs(TestServiceStubsOptions options) { 14 | enforceNonWorkflowThread(); 15 | return WorkflowThreadMarker.protectFromWorkflowThread( 16 | new TestServiceStubsImpl(options), TestServiceStubs.class); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /temporal-test-server/src/main/proto/buf.yaml: -------------------------------------------------------------------------------- 1 | version: v1beta1 2 | build: 3 | roots: 4 | - . 5 | lint: 6 | ignore: 7 | - dependencies 8 | use: 9 | - DEFAULT 10 | breaking: 11 | ignore: 12 | use: 13 | - PACKAGE -------------------------------------------------------------------------------- /temporal-test-server/src/main/resources/META-INF/native-image/io.temporal/temporal-test-server/predefined-classes-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type":"agent-extracted", 4 | "classes":[ 5 | ] 6 | } 7 | ] 8 | -------------------------------------------------------------------------------- /temporal-test-server/src/main/resources/META-INF/native-image/io.temporal/temporal-test-server/serialization-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "types":[ 3 | { 4 | "name":"java.lang.Enum" 5 | }, 6 | { 7 | "name":"java.lang.Object[]" 8 | }, 9 | { 10 | "name":"java.util.HashSet" 11 | }, 12 | { 13 | "name":"java.util.LinkedHashSet" 14 | }, 15 | { 16 | "name":"java.util.concurrent.ArrayBlockingQueue" 17 | }, 18 | { 19 | "name":"java.util.concurrent.locks.AbstractOwnableSynchronizer" 20 | }, 21 | { 22 | "name":"java.util.concurrent.locks.AbstractQueuedSynchronizer" 23 | }, 24 | { 25 | "name":"java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject" 26 | }, 27 | { 28 | "name":"java.util.concurrent.locks.ReentrantLock" 29 | }, 30 | { 31 | "name":"java.util.concurrent.locks.ReentrantLock$NonfairSync" 32 | }, 33 | { 34 | "name":"java.util.concurrent.locks.ReentrantLock$Sync" 35 | } 36 | ], 37 | "lambdaCapturingTypes":[ 38 | ], 39 | "proxies":[ 40 | ] 41 | } -------------------------------------------------------------------------------- /temporal-test-server/src/test/java/io/temporal/testserver/TestServicesStarterAccessor.java: -------------------------------------------------------------------------------- 1 | package io.temporal.testserver; 2 | 3 | import io.temporal.internal.testservice.TestServicesStarter; 4 | 5 | public final class TestServicesStarterAccessor { 6 | public static TestServicesStarter getStarter(TestServer.InProcessTestServer inProcessTestServer) { 7 | return inProcessTestServer.getStarter(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /temporal-test-server/src/test/java/io/temporal/testserver/functional/common/TestActivities.java: -------------------------------------------------------------------------------- 1 | package io.temporal.testserver.functional.common; 2 | 3 | import io.temporal.activity.ActivityInterface; 4 | import io.temporal.activity.ActivityMethod; 5 | 6 | public class TestActivities { 7 | @ActivityInterface 8 | public interface ActivityReturnsString { 9 | @ActivityMethod 10 | String execute(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /temporal-test-server/src/test/java/io/temporal/testserver/functional/timeskipping/SleepingActivity.java: -------------------------------------------------------------------------------- 1 | package io.temporal.testserver.functional.timeskipping; 2 | 3 | import io.temporal.activity.ActivityInterface; 4 | import io.temporal.activity.ActivityMethod; 5 | 6 | @ActivityInterface 7 | public interface SleepingActivity { 8 | @ActivityMethod 9 | void sleep(); 10 | } 11 | -------------------------------------------------------------------------------- /temporal-testing/src/main/java/io/temporal/internal/Issue.java: -------------------------------------------------------------------------------- 1 | package io.temporal.internal; 2 | 3 | /** 4 | * Test annotated with {@link Issue} covers a specific problem or edge case and is usually crafted 5 | * carefully to hit the right conditions to reproduce the problem. Please specify a link to a ticket 6 | * that describes what this test intends to cover. 7 | */ 8 | public @interface Issue { 9 | /** 10 | * @return Link to a ticket that describes what this test is intended to cover. 11 | */ 12 | String value(); 13 | } 14 | -------------------------------------------------------------------------------- /temporal-testing/src/main/java/io/temporal/testing/ActivityRequestedAsyncCompletion.java: -------------------------------------------------------------------------------- 1 | package io.temporal.testing; 2 | 3 | /** 4 | * Exception thrown when an activity request to complete asynchronously in the {@link 5 | * TestActivityEnvironment}. Intended to be used in unit tests to assert an activity requested async 6 | * completion. 7 | */ 8 | public final class ActivityRequestedAsyncCompletion extends RuntimeException { 9 | private final String activityId; 10 | private final boolean manualCompletion; 11 | 12 | public ActivityRequestedAsyncCompletion(String activityId, boolean manualCompletion) { 13 | super("activity requested async completion"); 14 | this.activityId = activityId; 15 | this.manualCompletion = manualCompletion; 16 | } 17 | 18 | public String getActivityId() { 19 | return activityId; 20 | } 21 | 22 | public boolean isManualCompletion() { 23 | return manualCompletion; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /temporal-testing/src/main/java/io/temporal/testing/ReplayResults.java: -------------------------------------------------------------------------------- 1 | package io.temporal.testing; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.List; 6 | 7 | public class ReplayResults { 8 | 9 | public class ReplayError { 10 | public final String workflowId; 11 | public final Exception exception; 12 | 13 | public ReplayError(String workflowId, Exception exception) { 14 | this.workflowId = workflowId; 15 | this.exception = exception; 16 | } 17 | } 18 | 19 | private final List replayErrors; 20 | 21 | ReplayResults() { 22 | replayErrors = new ArrayList<>(); 23 | } 24 | 25 | public Collection allErrors() { 26 | return replayErrors; 27 | } 28 | 29 | public boolean hadAnyError() { 30 | return !allErrors().isEmpty(); 31 | } 32 | 33 | void addError(String workflowId, Exception err) { 34 | replayErrors.add(new ReplayError(workflowId, err)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /temporal-testing/src/main/java/io/temporal/testing/WorkflowInitialTime.java: -------------------------------------------------------------------------------- 1 | package io.temporal.testing; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * JUnit5 only 10 | * 11 | *

Overrides the initial timestamp used by the {@link TestWorkflowExtension} 12 | */ 13 | @Retention(RetentionPolicy.RUNTIME) 14 | @Target(ElementType.METHOD) 15 | public @interface WorkflowInitialTime { 16 | 17 | String value(); 18 | } 19 | -------------------------------------------------------------------------------- /temporal-testing/src/test/java/io/temporal/testing/TestWorkflowEnvironmentCreationTest.java: -------------------------------------------------------------------------------- 1 | package io.temporal.testing; 2 | 3 | import io.temporal.client.WorkflowClientOptions; 4 | import io.temporal.worker.WorkerFactoryOptions; 5 | import org.junit.Test; 6 | 7 | public class TestWorkflowEnvironmentCreationTest { 8 | 9 | @Test 10 | public void testCreateWithValidatedDefaultOptions() { 11 | WorkflowClientOptions workflowClientOptions = 12 | WorkflowClientOptions.newBuilder().validateAndBuildWithDefaults(); 13 | WorkerFactoryOptions workerFactoryOptions = 14 | WorkerFactoryOptions.newBuilder().validateAndBuildWithDefaults(); 15 | TestWorkflowEnvironment testEnv = 16 | TestWorkflowEnvironment.newInstance( 17 | TestEnvironmentOptions.newBuilder() 18 | .setWorkflowClientOptions(workflowClientOptions) 19 | .setWorkerFactoryOptions(workerFactoryOptions) 20 | .validateAndBuildWithDefaults()); 21 | testEnv.close(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /temporal-testing/src/test/java/io/temporal/testing/TestWorkflowExtensionTimeSkippingTest.java: -------------------------------------------------------------------------------- 1 | package io.temporal.testing; 2 | 3 | import static org.junit.Assert.assertFalse; 4 | 5 | import org.junit.Test; 6 | 7 | public class TestWorkflowExtensionTimeSkippingTest { 8 | @Test 9 | public void testCheckNoTimeSkipping() { 10 | TestWorkflowExtension testWorkflow = 11 | TestWorkflowExtension.newBuilder().setUseTimeskipping(false).build(); 12 | 13 | assertFalse( 14 | "We disabled the time skipping on the extension, so the TestEnvironmentOptions should have it off too", 15 | testWorkflow.createTestEnvOptions(System.currentTimeMillis()).isUseTimeskipping()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /temporal-testing/src/test/java/io/temporal/testing/TestWorkflowRuleTimeSkippingTest.java: -------------------------------------------------------------------------------- 1 | package io.temporal.testing; 2 | 3 | import static org.junit.Assert.assertFalse; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import org.junit.Test; 7 | 8 | public class TestWorkflowRuleTimeSkippingTest { 9 | 10 | @Test 11 | public void testWorkflowRuleTimeSkipping() { 12 | TestWorkflowRule defaultTestWorkflowRule = TestWorkflowRule.newBuilder().build(); 13 | TestWorkflowRule noTimeSkippingWorkflowRule = 14 | TestWorkflowRule.newBuilder().setUseTimeskipping(false).build(); 15 | 16 | assertTrue( 17 | "By default time skipping should be on", 18 | defaultTestWorkflowRule 19 | .createTestEnvOptions(System.currentTimeMillis()) 20 | .isUseTimeskipping()); 21 | assertFalse( 22 | "We disabled the time skipping on the rule, so the TestEnvironmentOptions should have it off too", 23 | noTimeSkippingWorkflowRule 24 | .createTestEnvOptions(System.currentTimeMillis()) 25 | .isUseTimeskipping()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /whitesource.config: -------------------------------------------------------------------------------- 1 | gradle.ignoredConfigurations=.*test.* 2 | --------------------------------------------------------------------------------