-
Notifications
You must be signed in to change notification settings - Fork 20
Expand file tree
/
Copy pathInstaller.cs
More file actions
159 lines (138 loc) · 5.81 KB
/
Installer.cs
File metadata and controls
159 lines (138 loc) · 5.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
namespace PolyDeploy.DeployClient
{
using System.Net.Http.Headers;
using System.Reflection;
using System;
using System.Collections.Generic;
using System.Text.Json;
public class Installer : IInstaller
{
private readonly HttpClient httpClient;
private readonly IStopwatch stopwatch;
private static readonly string DeployClientVersion = Assembly.GetEntryAssembly()?.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion ?? string.Empty;
public Installer(HttpClient httpClient, IStopwatch stopwatch)
{
this.httpClient = httpClient;
this.stopwatch = stopwatch;
}
public async Task<Session> GetSessionAsync(DeployInput options, string sessionId)
{
try
{
using var response =
await this.SendRequestAsync(options, HttpMethod.Get, $"GetSession?sessionGuid={sessionId}");
var responseString = await response.Content.ReadAsStringAsync();
var responseBody = JsonSerializer.Deserialize<Session>(responseString);
if (responseBody == null)
{
throw new InvalidOperationException(
"Received an empty response trying to get a PolyDeploy session");
}
var responseJson = JsonSerializer.Deserialize<ResponseJson>(responseString);
if (!string.IsNullOrWhiteSpace(responseJson?.Response))
{
responseBody.Responses =
JsonSerializer.Deserialize<SortedList<int, SessionResponse?>>(responseJson.Response);
}
return responseBody;
}
catch (Exception ex)
{
throw new InstallerException("An Error Occurred Getting the Status of the Deployment Session", ex);
}
}
private class ResponseJson
{
public string? Response { get; set; }
}
public async Task InstallPackagesAsync(DeployInput options, string sessionId)
{
try
{
using var response = await this.SendRequestAsync(options, HttpMethod.Get, $"Install?sessionGuid={sessionId}");
}
catch (Exception e)
{
throw new InstallerException("An Error Occurred While Installing the Packages", e);
}
}
public async Task<string> StartSessionAsync(DeployInput options)
{
try
{
using var response = await this.SendRequestAsync(options, HttpMethod.Get, "CreateSession");
var responseStream = await response.Content.ReadAsStreamAsync();
var responseBody = await JsonSerializer.DeserializeAsync<CreateSessionResponse>(responseStream);
if (string.IsNullOrWhiteSpace(responseBody?.Guid))
{
throw new InvalidOperationException("Received an empty response trying to create PolyDeploy session");
}
return responseBody.Guid;
}
catch (Exception e)
{
throw new InstallerException("An Error Occurred While Starting the Deployment Session", e);
}
}
public async Task UploadPackageAsync(DeployInput options, string sessionId, Stream encryptedPackage, string packageName)
{
try
{
var fileName = Path.GetRelativePath(options.PackagesDirectoryPath, packageName);
var form = new MultipartFormDataContent
{
{ new StreamContent(encryptedPackage), "none", fileName },
};
using var response = await this.SendRequestAsync(options, HttpMethod.Post, $"AddPackages?sessionGuid={sessionId}", form);
}
catch (Exception e)
{
throw new InstallerException("An Error Occurred While Uploading the Packages", e);
}
}
private async Task<HttpResponseMessage> SendRequestAsync(DeployInput options, HttpMethod method, string path, HttpContent? content = null)
{
this.stopwatch.StartNew();
async Task<(HttpResponseMessage?, Exception?)> SendRequest()
{
using var request = new HttpRequestMessage
{
RequestUri = new Uri(options.GetTargetUri(), "DesktopModules/PolyDeploy/API/Remote/" + path),
Method = method,
Content = content,
};
request.Headers.Add("x-api-key", options.ApiKey);
request.Headers.UserAgent.Add(new ProductInfoHeaderValue("PolyDeploy", DeployClientVersion));
try
{
return (await this.httpClient.SendAsync(request), null);
}
catch (HttpRequestException exception)
{
return (null, exception);
}
}
var (response, exception) = await SendRequest();
while (exception != null || !response.IsSuccessStatusCode)
{
if (options.InstallationStatusTimeout <= stopwatch.Elapsed.TotalSeconds || content != null)
{
if (exception != null)
{
throw exception;
}
response.EnsureSuccessStatusCode();
}
else
{
(response, exception) = await SendRequest();
}
}
return response;
}
private class CreateSessionResponse
{
public string? Guid { get; set; }
}
}
}