add azaion loader

This commit is contained in:
Alex Bezdieniezhnykh
2025-06-01 19:16:49 +03:00
parent 2584b4f125
commit 500db31142
54 changed files with 629 additions and 291 deletions
+94 -122
View File
@@ -1,6 +1,5 @@
using System.IO;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Windows;
using System.Windows.Threading;
@@ -17,12 +16,12 @@ using Azaion.CommonSecurity.DTO;
using Azaion.CommonSecurity.DTO.Commands;
using Azaion.CommonSecurity.Services;
using Azaion.Dataset;
using CommandLine;
using LibVLCSharp.Shared;
using MediatR;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Serilog;
@@ -32,131 +31,24 @@ namespace Azaion.Suite;
public partial class App
{
private IHost _host = null!;
private ILogger<App> _logger = null!;
private IMediator _mediator = null!;
private FormState _formState = null!;
private IInferenceClient _inferenceClient = null!;
private Stream _securedConfig = null!;
private Stream _systemConfig = null!;
private IHost _host = null!;
private static readonly Guid KeyPressTaskId = Guid.NewGuid();
private string _loadErrors = "";
private readonly ICache _cache = new MemoryCache();
private IAzaionApi _azaionApi = null!;
private CancellationTokenSource _mainCTokenSource = new();
private readonly CancellationTokenSource _mainCTokenSource = new();
private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
_logger.LogError(e.Exception, e.Exception.Message);
Log.Logger.Error(e.Exception, "Unhandled exception");
e.Handled = true;
}
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
StartLogin();
}
private readonly List<string> _encryptedResources =
[
"Azaion.Annotator",
"Azaion.Dataset"
];
private static SecureAppConfig ReadSecureAppConfig()
{
try
{
if (!File.Exists(SecurityConstants.CONFIG_PATH))
throw new FileNotFoundException(SecurityConstants.CONFIG_PATH);
var configStr = File.ReadAllText(SecurityConstants.CONFIG_PATH);
var config = JsonConvert.DeserializeObject<SecureAppConfig>(configStr);
return config ?? SecurityConstants.DefaultSecureAppConfig;
}
catch (Exception e)
{
Console.WriteLine(e);
return SecurityConstants.DefaultSecureAppConfig;
}
}
private void StartLogin()
{
new ConfigUpdater().CheckConfig();
var secureAppConfig = ReadSecureAppConfig();
var apiDir = secureAppConfig.DirectoriesConfig.ApiResourcesDirectory;
_inferenceClient = new InferenceClient(new OptionsWrapper<InferenceClientConfig>(secureAppConfig.InferenceClientConfig), _mainCTokenSource.Token);
var login = new Login();
var loader = (IResourceLoader)_inferenceClient;
login.CredentialsEntered += (_, credentials) =>
{
_inferenceClient.Send(RemoteCommand.Create(CommandType.Login, credentials));
_azaionApi = new AzaionApi(new HttpClient { BaseAddress = new Uri(secureAppConfig.InferenceClientConfig.ApiUrl) }, _cache, credentials);
try
{
_securedConfig = loader.LoadFile("config.secured.json", apiDir);
_systemConfig = loader.LoadFile("config.system.json", apiDir);
}
catch (Exception e)
{
Console.WriteLine(e);
_securedConfig = new MemoryStream("{}"u8.ToArray());
var systemConfig = new
{
AnnotationConfig = Constants.DefaultAnnotationConfig,
AIRecognitionConfig = Constants.DefaultAIRecognitionConfig,
ThumbnailConfig = Constants.DefaultThumbnailConfig,
};
_systemConfig = new MemoryStream(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(systemConfig)));
}
AppDomain.CurrentDomain.AssemblyResolve += (_, a) =>
{
var assemblyName = a.Name.Split(',').First();
if (_encryptedResources.Contains(assemblyName))
{
try
{
var stream = loader.LoadFile($"{assemblyName}.dll", apiDir);
return Assembly.Load(stream.ToArray());
}
catch (Exception e)
{
Log.Logger.Error(e, $"Failed to load assembly {assemblyName}");
_loadErrors += $"{e.Message}{Environment.NewLine}{Environment.NewLine}";
var currentLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!;
var dllPath = Path.Combine(currentLocation, SecurityConstants.DUMMY_DIR, $"{assemblyName}.dll");
return Assembly.LoadFile(dllPath);
}
}
var loadedAssembly = AppDomain.CurrentDomain.GetAssemblies()
.FirstOrDefault(a => a.GetName().Name == assemblyName);
return loadedAssembly;
};
StartMain();
_host.Start();
EventManager.RegisterClassHandler(typeof(UIElement), UIElement.PreviewKeyDownEvent, new RoutedEventHandler(GlobalKeyHandler));
_host.Services.GetRequiredService<MainSuite>().Show();
};
login.Closed += (sender, args) =>
{
if (!login.MainSuiteOpened)
_inferenceClient.Dispose();
};
login.ShowDialog();
}
private void StartMain()
{
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.MinimumLevel.Information()
@@ -166,12 +58,86 @@ public partial class App
rollingInterval: RollingInterval.Day)
.CreateLogger();
Parser.Default.ParseArguments<ApiCredentials>(e.Args)
.WithParsed(Start)
.WithNotParsed(ErrorHandling);
}
private void ErrorHandling(IEnumerable<Error> obj)
{
Log.Fatal($"Error happened: {string.Join(",", obj.Select(x => x.Tag))}");
}
private static InitConfig ReadInitConfig()
{
try
{
if (!File.Exists(SecurityConstants.CONFIG_PATH))
throw new FileNotFoundException(SecurityConstants.CONFIG_PATH);
var configStr = File.ReadAllText(SecurityConstants.CONFIG_PATH);
var config = JsonConvert.DeserializeObject<InitConfig>(configStr);
return config ?? SecurityConstants.DefaultInitConfig;
}
catch (Exception e)
{
Console.WriteLine(e);
return SecurityConstants.DefaultInitConfig;
}
}
private Stream GetSystemConfig(LoaderClient loaderClient, string apiDir)
{
try
{
return loaderClient.LoadFile("config.system.json", apiDir);
}
catch (Exception e)
{
Log.Logger.Error(e, e.Message);
return new MemoryStream(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new
{
AnnotationConfig = Constants.DefaultAnnotationConfig,
AIRecognitionConfig = Constants.DefaultAIRecognitionConfig,
ThumbnailConfig = Constants.DefaultThumbnailConfig,
})));
}
}
private Stream GetSecuredConfig(LoaderClient loaderClient, string apiDir)
{
try
{
return loaderClient.LoadFile("config.secured.json", apiDir);
}
catch (Exception e)
{
Log.Logger.Error(e, e.Message);
throw;
}
}
private void Start(ApiCredentials credentials)
{
new ConfigUpdater().CheckConfig();
var initConfig = ReadInitConfig();
var apiDir = initConfig.DirectoriesConfig.ApiResourcesDirectory;
var loaderClient = new LoaderClient(initConfig.LoaderClientConfig, Log.Logger, _mainCTokenSource.Token);
#if DEBUG
loaderClient.StartClient();
#endif
loaderClient.Connect(); //Client app should be already started by LoaderUI
loaderClient.Send(RemoteCommand.Create(CommandType.Login, credentials));
var azaionApi = new AzaionApi(new HttpClient { BaseAddress = new Uri(initConfig.InferenceClientConfig.ApiUrl) }, _cache, credentials);
_host = Host.CreateDefaultBuilder()
.ConfigureAppConfiguration((context, config) => config
.ConfigureAppConfiguration((_, config) => config
.AddCommandLine(Environment.GetCommandLineArgs())
.AddJsonFile(SecurityConstants.CONFIG_PATH, optional: true, reloadOnChange: true)
.AddJsonStream(_securedConfig)
.AddJsonStream(_systemConfig))
.AddJsonStream(GetSystemConfig(loaderClient, apiDir))
.AddJsonStream(GetSecuredConfig(loaderClient, apiDir)))
.UseSerilog()
.ConfigureServices((context, services) =>
{
@@ -188,15 +154,20 @@ public partial class App
#region External Services
services.ConfigureSection<LoaderClientConfig>(context.Configuration);
services.AddSingleton(loaderClient);
services.ConfigureSection<InferenceClientConfig>(context.Configuration);
services.ConfigureSection<GpsDeniedClientConfig>(context.Configuration);
services.AddSingleton<IInferenceClient>(_inferenceClient);
services.AddSingleton<IGpsMatcherClient, GpsMatcherClient>();
services.AddSingleton<IInferenceClient, InferenceClient>();
services.AddSingleton<IInferenceService, InferenceService>();
services.ConfigureSection<GpsDeniedClientConfig>(context.Configuration);
services.AddSingleton<IGpsMatcherClient, GpsMatcherClient>();
services.AddSingleton<IGpsMatcherService, GpsMatcherService>();
services.AddSingleton<ISatelliteDownloader, SatelliteDownloader>();
services.AddHttpClient();
services.AddSingleton(_azaionApi);
services.AddSingleton(azaionApi);
#endregion
services.AddSingleton<IConfigUpdater, ConfigUpdater>();
@@ -235,12 +206,13 @@ public partial class App
datasetExplorer.Hide();
_mediator = _host.Services.GetRequiredService<IMediator>();
if (!string.IsNullOrEmpty(_loadErrors))
_mediator.Publish(new LoadErrorEvent(_loadErrors));
_logger = _host.Services.GetRequiredService<ILogger<App>>();
_formState = _host.Services.GetRequiredService<FormState>();
DispatcherUnhandledException += OnDispatcherUnhandledException;
_host.Start();
EventManager.RegisterClassHandler(typeof(UIElement), UIElement.PreviewKeyDownEvent, new RoutedEventHandler(GlobalKeyHandler));
_host.Services.GetRequiredService<MainSuite>().Show();
}
private void GlobalKeyHandler(object sender, RoutedEventArgs e)