Skip to content
Open
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
38 changes: 27 additions & 11 deletions google/cloud/bigtable/internal/bigtable_stub_factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include "absl/base/no_destructor.h"
#include "google/cloud/bigtable/internal/bigtable_stub_factory.h"
#include "google/cloud/bigtable/internal/bigtable_auth_decorator.h"
#include "google/cloud/bigtable/internal/bigtable_channel_refresh.h"
Expand All @@ -20,6 +21,7 @@
#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"
Expand All @@ -46,18 +48,32 @@ std::shared_ptr<grpc::Channel> CreateGrpcChannel(
return auth.CreateChannel(options.get<EndpointOption>(), std::move(args));
}

std::string CreateFeaturesMetadataString(bool enable_direct_access) {
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 (enable_direct_access) {
proto.set_traffic_director_enabled(true);
proto.set_direct_access_requested(true);
}
return internal::UrlsafeBase64Encode(proto.SerializeAsString());
}

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;
if (bigtable::internal::EnableDirectAccess()) {
static const absl::NoDestructor<std::string> kDirectAccessFeatures(
CreateFeaturesMetadataString(true));
return *kDirectAccessFeatures;
} else {
static const absl::NoDestructor<std::string> kDefaultFeatures(
CreateFeaturesMetadataString(false));
return *kDefaultFeatures;
}
}

} // 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