Skip to content

Commit 07e1ebf

Browse files
committed
Merge branch 'main' into vabachu/java-tracing-support
2 parents 1278d68 + f0757b0 commit 07e1ebf

File tree

5 files changed

+208
-3
lines changed

5 files changed

+208
-3
lines changed

azuremanaged/build.gradle

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ dependencies {
4444
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.10.0'
4545
testImplementation 'org.mockito:mockito-core:5.3.1'
4646
testImplementation 'org.mockito:mockito-junit-jupiter:5.3.1'
47+
testImplementation "io.grpc:grpc-netty:${grpcVersion}"
4748
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.10.0'
4849
}
4950

@@ -61,6 +62,7 @@ compileTestJava {
6162

6263
test {
6364
useJUnitPlatform()
65+
include '**/*Test.class'
6466
}
6567

6668
publishing {
@@ -174,4 +176,5 @@ compileJava.dependsOn generateVersionInfo
174176

175177
tasks.named('sourcesJar') {
176178
dependsOn generateVersionInfo
177-
}
179+
}
180+

azuremanaged/src/main/java/com/microsoft/durabletask/azuremanaged/DurableTaskSchedulerClientOptions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ public void start(ClientCall.Listener<RespT> responseListener, Metadata headers)
227227
);
228228

229229
headers.put(
230-
Metadata.Key.of("user-agent", Metadata.ASCII_STRING_MARSHALLER),
230+
Metadata.Key.of("x-user-agent", Metadata.ASCII_STRING_MARSHALLER),
231231
DurableTaskUserAgentUtil.getUserAgent()
232232
);
233233

azuremanaged/src/main/java/com/microsoft/durabletask/azuremanaged/DurableTaskSchedulerWorkerOptions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ public void start(ClientCall.Listener<RespT> responseListener, Metadata headers)
236236
);
237237

238238
headers.put(
239-
Metadata.Key.of("user-agent", Metadata.ASCII_STRING_MARSHALLER),
239+
Metadata.Key.of("x-user-agent", Metadata.ASCII_STRING_MARSHALLER),
240240
DurableTaskUserAgentUtil.getUserAgent()
241241
);
242242

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package com.microsoft.durabletask.azuremanaged;
2+
3+
import com.microsoft.durabletask.DurableTaskClient;
4+
import com.microsoft.durabletask.DurableTaskGrpcClientBuilder;
5+
import com.microsoft.durabletask.NewOrchestrationInstanceOptions;
6+
import io.grpc.*;
7+
import io.grpc.stub.ServerCalls;
8+
import io.grpc.stub.StreamObserver;
9+
import io.grpc.netty.NettyServerBuilder;
10+
import org.junit.jupiter.api.AfterEach;
11+
import org.junit.jupiter.api.BeforeEach;
12+
import org.junit.jupiter.api.Test;
13+
14+
import java.io.IOException;
15+
import java.util.concurrent.atomic.AtomicReference;
16+
17+
import static org.junit.jupiter.api.Assertions.*;
18+
19+
public class DurableTaskSchedulerClientExtensionsUserAgentTest {
20+
private Server server;
21+
private Channel channel;
22+
private final AtomicReference<String> capturedUserAgent = new AtomicReference<>();
23+
private static final String EXPECTED_USER_AGENT_PREFIX = "durabletask-java/";
24+
25+
// Dummy gRPC service definition
26+
public static class DummyService implements io.grpc.BindableService {
27+
@Override
28+
public ServerServiceDefinition bindService() {
29+
return ServerServiceDefinition.builder("TaskHubSidecarService")
30+
.addMethod(
31+
MethodDescriptor.<com.google.protobuf.Empty, com.google.protobuf.Empty>newBuilder()
32+
.setType(MethodDescriptor.MethodType.UNARY)
33+
.setFullMethodName(MethodDescriptor.generateFullMethodName("TaskHubSidecarService", "StartInstance"))
34+
.setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(com.google.protobuf.Empty.getDefaultInstance()))
35+
.setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(com.google.protobuf.Empty.getDefaultInstance()))
36+
.build(),
37+
ServerCalls.asyncUnaryCall(
38+
new ServerCalls.UnaryMethod<com.google.protobuf.Empty, com.google.protobuf.Empty>() {
39+
@Override
40+
public void invoke(com.google.protobuf.Empty request, StreamObserver<com.google.protobuf.Empty> responseObserver) {
41+
// Mock response for StartInstance
42+
responseObserver.onNext(com.google.protobuf.Empty.getDefaultInstance());
43+
responseObserver.onCompleted();
44+
}
45+
}
46+
)
47+
)
48+
.build();
49+
}
50+
}
51+
52+
@BeforeEach
53+
public void setUp() throws IOException {
54+
// Use NettyServerBuilder to expose the server via HTTP
55+
server = NettyServerBuilder.forPort(0)
56+
.addService(new DummyService()) // Register DummyService
57+
.intercept(new ServerInterceptor() {
58+
@Override
59+
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
60+
ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
61+
String userAgent = headers.get(Metadata.Key.of("x-user-agent", Metadata.ASCII_STRING_MARSHALLER));
62+
capturedUserAgent.set(userAgent);
63+
return next.startCall(call, headers);
64+
}
65+
})
66+
.directExecutor()
67+
.build()
68+
.start();
69+
int port = server.getPort();
70+
String endpoint = "localhost:" + port;
71+
DurableTaskSchedulerClientOptions options = new DurableTaskSchedulerClientOptions();
72+
options.setEndpointAddress(endpoint);
73+
options.setTaskHubName("testHub");
74+
options.setAllowInsecureCredentials(true); // Netty is insecure for localhost
75+
channel = options.createGrpcChannel();
76+
}
77+
78+
@AfterEach
79+
public void tearDown() {
80+
if (server != null) server.shutdownNow();
81+
if (channel != null && channel instanceof ManagedChannel) {
82+
((ManagedChannel) channel).shutdownNow();
83+
}
84+
}
85+
86+
@Test
87+
public void testUserAgentHeaderIsSet() {
88+
DurableTaskGrpcClientBuilder builder = new DurableTaskGrpcClientBuilder();
89+
builder.grpcChannel(channel);
90+
DurableTaskClient client = builder.build();
91+
92+
// Schedule a new orchestration instance
93+
String instanceId = client.scheduleNewOrchestrationInstance(
94+
"TestOrchestration",
95+
new NewOrchestrationInstanceOptions().setInput("TestInput"));
96+
97+
// Make a dummy call to trigger the request
98+
String userAgent = capturedUserAgent.get();
99+
assertNotNull(userAgent, "X-User-Agent header should be set");
100+
assertTrue(userAgent.startsWith(EXPECTED_USER_AGENT_PREFIX), "X-User-Agent should start with durabletask-java/");
101+
}
102+
}
103+

eng/ci/release.yml

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
pr: none
2+
trigger: none
3+
4+
resources:
5+
repositories:
6+
- repository: 1ESPipelineTemplates
7+
type: git
8+
name: 1ESPipelineTemplates/1ESPipelineTemplates
9+
ref: refs/tags/release
10+
pipelines:
11+
- pipeline: DurableTaskJavaBuildPipeline
12+
source: durabletask-java.official
13+
branch: main
14+
15+
extends:
16+
template: v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates
17+
parameters:
18+
pool:
19+
name: 1es-pool-azfunc
20+
image: 1es-ubuntu-22.04
21+
os: linux
22+
23+
stages:
24+
- stage: release
25+
jobs:
26+
- job: durabletask_azuremanaged
27+
templateContext:
28+
type: releaseJob
29+
isProduction: true
30+
inputs:
31+
# Declare inputs to be released here to ensure they receive relevant checks
32+
- input: pipelineArtifact
33+
pipeline: DurableTaskJavaBuildPipeline
34+
artifactName: drop
35+
targetPath: $(System.DefaultWorkingDirectory)/drop
36+
37+
steps:
38+
- task: SFP.release-tasks.custom-build-release-task.EsrpRelease@9
39+
displayName: 'Release durabletask-azuremanaged'
40+
inputs:
41+
connectedservicename: 'dtfx-internal-esrp-prod'
42+
usemanagedidentity: true
43+
keyvaultname: 'durable-esrp-akv'
44+
signcertname: 'dts-esrp-cert'
45+
clientid: '0b3ed1a4-0727-4a50-b82a-02c2bd9dec89'
46+
folderlocation: '$(System.DefaultWorkingDirectory)/drop/durabletask-azuremanaged'
47+
48+
approvers: '[email protected]'
49+
mainpublisher: 'durabletask-java'
50+
51+
- job: durabletask_client
52+
templateContext:
53+
type: releaseJob
54+
isProduction: true
55+
inputs:
56+
# Declare inputs to be released here to ensure they receive relevant checks
57+
- input: pipelineArtifact
58+
pipeline: DurableTaskJavaBuildPipeline
59+
artifactName: drop
60+
targetPath: $(System.DefaultWorkingDirectory)/drop
61+
62+
steps:
63+
- task: SFP.release-tasks.custom-build-release-task.EsrpRelease@9
64+
displayName: 'Release durabletask-client'
65+
inputs:
66+
connectedservicename: 'dtfx-internal-esrp-prod'
67+
usemanagedidentity: true
68+
keyvaultname: 'durable-esrp-akv'
69+
signcertname: 'dts-esrp-cert'
70+
clientid: '0b3ed1a4-0727-4a50-b82a-02c2bd9dec89'
71+
folderlocation: '$(System.DefaultWorkingDirectory)/drop/durabletask-client'
72+
73+
approvers: '[email protected]'
74+
mainpublisher: 'durabletask-java'
75+
76+
- job: durabletask_azure_functions
77+
templateContext:
78+
type: releaseJob
79+
isProduction: true
80+
inputs:
81+
# Declare inputs to be released here to ensure they receive relevant checks
82+
- input: pipelineArtifact
83+
pipeline: DurableTaskJavaBuildPipeline
84+
artifactName: drop
85+
targetPath: $(System.DefaultWorkingDirectory)/drop
86+
87+
steps:
88+
- task: SFP.release-tasks.custom-build-release-task.EsrpRelease@9
89+
displayName: 'Release durabletask-azure-functions'
90+
inputs:
91+
connectedservicename: 'dtfx-internal-esrp-prod'
92+
usemanagedidentity: true
93+
keyvaultname: 'durable-esrp-akv'
94+
signcertname: 'dts-esrp-cert'
95+
clientid: '0b3ed1a4-0727-4a50-b82a-02c2bd9dec89'
96+
folderlocation: '$(System.DefaultWorkingDirectory)/drop/durabletask-azure-functions'
97+
98+
approvers: '[email protected]'
99+
mainpublisher: 'durabletask-java'

0 commit comments

Comments
 (0)