Skip to content

Commit 773e99a

Browse files
committed
chore: Add domain name to the connector config.
See #2043 for the whole feature definition.
1 parent d14b4e4 commit 773e99a

File tree

6 files changed

+170
-9
lines changed

6 files changed

+170
-9
lines changed

core/src/main/java/com/google/cloud/sql/ConnectorConfig.java

+22-4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.google.auth.oauth2.GoogleCredentials;
2020
import com.google.common.base.Objects;
2121
import java.util.List;
22+
import java.util.function.Function;
2223
import java.util.function.Supplier;
2324

2425
/**
@@ -33,6 +34,7 @@ public class ConnectorConfig {
3334
private final String adminRootUrl;
3435
private final String adminServicePath;
3536
private final Supplier<GoogleCredentials> googleCredentialsSupplier;
37+
private final Function<String, String> instanceNameResolver;
3638
private final GoogleCredentials googleCredentials;
3739
private final String googleCredentialsPath;
3840
private final String adminQuotaProject;
@@ -50,7 +52,8 @@ private ConnectorConfig(
5052
String googleCredentialsPath,
5153
String adminQuotaProject,
5254
String universeDomain,
53-
RefreshStrategy refreshStrategy) {
55+
RefreshStrategy refreshStrategy,
56+
Function<String, String> instanceNameResolver) {
5457
this.targetPrincipal = targetPrincipal;
5558
this.delegates = delegates;
5659
this.adminRootUrl = adminRootUrl;
@@ -61,6 +64,7 @@ private ConnectorConfig(
6164
this.adminQuotaProject = adminQuotaProject;
6265
this.universeDomain = universeDomain;
6366
this.refreshStrategy = refreshStrategy;
67+
this.instanceNameResolver = instanceNameResolver;
6468
}
6569

6670
@Override
@@ -81,7 +85,8 @@ public boolean equals(Object o) {
8185
&& Objects.equal(googleCredentialsPath, that.googleCredentialsPath)
8286
&& Objects.equal(adminQuotaProject, that.adminQuotaProject)
8387
&& Objects.equal(universeDomain, that.universeDomain)
84-
&& Objects.equal(refreshStrategy, that.refreshStrategy);
88+
&& Objects.equal(refreshStrategy, that.refreshStrategy)
89+
&& Objects.equal(instanceNameResolver, that.instanceNameResolver);
8590
}
8691

8792
@Override
@@ -96,7 +101,8 @@ public int hashCode() {
96101
googleCredentialsPath,
97102
adminQuotaProject,
98103
universeDomain,
99-
refreshStrategy);
104+
refreshStrategy,
105+
instanceNameResolver);
100106
}
101107

102108
public String getTargetPrincipal() {
@@ -139,6 +145,10 @@ public RefreshStrategy getRefreshStrategy() {
139145
return refreshStrategy;
140146
}
141147

148+
public Function<String, String> getInstanceNameResolver() {
149+
return instanceNameResolver;
150+
}
151+
142152
/** The builder for the ConnectionConfig. */
143153
public static class Builder {
144154

@@ -152,6 +162,7 @@ public static class Builder {
152162
private String adminQuotaProject;
153163
private String universeDomain;
154164
private RefreshStrategy refreshStrategy = RefreshStrategy.BACKGROUND;
165+
private Function<String, String> instanceNameResolver;
155166

156167
/** Chained setter for TargetPrinciple field. */
157168
public Builder withTargetPrincipal(String targetPrincipal) {
@@ -214,6 +225,12 @@ public Builder withRefreshStrategy(RefreshStrategy refreshStrategy) {
214225
return this;
215226
}
216227

228+
/** Chained setter for the InstanceNameResolver field. */
229+
public Builder withInstanceNameResolver(Function<String, String> instanceNameResolver) {
230+
this.instanceNameResolver = instanceNameResolver;
231+
return this;
232+
}
233+
217234
/** Builds a new instance of {@code ConnectionConfig}. */
218235
public ConnectorConfig build() {
219236
// validate only one GoogleCredentials configuration field set
@@ -248,7 +265,8 @@ public ConnectorConfig build() {
248265
googleCredentialsPath,
249266
adminQuotaProject,
250267
universeDomain,
251-
refreshStrategy);
268+
refreshStrategy,
269+
instanceNameResolver);
252270
}
253271
}
254272
}

core/src/main/java/com/google/cloud/sql/core/ConnectionConfig.java

+60-1
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,19 @@ public class ConnectionConfig {
6363

6464
private final AuthType authType;
6565
private final String unixSocketPathSuffix;
66+
private final String domainName;
6667

6768
/** Create a new ConnectionConfig from the well known JDBC Connection properties. */
6869
public static ConnectionConfig fromConnectionProperties(Properties props) {
70+
// TODO convert internal uses to fromConnectionProperties(props, domainName)
71+
return fromConnectionProperties(props, null);
72+
}
73+
74+
/**
75+
* Create a new ConnectionConfig from the well known JDBC Connection properties, also setting
76+
* database domain name.
77+
*/
78+
public static ConnectionConfig fromConnectionProperties(Properties props, String domainName) {
6979
final String csqlInstanceName = props.getProperty(ConnectionConfig.CLOUD_SQL_INSTANCE_PROPERTY);
7080
final String namedConnection =
7181
props.getProperty(ConnectionConfig.CLOUD_SQL_NAMED_CONNECTOR_PROPERTY);
@@ -113,6 +123,7 @@ public static ConnectionConfig fromConnectionProperties(Properties props) {
113123
ipTypes,
114124
authType,
115125
unixSocketPathSuffix,
126+
domainName,
116127
new ConnectorConfig.Builder()
117128
.withTargetPrincipal(targetPrincipal)
118129
.withDelegates(delegates)
@@ -162,13 +173,20 @@ public boolean equals(Object o) {
162173
&& Objects.equals(unixSocketPath, config.unixSocketPath)
163174
&& Objects.equals(ipTypes, config.ipTypes)
164175
&& Objects.equals(authType, config.authType)
176+
&& Objects.equals(domainName, config.domainName)
165177
&& Objects.equals(connectorConfig, config.connectorConfig);
166178
}
167179

168180
@Override
169181
public int hashCode() {
170182
return Objects.hash(
171-
cloudSqlInstance, namedConnector, unixSocketPath, ipTypes, authType, connectorConfig);
183+
cloudSqlInstance,
184+
namedConnector,
185+
unixSocketPath,
186+
ipTypes,
187+
authType,
188+
domainName,
189+
connectorConfig);
172190
}
173191

174192
private ConnectionConfig(
@@ -178,6 +196,7 @@ private ConnectionConfig(
178196
List<IpType> ipTypes,
179197
AuthType authType,
180198
String unixSocketPathSuffix,
199+
String domainName,
181200
ConnectorConfig connectorConfig) {
182201
this.cloudSqlInstance = cloudSqlInstance;
183202
this.namedConnector = namedConnector;
@@ -186,6 +205,7 @@ private ConnectionConfig(
186205
this.unixSocketPathSuffix = unixSocketPathSuffix;
187206
this.connectorConfig = connectorConfig;
188207
this.authType = authType;
208+
this.domainName = domainName;
189209
}
190210

191211
/** Creates a new instance of the ConnectionConfig with an updated connectorConfig. */
@@ -197,9 +217,36 @@ public ConnectionConfig withConnectorConfig(ConnectorConfig config) {
197217
ipTypes,
198218
authType,
199219
unixSocketPathSuffix,
220+
domainName,
200221
config);
201222
}
202223

224+
/** Creates a new instance of the ConnectionConfig with an updated cloudSqlInstance. */
225+
public ConnectionConfig withCloudSqlInstance(String newCloudSqlInstance) {
226+
return new ConnectionConfig(
227+
newCloudSqlInstance,
228+
namedConnector,
229+
unixSocketPath,
230+
ipTypes,
231+
authType,
232+
unixSocketPathSuffix,
233+
domainName,
234+
connectorConfig);
235+
}
236+
237+
/** Creates a new instance of the ConnectionConfig with an updated cloudSqlInstance. */
238+
public ConnectionConfig withDomainName(String domainName) {
239+
return new ConnectionConfig(
240+
cloudSqlInstance,
241+
namedConnector,
242+
unixSocketPath,
243+
ipTypes,
244+
authType,
245+
unixSocketPathSuffix,
246+
domainName,
247+
connectorConfig);
248+
}
249+
203250
public String getNamedConnector() {
204251
return namedConnector;
205252
}
@@ -228,6 +275,10 @@ public AuthType getAuthType() {
228275
return authType;
229276
}
230277

278+
public String getDomainName() {
279+
return domainName;
280+
}
281+
231282
/** The builder for the ConnectionConfig. */
232283
public static class Builder {
233284

@@ -238,6 +289,7 @@ public static class Builder {
238289
private String unixSocketPathSuffix;
239290
private ConnectorConfig connectorConfig = new ConnectorConfig.Builder().build();
240291
private AuthType authType = DEFAULT_AUTH_TYPE;
292+
private String domainName;
241293

242294
/** Chained setter for CloudSqlInstance field. */
243295
public Builder withCloudSqlInstance(String cloudSqlInstance) {
@@ -281,6 +333,12 @@ public Builder withIpTypes(List<IpType> ipTypes) {
281333
return this;
282334
}
283335

336+
/** Set domainName. */
337+
public Builder withDomainName(String domainName) {
338+
this.domainName = domainName;
339+
return this;
340+
}
341+
284342
/** Chained setter for UnixSocketPathSuffix field. */
285343
public Builder withUnixSocketPathSuffix(String unixSocketPathSuffix) {
286344
this.unixSocketPathSuffix = unixSocketPathSuffix;
@@ -296,6 +354,7 @@ public ConnectionConfig build() {
296354
ipTypes,
297355
authType,
298356
unixSocketPathSuffix,
357+
domainName,
299358
connectorConfig);
300359
}
301360
}

core/src/main/java/com/google/cloud/sql/core/Connector.java

+36-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.security.KeyPair;
2929
import java.util.concurrent.ConcurrentHashMap;
3030
import java.util.concurrent.ExecutionException;
31+
import java.util.function.Function;
3132
import javax.net.ssl.SSLSocket;
3233
import jnr.unixsocket.UnixSocketAddress;
3334
import jnr.unixsocket.UnixSocketChannel;
@@ -140,9 +141,11 @@ Socket connect(ConnectionConfig config, long timeoutMs) throws IOException {
140141
}
141142
}
142143

143-
ConnectionInfoCache getConnection(ConnectionConfig config) {
144+
ConnectionInfoCache getConnection(final ConnectionConfig config) {
145+
final ConnectionConfig updatedConfig = resolveConnectionName(config);
146+
144147
ConnectionInfoCache instance =
145-
instances.computeIfAbsent(config, k -> createConnectionInfo(config));
148+
instances.computeIfAbsent(updatedConfig, k -> createConnectionInfo(updatedConfig));
146149

147150
// If the client certificate has expired (as when the computer goes to
148151
// sleep, and the refresh cycle cannot run), force a refresh immediately.
@@ -154,6 +157,37 @@ ConnectionInfoCache getConnection(ConnectionConfig config) {
154157
return instance;
155158
}
156159

160+
private ConnectionConfig resolveConnectionName(ConnectionConfig config) {
161+
// If domainName is not set, return the original configuration unmodified.
162+
if (config.getDomainName() == null || config.getDomainName().isEmpty()) {
163+
return config;
164+
}
165+
166+
// If both domainName and cloudSqlInstance are set, ignore the domain name. Return a new
167+
// configuration with domainName set to null.
168+
if (config.getCloudSqlInstance() != null && !config.getCloudSqlInstance().isEmpty()) {
169+
return config.withDomainName(null);
170+
}
171+
172+
// If only domainName is set, resolve the domain name.
173+
try {
174+
final String unresolvedName = config.getDomainName();
175+
final Function<String, String> resolver =
176+
config.getConnectorConfig().getInstanceNameResolver();
177+
if (resolver != null) {
178+
return config.withCloudSqlInstance(resolver.apply(unresolvedName));
179+
} else {
180+
throw new IllegalStateException(
181+
"Can't resolve domain " + unresolvedName + ". ConnectorConfig.resolver is not set.");
182+
}
183+
} catch (IllegalArgumentException e) {
184+
throw new IllegalArgumentException(
185+
String.format(
186+
"Cloud SQL connection name is invalid: \"%s\"", config.getCloudSqlInstance()),
187+
e);
188+
}
189+
}
190+
157191
private ConnectionInfoCache createConnectionInfo(ConnectionConfig config) {
158192
logger.debug(
159193
String.format("[%s] Connection info added to cache.", config.getCloudSqlInstance()));

core/src/test/java/com/google/cloud/sql/ConnectorConfigTest.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,8 @@ public void testHashCode() {
426426
wantGoogleCredentialsPath,
427427
wantAdminQuotaProject,
428428
null, // universeDomain
429-
wantRefreshStrategy // refreshStrategy
429+
wantRefreshStrategy, // refreshStrategy
430+
null // instanceNameResolver
430431
));
431432
}
432433
}

core/src/test/java/com/google/cloud/sql/core/ConnectionConfigTest.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public void testConfigFromProps() {
4949
final String wantAdminQuotaProject = "myNewProject";
5050
final String propRefreshStrategy = "Lazy";
5151
final RefreshStrategy wantRefreshStrategy = RefreshStrategy.LAZY;
52+
final String wantDomainName = "db.example.com";
5253

5354
Properties props = new Properties();
5455
props.setProperty(ConnectionConfig.CLOUD_SQL_INSTANCE_PROPERTY, wantCsqlInstance);
@@ -66,7 +67,7 @@ public void testConfigFromProps() {
6667
ConnectionConfig.CLOUD_SQL_ADMIN_QUOTA_PROJECT_PROPERTY, wantAdminQuotaProject);
6768
props.setProperty(ConnectionConfig.CLOUD_SQL_REFRESH_STRATEGY_PROPERTY, propRefreshStrategy);
6869

69-
ConnectionConfig c = ConnectionConfig.fromConnectionProperties(props);
70+
ConnectionConfig c = ConnectionConfig.fromConnectionProperties(props, wantDomainName);
7071

7172
assertThat(c.getCloudSqlInstance()).isEqualTo(wantCsqlInstance);
7273
assertThat(c.getNamedConnector()).isEqualTo(wantNamedConnector);
@@ -81,6 +82,7 @@ public void testConfigFromProps() {
8182
assertThat(c.getConnectorConfig().getAdminQuotaProject()).isEqualTo(wantAdminQuotaProject);
8283
assertThat(c.getUnixSocketPathSuffix()).isEqualTo(wantUnixSuffix);
8384
assertThat(c.getConnectorConfig().getRefreshStrategy()).isEqualTo(wantRefreshStrategy);
85+
assertThat(c.getDomainName()).isEqualTo(wantDomainName);
8486
}
8587

8688
@Test
@@ -96,6 +98,7 @@ public void testConfigFromBuilder() {
9698
final String wantAdminServicePath = "sqladmin/";
9799
final String wantUnixSuffix = ".psql.5432";
98100
final String wantAdminQuotaProject = "myNewProject";
101+
final String wantDomainName = "db.example.com";
99102

100103
ConnectorConfig cc =
101104
new ConnectorConfig.Builder()
@@ -115,6 +118,7 @@ public void testConfigFromBuilder() {
115118
.withUnixSocketPath(wantUnixSocket)
116119
.withUnixSocketPathSuffix(wantUnixSuffix)
117120
.withConnectorConfig(cc)
121+
.withDomainName(wantDomainName)
118122
.build();
119123

120124
assertThat(c.getCloudSqlInstance()).isEqualTo(wantCsqlInstance);
@@ -128,6 +132,7 @@ public void testConfigFromBuilder() {
128132
assertThat(c.getConnectorConfig().getAdminServicePath()).isEqualTo(wantAdminServicePath);
129133
assertThat(c.getConnectorConfig().getAdminQuotaProject()).isEqualTo(wantAdminQuotaProject);
130134
assertThat(c.getUnixSocketPathSuffix()).isEqualTo(wantUnixSuffix);
135+
assertThat(c.getDomainName()).isEqualTo(wantDomainName);
131136
}
132137

133138
@Test

0 commit comments

Comments
 (0)