Google APIs Client Library for C++
client_service.h
Go to the documentation of this file.
00001 /*
00002  * \copyright Copyright 2013 Google Inc. All Rights Reserved.
00003  * \license @{
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  *
00017  * @}
00018  */
00019 
00020 // Author: ewiseblatt@google.com (Eric Wiseblatt)
00021 
00022 /*
00023  * @defgroup ClientServiceLayer Client Service Layer
00024  *
00025  * The Client Service Layer provides application-level support for interacting
00026  * with Google Cloud Platform services and endpoints. It makes use of the
00027  * HTTP Transport Layer for the actual messaging and response handling but
00028  * hides these low level details with higher level abstractions specialized
00029  * for specific use cases.
00030  *
00031  * Much of this layer is geared around the consumption of services that present
00032  * REST-style interfaces.
00033  *
00034  * Typically programmers use the Google APIs Code Generator to generate a
00035  * C++ library specific to the service(s) they will be using. The output
00036  * of the code generator are libraries built ontop of the offerings in this
00037  * module.
00038  *
00039  * The client service layer also includes additional helper classes such as
00040  * the ServiceRequetsPager for paging through large resources using finer
00041  * granularity requests.
00042  */
00043 #ifndef APISERVING_CLIENTSCPP_SERVICE_CLIENT_SERVICE_H_
00044 #define APISERVING_CLIENTSCPP_SERVICE_CLIENT_SERVICE_H_
00045 
00046 #include <string>
00047 using std::string;
00048 #include "googleapis/base/macros.h"
00049 #include "googleapis/base/scoped_ptr.h"
00050 #include "googleapis/client/transport/http_transport.h"
00051 #include "googleapis/strings/stringpiece.h"
00052 #include "googleapis/util/status.h"
00053 namespace googleapis {
00054 
00055 namespace client {
00056 class SerializableJson;
00057 class AuthorizationCredential;
00058 class HttpRequest;
00059 struct UriTemplateConfig;
00060 
00061 class ClientService;
00062 /*
00063  * Base class for requests made to a ClientService.
00064  * @ingroup ClientServiceLayer
00065  *
00066  * This class is based on a Command Pattern. The instance is given the service
00067  * endpoint to invoke and is given the arguments to invoke with as expected
00068  * by that endpoint. When its Execute() method is called, it will invoke
00069  * the command and wait for the response. The caller can get any response
00070  * data as well as the overall status from the request instance.
00071  *
00072  * When using the code generator to create custom APIs for a given service,
00073  * the code generator will subclass these requests for each endpoint API.
00074  * The specialized subclasses will contain higher level methods for setting
00075  * the various arguments and parameters that are available to use. Those
00076  * class instances are created using the ClientService instance (i.e. the
00077  * ClientService acts as a ClientSrviceRequet factory. Therefore this class
00078  * is not typically explicitly instantiated. Lower level code may use this
00079  * class directly since it is concrete and fully capable.
00080  *
00081  * You should not explicitly destroy this class (or derived classes) when
00082  * making asynchronous requests unless you know that the request has
00083  * completely finished executing (its underlying HttpRequest is done).
00084  * It is safest to use DestroyWhenDone() instead. Otherwise code on the stack
00085  * may still be referencing the instance after it is destroyed, and your
00086  * program will crash.
00087  *
00088  * Requests are given a service and
00089  * <a href='http://tools.ietf.org/html/rfc6570'>RFC 6570</a>
00090  * URI Template to invoke within that service. The purpose of the URI
00091  * template is to ultimately provide the URL within the service. The
00092  * request instance can resolve the parameters in the template. This is
00093  * described in more detail with the PrepareUrl() method.
00094  */
00095 class ClientServiceRequest {
00096  public:
00097   /*
00098    * Construct a new request.
00099    *
00100    * @param[in] service The service to send the request to
00101    * @param[in] credential If not NULL, the credentials to invoke with
00102    * @param[in] method The HTTP method when making the HTTP request
00103    * @param[in] uri_template The URI template specifying the url to invoke
00104    *
00105    * @see DestroyWhenDone
00106    * @see Execute
00107    * @see ExecuteAsync
00108    */
00109   ClientServiceRequest(
00110       const ClientService* service, AuthorizationCredential* credential,
00111       const HttpRequest::HttpMethod& method, const StringPiece& uri_template);
00112 
00113   /*
00114    * Standard instance destructor.
00115    *
00116    * @pre The HttpRequestState must be HttpRequestState::done()
00117    * @see DestroyWhenDone
00118    */
00119   virtual ~ClientServiceRequest();
00120 
00121   /*
00122    * Tell instance to self-destruct (destroy itself) once it is safe to.
00123    *
00124    * This is the preferred means to destroy instances that are used
00125    * asynchronously. The instance will remain active until after the
00126    * callback (if any) has finished running and after any signaling has
00127    * been performed to HttpResponse::WaitUntilDone().
00128    *
00129    * This method will destroy the object immediately if it is safe to do so.
00130    */
00131   void DestroyWhenDone();
00132 
00133   /*
00134    * Ask the service to execute the request synchronously.
00135    *
00136    * The response data will be in the embedded HttpRequest
00137    *
00138    * @return status indicating the overall status of performing the request.
00139    *
00140    * @note HTTP failures (e.g. 4xx HTTP codes) are considered errors
00141    * as are transport level errors (e.g. unknown host). Finer grained status
00142    * information is available from the underlying HttpRequest.
00143    *
00144    * @see ExecuteAsync
00145    * @see ExecuteAndParseResponse
00146    * @see mutable_http_request
00147    * @see http_response
00148    */
00149   virtual util::Status Execute();
00150 
00151   /*
00152    * Ask the service to execute the request asynchronously.
00153    *
00154    * @param[in] callback  If not NULL then run this once the request is done.
00155    *
00156    * The callback will be called once the HttpRequest::done() criteria are
00157    * satisfied on the underlying HttpRequest. This is always the case, even
00158    * on fundamental transport errors such as unknown host or if the request
00159    * is invalid.
00160    *
00161    * The callback can check the HttpRequest details, including its HttpResponse
00162    * to get status and response details. These will be valid while the callback
00163    * is running, but will no longer be valid once the request is destroyed.
00164    *
00165    * @warning The callback might be called from another thread than this one.
00166    * For normal execution flows where the request can be sent to the service,
00167    * the callback will be invoked from the bound executor's context. If there
00168    * is a fundamental problem with the request or it could not be queued then
00169    * it may (but not necessarily) be called from the current context before
00170    * the method returns.
00171    *
00172    * @warning If DestroyWhenDone() has been called before invoking this method
00173    * then the instance might complete and thus be destroyed before this method
00174    * returns. This is ok, but you will have no way of knowing this without
00175    * recording extra state in your callback.
00176    *
00177    * @see Execute
00178    * @see mutable_http_request
00179    */
00180   virtual void ExecuteAsync(HttpRequestCallback* callback);
00181 
00182   /*
00183    * Returns the underlying HttpRequest.
00184    *
00185    * The request is set and managed by this instance.
00186    * The options on the request can be tuned. The request is owned by this
00187    * instance so you should not set its destroy_when_done attribute. Use
00188    * DestroyWhenDone on this instance instead if desired.
00189    */
00190   HttpRequest* mutable_http_request()  { return http_request_.get(); }
00191 
00192   /*
00193    * Returns the underlying HttpReqeust.
00194    *
00195    * The request is set and managed by this instance.
00196    * The request provides access to its current HttpRequestState, response
00197    * status, and the actual response.
00198    */
00199   const HttpRequest* http_request() const  { return http_request_.get(); }
00200 
00201   /*
00202    * Returns the underlying response.
00203    *
00204    * The response is set and managed by this instance (actually by the
00205    * instance's request). It is only valid over the lifetime of this instance
00206    * so be sure to look at any values before you destroy the request.
00207    */
00208   HttpResponse* http_response() { return http_request_->response(); }
00209 
00210  protected:
00211   /*
00212    * Fills out the mutable_http_request() owned by this instance with the
00213    * information specified by this request.
00214    *
00215    * The base class implementation calls PrepareUrl and snd sets the url
00216    * on the underlying request. Specialized classes may have other needs,
00217    * such as setting the requset payload.
00218    *
00219    * @param callback [in] If not NULL then this will be called on failure.
00220    */
00221   virtual util::Status PrepareHttpRequest(
00222       HttpRequestCallback* callback = NULL);
00223 
00224   /*
00225    * Resolves the templated URL into the actual URL to use.
00226    *
00227    * The base class implementation assumes that the content was set in the
00228    * constructor. It uses UriTemplate to handle URL parameters and expects
00229    * that specialized subclasses will override the ApendVariable method to
00230    * resolve the values for the variables that this method finds in the
00231    * template.
00232    *
00233    * @param[in] templated_url An
00234    * <a href='http://tools.ietf.org/html/rfc6570'>RFC 6570</a> formatted URL.
00235    * @param[out] prepared_url The templated_url after resolving the variables.
00236    *
00237    * @note Conceptually this method is <code>const</code>. However technically
00238    * it is not because so it can used as a callback method where the mechanism
00239    * does not permit non-const methods.
00240    */
00241   virtual util::Status PrepareUrl(
00242       const StringPiece& templated_url, string* prepared_url);
00243 
00244   /*
00245    * Appends the variable value to the target string.
00246    *
00247    * This method should use UriTemplate for the actual string append once
00248    * it locally determines what the value shoudl be.
00249    *
00250    * @param[in] variable_name The name of the variable to append
00251    * @param[in] config A pass through parameter needed when asking
00252    * UriTemplate to append the strings. The value of this paraemter is
00253    * determined internally by the methods within this class that invoke this
00254    * method.
00255    * @param[out] target The string to append to.
00256    */
00257   virtual util::Status AppendVariable(
00258       const StringPiece& variable_name,
00259       const UriTemplateConfig& config,
00260       string* target);
00261 
00262   /*
00263    * Appends the optional query parameters to the url.
00264    *
00265    * This method is called by the default PrepareHttpReqeuest to add the
00266    * optional parameters that might not be explicitly stated in the URI
00267    * template that was bound to the request.
00268    *
00269    * The base method simply returns success. Specialized requests should
00270    * add any optional query parameters that have been added into the request.
00271    */
00272   virtual util::Status AppendOptionalQueryParameters(string* target);
00273 
00274   /*
00275    * Execute the request synchronously. If the response suggests success then
00276    * load the response payload into the provided data parameter.
00277    *
00278    * @param[out] data The data will be cleared if the Execute was not
00279    * successful.
00280    * @return success if the Execute was successful and the response payload
00281    * could be loaded into the data object. Otherwise it will fail. If you want
00282    * to distinguish execute failures from response handling failures then you
00283    * will need to look at the http_response() details.
00284    *
00285    * This method is protected since it does not make sense on methods that
00286    * do not return json data objects. For those that do, their specialized
00287    * classes can expose this method by adding a public method that delegates
00288    * to this implementation.
00289    */
00290   util::Status ExecuteAndParseResponse(SerializableJson* data);
00291 
00292   /*
00293    * Accessor for the use_media_download attribute.
00294    *
00295    * This attribute should only be exposed by methods that support it.
00296    * @return true if the request should use HTTP media download.
00297    */
00298   bool get_use_media_download() const   { return use_media_download_; }
00299 
00300   /*
00301    * Setter for the use_media_download attribute.
00302    *
00303    * This attribute should only be exposed by methods that support it.
00304    * @param[in] use  True if HTTP should use media download.
00305    */
00306   void set_use_media_download(bool use) { use_media_download_ = use; }
00307 
00308   /*
00309    * Parse the response payload (i.e. its body_reader) as a data instance.
00310    *
00311    * @param[in,out] response The response to parse is modified as it is read.
00312    * @param[out] data The data to parse into
00313    *
00314    * @return Failure if the response has no data or cannot be parsed.
00315    * @see HttpResponse::body_reader()
00316    */
00317   static util::Status ParseResponse(
00318       HttpResponse* response, SerializableJson* data);
00319 
00320  private:
00321   scoped_ptr<HttpRequest> http_request_;  
00322   bool destroy_when_done_;
00323 
00324   /*
00325    * States whether request should use HTTP media download.
00326    *
00327    * This adds an implied optional query parameter 'alt=media' when true.
00328    * The parameter gets appended in the base AppendOptionalQueryParameters.
00329    */
00330   bool use_media_download_;
00331 
00332   /*
00333    * A helper method.
00334    *
00335    * This is an implementation for UriTemplate::AppendVariableCallback that
00336    * calls the virtual AppendVariable() method on this instance so that
00337    * subclasses can feed ther values into the template.
00338    */
00339   util::Status CallAppendVariable(
00340       const StringPiece& variable_name,
00341       const UriTemplateConfig& config,
00342       string* target);
00343 
00344   /*
00345    * A helper method.
00346    *
00347    * This is an HttpRequestCallback implementation used to auto-destroy
00348    * instances when done.
00349    */
00350   void CallbackThenDestroy(
00351       HttpRequestCallback* callback, HttpRequest* request);
00352 
00353   DISALLOW_COPY_AND_ASSIGN(ClientServiceRequest);
00354 };
00355 
00356 /*
00357  * Base class for denoting a cloud service.
00358  * @ingroup ClientServiceLayer
00359  *
00360  * A ClientService is a proxy to some service endpoint in the cloud.
00361  * It acts as a Facade to a particular service and Factory for specific
00362  * ClientServiceRequest instances to make requests of specific service
00363  * interfaces. There are no service methods common across all services so
00364  * the base class has an empty Facade and no requests to provide a factory
00365  * for. The specialized subclasses are more interesting with regard to these
00366  * roles.
00367  */
00368 class ClientService {
00369  public:
00370   /*
00371    * Constructs a service instance acting as a proxy to a given service
00372    * endpoint.
00373    *
00374    * @param[in] root_url  The root_url to access the given service.
00375    * Usually this is for the webserver that is hosting the service.
00376    *
00377    * @param[in] service_path  The additional path to append to the url
00378    * to get at the particular service.
00379    *
00380    * @param[in] transport A transport instance to use when sending requests
00381    * to the service. The service instance will take ownership of the transport.
00382    */
00383   ClientService(
00384     const StringPiece& root_url,
00385     const StringPiece& service_path,
00386     HttpTransport* transport);
00387 
00388   /*
00389    * Standard destructor.
00390    */
00391   virtual ~ClientService();
00392 
00393   /*
00394    * Returns the bound url_root attribute.
00395    */
00396   const StringPiece& url_root() const { return url_root_; }
00397 
00398   /*
00399    * Returns the bound url_path attribute.
00400    */
00401   const StringPiece& url_path() const { return url_path_; }
00402 
00403   /*
00404    * Returns the complete url to the service.
00405    * @return url_root + url_path
00406    */
00407   const string& service_url() const { return service_url_; }
00408 
00409   /*
00410    * Allows you to change the service_url.
00411    *
00412    * This method is intended as a hook to change the service_url location
00413    * from the default constructor, especially of specialized services that
00414    * might be created elsewhere. It is intended to point to a different
00415    * instance or location, such as for testing or staging.
00416    *
00417    * If you are going to change the URL, you should do so before you start
00418    * creating requests to send to it.
00419    *
00420    * @param[in] url_root The root url for the web server.
00421    * @param[in] url_path the path in the root_url for the service.
00422    * The service_url will be JoinPath(url_root,url_path)
00423    */
00424   void ChangeServiceUrl(
00425       const StringPiece& url_root, const StringPiece& url_path);
00426 
00427   /*
00428    * Returns the transport instance bound in the constructor.
00429    */
00430   HttpTransport* transport() const { return transport_.get(); }
00431 
00432  private:
00433   string service_url_;
00434   StringPiece url_root_;  // Subset of service_url_
00435   StringPiece url_path_;  // Subset of service_url_
00436 
00437   scoped_ptr<HttpTransport> transport_;
00438 
00439   DISALLOW_COPY_AND_ASSIGN(ClientService);
00440 };
00441 
00442 }  // namespace client
00443 
00444 } // namespace googleapis
00445 #endif  // APISERVING_CLIENTSCPP_SERVICE_CLIENT_SERVICE_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines