Seperated eventhub service from api service.

wip nbs flow.
Changed uploading a bit.
This commit is contained in:
2020-03-25 21:32:28 +01:00
parent e638370ad4
commit 691be2185e
11 changed files with 151 additions and 81 deletions

View File

@@ -13,9 +13,6 @@ using FarmmapsApi.Models;
using Google.Apis.Http;
using Google.Apis.Upload;
using IdentityModel;
using Microsoft.AspNetCore.Http.Connections;
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Winista.Mime;
@@ -24,23 +21,28 @@ namespace FarmmapsApi.Services
{
public class FarmmapsApiService
{
private readonly Configuration _configuration;
private readonly HttpClientSettings _httpClientSettings;
private readonly HttpClient _httpClient;
private readonly OpenIdConnectService _openIdConnectService;
private readonly Configuration _configuration;
private HubConnection _hubConnection;
public event Action<EventMessage> EventCallback;
public FarmmapsApiService(HttpClient httpClient,
public FarmmapsApiService(HttpClientSettings httpClientSettings, HttpClient httpClient,
OpenIdConnectService openIdConnectService, Configuration configuration)
{
_configuration = configuration;
_httpClientSettings = httpClientSettings;
_httpClient = httpClient;
_openIdConnectService = openIdConnectService;
_configuration = configuration;
_httpClient.BaseAddress = new Uri(configuration.Endpoint);
_httpClient.DefaultRequestHeaders.Add("Accept", MediaTypeNames.Application.Json);
if (!string.IsNullOrEmpty(_httpClientSettings.BearerToken))
{
_httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue(OidcConstants.AuthenticationSchemes.AuthorizationHeaderBearer,
_httpClientSettings.BearerToken);
}
}
public async Task AuthenticateAsync()
@@ -57,33 +59,10 @@ namespace FarmmapsApi.Services
if (token.IsError)
throw new AuthenticationException(token.Error);
_httpClientSettings.BearerToken = token.AccessToken;
_httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue(OidcConstants.AuthenticationSchemes.AuthorizationHeaderBearer,
token.AccessToken);
await StartEventHub(token.AccessToken);
}
private async Task StartEventHub(string accessToken)
{
var eventEndpoint = $"{_configuration.Endpoint}/EventHub";
_hubConnection = new HubConnectionBuilder()
.WithUrl(eventEndpoint, HttpTransportType.WebSockets,
options => options.SkipNegotiation = true)
.ConfigureLogging(log => log.AddConsole())
.WithAutomaticReconnect()
.Build();
await _hubConnection.StartAsync();
await AuthenticateEventHub(accessToken);
_hubConnection.Reconnected += async s => await AuthenticateEventHub(accessToken);
_hubConnection.On("event", (EventMessage eventMessage) => EventCallback?.Invoke(eventMessage));
}
private async Task AuthenticateEventHub(string accessToken)
{
await _hubConnection.SendAsync("authenticate", accessToken);
}
public async Task<string> GetCurrentUserCodeAsync()
@@ -301,19 +280,20 @@ namespace FarmmapsApi.Services
/// </summary>
/// <param name="filePath"></param>
/// <param name="parentItemCode"></param>
/// <param name="uploadCallback"></param>
/// <param name="progressCallback"></param>
/// <returns></returns>
/// <exception cref="FileNotFoundException"></exception>
public async Task<Uri> UploadFile(string filePath, string parentItemCode, Action<IUploadProgress> uploadCallback)
public async Task<UploadResults> UploadFile(string filePath, string parentItemCode,
Action<IUploadProgress> progressCallback = null)
{
if (!File.Exists(filePath))
throw new FileNotFoundException($"File not found {filePath}");
var mimeTypes = new MimeTypes();
var mimeType = mimeTypes.GetMimeTypeFromFile(filePath);
await using var uploadStream = new FileStream(filePath, FileMode.OpenOrCreate);
var request = new FileRequest()
{
Name = Path.GetFileName(filePath),
@@ -321,16 +301,17 @@ namespace FarmmapsApi.Services
Size = uploadStream.Length
};
Uri uploadIdentifierUri = null;
using var httpClient = CreateConfigurableHttpClient(_httpClient);
var farmmapsUploader = new FarmmapsUploader(httpClient, uploadStream, request, mimeType.ToString());
farmmapsUploader.ProgressChanged += uploadCallback;
farmmapsUploader.UploadSessionData += data => uploadIdentifierUri = data.UploadUri;
await farmmapsUploader.UploadAsync();
var farmmapsUploader = new FarmmapsUploader(httpClient, uploadStream, request,
mimeType.ToString(), ResourceEndpoints.ITEMS_UPLOAD_RESOURCE);
return uploadIdentifierUri;
Uri location = null;
farmmapsUploader.ProgressChanged += progressCallback;
farmmapsUploader.UploadSessionData += data => location = data.UploadUri;
var progress = await farmmapsUploader.UploadAsync();
return new UploadResults(progress, location);
}
/// <summary>
@@ -347,7 +328,7 @@ namespace FarmmapsApi.Services
throw new FileNotFoundException($"File not found {filePath}");
await using var uploadStream = new FileStream(filePath, FileMode.OpenOrCreate);
var request = new FileRequest()
{
Name = Path.GetFileName(filePath),
@@ -356,7 +337,8 @@ namespace FarmmapsApi.Services
};
using var httpClient = CreateConfigurableHttpClient(_httpClient);
var farmmapsUploader = new FarmmapsUploader(httpClient, uploadStream, request, string.Empty);
var farmmapsUploader = new FarmmapsUploader(httpClient, uploadStream,
request, string.Empty, ResourceEndpoints.ITEMS_UPLOAD_RESOURCE);
farmmapsUploader.ProgressChanged += uploadCallback;
await farmmapsUploader.ResumeAsync(location);
@@ -366,12 +348,14 @@ namespace FarmmapsApi.Services
private ConfigurableHttpClient CreateConfigurableHttpClient(HttpClient parent)
{
var googleHttpClient = new HttpClientFactory().CreateHttpClient(new CreateHttpClientArgs {GZipEnabled = true, ApplicationName = "FarmMaps"});
var googleHttpClient = new HttpClientFactory().CreateHttpClient(new CreateHttpClientArgs
{GZipEnabled = true, ApplicationName = "FarmMaps"});
googleHttpClient.BaseAddress = parent.BaseAddress;
googleHttpClient.DefaultRequestHeaders.Add("Accept", MediaTypeNames.Application.Json);
var authHeader = parent.DefaultRequestHeaders.Authorization;
googleHttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(authHeader.Scheme, authHeader.Parameter);
googleHttpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue(authHeader.Scheme, authHeader.Parameter);
return googleHttpClient;
}

View File

@@ -0,0 +1,45 @@
using System;
using System.Threading.Tasks;
using FarmmapsApi.Models;
using Microsoft.AspNetCore.Http.Connections;
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.Logging;
namespace FarmmapsApi.Services
{
public class FarmmapsEventHub
{
private readonly Configuration _configuration;
private readonly HttpClientSettings _httpClientSettings;
private HubConnection _hubConnection;
public event Action<EventMessage> EventCallback;
public FarmmapsEventHub(HttpClientSettings httpClientSettings, Configuration configuration)
{
_httpClientSettings = httpClientSettings;
_configuration = configuration;
}
public async Task StartEventHub()
{
if(_hubConnection != null)
throw new Exception("EventHub already started");
var eventEndpoint = $"{_configuration.Endpoint}/EventHub";
_hubConnection = new HubConnectionBuilder()
.WithUrl(eventEndpoint, HttpTransportType.WebSockets,
options => options.SkipNegotiation = true)
.ConfigureLogging(log => log.AddConsole())
.WithAutomaticReconnect()
.Build();
await _hubConnection.StartAsync();
await _hubConnection.SendAsync("authenticate", _httpClientSettings.BearerToken);
_hubConnection.Reconnected += async s => await _hubConnection.SendAsync("authenticate", _httpClientSettings.BearerToken);
_hubConnection.On("Event", (EventMessage eventMessage) => EventCallback?.Invoke(eventMessage));
}
}
}

View File

@@ -55,7 +55,7 @@ namespace FarmmapsApi.Services
/// completed.
/// Caller is responsible for closing the <paramref name="contentStream"/>.
/// </remarks>
public FarmmapsUploader(ConfigurableHttpClient httpClient, Stream contentStream, FileRequest body, string contentType)
public FarmmapsUploader(ConfigurableHttpClient httpClient, Stream contentStream, FileRequest body, string contentType, string path)
: base(contentStream,
new ResumableUploadOptions
{
@@ -69,9 +69,12 @@ namespace FarmmapsApi.Services
_streamLength = ContentStream.CanSeek ? ContentStream.Length : UnknownSize;
var twoMB = 2 * 0x100000;
ChunkSize = twoMB;
body.ChunkSize = ChunkSize;
Body = body;
Path = "api/v1/file";
Path = path;
HttpClient = httpClient;
HttpMethod = HttpConsts.Post;
ContentType = contentType;