Skip to content

Commit

Permalink
feat(pubsub): update subscription builders (#9326)
Browse files Browse the repository at this point in the history
We provide a few helpers to build the protos. While this may not be a
good idea in the long run, it is the current plan, so we need these
updates from time to time.
  • Loading branch information
coryan authored Jun 22, 2022
1 parent 55106da commit 5f49313
Show file tree
Hide file tree
Showing 5 changed files with 300 additions and 4 deletions.
18 changes: 14 additions & 4 deletions google/cloud/pubsub/snapshot_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,33 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN

/**
* Build a request to create a Cloud Pub/Sub snapshot.
*
* Makes it easier to create the protobuf messages consumed by
* `SubscriptionAdminClient`. The main advantages are:
*
* - Use a fluent API to set multiple values when constructing complex objects.
* - Automatically compute the set of paths for update requests.
*/
class SnapshotBuilder {
public:
SnapshotBuilder() = default;

/// Build a CreateSnapshotRequest where the server assigns the snapshot id.
/// Build a protocol buffer message to create snapshots with server-assigned
/// ids.
google::pubsub::v1::CreateSnapshotRequest BuildCreateRequest(
Subscription const& subscription) &&;

/// Build a CreateSnapshotRequest where the application assigns the snapshot
/// id.
/// Build a protocol buffer message to create snapshots with
/// application-assigned ids.
google::pubsub::v1::CreateSnapshotRequest BuildCreateRequest(
Subscription const& subscription, Snapshot const& snapshot) &&;

/// Build a UpdateSnapshotRequest.
/// Build a protocol buffer message to update an existing snapshot.
google::pubsub::v1::UpdateSnapshotRequest BuildUpdateRequest(
Snapshot const& snapshot) &&;

/// @name Setters for each protocol buffer field.
///@{
SnapshotBuilder& add_label(std::string const& key,
std::string const& value) & {
using value_type = protobuf::Map<std::string, std::string>::value_type;
Expand All @@ -67,6 +76,7 @@ class SnapshotBuilder {
return *this;
}
SnapshotBuilder&& clear_labels() && { return std::move(clear_labels()); }
///@}

private:
google::pubsub::v1::Snapshot proto_;
Expand Down
14 changes: 14 additions & 0 deletions google/cloud/pubsub/subscription_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,20 @@ SubscriptionBuilder& SubscriptionBuilder::set_push_config(
return *this;
}

SubscriptionBuilder& SubscriptionBuilder::set_bigquery_config(
BigQueryConfigBuilder v) & {
if (v.paths_.empty()) {
proto_.clear_bigquery_config();
paths_.insert("bigquery_config");
} else {
*proto_.mutable_bigquery_config() = std::move(v.proto_);
for (auto const& s : v.paths_) {
paths_.insert("bigquery_config." + s);
}
}
return *this;
}

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace pubsub
} // namespace cloud
Expand Down
151 changes: 151 additions & 0 deletions google/cloud/pubsub/subscription_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ class SubscriptionBuilder;

/**
* Helper class to create google::pubsub::v1::PushConfig protos.
*
* Makes it easier to create the protobuf messages consumed by
* `SubscriptionAdminClient`. The main advantages are:
*
* - Use a fluent API to set multiple values when constructing complex objects.
* - Automatically compute the set of paths for update requests.
*/
class PushConfigBuilder {
public:
Expand All @@ -42,9 +48,12 @@ class PushConfigBuilder {
set_push_endpoint(std::move(push_endpoint));
}

/// Build a protocol buffer message to update an existing push config.
google::pubsub::v1::ModifyPushConfigRequest BuildModifyPushConfig(
Subscription const& subscription) &&;

/// @name Setters for each protocol buffer field.
///@{
PushConfigBuilder& set_push_endpoint(std::string v) & {
proto_.set_push_endpoint(std::move(v));
paths_.insert("push_endpoint");
Expand Down Expand Up @@ -116,31 +125,115 @@ class PushConfigBuilder {
google::pubsub::v1::PushConfig::OidcToken token) && {
return std::move(set_authentication(std::move(token)));
}
//@}

private:
friend class SubscriptionBuilder;
google::pubsub::v1::PushConfig proto_;
std::set<std::string> paths_;
};

/**
* A helper class to build `google::pubsub::v1::BigQueryConfig` protos.
*
* Makes it easier to create the protobuf messages consumed by
* `SubscriptionAdminClient`. The main advantages are:
*
* - Use a fluent API to set multiple values when constructing complex objects.
* - Automatically compute the set of paths for update requests.
*/
class BigQueryConfigBuilder {
public:
BigQueryConfigBuilder() = default;

/// @name Setters for each protocol buffer field.
///@{
BigQueryConfigBuilder& set_table(std::string full_path) & {
*proto_.mutable_table() = std::move(full_path);
paths_.insert("table");
return *this;
}
BigQueryConfigBuilder&& set_table(std::string full_path) && {
return std::move(set_table(std::move(full_path)));
}
BigQueryConfigBuilder& set_table(std::string const& project_id,
std::string const& data_set_id,
std::string const& table_id) & {
return set_table(project_id + ':' + data_set_id + '.' + table_id);
}
BigQueryConfigBuilder&& set_table(std::string const& project_id,
std::string const& data_set_id,
std::string const& table_id) && {
return std::move(set_table(project_id, data_set_id, table_id));
}

BigQueryConfigBuilder& set_use_topic_schema(bool v) & {
proto_.set_use_topic_schema(v);
paths_.insert("use_topic_schema");
return *this;
}
BigQueryConfigBuilder&& set_use_topic_schema(bool v) && {
return std::move(set_use_topic_schema(v));
}

BigQueryConfigBuilder& set_write_metadata(bool v) & {
proto_.set_write_metadata(v);
paths_.insert("write_metadata");
return *this;
}
BigQueryConfigBuilder&& set_write_metadata(bool v) && {
return std::move(set_write_metadata(v));
}

BigQueryConfigBuilder& set_drop_unknown_fields(bool v) & {
proto_.set_drop_unknown_fields(v);
paths_.insert("drop_unknown_fields");
return *this;
}
BigQueryConfigBuilder&& set_drop_unknown_fields(bool v) && {
return std::move(set_drop_unknown_fields(v));
}
///@}

private:
friend class SubscriptionBuilder;
google::pubsub::v1::BigQueryConfig proto_;
std::set<std::string> paths_;
};

/**
* Create a Cloud Pub/Sub subscription configuration.
*
* Makes it easier to create the protobuf messages consumed by
* `SubscriptionAdminClient`. The main advantages are:
*
* - Use a fluent API to set multiple values when constructing complex objects.
* - Automatically compute the set of paths for update requests.
*/
class SubscriptionBuilder {
public:
SubscriptionBuilder() = default;

/// Build a protocol buffer message to update an existing subscription.
google::pubsub::v1::UpdateSubscriptionRequest BuildUpdateRequest(
Subscription const& subscription) &&;

/// Build a protocol buffer message to create a new subscription.
google::pubsub::v1::Subscription BuildCreateRequest(
Topic const& topic, Subscription const& subscription) &&;

/// @name Setters for each protocol buffer field.
///@{
SubscriptionBuilder& set_push_config(PushConfigBuilder v) &;
SubscriptionBuilder&& set_push_config(PushConfigBuilder v) && {
return std::move(set_push_config(std::move(v)));
}

SubscriptionBuilder& set_bigquery_config(BigQueryConfigBuilder v) &;
SubscriptionBuilder&& set_bigquery_config(BigQueryConfigBuilder v) && {
return std::move(set_bigquery_config(std::move(v)));
}

SubscriptionBuilder& set_ack_deadline(std::chrono::seconds v) & {
proto_.set_ack_deadline_seconds(static_cast<std::int32_t>(v.count()));
paths_.insert("ack_deadline_seconds");
Expand Down Expand Up @@ -256,6 +349,40 @@ class SubscriptionBuilder {
return std::move(clear_dead_letter_policy());
}

SubscriptionBuilder& set_retry_policy(google::pubsub::v1::RetryPolicy v) & {
*proto_.mutable_retry_policy() = std::move(v);
paths_.insert("retry_policy");
return *this;
}
SubscriptionBuilder&& set_retry_policy(google::pubsub::v1::RetryPolicy v) && {
return std::move(set_retry_policy(std::move(v)));
}

SubscriptionBuilder& clear_retry_policy() & {
proto_.clear_retry_policy();
paths_.insert("retry_policy");
return *this;
}
SubscriptionBuilder&& clear_retry_policy() && {
return std::move(clear_retry_policy());
}

SubscriptionBuilder& enable_exactly_once_delivery(bool v) & {
proto_.set_enable_exactly_once_delivery(v);
paths_.insert("enable_exactly_once_delivery");
return *this;
}
SubscriptionBuilder&& enable_exactly_once_delivery(bool v) && {
return std::move(enable_exactly_once_delivery(v));
}
///@}

/**
* Construct a `google::pubsub::v1::ExpirationPolicy` using a C++ duration.
*
* This is a convenience function to create the `set_expiration_policy()`
* argument.
*/
template <typename Rep, typename Period>
static google::pubsub::v1::ExpirationPolicy MakeExpirationPolicy(
std::chrono::duration<Rep, Period> d) {
Expand All @@ -265,6 +392,12 @@ class SubscriptionBuilder {
return result;
}

/**
* Construct a `google::pubsub::v1::DeadLetterPolicy`.
*
* This is a convenience function to create the `set_dead_letter_policy()`
* argument.
*/
static google::pubsub::v1::DeadLetterPolicy MakeDeadLetterPolicy(
Topic const& dead_letter_topic, std::int32_t max_delivery_attempts = 0) {
google::pubsub::v1::DeadLetterPolicy result;
Expand All @@ -273,6 +406,24 @@ class SubscriptionBuilder {
return result;
}

/**
* Construct a `google::pubsub::v1::RetryPolicy` using C++ durations.
*
* This is a convenience function to create the `set_retry_policy()`
* argument.
*/
template <typename Rep1, typename Period1, typename Rep2, typename Period2>
static google::pubsub::v1::RetryPolicy MakeRetryPolicy(
std::chrono::duration<Rep1, Period1> minimum_backoff,
std::chrono::duration<Rep2, Period2> maximum_backoff) {
google::pubsub::v1::RetryPolicy result;
*result.mutable_minimum_backoff() =
google::cloud::internal::ToDurationProto(minimum_backoff);
*result.mutable_maximum_backoff() =
google::cloud::internal::ToDurationProto(maximum_backoff);
return result;
}

private:
google::pubsub::v1::Subscription proto_;
std::set<std::string> paths_;
Expand Down
Loading

0 comments on commit 5f49313

Please sign in to comment.