Skip to content

Commit 98ae6f4

Browse files
feat: set the GoogleCredentials to use on a connector (#296)
1 parent b88c69f commit 98ae6f4

11 files changed

+343
-96
lines changed

alloydb-jdbc-connector/src/main/java/com/google/cloud/alloydb/ConnectionConfig.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class ConnectionConfig {
2929
public static final String ALLOYDB_DELEGATES = "alloydbDelegates";
3030
public static final String ALLOYDB_NAMED_CONNECTOR = "alloydbNamedConnector";
3131
public static final String ALLOYDB_ADMIN_SERVICE_ENDPOINT = "alloydbAdminServiceEndpoint";
32+
public static final String ALLOYDB_GOOGLE_CREDENTIALS_PATH = "alloydbGoogleCredentialsPath";
3233
private final InstanceName instanceName;
3334
private final String namedConnector;
3435
private final ConnectorConfig connectorConfig;
@@ -48,6 +49,8 @@ static ConnectionConfig fromConnectionProperties(Properties props) {
4849
} else {
4950
delegates = Collections.emptyList();
5051
}
52+
final String googleCredentialsPath =
53+
props.getProperty(ConnectionConfig.ALLOYDB_GOOGLE_CREDENTIALS_PATH);
5154

5255
return new ConnectionConfig(
5356
instanceName,
@@ -56,6 +59,7 @@ static ConnectionConfig fromConnectionProperties(Properties props) {
5659
.withTargetPrincipal(targetPrincipal)
5760
.withDelegates(delegates)
5861
.withAdminServiceEndpoint(adminServiceEndpoint)
62+
.withGoogleCredentialsPath(googleCredentialsPath)
5963
.build());
6064
}
6165

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright 2023 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud.alloydb;
18+
19+
/** Factory interface for creating SQLAdmin clients to interact with AlloyDB Admin API. */
20+
public interface ConnectionInfoRepositoryFactory {
21+
22+
DefaultConnectionInfoRepository create(
23+
CredentialFactory credentialFactory, ConnectorConfig config);
24+
}

alloydb-jdbc-connector/src/main/java/com/google/cloud/alloydb/ConnectorConfig.java

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616

1717
package com.google.cloud.alloydb;
1818

19+
import com.google.auth.oauth2.GoogleCredentials;
1920
import com.google.common.base.Objects;
2021
import java.util.List;
22+
import java.util.function.Supplier;
2123

2224
/**
2325
* ConnectorConfig is an immutable configuration value object that holds the entire configuration of
@@ -29,12 +31,23 @@ public class ConnectorConfig {
2931
private final String targetPrincipal;
3032
private final List<String> delegates;
3133
private final String adminServiceEndpoint;
34+
private final Supplier<GoogleCredentials> googleCredentialsSupplier;
35+
private final GoogleCredentials googleCredentials;
36+
private final String googleCredentialsPath;
3237

3338
private ConnectorConfig(
34-
String targetPrincipal, List<String> delegates, String adminServiceEndpoint) {
39+
String targetPrincipal,
40+
List<String> delegates,
41+
String adminServiceEndpoint,
42+
Supplier<GoogleCredentials> googleCredentialsSupplier,
43+
GoogleCredentials googleCredentials,
44+
String googleCredentialsPath) {
3545
this.targetPrincipal = targetPrincipal;
3646
this.delegates = delegates;
3747
this.adminServiceEndpoint = adminServiceEndpoint;
48+
this.googleCredentialsSupplier = googleCredentialsSupplier;
49+
this.googleCredentials = googleCredentials;
50+
this.googleCredentialsPath = googleCredentialsPath;
3851
}
3952

4053
@Override
@@ -48,12 +61,21 @@ public boolean equals(Object o) {
4861
ConnectorConfig that = (ConnectorConfig) o;
4962
return Objects.equal(targetPrincipal, that.targetPrincipal)
5063
&& Objects.equal(delegates, that.delegates)
51-
&& Objects.equal(adminServiceEndpoint, that.adminServiceEndpoint);
64+
&& Objects.equal(adminServiceEndpoint, that.adminServiceEndpoint)
65+
&& Objects.equal(googleCredentialsSupplier, that.googleCredentialsSupplier)
66+
&& Objects.equal(googleCredentials, that.googleCredentials)
67+
&& Objects.equal(googleCredentialsPath, that.googleCredentialsPath);
5268
}
5369

5470
@Override
5571
public int hashCode() {
56-
return Objects.hashCode(targetPrincipal, delegates, adminServiceEndpoint);
72+
return Objects.hashCode(
73+
targetPrincipal,
74+
delegates,
75+
adminServiceEndpoint,
76+
googleCredentialsSupplier,
77+
googleCredentials,
78+
googleCredentialsPath);
5779
}
5880

5981
public String getTargetPrincipal() {
@@ -68,12 +90,27 @@ public String getAdminServiceEndpoint() {
6890
return adminServiceEndpoint;
6991
}
7092

93+
public Supplier<GoogleCredentials> getGoogleCredentialsSupplier() {
94+
return googleCredentialsSupplier;
95+
}
96+
97+
public GoogleCredentials getGoogleCredentials() {
98+
return googleCredentials;
99+
}
100+
101+
public String getGoogleCredentialsPath() {
102+
return googleCredentialsPath;
103+
}
104+
71105
/** The builder for the ConnectionConfig. */
72106
public static class Builder {
73107

74108
private String targetPrincipal;
75109
private List<String> delegates;
76110
private String adminServiceEndpoint;
111+
private Supplier<GoogleCredentials> googleCredentialsSupplier;
112+
private GoogleCredentials googleCredentials;
113+
private String googleCredentialsPath;
77114

78115
public Builder withTargetPrincipal(String targetPrincipal) {
79116
this.targetPrincipal = targetPrincipal;
@@ -90,9 +127,48 @@ public Builder withAdminServiceEndpoint(String adminServiceEndpoint) {
90127
return this;
91128
}
92129

130+
public Builder withGoogleCredentialsSupplier(
131+
Supplier<GoogleCredentials> googleCredentialsSupplier) {
132+
this.googleCredentialsSupplier = googleCredentialsSupplier;
133+
return this;
134+
}
135+
136+
public Builder withGoogleCredentials(GoogleCredentials googleCredentials) {
137+
this.googleCredentials = googleCredentials;
138+
return this;
139+
}
140+
141+
public Builder withGoogleCredentialsPath(String googleCredentialsPath) {
142+
this.googleCredentialsPath = googleCredentialsPath;
143+
return this;
144+
}
145+
93146
/** Builds a new instance of {@code ConnectionConfig}. */
94147
public ConnectorConfig build() {
95-
return new ConnectorConfig(targetPrincipal, delegates, adminServiceEndpoint);
148+
// validate only one GoogleCredentials configuration field set
149+
int googleCredsCount = 0;
150+
if (googleCredentials != null) {
151+
googleCredsCount++;
152+
}
153+
if (googleCredentialsPath != null) {
154+
googleCredsCount++;
155+
}
156+
if (googleCredentialsSupplier != null) {
157+
googleCredsCount++;
158+
}
159+
if (googleCredsCount > 1) {
160+
throw new IllegalStateException(
161+
"Invalid configuration, more than one GoogleCredentials field has a value "
162+
+ "(googleCredentials, googleCredentialsPath, googleCredentialsSupplier)");
163+
}
164+
165+
return new ConnectorConfig(
166+
targetPrincipal,
167+
delegates,
168+
adminServiceEndpoint,
169+
googleCredentialsSupplier,
170+
googleCredentials,
171+
googleCredentialsPath);
96172
}
97173
}
98174
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright 2023 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.google.cloud.alloydb;
17+
18+
class CredentialFactoryProvider {
19+
20+
private final CredentialFactory defaultCredentialFactory;
21+
22+
CredentialFactoryProvider() {
23+
this.defaultCredentialFactory = new DefaultCredentialFactory();
24+
}
25+
26+
CredentialFactoryProvider(CredentialFactory defaultCredentialFactory) {
27+
this.defaultCredentialFactory = defaultCredentialFactory;
28+
}
29+
30+
CredentialFactory getDefaultCredentialFactory() {
31+
return defaultCredentialFactory;
32+
}
33+
34+
CredentialFactory getInstanceCredentialFactory(ConnectorConfig config) {
35+
36+
CredentialFactory instanceCredentialFactory;
37+
if (config.getGoogleCredentialsSupplier() != null) {
38+
instanceCredentialFactory =
39+
new SupplierCredentialFactory(config.getGoogleCredentialsSupplier());
40+
} else if (config.getGoogleCredentials() != null) {
41+
instanceCredentialFactory = new ConstantCredentialFactory(config.getGoogleCredentials());
42+
} else if (config.getGoogleCredentialsPath() != null) {
43+
instanceCredentialFactory = new FileCredentialFactory(config.getGoogleCredentialsPath());
44+
} else {
45+
instanceCredentialFactory = getDefaultCredentialFactory();
46+
}
47+
48+
// Validate targetPrincipal and delegates
49+
if (config.getTargetPrincipal() == null
50+
&& config.getDelegates() != null
51+
&& !config.getDelegates().isEmpty()) {
52+
throw new IllegalArgumentException(
53+
String.format(
54+
"Connection property %s must be when %s is set.",
55+
ConnectionConfig.ALLOYDB_TARGET_PRINCIPAL, ConnectionConfig.ALLOYDB_DELEGATES));
56+
}
57+
58+
// If targetPrincipal and delegates are set, then
59+
if (config.getTargetPrincipal() != null && !config.getTargetPrincipal().isEmpty()) {
60+
instanceCredentialFactory =
61+
new ServiceAccountImpersonatingCredentialFactory(
62+
instanceCredentialFactory, config.getTargetPrincipal(), config.getDelegates());
63+
}
64+
65+
return instanceCredentialFactory;
66+
}
67+
}

alloydb-jdbc-connector/src/main/java/com/google/cloud/alloydb/CredentialsProviderFactory.java

Lines changed: 0 additions & 49 deletions
This file was deleted.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2023 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud.alloydb;
18+
19+
import com.google.cloud.alloydb.v1.AlloyDBAdminClient;
20+
import com.google.common.util.concurrent.ListeningScheduledExecutorService;
21+
import java.io.IOException;
22+
23+
/** Factory for creating a SQLAdmin client that interacts with the real AlloyDB Admin API. */
24+
class DefaultConnectionInfoRepositoryFactory implements ConnectionInfoRepositoryFactory {
25+
private final ListeningScheduledExecutorService executor;
26+
27+
DefaultConnectionInfoRepositoryFactory(ListeningScheduledExecutorService executor) {
28+
this.executor = executor;
29+
}
30+
31+
@Override
32+
public DefaultConnectionInfoRepository create(
33+
CredentialFactory credentialFactory, ConnectorConfig config) {
34+
35+
AlloyDBAdminClient alloyDBAdminClient;
36+
try {
37+
alloyDBAdminClient =
38+
AlloyDBAdminClientFactory.create(
39+
credentialFactory.create(), config.getAdminServiceEndpoint());
40+
return new DefaultConnectionInfoRepository(executor, alloyDBAdminClient);
41+
} catch (IOException e) {
42+
throw new RuntimeException(e);
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)