-
Notifications
You must be signed in to change notification settings - Fork 83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PART 3: Add UploadArchiveToGithubStorageWithMultiPart method #1271
Changes from all commits
aab0557
1fca83d
f81e02a
2c8de4a
619e6da
bf5eef2
60e9ed1
cd88309
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,5 +1,6 @@ | ||||||||||||||
using System; | ||||||||||||||
using System.Collections.Generic; | ||||||||||||||
using System.IO; | ||||||||||||||
using System.Linq; | ||||||||||||||
using System.Net; | ||||||||||||||
using System.Net.Http; | ||||||||||||||
|
@@ -1071,6 +1072,33 @@ mutation abortRepositoryMigration( | |||||||||||||
} | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
public virtual async Task<string> UploadArchiveToGithubStorage(string orgDatabaseId, bool isMultipart, string archiveName, Stream archiveContent) | ||||||||||||||
{ | ||||||||||||||
using var httpContent = new StreamContent(archiveContent); | ||||||||||||||
string response; | ||||||||||||||
|
||||||||||||||
if (isMultipart) | ||||||||||||||
{ | ||||||||||||||
var url = $"https://uploads.github.com/organizations/{orgDatabaseId.EscapeDataString()}/gei/archive/blobs/uploads"; | ||||||||||||||
|
||||||||||||||
using var content = new MultipartFormDataContent | ||||||||||||||
{ | ||||||||||||||
{ httpContent, "archive", archiveName } | ||||||||||||||
}; | ||||||||||||||
Comment on lines
+1084
to
+1087
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Initializing a using variable with an object initializer might lead to problems if an exception is thrown during the initialization and the using variable may never get disposed so here it's better to add the content with the
Suggested change
|
||||||||||||||
|
||||||||||||||
response = await _client.PostAsync(url, content); | ||||||||||||||
begonaguereca marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||
} | ||||||||||||||
else | ||||||||||||||
{ | ||||||||||||||
var url = $"https://uploads.github.com/organizations/{orgDatabaseId.EscapeDataString()}/gei/archive?name={archiveName.EscapeDataString()}"; | ||||||||||||||
|
||||||||||||||
response = await _client.PostAsync(url, httpContent); | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. renaming
Suggested change
|
||||||||||||||
} | ||||||||||||||
|
||||||||||||||
var data = JObject.Parse(response); | ||||||||||||||
return "gei://archive/" + (string)data["archiveId"]; | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
private static object GetMannequinsPayload(string orgId) | ||||||||||||||
{ | ||||||||||||||
var query = "query($id: ID!, $first: Int, $after: String)"; | ||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -162,9 +162,14 @@ public virtual async Task<string> PatchAsync(string url, object body, Dictionary | |
|
||
if (body != null) | ||
{ | ||
_log.LogVerbose($"HTTP BODY: {body.ToJson()}"); | ||
_log.LogVerbose(body is MultipartFormDataContent or StreamContent ? "HTTP BODY: BLOB" : $"HTTP BODY: {body.ToJson()}"); | ||
|
||
request.Content = body.ToJson().ToStringContent(); | ||
request.Content = body switch | ||
{ | ||
MultipartFormDataContent multipartFormDataContent => multipartFormDataContent, | ||
StreamContent streamContent => streamContent, | ||
_ => body.ToJson().ToStringContent() | ||
}; | ||
Comment on lines
+165
to
+172
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was thinking this can be simplified as we now either support a if (body is HttpContent httpContent)
{
_log.LogVerbose("HTTP BODY: BLOB");
request.Content = httpContent;
}
else
{
var jsonBody = body.ToJson();
_log.LogVerbose($"HTTP BODY: {jsonBody}");
request.Content = jsonBody.ToStringContent();
} |
||
} | ||
|
||
using var response = await _httpClient.SendAsync(request); | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,6 +1,7 @@ | ||||||
using System; | ||||||
using System.Collections.Generic; | ||||||
using System.Collections.ObjectModel; | ||||||
using System.IO; | ||||||
using System.Linq; | ||||||
using System.Net; | ||||||
using System.Net.Http; | ||||||
|
@@ -3462,6 +3463,62 @@ await _githubApi.Invoking(api => api.AbortMigration(migrationId)) | |||||
.WithMessage(expectedErrorMessage); | ||||||
} | ||||||
|
||||||
[Fact] | ||||||
public async Task UploadArchiveToGithubStorage() | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
{ | ||||||
//Arange | ||||||
const string org = "1234"; | ||||||
const bool isMultipart = false; | ||||||
const string archiveName = "archiveName"; | ||||||
|
||||||
// Using a MemoryStream as a valid stream implementation | ||||||
using var archiveContent = new MemoryStream(new byte[] { 1, 2, 3 }); | ||||||
var expectedArchiveId = "123456"; | ||||||
var jsonResponse = $"{{ \"archiveId\": \"{expectedArchiveId}\" }}"; | ||||||
|
||||||
_githubClientMock | ||||||
.Setup(m => m.PostAsync(It.IsAny<string>(), It.IsAny<HttpContent>(), null)) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's make sure that
Suggested change
|
||||||
.ReturnsAsync(jsonResponse); | ||||||
|
||||||
var expectedStringResponse = "gei://archive/" + expectedArchiveId; | ||||||
|
||||||
// Act | ||||||
var actualStringResponse = await _githubApi.UploadArchiveToGithubStorage(org, isMultipart, archiveName, archiveContent); | ||||||
|
||||||
// Assert | ||||||
expectedStringResponse.Should().Be(actualStringResponse); | ||||||
|
||||||
} | ||||||
|
||||||
|
||||||
[Fact] | ||||||
public async Task UploadArchiveToGithubStorageWithMultiPart() | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We use snaked cased test names throughout the project:
Suggested change
|
||||||
{ | ||||||
//Arange | ||||||
const string org = "123455"; | ||||||
const bool isMultipart = true; | ||||||
const string archiveName = "archiveName"; | ||||||
|
||||||
// Using a MemoryStream as a valid stream implementation | ||||||
using var archiveContent = new MemoryStream(new byte[] { 1, 2, 3 }); | ||||||
|
||||||
var expectedArchiveId = "123456"; | ||||||
var jsonResponse = $"{{ \"archiveId\": \"{expectedArchiveId}\" }}"; | ||||||
|
||||||
_githubClientMock | ||||||
.Setup(m => m.PostAsync(It.IsAny<string>(), It.IsAny<HttpContent>(), null)) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
.ReturnsAsync(jsonResponse); | ||||||
|
||||||
var expectedStringResponse = "gei://archive/" + expectedArchiveId; | ||||||
|
||||||
// Act | ||||||
var actualStringResponse = await _githubApi.UploadArchiveToGithubStorage(org, isMultipart, archiveName, archiveContent); | ||||||
|
||||||
// Assert | ||||||
expectedStringResponse.Should().Be(actualStringResponse); | ||||||
|
||||||
} | ||||||
|
||||||
private string Compact(string source) => | ||||||
source | ||||||
.Replace("\r", "") | ||||||
|
@@ -3471,5 +3528,4 @@ private string Compact(string source) => | |||||
.Replace("\\n", "") | ||||||
.Replace("\\t", "") | ||||||
.Replace(" ", ""); | ||||||
|
||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I would call this variable
streamContent
for clarity as both stream and multipart from data are technicallyHttpContent
"