Added more new API Class

This commit is contained in:
TheJoKlLa 2022-05-16 22:41:29 +02:00
parent 4f3521eec3
commit 0ee3dc8497
29 changed files with 468 additions and 370 deletions

View File

@ -76,6 +76,10 @@
<Compile Include="PlatformInitializer.cs" /> <Compile Include="PlatformInitializer.cs" />
<Compile Include="Resources\Resource.designer.cs" /> <Compile Include="Resources\Resource.designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\APIBinder.cs" />
<Compile Include="Services\APIBindedService.cs" />
<Compile Include="Services\APIService.cs" />
<Compile Include="Services\APIServiceConnection.cs" />
<Compile Include="Services\PreferenceStorageService.cs" /> <Compile Include="Services\PreferenceStorageService.cs" />
<Compile Include="Services\SecretStorage.cs" /> <Compile Include="Services\SecretStorage.cs" />
<Compile Include="Services\VersioningService.cs" /> <Compile Include="Services\VersioningService.cs" />

View File

@ -1,7 +1,7 @@
using Borepin.Droid.Services; using Borepin.Droid.Services;
using Borepin.Service;
using Borepin.Service.Storage; using Borepin.Service.Storage;
using Borepin.Service.Versioning; using Borepin.Service.Versioning;
using FabAccessAPI;
using Prism; using Prism;
using Prism.Ioc; using Prism.Ioc;
@ -15,7 +15,7 @@ namespace Borepin.Droid
containerRegistry.Register<ISecretStorageService, SecretStorage>(); containerRegistry.Register<ISecretStorageService, SecretStorage>();
containerRegistry.Register<IVersioningService, VersioningService>(); containerRegistry.Register<IVersioningService, VersioningService>();
containerRegistry.RegisterSingleton<IAPI, API>(); containerRegistry.RegisterSingleton<IAPIService, APIService>();
} }
} }
} }

View File

@ -0,0 +1,50 @@
using Android.App;
using Android.Content;
using Android.OS;
using FabAccessAPI;
namespace Borepin.Droid.Services
{
[Service(Name= "org.fab_infra.fabaccess.APIService")]
public class APIBindedService : Android.App.Service
{
#region Private Members
private IAPI _API;
#endregion
#region Members
public IBinder Binder { get; private set; }
#endregion
#region Methods
public IAPI GetAPI()
{
return _API;
}
public override void OnCreate()
{
base.OnCreate();
_API = new API();
}
public override IBinder OnBind(Intent intent)
{
Binder = new APIBinder(this);
return Binder;
}
public override bool OnUnbind(Intent intent)
{
return base.OnUnbind(intent);
}
public override void OnDestroy()
{
Binder = null;
_API = null;
base.OnDestroy();
}
#endregion
}
}

View File

@ -0,0 +1,18 @@
using Android.OS;
namespace Borepin.Droid.Services
{
public class APIBinder : Binder
{
#region Constructors
public APIBinder(APIBindedService service)
{
Service = service;
}
#endregion
#region Members
public APIBindedService Service { get; private set; }
#endregion
}
}

View File

@ -0,0 +1,28 @@
using Android.App;
using Android.Content;
using Borepin.Service;
using FabAccessAPI;
namespace Borepin.Droid.Services
{
public class APIService : IAPIService
{
#region Private Members
private readonly APIServiceConnection _APIServiceConnection;
#endregion
#region Constructors
public APIService()
{
Context context = Application.Context;
Intent service = new Intent(context, typeof(APIBindedService));
context.BindService(service, _APIServiceConnection, Bind.AutoCreate);
}
#endregion
public IAPI GetAPI()
{
return _APIServiceConnection?.Binder?.Service?.GetAPI();
}
}
}

View File

@ -0,0 +1,32 @@
using Android.Content;
using Android.OS;
using FabAccessAPI;
namespace Borepin.Droid.Services
{
class APIServiceConnection : Java.Lang.Object, IServiceConnection
{
#region Members
public bool IsConnected
{
get
{
return Binder != null;
}
}
public APIBinder Binder { get; private set; } = null;
#endregion
#region Methods
public void OnServiceConnected(ComponentName name, IBinder service)
{
Binder = service as APIBinder;
}
public void OnServiceDisconnected(ComponentName name)
{
Binder = null;
}
#endregion
}
}

View File

@ -98,6 +98,7 @@
</Compile> </Compile>
<Compile Include="PlatformInitializer.cs" /> <Compile Include="PlatformInitializer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\APIService.cs" />
<Compile Include="Services\PreferenceStorageService.cs" /> <Compile Include="Services\PreferenceStorageService.cs" />
<Compile Include="Services\SecretStorageService.cs" /> <Compile Include="Services\SecretStorageService.cs" />
<Compile Include="Services\VersioningService.cs" /> <Compile Include="Services\VersioningService.cs" />

View File

@ -3,7 +3,7 @@ using Prism;
using Prism.Ioc; using Prism.Ioc;
using Borepin.Service.Storage; using Borepin.Service.Storage;
using Borepin.Service.Versioning; using Borepin.Service.Versioning;
using FabAccessAPI; using Borepin.Service;
namespace Borepin.UWP namespace Borepin.UWP
{ {
@ -15,7 +15,7 @@ namespace Borepin.UWP
containerRegistry.Register<ISecretStorageService, SecretStorageService>(); containerRegistry.Register<ISecretStorageService, SecretStorageService>();
containerRegistry.Register<IVersioningService, VersioningService>(); containerRegistry.Register<IVersioningService, VersioningService>();
containerRegistry.RegisterSingleton<IAPI, API>(); containerRegistry.RegisterSingleton<IAPIService, APIService>();
} }
} }
} }

View File

@ -0,0 +1,23 @@
using Borepin.Service;
using FabAccessAPI;
namespace Borepin.UWP.Services
{
public class APIService : IAPIService
{
#region Private Members
private readonly IAPI _API;
#endregion
#region Constructors
public APIService()
{
_API = new API();
}
#endregion
public IAPI GetAPI()
{
return _API;
}
}
}

View File

@ -81,6 +81,7 @@
<ItemGroup> <ItemGroup>
<Compile Include="Main.cs" /> <Compile Include="Main.cs" />
<Compile Include="AppDelegate.cs" /> <Compile Include="AppDelegate.cs" />
<Compile Include="Services\APIService.cs" />
<Compile Include="Services\PreferenceStorageService.cs" /> <Compile Include="Services\PreferenceStorageService.cs" />
<Compile Include="Services\SecretStorageService.cs" /> <Compile Include="Services\SecretStorageService.cs" />
<Compile Include="Services\VersioningService.cs" /> <Compile Include="Services\VersioningService.cs" />

View File

@ -1,7 +1,7 @@
using Borepin.iOS.Services; using Borepin.iOS.Services;
using Borepin.Service;
using Borepin.Service.Storage; using Borepin.Service.Storage;
using Borepin.Service.Versioning; using Borepin.Service.Versioning;
using FabAccessAPI;
using Prism; using Prism;
using Prism.Ioc; using Prism.Ioc;
@ -15,7 +15,7 @@ namespace Borepin.iOS
containerRegistry.Register<ISecretStorageService, SecretStorageService>(); containerRegistry.Register<ISecretStorageService, SecretStorageService>();
containerRegistry.Register<IVersioningService, VersioningService>(); containerRegistry.Register<IVersioningService, VersioningService>();
containerRegistry.RegisterSingleton<IAPI, API>(); containerRegistry.RegisterSingleton<IAPIService, APIService>();
} }
} }
} }

View File

@ -0,0 +1,23 @@
using Borepin.Service;
using FabAccessAPI;
namespace Borepin.iOS.Services
{
public class APIService : IAPIService
{
#region Private Members
private readonly IAPI _API;
#endregion
#region Constructors
public APIService()
{
_API = new API();
}
#endregion
public IAPI GetAPI()
{
return _API;
}
}
}

View File

@ -26,11 +26,6 @@ namespace Borepin
{ {
InitializeComponent(); InitializeComponent();
INavigationParameters parameters = new NavigationParameters()
{
{ "instance", 0 },
};
await NavigationService.NavigateAsync(new Uri("https://borepin.fab-access.org/StartPage")).ConfigureAwait(false); await NavigationService.NavigateAsync(new Uri("https://borepin.fab-access.org/StartPage")).ConfigureAwait(false);
} }
@ -71,7 +66,7 @@ namespace Borepin
// IPreferenceStorageService // IPreferenceStorageService
// ISecretStorageService // ISecretStorageService
// IVersioningService // IVersioningService
// IAPI // IAPIService
#endregion #endregion
} }
} }

View File

@ -1,9 +1,8 @@
using Borepin.Service.BFFH; using Borepin.Service;
using Borepin.Service.BFFH.Exceptions; using FabAccessAPI;
using Prism.Navigation; using Prism.Navigation;
using Prism.Services; using Prism.Services;
using System.Threading.Tasks; using System.Threading.Tasks;
using Xamarin.Forms;
namespace Borepin.Base namespace Borepin.Base
{ {
@ -14,14 +13,56 @@ namespace Borepin.Base
{ {
#region Private Fields #region Private Fields
protected readonly IPageDialogService _PageDialogService; protected readonly IPageDialogService _PageDialogService;
protected readonly IBFFHService _BFFHService; protected readonly IAPI _API;
#endregion #endregion
#region Constructors #region Constructors
protected ConnectionModelBase(INavigationService navigationService, IPageDialogService pageDialogService, IBFFHService bFFHService) : base(navigationService) protected ConnectionModelBase(INavigationService navigationService, IPageDialogService pageDialogService, IAPIService apiService) : base(navigationService)
{ {
_PageDialogService = pageDialogService; _PageDialogService = pageDialogService;
_BFFHService = bFFHService; _API = apiService.GetAPI();
_API.ConnectionStatusChanged += OnConnectionStatusChanged;
IsConnected = _API.IsConnected;
}
#endregion
#region Methods
public void OnConnectionStatusChanged(object sender, ConnectionStatusChange args)
{
switch(args)
{
case ConnectionStatusChange.Connected:
IsConnected = true;
LoadAPIData();
break;
case ConnectionStatusChange.Reconnected:
ReloadAPIData();
break;
case ConnectionStatusChange.ConnectionLoss:
case ConnectionStatusChange.Disconnected:
IsConnected = false;
break;
}
}
public virtual Task LoadAPIData()
{
return Task.CompletedTask;
}
public virtual Task ReloadAPIData()
{
return Task.CompletedTask;
}
public virtual Task LoadInstance(object instance)
{
return Task.CompletedTask;
}
public virtual Task<object> CreateInstance()
{
return Task.FromResult<object>(null);
} }
#endregion #endregion
@ -37,36 +78,31 @@ namespace Borepin.Base
} }
#endregion #endregion
#region Methods #region INavigationAware
/// <summary> public override void OnNavigatedTo(INavigationParameters parameters)
/// Checks connection to Server.
/// Display message if Connection is lost.
/// </summary>
/// <returns>True if connection is ok.</returns>
public async Task<bool> CheckConnection()
{ {
try if(parameters.ContainsKey("instance"))
{ {
if(_BFFHService.CurrentConnection != null && !_BFFHService.IsConnected) LoadInstance(parameters.GetValue<object>("instance"));
{
await _BFFHService.Reconnect().ConfigureAwait(false);
} }
else if(_BFFHService.CurrentConnection == null) else
{ {
return false; Log.Trace("No instance");
LoadInstance(null);
} }
return true; if(_API.IsConnected)
{
LoadAPIData();
}
} }
catch (ReconnectingFailedException)
{
Device.BeginInvokeOnMainThread(async () =>
{
await _PageDialogService.DisplayAlertAsync("Connection failed", "Lost connection to server.", "Ok").ConfigureAwait(false);
});
IsConnected = false; public override void OnNavigatedFrom(INavigationParameters parameters)
return false; {
object instance = CreateInstance();
if(instance != null)
{
parameters.Add("instance", instance);
} }
} }
#endregion #endregion

View File

@ -0,0 +1,22 @@
using System;
namespace Borepin.Base.Exceptions
{
public class InstanceIncorrectException : Exception
{
public InstanceIncorrectException()
{
}
public InstanceIncorrectException(string message) : base(message)
{
}
public InstanceIncorrectException(string message, Exception inner) : base(message, inner)
{
}
}
}

View File

@ -1,6 +1,6 @@
using Prism.Mvvm; using NLog;
using Prism.Mvvm;
using Prism.Navigation; using Prism.Navigation;
using System.Threading.Tasks;
namespace Borepin.Base namespace Borepin.Base
{ {
@ -9,6 +9,10 @@ namespace Borepin.Base
/// </summary> /// </summary>
public abstract class PageModelBase : BindableBase, INavigationAware public abstract class PageModelBase : BindableBase, INavigationAware
{ {
#region Logger
protected static readonly Logger Log = LogManager.GetCurrentClassLogger();
#endregion
#region Private Fields #region Private Fields
protected readonly INavigationService _NavigationService; protected readonly INavigationService _NavigationService;
@ -30,14 +34,6 @@ namespace Borepin.Base
} }
#endregion #endregion
#region Data
/// <summary>
/// Load Data async
/// </summary>
/// <returns></returns>
public abstract Task LoadData();
#endregion
#region INavigationAware #region INavigationAware
public abstract void OnNavigatedTo(INavigationParameters parameters); public abstract void OnNavigatedTo(INavigationParameters parameters);
public abstract void OnNavigatedFrom(INavigationParameters parameters); public abstract void OnNavigatedFrom(INavigationParameters parameters);

View File

@ -31,6 +31,7 @@
</PackageReference> </PackageReference>
<PackageReference Include="NaturalSort.Extension" Version="3.2.0" /> <PackageReference Include="NaturalSort.Extension" Version="3.2.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="NLog" Version="4.7.15" />
<PackageReference Include="Plugin.Multilingual" Version="1.0.2" /> <PackageReference Include="Plugin.Multilingual" Version="1.0.2" />
<PackageReference Include="Prism.DryIoc.Forms" Version="8.1.97" /> <PackageReference Include="Prism.DryIoc.Forms" Version="8.1.97" />
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2401" /> <PackageReference Include="Xamarin.Forms" Version="5.0.0.2401" />

View File

@ -1,10 +1,11 @@
using System; using System;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
using Borepin.Base; using Borepin.Base;
using Borepin.Model; using Borepin.Base.Exceptions;
using Borepin.Service.BFFH; using Borepin.Service;
using Borepin.Service.BFFH.Exceptions; using FabAccessAPI;
using FabAccessAPI.Exceptions; using FabAccessAPI.Exceptions;
using Prism.Commands; using Prism.Commands;
using Prism.Navigation; using Prism.Navigation;
@ -12,31 +13,32 @@ using Prism.Services;
namespace Borepin.PageModel.AddServerProcess namespace Borepin.PageModel.AddServerProcess
{ {
public class AuthPlainPageModel : PageModelBase public class AuthPlainPageModel : ConnectionModelBase
{ {
#region Private Fields #region Private Fields
private readonly IBFFHService _BFFHService; private ConnectionData _ConnectionData;
private readonly IPageDialogService _PageDialogService;
private Connection _Connection;
#endregion #endregion
#region Constructors #region Constructors
public AuthPlainPageModel(INavigationService navigationService, IBFFHService bffhService, IPageDialogService pageDialogService) : base(navigationService) public AuthPlainPageModel(INavigationService navigationService, IAPIService apiService, IPageDialogService pageDialogService) : base(navigationService, pageDialogService, apiService)
{ {
_BFFHService = bffhService;
_PageDialogService = pageDialogService;
AuthenticateCommand = new DelegateCommand(async () => await AuthenticateCommandExecute().ConfigureAwait(false)); AuthenticateCommand = new DelegateCommand(async () => await AuthenticateCommandExecute().ConfigureAwait(false));
} }
#endregion #endregion
#region LoadData #region LoadData
public override Task LoadData() public override Task LoadInstance(object instance)
{ {
Username = _Connection.Username; if(instance is ConnectionData)
{
_ConnectionData = instance as ConnectionData;
Username = _ConnectionData.Username;
}
else
{
throw new InstanceIncorrectException();
}
IsBusy = false;
return Task.CompletedTask; return Task.CompletedTask;
} }
#endregion #endregion
@ -68,16 +70,26 @@ namespace Borepin.PageModel.AddServerProcess
{ {
IsBusy = true; IsBusy = true;
_Connection.Username = Username; _ConnectionData = new ConnectionData()
if (_BFFHService.IsConnected)
{ {
await _BFFHService.Disconnect().ConfigureAwait(true); Host = _ConnectionData.Host,
Mechanism = Mechanism.PLAIN,
Username = Username,
Properties = new Dictionary<string, object>(StringComparer.Ordinal)
{
{ "username", Username },
{ "password", Password }
},
};
if (_API.IsConnected)
{
await _API.Disconnect().ConfigureAwait(true);
} }
try try
{ {
await _BFFHService.Connect(_Connection, Password).ConfigureAwait(true); await _API.Connect(_ConnectionData).ConfigureAwait(true);
} }
catch (ConnectingFailedException) catch (ConnectingFailedException)
{ {
@ -101,30 +113,10 @@ namespace Borepin.PageModel.AddServerProcess
return; return;
} }
await _NavigationService.NavigateAsync("/MainPage/NavigationPage/MachineListPage").ConfigureAwait(false); INavigationResult result = await _NavigationService.NavigateAsync("/MainPage/NavigationPage/MachineListPage").ConfigureAwait(false);
} if(result.Exception != null)
#endregion
#region INavigationAware
public override void OnNavigatedTo(INavigationParameters parameters)
{ {
if (parameters.ContainsKey("instance") && parameters["instance"] is Connection) Log.Fatal(result.Exception, "Navigating failed");
{
_Connection = parameters["instance"] as Connection;
}
else
{
_Connection = new Connection();
}
LoadData();
}
public override void OnNavigatedFrom(INavigationParameters parameters)
{
if(parameters.GetNavigationMode() == NavigationMode.Back)
{
parameters.Add("instance", _Connection);
} }
} }
#endregion #endregion

View File

@ -1,59 +1,56 @@
using Borepin.Base; using Borepin.Base;
using Borepin.Model; using Borepin.Service;
using Borepin.Service.BFFH; using FabAccessAPI;
using Prism.AppModel; using FabAccessAPI.Exceptions;
using Prism.Commands;
using Prism.Navigation; using Prism.Navigation;
using Prism.Services; using Prism.Services;
using Prism.Services.Dialogs;
using System; using System;
using System.Globalization;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
using Xamarin.Forms;
namespace Borepin.PageModel.AddServerProcess namespace Borepin.PageModel.AddServerProcess
{ {
public class SelectServerPageModel : PageModelBase, IPageLifecycleAware public class SelectServerPageModel : ConnectionModelBase
{ {
#region Private Fields #region Private Fields
private readonly IBFFHService _BFFHService; private ConnectionData _ConnectionData;
private readonly IPageDialogService _PageDialogService;
private readonly IDialogService _DialogService;
private Connection _Connection;
private bool _Scanned;
#endregion #endregion
#region Constructors #region Constructors
public SelectServerPageModel(INavigationService navigationService, IBFFHService bffhService, IPageDialogService pageDialogService, IDialogService dialogService) : base(navigationService) public SelectServerPageModel(INavigationService navigationService, IPageDialogService pageDialogService, IAPIService apiService) : base(navigationService, pageDialogService, apiService)
{ {
_BFFHService = bffhService; ConnectToServerCommand = new DelegateCommand(async () => await ConnectToServerExecute().ConfigureAwait(false));
_PageDialogService = pageDialogService; DetectLocalServerCommand = new DelegateCommand(DetectHostCommandExecute);
_DialogService = dialogService; ScanCodeCommand = new DelegateCommand(ScanCodeCommandExecute);
ConnectToServerCommand = new Command(async ()=> await ConnectToServerExecute().ConfigureAwait(false));
DetectLocalServerCommand = new Command(DetectHostCommandExecute);
ScanCodeCommand = new Command(ScanCodeCommandExecute);
} }
#endregion #endregion
#region LoadData #region LoadData
public override Task LoadData() public override Task LoadInstance(object instance)
{ {
Server = string.Format(CultureInfo.InvariantCulture, "{0}:{1}", _Connection.Address.Host, _Connection.Address.Port); if(instance is ConnectionData)
{
_ConnectionData = instance as ConnectionData;
Host = _ConnectionData.Host.ToString();
}
IsBusy = false;
return Task.CompletedTask; return Task.CompletedTask;
} }
public override Task<object> CreateInstance()
{
return Task.FromResult<object>(_ConnectionData);
}
#endregion #endregion
#region Fields #region Fields
private string _Server; private string _Host;
public string Server public string Host
{ {
get => _Server; get => _Host;
set => SetProperty(ref _Server, value); set => SetProperty(ref _Host, value);
} }
#endregion #endregion
@ -71,13 +68,13 @@ namespace Borepin.PageModel.AddServerProcess
try try
{ {
string server_address = ""; string server_address = "";
if(Regex.IsMatch(Server, "([a-zA-Z]{2,20}):\\/\\/", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture, TimeSpan.FromSeconds(1))) if(Regex.IsMatch(Host, "([a-zA-Z]{2,20}):\\/\\/", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture, TimeSpan.FromSeconds(1)))
{ {
server_address = Server; server_address = Host;
} }
else else
{ {
server_address = "http://" + Server; server_address = "http://" + Host;
} }
UriBuilder builder = new UriBuilder(server_address); UriBuilder builder = new UriBuilder(server_address);
@ -86,9 +83,9 @@ namespace Borepin.PageModel.AddServerProcess
builder.Port = 59661; builder.Port = 59661;
} }
_Connection = new Connection() _ConnectionData = new ConnectionData()
{ {
Address = builder.Uri, Host = builder.Uri,
}; };
} }
catch (UriFormatException) catch (UriFormatException)
@ -99,7 +96,11 @@ namespace Borepin.PageModel.AddServerProcess
return; return;
} }
if (!await _BFFHService.TestConnection(_Connection).ConfigureAwait(true)) try
{
await _API.TestConnection(_ConnectionData).ConfigureAwait(true);
}
catch(ConnectingFailedException)
{ {
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to connect to server.", "Ok").ConfigureAwait(false); await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to connect to server.", "Ok").ConfigureAwait(false);
@ -107,12 +108,11 @@ namespace Borepin.PageModel.AddServerProcess
return; return;
} }
INavigationParameters parameters = new NavigationParameters() INavigationResult result = await _NavigationService.NavigateAsync("AddServerProcess_ChooseAuthTypePage").ConfigureAwait(false);
if (result.Exception != null)
{ {
{"instance", _Connection }, Log.Fatal(result.Exception, "Navigating failed");
}; }
await _NavigationService.NavigateAsync("AddServerProcess_ChooseAuthTypePage", parameters).ConfigureAwait(false);
} }
private ICommand _ScanCodeCommand; private ICommand _ScanCodeCommand;
@ -123,16 +123,7 @@ namespace Borepin.PageModel.AddServerProcess
} }
public void ScanCodeCommandExecute() public void ScanCodeCommandExecute()
{ {
_DialogService.ShowDialog("ScanDialog", ScanCodeCommandExecute_Dialog);
}
public void ScanCodeCommandExecute_Dialog(IDialogResult result)
{
if (string.Equals(result.Parameters.GetValue<string>("result"), "scanned", StringComparison.Ordinal))
{
Server = result.Parameters["value"] as string;
_Scanned = true;
}
} }
private ICommand _DetectLocalServerCommand; private ICommand _DetectLocalServerCommand;
@ -144,52 +135,7 @@ namespace Borepin.PageModel.AddServerProcess
public void DetectHostCommandExecute() public void DetectHostCommandExecute()
{ {
// Get Example Server Address // Get Example Server Address
Server = "127.0.0.1:59661"; Host = "127.0.0.1:59661";
}
#endregion
#region IPageLifecycleAware
public async void OnAppearing()
{
if (_Scanned)
{
_Scanned = false;
await ConnectToServerExecute().ConfigureAwait(false);
}
}
public void OnDisappearing()
{
}
#endregion
#region INavigationAware
public override void OnNavigatedTo(INavigationParameters parameters)
{
if(_Connection == null)
{
if (parameters.ContainsKey("instance") && parameters["instance"] is Connection)
{
_Connection = parameters["instance"] as Connection;
}
else
{
_Connection = new Connection();
}
LoadData();
}
else
{
IsBusy = false;
}
}
public override void OnNavigatedFrom(INavigationParameters parameters)
{
} }
#endregion #endregion
} }

View File

@ -4,7 +4,6 @@ using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
using Prism.Commands; using Prism.Commands;
using Prism.Navigation; using Prism.Navigation;
using Borepin.Service.BFFH;
using Borepin.Base; using Borepin.Base;
using FabAccessAPI.Schema; using FabAccessAPI.Schema;
using Prism.Services; using Prism.Services;
@ -12,6 +11,7 @@ using static FabAccessAPI.Schema.Machine;
using System; using System;
using NaturalSort.Extension; using NaturalSort.Extension;
using System.Linq; using System.Linq;
using Borepin.Service;
namespace Borepin.PageModel namespace Borepin.PageModel
{ {
@ -22,7 +22,7 @@ namespace Borepin.PageModel
#endregion #endregion
#region Constructors #region Constructors
public MachineListPageModel(INavigationService navigationService, IPageDialogService pageDialogService, IBFFHService bFFHService) : base(navigationService, pageDialogService, bFFHService) public MachineListPageModel(INavigationService navigationService, IPageDialogService pageDialogService, IAPIService apiService) : base(navigationService, pageDialogService, apiService)
{ {
SelectInstanceCommand = new DelegateCommand<object>(SelectInstanceCommandExecute); SelectInstanceCommand = new DelegateCommand<object>(SelectInstanceCommandExecute);
ScanCodeCommand = new DelegateCommand(async () => await ScanCodeCommandExecute().ConfigureAwait(false)); ScanCodeCommand = new DelegateCommand(async () => await ScanCodeCommandExecute().ConfigureAwait(false));

View File

@ -4,11 +4,10 @@ using Prism.Navigation;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
using FabAccessAPI.Schema; using FabAccessAPI.Schema;
using Borepin.Service.BFFH;
using static FabAccessAPI.Schema.MachineSystem;
using Borepin.Model; using Borepin.Model;
using Prism.Services; using Prism.Services;
using Borepin.Service.BFFH.Exceptions; using Borepin.Service;
using Borepin.Base.Exceptions;
namespace Borepin.PageModel namespace Borepin.PageModel
{ {
@ -20,7 +19,7 @@ namespace Borepin.PageModel
#endregion #endregion
#region Contructors #region Contructors
public MachinePageModel(INavigationService navigationService, IPageDialogService pageDialogService, IBFFHService bffhService) : base(navigationService, pageDialogService, bffhService) public MachinePageModel(INavigationService navigationService, IPageDialogService pageDialogService, IAPIService apiService) : base(navigationService, pageDialogService, apiService)
{ {
UseMachineCommand = new DelegateCommand(UseMachineCommandExecute); UseMachineCommand = new DelegateCommand(UseMachineCommandExecute);
GiveBackMachineCommand = new DelegateCommand(GiveBackMachineCommandExecute); GiveBackMachineCommand = new DelegateCommand(GiveBackMachineCommandExecute);
@ -29,34 +28,29 @@ namespace Borepin.PageModel
#endregion #endregion
#region Data #region Data
public override async Task LoadData() public override Task LoadInstance(object instance)
{ {
IsBusy = true; IsBusy = true;
if (!await CheckConnection().ConfigureAwait(false))
if(instance is string)
{ {
IsConnected = false; _ID = instance as string;
}
else
{
throw new InstanceIncorrectException();
}
IsBusy = false; IsBusy = false;
return;
return Task.CompletedTask;
} }
MachineSystem machineSystem; public override async Task LoadAPIData()
try
{ {
machineSystem = (await _BFFHService.GetSession().ConfigureAwait(false)).MachineSystem; _Machine = (await _API.Session.MachineSystem.Info.GetMachine(_ID).ConfigureAwait(false)).Just;
}
catch(ReconnectingFailedException)
{
await _PageDialogService.DisplayAlertAsync("Connection failed", "Lost connection to server.", "Ok").ConfigureAwait(false);
return;
}
_Machine = (await machineSystem.Info.GetMachine(_ID).ConfigureAwait(false)).Just;
MachineItem = new MachineVisualize(_Machine); MachineItem = new MachineVisualize(_Machine);
MachineItem.LoadData(); MachineItem.LoadData();
IsBusy = false;
} }
#endregion #endregion
@ -81,18 +75,14 @@ namespace Borepin.PageModel
public async void UseMachineCommandExecute() public async void UseMachineCommandExecute()
{ {
IsBusy = true; IsBusy = true;
if (!await CheckConnection().ConfigureAwait(false))
if(_API.IsConnected)
{ {
IsConnected = false;
IsBusy = false;
return;
}
Machine.IUseInterface useInterface = _Machine.Use; Machine.IUseInterface useInterface = _Machine.Use;
await useInterface.Use().ConfigureAwait(false); await useInterface.Use().ConfigureAwait(false);
await LoadData().ConfigureAwait(false); await LoadAPIData().ConfigureAwait(false);
}
IsBusy = false; IsBusy = false;
} }
@ -107,18 +97,14 @@ namespace Borepin.PageModel
public async void GiveBackMachineCommandExecute() public async void GiveBackMachineCommandExecute()
{ {
IsBusy = true; IsBusy = true;
if (!await CheckConnection().ConfigureAwait(false))
if (_API.IsConnected)
{ {
IsConnected = false;
IsBusy = false;
return;
}
Machine.IInUseInterface inUseInterface = _Machine.Inuse; Machine.IInUseInterface inUseInterface = _Machine.Inuse;
await inUseInterface.GiveBack().ConfigureAwait(false); await inUseInterface.GiveBack().ConfigureAwait(false);
await LoadData().ConfigureAwait(false); await LoadAPIData().ConfigureAwait(false);
}
IsBusy = false; IsBusy = false;
} }
@ -133,35 +119,18 @@ namespace Borepin.PageModel
public async void ForceFreeMachineCommandExecute() public async void ForceFreeMachineCommandExecute()
{ {
IsBusy = true; IsBusy = true;
if (!await CheckConnection().ConfigureAwait(false))
{
IsConnected = false;
IsBusy = false; if (_API.IsConnected)
return; {
}
Machine.IManageInterface manageInterface = _Machine.Manage; Machine.IManageInterface manageInterface = _Machine.Manage;
await manageInterface.ForceFree().ConfigureAwait(false); await manageInterface.ForceFree().ConfigureAwait(false);
await LoadData().ConfigureAwait(false); await LoadAPIData().ConfigureAwait(false);
}
IsBusy = false; IsBusy = false;
} }
#endregion #endregion
#region INavigationService
public override void OnNavigatedFrom(INavigationParameters parameters)
{
}
public override async void OnNavigatedTo(INavigationParameters parameters)
{
_ID = parameters["id"] as string;
await LoadData().ConfigureAwait(false);
}
#endregion
} }
} }

View File

@ -1,6 +1,5 @@
using Borepin.Base; using Borepin.Base;
using Borepin.Service.BFFH; using Borepin.Service;
using Borepin.Service.BFFH.Exceptions;
using FabAccessAPI.Schema; using FabAccessAPI.Schema;
using Prism.Commands; using Prism.Commands;
using Prism.Navigation; using Prism.Navigation;
@ -17,7 +16,7 @@ namespace Borepin.PageModel
class ScanURNPageModel : ConnectionModelBase class ScanURNPageModel : ConnectionModelBase
{ {
#region Contructors #region Contructors
public ScanURNPageModel(INavigationService navigationService, IPageDialogService pageDialogService, IBFFHService bffhService) : base(navigationService, pageDialogService, bffhService) public ScanURNPageModel(INavigationService navigationService, IPageDialogService pageDialogService, IAPIService apiService) : base(navigationService, pageDialogService, apiService)
{ {
AbortCommand = new DelegateCommand(async () => await AbortCommandExecute().ConfigureAwait(true)); AbortCommand = new DelegateCommand(async () => await AbortCommandExecute().ConfigureAwait(true));
ScannedCommand = new DelegateCommand(async () => await ScannedCommandExecuteAsync().ConfigureAwait(false)); ScannedCommand = new DelegateCommand(async () => await ScannedCommandExecuteAsync().ConfigureAwait(false));
@ -27,13 +26,6 @@ namespace Borepin.PageModel
} }
#endregion #endregion
#region Data
public override async Task LoadData()
{
await Task.CompletedTask.ConfigureAwait(false);
}
#endregion
#region Fields #region Fields
public MobileBarcodeScanningOptions ScanOptions public MobileBarcodeScanningOptions ScanOptions
{ {
@ -98,21 +90,8 @@ namespace Borepin.PageModel
return; return;
} }
// END HACK // END HACK
string id = null;
try
{
id = await QRToID(ScanResult.Text).ConfigureAwait(false);
}
catch(ReconnectingFailedException)
{
Device.BeginInvokeOnMainThread(async () =>
{
await _PageDialogService.DisplayAlertAsync("Connection failed", "Please reconnect to the server.", "OK").ConfigureAwait(false);
IsScanning = true;
});
return; string id = await QRToID(ScanResult.Text).ConfigureAwait(false);
}
if (id != null) if (id != null)
{ {
@ -141,17 +120,9 @@ namespace Borepin.PageModel
public async Task<string> QRToID(string value) public async Task<string> QRToID(string value)
{ {
if (!_BFFHService.IsConnected) if (_API.IsConnected)
{ {
await _BFFHService.Reconnect().ConfigureAwait(false); Optional<Machine> optional = await _API.Session.MachineSystem.Info.GetMachineURN(value).ConfigureAwait(false);
IsConnected = false;
return null;
}
MachineSystem machineSystem = (await _BFFHService.GetSession().ConfigureAwait(false)).MachineSystem;
Optional<Machine> optional = await machineSystem.Info.GetMachineURN(value).ConfigureAwait(false);
if (optional.Just == null) if (optional.Just == null)
{ {
@ -160,6 +131,11 @@ namespace Borepin.PageModel
return optional.Just.Id; return optional.Just.Id;
} }
else
{
return null;
}
}
private ICommand _AbortCommand; private ICommand _AbortCommand;
public ICommand AbortCommand public ICommand AbortCommand
@ -175,17 +151,5 @@ namespace Borepin.PageModel
await _NavigationService.GoBackAsync().ConfigureAwait(false); await _NavigationService.GoBackAsync().ConfigureAwait(false);
} }
#endregion #endregion
#region INavigationService
public override void OnNavigatedFrom(INavigationParameters parameters)
{
}
public override void OnNavigatedTo(INavigationParameters parameters)
{
}
#endregion
} }
} }

View File

@ -2,25 +2,28 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Linq; using System.Linq;
using Borepin.Model;
using System.Windows.Input; using System.Windows.Input;
using Prism.Commands; using Prism.Commands;
using Prism.Navigation; using Prism.Navigation;
using Borepin.Service.BFFH;
using Borepin.Base; using Borepin.Base;
using Borepin.Service.Storage;
using FabAccessAPI;
using Borepin.Service;
namespace Borepin.PageModel namespace Borepin.PageModel
{ {
public class ServerListPageModel : PageModelBase public class ServerListPageModel : PageModelBase
{ {
#region Private Fields #region Private Fields
private readonly IBFFHService _BFFHService; private readonly ILoginStorageService _LoginStorageService;
private readonly IAPI _API;
#endregion #endregion
#region Constructors #region Constructors
public ServerListPageModel(INavigationService navigationService, IBFFHService bffhService) : base(navigationService) public ServerListPageModel(INavigationService navigationService, ILoginStorageService loginStorageService, IAPIService apiService) : base(navigationService)
{ {
_BFFHService = bffhService; _LoginStorageService = loginStorageService;
_API = apiService.GetAPI();
AddInstancesCommand = new DelegateCommand(AddInstancesCommandExecute); AddInstancesCommand = new DelegateCommand(AddInstancesCommandExecute);
SelectInstanceCommand = new DelegateCommand<object>(SelectInstanceCommandExecute); SelectInstanceCommand = new DelegateCommand<object>(SelectInstanceCommandExecute);
@ -28,14 +31,14 @@ namespace Borepin.PageModel
#endregion #endregion
#region Data #region Data
public override async Task LoadData() public async Task LoadData()
{ {
IList<Connection> list = await _BFFHService.GetConnections().ConfigureAwait(false); IList<ConnectionData> list = await _LoginStorageService.GetList().ConfigureAwait(false);
if (_BFFHService.IsConnected) if (_API.IsConnected)
{ {
ActiveConnection = new ServerListItemViewModel(_BFFHService.CurrentConnection); ActiveConnection = new ServerListItemViewModel(_API.ConnectionData);
list.Remove(_BFFHService.CurrentConnection); list.Remove(_API.ConnectionData);
HasActiveConnection = true; HasActiveConnection = true;
} }

View File

@ -1,7 +1,7 @@
using Borepin.Base; using Borepin.Base;
using Borepin.Model; using Borepin.Service;
using Borepin.Service.BFFH; using FabAccessAPI;
using Borepin.Service.BFFH.Exceptions; using FabAccessAPI.Exceptions;
using Prism.Commands; using Prism.Commands;
using Prism.Navigation; using Prism.Navigation;
using Prism.Services; using Prism.Services;
@ -13,22 +13,17 @@ using System.Windows.Input;
namespace Borepin.PageModel namespace Borepin.PageModel
{ {
public class ServerPageModel : PageModelBase public class ServerPageModel : ConnectionModelBase
{ {
#region Private Fields #region Private Fields
private readonly IDialogService _DialogService; private readonly IDialogService _DialogService;
private readonly IBFFHService _BFFHService;
private readonly IPageDialogService _PageDialogService;
#endregion #endregion
#region Constructors #region Constructors
public ServerPageModel(INavigationService navigationService, IDialogService dialogService, IBFFHService bffhService, IPageDialogService pageDialogService) : base(navigationService) public ServerPageModel(INavigationService navigationService, IPageDialogService pageDialogService, IAPIService apiService, IDialogService dialogService,) : base(navigationService, pageDialogService, apiService)
{ {
_DialogService = dialogService; _DialogService = dialogService;
_BFFHService = bffhService;
_PageDialogService = pageDialogService;
ConnectCommand = new DelegateCommand(async () => await ConnectCommandExecute().ConfigureAwait(false)); ConnectCommand = new DelegateCommand(async () => await ConnectCommandExecute().ConfigureAwait(false));
DisconnectCommand = new DelegateCommand(async () => await DisonnectCommandExecute().ConfigureAwait(false)); DisconnectCommand = new DelegateCommand(async () => await DisonnectCommandExecute().ConfigureAwait(false));
DeleteCommand = new DelegateCommand(DeleteCommandExecute); DeleteCommand = new DelegateCommand(DeleteCommandExecute);
@ -58,8 +53,8 @@ namespace Borepin.PageModel
#endregion #endregion
#region Fields #region Fields
private Connection _Connection_Item; private ConnectionData _Connection_Item;
public Connection Connection_Item public ConnectionData Connection_Item
{ {
get => _Connection_Item; get => _Connection_Item;
set => SetProperty(ref _Connection_Item, value); set => SetProperty(ref _Connection_Item, value);
@ -91,14 +86,14 @@ namespace Borepin.PageModel
{ {
IsBusy = true; IsBusy = true;
if(_BFFHService.IsConnected) if(_API.IsConnected)
{ {
await _BFFHService.Disconnect().ConfigureAwait(true); await _API.Disconnect().ConfigureAwait(true);
} }
try try
{ {
await _BFFHService.Connect(Connection_Item).ConfigureAwait(true); await _API.Connect(Connection_Item).ConfigureAwait(true);
} }
catch(ConnectingFailedException) catch(ConnectingFailedException)
{ {
@ -107,21 +102,13 @@ namespace Borepin.PageModel
IsBusy = false; IsBusy = false;
return; return;
} }
catch(AuthenticatingFailedException) catch(AuthenticationFailedException)
{ {
await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to authenticate to server.", "Ok").ConfigureAwait(false); await _PageDialogService.DisplayAlertAsync("Connection failed", "Unable to authenticate to server.", "Ok").ConfigureAwait(false);
IsBusy = false; IsBusy = false;
return; return;
} }
catch(MissingCredentialsException)
{
await _PageDialogService.DisplayAlertAsync("Secure Storage failed", "Unable to load connections from secure storage.\n Please recreate the connection.", "Ok").ConfigureAwait(false);
await _NavigationService.NavigateAsync("/MainPage/NavigationPage/ServerListPage").ConfigureAwait(false);
IsBusy = false;
return;
}
await _NavigationService.NavigateAsync("/MainPage/NavigationPage/MachineListPage").ConfigureAwait(false); await _NavigationService.NavigateAsync("/MainPage/NavigationPage/MachineListPage").ConfigureAwait(false);
} }
@ -134,7 +121,7 @@ namespace Borepin.PageModel
} }
public async Task DisonnectCommandExecute() public async Task DisonnectCommandExecute()
{ {
await _BFFHService.Disconnect().ConfigureAwait(false); await _API.Disconnect().ConfigureAwait(false);
await LoadData().ConfigureAwait(false); await LoadData().ConfigureAwait(false);
} }
@ -170,22 +157,5 @@ namespace Borepin.PageModel
} }
} }
#endregion #endregion
#region INavigationAware
public override void OnNavigatedFrom(INavigationParameters parameters)
{
}
public override async void OnNavigatedTo(INavigationParameters parameters)
{
if(Connection_Item == null)
{
Connection_Item = parameters["instance"] as Connection;
await LoadData().ConfigureAwait(false);
}
}
#endregion
} }
} }

View File

@ -0,0 +1,9 @@
using FabAccessAPI;
namespace Borepin.Service
{
public interface IAPIService
{
IAPI GetAPI();
}
}

View File

@ -1,4 +1,5 @@
using Borepin.Model; using Borepin.Model;
using FabAccessAPI;
using Prism.Mvvm; using Prism.Mvvm;
namespace Borepin.ViewModel namespace Borepin.ViewModel
@ -6,16 +7,16 @@ namespace Borepin.ViewModel
public class ServerListItemViewModel : BindableBase public class ServerListItemViewModel : BindableBase
{ {
#region Constructors #region Constructors
public ServerListItemViewModel(Connection instance) public ServerListItemViewModel(ConnectionData instance)
{ {
Instance = instance; Instance = instance;
Address = instance.Address.Host; Address = instance.Host.Host;
Username = instance.Username; Username = instance.Username;
} }
#endregion #endregion
#region Fields #region Fields
public readonly Connection Instance; public readonly ConnectionData Instance;
private string _Address; private string _Address;
public string Address public string Address

View File

@ -1,6 +1,7 @@
using Capnp.Rpc; using Capnp.Rpc;
using FabAccessAPI.Exceptions; using FabAccessAPI.Exceptions;
using FabAccessAPI.Schema; using FabAccessAPI.Schema;
using NLog;
using S22.Sasl; using S22.Sasl;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -14,6 +15,10 @@ namespace FabAccessAPI
{ {
public class API : IAPI public class API : IAPI
{ {
#region Logger
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
#endregion
#region Private Members #region Private Members
private TcpRpcClient _TcpRpcClient; private TcpRpcClient _TcpRpcClient;
private IBootstrap _Bootstrap; private IBootstrap _Bootstrap;
@ -40,11 +45,14 @@ namespace FabAccessAPI
if (args.LastState == ConnectionState.Initializing && args.NewState == ConnectionState.Active) if (args.LastState == ConnectionState.Initializing && args.NewState == ConnectionState.Active)
{ {
Log.Trace("TcpRpcClient Event Connected");
eventHandler(this, ConnectionStatusChange.Connected); eventHandler(this, ConnectionStatusChange.Connected);
} }
if (args.LastState == ConnectionState.Active && args.NewState == ConnectionState.Down) if (args.LastState == ConnectionState.Active && args.NewState == ConnectionState.Down)
{ {
Log.Trace("TcpRpcClient Event ConnectionLoss");
eventHandler(this, ConnectionStatusChange.ConnectionLoss); eventHandler(this, ConnectionStatusChange.ConnectionLoss);
_TcpRpcClient = null;
} }
} }
#endregion #endregion
@ -98,11 +106,14 @@ namespace FabAccessAPI
Session = await _Authenticate(connectionData).ConfigureAwait(false); Session = await _Authenticate(connectionData).ConfigureAwait(false);
ConnectionData = connectionData; ConnectionData = connectionData;
Log.Info("API connected");
} }
catch(System.Exception) catch(System.Exception ex)
{ {
await Disconnect().ConfigureAwait(false); await Disconnect().ConfigureAwait(false);
throw; Log.Warn(ex, "API connecting failed");
throw ex;
} }
} }
@ -121,6 +132,8 @@ namespace FabAccessAPI
ConnectionStatusChanged?.Invoke(this, ConnectionStatusChange.Disconnected); ConnectionStatusChanged?.Invoke(this, ConnectionStatusChange.Disconnected);
Log.Info("API disconnected");
return Task.CompletedTask; return Task.CompletedTask;
} }
@ -132,6 +145,7 @@ namespace FabAccessAPI
} }
ConnectionStatusChanged?.Invoke(this, ConnectionStatusChange.Reconnected); ConnectionStatusChanged?.Invoke(this, ConnectionStatusChange.Reconnected);
Log.Info("API reconnected");
} }
public async Task<ConnectionInfo> TestConnection(ConnectionData connectionData, TcpRpcClient tcpRpcClient = null) public async Task<ConnectionInfo> TestConnection(ConnectionData connectionData, TcpRpcClient tcpRpcClient = null)

View File

@ -12,8 +12,8 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="CapnpC.CSharp.MsBuild.Generation" Version="1.3.118" /> <PackageReference Include="CapnpC.CSharp.MsBuild.Generation" Version="1.3.118" />
<PackageReference Include="log4net" Version="2.0.14" />
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="6.1.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="6.1.0" />
<PackageReference Include="NLog" Version="4.7.15" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -37,7 +37,7 @@ namespace FabAccessAPI
/// Connect to BFFH Server /// Connect to BFFH Server
/// </summary> /// </summary>
/// <param name="connectionData"></param> /// <param name="connectionData"></param>
Task Connect(ConnectionData connectionData, TcpRpcClient tcpRpcClient); Task Connect(ConnectionData connectionData, TcpRpcClient tcpRpcClient = null);
/// <summary> /// <summary>
/// Disconnect from BFFH Server /// Disconnect from BFFH Server
@ -53,6 +53,6 @@ namespace FabAccessAPI
/// Connect to Server and get ConnectionInfo. /// Connect to Server and get ConnectionInfo.
/// The Connection is not maintained. /// The Connection is not maintained.
/// </summary> /// </summary>
Task<ConnectionInfo> TestConnection(ConnectionData connectionData, TcpRpcClient tcpRpcClient); Task<ConnectionInfo> TestConnection(ConnectionData connectionData, TcpRpcClient tcpRpcClient = null);
} }
} }