Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
51d210f
Add gradle task to update submodule and update proto to latest version
YunchuWang Jan 23, 2025
8660f1b
bump build pipeline github action version to non deprecated version
YunchuWang Jan 23, 2025
8a54ce4
initial dts support changes
YunchuWang Jan 23, 2025
f951428
placeholder
YunchuWang Jan 23, 2025
12e9e50
ignore
YunchuWang Jan 23, 2025
3b09d59
update
YunchuWang Jan 23, 2025
32eca1e
remove
YunchuWang Jan 23, 2025
ea2e181
update
YunchuWang Jan 23, 2025
e025538
update
YunchuWang Jan 23, 2025
6ea3a65
update
YunchuWang Jan 23, 2025
2270ed2
signing is disabled, should not exclude as there is no sign
YunchuWang Jan 23, 2025
9a02b23
save
YunchuWang Jan 29, 2025
8fb193f
feedback changes
YunchuWang Jan 29, 2025
a51ba86
delete legacy lib/java
YunchuWang Jan 29, 2025
7241e34
create skeleton project for pkg "com.microsoft.durabletask-azuremanaged"
YunchuWang Jan 29, 2025
8688320
split pkg in progress
YunchuWang Mar 14, 2025
628c093
move out
YunchuWang Mar 18, 2025
a7e8d19
progress
YunchuWang Mar 18, 2025
ab89785
p
YunchuWang Mar 18, 2025
6fc0748
progress
YunchuWang Mar 18, 2025
e3406d7
progress
YunchuWang Mar 18, 2025
110306e
fix
YunchuWang Mar 18, 2025
b7a88af
p
YunchuWang Mar 18, 2025
1b7fe1c
save
YunchuWang Mar 19, 2025
b74d699
save
YunchuWang Mar 19, 2025
f6611af
save
YunchuWang Mar 19, 2025
03df094
save
YunchuWang Mar 19, 2025
3cd3598
clientoptions done
YunchuWang Mar 19, 2025
357ecdd
client ext
YunchuWang Mar 19, 2025
df4a0e4
client refactored
YunchuWang Mar 19, 2025
0f79297
worker done
YunchuWang Mar 19, 2025
c7eb4f1
sample update
YunchuWang Mar 19, 2025
aa94d9c
fix
YunchuWang Mar 19, 2025
02f92ea
save
YunchuWang Mar 19, 2025
2b9d8eb
fix
YunchuWang Mar 19, 2025
3eca075
cleanup
YunchuWang Mar 19, 2025
6e9a6e8
cleanup
YunchuWang Mar 19, 2025
2f2a359
Merge branch 'main' into wangbill/update-proto
YunchuWang Mar 20, 2025
41ef360
Merge branch 'main' into wangbill/update-proto
YunchuWang Mar 20, 2025
d9e20ec
unit tests
YunchuWang Mar 20, 2025
f59af6b
Update Gradle build command to include stacktrace option for better d…
YunchuWang Mar 20, 2025
f7c5376
cleanup
YunchuWang Mar 20, 2025
538033c
Enhance build validation workflow to handle build failures by uploadi…
YunchuWang Mar 20, 2025
bb1fbb1
Update PATH_TO_TEST_JAVA_RUNTIME in build.gradle files to use environ…
YunchuWang Mar 21, 2025
637863c
Revert "Update PATH_TO_TEST_JAVA_RUNTIME in build.gradle files to use…
YunchuWang Mar 21, 2025
8d530cb
separate build and unit tests
YunchuWang Mar 21, 2025
5f3ebfb
use jdk11 for unit tests
YunchuWang Mar 21, 2025
02ec66d
update sample
YunchuWang Mar 21, 2025
f23edcc
clean up
YunchuWang Mar 21, 2025
299ab73
rename azuremanaged module names to avoid colliding module names name…
YunchuWang Mar 21, 2025
8cf6cdb
update azure managed to one package
YunchuWang Mar 21, 2025
1bebf5a
conn str support
YunchuWang Mar 23, 2025
98cf7eb
changelog
YunchuWang Mar 23, 2025
8705055
Add support for Visual Studio Code and Interactive Browser authentica…
YunchuWang Mar 24, 2025
ad72eca
Add support for IntelliJ authentication type in DurableTaskSchedulerC…
YunchuWang Mar 24, 2025
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
20 changes: 19 additions & 1 deletion .github/workflows/build-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,25 @@ jobs:
uses: gradle/gradle-build-action@v2

- name: Build with Gradle
run: ./gradlew build
run: ./gradlew build -x test

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

- name: Upload test reports if tests failed
if: env.UNIT_TEST_FAILED == 'true'
uses: actions/upload-artifact@v4
with:
name: Unit Test Reports
path: '**/build/reports/tests/test'
if-no-files-found: ignore # Prevents errors if no reports exist

- name: Fail the job if unit tests failed
if: env.UNIT_TEST_FAILED == 'true'
run: exit 1

# TODO: Move the sidecar into a central image repository
- name: Initialize Durable Task Sidecar
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ build/
.project
.settings
.classpath
repo/
repo/

# Ignore sample application properties or any other properties files used for sample
samples/src/main/resources/*.properties
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
## placeholder
* DTS Support ([#201](https://github.com/microsoft/durabletask-java/pull/201))
* Add automatic proto file download and commit hash tracking during build ([#207](https://github.com/microsoft/durabletask-java/pull/207))
* Fix infinite loop when use continueasnew after wait external event ([#183](https://github.com/microsoft/durabletask-java/pull/183))
* Fix the issue "Deserialize Exception got swallowed when use anyOf with external event." ([#185](https://github.com/microsoft/durabletask-java/pull/185))
Expand Down
116 changes: 116 additions & 0 deletions azuremanaged/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* This build file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java project to get you started.
* For more details take a look at the Java Quickstart chapter in the Gradle
* user guide available at https://docs.gradle.org/4.4.1/userguide/tutorial_java_projects.html
*/

plugins {
id 'java'
id 'com.google.protobuf' version '0.8.16'
id 'idea'
id 'maven-publish'
id 'signing'
}

archivesBaseName = 'durabletask-azuremanaged'
group 'com.microsoft'
version = '1.5.0-preview.1'

def grpcVersion = '1.59.0'
def azureCoreVersion = '1.45.0'
def azureIdentityVersion = '1.11.1'
// When build on local, you need to set this value to your local jdk11 directory.
// Java11 is used to compile and run all the tests.
def PATH_TO_TEST_JAVA_RUNTIME = System.env.JDK_11 ?: System.getProperty("java.home")

repositories {
mavenCentral()
}

dependencies {
implementation project(':client')
implementation "io.grpc:grpc-protobuf:${grpcVersion}"
implementation "io.grpc:grpc-stub:${grpcVersion}"
runtimeOnly "io.grpc:grpc-netty-shaded:${grpcVersion}"

implementation "com.azure:azure-core:${azureCoreVersion}"
implementation "com.azure:azure-identity:${azureIdentityVersion}"

// Test dependencies
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.0'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.10.0'
testImplementation 'org.mockito:mockito-core:5.3.1'
testImplementation 'org.mockito:mockito-junit-jupiter:5.3.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.10.0'
}

compileJava {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

compileTestJava {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
options.fork = true
options.forkOptions.executable = "${PATH_TO_TEST_JAVA_RUNTIME}/bin/javac"
}

test {
useJUnitPlatform()
}

publishing {
repositories {
maven {
url "file://$project.rootDir/repo"
}
}
publications {
mavenJava(MavenPublication) {
from components.java
artifactId = archivesBaseName
pom {
name = 'Durable Task Azure Managed SDK for Java'
description = 'This package contains classes and interfaces for building Durable Task orchestrations in Java using Azure Managed mode.'
url = "https://github.com/microsoft/durabletask-java/tree/main/azuremanaged"
licenses {
license {
name = "MIT License"
url = "https://opensource.org/licenses/MIT"
distribution = "repo"
}
}
developers {
developer {
id = "Microsoft"
name = "Microsoft Corporation"
}
}
scm {
connection = "scm:git:https://github.com/microsoft/durabletask-java"
developerConnection = "scm:git:git@github.com:microsoft/durabletask-java"
url = "https://github.com/microsoft/durabletask-java/tree/main/azuremanaged"
}
withXml {
project.configurations.compileOnly.allDependencies.each { dependency ->
asNode().dependencies[0].appendNode("dependency").with {
it.appendNode("groupId", dependency.group)
it.appendNode("artifactId", dependency.name)
it.appendNode("version", dependency.version)
it.appendNode("scope", "provided")
}
}
}
}
}
}
}

java {
withSourcesJar()
withJavadocJar()
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.microsoft.durabletask.azuremanaged;

import com.azure.core.credential.TokenCredential;
import com.azure.core.credential.AccessToken;
import com.azure.core.credential.TokenRequestContext;

import java.time.Duration;
import java.time.OffsetDateTime;

/**
* Caches access tokens for Azure authentication.
* This class is used by both client and worker components to authenticate with Azure-managed Durable Task Scheduler.
*/
public final class AccessTokenCache {
private final TokenCredential credential;
private final TokenRequestContext context;
private final Duration margin;
private AccessToken cachedToken;

/**
* Creates a new instance of the AccessTokenCache.
*
* @param credential The token credential to use for obtaining tokens.
* @param context The token request context specifying the scopes.
* @param margin The time margin before token expiration to refresh the token.
*/
public AccessTokenCache(TokenCredential credential, TokenRequestContext context, Duration margin) {
this.credential = credential;
this.context = context;
this.margin = margin;
}

/**
* Gets a valid access token, refreshing it if necessary.
*
* @return A valid access token.
*/
public AccessToken getToken() {
OffsetDateTime nowWithMargin = OffsetDateTime.now().plus(margin);

if (cachedToken == null
|| cachedToken.getExpiresAt().isBefore(nowWithMargin)) {
this.cachedToken = credential.getToken(context).block();
}

return cachedToken;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.microsoft.durabletask.azuremanaged;

import com.microsoft.durabletask.DurableTaskGrpcClientBuilder;
import com.azure.core.credential.TokenCredential;
import io.grpc.Channel;
import java.util.Objects;
import javax.annotation.Nullable;

/**
* Extension methods for creating DurableTaskClient instances that connect to Azure-managed Durable Task Scheduler.
* This class provides various methods to create and configure clients using either connection strings or explicit parameters.
*/
public final class DurableTaskSchedulerClientExtensions {

private DurableTaskSchedulerClientExtensions() {}

/**
* Configures a DurableTaskGrpcClientBuilder to use Azure-managed Durable Task Scheduler with a connection string.
*
* @param builder The builder to configure.
* @param connectionString The connection string for Azure-managed Durable Task Scheduler.
* @throws NullPointerException if builder or connectionString is null
*/
public static void useDurableTaskScheduler(
DurableTaskGrpcClientBuilder builder,
String connectionString) {
Objects.requireNonNull(builder, "builder must not be null");
Objects.requireNonNull(connectionString, "connectionString must not be null");

configureBuilder(builder,
DurableTaskSchedulerClientOptions.fromConnectionString(connectionString));
}

/**
* Configures a DurableTaskGrpcClientBuilder to use Azure-managed Durable Task Scheduler with explicit parameters.
*
* @param builder The builder to configure.
* @param endpoint The endpoint address for Azure-managed Durable Task Scheduler.
* @param taskHubName The name of the task hub to connect to.
* @param tokenCredential The token credential for authentication, or null for anonymous access.
* @throws NullPointerException if builder, endpoint, or taskHubName is null
*/
public static void useDurableTaskScheduler(
DurableTaskGrpcClientBuilder builder,
String endpoint,
String taskHubName,
@Nullable TokenCredential tokenCredential) {
Objects.requireNonNull(builder, "builder must not be null");
Objects.requireNonNull(endpoint, "endpoint must not be null");
Objects.requireNonNull(taskHubName, "taskHubName must not be null");

configureBuilder(builder, new DurableTaskSchedulerClientOptions()
.setEndpointAddress(endpoint)
.setTaskHubName(taskHubName)
.setCredential(tokenCredential));
}

/**
* Creates a DurableTaskGrpcClientBuilder configured for Azure-managed Durable Task Scheduler using a connection string.
*
* @param connectionString The connection string for Azure-managed Durable Task Scheduler.
* @return A new configured DurableTaskGrpcClientBuilder instance.
* @throws NullPointerException if connectionString is null
*/
public static DurableTaskGrpcClientBuilder createClientBuilder(
String connectionString) {
Objects.requireNonNull(connectionString, "connectionString must not be null");
return createBuilderFromOptions(
DurableTaskSchedulerClientOptions.fromConnectionString(connectionString));
}

/**
* Creates a DurableTaskGrpcClientBuilder configured for Azure-managed Durable Task Scheduler using explicit parameters.
*
* @param endpoint The endpoint address for Azure-managed Durable Task Scheduler.
* @param taskHubName The name of the task hub to connect to.
* @param tokenCredential The token credential for authentication, or null for anonymous access.
* @return A new configured DurableTaskGrpcClientBuilder instance.
* @throws NullPointerException if endpoint or taskHubName is null
*/
public static DurableTaskGrpcClientBuilder createClientBuilder(
String endpoint,
String taskHubName,
@Nullable TokenCredential tokenCredential) {
Objects.requireNonNull(endpoint, "endpoint must not be null");
Objects.requireNonNull(taskHubName, "taskHubName must not be null");

return createBuilderFromOptions(new DurableTaskSchedulerClientOptions()
.setEndpointAddress(endpoint)
.setTaskHubName(taskHubName)
.setCredential(tokenCredential));
}

// Private helper methods to reduce code duplication
private static DurableTaskGrpcClientBuilder createBuilderFromOptions(DurableTaskSchedulerClientOptions options) {
Channel grpcChannel = options.createGrpcChannel();
return new DurableTaskGrpcClientBuilder().grpcChannel(grpcChannel);
}

private static void configureBuilder(DurableTaskGrpcClientBuilder builder, DurableTaskSchedulerClientOptions options) {
Channel grpcChannel = options.createGrpcChannel();
builder.grpcChannel(grpcChannel);
}
}
Loading
Loading