Skip to content

Commit a03ecc0

Browse files
author
Martin Kennish
authored
Merge pull request #32 from bdukes/async-client
Use async/await in Deploy Client
2 parents f931a76 + d0a13d1 commit a03ecc0

File tree

4 files changed

+65
-51
lines changed

4 files changed

+65
-51
lines changed

DeployClient/API.cs

+23-32
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,23 @@ class API
1616

1717
private static HttpClient BuildClient()
1818
{
19-
HttpClient client = new HttpClient();
19+
HttpClient client = new HttpClient()
20+
{
21+
BaseAddress = new Uri(new Uri(Program.Options.TargetUri), "DesktopModules/PolyDeploy/API/")
22+
};
2023

21-
client.BaseAddress = new Uri(new Uri(Program.Options.TargetUri), "DesktopModules/PolyDeploy/API/");
2224
client.DefaultRequestHeaders.Add("x-api-key", APIKey);
23-
client.Timeout = TimeSpan.FromSeconds(25);
2425

2526
return client;
2627
}
2728

28-
public static string CreateSession()
29+
public static async Task<string> CreateSessionAsync()
2930
{
3031
string endpoint = "Remote/CreateSession";
3132

3233
using (HttpClient client = BuildClient())
3334
{
34-
string json = client.GetStringAsync(endpoint).Result;
35+
string json = await client.GetStringAsync(endpoint);
3536

3637
JavaScriptSerializer jsonSer = new JavaScriptSerializer();
3738

@@ -48,36 +49,31 @@ public static string CreateSession()
4849
}
4950
}
5051

51-
public static bool GetSession(string sessionGuid, out Dictionary<string, dynamic> results)
52+
public static async Task<(bool success, Dictionary<string, dynamic> results)> GetSessionAsync(string sessionGuid)
5253
{
5354
string endpoint = string.Format("Remote/GetSession?sessionGuid={0}", sessionGuid);
5455

5556
JavaScriptSerializer jsonSer = new JavaScriptSerializer();
5657

5758
using (HttpClient client = BuildClient())
5859
{
59-
bool success;
60-
var httpResponse = client.GetAsync(endpoint).Result;
60+
var httpResponse = await client.GetAsync(endpoint);
6161
if (httpResponse.StatusCode == HttpStatusCode.OK)
6262
{
6363
string json = httpResponse.Content.ReadAsStringAsync().Result;
64-
results = jsonSer.Deserialize<Dictionary<string, dynamic>>(json);
65-
success = true;
66-
}
67-
else if (httpResponse.StatusCode == HttpStatusCode.NotFound)
68-
{
69-
results = new Dictionary<string, dynamic>();
70-
success = false;
64+
return (true, jsonSer.Deserialize<Dictionary<string, dynamic>>(json));
7165
}
72-
else
66+
67+
if (httpResponse.StatusCode == HttpStatusCode.NotFound)
7368
{
74-
throw new HttpException($"Invalid status code returned from remote api: {httpResponse.StatusCode}");
69+
return (false, new Dictionary<string, dynamic>(0));
7570
}
76-
return success;
71+
72+
throw new HttpException($"Invalid status code returned from remote api: {httpResponse.StatusCode}");
7773
}
7874
}
7975

80-
public static void AddPackages(string sessionGuid, List<KeyValuePair<string, Stream>> streams)
76+
public static async Task AddPackagesAsync(string sessionGuid, List<KeyValuePair<string, Stream>> streams)
8177
{
8278
string endpoint = string.Format("Remote/AddPackages?sessionGuid={0}", sessionGuid);
8379

@@ -90,11 +86,11 @@ public static void AddPackages(string sessionGuid, List<KeyValuePair<string, Str
9086
form.Add(new StreamContent(keyValuePair.Value), "none", keyValuePair.Key);
9187
}
9288

93-
HttpResponseMessage response = client.PostAsync(endpoint, form).Result;
89+
await client.PostAsync(endpoint, form);
9490
}
9591
}
9692

97-
public static void AddPackageAsync(string sessionGuid, Stream stream, string filename)
93+
public static async Task AddPackageAsync(string sessionGuid, Stream stream, string filename)
9894
{
9995
string endpoint = string.Format("Remote/AddPackages?sessionGuid={0}", sessionGuid);
10096

@@ -104,31 +100,26 @@ public static void AddPackageAsync(string sessionGuid, Stream stream, string fil
104100

105101
form.Add(new StreamContent(stream), "none", filename);
106102

107-
HttpResponseMessage response = client.PostAsync(endpoint, form).Result;
103+
await client.PostAsync(endpoint, form);
108104
}
109105
}
110106

111-
public static bool Install(string sessionGuid, out SortedList<string, dynamic> response)
107+
public static async Task<(bool success, SortedList<string, dynamic> response)> InstallAsync(string sessionGuid)
112108
{
113109
string endpoint = string.Format("Remote/Install?sessionGuid={0}", sessionGuid);
114110

115-
bool success = false;
116-
117111
JavaScriptSerializer jsonSer = new JavaScriptSerializer();
118112

119-
response = null;
120-
121113
using (HttpClient client = BuildClient())
122114
{
123115
try
124116
{
125-
HttpResponseMessage httpResponse = client.GetAsync(endpoint).Result;
117+
HttpResponseMessage httpResponse = await client.GetAsync(endpoint);
126118

127119
if (httpResponse.StatusCode.Equals(HttpStatusCode.OK))
128120
{
129-
success = true;
130-
string json = httpResponse.Content.ReadAsStringAsync().Result;
131-
response = jsonSer.Deserialize<SortedList<string, dynamic>>(json);
121+
string json = await httpResponse.Content.ReadAsStringAsync();
122+
return (true, jsonSer.Deserialize<SortedList<string, dynamic>>(json));
132123
}
133124
}
134125
catch (Exception ex)
@@ -137,7 +128,7 @@ public static bool Install(string sessionGuid, out SortedList<string, dynamic> r
137128
}
138129

139130
// Always fail.
140-
return false;
131+
return (false, null);
141132
}
142133
}
143134
}

DeployClient/DeployClient.csproj

+5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<DefineConstants>DEBUG;TRACE</DefineConstants>
2323
<ErrorReport>prompt</ErrorReport>
2424
<WarningLevel>4</WarningLevel>
25+
<LangVersion>latest</LangVersion>
2526
</PropertyGroup>
2627
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
2728
<PlatformTarget>AnyCPU</PlatformTarget>
@@ -31,6 +32,7 @@
3132
<DefineConstants>TRACE</DefineConstants>
3233
<ErrorReport>prompt</ErrorReport>
3334
<WarningLevel>4</WarningLevel>
35+
<LangVersion>latest</LangVersion>
3436
</PropertyGroup>
3537
<ItemGroup>
3638
<Reference Include="CommandLine, Version=1.9.71.2, Culture=neutral, PublicKeyToken=de6f01bd326f8c32, processorArchitecture=MSIL">
@@ -39,6 +41,9 @@
3941
<Reference Include="System" />
4042
<Reference Include="System.Configuration" />
4143
<Reference Include="System.Core" />
44+
<Reference Include="System.ValueTuple, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
45+
<HintPath>..\packages\System.ValueTuple.4.3.0\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
46+
</Reference>
4247
<Reference Include="System.Web" />
4348
<Reference Include="System.Web.Extensions" />
4449
<Reference Include="System.Xml.Linq" />

DeployClient/Program.cs

+36-19
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
using Cantarus.Libraries.Encryption;
1+
using Cantarus.Libraries.Encryption;
22
using System;
33
using System.Collections;
44
using System.Collections.Generic;
55
using System.Configuration;
66
using System.IO;
7+
using System.Linq;
8+
using System.Threading.Tasks;
79
using System.Web;
810
using System.Web.Script.Serialization;
911

@@ -22,7 +24,7 @@ enum ExitCode : int
2224
InstallFailure = 4
2325
}
2426

25-
static void Main(string[] args)
27+
static async Task Main(string[] args)
2628
{
2729
try
2830
{
@@ -31,7 +33,7 @@ static void Main(string[] args)
3133
// Output start.
3234
WriteLine("*** PolyDeploy Client ***");
3335
WriteLine();
34-
36+
3537
// Do we have a target uri.
3638
if (Options.TargetUri.Equals(string.Empty))
3739
{
@@ -91,16 +93,16 @@ static void Main(string[] args)
9193
WriteLine();
9294
}
9395

94-
// Inform user of encryption.
95-
WriteLine("Starting encryption and upload...");
96-
9796
// Get a session.
98-
string sessionGuid = API.CreateSession();
97+
string sessionGuid = await API.CreateSessionAsync();
9998

10099
WriteLine(string.Format("Got session: {0}", sessionGuid));
101100

102101
DateTime startTime = DateTime.Now;
103102

103+
// Inform user of encryption.
104+
WriteLine("Starting encryption and upload...");
105+
104106
foreach (string zipFile in zipFiles)
105107
{
106108

@@ -113,7 +115,7 @@ static void Main(string[] args)
113115
{
114116
Write("uploading...");
115117

116-
API.AddPackageAsync(sessionGuid, es, Path.GetFileName(zipFile));
118+
await API.AddPackageAsync(sessionGuid, es, Path.GetFileName(zipFile));
117119
}
118120

119121
WriteLine("done.");
@@ -129,22 +131,23 @@ static void Main(string[] args)
129131
JavaScriptSerializer jsonSer = new JavaScriptSerializer();
130132

131133
// Start.
132-
SortedList<string, dynamic> results = null;
133-
134-
if (!API.Install(sessionGuid, out results))
134+
(bool installSuccess, SortedList<string, dynamic> results) = await API.InstallAsync(sessionGuid);
135+
if (!installSuccess)
135136
{
136-
TimeSpan interval = new TimeSpan(0, 0, 0, 2);
137+
TimeSpan interval = TimeSpan.FromSeconds(2);
137138
Dictionary<string, dynamic> response;
138139
var successfullyReachedApi = false;
139140
DateTime apiNotFoundAbortTime = DateTime.Now.AddSeconds(Options.InstallationStatusTimeout);
140141

141-
// Attempt to get the status of the session from the remote api.
142+
// Attempt to get the status of the session from the remote api.
142143
// This can fail shortly after an installation as the api has not yet been initialised,
143144
// so attempt to get it for the given timespan.
144145
do
145146
{
146147
// Get whether we can reach the api
147-
successfullyReachedApi = API.GetSession(sessionGuid, out response);
148+
(bool getSessionSuccess, Dictionary<string, dynamic> getSessionResponse) = await API.GetSessionAsync(sessionGuid);
149+
successfullyReachedApi = getSessionSuccess;
150+
response = getSessionResponse;
148151

149152
if (!successfullyReachedApi)
150153
{
@@ -161,7 +164,7 @@ static void Main(string[] args)
161164

162165
int status = -1;
163166
string previousPrint = null;
164-
167+
165168
DateTime abortTime = DateTime.Now.AddMinutes(10);
166169

167170
// Get the installation status from the API until it is complete or until the abort time is reached
@@ -202,15 +205,16 @@ static void Main(string[] args)
202205

203206
System.Threading.Thread.Sleep(interval);
204207

205-
var success = API.GetSession(sessionGuid, out response);
208+
(bool success, Dictionary<string, dynamic> getSessionResponse) = await API.GetSessionAsync(sessionGuid);
209+
response = getSessionResponse;
206210

207211
// The api should not be returning a 404 status at this point
208212
if (!success)
209213
{
210214
throw new HttpException("Remote API returned status 404");
211215
}
212216
} while (status < 2 && DateTime.Now < abortTime);
213-
217+
214218
}
215219
else
216220
{
@@ -294,10 +298,23 @@ private static string BuildUpdateString(SortedList<string, dynamic> results)
294298

295299
private static void WriteException(Exception ex, int maxDepth = 10, int depth = 0)
296300
{
297-
WriteLine(ex.Message);
301+
WriteLine($"{ex.GetType()} | {ex.Message}");
298302
WriteLine(ex.StackTrace);
299303

300-
if (depth < maxDepth && ex.InnerException != null)
304+
if (depth >= maxDepth)
305+
{
306+
return;
307+
}
308+
309+
if (ex is AggregateException aggregate && aggregate.InnerExceptions.Any())
310+
{
311+
depth++;
312+
foreach (Exception inner in aggregate.InnerExceptions)
313+
{
314+
WriteException(inner, maxDepth, depth);
315+
}
316+
}
317+
else if (ex.InnerException != null)
301318
{
302319
depth++;
303320
WriteException(ex.InnerException, maxDepth, depth);

DeployClient/packages.config

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<packages>
33
<package id="CommandLineParser" version="1.9.71" targetFramework="net45" />
4+
<package id="System.ValueTuple" version="4.3.0" targetFramework="net45" />
45
</packages>

0 commit comments

Comments
 (0)