Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit d6c2f58

Browse files
committedJul 12, 2016
2 parents 661f89b + 76eb269 commit d6c2f58

File tree

7 files changed

+156
-64
lines changed

7 files changed

+156
-64
lines changed
 

‎Rally.RestApi.UiForWinforms/RestApiAuthMgrWinforms.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@ public class RestApiAuthMgrWinforms : ApiAuthManager
2929
/// for UI support.</param>
3030
/// <param name="encryptionRoutines">The encryption routines to use for encryption/decryption of data. Only used for UI support.</param>
3131
/// <param name="webServiceVersion">The version of the WSAPI API to use.</param>
32+
/// <param name="traceInfo">Controls diagnostic trace information being logged</param>
3233
public RestApiAuthMgrWinforms(string applicationToken, string encryptionKey,
33-
IEncryptionRoutines encryptionRoutines, string webServiceVersion = RallyRestApi.DEFAULT_WSAPI_VERSION)
34-
: base(true, applicationToken, encryptionKey, encryptionRoutines, webServiceVersion)
34+
IEncryptionRoutines encryptionRoutines, string webServiceVersion = RallyRestApi.DEFAULT_WSAPI_VERSION, TraceFieldEnum traceInfo = RallyRestApi.DEFAULT_TRACE_FIELDS)
35+
: base(true, applicationToken, encryptionKey, encryptionRoutines, webServiceVersion, traceInfo)
3536
{
3637
}
3738
#endregion

‎Rally.RestApi/Auth/ApiAuthManager.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,9 @@ static ApiAuthManager()
171171
/// for UI support.</param>
172172
/// <param name="encryptionRoutines">The encryption routines to use for encryption/decryption of data. Only used for UI support.</param>
173173
/// <param name="webServiceVersion">The version of the WSAPI API to use.</param>
174+
/// <param name="traceInfo">Controls diagnostic trace information being logged</param>
174175
protected ApiAuthManager(bool isUiSupported, string applicationToken, string encryptionKey,
175-
IEncryptionRoutines encryptionRoutines, string webServiceVersion = RallyRestApi.DEFAULT_WSAPI_VERSION)
176+
IEncryptionRoutines encryptionRoutines, string webServiceVersion = RallyRestApi.DEFAULT_WSAPI_VERSION, TraceFieldEnum traceInfo = RallyRestApi.DEFAULT_TRACE_FIELDS)
176177
{
177178
if (isUiSupported)
178179
{
@@ -203,7 +204,7 @@ protected ApiAuthManager(bool isUiSupported, string applicationToken, string enc
203204
}
204205

205206
IsUiSupported = isUiSupported;
206-
Api = new RallyRestApi(this, webServiceVersion: webServiceVersion);
207+
Api = new RallyRestApi(this, webServiceVersion: webServiceVersion, traceInfo: traceInfo);
207208
}
208209
#endregion
209210

‎Rally.RestApi/Auth/ApiConsoleAuthManager.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ public class ApiConsoleAuthManager : ApiAuthManager
1515
/// Constructor
1616
/// </summary>
1717
/// <param name="webServiceVersion">The version of the WSAPI API to use.</param>
18-
public ApiConsoleAuthManager(string webServiceVersion = RallyRestApi.DEFAULT_WSAPI_VERSION)
19-
: base(false, null, null, null, webServiceVersion)
18+
/// <param name="traceInfo">Controls diagnostic trace information being logged</param>
19+
public ApiConsoleAuthManager(string webServiceVersion = RallyRestApi.DEFAULT_WSAPI_VERSION, TraceFieldEnum traceInfo = RallyRestApi.DEFAULT_TRACE_FIELDS)
20+
: base(false, null, null, null, webServiceVersion, traceInfo)
2021
{
2122
}
2223
#endregion

‎Rally.RestApi/Rally.RestApi.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
<Compile Include="Connection\ConnectionType.cs" />
8686
<Compile Include="Exceptions\RallyFailedToDeserializeJson.cs" />
8787
<Compile Include="Response\AttachmentResult.cs" />
88+
<Compile Include="TraceHelper.cs" />
8889
<Compile Include="Web\SsoWebClient.cs" />
8990
<Compile Include="Web\CookieAwareCacheableWebClient.cs" />
9091
<Compile Include="Web\CookieAwareWebClient.cs" />

‎Rally.RestApi/RallyRestApi.cs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ internal class StringValue : Attribute
120120
/// </summary>
121121
public const string DEFAULT_WSAPI_VERSION = "v2.0";
122122
/// <summary>
123+
/// The default Trace fields
124+
/// </summary>
125+
public const TraceFieldEnum DEFAULT_TRACE_FIELDS = TraceFieldEnum.Data | TraceFieldEnum.Headers | TraceFieldEnum.Cookies;
126+
/// <summary>
123127
/// The default server to use: (https://rally1.rallydev.com)
124128
/// </summary>
125129
public const string DEFAULT_SERVER = "https://rally1.rallydev.com";
@@ -132,6 +136,7 @@ internal class StringValue : Attribute
132136
#region Properties and Fields
133137
private ApiAuthManager authManger;
134138
private HttpService httpService;
139+
private int maxRetries;
135140
private readonly DynamicJsonSerializer serializer = new DynamicJsonSerializer();
136141
/// <summary>
137142
/// The HTTP headers to be included on all REST requests
@@ -176,6 +181,8 @@ public string WebServiceUrl
176181
/// <param name="authManger">The authorization manager to use when authentication requires it. If no driver is
177182
/// provided a console authentication manager will be used which does not allow SSO authentication.</param>
178183
/// <param name="webServiceVersion">The WSAPI version to use (defaults to DEFAULT_WSAPI_VERSION)</param>
184+
/// <param name="maxRetries">Requests will be attempted a number of times (defaults to 3)</param>
185+
/// <param name="traceInfo">Controls diagnostic trace information being logged</param>
179186
/// <example>
180187
/// For a console application, no authentication manager is needed as shown in this example.
181188
/// <code language="C#">
@@ -196,13 +203,15 @@ public string WebServiceUrl
196203
/// wpfAuthMgr = new RestApiAuthMgrWpf(applicationToken, encryptionKey, encryptionUtilities);
197204
/// </code>
198205
/// </example>
199-
public RallyRestApi(ApiAuthManager authManger = null, string webServiceVersion = DEFAULT_WSAPI_VERSION)
206+
public RallyRestApi(ApiAuthManager authManger = null, string webServiceVersion = DEFAULT_WSAPI_VERSION, int maxRetries = 3, TraceFieldEnum traceInfo = RallyRestApi.DEFAULT_TRACE_FIELDS)
200207
{
201208
// NOTE: The example for using the RestApiAuthMgrWpf is also shown there. Make sure you
202209
// update both if you change it.
203210

211+
TraceHelper.TraceFields = traceInfo;
212+
204213
if (authManger == null)
205-
authManger = new ApiConsoleAuthManager();
214+
authManger = new ApiConsoleAuthManager(webServiceVersion, traceInfo);
206215

207216
this.authManger = authManger;
208217

@@ -211,6 +220,8 @@ public RallyRestApi(ApiAuthManager authManger = null, string webServiceVersion =
211220
WsapiVersion = DEFAULT_WSAPI_VERSION;
212221

213222
AuthenticationState = AuthenticationResult.NotAuthorized;
223+
224+
this.maxRetries = maxRetries;
214225
}
215226
#endregion
216227

@@ -593,7 +604,7 @@ public QueryResult Query(Request request)
593604
alreadyDownloadedItems = request.Start - 1 + request.PageSize;
594605
}
595606

596-
Trace.TraceInformation("The number of threaded requests is : {0}", subsequentQueries.Count);
607+
TraceHelper.TraceMessage("The number of threaded requests is : {0}", subsequentQueries.Count);
597608

598609
var resultDictionary = new Dictionary<int, QueryResult>();
599610
Parallel.ForEach(subsequentQueries, new ParallelOptions { MaxDegreeOfParallelism = MAX_THREADS_ALLOWED }, request1 =>
@@ -1339,7 +1350,7 @@ private DynamicJsonObject DoGetAsPost(Request request, bool retry = true, int re
13391350
Dictionary<string, string> processedHeaders = GetProcessedHeaders();
13401351
DynamicJsonObject response = serializer.Deserialize(httpService.GetAsPost(GetSecuredUri(uri), data, processedHeaders));
13411352

1342-
if (retry && response[response.Fields.First()].Errors.Count > 0 && retryCounter < 3)
1353+
if (retry && response[response.Fields.First()].Errors.Count > 0 && retryCounter < this.maxRetries)
13431354
{
13441355
ConnectionInfo.SecurityToken = GetSecurityToken();
13451356
httpService = new HttpService(authManger, ConnectionInfo);
@@ -1351,7 +1362,7 @@ private DynamicJsonObject DoGetAsPost(Request request, bool retry = true, int re
13511362
}
13521363
catch (Exception)
13531364
{
1354-
if (retryCounter < 3)
1365+
if (retryCounter < this.maxRetries)
13551366
{
13561367
Thread.Sleep(retrySleepTime * retryCounter);
13571368
return DoGetAsPost(request, true, ++retryCounter);
@@ -1378,7 +1389,7 @@ private DynamicJsonObject DoGet(Uri uri, bool retry = true, int retryCounter = 1
13781389
Dictionary<string, string> processedHeaders = GetProcessedHeaders();
13791390
DynamicJsonObject response = serializer.Deserialize(httpService.Get(uri, processedHeaders));
13801391

1381-
if (retry && response[response.Fields.First()].Errors.Count > 0 && retryCounter < 3)
1392+
if (retry && response[response.Fields.First()].Errors.Count > 0 && retryCounter < this.maxRetries)
13821393
{
13831394
ConnectionInfo.SecurityToken = GetSecurityToken();
13841395
httpService = new HttpService(authManger, ConnectionInfo);
@@ -1390,7 +1401,7 @@ private DynamicJsonObject DoGet(Uri uri, bool retry = true, int retryCounter = 1
13901401
}
13911402
catch (Exception)
13921403
{
1393-
if (retryCounter < 3)
1404+
if (retryCounter < this.maxRetries)
13941405
{
13951406
Thread.Sleep(retrySleepTime * retryCounter);
13961407
return DoGet(uri, true, ++retryCounter);
@@ -1417,7 +1428,7 @@ private DynamicJsonObject DoPost(Uri uri, DynamicJsonObject data, bool retry = t
14171428
Dictionary<string, string> processedHeaders = GetProcessedHeaders();
14181429
var response = serializer.Deserialize(httpService.Post(GetSecuredUri(uri), serializer.Serialize(data), processedHeaders));
14191430

1420-
if (retry && response[response.Fields.First()].Errors.Count > 0 && retryCounter < 3)
1431+
if (retry && response[response.Fields.First()].Errors.Count > 0 && retryCounter < this.maxRetries)
14211432
{
14221433
ConnectionInfo.SecurityToken = GetSecurityToken();
14231434
httpService = new HttpService(authManger, ConnectionInfo);
@@ -1429,7 +1440,7 @@ private DynamicJsonObject DoPost(Uri uri, DynamicJsonObject data, bool retry = t
14291440
}
14301441
catch (Exception)
14311442
{
1432-
if (retryCounter < 3)
1443+
if (retryCounter < this.maxRetries)
14331444
{
14341445
Thread.Sleep(retrySleepTime * retryCounter);
14351446
return DoPost(uri, data, true, ++retryCounter);
@@ -1479,7 +1490,7 @@ private string GetSecurityToken()
14791490
{
14801491
try
14811492
{
1482-
DynamicJsonObject securityTokenResponse = DoGet(new Uri(GetFullyQualifiedRef(SECURITY_ENDPOINT)));
1493+
DynamicJsonObject securityTokenResponse = DoGet(new Uri(GetFullyQualifiedRef(SECURITY_ENDPOINT)), this.maxRetries > 1);
14831494
return securityTokenResponse["OperationResult"]["SecurityToken"];
14841495
}
14851496
catch

‎Rally.RestApi/TraceHelper.cs

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace Rally.RestApi
9+
{
10+
/// <summary>
11+
/// Diagnostic trace settings
12+
/// </summary>
13+
[Flags]
14+
public enum TraceFieldEnum
15+
{
16+
/// <summary>
17+
/// No trace
18+
/// </summary>
19+
None = 0,
20+
21+
/// <summary>
22+
/// Includes Request/Response Data
23+
/// </summary>
24+
Data = 1,
25+
26+
/// <summary>
27+
/// Include Request/Response Headers
28+
/// </summary>
29+
Headers = 2,
30+
31+
/// <summary>
32+
/// Include Before/After Cookies
33+
/// </summary>
34+
Cookies = 4
35+
}
36+
37+
/// <summary>
38+
/// Helper class for logging diagnostic trace messages
39+
/// </summary>
40+
public static class TraceHelper
41+
{
42+
/// <summary>
43+
/// Variable controlling level of Trace output
44+
/// </summary>
45+
public static TraceFieldEnum TraceFields { get; set; }
46+
47+
/// <summary>
48+
/// Log a Trace message
49+
/// </summary>
50+
public static void TraceMessage(string format, params object[] args)
51+
{
52+
if (TraceHelper.TraceFields > 0)
53+
{
54+
Trace.TraceInformation(format + "\r\n\r\n", args);
55+
}
56+
}
57+
58+
/// <summary>
59+
/// Log a Http Trace message
60+
/// </summary>
61+
public static void TraceHttpMessage(string action, DateTime startTime, Uri target, string requestHeaders, object responseData, string responseHeaders)
62+
{
63+
TraceHttpMessage(action, startTime, target, null, requestHeaders, null, responseData, responseHeaders, null);
64+
}
65+
66+
/// <summary>
67+
/// Log a Http Trace message
68+
/// </summary>
69+
public static void TraceHttpMessage(string action, DateTime startTime, Uri target, string requestHeaders, string cookiesBefore, object responseData, string responseHeaders, string cookiesAfter)
70+
{
71+
TraceHttpMessage(action, startTime, target, null, requestHeaders, cookiesBefore, responseData, responseHeaders, cookiesAfter);
72+
}
73+
74+
/// <summary>
75+
/// Log a Http Trace message
76+
/// </summary>
77+
public static void TraceHttpMessage(string action, DateTime startTime, Uri target, object requestData, string requestHeaders, string cookiesBefore, object responseData, string responseHeaders, string cookiesAfter)
78+
{
79+
if (TraceHelper.TraceFields > 0)
80+
{
81+
string traceRequestData = "", traceResponseData = "", traceRequestHeaders = "", traceResponseHeaders = "", traceCookiesBefore = "", traceCookiesAfter = "";
82+
83+
var traceSummary = string.Format("{0} ({1}):\r\n{2}", action, DateTime.Now.Subtract(startTime).ToString(), target.ToString());
84+
85+
// Include data
86+
if (TraceHelper.TraceFields.HasFlag(TraceFieldEnum.Data))
87+
{
88+
traceRequestData = requestData == null ? "" : string.Format("\r\nRequest Data:\r\n{0}\r\n", requestData);
89+
traceResponseData = string.Format("\r\nResponse Data\r\n{0}", responseData);
90+
}
91+
92+
// Include headers
93+
if (TraceHelper.TraceFields.HasFlag(TraceFieldEnum.Headers))
94+
{
95+
traceRequestHeaders = string.Format("\r\nRequest Headers:\r\n{0}", requestHeaders);
96+
traceResponseHeaders = string.Format("\r\nResponse Headers:\r\n{0}", responseHeaders);
97+
}
98+
99+
// Include cookies
100+
if (TraceHelper.TraceFields.HasFlag(TraceFieldEnum.Cookies))
101+
{
102+
traceCookiesBefore = string.Format("\r\nCookies Before:\r\n{0}", cookiesBefore);
103+
traceCookiesAfter = string.Format("\r\nCookies After:\r\n{0}", cookiesAfter);
104+
}
105+
106+
// Log the trace information
107+
Trace.TraceInformation(String.Concat(
108+
traceSummary,
109+
traceRequestHeaders,
110+
traceCookiesBefore,
111+
traceRequestData,
112+
traceResponseHeaders,
113+
traceCookiesAfter,
114+
traceResponseData,
115+
"\r\n\r\n"));
116+
}
117+
}
118+
}
119+
}

‎Rally.RestApi/Web/HttpService.cs

Lines changed: 6 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,7 @@ internal byte[] Download(Uri target, IDictionary<string, string> headers = null)
123123
}
124124
finally
125125
{
126-
Trace.TraceInformation("Get ({0}):\r\n{1}\r\nRequest Headers:\r\n{2}Cookies Before:\r\n{3}Response Headers:\r\n{4}Cookies After:\r\n{5}Response Data\r\n{6}",
127-
DateTime.Now.Subtract(startTime).ToString(),
128-
target.ToString(),
129-
requestHeaders,
130-
cookiesBefore,
131-
responseHeaders,
132-
cookiesAfter,
133-
response);
126+
TraceHelper.TraceHttpMessage("GET", startTime, target, requestHeaders, cookiesBefore, response, responseHeaders, cookiesAfter);
134127
}
135128
}
136129
#endregion
@@ -159,15 +152,7 @@ internal string Post(Uri target, string data, IDictionary<string, string> header
159152
}
160153
finally
161154
{
162-
Trace.TraceInformation("Post ({0}):\r\n{1}\r\nRequest Headers:\r\n{2}Cookies Before:\r\n{3}Request Data:\r\n{4}\r\nResponse Headers:\r\n{5}Cookies After:\r\n{6}Response Data\r\n{7}",
163-
DateTime.Now.Subtract(startTime).ToString(),
164-
target.ToString(),
165-
requestHeaders,
166-
cookiesBefore,
167-
data,
168-
responseHeaders,
169-
cookiesAfter,
170-
response);
155+
TraceHelper.TraceHttpMessage("POST", startTime, target, data, requestHeaders, cookiesBefore, response, responseHeaders, cookiesAfter);
171156
}
172157
}
173158
#endregion
@@ -211,15 +196,7 @@ internal string GetAsPost(Uri target, IDictionary<string, string> data, IDiction
211196
}
212197
finally
213198
{
214-
Trace.TraceInformation("Post ({0}):\r\n{1}\r\nRequest Headers:\r\n{2}Cookies Before:\r\n{3}Request Data:\r\n{4}\r\nResponse Headers:\r\n{5}Cookies After:\r\n{6}Response Data\r\n{7}",
215-
DateTime.Now.Subtract(startTime).ToString(),
216-
target.ToString(),
217-
requestHeaders,
218-
cookiesBefore,
219-
data,
220-
responseHeaders,
221-
cookiesAfter,
222-
response);
199+
TraceHelper.TraceHttpMessage("POST", startTime, target, data, requestHeaders, cookiesBefore, response, responseHeaders, cookiesAfter);
223200
}
224201
}
225202
#endregion
@@ -257,14 +234,7 @@ internal string Get(Uri target, IDictionary<string, string> headers = null)
257234
}
258235
finally
259236
{
260-
Trace.TraceInformation("Get ({0}):\r\n{1}\r\nRequest Headers:\r\n{2}Cookies Before:\r\n{3}Response Headers:\r\n{4}Cookies After:\r\n{5}Response Data\r\n{6}",
261-
DateTime.Now.Subtract(startTime).ToString(),
262-
target.ToString(),
263-
requestHeaders,
264-
cookiesBefore,
265-
responseHeaders,
266-
cookiesAfter,
267-
response);
237+
TraceHelper.TraceHttpMessage("GET", startTime, target, requestHeaders, cookiesBefore, response, responseHeaders, cookiesAfter);
268238
}
269239
}
270240
#endregion
@@ -300,12 +270,7 @@ internal DynamicJsonObject GetCacheable(Uri target, out bool isCachedResult, IDi
300270
}
301271
finally
302272
{
303-
Trace.TraceInformation("Get ({0}):\r\n{1}\r\nRequest Headers:\r\n{2}Response Headers:\r\n{3}Response Data\r\n{4}",
304-
DateTime.Now.Subtract(startTime).ToString(),
305-
target.ToString(),
306-
requestHeaders,
307-
responseHeaders,
308-
response);
273+
TraceHelper.TraceHttpMessage("GET", startTime, target, requestHeaders, response, responseHeaders);
309274
}
310275
}
311276
#endregion
@@ -353,14 +318,7 @@ internal string Delete(Uri target, IDictionary<string, string> headers = null)
353318
}
354319
finally
355320
{
356-
Trace.TraceInformation("Delete ({0}):\r\n{1}\r\nRequest Headers:\r\n{2}Cookies Before:\r\n{3}Response Headers:\r\n{4}Cookies After:\r\n{5}Response Data\r\n{6}",
357-
DateTime.Now.Subtract(startTime).ToString(),
358-
target.ToString(),
359-
requestHeaders,
360-
cookiesBefore,
361-
responseHeaders,
362-
cookiesAfter,
363-
response);
321+
TraceHelper.TraceHttpMessage("DELETE", startTime, target, requestHeaders, cookiesBefore, response, responseHeaders, cookiesAfter);
364322
}
365323
}
366324
#endregion

0 commit comments

Comments
 (0)