Files
devops-lab4/src/CommunicationControl/DevOpsProject.HiveMind.Logic/Services/HiveMindService.cs
T

154 lines
6.3 KiB
C#
Raw Normal View History

2025-02-16 20:15:22 +00:00
using DevOpsProject.HiveMind.Logic.Services.Interfaces;
using DevOpsProject.Shared.Clients;
using DevOpsProject.Shared.Models;
using DevOpsProject.Shared.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Text.Json;
using DevOpsProject.HiveMind.Logic.State;
2025-02-18 09:47:50 +00:00
using System.Text;
using Polly;
2025-02-16 20:15:22 +00:00
namespace DevOpsProject.HiveMind.Logic.Services
{
public class HiveMindService : IHiveMindService
{
2025-02-18 09:47:50 +00:00
private readonly IHttpClientFactory _httpClientFactory;
2025-02-16 20:15:22 +00:00
private readonly HiveMindHttpClient _httpClient;
private readonly ILogger<HiveMindService> _logger;
private readonly HiveCommunicationConfig _communicationConfigurationOptions;
private Timer _telemetryTimer;
2025-02-18 09:47:50 +00:00
public HiveMindService(IHttpClientFactory httpClientFactory, HiveMindHttpClient httpClient, ILogger<HiveMindService> logger, IOptionsSnapshot<HiveCommunicationConfig> communicationConfigurationOptions)
2025-02-16 20:15:22 +00:00
{
_httpClient = httpClient;
2025-02-18 09:47:50 +00:00
_httpClientFactory = httpClientFactory;
2025-02-16 20:15:22 +00:00
_logger = logger;
_communicationConfigurationOptions = communicationConfigurationOptions.Value;
}
public async Task ConnectHive()
{
var request = new HiveConnectRequest
{
HiveSchema = _communicationConfigurationOptions.RequestSchema,
2025-02-16 20:15:22 +00:00
HiveIP = _communicationConfigurationOptions.HiveIP,
HivePort = _communicationConfigurationOptions.HivePort,
HiveID = _communicationConfigurationOptions.HiveID
};
2025-02-18 09:47:50 +00:00
var httpClient = _httpClientFactory.CreateClient("HiveConnectClient");
2025-02-16 20:15:22 +00:00
2025-02-18 09:47:50 +00:00
var uriBuilder = new UriBuilder
2025-02-16 20:15:22 +00:00
{
2025-02-18 09:47:50 +00:00
Scheme = _communicationConfigurationOptions.RequestSchema,
Host = _communicationConfigurationOptions.CommunicationControlIP,
Port = _communicationConfigurationOptions.CommunicationControlPort,
Path = $"{_communicationConfigurationOptions.CommunicationControlPath}/connect"
};
var jsonContent = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json");
_logger.LogInformation("Attempting to connect Hive. Request: {@request}, URI: {uri}", request, uriBuilder.Uri);
2025-02-18 09:47:50 +00:00
var retryPolicy = Policy.HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
.WaitAndRetryAsync(
10,
retryAttempt => TimeSpan.FromSeconds(2),
(result, timeSpan, retryCount, context) =>
{
_logger.LogWarning($"Connecting HiveID: {_communicationConfigurationOptions.HiveID}, retry attempt: {retryCount}. \nRequest URL: {uriBuilder.Uri}, request content: {jsonContent}");
});
var response = await retryPolicy.ExecuteAsync(() => httpClient.PostAsync(uriBuilder.Uri, jsonContent));
if (response.IsSuccessStatusCode)
{
var connectResponse = await response.Content.ReadAsStringAsync();
var hiveConnectResponse = JsonSerializer.Deserialize<HiveConnectResponse>(connectResponse);
2025-02-16 20:15:22 +00:00
if (hiveConnectResponse != null && hiveConnectResponse.ConnectResult)
{
HiveInMemoryState.OperationalArea = hiveConnectResponse.OperationalArea;
HiveInMemoryState.CurrentLocation = _communicationConfigurationOptions.InitialLocation;
StartTelemetry();
}
else
{
_logger.LogInformation($"Connecting hive failed for ID: {request.HiveID}");
throw new Exception($"Failed to connect HiveID: {request.HiveID}");
}
}
else
{
2025-02-18 09:47:50 +00:00
_logger.LogError($"Failed to connect hive, terminating process");
Environment.Exit(1);
2025-02-16 20:15:22 +00:00
}
2025-02-18 09:47:50 +00:00
2025-02-16 20:15:22 +00:00
}
public void StopAllTelemetry()
{
StopTelemetry();
}
#region private methods
private void StartTelemetry()
{
if (HiveInMemoryState.IsTelemetryRunning) return;
// TODO: Sending telemetry each N seconds
_telemetryTimer = new Timer(SendTelemetry, null, TimeSpan.Zero, TimeSpan.FromSeconds(5));
_logger.LogInformation("Telemetry timer started.");
}
private void StopTelemetry()
{
_telemetryTimer?.Dispose();
HiveInMemoryState.IsTelemetryRunning = false;
_logger.LogInformation("Telemetry timer stopped.");
}
private async void SendTelemetry(object state)
{
var currentLocation = HiveInMemoryState.CurrentLocation;
try
{
var request = new HiveTelemetryRequest
{
HiveID = _communicationConfigurationOptions.HiveID,
Location = HiveInMemoryState.CurrentLocation ?? default,
// TODO: MOCKED FOR NOW
Height = 5,
Speed = 15,
State = Shared.Enums.State.Move
};
2025-02-18 09:47:50 +00:00
var connectResult = await _httpClient.SendCommunicationControlTelemetryAsync(_communicationConfigurationOptions.RequestSchema,
_communicationConfigurationOptions.CommunicationControlIP, _communicationConfigurationOptions.CommunicationControlPort,
2025-02-16 20:15:22 +00:00
_communicationConfigurationOptions.CommunicationControlPath, request);
_logger.LogInformation($"Telemetry sent for HiveID: {request.HiveID}: {connectResult}");
if (connectResult != null)
{
// TODO: Store timestamp
var hiveConnectResponse = JsonSerializer.Deserialize<HiveTelemetryResponse>(connectResult);
}
else
{
_logger.LogError($"Unable to send Hive telemetry for HiveID: {request.HiveID}.");
throw new Exception($"Failed to send telemetry for HiveID: {request.HiveID}");
}
}
catch (Exception ex)
{
_logger.LogError("Error sending telemetry: {Message}", ex.Message);
}
}
#endregion
}
}