Skip to content

Commit 0661997

Browse files
authored
Merge pull request #34 from cicoyle/feat-cross-app-wf
Feat cross app wf + use Java 11, not Java 8
2 parents 688b059 + d6d3f47 commit 0661997

File tree

22 files changed

+631
-230
lines changed

22 files changed

+631
-230
lines changed

.github/workflows/build-validation.yml

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,6 @@ jobs:
2525
uses: actions/setup-java@v2
2626
with:
2727
java-version: '11'
28-
distribution: 'microsoft'
29-
30-
- name: set JDK_11 environment variable test compiling and running
31-
env:
32-
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
33-
run: echo ::set-env name=JDK_11::$(echo $JAVA_HOME)
34-
35-
- name: Set up JDK 8
36-
uses: actions/setup-java@v2
37-
with:
38-
java-version: '8'
3928
distribution: 'temurin'
4029

4130
- name: Setup Gradle
@@ -57,7 +46,6 @@ jobs:
5746

5847
- name: Run Unit Tests with Gradle
5948
run: |
60-
export JAVA_HOME=$JDK_11
6149
./gradlew clean test || echo "UNIT_TEST_FAILED=true" >> $GITHUB_ENV
6250
continue-on-error: true
6351

CONTRIBUTING.md

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,52 @@
1+
Verify Compilation:
2+
```shell
3+
./gradlew compileJava
4+
```
5+
16
Build & test:
27

38
```shell
49
./gradlew build
5-
```
10+
```
11+
12+
## Verify Build Components
13+
14+
To ensure all build components work correctly after making changes:
15+
16+
```shell
17+
# Build without tests
18+
./gradlew build -x test
19+
20+
# Run unit tests
21+
./gradlew test
22+
23+
# Run SpotBugs
24+
./gradlew spotbugsMain spotbugsTest
25+
```
26+
27+
## Updating Protobuf Definitions
28+
29+
When updating the protobuf definitions in `internal/durabletask-protobuf/protos/orchestrator_service.proto`:
30+
31+
1. Manually copy the updated protobuf file from dapr/durabletask-protobuf
32+
2. Update the commit hash in `internal/durabletask-protobuf/PROTO_SOURCE_COMMIT_HASH` to reflect the new commit
33+
3. Regenerate the Java classes from the protobuf definitions:
34+
35+
```shell
36+
./gradlew generateProto
37+
```
38+
39+
## Test locally from dapr/java-sdk
40+
41+
```shell
42+
./gradlew publishToMavenLocal
43+
```
44+
45+
or simply `./gradlew build publishToMavenLocal`
46+
47+
Check if it was released locally with:
48+
```shell
49+
ls ~/.m2/repository/io/dapr/durabletask-client/
50+
```
51+
52+
Then update the durabletask-client in the java-sdk pom.xml file to the newest version you released locally.

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
# Durable Task Client SDK for Java
22

3-
[![Build](https://github.com/microsoft/durabletask-java/actions/workflows/build-validation.yml/badge.svg)](https://github.com/microsoft/durabletask-java/actions/workflows/build-validation.yml)
3+
[![Build](https://github.com/dapr/durabletask-java/actions/workflows/build-validation.yml/badge.svg)](https://github.com/dapr/durabletask-java/actions/workflows/build-validation.yml)
44
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
55

66
This repo contains the Java SDK for the Durable Task Framework as well as classes and annotations to support running [Azure Durable Functions](https://docs.microsoft.com/azure/azure-functions/durable/durable-functions-overview?tabs=java) for Java. With this SDK, you can define, schedule, and manage durable orchestrations using ordinary Java code.
77

8+
## Requirements
9+
10+
- **Java 11 or higher** - This SDK requires Java 11 as the minimum version
11+
- **Gradle** - The project uses [Gradle 7.6.4](gradle/wrapper/gradle-wrapper.properties)
12+
813
### Simple, fault-tolerant sequences
914

1015
```java
@@ -78,8 +83,7 @@ The following packages are produced from this repo.
7883

7984
| Package | Latest version |
8085
| - | - |
81-
| Durable Task - Client | [![Maven Central](https://img.shields.io/maven-central/v/com.microsoft/durabletask-client?label=durabletask-client)](https://mvnrepository.com/artifact/com.microsoft/durabletask-client/1.0.0) |
82-
| Durable Task - Azure Functions | [![Maven Central](https://img.shields.io/maven-central/v/com.microsoft/durabletask-azure-functions?label=durabletask-azure-functions)](https://mvnrepository.com/artifact/com.microsoft/durabletask-azure-functions/1.0.1) |
86+
| Durable Task - Client | [![Maven Central](https://img.shields.io/maven-central/v/io.dapr/durabletask-client?label=durabletask-client)](https://mvnrepository.com/artifact/io.dapr/durabletask-client/1.5.7) |
8387

8488
## Getting started with Azure Functions
8589

azurefunctions/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ In this article, you follow steps to create and run a simple azure durable funct
66

77
The following are the requirements for you local environment:
88

9-
- The Java Developer Kit, version 8 or 11, is required. Between the two, JDK 11 is recommended.
9+
- The Java Developer Kit, version 11 or higher, is required.
1010
- The `JAVA_HOME` environment variable must be set to the install location of the correct version of the JDK.
1111
- [Apache Maven](https://maven.apache.org/), version 3.0 or above for azure function app creation, is required for using automatic project creation tools.
1212
- If Maven isn't your preferred development tool, check out our similar tutorials to [create a function app](https://docs.microsoft.com/en-us/azure/azure-functions/create-first-function-cli-java?tabs=bash%2Cazure-cli%2Cbrowser). This README also contains instructions for [Gradle](https://gradle.org/).

client/build.gradle

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,20 @@ plugins {
1111
}
1212

1313
group 'io.dapr'
14-
version = '1.5.7'
14+
version = '1.5.8'
1515
archivesBaseName = 'durabletask-client'
1616

1717
def grpcVersion = '1.69.0'
1818
def protocVersion = '3.25.5'
1919
def jacksonVersion = '2.15.3'
20-
// When build on local, you need to set this value to your local jdk11 directory.
21-
// Java11 is used to compile and run all the tests.
22-
// Example for Windows: C:/Program Files/Java/openjdk-11.0.12_7/
23-
def PATH_TO_TEST_JAVA_RUNTIME = System.env.JDK_11 ?: System.getProperty("java.home")
20+
// Java 11 is now the minimum required version for both compilation and testing
2421

2522
dependencies {
2623

2724
// https://github.com/grpc/grpc-java#download
2825
implementation "io.grpc:grpc-protobuf:${grpcVersion}"
2926
implementation "io.grpc:grpc-stub:${grpcVersion}"
27+
implementation 'com.google.protobuf:protobuf-java:3.25.5'
3028
runtimeOnly "io.grpc:grpc-netty-shaded:${grpcVersion}"
3129

3230
compileOnly "org.apache.tomcat:annotations-api:6.0.53"
@@ -44,49 +42,59 @@ dependencies {
4442

4543
// Netty dependencies for TLS
4644
implementation "io.grpc:grpc-netty-shaded:${grpcVersion}"
47-
implementation "io.netty:netty-handler:4.1.94.Final"
45+
implementation 'io.netty:netty-handler:4.1.119.Final'
4846
implementation "io.netty:netty-tcnative-boringssl-static:2.0.59.Final"
4947

5048
// Add Netty dependencies to test classpath
5149
testImplementation "io.grpc:grpc-netty-shaded:${grpcVersion}"
52-
testImplementation "io.netty:netty-handler:4.1.94.Final"
50+
testImplementation 'io.netty:netty-handler:4.1.119.Final'
5351
testImplementation "io.netty:netty-tcnative-boringssl-static:2.0.59.Final"
5452

5553
testImplementation 'org.bouncycastle:bcprov-jdk15on:1.70'
5654
testImplementation 'org.bouncycastle:bcpkix-jdk15on:1.70'
5755
}
5856

5957
compileJava {
60-
sourceCompatibility = JavaVersion.VERSION_1_8
61-
targetCompatibility = JavaVersion.VERSION_1_8
58+
sourceCompatibility = JavaVersion.VERSION_11
59+
targetCompatibility = JavaVersion.VERSION_11
6260
}
6361
compileTestJava {
6462
sourceCompatibility = JavaVersion.VERSION_11
6563
targetCompatibility = JavaVersion.VERSION_11
66-
options.fork = true
67-
options.forkOptions.executable = "${PATH_TO_TEST_JAVA_RUNTIME}/bin/javac"
6864
}
6965

7066
task downloadProtoFiles {
7167
ext.branch = project.hasProperty('protoBranch') ? project.protoBranch : 'main'
7268

7369
doLast {
7470
def protoDir = file("${rootProject.projectDir}/internal/durabletask-protobuf/protos")
71+
def protoFile = new File(protoDir, 'orchestrator_service.proto')
72+
def commitHashFile = new File("${rootProject.projectDir}/internal/durabletask-protobuf/PROTO_SOURCE_COMMIT_HASH")
7573
protoDir.mkdirs()
7674

7775
// Download the proto file
7876
new URL("https://raw.githubusercontent.com/dapr/durabletask-protobuf/${ext.branch}/protos/orchestrator_service.proto")
7977
.withInputStream { i ->
80-
new File(protoDir, 'orchestrator_service.proto').withOutputStream { it << i }
78+
protoFile.withOutputStream { it << i }
8179
}
82-
83-
// Get and save the commit hash
84-
def commitHashFile = new File("${rootProject.projectDir}/internal/durabletask-protobuf/PROTO_SOURCE_COMMIT_HASH")
85-
def commitApiUrl = new URL("https://api.github.com/repos/dapr/durabletask-protobuf/commits?path=protos/orchestrator_service.proto&sha=${ext.branch}&per_page=1")
86-
def connection = commitApiUrl.openConnection()
87-
connection.setRequestProperty('Accept', 'application/vnd.github.v3+json')
88-
def commitHash = new groovy.json.JsonSlurper().parse(connection.inputStream)[0].sha
89-
commitHashFile.text = commitHash
80+
81+
try {
82+
def commitApiUrl = new URL("https://api.github.com/repos/dapr/durabletask-protobuf/commits?path=protos/orchestrator_service.proto&sha=${ext.branch}&per_page=1")
83+
def connection = commitApiUrl.openConnection()
84+
connection.setRequestProperty('Accept', 'application/vnd.github.v3+json')
85+
connection.setRequestProperty('User-Agent', 'durabletask-java-build')
86+
87+
// Add GitHub token if available (automatically provided in GitHub Actions)
88+
if (System.env.GITHUB_TOKEN) {
89+
connection.setRequestProperty('Authorization', "token ${System.env.GITHUB_TOKEN}")
90+
}
91+
92+
def commitHash = new groovy.json.JsonSlurper().parse(connection.inputStream)[0].sha
93+
commitHashFile.text = commitHash
94+
logger.info("Successfully updated proto commit hash: ${commitHash}")
95+
} catch (Exception e) {
96+
logger.error("Failed to fetch commit hash from GitHub API: ${e.message}")
97+
}
9098
}
9199
}
92100

@@ -115,10 +123,6 @@ sourceSets {
115123
}
116124
}
117125

118-
tasks.withType(Test) {
119-
executable = new File("${PATH_TO_TEST_JAVA_RUNTIME}", 'bin/java')
120-
}
121-
122126
test {
123127
useJUnitPlatform {
124128
// Skip tests tagged as "integration" since those are slower
@@ -208,6 +212,10 @@ java {
208212
withJavadocJar()
209213
}
210214

215+
tasks.named('sourcesJar').configure {
216+
dependsOn tasks.named('generateProto')
217+
}
218+
211219
spotbugs {
212220
toolVersion = '4.9.2'
213221
effort = 'max'

client/src/main/java/io/dapr/durabletask/DurableTaskGrpcWorker.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public final class DurableTaskGrpcWorker implements AutoCloseable {
3636
private final DataConverter dataConverter;
3737
private final Duration maximumTimerInterval;
3838
private final ExecutorService workerPool;
39+
private final String appId; // App ID for cross-app routing
3940

4041
private final TaskHubSidecarServiceBlockingStub sidecarClient;
4142
private final boolean isExecutorServiceManaged;
@@ -45,6 +46,7 @@ public final class DurableTaskGrpcWorker implements AutoCloseable {
4546
DurableTaskGrpcWorker(DurableTaskGrpcWorkerBuilder builder) {
4647
this.orchestrationFactories.putAll(builder.orchestrationFactories);
4748
this.activityFactories.putAll(builder.activityFactories);
49+
this.appId = builder.appId;
4850

4951
Channel sidecarGrpcChannel;
5052
if (builder.channel != null) {
@@ -128,7 +130,8 @@ public void startAndBlock() {
128130
this.orchestrationFactories,
129131
this.dataConverter,
130132
this.maximumTimerInterval,
131-
logger);
133+
logger,
134+
this.appId);
132135
TaskActivityExecutor taskActivityExecutor = new TaskActivityExecutor(
133136
this.activityFactories,
134137
this.dataConverter,
@@ -143,6 +146,9 @@ public void startAndBlock() {
143146
RequestCase requestType = workItem.getRequestCase();
144147
if (requestType == RequestCase.ORCHESTRATORREQUEST) {
145148
OrchestratorRequest orchestratorRequest = workItem.getOrchestratorRequest();
149+
logger.log(Level.FINEST,
150+
String.format("Processing orchestrator request for instance: {0}",
151+
orchestratorRequest.getInstanceId()));
146152

147153
// TODO: Error handling
148154
this.workerPool.submit(() -> {
@@ -159,6 +165,9 @@ public void startAndBlock() {
159165

160166
try {
161167
this.sidecarClient.completeOrchestratorTask(response);
168+
logger.log(Level.FINEST,
169+
"Completed orchestrator request for instance: {0}",
170+
orchestratorRequest.getInstanceId());
162171
} catch (StatusRuntimeException e) {
163172
if (e.getStatus().getCode() == Status.Code.UNAVAILABLE) {
164173
logger.log(Level.WARNING,
@@ -177,7 +186,12 @@ public void startAndBlock() {
177186
});
178187
} else if (requestType == RequestCase.ACTIVITYREQUEST) {
179188
ActivityRequest activityRequest = workItem.getActivityRequest();
189+
logger.log(Level.FINEST,
190+
String.format("Processing activity request: %s for instance: %s}",
191+
activityRequest.getName(),
192+
activityRequest.getOrchestrationInstance().getInstanceId()));
180193

194+
// TODO: Error handling
181195
this.workerPool.submit(() -> {
182196
String output = null;
183197
TaskFailureDetails failureDetails = null;
@@ -228,7 +242,8 @@ public void startAndBlock() {
228242
} else if (requestType == RequestCase.HEALTHPING) {
229243
// No-op
230244
} else {
231-
logger.log(Level.WARNING, "Received and dropped an unknown '{0}' work-item from the sidecar.",
245+
logger.log(Level.WARNING,
246+
"Received and dropped an unknown '{0}' work-item from the sidecar.",
232247
requestType);
233248
}
234249
}

0 commit comments

Comments
 (0)