Compare commits

...

1 Commits

Author SHA1 Message Date
Jedd Morgan 0ca9162e7b pass etag to trigger processing (#447)
.NET Build and Publish / build (push) Has been cancelled
2026-02-26 16:09:19 +00:00
4 changed files with 45 additions and 31 deletions
+1 -24
View File
@@ -193,30 +193,7 @@ public sealed class BlobApi : IBlobApi
using var response = await _unauthedClient.SendAsync(requestMessage, cancellationToken).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
return ParseEtagHeader(response.Headers);
}
private static string ParseEtagHeader(HttpResponseHeaders headers)
{
if (!headers.TryGetValues("ETag", out var etagValues))
{
throw new ArgumentException(
"Response does not have an ETag attached to it, cannot use this as an upload",
nameof(headers)
);
}
var etagValuesArray = etagValues.ToArray();
if (etagValuesArray.Length != 1)
{
throw new ArgumentException(
$"Expected Etag header to have a single value but got {etagValuesArray.Length}",
nameof(headers)
);
}
return etagValuesArray[0];
return BlobApiHelpers.ParseEtagHeader(response.Headers);
}
/// <summary>
+29
View File
@@ -0,0 +1,29 @@
using System.Net.Http.Headers;
namespace Speckle.Sdk.Helpers;
public static class BlobApiHelpers
{
public static string ParseEtagHeader(HttpResponseHeaders headers)
{
if (!headers.TryGetValues("ETag", out var etagValues))
{
throw new ArgumentException(
"Response does not have an ETag attached to it, cannot use this as an upload",
nameof(headers)
);
}
var etagValuesArray = etagValues.ToArray();
if (etagValuesArray.Length != 1)
{
throw new ArgumentException(
$"Expected Etag header to have a single value but got {etagValuesArray.Length}",
nameof(headers)
);
}
return etagValuesArray[0];
}
}
+11 -5
View File
@@ -1,4 +1,5 @@
using System.Net.Http.Headers;
using System.Text;
using Microsoft.Extensions.Logging;
using Speckle.InterfaceGenerator;
using Speckle.Newtonsoft.Json;
@@ -54,9 +55,9 @@ public sealed class Uploader : IDisposable
public async Task Send(Stream fileStream)
{
PresignedUploadResponse presignedUploadResponse = await GetPresignedUrl().ConfigureAwait(false);
await UploadToS3(fileStream, presignedUploadResponse).ConfigureAwait(false);
var etag = await UploadToS3(fileStream, presignedUploadResponse).ConfigureAwait(false);
await TriggerProcessing().ConfigureAwait(false);
await TriggerProcessing(new() { Etag = etag }).ConfigureAwait(false);
}
private async Task<PresignedUploadResponse> GetPresignedUrl()
@@ -77,7 +78,7 @@ public sealed class Uploader : IDisposable
return presignedUpload;
}
private async Task UploadToS3(Stream fileStream, PresignedUploadResponse presignedUploadResponse)
private async Task<string> UploadToS3(Stream fileStream, PresignedUploadResponse presignedUploadResponse)
{
_logger.LogInformation("Uploading file to pre-signed url");
@@ -100,16 +101,21 @@ public sealed class Uploader : IDisposable
.ConfigureAwait(false);
uploadResponse.EnsureSuccessStatusCode();
return BlobApiHelpers.ParseEtagHeader(uploadResponse.Headers);
}
private async Task TriggerProcessing()
private async Task TriggerProcessing(TriggerUploadRequest request)
{
Uri processUri = new($"projects/{_projectId}/modelingestion/{_ingestionId}/uploads/process", UriKind.Relative);
string requestBody = JsonConvert.SerializeObject(request);
using var content = new StringContent(requestBody, Encoding.UTF8, "application/json");
using HttpResponseMessage processResponse = await _speckleClient
.PostAsync(processUri, null, _cancellationToken)
.PostAsync(processUri, content, _cancellationToken)
.ConfigureAwait(false);
string body = await processResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
processResponse.EnsureSuccessStatusCode();
}
@@ -1,3 +1,4 @@
using Speckle.Newtonsoft.Json;
using Speckle.Sdk.Models;
using Speckle.Sdk.Serialisation;
@@ -12,7 +13,8 @@ internal record PresignedUploadResponse
public Dictionary<string, string> AdditionalRequestHeaders { get; init; } = new();
}
internal record ProcessUploadResponse
internal readonly struct TriggerUploadRequest
{
public required string ingestionId { get; init; }
[JsonProperty("etag")]
public required string Etag { get; init; }
}