Skip to content
26 changes: 15 additions & 11 deletions google/cloud/bigtable/internal/bigtable_stub_factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@
#include "google/cloud/bigtable/internal/bigtable_round_robin_decorator.h"
#include "google/cloud/bigtable/internal/bigtable_tracing_stub.h"
#include "google/cloud/bigtable/internal/connection_refresh_state.h"
#include "google/cloud/bigtable/internal/defaults.h"
#include "google/cloud/bigtable/options.h"
#include "google/cloud/common_options.h"
#include "google/cloud/grpc_options.h"
#include "google/cloud/internal/algorithm.h"
#include "google/cloud/internal/api_client_header.h"
#include "google/cloud/internal/base64_transforms.h"
#include "google/cloud/internal/getenv.h"
#include "google/cloud/internal/opentelemetry.h"
#include "google/cloud/internal/unified_grpc_credentials.h"
#include "google/cloud/log.h"
Expand All @@ -47,17 +49,19 @@ std::shared_ptr<grpc::Channel> CreateGrpcChannel(
}

std::string FeaturesMetadata() {
static auto const* const kFeatures = new auto([] {
google::bigtable::v2::FeatureFlags proto;
proto.set_reverse_scans(true);
proto.set_last_scanned_row_responses(true);
proto.set_mutate_rows_rate_limit(true);
proto.set_mutate_rows_rate_limit2(true);
proto.set_routing_cookie(true);
proto.set_retry_info(true);
return internal::UrlsafeBase64Encode(proto.SerializeAsString());
}());
return *kFeatures;
google::bigtable::v2::FeatureFlags proto;
proto.set_reverse_scans(true);
proto.set_last_scanned_row_responses(true);
proto.set_mutate_rows_rate_limit(true);
proto.set_mutate_rows_rate_limit2(true);
proto.set_routing_cookie(true);
proto.set_retry_info(true);

if (bigtable::internal::EnableDirectAccess()) {
proto.set_traffic_director_enabled(true);
proto.set_direct_access_requested(true);
}
return internal::UrlsafeBase64Encode(proto.SerializeAsString());
}

} // namespace
Expand Down
25 changes: 13 additions & 12 deletions google/cloud/bigtable/internal/defaults.cc
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@ Options HandleUniverseDomain(Options opts) {
return opts;
}

bool EnableDirectAccess() {
absl::optional<std::string> env_directpath =
google::cloud::internal::GetEnv("CBT_ENABLE_DIRECTPATH");
return env_directpath.has_value() && env_directpath.value() == "true";
}

Options DefaultOptions(Options opts) {
using ::google::cloud::internal::GetEnv;
auto ud = GetEnv("GOOGLE_CLOUD_UNIVERSE_DOMAIN");
Expand All @@ -164,18 +170,13 @@ Options DefaultOptions(Options opts) {
}
}

auto const direct_path =
GetEnv("GOOGLE_CLOUD_ENABLE_DIRECT_PATH").value_or("");
if (absl::c_any_of(absl::StrSplit(direct_path, ','),
[](absl::string_view v) { return v == "bigtable"; })) {
opts.set<DataEndpointOption>(
"google-c2p:///directpath-bigtable.googleapis.com")
.set<AuthorityOption>("directpath-bigtable.googleapis.com");

// When using DirectPath the gRPC library already does load balancing across
// multiple sockets, it makes little sense to perform additional load
// balancing in the client library.
if (!opts.has<GrpcNumChannelsOption>()) opts.set<GrpcNumChannelsOption>(1);
if (EnableDirectAccess()) {
std::string endpoint = opts.get<EndpointOption>();
if (endpoint.empty()) {
endpoint = "bigtable.googleapis.com";
}
opts.set<DataEndpointOption>("c2p:///" + endpoint)
.set<AuthorityOption>(endpoint);
}

auto emulator = GetEnv("BIGTABLE_EMULATOR_HOST");
Expand Down
2 changes: 2 additions & 0 deletions google/cloud/bigtable/internal/defaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ namespace internal {

int DefaultConnectionPoolSize();

bool EnableDirectAccess();

/**
* Returns an `Options` with the appropriate defaults for Bigtable.
*
Expand Down
25 changes: 10 additions & 15 deletions google/cloud/bigtable/internal/defaults_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -426,24 +426,20 @@ TEST(EndpointEnvTest, UserCredentialsOverrideEmulatorEnv) {

TEST(EndpointEnvTest, DirectPathEnabled) {
ScopedEnvironment emulator("BIGTABLE_EMULATOR_HOST", absl::nullopt);
ScopedEnvironment direct_path("GOOGLE_CLOUD_ENABLE_DIRECT_PATH",
"storage,bigtable");
ScopedEnvironment direct_path("CBT_ENABLE_DIRECTPATH", "true");

auto opts = DefaultOptions();
EXPECT_EQ("google-c2p:///directpath-bigtable.googleapis.com",
opts.get<DataEndpointOption>());
EXPECT_EQ("directpath-bigtable.googleapis.com", opts.get<AuthorityOption>());
EXPECT_EQ("c2p:///bigtable.googleapis.com", opts.get<DataEndpointOption>());
EXPECT_EQ("bigtable.googleapis.com", opts.get<AuthorityOption>());
// Admin endpoints are not affected.
EXPECT_EQ("bigtableadmin.googleapis.com", opts.get<AdminEndpointOption>());
EXPECT_EQ("bigtableadmin.googleapis.com",
opts.get<InstanceAdminEndpointOption>());
EXPECT_EQ(1, opts.get<GrpcNumChannelsOption>());
}

TEST(EndpointEnvTest, DirectPathNoMatch) {
TEST(EndpointEnvTest, DirectPathNotEnabled) {
ScopedEnvironment emulator("BIGTABLE_EMULATOR_HOST", absl::nullopt);
ScopedEnvironment direct_path("GOOGLE_CLOUD_ENABLE_DIRECT_PATH",
"bigtable-not,almost-bigtable");
ScopedEnvironment direct_path("CBT_ENABLE_DIRECTPATH", "false");

auto opts = DefaultDataOptions(Options{});
EXPECT_EQ("bigtable.googleapis.com", opts.get<EndpointOption>());
Expand All @@ -452,18 +448,17 @@ TEST(EndpointEnvTest, DirectPathNoMatch) {

TEST(EndpointEnvTest, DirectPathOverridesUserEndpoints) {
ScopedEnvironment emulator("BIGTABLE_EMULATOR_HOST", absl::nullopt);
ScopedEnvironment direct_path("GOOGLE_CLOUD_ENABLE_DIRECT_PATH", "bigtable");
ScopedEnvironment direct_path("CBT_ENABLE_DIRECTPATH", "true");

auto opts = DefaultDataOptions(
Options{}.set<EndpointOption>("ignored").set<AuthorityOption>("ignored"));
EXPECT_EQ("google-c2p:///directpath-bigtable.googleapis.com",
opts.get<EndpointOption>());
EXPECT_EQ("directpath-bigtable.googleapis.com", opts.get<AuthorityOption>());
Options{}.set<EndpointOption>("userendpoint").set<AuthorityOption>("userendpoint"));
EXPECT_EQ("c2p:///userendpoint", opts.get<EndpointOption>());
EXPECT_EQ("userendpoint", opts.get<AuthorityOption>());
}

TEST(EndpointEnvTest, EmulatorOverridesDirectPath) {
ScopedEnvironment emulator("BIGTABLE_EMULATOR_HOST", "emulator-host:8000");
ScopedEnvironment direct_path("GOOGLE_CLOUD_ENABLE_DIRECT_PATH", "bigtable");
ScopedEnvironment direct_path("CBT_ENABLE_DIRECTPATH", "true");

auto opts = DefaultDataOptions(Options{});
EXPECT_EQ("emulator-host:8000", opts.get<EndpointOption>());
Expand Down
Loading