1 // Copyright 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_PUBSUB_TOPIC_ADMIN_CLIENT_H
16 #define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_PUBSUB_TOPIC_ADMIN_CLIENT_H
17 
18 #include "google/cloud/pubsub/snapshot.h"
19 #include "google/cloud/pubsub/topic_admin_connection.h"
20 #include "google/cloud/pubsub/topic_builder.h"
21 #include "google/cloud/pubsub/version.h"
22 #include <memory>
23 
24 namespace google {
25 namespace cloud {
26 namespace pubsub {
27 inline namespace GOOGLE_CLOUD_CPP_PUBSUB_NS {
28 
29 /**
30  * Performs publisher operations in Cloud Pub/Sub.
31  *
32  * Applications use this class to perform operations on
33  * [Cloud Pub/Sub][pubsub-doc-link].
34  *
35  * @par Performance
36  * `PublisherClient` objects are cheap to create, copy, and move. However,
37  * each `PublisherClient` object must be created with a
38  * `std::shared_ptr<PublisherConnection>`, which itself is relatively
39  * expensive to create. Therefore, connection instances should be shared when
40  * possible. See the `MakeTopicAdminConnection()` function and the
41  * `PublisherConnection` interface for more details.
42  *
43  * @par Thread Safety
44  * Instances of this class created via copy-construction or copy-assignment
45  * share the underlying pool of connections. Access to these copies via multiple
46  * threads is guaranteed to work. Two threads operating on the same instance of
47  * this class is not guaranteed to work.
48  *
49  * @par Error Handling
50  * This class uses `StatusOr<T>` to report errors. When an operation fails to
51  * perform its work the returned `StatusOr<T>` contains the error details. If
52  * the `ok()` member function in the `StatusOr<T>` returns `true` then it
53  * contains the expected result. Please consult the
54  * [`StatusOr<T>` documentation](#google::cloud::v1::StatusOr) for more details.
55  *
56  * [pubsub-doc-link]: https://cloud.google.com/pubsub/docs
57  */
58 class TopicAdminClient {
59  public:
60   explicit TopicAdminClient(std::shared_ptr<TopicAdminConnection> connection);
61 
62   /**
63    * The default constructor is deleted.
64    *
65    * Use `PublisherClient(std::shared_ptr<PublisherConnection>)`
66    */
67   TopicAdminClient() = delete;
68 
69   /**
70    * Creates a new topic in Cloud Pub/Sub.
71    *
72    * @par Idempotency
73    * This operation is idempotent, as it succeeds only once, therefore the
74    * library retries the call. It might return a status code of
75    * `kAlreadyExists` as a consequence of retrying a successful (but reported as
76    * failed) request.
77    *
78    * @par Example
79    * @snippet samples.cc create-topic
80    *
81    * @param builder the configuration for the new topic, includes the name.
82    */
CreateTopic(TopicBuilder builder)83   StatusOr<google::pubsub::v1::Topic> CreateTopic(TopicBuilder builder) {
84     return connection_->CreateTopic({std::move(builder).BuildCreateRequest()});
85   }
86 
87   /**
88    * Gets information about an existing Cloud Pub/Sub topic.
89    *
90    * @par Idempotency
91    * This is a read-only operation and therefore always idempotent and retried.
92    *
93    * @par Example
94    * @snippet samples.cc get-topic
95    */
GetTopic(Topic topic)96   StatusOr<google::pubsub::v1::Topic> GetTopic(Topic topic) {
97     return connection_->GetTopic({std::move(topic)});
98   }
99 
100   /**
101    * Updates the configuration of an existing Cloud Pub/Sub topic.
102    *
103    * @par Idempotency
104    * This operation is idempotent, the state of the system is the same after one
105    * or several calls, and therefore it is always retried.
106    *
107    * @par Example
108    * @snippet samples.cc update-topic
109    *
110    * @param builder the configuration for the new topic, includes the name.
111    */
UpdateTopic(TopicBuilder builder)112   StatusOr<google::pubsub::v1::Topic> UpdateTopic(TopicBuilder builder) {
113     return connection_->UpdateTopic({std::move(builder).BuildUpdateRequest()});
114   }
115 
116   /**
117    * Lists all the topics for a given project id.
118    *
119    * @par Idempotency
120    * This is a read-only operation and therefore always idempotent and retried.
121    *
122    * @par Example
123    * @snippet samples.cc list-topics
124    */
ListTopics(std::string const & project_id)125   ListTopicsRange ListTopics(std::string const& project_id) {
126     return connection_->ListTopics({"projects/" + project_id});
127   }
128 
129   /**
130    * Deletes an existing topic in Cloud Pub/Sub.
131    *
132    * @par Idempotency
133    * This operation is idempotent, the state of the system is the same after one
134    * or several calls, and therefore it is always retried. It might return a
135    * status code of `kNotFound` as a consequence of retrying a successful
136    * (but reported as failed) request.
137    *
138    * @par Example
139    * @snippet samples.cc delete-topic
140    *
141    * @param topic the name of the topic to be deleted.
142    */
DeleteTopic(Topic topic)143   Status DeleteTopic(Topic topic) {
144     return connection_->DeleteTopic({std::move(topic)});
145   }
146 
147   /**
148    * Detaches an existing subscription.
149    *
150    * This operation stops the subscription from receiving any further messages,
151    * it drops any messages still retained by the subscription, and any
152    * outstanding pull requests will fail with `kFailedPrecondition`.
153    *
154    * @par Idempotency
155    * This operation is idempotent, the state of the system is the same after one
156    * or several calls, and therefore it is always retried.
157    *
158    * @par Example
159    * @snippet samples.cc detach-subscription
160    *
161    * @param subscription the name of the subscription to detach.
162    */
DetachSubscription(Subscription subscription)163   StatusOr<google::pubsub::v1::DetachSubscriptionResponse> DetachSubscription(
164       Subscription subscription) {
165     return connection_->DetachSubscription({std::move(subscription)});
166   }
167 
168   /**
169    * Lists all the subscription names for a given topic.
170    *
171    * @note
172    * The returned range contains fully qualified subscription names, e.g.,
173    * `"projects/my-project/subscriptions/my-subscription"`. Applications may
174    * need to parse these names to use with other APIs.
175    *
176    * @par Idempotency
177    * This is a read-only operation and therefore always idempotent and retried.
178    *
179    * @par Example
180    * @snippet samples.cc list-topic-subscriptions
181    */
ListTopicSubscriptions(Topic const & topic)182   ListTopicSubscriptionsRange ListTopicSubscriptions(Topic const& topic) {
183     return connection_->ListTopicSubscriptions({topic.FullName()});
184   }
185 
186   /**
187    * Lists all the subscription names for a given topic.
188    *
189    * @note
190    * The returned range contains fully qualified snapshot names, e.g.,
191    * `"projects/my-project/snapshots/my-subscription"`. Applications may
192    * need to parse these names to use with other APIs.
193    *
194    * @par Idempotency
195    * This is a read-only operation and therefore always idempotent and retried.
196    *
197    * @par Example
198    * @snippet samples.cc list-topic-snapshots
199    *
200    * @see https://cloud.google.com/pubsub/docs/replay-overview for a detailed
201    *     description of Cloud Pub/Sub's snapshots.
202    */
ListTopicSnapshots(Topic const & topic)203   ListTopicSnapshotsRange ListTopicSnapshots(Topic const& topic) {
204     return connection_->ListTopicSnapshots({topic.FullName()});
205   }
206 
207  private:
208   std::shared_ptr<TopicAdminConnection> connection_;
209 };
210 
211 }  // namespace GOOGLE_CLOUD_CPP_PUBSUB_NS
212 }  // namespace pubsub
213 }  // namespace cloud
214 }  // namespace google
215 
216 #endif  // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_PUBSUB_TOPIC_ADMIN_CLIENT_H
217