Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

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 @@ -29,6 +29,7 @@ class ConnectionConfig {
public static final String ALLOYDB_DELEGATES = "alloydbDelegates";
public static final String ALLOYDB_NAMED_CONNECTOR = "alloydbNamedConnector";
public static final String ALLOYDB_ADMIN_SERVICE_ENDPOINT = "alloydbAdminServiceEndpoint";
public static final String ALLOYDB_GOOGLE_CREDENTIALS_PATH = "alloydbGoogleCredentialsPath";
private final InstanceName instanceName;
private final String namedConnector;
private final ConnectorConfig connectorConfig;
Expand All @@ -48,6 +49,8 @@ static ConnectionConfig fromConnectionProperties(Properties props) {
} else {
delegates = Collections.emptyList();
}
final String googleCredentialsPath =
props.getProperty(ConnectionConfig.ALLOYDB_GOOGLE_CREDENTIALS_PATH);

return new ConnectionConfig(
instanceName,
Expand All @@ -56,6 +59,7 @@ static ConnectionConfig fromConnectionProperties(Properties props) {
.withTargetPrincipal(targetPrincipal)
.withDelegates(delegates)
.withAdminServiceEndpoint(adminServiceEndpoint)
.withGoogleCredentialsPath(googleCredentialsPath)
.build());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.cloud.alloydb;

/** Factory interface for creating SQLAdmin clients to interact with AlloyDB Admin API. */
public interface ConnectionInfoRepositoryFactory {

DefaultConnectionInfoRepository create(
CredentialFactory credentialFactory, ConnectorConfig config);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@

package com.google.cloud.alloydb;

import com.google.auth.oauth2.GoogleCredentials;
import com.google.common.base.Objects;
import java.util.List;
import java.util.function.Supplier;

/**
* ConnectorConfig is an immutable configuration value object that holds the entire configuration of
Expand All @@ -29,12 +31,23 @@ public class ConnectorConfig {
private final String targetPrincipal;
private final List<String> delegates;
private final String adminServiceEndpoint;
private final Supplier<GoogleCredentials> googleCredentialsSupplier;
private final GoogleCredentials googleCredentials;
private final String googleCredentialsPath;

private ConnectorConfig(
String targetPrincipal, List<String> delegates, String adminServiceEndpoint) {
String targetPrincipal,
List<String> delegates,
String adminServiceEndpoint,
Supplier<GoogleCredentials> googleCredentialsSupplier,
GoogleCredentials googleCredentials,
String googleCredentialsPath) {
this.targetPrincipal = targetPrincipal;
this.delegates = delegates;
this.adminServiceEndpoint = adminServiceEndpoint;
this.googleCredentialsSupplier = googleCredentialsSupplier;
this.googleCredentials = googleCredentials;
this.googleCredentialsPath = googleCredentialsPath;
}

@Override
Expand All @@ -48,12 +61,21 @@ public boolean equals(Object o) {
ConnectorConfig that = (ConnectorConfig) o;
return Objects.equal(targetPrincipal, that.targetPrincipal)
&& Objects.equal(delegates, that.delegates)
&& Objects.equal(adminServiceEndpoint, that.adminServiceEndpoint);
&& Objects.equal(adminServiceEndpoint, that.adminServiceEndpoint)
&& Objects.equal(googleCredentialsSupplier, that.googleCredentialsSupplier)
&& Objects.equal(googleCredentials, that.googleCredentials)
&& Objects.equal(googleCredentialsPath, that.googleCredentialsPath);
}

@Override
public int hashCode() {
return Objects.hashCode(targetPrincipal, delegates, adminServiceEndpoint);
return Objects.hashCode(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add tests for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have here

targetPrincipal,
delegates,
adminServiceEndpoint,
googleCredentialsSupplier,
googleCredentials,
googleCredentialsPath);
}

public String getTargetPrincipal() {
Expand All @@ -68,12 +90,27 @@ public String getAdminServiceEndpoint() {
return adminServiceEndpoint;
}

public Supplier<GoogleCredentials> getGoogleCredentialsSupplier() {
return googleCredentialsSupplier;
}

public GoogleCredentials getGoogleCredentials() {
return googleCredentials;
}

public String getGoogleCredentialsPath() {
return googleCredentialsPath;
}

/** The builder for the ConnectionConfig. */
public static class Builder {

private String targetPrincipal;
private List<String> delegates;
private String adminServiceEndpoint;
private Supplier<GoogleCredentials> googleCredentialsSupplier;
private GoogleCredentials googleCredentials;
private String googleCredentialsPath;

public Builder withTargetPrincipal(String targetPrincipal) {
this.targetPrincipal = targetPrincipal;
Expand All @@ -90,9 +127,48 @@ public Builder withAdminServiceEndpoint(String adminServiceEndpoint) {
return this;
}

public Builder withGoogleCredentialsSupplier(
Supplier<GoogleCredentials> googleCredentialsSupplier) {
this.googleCredentialsSupplier = googleCredentialsSupplier;
return this;
}

public Builder withGoogleCredentials(GoogleCredentials googleCredentials) {
this.googleCredentials = googleCredentials;
return this;
}

public Builder withGoogleCredentialsPath(String googleCredentialsPath) {
this.googleCredentialsPath = googleCredentialsPath;
return this;
}

/** Builds a new instance of {@code ConnectionConfig}. */
public ConnectorConfig build() {
return new ConnectorConfig(targetPrincipal, delegates, adminServiceEndpoint);
// validate only one GoogleCredentials configuration field set
int googleCredsCount = 0;
if (googleCredentials != null) {
googleCredsCount++;
}
if (googleCredentialsPath != null) {
googleCredsCount++;
}
if (googleCredentialsSupplier != null) {
googleCredsCount++;
}
if (googleCredsCount > 1) {
throw new IllegalStateException(
"Invalid configuration, more than one GoogleCredentials field has a value "
+ "(googleCredentials, googleCredentialsPath, googleCredentialsSupplier)");
}

return new ConnectorConfig(
targetPrincipal,
delegates,
adminServiceEndpoint,
googleCredentialsSupplier,
googleCredentials,
googleCredentialsPath);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.cloud.alloydb;

class CredentialFactoryProvider {

private final CredentialFactory defaultCredentialFactory;

CredentialFactoryProvider() {
this.defaultCredentialFactory = new DefaultCredentialFactory();
}

CredentialFactoryProvider(CredentialFactory defaultCredentialFactory) {
this.defaultCredentialFactory = defaultCredentialFactory;
}

CredentialFactory getDefaultCredentialFactory() {
return defaultCredentialFactory;
}

CredentialFactory getInstanceCredentialFactory(ConnectorConfig config) {

CredentialFactory instanceCredentialFactory;
if (config.getGoogleCredentialsSupplier() != null) {
instanceCredentialFactory =
new SupplierCredentialFactory(config.getGoogleCredentialsSupplier());
} else if (config.getGoogleCredentials() != null) {
instanceCredentialFactory = new ConstantCredentialFactory(config.getGoogleCredentials());
} else if (config.getGoogleCredentialsPath() != null) {
instanceCredentialFactory = new FileCredentialFactory(config.getGoogleCredentialsPath());
} else {
instanceCredentialFactory = getDefaultCredentialFactory();
}

// Validate targetPrincipal and delegates
if (config.getTargetPrincipal() == null
&& config.getDelegates() != null
&& !config.getDelegates().isEmpty()) {
throw new IllegalArgumentException(
String.format(
"Connection property %s must be when %s is set.",
ConnectionConfig.ALLOYDB_TARGET_PRINCIPAL, ConnectionConfig.ALLOYDB_DELEGATES));
}

// If targetPrincipal and delegates are set, then
if (config.getTargetPrincipal() != null && !config.getTargetPrincipal().isEmpty()) {
instanceCredentialFactory =
new ServiceAccountImpersonatingCredentialFactory(
instanceCredentialFactory, config.getTargetPrincipal(), config.getDelegates());
}

return instanceCredentialFactory;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.cloud.alloydb;

import com.google.cloud.alloydb.v1.AlloyDBAdminClient;
import com.google.common.util.concurrent.ListeningScheduledExecutorService;
import java.io.IOException;

/** Factory for creating a SQLAdmin client that interacts with the real AlloyDB Admin API. */
class DefaultConnectionInfoRepositoryFactory implements ConnectionInfoRepositoryFactory {
private final ListeningScheduledExecutorService executor;

DefaultConnectionInfoRepositoryFactory(ListeningScheduledExecutorService executor) {
this.executor = executor;
}

@Override
public DefaultConnectionInfoRepository create(
CredentialFactory credentialFactory, ConnectorConfig config) {

AlloyDBAdminClient alloyDBAdminClient;
try {
alloyDBAdminClient =
AlloyDBAdminClientFactory.create(
credentialFactory.create(), config.getAdminServiceEndpoint());
return new DefaultConnectionInfoRepository(executor, alloyDBAdminClient);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
Loading