Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(362)

Side by Side Diff: Src/GoogleApis/Apis/Services/BaseClientService.cs

Issue 13412046: Reimplement OAuth2 library - Step 1 (Closed) Base URL: https://google-api-dotnet-client.googlecode.com/hg/
Patch Set: minor Created 10 years, 10 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 Copyright 2013 Google Inc 2 Copyright 2013 Google Inc
3 3
4 Licensed under the Apache License, Version 2.0 (the "License"); 4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License. 5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at 6 You may obtain a copy of the License at
7 7
8 http://www.apache.org/licenses/LICENSE-2.0 8 http://www.apache.org/licenses/LICENSE-2.0
9 9
10 Unless required by applicable law or agreed to in writing, software 10 Unless required by applicable law or agreed to in writing, software
(...skipping 24 matching lines...) Expand all
35 35
36 namespace Google.Apis.Services 36 namespace Google.Apis.Services
37 { 37 {
38 /// <summary> 38 /// <summary>
39 /// A thread-safe base class for a client service which provides common mech anism for all services, like· 39 /// A thread-safe base class for a client service which provides common mech anism for all services, like·
40 /// serialization and GZip support. 40 /// serialization and GZip support.
41 /// This class adds a special <see cref="Google.Apis.Http.IHttpExecuteInterc eptor"/> to the· 41 /// This class adds a special <see cref="Google.Apis.Http.IHttpExecuteInterc eptor"/> to the·
42 /// <see cref="Google.Apis.Http.ConfigurableMessageHandler"/> execute interc eptor list, which uses the given· 42 /// <see cref="Google.Apis.Http.ConfigurableMessageHandler"/> execute interc eptor list, which uses the given·
43 /// Authenticator. It calls to its applying authentication method, and injec ts the "Authorization" header in the· 43 /// Authenticator. It calls to its applying authentication method, and injec ts the "Authorization" header in the·
44 /// request. 44 /// request.
45 /// If the given Authenticator implements <see cref="Google.Apis.Http.IUnsuc cessfulReponseHandler"/>, this class 45 /// If the given Authenticator implements <see cref="Google.Apis.Http.IHttpU nsuccessfulResponseHandler"/>, this·
46 /// adds the Authenticator to the <see cref="Google.Apis.Http.ConfigurableMe ssageHandler"/>'s unsuccessful response 46 /// class adds the Authenticator to the <see cref="Google.Apis.Http.Configur ableMessageHandler"/>'s unsuccessful·
47 /// handler list. 47 /// response handler list.
48 /// </summary> 48 /// </summary>
49 public abstract class BaseClientService : IClientService 49 public abstract class BaseClientService : IClientService
50 { 50 {
51 /// <summary> The class logger. </summary> 51 /// <summary>The class logger.</summary>
52 private static readonly ILogger Logger = ApplicationContext.Logger.ForTy pe<BaseClientService>(); 52 private static readonly ILogger Logger = ApplicationContext.Logger.ForTy pe<BaseClientService>();
53 53
54 #region Initializer 54 #region Initializer
55 55
56 /// <summary>· 56 /// <summary>An initializer class for the client service.</summary>
57 /// Indicates if exponential back-off is used automatically on exception in a service request and\or when 503·
58 /// response is returned form the server.
59 /// </summary>
60 [Flags]
61 public enum ExponentialBackOffPolicy
62 {
63 None = 0,
64 Exception = 1,
65 UnsuccessfulResponse503 = 2
66 }
67
68 /// <summary> An initializer class for the client service. </summary>
69 public class Initializer 57 public class Initializer
70 { 58 {
71 /// <summary> 59 /// <summary>
72 /// Gets or sets the factory for creating <see cref="System.Net.Http .HttpClient"/> instance. If this· 60 /// Gets or sets the factory for creating <see cref="System.Net.Http .HttpClient"/> instance. If this·
73 /// property is not set the service uses a new <see cref="Google.Api s.Http.HttpClientFactory"/> instance. 61 /// property is not set the service uses a new <see cref="Google.Api s.Http.HttpClientFactory"/> instance.
74 /// </summary> 62 /// </summary>
75 public IHttpClientFactory HttpClientFactory { get; set; } 63 public IHttpClientFactory HttpClientFactory { get; set; }
76 64
77 /// <summary> 65 /// <summary>
78 /// Gets or sets an Http client initializer which is able to customi ze properties on· 66 /// Gets or sets a HTTP client initializer which is able to customiz e properties on·
79 /// <see cref="Google.Apis.Http.ConfigurableHttpClient"/> and· 67 /// <see cref="Google.Apis.Http.ConfigurableHttpClient"/> and·
80 /// <see cref="Google.Apis.Http.ConfigurableMessageHandler"/>. 68 /// <see cref="Google.Apis.Http.ConfigurableMessageHandler"/>.
81 /// </summary> 69 /// </summary>
82 public IConfigurableHttpClientInitializer HttpClientInitializer { ge t; set; } 70 public IConfigurableHttpClientInitializer HttpClientInitializer { ge t; set; }
83 71
84 /// <summary> 72 /// <summary>
85 /// Get or sets the exponential back-off policy used by the service. Default value is· 73 /// Get or sets the exponential back-off policy used by the service. Default value is·
86 /// <c>UnsuccessfulResponse503</c>, which means that exponential bac k-off is used on 503 abnormal HTTP 74 /// <c>UnsuccessfulResponse503</c>, which means that exponential bac k-off is used on 503 abnormal HTTP
87 /// response. 75 /// response.
88 /// If the value is set to <c>None</c>, no exponential back-off poli cy is used, and it's up to user to 76 /// If the value is set to <c>None</c>, no exponential back-off poli cy is used, and it's up to user to
89 /// configure the <seealso cref="Google.Apis.Http.ConfigurableMessag eHandler"/> in an 77 /// configure the <seealso cref="Google.Apis.Http.ConfigurableMessag eHandler"/> in an
90 /// <seealso cref="Google.Apis.Http.IConfigurableHttpClientInitializ er"/> to set a specific back-off 78 /// <seealso cref="Google.Apis.Http.IConfigurableHttpClientInitializ er"/> to set a specific back-off
91 /// implementation (using <seealso cref="Google.Api.Http.BackOffHand ler"/>). 79 /// implementation (using <seealso cref="Google.Apis.Http.BackOffHan dler"/>).
92 /// </summary> 80 /// </summary>
93 public ExponentialBackOffPolicy DefaultExponentialBackOffPolicy { ge t; set; } 81 public ExponentialBackOffPolicy DefaultExponentialBackOffPolicy { ge t; set; }
94 82
95 /// <summary> Gets or sets whether this service supports GZip. Defau lt value is <c>true</c>. </summary> 83 /// <summary>Gets or sets whether this service supports GZip. Defaul t value is <c>true</c>.</summary>
96 public bool GZipEnabled { get; set; } 84 public bool GZipEnabled { get; set; }
97 85
98 /// <summary> 86 /// <summary>
99 /// Gets and Sets the Serializer. Default value is <see cref="Google .Apis.Json.NewtonsoftJsonSerializer"/>. 87 /// Gets and Sets the serializer. Default value is <see cref="Google .Apis.Json.NewtonsoftJsonSerializer"/>.
100 /// </summary> 88 /// </summary>
101 public ISerializer Serializer { get; set; } 89 public ISerializer Serializer { get; set; }
102 90
103 /// <summary> Gets or sets the API Key. Default value is <c>null</c> . </summary> 91 /// <summary>Gets or sets the API Key. Default value is <c>null</c>. </summary>
104 public string ApiKey { get; set; } 92 public string ApiKey { get; set; }
105 93
106 /// <summary> 94 /// <summary>
107 /// Gets or sets the Authenticator. Default value is· 95 /// Gets or sets the Authenticator. Default value is·
108 /// <see cref="Google.Apis.Authentication.NullAuthenticator.Instance "/>. 96 /// <see cref="Google.Apis.Authentication.NullAuthenticator.Instance "/>.
109 /// </summary> 97 /// </summary>
110 public IAuthenticator Authenticator { get; set; } 98 public IAuthenticator Authenticator { get; set; }
111 99
112 /// <summary> 100 /// <summary>
113 /// Gets or sets Application name to be used in the User-Agent heade r. Default value is <c>null</c>.· 101 /// Gets or sets Application name to be used in the User-Agent heade r. Default value is <c>null</c>.·
114 /// </summary> 102 /// </summary>
115 public string ApplicationName { get; set; } 103 public string ApplicationName { get; set; }
116 104
117 /// <summary> Constructs a new initializer with default values. </su mmary> 105 /// <summary>Constructs a new initializer with default values.</summ ary>
118 public Initializer() 106 public Initializer()
119 { 107 {
120 GZipEnabled = true; 108 GZipEnabled = true;
121 Serializer = new NewtonsoftJsonSerializer(); 109 Serializer = new NewtonsoftJsonSerializer();
122 Authenticator = NullAuthenticator.Instance; 110 Authenticator = NullAuthenticator.Instance;
123 DefaultExponentialBackOffPolicy = ExponentialBackOffPolicy.Unsuc cessfulResponse503; 111 DefaultExponentialBackOffPolicy = ExponentialBackOffPolicy.Unsuc cessfulResponse503;
124 } 112 }
125 } 113 }
126 114
127 /// <summary>
128 /// An initializer which adds exponential back-off as exception handler and\or unsuccessful response handler by
129 /// the given <seealso cref="BaseClientService.ExponentialBackOffPolicy" />.
130 /// </summary>
131 private class ExponentialBackOffInitializer : IConfigurableHttpClientIni tializer
132 {
133 private ExponentialBackOffPolicy Policy { get; set; }
134 private Func<BackOffHandler> CreateBackOff { get; set; }
135
136 /// <summary>
137 /// Constructs a new back-off initializer with the given policy and back-off handler create function.
138 /// </summary>
139 public ExponentialBackOffInitializer(ExponentialBackOffPolicy policy , Func<BackOffHandler> createBackOff)
140 {
141 Policy = policy;
142 CreateBackOff = createBackOff;
143 }
144
145 public void Initialize(ConfigurableHttpClient httpClient)
146 {
147 var backOff = CreateBackOff();
148
149 // add exception handler and\or unsuccessful response handler
150 if ((Policy & ExponentialBackOffPolicy.Exception) == Exponential BackOffPolicy.Exception)
151 {
152 httpClient.MessageHandler.ExceptionHandlers.Add(backOff);
153 }
154
155 if ((Policy & ExponentialBackOffPolicy.UnsuccessfulResponse503) ==
156 ExponentialBackOffPolicy.UnsuccessfulResponse503)
157 {
158 httpClient.MessageHandler.UnsuccessfulResponseHandlers.Add(b ackOff);
159 }
160 }
161 }
162
163 #endregion 115 #endregion
164 116
165 /// <summary> Constructs a new base client with the specified initialize r. </summary> 117 /// <summary>Constructs a new base client with the specified initializer .</summary>
166 protected BaseClientService(Initializer initializer) 118 protected BaseClientService(Initializer initializer)
167 { 119 {
168 // sets the right properties by the initializer's properties 120 // Set the right properties by the initializer's properties.
169 GZipEnabled = initializer.GZipEnabled; 121 GZipEnabled = initializer.GZipEnabled;
170 Serializer = initializer.Serializer; 122 Serializer = initializer.Serializer;
171 ApiKey = initializer.ApiKey; 123 ApiKey = initializer.ApiKey;
172 Authenticator = initializer.Authenticator; 124 Authenticator = initializer.Authenticator;
173 ApplicationName = initializer.ApplicationName; 125 ApplicationName = initializer.ApplicationName;
174 if (ApplicationName == null) 126 if (ApplicationName == null)
175 { 127 {
176 Logger.Warning("Application name is not set. Please set Initiali zer.ApplicationName property"); 128 Logger.Warning("Application name is not set. Please set Initiali zer.ApplicationName property");
177 } 129 }
178 HttpClientInitializer = initializer.HttpClientInitializer; 130 HttpClientInitializer = initializer.HttpClientInitializer;
179 131
180 // create an Http client for this service 132 // Create a HTTP client for this service.
181 HttpClient = CreateHttpClient(initializer); 133 HttpClient = CreateHttpClient(initializer);
182 } 134 }
183 135
184 /// <summary> Return <c>true</c> if this service contains the specified feature. </summary> 136 /// <summary>Returns <c>true</c> if this service contains the specified feature.</summary>
185 private bool HasFeature(Features feature) 137 private bool HasFeature(Features feature)
186 { 138 {
187 return Features.Contains(feature.GetStringValue()); 139 return Features.Contains(feature.GetStringValue());
188 } 140 }
189 141
190 private ConfigurableHttpClient CreateHttpClient(Initializer initializer) 142 private ConfigurableHttpClient CreateHttpClient(Initializer initializer)
191 { 143 {
192 // if factory wasn't set use the default Http client factory 144 // If factory wasn't set use the default HTTP client factory.
193 var factory = initializer.HttpClientFactory ?? new HttpClientFactory (); 145 var factory = initializer.HttpClientFactory ?? new HttpClientFactory ();
194 var args = new CreateHttpClientArgs 146 var args = new CreateHttpClientArgs
195 { 147 {
196 GZipEnabled = GZipEnabled, 148 GZipEnabled = GZipEnabled,
197 ApplicationName = ApplicationName, 149 ApplicationName = ApplicationName,
198 }; 150 };
199 151
200 // add the user's input initializer 152 // Add the user's input initializer.
201 if (HttpClientInitializer != null) 153 if (HttpClientInitializer != null)
202 { 154 {
203 args.Initializers.Add(HttpClientInitializer); 155 args.Initializers.Add(HttpClientInitializer);
204 } 156 }
205 157
206 // add exponential back-off initializer if necessary 158 // Add exponential back-off initializer if necessary.
207 if (initializer.DefaultExponentialBackOffPolicy != ExponentialBackOf fPolicy.None) 159 if (initializer.DefaultExponentialBackOffPolicy != ExponentialBackOf fPolicy.None)
208 { 160 {
209 args.Initializers.Add(new ExponentialBackOffInitializer(initiali zer.DefaultExponentialBackOffPolicy, 161 args.Initializers.Add(new ExponentialBackOffInitializer(initiali zer.DefaultExponentialBackOffPolicy,
210 CreateBackOffHandler)); 162 CreateBackOffHandler));
211 } 163 }
212 164
213 // add authenticator initializer to intercept a request and add the "Authorization" header and also handle 165 // Add authenticator initializer to intercept a request and add the "Authorization" header and also handle
214 // abnormal 401 responses in case the authenticator is an instance o f unsuccessful response handler. 166 // abnormal 401 responses in case the authenticator is an instance o f unsuccessful response handler.
215 args.Initializers.Add(new AuthenticatorMessageHandlerInitializer(Aut henticator)); 167 args.Initializers.Add(new AuthenticatorMessageHandlerInitializer(Aut henticator));
216 168
217 return factory.CreateHttpClient(args); 169 return factory.CreateHttpClient(args);
218 } 170 }
219 171
220 /// <summary> 172 /// <summary>
221 /// Creates the back-off handler with <seealso cref="Google.Apis.Util.Ex ponentialBackOff"/>.· 173 /// Creates the back-off handler with <seealso cref="Google.Apis.Util.Ex ponentialBackOff"/>.·
222 /// Overrides this method to change the default behavior of back-off han dler (e.g. you can change the maximum 174 /// Overrides this method to change the default behavior of back-off han dler (e.g. you can change the maximum
223 /// waited request's time span, or create a back-off handler with you ow n implementation of· 175 /// waited request's time span, or create a back-off handler with you ow n implementation of·
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 public ISerializer Serializer { get; private set; } 229 public ISerializer Serializer { get; private set; }
278 230
279 public virtual string SerializeObject(object obj) 231 public virtual string SerializeObject(object obj)
280 { 232 {
281 if (HasFeature(Discovery.Features.LegacyDataResponse)) 233 if (HasFeature(Discovery.Features.LegacyDataResponse))
282 { 234 {
283 // Legacy path 235 // Legacy path
284 var request = new StandardResponse<object> { Data = obj }; 236 var request = new StandardResponse<object> { Data = obj };
285 return Serializer.Serialize(request); 237 return Serializer.Serialize(request);
286 } 238 }
287
288 // New v1.0 path
289 return Serializer.Serialize(obj); 239 return Serializer.Serialize(obj);
290 } 240 }
291 241
292 public virtual async Task<T> DeserializeResponse<T>(HttpResponseMessage response) 242 public virtual async Task<T> DeserializeResponse<T>(HttpResponseMessage response)
293 { 243 {
294 var text = await response.Content.ReadAsStringAsync().ConfigureAwait (false); 244 var text = await response.Content.ReadAsStringAsync().ConfigureAwait (false);
295 245
296 // If a string is request, don't parse the response. 246 // If a string is request, don't parse the response.
297 if (typeof(T).Equals(typeof(string))) 247 if (typeof(T).Equals(typeof(string)))
298 { 248 {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 // Standard response (which contains data and error properties) 317 // Standard response (which contains data and error properties)
368 throw new GoogleApiException(Name, 318 throw new GoogleApiException(Name,
369 "An Error occurred, but the error response could not be dese rialized", ex); 319 "An Error occurred, but the error response could not be dese rialized", ex);
370 } 320 }
371 321
372 return errorResponse.Error; 322 return errorResponse.Error;
373 } 323 }
374 324
375 #endregion 325 #endregion
376 326
377 #region Abstract Memebrs 327 #region Abstract Members
378 328
379 public abstract string Name { get; } 329 public abstract string Name { get; }
380 public abstract string BaseUri { get; } 330 public abstract string BaseUri { get; }
381 public abstract string BasePath { get; } 331 public abstract string BasePath { get; }
382 332
383 public abstract IList<string> Features { get; } 333 public abstract IList<string> Features { get; }
384 334
385 #endregion 335 #endregion
386 336
387 #endregion 337 #endregion
388 338
389 /// <summary> Creates a GZip stream by the given serialized object. </su mmary> 339 /// <summary>Creates a GZip stream by the given serialized object.</summ ary>
390 private static Stream CreateGZipStream(string serializedObject) 340 private static Stream CreateGZipStream(string serializedObject)
391 { 341 {
392 byte[] bytes = System.Text.Encoding.UTF8.GetBytes(serializedObject); 342 byte[] bytes = System.Text.Encoding.UTF8.GetBytes(serializedObject);
393 using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) 343 using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
394 { 344 {
395 using (GZipStream gzip = new GZipStream(ms, CompressionMode.Comp ress, true)) 345 using (GZipStream gzip = new GZipStream(ms, CompressionMode.Comp ress, true))
396 { 346 {
397 gzip.Write(bytes, 0, bytes.Length); 347 gzip.Write(bytes, 0, bytes.Length);
398 } 348 }
399 349
400 // reset the stream to the beginning. It doesn't work otherwise! 350 // reset the stream to the beginning. It doesn't work otherwise!
401 ms.Position = 0; 351 ms.Position = 0;
402 byte[] compressed = new byte[ms.Length]; 352 byte[] compressed = new byte[ms.Length];
403 ms.Read(compressed, 0, compressed.Length); 353 ms.Read(compressed, 0, compressed.Length);
404 return new MemoryStream(compressed); 354 return new MemoryStream(compressed);
405 } 355 }
406 } 356 }
407 357
408 public virtual void Dispose() 358 public virtual void Dispose()
409 { 359 {
410 if (HttpClient != null) 360 if (HttpClient != null)
411 { 361 {
412 HttpClient.Dispose(); 362 HttpClient.Dispose();
413 } 363 }
414 } 364 }
415 } 365 }
416 } 366 }
OLDNEW

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b