Skip to content

Commit d72c2f7

Browse files
authored
feat: exposes default leader in database, and leader options / replicas in instance config (#1283)
* feat: expose leader options in instance config Exposes the list of leader options for an instance from an instance config. * feat: expose default leader in database * test: add it test for instance leader options * test: add it test for database default leader * feat: create replica info / type model * feat: expose replicas in instance config * test: add it test for replicas in instance config * test: skip leader tests for emulator * test: skip emulator for instance admin test Skips leader options / replicas checking related tests for the emulator. * docs: add link for leader config accepted values * docs: fix the link for replica infos. * test: skip / removes leader tests We decided not to have setting the default leader tests, because it requires a multi-regional instance. The one we currently have for running the tests is regional, so the cost of setup would not justify the testing. We also skip the get leader options test, since the feature is not enabled in production yet.
1 parent dc736d5 commit d72c2f7

File tree

11 files changed

+561
-37
lines changed

11 files changed

+561
-37
lines changed

google-cloud-spanner/src/main/java/com/google/cloud/spanner/Database.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ static Database fromProto(
187187
.setVersionRetentionPeriod(proto.getVersionRetentionPeriod())
188188
.setEarliestVersionTime(Timestamp.fromProto(proto.getEarliestVersionTime()))
189189
.setEncryptionConfig(CustomerManagedEncryption.fromProtoOrNull(proto.getEncryptionConfig()))
190+
.setDefaultLeader(proto.getDefaultLeader())
190191
.setProto(proto)
191192
.build();
192193
}

google-cloud-spanner/src/main/java/com/google/cloud/spanner/DatabaseInfo.java

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
/** Represents a Cloud Spanner database. */
2626
public class DatabaseInfo {
27+
2728
public abstract static class Builder {
2829
abstract Builder setState(State state);
2930

@@ -44,6 +45,15 @@ public abstract static class Builder {
4445
*/
4546
public abstract Builder setEncryptionConfig(CustomerManagedEncryption encryptionConfig);
4647

48+
/**
49+
* The read-write region which will be used for the database's leader replicas. This can be one
50+
* of the values as specified in
51+
* https://cloud.google.com/spanner/docs/instances#available-configurations-multi-region.
52+
*/
53+
public Builder setDefaultLeader(String defaultLeader) {
54+
throw new UnsupportedOperationException("Unimplemented");
55+
}
56+
4757
abstract Builder setProto(com.google.spanner.admin.database.v1.Database proto);
4858

4959
/** Builds the database from this builder. */
@@ -58,6 +68,7 @@ abstract static class BuilderImpl extends Builder {
5868
private String versionRetentionPeriod;
5969
private Timestamp earliestVersionTime;
6070
private CustomerManagedEncryption encryptionConfig;
71+
private String defaultLeader;
6172
private com.google.spanner.admin.database.v1.Database proto;
6273

6374
BuilderImpl(DatabaseId id) {
@@ -72,6 +83,7 @@ abstract static class BuilderImpl extends Builder {
7283
this.versionRetentionPeriod = other.versionRetentionPeriod;
7384
this.earliestVersionTime = other.earliestVersionTime;
7485
this.encryptionConfig = other.encryptionConfig;
86+
this.defaultLeader = other.defaultLeader;
7587
this.proto = other.proto;
7688
}
7789

@@ -111,6 +123,12 @@ public Builder setEncryptionConfig(@Nullable CustomerManagedEncryption encryptio
111123
return this;
112124
}
113125

126+
@Override
127+
public Builder setDefaultLeader(String defaultLeader) {
128+
this.defaultLeader = defaultLeader;
129+
return this;
130+
}
131+
114132
@Override
115133
Builder setProto(@Nullable com.google.spanner.admin.database.v1.Database proto) {
116134
this.proto = proto;
@@ -137,6 +155,7 @@ public enum State {
137155
private final String versionRetentionPeriod;
138156
private final Timestamp earliestVersionTime;
139157
private final CustomerManagedEncryption encryptionConfig;
158+
private final String defaultLeader;
140159
private final com.google.spanner.admin.database.v1.Database proto;
141160

142161
public DatabaseInfo(DatabaseId id, State state) {
@@ -147,6 +166,7 @@ public DatabaseInfo(DatabaseId id, State state) {
147166
this.versionRetentionPeriod = null;
148167
this.earliestVersionTime = null;
149168
this.encryptionConfig = null;
169+
this.defaultLeader = null;
150170
this.proto = null;
151171
}
152172

@@ -158,6 +178,7 @@ public DatabaseInfo(DatabaseId id, State state) {
158178
this.versionRetentionPeriod = builder.versionRetentionPeriod;
159179
this.earliestVersionTime = builder.earliestVersionTime;
160180
this.encryptionConfig = builder.encryptionConfig;
181+
this.defaultLeader = builder.defaultLeader;
161182
this.proto = builder.proto;
162183
}
163184

@@ -209,6 +230,15 @@ public Timestamp getEarliestVersionTime() {
209230
return encryptionConfig;
210231
}
211232

233+
/**
234+
* The read-write region which contains the database's leader replicas. If this value was not
235+
* explicitly set during a create database or update database ddl operations, it will be {@code
236+
* NULL}.
237+
*/
238+
public @Nullable String getDefaultLeader() {
239+
return defaultLeader;
240+
}
241+
212242
/** Returns the raw proto instance that was used to construct this {@link Database}. */
213243
public @Nullable com.google.spanner.admin.database.v1.Database getProto() {
214244
return proto;
@@ -229,7 +259,8 @@ public boolean equals(Object o) {
229259
&& Objects.equals(restoreInfo, that.restoreInfo)
230260
&& Objects.equals(versionRetentionPeriod, that.versionRetentionPeriod)
231261
&& Objects.equals(earliestVersionTime, that.earliestVersionTime)
232-
&& Objects.equals(encryptionConfig, that.encryptionConfig);
262+
&& Objects.equals(encryptionConfig, that.encryptionConfig)
263+
&& Objects.equals(defaultLeader, that.defaultLeader);
233264
}
234265

235266
@Override
@@ -241,19 +272,21 @@ public int hashCode() {
241272
restoreInfo,
242273
versionRetentionPeriod,
243274
earliestVersionTime,
244-
encryptionConfig);
275+
encryptionConfig,
276+
defaultLeader);
245277
}
246278

247279
@Override
248280
public String toString() {
249281
return String.format(
250-
"Database[%s, %s, %s, %s, %s, %s, %s]",
282+
"Database[%s, %s, %s, %s, %s, %s, %s, %s]",
251283
id.getName(),
252284
state,
253285
createTime,
254286
restoreInfo,
255287
versionRetentionPeriod,
256288
earliestVersionTime,
257-
encryptionConfig);
289+
encryptionConfig,
290+
defaultLeader);
258291
}
259292
}

google-cloud-spanner/src/main/java/com/google/cloud/spanner/InstanceConfig.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616

1717
package com.google.cloud.spanner;
1818

19+
import java.util.Collections;
20+
import java.util.List;
21+
import java.util.stream.Collectors;
22+
1923
/**
2024
* Represents a Cloud Spanner instance config.{@code InstanceConfig} adds a layer of service related
2125
* functionality over {@code InstanceConfigInfo}.
@@ -25,7 +29,16 @@ public class InstanceConfig extends InstanceConfigInfo {
2529
private final InstanceAdminClient client;
2630

2731
public InstanceConfig(InstanceConfigId id, String displayName, InstanceAdminClient client) {
28-
super(id, displayName);
32+
this(id, displayName, Collections.emptyList(), Collections.emptyList(), client);
33+
}
34+
35+
public InstanceConfig(
36+
InstanceConfigId id,
37+
String displayName,
38+
List<ReplicaInfo> replicas,
39+
List<String> leaderOptions,
40+
InstanceAdminClient client) {
41+
super(id, displayName, replicas, leaderOptions);
2942
this.client = client;
3043
}
3144

@@ -36,6 +49,11 @@ public InstanceConfig reload() {
3649

3750
static InstanceConfig fromProto(
3851
com.google.spanner.admin.instance.v1.InstanceConfig proto, InstanceAdminClient client) {
39-
return new InstanceConfig(InstanceConfigId.of(proto.getName()), proto.getDisplayName(), client);
52+
return new InstanceConfig(
53+
InstanceConfigId.of(proto.getName()),
54+
proto.getDisplayName(),
55+
proto.getReplicasList().stream().map(ReplicaInfo::fromProto).collect(Collectors.toList()),
56+
proto.getLeaderOptionsList(),
57+
client);
4058
}
4159
}

google-cloud-spanner/src/main/java/com/google/cloud/spanner/InstanceConfigInfo.java

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,34 @@
1616

1717
package com.google.cloud.spanner;
1818

19+
import java.util.Collections;
20+
import java.util.List;
1921
import java.util.Objects;
2022

2123
/** Represents a Cloud Spanner instance config resource. */
2224
public class InstanceConfigInfo {
2325

2426
private final InstanceConfigId id;
2527
private final String displayName;
28+
private final List<ReplicaInfo> replicas;
29+
private final List<String> leaderOptions;
2630

2731
public InstanceConfigInfo(InstanceConfigId id, String displayName) {
32+
this(id, displayName, Collections.emptyList(), Collections.emptyList());
33+
}
34+
35+
public InstanceConfigInfo(
36+
InstanceConfigId id,
37+
String displayName,
38+
List<ReplicaInfo> replicas,
39+
List<String> leaderOptions) {
2840
this.id = id;
2941
this.displayName = displayName;
42+
this.replicas = replicas;
43+
this.leaderOptions = leaderOptions;
3044
}
3145

32-
/*
33-
* Returns the id of this instance config.
34-
*/
46+
/** Returns the id of this instance config. */
3547
public InstanceConfigId getId() {
3648
return id;
3749
}
@@ -41,25 +53,45 @@ public String getDisplayName() {
4153
return displayName;
4254
}
4355

44-
@Override
45-
public int hashCode() {
46-
return Objects.hash(id, displayName);
56+
/**
57+
* The geographic placement of nodes in this instance configuration and their replication
58+
* properties.
59+
*/
60+
public List<ReplicaInfo> getReplicas() {
61+
return replicas;
62+
}
63+
64+
/**
65+
* Allowed values of the default leader schema option for databases in instances that use this
66+
* instance configuration.
67+
*/
68+
public List<String> getLeaderOptions() {
69+
return leaderOptions;
4770
}
4871

4972
@Override
5073
public boolean equals(Object o) {
5174
if (this == o) {
5275
return true;
5376
}
54-
if (o == null || getClass() != o.getClass()) {
77+
if (!(o instanceof InstanceConfigInfo)) {
5578
return false;
5679
}
5780
InstanceConfigInfo that = (InstanceConfigInfo) o;
58-
return that.id.equals(id) && that.displayName.equals(displayName);
81+
return Objects.equals(id, that.id)
82+
&& Objects.equals(displayName, that.displayName)
83+
&& Objects.equals(replicas, that.replicas)
84+
&& Objects.equals(leaderOptions, that.leaderOptions);
85+
}
86+
87+
@Override
88+
public int hashCode() {
89+
return Objects.hash(id, displayName, replicas, leaderOptions);
5990
}
6091

6192
@Override
6293
public String toString() {
63-
return String.format("Instance Config[%s, %s]", id, displayName);
94+
return String.format(
95+
"Instance Config[%s, %s, %s, %s]", id, displayName, replicas, leaderOptions);
6496
}
6597
}

0 commit comments

Comments
 (0)