Skip to content

Commit 5665098

Browse files
SSL/TLS Support (#90)
1 parent 0590434 commit 5665098

2 files changed

Lines changed: 73 additions & 11 deletions

File tree

src/main/java/io/temporal/internal/WorkflowServiceStubsImpl.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@
2323
import io.grpc.ClientInterceptor;
2424
import io.grpc.ClientInterceptors;
2525
import io.grpc.ManagedChannel;
26-
import io.grpc.ManagedChannelBuilder;
2726
import io.grpc.Metadata;
2827
import io.grpc.Server;
2928
import io.grpc.inprocess.InProcessChannelBuilder;
3029
import io.grpc.inprocess.InProcessServerBuilder;
30+
import io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder;
3131
import io.grpc.stub.MetadataUtils;
3232
import io.temporal.proto.workflowservice.WorkflowServiceGrpc;
3333
import io.temporal.serviceclient.WorkflowServiceStubs;
@@ -103,11 +103,19 @@ public WorkflowServiceStubsImpl(
103103
// Do not shutdown a channel passed to the constructor from outside
104104
channelNeedsShutdown = serviceImpl != null;
105105
} else {
106-
this.channel =
107-
ManagedChannelBuilder.forTarget(options.getTarget())
108-
.defaultLoadBalancingPolicy("round_robin")
109-
.usePlaintext()
110-
.build();
106+
NettyChannelBuilder builder =
107+
NettyChannelBuilder.forTarget(options.getTarget())
108+
.defaultLoadBalancingPolicy("round_robin");
109+
110+
if (options.getSslContext() == null && !options.getEnableHttps()) {
111+
builder.usePlaintext();
112+
} else if (options.getSslContext() != null) {
113+
builder.sslContext(options.getSslContext());
114+
} else {
115+
builder.useTransportSecurity();
116+
}
117+
118+
this.channel = builder.build();
111119
channelNeedsShutdown = true;
112120
}
113121
GrpcMetricsInterceptor metricsInterceptor =

src/main/java/io/temporal/serviceclient/WorkflowServiceStubsOptions.java

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import io.grpc.ManagedChannel;
2626
import io.grpc.ManagedChannelBuilder;
2727
import io.grpc.NameResolver;
28+
import io.grpc.netty.shaded.io.netty.handler.ssl.SslContext;
2829
import io.temporal.proto.workflowservice.WorkflowServiceGrpc;
2930
import java.util.Map;
3031
import java.util.Optional;
@@ -63,16 +64,22 @@ public static WorkflowServiceStubsOptions getDefaultInstance() {
6364

6465
private final String target;
6566

66-
/** The tChannel timeout in milliseconds */
67+
/** The user provided context for SSL/TLS over gRPC * */
68+
private final SslContext sslContext;
69+
70+
/** Indicates whether basic HTTPS/SSL/TLS should be enabled * */
71+
private final boolean enableHttps;
72+
73+
/** The gRPC timeout in milliseconds */
6774
private final long rpcTimeoutMillis;
6875

69-
/** The tChannel timeout for long poll calls in milliseconds */
76+
/** The gRPC timeout for long poll calls in milliseconds */
7077
private final long rpcLongPollTimeoutMillis;
7178

72-
/** The tChannel timeout for query workflow call in milliseconds */
79+
/** The gRPC timeout for query workflow call in milliseconds */
7380
private final long rpcQueryTimeoutMillis;
7481

75-
/** Optional TChannel headers */
82+
/** Optional gRPC headers */
7683
private final Map<String, String> headers;
7784

7885
private final Scope metricsScope;
@@ -89,6 +96,8 @@ public static WorkflowServiceStubsOptions getDefaultInstance() {
8996

9097
private WorkflowServiceStubsOptions(Builder builder) {
9198
this.target = builder.target;
99+
this.sslContext = builder.sslContext;
100+
this.enableHttps = builder.enableHttps;
92101
this.channel = builder.channel;
93102
this.rpcLongPollTimeoutMillis = builder.rpcLongPollTimeoutMillis;
94103
this.rpcQueryTimeoutMillis = builder.rpcQueryTimeoutMillis;
@@ -104,8 +113,21 @@ private WorkflowServiceStubsOptions(Builder builder, boolean ignore) {
104113
throw new IllegalStateException(
105114
"Only one of the target and channel options can be set at a time");
106115
}
116+
117+
if (builder.sslContext != null && builder.channel != null) {
118+
throw new IllegalStateException(
119+
"Only one of the sslContext and channel options can be set at a time");
120+
}
121+
122+
if (builder.enableHttps && builder.channel != null) {
123+
throw new IllegalStateException(
124+
"Only one of the enableHttps and channel options can be set at a time");
125+
}
126+
107127
this.target =
108128
builder.target == null && builder.channel == null ? LOCAL_DOCKER_TARGET : builder.target;
129+
this.sslContext = builder.sslContext;
130+
this.enableHttps = builder.enableHttps;
109131
this.channel = builder.channel;
110132
this.rpcLongPollTimeoutMillis = builder.rpcLongPollTimeoutMillis;
111133
this.rpcQueryTimeoutMillis = builder.rpcQueryTimeoutMillis;
@@ -125,6 +147,16 @@ public String getTarget() {
125147
return target;
126148
}
127149

150+
/** @return Returns the gRPC SSL Context to use. * */
151+
public SslContext getSslContext() {
152+
return sslContext;
153+
}
154+
155+
/** @return Returns a boolean indicating whether gRPC should use SSL/TLS. * */
156+
public boolean getEnableHttps() {
157+
return enableHttps;
158+
}
159+
128160
/** @return Returns the rpc timeout value in millis. */
129161
public long getRpcTimeoutMillis() {
130162
return rpcTimeoutMillis;
@@ -171,6 +203,8 @@ public Scope getMetricsScope() {
171203
*/
172204
public static class Builder {
173205
private ManagedChannel channel;
206+
private SslContext sslContext;
207+
private boolean enableHttps;
174208
private String target;
175209
private long rpcTimeoutMillis = DEFAULT_RPC_TIMEOUT_MILLIS;
176210
private long rpcLongPollTimeoutMillis = DEFAULT_POLL_RPC_TIMEOUT_MILLIS;
@@ -191,6 +225,8 @@ private Builder() {}
191225
private Builder(WorkflowServiceStubsOptions options) {
192226
this.target = options.target;
193227
this.channel = options.channel;
228+
this.enableHttps = options.enableHttps;
229+
this.sslContext = options.sslContext;
194230
this.rpcLongPollTimeoutMillis = options.rpcLongPollTimeoutMillis;
195231
this.rpcQueryTimeoutMillis = options.rpcQueryTimeoutMillis;
196232
this.rpcTimeoutMillis = options.rpcTimeoutMillis;
@@ -200,12 +236,30 @@ private Builder(WorkflowServiceStubsOptions options) {
200236
this.metricsScope = options.metricsScope;
201237
}
202238

203-
/** Sets gRPC channel to use. Exclusive with target. */
239+
/** Sets gRPC channel to use. Exclusive with target and sslContext. */
204240
public Builder setChannel(ManagedChannel channel) {
205241
this.channel = channel;
206242
return this;
207243
}
208244

245+
/**
246+
* Sets gRPC SSL Context to use, used for more advanced scenarios such as mTLS. Supercedes
247+
* enableHttps; Exclusive with channel.
248+
*/
249+
public Builder setSslContext(SslContext sslContext) {
250+
this.sslContext = sslContext;
251+
return this;
252+
}
253+
254+
/**
255+
* Sets option to enable SSL/TLS/HTTPS for gRPC. Exclusive with channel; Ignored if SSLContext
256+
* is specified
257+
*/
258+
public Builder setEnableHttps(boolean enableHttps) {
259+
this.enableHttps = enableHttps;
260+
return this;
261+
}
262+
209263
/**
210264
* Sets a target string, which can be either a valid {@link NameResolver}-compliant URI, or an
211265
* authority string. See {@link ManagedChannelBuilder#forTarget(String)} for more information

0 commit comments

Comments
 (0)