Skip to content

Commit

Permalink
feat: admin API changes for databoost (#2181)
Browse files Browse the repository at this point in the history
* feat: add Data Boost configurations to admin API

PiperOrigin-RevId: 617925342

Source-Link: googleapis/googleapis@6f289d7

Source-Link: googleapis/googleapis-gen@92da6d5
Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiOTJkYTZkNWQ0MzVhZjUzM2Y3MjZhOTdiY2ZmZjNjNzE3ODMyYzg3NyJ9

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* feat: admin API changes for databoost

* 🦉 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* add a integration test

* update integration test

---------

Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
  • Loading branch information
mutianf and gcf-owl-bot[bot] committed Apr 22, 2024
1 parent 83a196f commit 3b1886b
Show file tree
Hide file tree
Showing 7 changed files with 263 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.google.cloud.bigtable.admin.v2.models;

import com.google.api.core.InternalApi;
import com.google.bigtable.admin.v2.AppProfile.DataBoostIsolationReadOnly;
import com.google.bigtable.admin.v2.AppProfile.MultiClusterRoutingUseAny;
import com.google.bigtable.admin.v2.AppProfile.Priority;
import com.google.bigtable.admin.v2.AppProfile.StandardIsolation;
Expand Down Expand Up @@ -81,6 +82,8 @@ public RoutingPolicy getPolicy() {
public IsolationPolicy getIsolationPolicy() {
if (proto.hasStandardIsolation()) {
return new StandardIsolationPolicy(proto.getStandardIsolation());
} else if (proto.hasDataBoostIsolationReadOnly()) {
return new DataBoostIsolationReadOnlyPolicy(proto.getDataBoostIsolationReadOnly());
} else {
// Should never happen because the constructor verifies that one must exist.
throw new IllegalStateException();
Expand Down Expand Up @@ -409,4 +412,105 @@ public int hashCode() {
return Objects.hashCode(proto);
}
}

/** Compute Billing Owner specifies how usage should be accounted when using Data Boost. */
public static enum ComputeBillingOwner {
UNSPECIFIED(DataBoostIsolationReadOnly.ComputeBillingOwner.COMPUTE_BILLING_OWNER_UNSPECIFIED),
HOST_PAYS(DataBoostIsolationReadOnly.ComputeBillingOwner.HOST_PAYS),
UNRECOGNIZED(DataBoostIsolationReadOnly.ComputeBillingOwner.UNRECOGNIZED);

private final com.google.bigtable.admin.v2.AppProfile.DataBoostIsolationReadOnly
.ComputeBillingOwner
proto;

/**
* Wraps the protobuf. This method is considered an internal implementation detail and not meant
* to be used by applications.
*/
@InternalApi
public static ComputeBillingOwner fromProto(
com.google.bigtable.admin.v2.AppProfile.DataBoostIsolationReadOnly.ComputeBillingOwner
proto) {
Preconditions.checkNotNull(proto);

for (ComputeBillingOwner owner : values()) {
if (owner.proto.equals(proto)) {
return owner;
}
}

return UNRECOGNIZED;
}

/**
* Creates the request protobuf. This method is considered an internal implementation detail and
* not meant to be used by applications.
*/
@InternalApi
public DataBoostIsolationReadOnly.ComputeBillingOwner toProto() {
return proto;
}

ComputeBillingOwner(DataBoostIsolationReadOnly.ComputeBillingOwner proto) {
this.proto = proto;
}
}

/**
* A Data Boost Read Only {@link IsolationPolicy} for running high-throughput read traffic on your
* Bigtable data without affecting application traffic. Data Boost App Profile needs to be created
* with a ComputeBillingOwner which specifies how usage should be accounted when using Data Boost.
*/
public static class DataBoostIsolationReadOnlyPolicy implements IsolationPolicy {
private final DataBoostIsolationReadOnly proto;

DataBoostIsolationReadOnlyPolicy(DataBoostIsolationReadOnly proto) {
this.proto = proto;
}

/**
* Creates a new instance of {@link DataBoostIsolationReadOnlyPolicy} with specified {@link
* ComputeBillingOwner}.
*/
public static DataBoostIsolationReadOnlyPolicy of(ComputeBillingOwner billingOwner) {
return new DataBoostIsolationReadOnlyPolicy(
DataBoostIsolationReadOnly.newBuilder()
.setComputeBillingOwner(billingOwner.toProto())
.build());
}

/**
* Gets the {@link ComputeBillingOwner} on the current {@link DataBoostIsolationReadOnlyPolicy}
* instance.
*/
public ComputeBillingOwner getComputeBillingOwner() {
return ComputeBillingOwner.fromProto(proto.getComputeBillingOwner());
}

/**
* Creates the request protobuf. This method is considered an internal implementation detail and
* not meant to be used by applications.
*/
@InternalApi
public DataBoostIsolationReadOnly toProto() {
return proto;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
DataBoostIsolationReadOnlyPolicy that = (DataBoostIsolationReadOnlyPolicy) o;
return Objects.equal(proto, that.proto);
}

@Override
public int hashCode() {
return Objects.hashCode(proto);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,15 @@ public CreateAppProfileRequest setRoutingPolicy(RoutingPolicy routingPolicy) {
/** Sets the isolation policy for all read/write requests that use this app profile. */
public CreateAppProfileRequest setIsolationPolicy(IsolationPolicy isolationPolicy) {
Preconditions.checkNotNull(isolationPolicy);

if (isolationPolicy instanceof StandardIsolationPolicy) {
proto
.getAppProfileBuilder()
.setStandardIsolation(((StandardIsolationPolicy) isolationPolicy).toProto());
} else if (isolationPolicy instanceof AppProfile.DataBoostIsolationReadOnlyPolicy) {
proto
.getAppProfileBuilder()
.setDataBoostIsolationReadOnly(
((AppProfile.DataBoostIsolationReadOnlyPolicy) isolationPolicy).toProto());
} else {
throw new IllegalArgumentException("Unknown policy type: " + isolationPolicy);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import com.google.api.core.InternalApi;
import com.google.cloud.bigtable.admin.v2.internal.NameUtil;
import com.google.cloud.bigtable.admin.v2.models.AppProfile.DataBoostIsolationReadOnlyPolicy;
import com.google.cloud.bigtable.admin.v2.models.AppProfile.IsolationPolicy;
import com.google.cloud.bigtable.admin.v2.models.AppProfile.MultiClusterRoutingPolicy;
import com.google.cloud.bigtable.admin.v2.models.AppProfile.RoutingPolicy;
Expand Down Expand Up @@ -132,6 +133,13 @@ public UpdateAppProfileRequest setIsolationPolicy(@Nonnull IsolationPolicy isola
.getAppProfileBuilder()
.setStandardIsolation(((StandardIsolationPolicy) isolationPolicy).toProto());
updateFieldMask(com.google.bigtable.admin.v2.AppProfile.STANDARD_ISOLATION_FIELD_NUMBER);
} else if (isolationPolicy instanceof DataBoostIsolationReadOnlyPolicy) {
proto
.getAppProfileBuilder()
.setDataBoostIsolationReadOnly(
((DataBoostIsolationReadOnlyPolicy) isolationPolicy).toProto());
updateFieldMask(
com.google.bigtable.admin.v2.AppProfile.DATA_BOOST_ISOLATION_READ_ONLY_FIELD_NUMBER);
} else {
throw new IllegalArgumentException("Unknown policy type: " + isolationPolicy);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,43 @@ public void appProfileTestPriority() {
}
}

@Test
public void appProfileTestDataBoost() {
String newInstanceId = prefixGenerator.newPrefix();
String newClusterId = newInstanceId + "-c1";

client.createInstance(
CreateInstanceRequest.of(newInstanceId)
.addCluster(newClusterId, testEnvRule.env().getPrimaryZone(), 1, StorageType.SSD)
.setDisplayName("Priority-Instance-Test")
.addLabel("state", "readytodelete")
.setType(Type.PRODUCTION));

try {
assertThat(client.exists(newInstanceId)).isTrue();

String testAppProfile = prefixGenerator.newPrefix();

CreateAppProfileRequest request =
CreateAppProfileRequest.of(newInstanceId, testAppProfile)
.setRoutingPolicy(AppProfile.SingleClusterRoutingPolicy.of(newClusterId))
.setIsolationPolicy(
AppProfile.DataBoostIsolationReadOnlyPolicy.of(
AppProfile.ComputeBillingOwner.HOST_PAYS))
.setDescription("databoost app profile");

AppProfile newlyCreateAppProfile = client.createAppProfile(request);
AppProfile.ComputeBillingOwner computeBillingOwner =
((AppProfile.DataBoostIsolationReadOnlyPolicy) newlyCreateAppProfile.getIsolationPolicy())
.getComputeBillingOwner();
assertThat(computeBillingOwner).isEqualTo(AppProfile.ComputeBillingOwner.HOST_PAYS);
} finally {
if (client.exists(newInstanceId)) {
client.deleteInstance(newInstanceId);
}
}
}

@Test
public void iamUpdateTest() {
Policy policy = client.getIamPolicy(instanceId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,4 +234,61 @@ public void testHashCode() {
assertThat(updateAppProfileRequest.hashCode())
.isNotEqualTo(updateAppProfileRequest3.hashCode());
}

@Test
public void testFromProtoWithDataBoostIsolation() {
AppProfile producer =
AppProfile.fromProto(
com.google.bigtable.admin.v2.AppProfile.newBuilder()
.setName(AppProfileName.of("my-project", "my-instance", "my-profile").toString())
.setDescription("my description")
.setSingleClusterRouting(
SingleClusterRouting.newBuilder()
.setClusterId("my-cluster")
.setAllowTransactionalWrites(true)
.build())
.setDataBoostIsolationReadOnly(
com.google.bigtable.admin.v2.AppProfile.DataBoostIsolationReadOnly.newBuilder()
.setComputeBillingOwner(
com.google.bigtable.admin.v2.AppProfile.DataBoostIsolationReadOnly
.ComputeBillingOwner.HOST_PAYS))
.setEtag("my-etag")
.build());

assertThat(producer.getInstanceId()).isEqualTo("my-instance");
assertThat(producer.getId()).isEqualTo("my-profile");
assertThat(producer.getDescription()).isEqualTo("my description");
assertThat(producer.getPolicy()).isEqualTo(SingleClusterRoutingPolicy.of("my-cluster", true));
assertThat(producer.getIsolationPolicy())
.isEqualTo(
AppProfile.DataBoostIsolationReadOnlyPolicy.of(
AppProfile.ComputeBillingOwner.HOST_PAYS));

AppProfile consumer =
AppProfile.fromProto(
com.google.bigtable.admin.v2.AppProfile.newBuilder()
.setName(AppProfileName.of("my-project", "my-instance", "my-profile").toString())
.setDescription("my description")
.setSingleClusterRouting(
SingleClusterRouting.newBuilder()
.setClusterId("my-cluster")
.setAllowTransactionalWrites(true)
.build())
.setDataBoostIsolationReadOnly(
com.google.bigtable.admin.v2.AppProfile.DataBoostIsolationReadOnly.newBuilder()
.setComputeBillingOwner(
com.google.bigtable.admin.v2.AppProfile.DataBoostIsolationReadOnly
.ComputeBillingOwner.COMPUTE_BILLING_OWNER_UNSPECIFIED))
.setEtag("my-etag")
.build());

assertThat(consumer.getInstanceId()).isEqualTo("my-instance");
assertThat(consumer.getId()).isEqualTo("my-profile");
assertThat(consumer.getDescription()).isEqualTo("my description");
assertThat(consumer.getPolicy()).isEqualTo(SingleClusterRoutingPolicy.of("my-cluster", true));
assertThat(consumer.getIsolationPolicy())
.isEqualTo(
AppProfile.DataBoostIsolationReadOnlyPolicy.of(
AppProfile.ComputeBillingOwner.UNSPECIFIED));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import static com.google.common.truth.Truth.assertThat;

import com.google.bigtable.admin.v2.AppProfile.DataBoostIsolationReadOnly;
import com.google.bigtable.admin.v2.AppProfile.MultiClusterRoutingUseAny;
import com.google.bigtable.admin.v2.AppProfile.SingleClusterRouting;
import com.google.bigtable.admin.v2.AppProfile.StandardIsolation;
Expand Down Expand Up @@ -84,4 +85,20 @@ public void testStandardIsolation() {
assertThat(wrapper.toProto("my-project").getAppProfile().getStandardIsolation())
.isEqualTo(StandardIsolation.getDefaultInstance());
}

@Test
public void testDataBoostIsolationReadOnly() {
CreateAppProfileRequest wrapper =
CreateAppProfileRequest.of("my-instance", "my-profile")
.setRoutingPolicy(MultiClusterRoutingPolicy.of())
.setIsolationPolicy(
AppProfile.DataBoostIsolationReadOnlyPolicy.of(
AppProfile.ComputeBillingOwner.HOST_PAYS));

assertThat(wrapper.toProto("my-project").getAppProfile().getDataBoostIsolationReadOnly())
.isEqualTo(
DataBoostIsolationReadOnly.newBuilder()
.setComputeBillingOwner(DataBoostIsolationReadOnly.ComputeBillingOwner.HOST_PAYS)
.build());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import static com.google.common.truth.Truth.assertThat;

import com.google.bigtable.admin.v2.AppProfile.DataBoostIsolationReadOnly;
import com.google.bigtable.admin.v2.AppProfile.MultiClusterRoutingUseAny;
import com.google.bigtable.admin.v2.AppProfile.SingleClusterRouting;
import com.google.bigtable.admin.v2.AppProfile.StandardIsolation;
Expand Down Expand Up @@ -111,4 +112,38 @@ public void testUpdateExistingStandardIsolation() {
.setUpdateMask(FieldMask.newBuilder().addPaths("standard_isolation"))
.build());
}

@Test
public void testUpdateExistingDataBoostIsolationReadOnly() {
com.google.bigtable.admin.v2.AppProfile existingProto =
com.google.bigtable.admin.v2.AppProfile.newBuilder()
.setName("projects/my-project/instances/my-instance/appProfiles/my-profile")
.setEtag("my-etag")
.setDescription("description")
.setMultiClusterRoutingUseAny(MultiClusterRoutingUseAny.getDefaultInstance())
.setStandardIsolation(StandardIsolation.getDefaultInstance())
.build();

AppProfile existingWrapper = AppProfile.fromProto(existingProto);

UpdateAppProfileRequest updateWrapper =
UpdateAppProfileRequest.of(existingWrapper)
.setIsolationPolicy(
AppProfile.DataBoostIsolationReadOnlyPolicy.of(
AppProfile.ComputeBillingOwner.HOST_PAYS));

assertThat(updateWrapper.toProto("my-project"))
.isEqualTo(
com.google.bigtable.admin.v2.UpdateAppProfileRequest.newBuilder()
.setAppProfile(
existingProto
.toBuilder()
.setDataBoostIsolationReadOnly(
DataBoostIsolationReadOnly.newBuilder()
.setComputeBillingOwner(
DataBoostIsolationReadOnly.ComputeBillingOwner.HOST_PAYS)
.build()))
.setUpdateMask(FieldMask.newBuilder().addPaths("data_boost_isolation_read_only"))
.build());
}
}

0 comments on commit 3b1886b

Please sign in to comment.