Google APIs Client Library for C++
|
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 00021 #ifndef APISERVING_CLIENTS_CPP_TRANSPORT_JSON_SCRIBE_H_ 00022 #define APISERVING_CLIENTS_CPP_TRANSPORT_JSON_SCRIBE_H_ 00023 00024 #include <string> 00025 using std::string; 00026 00027 #include "googleapis/client/transport/http_scribe.h" 00028 #include "googleapis/base/thread_annotations.h" 00029 #include "googleapis/base/integral_types.h" 00030 #include "googleapis/base/scoped_ptr.h" 00031 #include "googleapis/strings/strcat.h" 00032 #include "googleapis/strings/stringpiece.h" 00033 #include <json/value.h> 00034 #include <json/writer.h> 00035 namespace googleapis { 00036 00037 namespace client { 00038 class DataWriter; 00039 00040 /* 00041 * Specialized HttpScribe that produces JSON transcripts. 00042 * @ingroup TransportLayerTesting 00043 * 00044 * The scribe writes JSON directly to the writer. It does not proovide 00045 * an interactive interface to interpret the JSON it is writing. In order 00046 * to see the events, you must look at the writer. 00047 * 00048 * The implementation of this class may stream directly to the writer, in 00049 * which case it may not be well-formed if it did not finish properly 00050 * (e.g. it is still scribing or the process crashed). If that is the case, 00051 * you may need to append the closing brackets and braces to make it well 00052 * formed if you wish to read it back as json. 00053 * 00054 * The transcript has the following JSON structure: 00055 * { 00056 * kStartTime : datetime 00057 * kMaxSnippet: int64 00058 * kMessages : [ 00059 * { 00060 * kUrl : string 00061 * kHttpCode : int # none or 0 if no response 00062 * kStatusCode : int # transport error, if any 00063 * kStatusMessage : string # transport error, if any 00064 * kRequest : { 00065 * kHeaders : [ 00066 * string : string # name, value pairs 00067 * string : string 00068 * ] 00069 * kBytes : string 00070 * kSize : int64 00071 * kCensored : bool 00072 * } 00073 * kResponse : { 00074 * (same as request but for response data) 00075 * } 00076 * ] 00077 * kEndTime : datetime 00078 * } 00079 * 00080 * The individual fields are documented as class constants. Each constant also 00081 * documents the JSON format for the values. 00082 */ 00083 class JsonScribe : public HttpEntryScribe { 00084 public: 00085 /* 00086 * Constructor. 00087 * 00088 * @param[in] censor The caller retains ownership. 00089 * @param[in] writer Ownership is passed to the scribe. This writer will 00090 * store the transcript. 00091 * @param[in] compact If truen then write compact json, otherwise stylized. 00092 */ 00093 JsonScribe( 00094 HttpScribeCensor* censor, DataWriter* writer, bool compact = true); 00095 00096 /* 00097 * Standard destructor. 00098 * 00099 * This will finish the JSON and flush the writer to make a well formed 00100 * JSON document transcript. 00101 */ 00102 virtual ~JsonScribe(); 00103 00104 /* 00105 * Implements base Checkpoint method. 00106 */ 00107 virtual void Checkpoint(); 00108 00109 //------------------------- JSON Tag Constants ------------------------- 00110 00111 static const char kStartTime[]; //< The transcript start time (date). 00112 static const char kMaxSnippet[]; //< The max_snippet size used (int64). 00113 static const char kEndTime[]; //< The transcript end time (date). 00114 /* 00115 * The JSON object tag for the message sequence. 00116 * 00117 * The message sequence is a JSON array object where each element in the 00118 * array is a flat dictionary containing the per-request attributes. 00119 */ 00120 static const char kMessages[]; 00121 00122 static const char kMethod[]; //< Request HTTP method type (string). 00123 static const char kUrl[]; //< Request url (string). 00124 00125 /* 00126 * The HTTP response code, if any (int). 00127 * 00128 * If this tag is not present, or the value is 0, then a response was not 00129 * received. This could be because of a transport error in which case 00130 * the kStatusCode and kStatusMessage fields should be present. Otherwise 00131 * it means that a response was not yet recorded for whatever reason 00132 * including the transcript was finished before the request completed. 00133 */ 00134 static const char kHttpCode[]; 00135 00136 /* 00137 * The transport util::Status::error_code value (int). 00138 * 00139 * An error here indicates a transport error when sending the request. 00140 * The response was either never received or the request was never sent. 00141 * 00142 * Note that the status codes that specific errors produce is not yet 00143 * well defined so may change from release to release. The StatusMessage 00144 * will be of more value if you are physically inspecting these messages. 00145 * 00146 * A value of 0 indicates everything was ok. This is the only well defined 00147 * value that will not change in future releases. If this field is not 00148 * present, then the transport status is assumed to be OK. 00149 * 00150 * @see HttpRequestState::transport_status 00151 */ 00152 static const char kStatusCode[]; 00153 00154 /* 00155 * The transport util::Status::error_message value (string). 00156 * 00157 * If this is present and not empty then it gives an explanation for the 00158 * transport status. This is usually an error but not necessarily. The 00159 * kStatusCode field will indicate whether it is ok or not. 00160 * 00161 * The message values are intended to be human readable and may change from 00162 * release to release. 00163 */ 00164 static const char kStatusMessage[]; 00165 00166 /* 00167 * Timestamp request was sent in microseconds since the epoch (int64). 00168 */ 00169 static const char kSendMicros[]; 00170 00171 /* 00172 * Timestamp response was received in microseconds since the epoch (int64). 00173 */ 00174 static const char kResponseMicros[]; 00175 00176 /* 00177 * Timestamp of transport error in microseconds since the epoch (int64). 00178 */ 00179 static const char kErrorMicros[]; 00180 00181 static const char kRequest[]; //< Message request (dict). 00182 static const char kResponse[]; //< Message response (dict). 00183 00184 // These are fields within the request and response dictionaries. 00185 static const char kPayload[]; //< Message payload data. 00186 static const char kPayloadSize[]; //< Real request payload size (int64). 00187 static const char kPayloadCensored[]; //< True if censored (bool). 00188 static const char kHeaders[]; //< Headers (dict). ( 00189 00190 protected: 00191 /* 00192 * Returns an entry that produces the individual JSON transcript for 00193 * the request. 00194 */ 00195 virtual Entry* NewEntry(const HttpRequest* request); 00196 00197 private: 00198 scoped_ptr<DataWriter> writer_; 00199 scoped_ptr<Json::Writer> json_writer_; 00200 int64 last_checkpoint_; 00201 bool started_; 00202 Json::Value json_; 00203 }; 00204 00205 } // namespace client 00206 00207 } // namespace googleapis 00208 #endif // APISERVING_CLIENTS_CPP_TRANSPORT_JSON_SCRIBE_H_