Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
32 changes: 32 additions & 0 deletions sdk/src/main/java/io/dapr/config/Properties.java
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,38 @@ public class Properties {
"DAPR_GRPC_ENDPOINT",
null);

/**
* GRPC enable keep alive.
*/
public static final Property<Boolean> GRPC_ENABLE_KEEP_ALIVE = new BooleanProperty(
"dapr.grpc.enableKeepAlive",
"DAPR_GRPC_ENABLE_KEEP_ALIVE",
false);

/**
* GRPC keep alive time in milliseconds.
*/
public static final Property<Duration> GRPC_KEEP_ALIVE_TIME_MILLISECONDS = new MillisecondsDurationProperty(
"dapr.grpc.keepAliveTimeSeconds",
"DAPR_GRPC_KEEP_ALIVE_TIME_MILLISECONDS",
Duration.ofMillis(10000));

/**
* GRPC keep alive timeout in seconds.
*/
public static final Property<Duration> GRPC_KEEP_ALIVE_TIMEOUT_MILLISECONDS = new MillisecondsDurationProperty(
"dapr.grpc.keepAliveTimeoutSeconds",
"DAPR_GRPC_KEEP_ALIVE_TIMEOUT_MILLISECONDS",
Duration.ofMillis(1000));

/**
* GRPC keep alive without calls.
*/
public static final Property<Boolean> GRPC_KEEP_ALIVE_WITHOUT_CALLS = new BooleanProperty(
"dapr.grpc.keepAliveWithoutCalls",
"DAPR_GRPC_KEEP_ALIVE_WITHOUT_CALLS",
false);

/**
* GRPC endpoint for remote sidecar connectivity.
*/
Expand Down
81 changes: 58 additions & 23 deletions sdk/src/main/java/io/dapr/utils/NetworkUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

package io.dapr.utils;


import io.dapr.config.Properties;
import io.dapr.exceptions.DaprError;
import io.dapr.exceptions.DaprException;
Expand All @@ -32,9 +33,15 @@
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

import static io.dapr.config.Properties.GRPC_ENABLE_KEEP_ALIVE;
import static io.dapr.config.Properties.GRPC_ENDPOINT;
import static io.dapr.config.Properties.GRPC_KEEP_ALIVE_TIMEOUT_MILLISECONDS;
import static io.dapr.config.Properties.GRPC_KEEP_ALIVE_TIME_MILLISECONDS;
import static io.dapr.config.Properties.GRPC_KEEP_ALIVE_WITHOUT_CALLS;
import static io.dapr.config.Properties.GRPC_PORT;
import static io.dapr.config.Properties.GRPC_TLS_CA_PATH;
import static io.dapr.config.Properties.GRPC_TLS_CERT_PATH;
Expand Down Expand Up @@ -68,8 +75,8 @@

private static final String GRPC_ENDPOINT_HOSTNAME_REGEX_PART = "(([A-Za-z0-9_\\-\\.]+)|(\\[" + IPV6_REGEX + "\\]))";

private static final String GRPC_ENDPOINT_DNS_AUTHORITY_REGEX_PART =
"(?<dnsWithAuthority>dns://)(?<authorityEndpoint>"
private static final String GRPC_ENDPOINT_DNS_AUTHORITY_REGEX_PART = "(?<dnsWithAuthority>dns://)"
+ "(?<authorityEndpoint>"
+ GRPC_ENDPOINT_HOSTNAME_REGEX_PART + ":[0-9]+)?/";

private static final String GRPC_ENDPOINT_PARAM_REGEX_PART = "(\\?(?<param>tls\\=((true)|(false))))?";
Expand Down Expand Up @@ -144,7 +151,8 @@
} catch (Exception e) {
throw new DaprException(
new DaprError().setErrorCode("TLS_CREDENTIALS_ERROR")
.setMessage("Failed to create insecure TLS credentials"), e);
.setMessage("Failed to create insecure TLS credentials"),

Check warning on line 154 in sdk/src/main/java/io/dapr/utils/NetworkUtils.java

View check run for this annotation

Codecov / codecov/patch

sdk/src/main/java/io/dapr/utils/NetworkUtils.java#L154

Added line #L154 was not covered by tests
e);
}
}

Expand All @@ -155,23 +163,24 @@
ManagedChannelBuilder<?> builder = ManagedChannelBuilder.forTarget(settings.endpoint);

if (clientCertPath != null && clientKeyPath != null) {
// mTLS case - using client cert and key, with optional CA cert for server authentication
// mTLS case - using client cert and key, with optional CA cert for server
// authentication
try (
InputStream clientCertInputStream = new FileInputStream(clientCertPath);
InputStream clientKeyInputStream = new FileInputStream(clientKeyPath);
InputStream caCertInputStream = caCertPath != null ? new FileInputStream(caCertPath) : null
) {
InputStream caCertInputStream = caCertPath != null ? new FileInputStream(caCertPath) : null) {
TlsChannelCredentials.Builder builderCreds = TlsChannelCredentials.newBuilder()
.keyManager(clientCertInputStream, clientKeyInputStream); // For client authentication
.keyManager(clientCertInputStream, clientKeyInputStream); // For client authentication
if (caCertInputStream != null) {
builderCreds.trustManager(caCertInputStream); // For server authentication
builderCreds.trustManager(caCertInputStream); // For server authentication
}
ChannelCredentials credentials = builderCreds.build();
builder = Grpc.newChannelBuilder(settings.endpoint, credentials);
} catch (IOException e) {
throw new DaprException(
new DaprError().setErrorCode("TLS_CREDENTIALS_ERROR")
.setMessage("Failed to create mTLS credentials" + (caCertPath != null ? " with CA cert" : "")), e);
.setMessage("Failed to create mTLS credentials" + (caCertPath != null ? " with CA cert" : "")),
e);
}
} else if (caCertPath != null) {
// Simple TLS case - using CA cert only for server authentication
Expand All @@ -183,7 +192,8 @@
} catch (IOException e) {
throw new DaprException(
new DaprError().setErrorCode("TLS_CREDENTIALS_ERROR")
.setMessage("Failed to create TLS credentials with CA cert"), e);
.setMessage("Failed to create TLS credentials with CA cert"),
e);
}
} else if (!settings.secure) {
builder = builder.usePlaintext();
Expand All @@ -194,6 +204,13 @@
if (interceptors != null && interceptors.length > 0) {
builder = builder.intercept(interceptors);
}

if (settings.enableKeepAlive) {
builder.keepAliveTime(settings.keepAliveTimeSeconds.toMillis(), TimeUnit.MILLISECONDS)
.keepAliveTimeout(settings.keepAliveTimeoutSeconds.toMillis(), TimeUnit.MILLISECONDS)
.keepAliveWithoutCalls(settings.keepAliveWithoutCalls);

Check warning on line 211 in sdk/src/main/java/io/dapr/utils/NetworkUtils.java

View check run for this annotation

Codecov / codecov/patch

sdk/src/main/java/io/dapr/utils/NetworkUtils.java#L209-L211

Added lines #L209 - L211 were not covered by tests
}

return builder.build();
}

Expand All @@ -205,13 +222,24 @@
final String tlsCertPath;
final String tlsCaPath;

final boolean enableKeepAlive;
final Duration keepAliveTimeSeconds;
final Duration keepAliveTimeoutSeconds;
final boolean keepAliveWithoutCalls;

private GrpcEndpointSettings(
String endpoint, boolean secure, String tlsPrivateKeyPath, String tlsCertPath, String tlsCaPath) {
String endpoint, boolean secure, String tlsPrivateKeyPath, String tlsCertPath, String tlsCaPath,
boolean enableKeepAlive, Duration keepAliveTimeSeconds, Duration keepAliveTimeoutSeconds,
boolean keepAliveWithoutCalls) {
this.endpoint = endpoint;
this.secure = secure;
this.tlsPrivateKeyPath = tlsPrivateKeyPath;
this.tlsCertPath = tlsCertPath;
this.tlsCaPath = tlsCaPath;
this.enableKeepAlive = enableKeepAlive;
this.keepAliveTimeSeconds = keepAliveTimeSeconds;
this.keepAliveTimeoutSeconds = keepAliveTimeoutSeconds;
this.keepAliveWithoutCalls = keepAliveWithoutCalls;
}

static GrpcEndpointSettings parse(Properties properties) {
Expand All @@ -220,6 +248,10 @@
String clientKeyPath = properties.getValue(GRPC_TLS_KEY_PATH);
String clientCertPath = properties.getValue(GRPC_TLS_CERT_PATH);
String caCertPath = properties.getValue(GRPC_TLS_CA_PATH);
boolean enablekeepAlive = properties.getValue(GRPC_ENABLE_KEEP_ALIVE);
Duration keepAliveTimeMilliseconds = properties.getValue(GRPC_KEEP_ALIVE_TIME_MILLISECONDS);
Duration keepAliveTimeoutMilliseconds = properties.getValue(GRPC_KEEP_ALIVE_TIMEOUT_MILLISECONDS);
boolean keepAliveWithoutCalls = properties.getValue(GRPC_KEEP_ALIVE_WITHOUT_CALLS);

boolean secure = false;
String grpcEndpoint = properties.getValue(GRPC_ENDPOINT);
Expand Down Expand Up @@ -257,30 +289,33 @@
var authorityEndpoint = matcher.group("authorityEndpoint");
if (authorityEndpoint != null) {
return new GrpcEndpointSettings(
String.format(
"dns://%s/%s:%d",
authorityEndpoint,
address,
port
), secure, clientKeyPath, clientCertPath, caCertPath);
String.format(
"dns://%s/%s:%d",
authorityEndpoint,
address,
port),
secure, clientKeyPath, clientCertPath, caCertPath, enablekeepAlive, keepAliveTimeMilliseconds,
keepAliveTimeoutMilliseconds, keepAliveWithoutCalls);
}

var socket = matcher.group("socket");
if (socket != null) {
return new GrpcEndpointSettings(socket, secure, clientKeyPath, clientCertPath, caCertPath);
return new GrpcEndpointSettings(socket, secure, clientKeyPath, clientCertPath, caCertPath, enablekeepAlive,
keepAliveTimeMilliseconds, keepAliveTimeoutMilliseconds, keepAliveWithoutCalls);
}

var vsocket = matcher.group("vsocket");
if (vsocket != null) {
return new GrpcEndpointSettings(vsocket, secure, clientKeyPath, clientCertPath, caCertPath);
return new GrpcEndpointSettings(vsocket, secure, clientKeyPath, clientCertPath, caCertPath, enablekeepAlive,
keepAliveTimeMilliseconds, keepAliveTimeoutMilliseconds, keepAliveWithoutCalls);
}
}

return new GrpcEndpointSettings(String.format(
"dns:///%s:%d",
address,
port
), secure, clientKeyPath, clientCertPath, caCertPath);
"dns:///%s:%d",
address,
port), secure, clientKeyPath, clientCertPath, caCertPath, enablekeepAlive, keepAliveTimeMilliseconds,
keepAliveTimeoutMilliseconds, keepAliveWithoutCalls);
}

}
Expand Down
Loading