Skip to content
This repository was archived by the owner on May 8, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
package com.google.cloud.bigtable.data.v2;

import com.google.api.core.BetaApi;
import com.google.bigtable.v2.InstanceName;
import com.google.cloud.bigtable.data.v2.internal.api.InstanceName;
import com.google.cloud.bigtable.data.v2.stub.BigtableClientContext;
import com.google.cloud.bigtable.data.v2.stub.ClientOperationSettings;
import com.google.cloud.bigtable.data.v2.stub.EnhancedBigtableStub;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ public abstract class RequestContext implements Serializable {

public static RequestContext create(ClientInfo clientInfo) {
return create(
clientInfo.getInstanceName().getProject(),
clientInfo.getInstanceName().getInstance(),
clientInfo.getInstanceName().getProjectId(),
clientInfo.getInstanceName().getInstanceId(),
clientInfo.getAppProfileId());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright 2025 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.cloud.bigtable.data.v2.internal.api;

import com.google.auto.value.AutoValue;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import java.util.List;

@AutoValue
public abstract class InstanceName {
public abstract String getProjectId();

public abstract String getInstanceId();

@Override
public final String toString() {
return String.format("projects/%s/instances/%s", getProjectId(), getInstanceId());
}

public static InstanceName of(String projectId, String instanceId) {
return InstanceName.builder().setProjectId(projectId).setInstanceId(instanceId).build();
}

public static Builder builder() {
return new AutoValue_InstanceName.Builder();
}

public static InstanceName parse(String name) {
List<String> parts = Splitter.on('/').splitToList(name);
Preconditions.checkArgument(parts.size() == 4, "Invalid instance name: %s", name);
Preconditions.checkArgument(
"projects".equals(parts.get(0)),
"Invalid instance name: %s, must start with projects/",
name);
Preconditions.checkArgument(
!parts.get(1).isEmpty(), "Invalid instance name %s, must have a project id", name);
Preconditions.checkArgument(
"instances".equals(parts.get(2)),
"Invalid instance name: %s, must start with projects/$PROJECT_ID/instances/",
name);
Preconditions.checkArgument(
!parts.get(3).isEmpty(), "Invalid instance name %s, must have an instance id", name);

return builder().setProjectId(parts.get(1)).setInstanceId(parts.get(3)).build();
}

@AutoValue.Builder
public abstract static class Builder {
public abstract Builder setProjectId(String projectId);

public abstract Builder setInstanceId(String instanceId);

public abstract InstanceName build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright 2025 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.cloud.bigtable.data.v2.internal.api;

import com.google.auto.value.AutoValue;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import java.util.List;

@AutoValue
public abstract class TableName {
public abstract String getProjectId();

public abstract String getInstanceId();

public abstract String getTableId();

public InstanceName getInstanceName() {
return InstanceName.builder()
.setProjectId(getProjectId())
.setInstanceId(getInstanceId())
.build();
}

@Override
public final String toString() {
return String.format("%s/tables/%s", getInstanceName(), getTableId());
}

public static Builder builder() {
return new AutoValue_TableName.Builder();
}

public static TableName parse(String name) {
List<String> parts = Splitter.on('/').splitToList(name);
Preconditions.checkArgument(parts.size() == 6, "Invalid table name: %s", name);
Preconditions.checkArgument(
"projects".equals(parts.get(0)), "Invalid table name: %s, must start with projects/", name);
Preconditions.checkArgument(
!parts.get(1).isEmpty(), "Invalid table name %s, must have a project id", name);
Preconditions.checkArgument(
"instances".equals(parts.get(2)),
"Invalid table name: %s, must start with projects/$PROJECT_ID/instances/",
name);
Preconditions.checkArgument(
!parts.get(3).isEmpty(), "Invalid table name %s, must have an instance id", name);
Preconditions.checkArgument(
"tables".equals(parts.get(4)),
"Invalid table name: %s, must start with"
+ " projects/$PROJECT_ID/instances/$INSTANCE_ID/tables",
name);
Preconditions.checkArgument(
!parts.get(5).isEmpty(), "Invalid table name %s, must have table id", name);

return builder()
.setProjectId(parts.get(1))
.setInstanceId(parts.get(3))
.setTableId(parts.get(5))
.build();
}

@AutoValue.Builder
public abstract static class Builder {
public abstract Builder setProjectId(String projectId);

public abstract Builder setInstanceId(String instanceId);

public abstract Builder setTableId(String tableId);

public abstract TableName build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,10 @@ private static ApiTracerFactory createOCTracingFactory(ClientInfo clientInfo) {
// Annotate traces with the same tags as metrics
.put(
RpcMeasureConstants.BIGTABLE_PROJECT_ID.getName(),
clientInfo.getInstanceName().getProject())
clientInfo.getInstanceName().getProjectId())
.put(
RpcMeasureConstants.BIGTABLE_INSTANCE_ID.getName(),
clientInfo.getInstanceName().getInstance())
clientInfo.getInstanceName().getInstanceId())
.put(
RpcMeasureConstants.BIGTABLE_APP_PROFILE_ID.getName(), clientInfo.getAppProfileId())
// Also annotate traces with library versions
Expand All @@ -222,10 +222,10 @@ private static ApiTracerFactory createOCMetricsFactory(
ImmutableMap.<TagKey, TagValue>builder()
.put(
RpcMeasureConstants.BIGTABLE_PROJECT_ID,
TagValue.create(clientInfo.getInstanceName().getProject()))
TagValue.create(clientInfo.getInstanceName().getProjectId()))
.put(
RpcMeasureConstants.BIGTABLE_INSTANCE_ID,
TagValue.create(clientInfo.getInstanceName().getInstance()))
TagValue.create(clientInfo.getInstanceName().getInstanceId()))
.put(
RpcMeasureConstants.BIGTABLE_APP_PROFILE_ID,
TagValue.create(clientInfo.getAppProfileId()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
package com.google.cloud.bigtable.data.v2.internal.csm.attributes;

import com.google.auto.value.AutoValue;
import com.google.bigtable.v2.InstanceName;
import com.google.cloud.bigtable.Version;
import com.google.cloud.bigtable.data.v2.internal.api.InstanceName;

/**
* A value class to capture parameters that the client was instantiated with. These parameters will
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ public void onFailure(Throwable throwable) {
" Need monitoring metric writer permission on project=%s. Follow"
+ " https://cloud.google.com/bigtable/docs/client-side-metrics-setup"
+ " to set up permissions.",
clientInfo.getInstanceName().getProject());
clientInfo.getInstanceName().getProjectId());
}
RuntimeException asyncWrapper = new RuntimeException("export failed", throwable);
asyncWrapper.setStackTrace(stackTrace);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,9 @@ public void record(ClientInfo clientInfo, long value) {
Attributes attributes =
getSchema()
.createResourceAttrs(clientInfo)
.put(MetricLabels.BIGTABLE_PROJECT_ID_KEY, clientInfo.getInstanceName().getProject())
.put(MetricLabels.INSTANCE_ID_KEY, clientInfo.getInstanceName().getInstance())
.put(
MetricLabels.BIGTABLE_PROJECT_ID_KEY, clientInfo.getInstanceName().getProjectId())
.put(MetricLabels.INSTANCE_ID_KEY, clientInfo.getInstanceName().getInstanceId())
.put(MetricLabels.CLIENT_NAME, clientInfo.getClientName())
.put(MetricLabels.APP_PROFILE_KEY, clientInfo.getAppProfileId())
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ public ClientSchema() {

@Override
public ProjectName extractProjectName(Attributes attrs, EnvInfo envInfo, ClientInfo clientInfo) {
return ProjectName.of(clientInfo.getInstanceName().getProject());
return ProjectName.of(clientInfo.getInstanceName().getProjectId());
}

public AttributesBuilder createResourceAttrs(ClientInfo clientInfo) {
return Attributes.builder()
.put(BIGTABLE_PROJECT_ID_KEY, clientInfo.getInstanceName().getProject())
.put(INSTANCE_ID_KEY, clientInfo.getInstanceName().getInstance())
.put(BIGTABLE_PROJECT_ID_KEY, clientInfo.getInstanceName().getProjectId())
.put(INSTANCE_ID_KEY, clientInfo.getInstanceName().getInstanceId())
.put(APP_PROFILE_KEY, clientInfo.getAppProfileId())
.put(CLIENT_NAME, clientInfo.getClientName());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
public final class GrpcClientSchema extends Schema {
// Unlike the normal ClientSchema, the bigtable resource ids must be injected during export time
private static final DeferredAttr BIGTABLE_PROJECT_ID =
DeferredAttr.fromClientInfo("project_id", ci -> ci.getInstanceName().getProject());
DeferredAttr.fromClientInfo("project_id", ci -> ci.getInstanceName().getProjectId());
private static final DeferredAttr INSTANCE_ID =
DeferredAttr.fromClientInfo("instance", ci -> ci.getInstanceName().getInstance());
DeferredAttr.fromClientInfo("instance", ci -> ci.getInstanceName().getInstanceId());
private static final DeferredAttr APP_PROFILE_ID =
DeferredAttr.fromClientInfo("app_profile", ClientInfo::getAppProfileId);
private static final DeferredAttr CLIENT_NAME =
Expand Down Expand Up @@ -73,6 +73,6 @@ private GrpcClientSchema() {
@Override
public ProjectName extractProjectName(
Attributes ignored, EnvInfo ignored2, ClientInfo clientInfo) {
return ProjectName.of(clientInfo.getInstanceName().getProject());
return ProjectName.of(clientInfo.getInstanceName().getProjectId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ public ProjectName extractProjectName(Attributes attrs, EnvInfo envInfo, ClientI
public AttributesBuilder createResourceAttrs(
ClientInfo clientInfo, String tableId, @Nullable ResponseParams clusterInfo) {
return Attributes.builder()
.put(BIGTABLE_PROJECT_ID_KEY, clientInfo.getInstanceName().getProject())
.put(INSTANCE_ID_KEY, clientInfo.getInstanceName().getInstance())
.put(BIGTABLE_PROJECT_ID_KEY, clientInfo.getInstanceName().getProjectId())
.put(INSTANCE_ID_KEY, clientInfo.getInstanceName().getInstanceId())
.put(TABLE_ID_KEY, tableId)
.put(CLUSTER_ID_KEY, Util.formatClusterIdMetricLabel(clusterInfo))
.put(ZONE_ID_KEY, Util.formatZoneIdMetricLabel(clusterInfo));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
import com.google.api.core.SettableApiFuture;
import com.google.auth.Credentials;
import com.google.bigtable.v2.BigtableGrpc;
import com.google.bigtable.v2.InstanceName;
import com.google.bigtable.v2.PingAndWarmRequest;
import com.google.bigtable.v2.PingAndWarmResponse;
import com.google.cloud.bigtable.data.v2.internal.api.InstanceName;
import com.google.cloud.bigtable.gaxx.grpc.ChannelPrimer;
import io.grpc.CallCredentials;
import io.grpc.CallOptions;
Expand Down Expand Up @@ -80,7 +80,7 @@ static BigtableChannelPrimer create(

request =
PingAndWarmRequest.newBuilder()
.setName(InstanceName.format(projectId, instanceId))
.setName(InstanceName.of(projectId, instanceId).toString())
.setAppProfileId(appProfileId)
.build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
import com.google.api.gax.rpc.ClientContext;
import com.google.auth.Credentials;
import com.google.auth.oauth2.ServiceAccountJwtAccessCredentials;
import com.google.bigtable.v2.InstanceName;
import com.google.cloud.bigtable.data.v2.internal.JwtCredentialsWithAudience;
import com.google.cloud.bigtable.data.v2.internal.api.InstanceName;
import com.google.cloud.bigtable.data.v2.internal.csm.MetricRegistry;
import com.google.cloud.bigtable.data.v2.internal.csm.Metrics;
import com.google.cloud.bigtable.data.v2.internal.csm.MetricsImpl;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright 2025 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.cloud.bigtable.data.v2.internal.api;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;

class InstanceNameTest {

@Test
void testParseOk() {
assertThat(InstanceName.parse("projects/my-project/instances/my-instance"))
.isEqualTo(
InstanceName.builder().setProjectId("my-project").setInstanceId("my-instance").build());
}

@Test
void testParseFail() {
assertThrows(IllegalArgumentException.class, () -> InstanceName.parse(""));
assertThrows(IllegalArgumentException.class, () -> InstanceName.parse("projects/my-project"));
assertThrows(
IllegalArgumentException.class, () -> TableName.parse("projects/my-project/instances"));
assertThrows(
IllegalArgumentException.class,
() -> InstanceName.parse("projects/my-project/instances/my-instance/extra"));
assertThrows(
IllegalArgumentException.class,
() -> InstanceName.parse("projects//instances/my-instance"));
assertThrows(
IllegalArgumentException.class, () -> InstanceName.parse("projects/my-project/instances/"));
assertThrows(
IllegalArgumentException.class,
() -> InstanceName.parse("projects/my-project/instances//"));
}
}
Loading
Loading