Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ rootProject.name='temporal-java-sdk'
include 'temporal-serviceclient'
include 'temporal-sdk'
include 'temporal-testing'
include 'temporal-test-server'
include 'temporal-opentracing'
include 'temporal-kotlin'
include 'temporal-kotlin'
File renamed without changes.
18 changes: 18 additions & 0 deletions temporal-test-server/LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Temporal Java SDK

Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved

Copyright (c) 2017 Uber Technologies, Inc. All Rights Reserved

AWS Simple Workflow Flow Library
Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
46 changes: 46 additions & 0 deletions temporal-test-server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Temporal Test Workflow Server

This module includes an in-memory Temporal testing service implementation. It is
not intended to be used directly but rather by programming against the
`TestWorkflowEnvironment` interface in the `temporal-testing` module.

In addition to being consumed as a library by JVM-based languages, this module
can be built into a standalone executable and run as an independent process.

## Usage

Do not depend on this module directly, see the instructions in
[temporal-testing](../temporal-testing/README.md).

## In-memory Temporal testing service

This service allows to run a test-only in-memory implementation of Temporal server API.

## To build a test server using GraalVM native-image

From the root of the java-sdk repo:
```
./gradlew :temporal-test-server:build
```
This will give you a native executable `build/graal/temporal-test-server`. The
executable requires a single argument: the port number on which it should
listen.

## To build a test server docker image

From the root of the java-sdk repo:
```
./gradlew :temporal-test-server:docker
```

This will result in a local image being built:
`temporalio/temporal-test-server`.

## GraalVM native-image configuration

The GraalVM native-image compiler uses the native-image.properties file and the
referenced JSON files during compilation. The JSON files are generated by
running the test server java code in a JVM configured with the [GraalVM tracing
agent](https://www.graalvm.org/reference-manual/native-image/Agent/) configured,
e.g. with the flag
`-agentlib:native-image-agent=config-output-dir=temporal-test-server/src/main/resources/META-INF/native-image/io.temporal/temporal-test-server`.
58 changes: 58 additions & 0 deletions temporal-test-server/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
plugins {
id 'application'
id 'com.palantir.graal' version '0.10.0'
id 'com.palantir.docker' version '0.32.0'
}

description = '''Temporal test workflow server'''

dependencies {
api project(':temporal-sdk')
implementation("io.grpc:grpc-core:$grpcVersion")
implementation "com.google.guava:guava:$guavaVersion"
implementation group: 'com.cronutils', name: 'cron-utils', version: '9.1.6'
}

application {
mainClassName = 'io.temporal.internal.testservice.TestServiceServer'
}

jar {
manifest {
attributes("Main-Class": application.mainClassName)
}
}

graal {
outputName "temporal-test-server"
mainClass application.mainClassName
javaVersion '17'
graalVersion '21.3.0'

// Ignore type resolution errors at build-time
option "--allow-incomplete-classpath"

// Don't fallback to running a JVM
option "--no-fallback"

// Signal handling so that ^C actually stops the process
option "--install-exit-handlers"

// If we're on linux, static link everything but libc. Otherwise link
// everything dynamically (note the '-' rather than '+' in fromt of
// StaticExecutable)
option isLinux()
? "-H:+StaticExecutableWithDynamicLibC"
: "-H:-StaticExecutable"
}

docker {
name "temporalio/temporal-test-server:${version}"
files tasks.nativeImage.outputs
}

def isLinux() {
return System.properties['os.name'].toLowerCase().contains('linux')
}

tasks.build.dependsOn('nativeImage')
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#
# Copyright (C) 2020 Temporal Technologies, Inc. All Rights Reserved.
#
# Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Modifications copyright (C) 2017 Uber Technologies, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You may not
# use this file except in compliance with the License. A copy of the License is
# located at
#
# http://aws.amazon.com/apache2.0
#
# or in the "license" file accompanying this file. This file is distributed on
# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied. See the License for the specific language governing
# permissions and limitations under the License.
#

Args = --initialize-at-build-time=org.slf4j.impl.StaticLoggerBinder \
--initialize-at-build-time=org.slf4j.LoggerFactory \
--initialize-at-run-time=io.grpc.netty.shaded.io.netty.channel.epoll \
--initialize-at-run-time=io.grpc.netty.shaded.io.netty.channel.unix \
--initialize-at-run-time=io.grpc.netty.shaded.io.netty.util.internal.logging.Log4JLogger \
--initialize-at-run-time=io.grpc.netty.shaded.io.netty.internal.tcnative \
--initialize-at-run-time=io.grpc.netty.shaded.io.netty.handler.ssl \
-H:DynamicProxyConfigurationResources=${.}/proxy-config.json \
-H:JNIConfigurationResources=${.}/jni-config.json \
-H:ReflectionConfigurationResources=${.}/reflect-config.json \
-H:ResourceConfigurationResources=${.}/resource-config.json \
-H:SerializationConfigurationResources=${.}/serialization-config.json

30 changes: 2 additions & 28 deletions temporal-testing/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Temporal Workflow Java SDK Testing module

This module includes an in-memory Temporal testing service implementation,
supporting classes for unit tests and extensions for testing framework
This module includes Temporal testing utilities for unit tests and extensions
for testing frameworks.

## Usage

Expand Down Expand Up @@ -29,11 +29,6 @@ testImplementation("io.temporal:temporal-testing:N.N.N") {
}
```

## In-memory Temporal testing service

This service allows to run a test-only in-memory implementation of Temporal server API.
The entry point is `io.temporal.testing.TestWorkflowEnvironment`

## JUnit4 and Junit5 extensions

For JUnit4 see `io.temporal.testing.TestWorkflowRule` for testing of workflows
Expand All @@ -45,24 +40,3 @@ and `io.temporal.testing.TestActivityExtension` for isolated testing of activiti
See `io.temporal.testing.TestActivityEnvironment` that provides an easy way for isolated testing of
activity implementations without needing to provide workflows calling the activities, triggering the workflows
and bootstrapping a Temporal server or In-memory testing service.

## To build a test service using GraalVM native-image

From the root of the java-sdk repo:
```
./gradlew :temporal-testing:copyDependencies
```
```
native-image -jar "./temporal-testing/build/libs/temporal-testing-1.6.0-SNAPSHOT.jar" test-server --class-path "./temporal-testing/build/dependencies/*" \
--allow-incomplete-classpath --no-fallback
```
Additional `native-image` flags to consider:
1. `--static` to build a fully static binary. _[Not supported](https://developer.apple.com/library/archive/qa/qa1118/_index.html) for MacOS._

### Notes on installing GraalVM
1. Install [prerequisites](https://www.graalvm.org/reference-manual/native-image/#prerequisites)
2. Install [sdkman](https://sdkman.io/install)
3. `sdk install java 21.2.0.r11-grl` GraalVM on JDK 11
4. `sdk use java 21.2.0.r11-grl`
5. `gu install native-image`, where `gu` is GraalVM Updater.
6. After these steps, if sdkman is configured properly, you can switch to GraalVM JDK any time in the shell by using `sdk use java 21.2.0.r11-grl` which will make `native-image` tool also available
54 changes: 1 addition & 53 deletions temporal-testing/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
plugins {
id 'application'
id 'com.palantir.graal' version '0.10.0'
id 'com.palantir.docker' version '0.32.0'
}

description = '''Temporal Workflow Java SDK testing'''
Expand All @@ -17,11 +15,7 @@ java {

dependencies {
api project(':temporal-sdk')

implementation("io.grpc:grpc-core:$grpcVersion")
implementation "com.google.guava:guava:$guavaVersion"
implementation group: 'com.cronutils', name: 'cron-utils', version: '9.1.6'
implementation "com.jayway.jsonpath:json-path:$jsonPathVersion"
api project(':temporal-test-server')

junit4Api 'junit:junit:4.13.2'

Expand All @@ -32,52 +26,6 @@ dependencies {
testRuntimeOnly group: 'ch.qos.logback', name: 'logback-classic', version: "${logbackVersion}"
}

application {
mainClassName = 'io.temporal.internal.testservice.TestServiceServer'
}

task copyDependencies(type: Copy) {
from configurations.runtimeClasspath
into 'build/dependencies'
}

jar {
manifest {
attributes("Main-Class": application.mainClassName)
}
}

task testServiceServer(type: CreateStartScripts) {
mainClassName = 'io.temporal.internal.testservice.TestServiceServer'
applicationName = 'test-service-server'
outputDir = new File(project.buildDir, 'dist')
classpath = startScripts.classpath
dependsOn 'sourcesJar'
}

graal {
outputName "temporal-test-server"
mainClass application.mainClassName
javaVersion '17'
graalVersion '21.3.0'
option "--class-path=${buildDir}/dependencies/*"
option "--allow-incomplete-classpath"
option "--no-fallback"
option "--install-exit-handlers"
option "-H:+StaticExecutableWithDynamicLibC"
}

docker {
name "temporalio/temporal-test-server:${version}"
files tasks.nativeImage.outputs
}

// Run: ./gradlew installDist :temporal-testing:testServiceServer
applicationDistribution.into('bin') {
from(testServiceServer)
fileMode = 0755
}

test {
useJUnitPlatform()
}