Skip to content

Commit

Permalink
feat: exposes default leader in database, and leader options / replic…
Browse files Browse the repository at this point in the history
…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 d72c2f7
Show file tree
Hide file tree
Showing 11 changed files with 561 additions and 37 deletions.
Expand Up @@ -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();
}
Expand Down
Expand Up @@ -24,6 +24,7 @@

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

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

Expand All @@ -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. */
Expand All @@ -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) {
Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
Expand All @@ -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) {
Expand All @@ -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;
}

Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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);
}
}
Expand Up @@ -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}.
Expand All @@ -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;
}

Expand All @@ -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);
}
}
Expand Up @@ -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;
}
Expand All @@ -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.