Skip to content

Commit fcbfef8

Browse files
GregBestlandAlexandre Dutra
authored andcommitted
JAVA-2356: Migrate Cloud API to OSS driver
1 parent e4da25d commit fcbfef8

20 files changed

Lines changed: 902 additions & 4 deletions

File tree

build.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ build:
1313
goals: verify --batch-mode
1414
properties: |
1515
ccm.version=$CCM_CASSANDRA_VERSION
16+
proxy.path=$HOME/proxy
1617
- xunit:
1718
- "**/target/surefire-reports/TEST-*.xml"
1819
- "**/target/failsafe-reports/TEST-*.xml"

core-shaded/pom.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,14 +128,29 @@
128128
-->
129129
<include>com.datastax.oss:java-driver-core</include>
130130
<include>io.netty:*</include>
131+
<include>com.fasterxml.jackson.core:*</include>
131132
</includes>
132133
</artifactSet>
133134
<relocations>
134135
<relocation>
135136
<pattern>io.netty</pattern>
136137
<shadedPattern>com.datastax.oss.driver.shaded.netty</shadedPattern>
137138
</relocation>
139+
<relocation>
140+
<pattern>com.fasterxml.jackson</pattern>
141+
<shadedPattern>com.datastax.oss.driver.shaded.fasterxml.jackson</shadedPattern>
142+
</relocation>
138143
</relocations>
144+
<filters>
145+
<!-- Note: most exclusions are done later on with the dependency plugin, but
146+
these one must be done here because its pattern is too wide -->
147+
<filter>
148+
<artifact>com.fasterxml.jackson.core:*</artifact>
149+
<excludes>
150+
<exclude>META-INF/**</exclude>
151+
</excludes>
152+
</filter>
153+
</filters>
139154
</configuration>
140155
</execution>
141156
</executions>

core/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@
9191
<groupId>com.github.spotbugs</groupId>
9292
<artifactId>spotbugs-annotations</artifactId>
9393
</dependency>
94+
<dependency>
95+
<groupId>com.fasterxml.jackson.core</groupId>
96+
<artifactId>jackson-databind</artifactId>
97+
</dependency>
9498
<dependency>
9599
<groupId>ch.qos.logback</groupId>
96100
<artifactId>logback-classic</artifactId>

core/src/main/java/com/datastax/oss/driver/api/core/config/DefaultDriverOption.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,8 @@ public enum DefaultDriverOption implements DriverOption {
782782
* <p>Value-type: boolean
783783
*/
784784
NETTY_DAEMON("advanced.netty.daemon"),
785+
786+
CLOUD_SECURE_CONNECT_BUNDLE("basic.cloud.secure-connect-bundle"),
785787
;
786788

787789
private final String path;

core/src/main/java/com/datastax/oss/driver/api/core/session/ProgrammaticArguments.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap;
2727
import edu.umd.cs.findbugs.annotations.NonNull;
2828
import edu.umd.cs.findbugs.annotations.Nullable;
29+
import java.net.InetSocketAddress;
2930
import java.util.List;
3031
import java.util.Map;
3132
import java.util.function.Predicate;
@@ -52,6 +53,7 @@ public static Builder builder() {
5253
private final ClassLoader classLoader;
5354
private final AuthProvider authProvider;
5455
private final SslEngineFactory sslEngineFactory;
56+
private final InetSocketAddress cloudAddress;
5557

5658
private ProgrammaticArguments(
5759
@NonNull List<TypeCodec<?>> typeCodecs,
@@ -62,7 +64,8 @@ private ProgrammaticArguments(
6264
@NonNull Map<String, Predicate<Node>> nodeFilters,
6365
@Nullable ClassLoader classLoader,
6466
@Nullable AuthProvider authProvider,
65-
@Nullable SslEngineFactory sslEngineFactory) {
67+
@Nullable SslEngineFactory sslEngineFactory,
68+
@Nullable InetSocketAddress cloudAddress) {
6669
this.typeCodecs = typeCodecs;
6770
this.nodeStateListener = nodeStateListener;
6871
this.schemaChangeListener = schemaChangeListener;
@@ -72,6 +75,7 @@ private ProgrammaticArguments(
7275
this.classLoader = classLoader;
7376
this.authProvider = authProvider;
7477
this.sslEngineFactory = sslEngineFactory;
78+
this.cloudAddress = cloudAddress;
7579
}
7680

7781
@NonNull
@@ -119,6 +123,11 @@ public SslEngineFactory getSslEngineFactory() {
119123
return sslEngineFactory;
120124
}
121125

126+
@Nullable
127+
public InetSocketAddress getCloudAddress() {
128+
return cloudAddress;
129+
}
130+
122131
public static class Builder {
123132

124133
private ImmutableList.Builder<TypeCodec<?>> typeCodecsBuilder = ImmutableList.builder();
@@ -131,6 +140,7 @@ public static class Builder {
131140
private ClassLoader classLoader;
132141
private AuthProvider authProvider;
133142
private SslEngineFactory sslEngineFactory;
143+
private InetSocketAddress cloudAddress;
134144

135145
@NonNull
136146
public Builder addTypeCodecs(@NonNull TypeCodec<?>... typeCodecs) {
@@ -192,6 +202,12 @@ public Builder withClassLoader(@Nullable ClassLoader classLoader) {
192202
return this;
193203
}
194204

205+
@NonNull
206+
public Builder withCloudAddress(@Nullable InetSocketAddress cloudAddress) {
207+
this.cloudAddress = cloudAddress;
208+
return this;
209+
}
210+
195211
@NonNull
196212
public Builder withAuthProvider(@Nullable AuthProvider authProvider) {
197213
this.authProvider = authProvider;
@@ -215,7 +231,8 @@ public ProgrammaticArguments build() {
215231
nodeFiltersBuilder.build(),
216232
classLoader,
217233
authProvider,
218-
sslEngineFactory);
234+
sslEngineFactory,
235+
cloudAddress);
219236
}
220237
}
221238
}

core/src/main/java/com/datastax/oss/driver/api/core/session/SessionBuilder.java

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,15 @@
3434
import com.datastax.oss.driver.api.core.type.codec.TypeCodec;
3535
import com.datastax.oss.driver.internal.core.ContactPoints;
3636
import com.datastax.oss.driver.internal.core.auth.ProgrammaticPlainTextAuthProvider;
37+
import com.datastax.oss.driver.internal.core.config.cloud.DbaasConfig;
38+
import com.datastax.oss.driver.internal.core.config.cloud.DbaasConfigUtil;
3739
import com.datastax.oss.driver.internal.core.config.typesafe.DefaultDriverConfigLoader;
3840
import com.datastax.oss.driver.internal.core.context.DefaultDriverContext;
3941
import com.datastax.oss.driver.internal.core.context.InternalDriverContext;
4042
import com.datastax.oss.driver.internal.core.metadata.DefaultEndPoint;
43+
import com.datastax.oss.driver.internal.core.metadata.SniEndPoint;
4144
import com.datastax.oss.driver.internal.core.session.DefaultSession;
45+
import com.datastax.oss.driver.internal.core.ssl.SniSslEngineFactory;
4246
import com.datastax.oss.driver.internal.core.util.concurrent.BlockingOperation;
4347
import com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures;
4448
import edu.umd.cs.findbugs.annotations.NonNull;
@@ -73,6 +77,7 @@ public abstract class SessionBuilder<SelfT extends SessionBuilder, SessionT> {
7377
protected DriverConfigLoader configLoader;
7478
protected Set<EndPoint> programmaticContactPoints = new HashSet<>();
7579
protected CqlIdentifier keyspace;
80+
protected String cloudConfigPath;
7681

7782
protected ProgrammaticArguments.Builder programmaticArgumentsBuilder =
7883
ProgrammaticArguments.builder();
@@ -377,6 +382,20 @@ public SelfT withClassLoader(@Nullable ClassLoader classLoader) {
377382
return self;
378383
}
379384

385+
/**
386+
* Creates a SessionBuilder pre-configured for a specific Cloud endpoint or configuration file.
387+
* Currently this supports only a path on the local filesystem pointing to the secure connect
388+
* bundle zip file. In the future this will be extended to work with CaaS service provider
389+
* endpoints.
390+
*
391+
* @param cloudConfigPath Absolute path to the secure connect bundle zip file.
392+
*/
393+
@NonNull
394+
public SelfT withCloudSecureConnectBundle(@NonNull String cloudConfigPath) {
395+
this.cloudConfigPath = cloudConfigPath;
396+
return self;
397+
}
398+
380399
/**
381400
* Creates the session with the options set by this builder.
382401
*
@@ -390,7 +409,6 @@ public CompletionStage<SessionT> buildAsync() {
390409
CompletableFutures.propagateCancellation(wrapStage, buildStage);
391410
return wrapStage;
392411
}
393-
394412
/**
395413
* Convenience method to call {@link #buildAsync()} and block on the result.
396414
*
@@ -410,6 +428,28 @@ protected final CompletionStage<CqlSession> buildDefaultSessionAsync() {
410428
DriverConfigLoader configLoader = buildIfNull(this.configLoader, this::defaultConfigLoader);
411429

412430
DriverExecutionProfile defaultConfig = configLoader.getInitialConfig().getDefaultProfile();
431+
if (cloudConfigPath == null) {
432+
cloudConfigPath =
433+
defaultConfig.getString(DefaultDriverOption.CLOUD_SECURE_CONNECT_BUNDLE, null);
434+
}
435+
if (cloudConfigPath != null) {
436+
DbaasConfig dbaasConfig = DbaasConfigUtil.getConfig(cloudConfigPath);
437+
for (String hostID : dbaasConfig.getHostIds()) {
438+
programmaticContactPoints.add(
439+
new SniEndPoint(
440+
new InetSocketAddress(dbaasConfig.getSniHost(), dbaasConfig.getSniPort()),
441+
hostID));
442+
}
443+
withLocalDatacenter(dbaasConfig.getLocalDataCenter());
444+
if (dbaasConfig.getUsername() != null && dbaasConfig.getPassword() != null) {
445+
withAuthCredentials(dbaasConfig.getUsername(), dbaasConfig.getPassword());
446+
}
447+
SSLContext sslContext = DbaasConfigUtil.getSSLContext(dbaasConfig);
448+
withSslEngineFactory(new SniSslEngineFactory(sslContext));
449+
programmaticArgumentsBuilder.withCloudAddress(
450+
new InetSocketAddress(dbaasConfig.getSniHost(), dbaasConfig.getSniPort()));
451+
}
452+
413453
List<String> configContactPoints =
414454
defaultConfig.getStringList(DefaultDriverOption.CONTACT_POINTS, Collections.emptyList());
415455
boolean resolveAddresses =
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/*
2+
* Copyright DataStax, Inc.
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+
package com.datastax.oss.driver.internal.core.config.cloud;
17+
18+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
19+
import java.nio.file.Path;
20+
import java.util.List;
21+
22+
/**
23+
* The POJO representation of the config.json that is distributed as part of the creds.zip. It is
24+
* populated mostly by the config.json. With the hostIds, and localDc being filled in by the
25+
* metadata service.
26+
*/
27+
@JsonIgnoreProperties(ignoreUnknown = true)
28+
public class DbaasConfig {
29+
30+
private String username;
31+
private String password;
32+
private String host;
33+
private int port;
34+
private String sniHost;
35+
private int sniPort;
36+
private List<String> hostIds;
37+
private String localDC;
38+
private String keyStorePassword;
39+
private String trustStorePassword;
40+
private Path secureConnectBundlePath;
41+
42+
public void setUsername(String username) {
43+
this.username = username;
44+
}
45+
46+
public void setPassword(String password) {
47+
this.password = password;
48+
}
49+
50+
public void setHost(String host) {
51+
this.host = host;
52+
}
53+
54+
public void setPort(int port) {
55+
this.port = port;
56+
}
57+
58+
public void setLocalDC(String localDC) {
59+
this.localDC = localDC;
60+
}
61+
62+
public void setKeyStorePassword(String keyStorePassword) {
63+
this.keyStorePassword = keyStorePassword;
64+
}
65+
66+
public void setTrustStorePassword(String trustStorePassword) {
67+
this.trustStorePassword = trustStorePassword;
68+
}
69+
70+
public String getUsername() {
71+
return username;
72+
}
73+
74+
public String getPassword() {
75+
return password;
76+
}
77+
78+
public String getHost() {
79+
return host;
80+
}
81+
82+
public int getPort() {
83+
return port;
84+
}
85+
86+
public String getLocalDataCenter() {
87+
return localDC;
88+
}
89+
90+
public String getKeyStorePassword() {
91+
return keyStorePassword;
92+
}
93+
94+
public String getTrustStorePassword() {
95+
return trustStorePassword;
96+
}
97+
98+
public String getSniHost() {
99+
return sniHost;
100+
}
101+
102+
public void setSniHost(String sniHost) {
103+
this.sniHost = sniHost;
104+
}
105+
106+
public int getSniPort() {
107+
return sniPort;
108+
}
109+
110+
public void setSniPort(int sniPort) {
111+
this.sniPort = sniPort;
112+
}
113+
114+
public List<String> getHostIds() {
115+
return hostIds;
116+
}
117+
118+
public void setHostIds(List<String> hostIds) {
119+
this.hostIds = hostIds;
120+
}
121+
122+
public Path getSecureConnectBundlePath() {
123+
return secureConnectBundlePath;
124+
}
125+
126+
public void setSecureConnectBundlePath(Path secureConnectBundlePath) {
127+
this.secureConnectBundlePath = secureConnectBundlePath;
128+
}
129+
}

0 commit comments

Comments
 (0)