Skip to content
Permalink
Browse files
feat: exposes default leader in database, and leader options / replic…
…as 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.
  • Loading branch information
thiagotnunes committed Jul 19, 2021
1 parent dc736d5 commit d72c2f79f8cf0b83da00060587a079ce859c87a2
@@ -187,6 +187,7 @@ static Database fromProto(
.setVersionRetentionPeriod(proto.getVersionRetentionPeriod())
.setEarliestVersionTime(Timestamp.fromProto(proto.getEarliestVersionTime()))
.setEncryptionConfig(CustomerManagedEncryption.fromProtoOrNull(proto.getEncryptionConfig()))
.setDefaultLeader(proto.getDefaultLeader())
.setProto(proto)
.build();
}
@@ -24,6 +24,7 @@

/** Represents a Cloud Spanner database. */
public class DatabaseInfo {

public abstract static class Builder {
abstract Builder setState(State state);

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

/**
* The read-write region which will be used for the database's leader replicas. This can be one
* of the values as specified in
* https://cloud.google.com/spanner/docs/instances#available-configurations-multi-region.
*/
public Builder setDefaultLeader(String defaultLeader) {
throw new UnsupportedOperationException("Unimplemented");
}

abstract Builder setProto(com.google.spanner.admin.database.v1.Database proto);

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

BuilderImpl(DatabaseId id) {
@@ -72,6 +83,7 @@ abstract static class BuilderImpl extends Builder {
this.versionRetentionPeriod = other.versionRetentionPeriod;
this.earliestVersionTime = other.earliestVersionTime;
this.encryptionConfig = other.encryptionConfig;
this.defaultLeader = other.defaultLeader;
this.proto = other.proto;
}

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

@Override
public Builder setDefaultLeader(String defaultLeader) {
this.defaultLeader = defaultLeader;
return this;
}

@Override
Builder setProto(@Nullable com.google.spanner.admin.database.v1.Database proto) {
this.proto = proto;
@@ -137,6 +155,7 @@ public enum State {
private final String versionRetentionPeriod;
private final Timestamp earliestVersionTime;
private final CustomerManagedEncryption encryptionConfig;
private final String defaultLeader;
private final com.google.spanner.admin.database.v1.Database proto;

public DatabaseInfo(DatabaseId id, State state) {
@@ -147,6 +166,7 @@ public DatabaseInfo(DatabaseId id, State state) {
this.versionRetentionPeriod = null;
this.earliestVersionTime = null;
this.encryptionConfig = null;
this.defaultLeader = null;
this.proto = null;
}

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

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

/**
* The read-write region which contains the database's leader replicas. If this value was not
* explicitly set during a create database or update database ddl operations, it will be {@code
* NULL}.
*/
public @Nullable String getDefaultLeader() {
return defaultLeader;
}

/** Returns the raw proto instance that was used to construct this {@link Database}. */
public @Nullable com.google.spanner.admin.database.v1.Database getProto() {
return proto;
@@ -229,7 +259,8 @@ public boolean equals(Object o) {
&& Objects.equals(restoreInfo, that.restoreInfo)
&& Objects.equals(versionRetentionPeriod, that.versionRetentionPeriod)
&& Objects.equals(earliestVersionTime, that.earliestVersionTime)
&& Objects.equals(encryptionConfig, that.encryptionConfig);
&& Objects.equals(encryptionConfig, that.encryptionConfig)
&& Objects.equals(defaultLeader, that.defaultLeader);
}

@Override
@@ -241,19 +272,21 @@ public int hashCode() {
restoreInfo,
versionRetentionPeriod,
earliestVersionTime,
encryptionConfig);
encryptionConfig,
defaultLeader);
}

@Override
public String toString() {
return String.format(
"Database[%s, %s, %s, %s, %s, %s, %s]",
"Database[%s, %s, %s, %s, %s, %s, %s, %s]",
id.getName(),
state,
createTime,
restoreInfo,
versionRetentionPeriod,
earliestVersionTime,
encryptionConfig);
encryptionConfig,
defaultLeader);
}
}
@@ -16,6 +16,10 @@

package com.google.cloud.spanner;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
* Represents a Cloud Spanner instance config.{@code InstanceConfig} adds a layer of service related
* functionality over {@code InstanceConfigInfo}.
@@ -25,7 +29,16 @@ public class InstanceConfig extends InstanceConfigInfo {
private final InstanceAdminClient client;

public InstanceConfig(InstanceConfigId id, String displayName, InstanceAdminClient client) {
super(id, displayName);
this(id, displayName, Collections.emptyList(), Collections.emptyList(), client);
}

public InstanceConfig(
InstanceConfigId id,
String displayName,
List<ReplicaInfo> replicas,
List<String> leaderOptions,
InstanceAdminClient client) {
super(id, displayName, replicas, leaderOptions);
this.client = client;
}

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

static InstanceConfig fromProto(
com.google.spanner.admin.instance.v1.InstanceConfig proto, InstanceAdminClient client) {
return new InstanceConfig(InstanceConfigId.of(proto.getName()), proto.getDisplayName(), client);
return new InstanceConfig(
InstanceConfigId.of(proto.getName()),
proto.getDisplayName(),
proto.getReplicasList().stream().map(ReplicaInfo::fromProto).collect(Collectors.toList()),
proto.getLeaderOptionsList(),
client);
}
}
@@ -16,22 +16,34 @@

package com.google.cloud.spanner;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

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

private final InstanceConfigId id;
private final String displayName;
private final List<ReplicaInfo> replicas;
private final List<String> leaderOptions;

public InstanceConfigInfo(InstanceConfigId id, String displayName) {
this(id, displayName, Collections.emptyList(), Collections.emptyList());
}

public InstanceConfigInfo(
InstanceConfigId id,
String displayName,
List<ReplicaInfo> replicas,
List<String> leaderOptions) {
this.id = id;
this.displayName = displayName;
this.replicas = replicas;
this.leaderOptions = leaderOptions;
}

/*
* Returns the id of this instance config.
*/
/** Returns the id of this instance config. */
public InstanceConfigId getId() {
return id;
}
@@ -41,25 +53,45 @@ public String getDisplayName() {
return displayName;
}

@Override
public int hashCode() {
return Objects.hash(id, displayName);
/**
* The geographic placement of nodes in this instance configuration and their replication
* properties.
*/
public List<ReplicaInfo> getReplicas() {
return replicas;
}

/**
* Allowed values of the default leader schema option for databases in instances that use this
* instance configuration.
*/
public List<String> getLeaderOptions() {
return leaderOptions;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
if (!(o instanceof InstanceConfigInfo)) {
return false;
}
InstanceConfigInfo that = (InstanceConfigInfo) o;
return that.id.equals(id) && that.displayName.equals(displayName);
return Objects.equals(id, that.id)
&& Objects.equals(displayName, that.displayName)
&& Objects.equals(replicas, that.replicas)
&& Objects.equals(leaderOptions, that.leaderOptions);
}

@Override
public int hashCode() {
return Objects.hash(id, displayName, replicas, leaderOptions);
}

@Override
public String toString() {
return String.format("Instance Config[%s, %s]", id, displayName);
return String.format(
"Instance Config[%s, %s, %s, %s]", id, displayName, replicas, leaderOptions);
}
}

0 comments on commit d72c2f7

Please sign in to comment.