async Task IUnitsAccess.SendCurrentAttendeesAsync(UnitsEndpoint unitsEndpoint, SyncCurrentAttendeesRequest currentAttendeesRequest) { const string requestPath = "/bot-api/discordsync/current-attendees"; var serialized = JsonConvert.SerializeObject(currentAttendeesRequest); var requestContent = new StringContent(serialized, Encoding.UTF8, "application/json"); await UseHttpClient(ExecuteHttpCall, HandleResponseMessage, unitsEndpoint.BaseAddress, unitsEndpoint.Secret); async Task <HttpResponseMessage?> ExecuteHttpCall(HttpClient httpClient) { try { return(await httpClient.PostAsync(requestPath, requestContent)); } catch (HttpRequestException e) { var baseExceptionMessage = e.GetBaseException().Message; _logger.LogRequestError(unitsEndpoint.BaseAddress, requestPath, baseExceptionMessage); return(null); } } async Task HandleResponseMessage(HttpResponseMessage?responseMessage) { if (responseMessage == null) { return; } if (!responseMessage.IsSuccessStatusCode) { await _logger.LogRequestErrorAsync(unitsEndpoint.BaseAddress, requestPath, responseMessage); } } }
async Task <SyncAllUsersResponse?> IUnitsAccess.SendAllUsersAsync(UnitsEndpoint unitsEndpoint, UserModel[] users) { const string requestPath = "/bot-api/discordsync/all-users"; SyncAllUsersResponse?methodResult = null; var request = new SyncAllUsersRequest(users); var serialized = JsonConvert.SerializeObject(request); var requestContent = new StringContent(serialized, Encoding.UTF8, "application/json"); await UseHttpClient(ExecuteHttpCall, HandleResponseMessage, unitsEndpoint.BaseAddress, unitsEndpoint.Secret); return(methodResult); async Task <HttpResponseMessage?> ExecuteHttpCall(HttpClient httpClient) { try { return(await httpClient.PostAsync(requestPath, requestContent)); } catch (HttpRequestException e) { var baseExceptionMessage = e.GetBaseException().Message; _logger.LogRequestError(unitsEndpoint.BaseAddress, requestPath, baseExceptionMessage); return(null); } } async Task HandleResponseMessage(HttpResponseMessage?responseMessage) { if (responseMessage == null) { return; } if (responseMessage.IsSuccessStatusCode) { var responseContent = await responseMessage.Content.ReadAsStringAsync(); methodResult = JsonConvert.DeserializeObject <SyncAllUsersResponse>(responseContent); } else { await _logger.LogRequestErrorAsync(unitsEndpoint.BaseAddress, requestPath, responseMessage); } } }
async Task <string[]?> IUnitsAccess.GetValidRoleNamesAsync(UnitsEndpoint unitsEndpoint) { const string requestPath = "/bot-api/discordsync/valid-role-names"; string[]? methodResult = null; async Task <HttpResponseMessage?> ExecuteHttpCall(HttpClient httpClient) { try { return(await httpClient.GetAsync(requestPath)); } catch (HttpRequestException e) { var baseExceptionMessage = e.GetBaseException().Message; _logger.LogRequestError(unitsEndpoint.BaseAddress, requestPath, baseExceptionMessage); return(null); } } async Task HandleResponseMessage(HttpResponseMessage?responseMessage) { if (responseMessage == null) { return; } if (!responseMessage.IsSuccessStatusCode) { await _logger.LogRequestErrorAsync(unitsEndpoint.BaseAddress, requestPath, responseMessage); return; } var stringContent = await responseMessage.Content.ReadAsStringAsync(); var result = JsonConvert.DeserializeObject <string[]>(stringContent); methodResult = result; } await UseHttpClient(ExecuteHttpCall, HandleResponseMessage, unitsEndpoint.BaseAddress, unitsEndpoint.Secret); return(methodResult); }
async Task IUnitsSignalRClient.ConnectAsync(UnitsEndpoint unitsEndpoint) { if (_hubConnections.ContainsKey(unitsEndpoint.BaseAddress)) { return; } var hubRoute = unitsEndpoint.BaseAddress + BotHubRoute; var connection = new HubConnectionBuilder() .WithUrl(hubRoute, options => { #if DEBUG options.WebSocketConfiguration = conf => { conf.RemoteCertificateValidationCallback = (sender, certificate, chain, errors) => true; }; options.HttpMessageHandlerFactory = handler => { if (handler is HttpClientHandler clientHandler) { clientHandler.ServerCertificateCustomValidationCallback = (message, certificate2, arg3, arg4) => true; } return(handler); }; #endif options.AccessTokenProvider = async() => { var token = await _bearerTokenManager.GetBearerTokenAsync(GetHttpClient(unitsEndpoint.BaseAddress), unitsEndpoint.BaseAddress, unitsEndpoint.Secret, _requiresTokenRefresh [unitsEndpoint.BaseAddress]); _requiresTokenRefresh[unitsEndpoint.BaseAddress] = false; return(token); }; }) .ConfigureLogging(logging => { logging.SetMinimumLevel(LogLevel.Trace); logging.AddSerilog(); }) .Build(); connection.Closed += async(error) => { _logger.LogWarning("Connection to UNITS at {BaseUrl} closed. Trying to reconnect ...", unitsEndpoint.BaseAddress); do { try { await Task.Delay(new Random().Next(0, 5) * 10_000); if (connection.State != HubConnectionState.Connecting) { await connection.StartAsync(); } } catch (Exception e) { _logger.LogError(e, "Failed to re-connect to UNITS at {BaseUrl}.", unitsEndpoint.BaseAddress); if (e is HttpRequestException httpRequestException && httpRequestException.Message.Contains("401")) { _requiresTokenRefresh[unitsEndpoint.BaseAddress] = true; } } } while (connection.State != HubConnectionState.Connected); }; RegisterHandlers(connection, unitsEndpoint.BaseAddress); _requiresTokenRefresh.Add(unitsEndpoint.BaseAddress, false); _hubConnections.Add(unitsEndpoint.BaseAddress, connection); _logger.LogInformation("Connecting to UNITS at {BaseUrl} ...", unitsEndpoint.BaseAddress); do { try { await connection.StartAsync(); if (connection.State == HubConnectionState.Connected) { _logger.LogInformation("Connected to UNITS at {BaseUrl}.", unitsEndpoint.BaseAddress); } } catch (Exception e) { var delaySeconds = new Random().Next(5, 20); _logger.LogError(e, "Failed to initially connect to UNITS at {BaseUrl}. Trying again in {Seconds} seconds ...", unitsEndpoint.BaseAddress, delaySeconds); await Task.Delay(delaySeconds * 1000); } } while (connection.State != HubConnectionState.Connected); }