Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: disable dynamic code loading properties by default #2606

Merged
merged 2 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import com.google.cloud.spanner.SpannerOptions;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Sets;
import com.google.spanner.v1.ExecuteSqlRequest.QueryOptions;
import java.io.IOException;
Expand Down Expand Up @@ -205,8 +206,14 @@ public String[] getValidValues() {
public static final String CREDENTIALS_PROPERTY_NAME = "credentials";
/** Name of the 'encodedCredentials' connection property. */
public static final String ENCODED_CREDENTIALS_PROPERTY_NAME = "encodedCredentials";

public static final String ENABLE_ENCODED_CREDENTIALS_SYSTEM_PROPERTY =
"ENABLE_ENCODED_CREDENTIALS";
/** Name of the 'credentialsProvider' connection property. */
public static final String CREDENTIALS_PROVIDER_PROPERTY_NAME = "credentialsProvider";

public static final String ENABLE_CREDENTIALS_PROVIDER_SYSTEM_PROPERTY =
"ENABLE_CREDENTIALS_PROVIDER";
/**
* OAuth token to use for authentication. Cannot be used in combination with a credentials file.
*/
Expand All @@ -219,6 +226,8 @@ public String[] getValidValues() {
public static final String NUM_CHANNELS_PROPERTY_NAME = "numChannels";
/** Name of the 'channelProvider' connection property. */
public static final String CHANNEL_PROVIDER_PROPERTY_NAME = "channelProvider";

public static final String ENABLE_CHANNEL_PROVIDER_SYSTEM_PROPERTY = "ENABLE_CHANNEL_PROVIDER";
/** Custom user agent string is only for other Google libraries. */
private static final String USER_AGENT_PROPERTY_NAME = "userAgent";
/** Query optimizer version to use for a connection. */
Expand Down Expand Up @@ -248,6 +257,19 @@ public String[] getValidValues() {
public static final String MAX_PARTITIONED_PARALLELISM_PROPERTY_NAME =
"maxPartitionedParallelism";

private static final String GUARDED_CONNECTION_PROPERTY_ERROR_MESSAGE =
"%s can only be used if the system property %s has been set to true. "
+ "Start the application with the JVM command line option -D%s=true";

private static String generateGuardedConnectionPropertyError(
String systemPropertyName, String connectionPropertyName) {
return String.format(
GUARDED_CONNECTION_PROPERTY_ERROR_MESSAGE,
connectionPropertyName,
systemPropertyName,
systemPropertyName);
}

/** All valid connection properties. */
public static final Set<ConnectionProperty> VALID_PROPERTIES =
Collections.unmodifiableSet(
Expand Down Expand Up @@ -846,40 +868,64 @@ static boolean parseRetryAbortsInternally(String uri) {

@VisibleForTesting
static @Nullable String parseEncodedCredentials(String uri) {
return parseUriProperty(uri, ENCODED_CREDENTIALS_PROPERTY_NAME);
String encodedCredentials = parseUriProperty(uri, ENCODED_CREDENTIALS_PROPERTY_NAME);
checkGuardedProperty(
encodedCredentials,
ENABLE_ENCODED_CREDENTIALS_SYSTEM_PROPERTY,
ENCODED_CREDENTIALS_PROPERTY_NAME);
return encodedCredentials;
}

@VisibleForTesting
static @Nullable CredentialsProvider parseCredentialsProvider(String uri) {
String name = parseUriProperty(uri, CREDENTIALS_PROVIDER_PROPERTY_NAME);
if (name != null) {
String credentialsProviderName = parseUriProperty(uri, CREDENTIALS_PROVIDER_PROPERTY_NAME);
checkGuardedProperty(
credentialsProviderName,
ENABLE_CREDENTIALS_PROVIDER_SYSTEM_PROPERTY,
CREDENTIALS_PROVIDER_PROPERTY_NAME);
if (!Strings.isNullOrEmpty(credentialsProviderName)) {
try {
Class<? extends CredentialsProvider> clazz =
(Class<? extends CredentialsProvider>) Class.forName(name);
(Class<? extends CredentialsProvider>) Class.forName(credentialsProviderName);
Constructor<? extends CredentialsProvider> constructor = clazz.getDeclaredConstructor();
return constructor.newInstance();
} catch (ClassNotFoundException classNotFoundException) {
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.INVALID_ARGUMENT,
"Unknown or invalid CredentialsProvider class name: " + name,
"Unknown or invalid CredentialsProvider class name: " + credentialsProviderName,
classNotFoundException);
} catch (NoSuchMethodException noSuchMethodException) {
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.INVALID_ARGUMENT,
"Credentials provider " + name + " does not have a public no-arg constructor.",
"Credentials provider "
+ credentialsProviderName
+ " does not have a public no-arg constructor.",
noSuchMethodException);
} catch (InvocationTargetException
| InstantiationException
| IllegalAccessException exception) {
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.INVALID_ARGUMENT,
"Failed to create an instance of " + name + ": " + exception.getMessage(),
"Failed to create an instance of "
+ credentialsProviderName
+ ": "
+ exception.getMessage(),
exception);
}
}
return null;
}

private static void checkGuardedProperty(
String value, String systemPropertyName, String connectionPropertyName) {
if (!Strings.isNullOrEmpty(value)
&& !Boolean.parseBoolean(System.getProperty(systemPropertyName))) {
throw SpannerExceptionFactory.newSpannerException(
ErrorCode.FAILED_PRECONDITION,
generateGuardedConnectionPropertyError(systemPropertyName, connectionPropertyName));
}
}

@VisibleForTesting
static @Nullable String parseOAuthToken(String uri) {
String value = parseUriProperty(uri, OAUTH_TOKEN_PROPERTY_NAME);
Expand Down Expand Up @@ -907,6 +953,8 @@ static String parseNumChannels(String uri) {
@VisibleForTesting
static String parseChannelProvider(String uri) {
String value = parseUriProperty(uri, CHANNEL_PROVIDER_PROPERTY_NAME);
checkGuardedProperty(
value, ENABLE_CHANNEL_PROVIDER_SYSTEM_PROPERTY, CHANNEL_PROVIDER_PROPERTY_NAME);
return value != null ? value : DEFAULT_CHANNEL_PROVIDER;
}

Expand Down
Loading