Skip to content
Draft
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
114 changes: 114 additions & 0 deletions doc/v3-migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,120 @@ internal legacy files.

</details>

<details>
<summary>Removed <code>bigtable::AdminClient</code> and <code>bigtable::TableAdmin</code></summary>

The `bigtable::AdminClient` class and `bigtable::TableAdmin` class have been
replaced with `bigtable_admin::BigtableTableAdminClient`.

**Before:**

```cpp

std::shared_ptr<bigtable::AdminClient> admin_client =
bigtable::MakeAdminClient("project-id");
auto table_admin = std::make_unique<bigtable::TableAdmin>(
admin_client, "instance-id");

// Drop a selection of rows by key prefix.
auto result = table_admin.DropRowByPrefix("table-id", "row-key-prefix");

// Drop all rows.
result = table_admin.DropAllRows("table-id");
```

**After:**

```cpp
#include "google/cloud/bigtable/admin/bigtable_table_admin_client.h"

auto table_admin = bigtable_admin::BigtableTableAdminClient(
bigtable_admin::MakeBigtableAdminConnection());
auto table_name = bigtable::TableName("project-id", "instance-id", "table-id");

// Drop a selection of rows by key prefix.
google::bigtable::admin::v2::DropRowRangeRequest drop_rows_by_prefix;
drop_rows_by_prefix.set_name(table_name);
drop_rows_by_prefix.set_row_key_prefix("row-key-prefix");
auto result = table_admin.DropRowRange(drop_rows_by_prefix);

// Drop all rows.
google::bigtable::admin::v2::DropRowRangeRequest drop_all_rows;
drop_all_rows.set_name(table_name);
drop_all_rows.set_delete_all_data_from_table(true);
result = table_admin.DropRowRange(drop_all_rows);
```

</details>

<details><summary><code>WaitForConsistency</code> is now a free function</summary>

With the removal of the `bigtable::TableAdmin` class, `WaitForConsistency` is
now a free function.

**Before:**

```cpp

std::shared_ptr<bigtable::AdminClient> admin_client =
bigtable::MakeAdminClient("project-id");
auto table_admin = std::make_unique<bigtable::TableAdmin>(
admin_client, "instance-id");

auto token = table_admin.GenerateConsistencyToken("table-id");
if (!token) throw std::runtime_error(token.status().message());
auto result = table_admin.WaitForConsistency("table-id", *token);
```

**After:**

```cpp
#include "google/cloud/bigtable/admin/bigtable_table_admin_client.h"
#include "google/cloud/bigtable/wait_for_consistency.h"

auto connection = bigtable_admin::MakeBigtableAdminConnection();
auto table_admin = bigtable_admin::BigtableTableAdminClient(connection);
auto table_name = bigtable::TableName("project-id", "instance-id", "table-id");

auto token = table_admin.GenerateConsistencyToken(table_name);
if (!token) throw std::runtime_error(token.status().message());
auto result = bigtable_admin::WaitForConsistency(connection, table_name,
token->consistency_token());
```

</details>

<details>
<summary>Removed <code>bigtable::InstanceAdminClient</code> and <code>bigtable::InstanceAdmin</code></summary>

The `bigtable::InstanceAdminClient` class and `bigtable::InstanceAdmin` class
have been replaced with `bigtable_admin::BigtableInstanceAdminClient`.

**Before:**

```cpp
auto instance_admin_client = bigtable::MakeInstanceAdminClient("project-id");
auto instance_admin =
std::make_unique<bigtable::InstanceAdmin>(instance_admin_client);

auto clusters = instance_admin->ListClusters();
```

**After:**

```cpp
#include "google/cloud/bigtable/admin/bigtable_instance_admin_client.h"

auto instance_admin =
std::make_unique<bigtable_admin::BigtableInstanceAdminClient>(
bigtable_admin::MakeBigtableInstanceAdminConnection());

auto clusters = instance_admin->ListClusters(
InstanceName("project-id", "instance-id"));
```

</details>

### Pubsub

<details>
Expand Down
19 changes: 14 additions & 5 deletions generator/generator_config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,20 @@ message ServiceConfiguration {
// generated.
bool omit_streaming_updater = 29;

// In rare cases, specifically bigtable::WaitForConsistency, the
// CompletionQueue from the BackgroundThreads owned by the Connection is
// needed elsewhere. This emits a protected accessor and friend function for
// that purpose.
bool emit_completion_queue_accessor = 30;
message BespokeMethod {
string name = 1;
string return_type = 2;
string parameters = 3;
}

// Only added to maintain feature parity when migrating from the handwritten
// Bigtable Table Admin class to the generated class. While some attempts were
// made to generalize this feature, it currently only supports the
// WaitForConsistency method. This functionality can be enhanced later if we
// ever need to use this again.
// The implementation for this method in the ConnectionImpl class is not
// generated and must be handwritten in a separate .cc file.
repeated BespokeMethod bespoke_methods = 30;
}

message DiscoveryDocumentDefinedProduct {
Expand Down
8 changes: 7 additions & 1 deletion generator/generator_config.textproto
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,13 @@ service {
{rpc_name: "BigtableTableAdmin.CheckConsistency", idempotency: IDEMPOTENT}
]
omit_repo_metadata: true
emit_completion_queue_accessor: true
bespoke_methods : [
{
name: "WaitForConsistency",
return_type: "future<StatusOr<google::bigtable::admin::v2::CheckConsistencyResponse>>",
parameters: "(google::bigtable::admin::v2::CheckConsistencyRequest const& request, Options opts = {})"
}
]
}

# Billing
Expand Down
59 changes: 59 additions & 0 deletions generator/internal/client_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,51 @@
#include "generator/internal/predicate_utils.h"
#include "generator/internal/printer.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_replace.h"
#include "google/api/client.pb.h"
#include <google/protobuf/descriptor.h>

namespace google {
namespace cloud {
namespace generator_internal {
namespace {
std::string FormatBespokeMethodComments(std::string const& method_name) {
if (method_name == "WaitForConsistency") {
return R"""(
// clang-format off
///
/// Polls a table until it is consistent or the RetryPolicy is exhausted based
/// on a consistency token, that is, if replication has caught up based on the
/// provided conditions specified in the token and the check request.
///
/// @param request Unary RPCs, such as the one wrapped by this
/// function, receive a single `request` proto message which includes all
/// the inputs for the RPC. In this case, the proto message is a
/// [google.bigtable.admin.v2.CheckConsistencyRequest].
/// Proto messages are converted to C++ classes by Protobuf, using the
/// [Protobuf mapping rules].
/// @param opts Optional. Override the class-level options, such as retry and
/// backoff policies.
/// @return the result of the RPC. The response message type
/// ([google.bigtable.admin.v2.CheckConsistencyResponse])
/// is mapped to a C++ class using the [Protobuf mapping rules].
/// If the request fails, the [`StatusOr`] contains the error details.
///
/// [Protobuf mapping rules]: https://protobuf.dev/reference/cpp/cpp-generated/
/// [input iterator requirements]: https://en.cppreference.com/w/cpp/named_req/InputIterator
/// [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
/// [`future`]: @ref google::cloud::future
/// [`StatusOr`]: @ref google::cloud::StatusOr
/// [`Status`]: @ref google::cloud::Status
/// [google.bigtable.admin.v2.CheckConsistencyRequest]: @googleapis_reference_link{google/bigtable/admin/v2/bigtable_table_admin.proto#L909}
/// [google.bigtable.admin.v2.CheckConsistencyResponse]: @googleapis_reference_link{google/bigtable/admin/v2/bigtable_table_admin.proto#L948}
///
// clang-format on
)""";
}
return "";
}
} // namespace

ClientGenerator::ClientGenerator(
google::protobuf::ServiceDescriptor const* service_descriptor,
Expand Down Expand Up @@ -380,6 +419,13 @@ R"""( std::unique_ptr<::google::cloud::AsyncStreamingReadWriteRpc<
__FILE__, __LINE__);
}

for (auto const& method : bespoke_methods()) {
HeaderPrint("\n");
HeaderPrint(FormatBespokeMethodComments(method.name()));
HeaderPrint(absl::StrCat(method.return_type(), " ", method.name(),
method.parameters(), ";"));
}

HeaderPrint( // clang-format off
"\n"
" private:\n"
Expand Down Expand Up @@ -716,6 +762,19 @@ std::unique_ptr<::google::cloud::AsyncStreamingReadWriteRpc<
__FILE__, __LINE__);
}

for (auto const& method : bespoke_methods()) {
CcPrint("\n");
CcPrint(absl::StrCat(
method.return_type(), R"""( $client_class_name$::)""", method.name(),
absl::StrReplaceAll(method.parameters(), {{" = {}", ""}}),
absl::StrFormat(R"""( {
internal::OptionsSpan span(internal::MergeOptions(std::move(opts), options_));
return connection_->%s(request);
}
)""",
method.name())));
}

CcCloseNamespaces();
return {};
}
Expand Down
6 changes: 6 additions & 0 deletions generator/internal/codegen_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ void ProcessArgOmitRpc(
ProcessRepeated("omit_rpc", "omitted_rpcs", command_line_args);
}

void ProcessArgBespokeMethod(
std::vector<std::pair<std::string, std::string>>& command_line_args) {
ProcessRepeated("bespoke_method", "bespoke_methods", command_line_args);
}

void ProcessArgServiceEndpointEnvVar(
std::vector<std::pair<std::string, std::string>>& command_line_args) {
auto service_endpoint_env_var =
Expand Down Expand Up @@ -269,6 +274,7 @@ ProcessCommandLineArgs(std::string const& parameters) {
ProcessArgCopyrightYear(command_line_args);
ProcessArgOmitService(command_line_args);
ProcessArgOmitRpc(command_line_args);
ProcessArgBespokeMethod(command_line_args);
ProcessArgServiceEndpointEnvVar(command_line_args);
ProcessArgEmulatorEndpointEnvVar(command_line_args);
ProcessArgEndpointLocationStyle(command_line_args);
Expand Down
53 changes: 25 additions & 28 deletions generator/internal/connection_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "generator/internal/pagination.h"
#include "generator/internal/predicate_utils.h"
#include "generator/internal/printer.h"
#include "absl/strings/str_replace.h"
#include "absl/strings/str_split.h"
#include <google/protobuf/descriptor.h>

Expand Down Expand Up @@ -57,8 +58,6 @@ Status ConnectionGenerator::GenerateHeader() {
{vars("idempotency_policy_header_path"), vars("retry_traits_header_path"),
HasLongrunningMethod() ? "google/cloud/no_await_tag.h" : "",
IsExperimental() ? "google/cloud/experimental_tag.h" : "",
HasEmitCompletionQueueAccessor() ? "google/cloud/completion_queue.h"
: "",
"google/cloud/backoff_policy.h",
HasLongrunningMethod() || HasAsyncMethod() ? "google/cloud/future.h"
: "",
Expand Down Expand Up @@ -93,21 +92,7 @@ Status ConnectionGenerator::GenerateHeader() {
}
}

Status result;
if (HasEmitCompletionQueueAccessor()) {
result = HeaderOpenNamespaces();
if (!result.ok()) return result;
HeaderPrint(R"""(class $connection_class_name$;)""");
HeaderCloseNamespaces();

result = HeaderOpenNamespaces(NamespaceType::kInternal);
if (!result.ok()) return result;
HeaderPrint(
R"""(StatusOr<CompletionQueue> completion_queue($product_namespace$::$connection_class_name$ const& conn);)""");
HeaderCloseNamespaces();
}

result = HeaderOpenNamespaces();
auto result = HeaderOpenNamespaces();
if (!result.ok()) return result;

HeaderPrint(R"""(
Expand Down Expand Up @@ -331,13 +316,14 @@ class $connection_class_name$ {
__FILE__, __LINE__);
}

if (HasEmitCompletionQueueAccessor()) {
HeaderPrint(R"""( protected:
friend StatusOr<CompletionQueue> $product_internal_namespace$::completion_queue(
$connection_class_name$ const& conn);
virtual StatusOr<CompletionQueue> completion_queue() const;
)""");
for (auto const& method : bespoke_methods()) {
HeaderPrint("\n");
HeaderPrint(absl::StrCat(
" virtual ", method.return_type(), " ", method.name(),
absl::StrReplaceAll(method.parameters(), {{", Options opts = {}", ""}}),
";\n"));
}

// close abstract interface Connection base class
HeaderPrint("};\n");

Expand Down Expand Up @@ -513,13 +499,24 @@ future<StatusOr<$response_type$>>
__FILE__, __LINE__);
}

if (HasEmitCompletionQueueAccessor()) {
for (auto const& method : bespoke_methods()) {
CcPrint("\n");
std::string make_return =
absl::StrContains(method.return_type(), "future")
? absl::StrCat("google::cloud::make_ready_", method.return_type())
: method.return_type();

CcPrint(
R"""(
StatusOr<CompletionQueue> $connection_class_name$::completion_queue() const {
return Status(StatusCode::kUnimplemented, "not implemented");
absl::StrCat(method.return_type(), R"""( $connection_class_name$::)""",
method.name(),
absl::StrReplaceAll(method.parameters(),
{{" request, Options opts = {}", ""}}),
" {\n",
absl::StrFormat(R"""( return %s(
Status(StatusCode::kUnimplemented, "not implemented"));
}
)""");
)""",
make_return)));
}

if (HasGenerateGrpcTransport()) {
Expand Down
Loading