9
9
import io .dapr .durabletask .implementation .protobuf .TaskHubSidecarServiceGrpc .*;
10
10
11
11
import io .grpc .*;
12
+ import io .grpc .netty .shaded .io .grpc .netty .GrpcSslContexts ;
13
+ import io .grpc .netty .shaded .io .grpc .netty .NettyChannelBuilder ;
14
+ import io .grpc .netty .shaded .io .netty .handler .ssl .util .InsecureTrustManagerFactory ;
15
+ import java .io .FileInputStream ;
16
+ import java .io .InputStream ;
12
17
13
18
import javax .annotation .Nullable ;
14
19
import java .time .Duration ;
17
22
import java .util .concurrent .TimeUnit ;
18
23
import java .util .concurrent .TimeoutException ;
19
24
import java .util .logging .Logger ;
25
+ import java .io .IOException ;
20
26
21
27
/**
22
28
* Durable Task client implementation that uses gRPC to connect to a remote "sidecar" process.
23
29
*/
24
30
public final class DurableTaskGrpcClient extends DurableTaskClient {
25
31
private static final int DEFAULT_PORT = 4001 ;
26
32
private static final Logger logger = Logger .getLogger (DurableTaskGrpcClient .class .getPackage ().getName ());
33
+ private static final String GRPC_TLS_CA_PATH = "DAPR_GRPC_TLS_CA_PATH" ;
34
+ private static final String GRPC_TLS_CERT_PATH = "DAPR_GRPC_TLS_CERT_PATH" ;
35
+ private static final String GRPC_TLS_KEY_PATH = "DAPR_GRPC_TLS_KEY_PATH" ;
36
+ private static final String GRPC_TLS_INSECURE = "DAPR_GRPC_TLS_INSECURE" ;
27
37
28
38
private final DataConverter dataConverter ;
29
39
private final ManagedChannel managedSidecarChannel ;
@@ -44,11 +54,60 @@ public final class DurableTaskGrpcClient extends DurableTaskClient {
44
54
port = builder .port ;
45
55
}
46
56
57
+ String endpoint = "localhost:" + port ;
58
+ ManagedChannelBuilder <?> channelBuilder ;
59
+
60
+ // Get TLS configuration from builder or environment variables
61
+ String tlsCaPath = builder .tlsCaPath != null ? builder .tlsCaPath : System .getenv (GRPC_TLS_CA_PATH );
62
+ String tlsCertPath = builder .tlsCertPath != null ? builder .tlsCertPath : System .getenv (GRPC_TLS_CERT_PATH );
63
+ String tlsKeyPath = builder .tlsKeyPath != null ? builder .tlsKeyPath : System .getenv (GRPC_TLS_KEY_PATH );
64
+ boolean insecure = builder .insecure || Boolean .parseBoolean (System .getenv (GRPC_TLS_INSECURE ));
65
+
66
+ if (insecure ) {
67
+ // Insecure mode - uses TLS but doesn't verify certificates
68
+ try {
69
+ channelBuilder = NettyChannelBuilder .forTarget (endpoint )
70
+ .sslContext (GrpcSslContexts .forClient ()
71
+ .trustManager (InsecureTrustManagerFactory .INSTANCE )
72
+ .build ());
73
+ } catch (Exception e ) {
74
+ throw new RuntimeException ("Failed to create insecure TLS credentials" , e );
75
+ }
76
+ } else if (tlsCertPath != null && tlsKeyPath != null ) {
77
+ // mTLS case - using client cert and key, with optional CA cert for server authentication
78
+ try (
79
+ InputStream clientCertInputStream = new FileInputStream (tlsCertPath );
80
+ InputStream clientKeyInputStream = new FileInputStream (tlsKeyPath );
81
+ InputStream caCertInputStream = tlsCaPath != null ? new FileInputStream (tlsCaPath ) : null
82
+ ) {
83
+ TlsChannelCredentials .Builder tlsBuilder = TlsChannelCredentials .newBuilder ()
84
+ .keyManager (clientCertInputStream , clientKeyInputStream ); // For client authentication
85
+ if (caCertInputStream != null ) {
86
+ tlsBuilder .trustManager (caCertInputStream ); // For server authentication
87
+ }
88
+ ChannelCredentials credentials = tlsBuilder .build ();
89
+ channelBuilder = Grpc .newChannelBuilder (endpoint , credentials );
90
+ } catch (IOException e ) {
91
+ throw new RuntimeException ("Failed to create mTLS credentials" +
92
+ (tlsCaPath != null ? " with CA cert" : "" ), e );
93
+ }
94
+ } else if (tlsCaPath != null ) {
95
+ // Simple TLS case - using CA cert only for server authentication
96
+ try (InputStream caCertInputStream = new FileInputStream (tlsCaPath )) {
97
+ ChannelCredentials credentials = TlsChannelCredentials .newBuilder ()
98
+ .trustManager (caCertInputStream )
99
+ .build ();
100
+ channelBuilder = Grpc .newChannelBuilder (endpoint , credentials );
101
+ } catch (IOException e ) {
102
+ throw new RuntimeException ("Failed to create TLS credentials with CA cert" , e );
103
+ }
104
+ } else {
105
+ // No TLS config provided, use plaintext
106
+ channelBuilder = ManagedChannelBuilder .forTarget (endpoint ).usePlaintext ();
107
+ }
108
+
47
109
// Need to keep track of this channel so we can dispose it on close()
48
- this .managedSidecarChannel = ManagedChannelBuilder
49
- .forAddress ("localhost" , port )
50
- .usePlaintext ()
51
- .build ();
110
+ this .managedSidecarChannel = channelBuilder .build ();
52
111
sidecarGrpcChannel = this .managedSidecarChannel ;
53
112
}
54
113
0 commit comments