Logik übertragen - weitere Ausarbeitung

This commit is contained in:
2024-06-06 15:42:04 +02:00
parent e2cf258f36
commit 3f9f42b593
15 changed files with 523 additions and 226 deletions

View File

@@ -89,7 +89,7 @@ namespace BeWoLauncher.Logic.Behavior
{
GenericTextLogger.Post(error);
ViewBehavior.ShowError(error);
ShowError(error);
}
}
@@ -108,7 +108,7 @@ namespace BeWoLauncher.Logic.Behavior
{
GenericTextLogger.Post(error);
ViewBehavior.ShowError(error);
ShowError(error);
}
}
@@ -124,7 +124,7 @@ namespace BeWoLauncher.Logic.Behavior
{
GenericTextLogger.Post(error);
ViewBehavior.ShowError(error);
ShowError(error);
}
}

View File

@@ -121,6 +121,7 @@ namespace BeWoLauncher.Logic.Controller
try
{
Manager.GetDeletePlan();
return null;
}
catch (Exception e)
@@ -140,7 +141,6 @@ namespace BeWoLauncher.Logic.Controller
}
return false;
}

View File

@@ -83,7 +83,7 @@ namespace BeWoLauncher.Logic.Utils
}
public static string GetLoggerPath()
{
return Path.Combine(new string[] { LauncherAppdataConfig.Location, "log" });
return Path.Combine(new string[] { LauncherAppdataConfig.Location, "log", "update" });
}
public static string GetDownloadPath()
{

View File

@@ -510,8 +510,12 @@
<Compile Include="ServiceUtils\Paths\ServerFilePaths.cs" />
<Compile Include="ServiceUtils\ServiceTranslator.cs" />
<Compile Include="ServiceUtils\Update\UpdateConfigReader.cs" />
<Compile Include="ServiceUtils\Update\UpdateFileLimiter.cs" />
<Compile Include="ServiceUtils\Update\UpdateFileResponseBuilder.cs" />
<Compile Include="ServiceUtils\Update\UpdatePlanResponseBuilder.cs" />
<Compile Include="ServiceUtils\Update\UpdateRequestValidator.cs" />
<Compile Include="ServiceUtils\Update\UpdateServerSession.cs" />
<Compile Include="ServiceUtils\Update\UpdateServerSessionManager.cs" />
<Compile Include="UnitOfWork\HibernateSessionEndpointBehavior.cs" />
<Compile Include="UnitOfWork\HibernateSessionBehaviorExtension.cs" />
<Compile Include="UnitOfWork\HibernateSessionContextInitializer.cs" />

View File

@@ -6,6 +6,7 @@ using System.IO;
using System.Linq;
using System.Net;
using System.ServiceModel;
using System.Threading;
using System.Xml;
using BeWo.Data;
using BeWo.Service.ServiceContracts;
@@ -22,8 +23,6 @@ namespace BeWo.Service.ServiceImplementations
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
public class DownloadBeWoServiceImp : IDownloadBeWoService
{
private string GETSERVER_URL = "https://support.bewoplaner.de/api/getserver.php?k={0}&t=0";
public string Tenant => MultitenancyOperationContextExt.Current.Tenant;
public UpdatePlanResponse GetUpdatePlan(UpdatePlanRequest request)
@@ -38,14 +37,10 @@ namespace BeWo.Service.ServiceImplementations
{
GenericTextLogger.Post("Validiere Plan Request.");
ValidatePlanRequest(request);
GenericTextLogger.Post("Plan Request erfolreich validiert. Verifiziere Login.");
VerifyLogin(request.Login);
GenericTextLogger.Post("Login verifiziert. Baue Antwort.");
UpdateRequestValidator.ValidatePlanRequest(request);
GenericTextLogger.Post("Plan Request erfolreich validiert. Baue Antwort.");
UpdatePlanResponseBuilder.BuildResponse(request, Tenant, response);
response.Successful = true;
@@ -77,69 +72,13 @@ namespace BeWo.Service.ServiceImplementations
response.Error = e.ToString();
}
if(response.Error is object)
{
Thread.Sleep(3000);
}
return response;
}
private void ValidatePlanRequest(UpdatePlanRequest request)
{
if (!TryValidatePlanRequest(request))
throw new UpdateException("Kann Request nicht bestätigen");
}
private bool TryValidatePlanRequest(UpdatePlanRequest request)
{
if (request.PlanerRootFolderExists)
{
// ...
}
else
{
// Root Folder ex. nicht
if (request.DownloadFolderExists)
return false;
if (!request.DownloadFolderIsEmpty)
return false;
if (request.ApplyFolderExists)
return false;
if (!request.ApplyFolderIsEmpty)
return false;
}
return true;
}
private void VerifyLogin(LoginDC login) => VerifyLogin(login.Username, login.Password, Tenant, login.Pin, login.ClientID);
private void VerifyLogin(string username, string password, string tenant, string pin, string clientid)
{
string server_address = string.Empty;
try
{
SessionInformation.Login.Username = username;
SessionInformation.Login.Password = password;
SessionInformation.Login.Tenant = tenant;
server_address = GetServerFromTenant();
#if DEBUG
server_address = "http://localhost:3777/Host";
#endif
ServiceFacade.UpdateServerAddresses(server_address);
var result = ServiceFacade.DoLauncherServiceSync(x => x.IsUserValid(username, password, pin, clientid, true));
if (result != BS.SharedLauncher.Enums.UserValidationResult.UserValid)
throw new HideClientUpdateException("Kann Anmeldung nicht bestätigen!");
}
catch (Exception e)
{
throw new HideClientUpdateException("Kann Anmeldung nicht bestätigen! ", e);
}
}
public UpdateFileResponse GetUpdateFile(UpdateFileRequest request)
{
GenericTextLogger.Init(ServerFilePaths.GetLogFolderPath(Tenant));
@@ -152,17 +91,13 @@ namespace BeWo.Service.ServiceImplementations
{
GenericTextLogger.Post("Validiere File Request.");
// ValidatePlanRequest(request);
UpdateRequestValidator.ValidateFileRequest(request);
GenericTextLogger.Post("Plan Request erfolreich validiert.");
GenericTextLogger.PostArrow($"File: {request.UpdateFile.RelativePath}");
GenericTextLogger.Post("Verifiziere Login.");
VerifyLogin(request.Login);
GenericTextLogger.Post("Login verifiziert. Baue Antwort.");
GenericTextLogger.Post("Baue Antwort.");
UpdateFileResponseBuilder.BuildResponse(request, Tenant, response);
@@ -195,43 +130,13 @@ namespace BeWo.Service.ServiceImplementations
response.Error = e.ToString();
}
if(response.Error is object)
{
Thread.Sleep(3000);
}
return response;
}
private bool isUpdateFileRequestValid(UpdateFileRequest request)
{
// Check for Login
// Check for Correct Version
// Check for File Permissions
return true;
}
private string GetServerFromTenant(string tenant = null)
{
if (tenant is null)
tenant = SessionInformation.Login.Tenant;
if (tenant == "demo")
return null;
try
{
String url = String.Format(GETSERVER_URL, tenant);
using (WebClient client = new WebClient())
{
//MessageBox.Show(hostAddress);
byte[] response = client.UploadValues(url, "POST", new NameValueCollection());
String server = System.Text.Encoding.ASCII.GetString(response);
return $"https://{server}/service";
}
}
catch (Exception ex)
{
throw new HideClientUpdateException("Login konnte nicht verifiziert werden.", ex);
}
}
public bool TestConnection()
{

View File

@@ -1,4 +1,6 @@
using System;
using BS.SharedLauncher.Enums;
using BS.SharedLauncher.Exceptions;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
@@ -58,10 +60,38 @@ namespace BeWo.Service.ServiceUtils.Paths
private static string GetVersionFolderPath(string version) => Path.Combine(VersionsFilePath, version);
public static string GetSpecialTenantFolderPath(string tenant) => Path.Combine(SpecialTenantFilesPath, tenant);
private static string GetSpecialTenantFolderPath(string tenant) => Path.Combine(SpecialTenantFilesPath, tenant);
private static string GetVersionTenantFolderPath(string version, string tenant) => Path.Combine(GetVersionFolderPath(version), tenant);
private static string GetVersionDefaultFolderPath(string version) => GetVersionTenantFolderPath(version, "default");
public static string GetVersionTenantFolderPath(string version, string tenant) => Path.Combine(GetVersionFolderPath(version), tenant);
public static string GetVersionDefaultFolderPath(string version) => GetVersionTenantFolderPath(version, "default");
public static string GetSourceFolderPath(UpdateFileSource source, string version, string tenant)
{
switch (source)
{
case UpdateFileSource.Invalid:
throw new UpdateException("Invalid UpdateFileSource");
case UpdateFileSource.VersionDefault:
return GetVersionDefaultFolderPath(version);
case UpdateFileSource.VersionTenant:
return GetVersionTenantFolderPath(version, tenant);
case UpdateFileSource.VersionUser:
break;
case UpdateFileSource.OverrideTenant:
return GetSpecialTenantFolderPath(tenant);
case UpdateFileSource.OverrideUser:
break;
default:
break;
}
// User bekommt eigene Daten Feature
throw new UpdateException("UpdateFileSourceType Unknown: " + source.ToString());
}
public static string GetLogFolderPath(string tenant) => Path.Combine(LogPath, tenant);
}

View File

@@ -1,4 +1,5 @@
using BS.SharedLauncher.Enums;
using BeWo.Service.ServiceUtils.Paths;
using BS.SharedLauncher.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -8,12 +9,34 @@ using System.Xml;
namespace BeWo.Service.ServiceUtils.Update
{
public class UpdateConfigReader
public static class UpdateConfigReader
{
private XmlDocument Document{ get; set; }
public static Tuple<string, string> GetDefaultTenantVersion(string tenant)
{
var reader = new UpdateConfigReaderClient(ServerFilePaths.UpdateConfigPath, tenant);
return new Tuple<string, string>(reader.GetDefaultVersion(), reader.GetSpecificVersion());
}
public static string GetValidVersion(string tenant)
{
var tuple = GetDefaultTenantVersion(tenant);
return GetValidVersion(tuple.Item1, tuple.Item2);
}
public static string GetValidVersion(string default_version, string tenant_version)
{
return tenant_version ?? default_version;
}
}
internal class UpdateConfigReaderClient
{
private XmlDocument Document { get; set; }
private string Tenant { get; set; }
public UpdateConfigReader(string configFilePath, string tenant)
internal UpdateConfigReaderClient(string configFilePath, string tenant)
{
Document = new XmlDocument();
Document.Load(configFilePath);
@@ -22,16 +45,16 @@ namespace BeWo.Service.ServiceUtils.Update
}
//public PlanerUpdateSource Source => GotSpecialVersion ? PlanerUpdateSource.SpecialVersion : PlanerUpdateSource.NewestVersion;
public string GetSpecificVersion()
{
try
{
return Document.SelectSingleNode($"/config/versions/tenant[@id='{Tenant}']/version")?.InnerXml;
return Document.SelectSingleNode($"/config/versions/tenant[@id='{Tenant}']/version").InnerXml;
}
catch (Exception)
{
return null;
return null;
}
}

View File

@@ -0,0 +1,23 @@
using BS.SharedLauncher.DataContract;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BeWo.Service.ServiceUtils.Update
{
public class UpdateFileLimiter
{
public UpdateFileDC UpdateFile { get; set; }
public int RequestsLeft { get; set; }
public bool CanRequestMore
{
get
{
return RequestsLeft > 0;
}
}
}
}

View File

@@ -18,59 +18,20 @@ namespace BeWo.Service.ServiceUtils.Update
private static string _Version;
private static string _Tenant;
private static UpdateFileRequest _Request;
private static UpdateFileResponse _Response;
public static void BuildResponse(UpdateFileRequest request, string tenant, UpdateFileResponse response)
{
_Response = response;
_Tenant = tenant;
_Request = request;
_Version = request.Version;
calculate();
calculate(request.UpdateFile.AbsolutePath);
}
private static void calculate()
private static void calculate(string path)
{
var relative_path = _Request.UpdateFile.RelativePath;
var path = Path.Combine(getSourceFolderPath(), relative_path);
var file_data = File.ReadAllBytes(path);
if (file_data.Length > 512 * 1024 * 1024 - 1)
throw new HideClientUpdateException($"Die angefragte File \"{relative_path}\" überschreitet die maximale Größe von 512 MB.");
_Response.FileData = file_data;
}
private static string getSourceFolderPath()
{
switch (_Request.UpdateFile.Source)
{
case BS.SharedLauncher.Enums.UpdateFileSource.Invalid:
throw new UpdateException("Invalid UpdateFileSource");
case BS.SharedLauncher.Enums.UpdateFileSource.VersionDefault:
return ServerFilePaths.GetVersionDefaultFolderPath(_Version);
case BS.SharedLauncher.Enums.UpdateFileSource.VersionTenant:
return ServerFilePaths.GetVersionTenantFolderPath(_Version, _Tenant);
case BS.SharedLauncher.Enums.UpdateFileSource.VersionUser:
break;
case BS.SharedLauncher.Enums.UpdateFileSource.OverrideTenant:
return ServerFilePaths.GetSpecialTenantFolderPath(_Tenant);
case BS.SharedLauncher.Enums.UpdateFileSource.OverrideUser:
break;
default:
break;
}
// User bekommt eigene Daten Feature
throw new HideClientUpdateException("#479839129");
_Response.FileData = File.ReadAllBytes(path);
}
}
}

View File

@@ -27,69 +27,35 @@ namespace BeWo.Service.ServiceUtils.Update
{
_Response = response;
var (default_version, tenant_version) = UpdateConfigReader.GetDefaultTenantVersion(tenant);
_Version = UpdateConfigReader.GetValidVersion(default_version, tenant_version);
_Tenant = tenant;
_Request = request;
ReadUpdateConfig(out string default_version, out string special_version);
_Response.CurrentPackage = new UpdatePlanDC
{
DefaultVersion = default_version,
TenantVersion = special_version
TenantVersion = tenant_version
};
_Version = _Response.CurrentPackage.Version;
// Lädt komplettes Paket ohne Hash
CalcFullPackage();
try
{
// Lädt komplettes Paket ohne Hash
CalcFullPackage();
// Lade Hash Werte
_Response.CurrentPackage.LoadHash();
// Lade Hash Werte
_Response.CurrentPackage.LoadHash();
CalcFilesToRequest();
CalcFilesToRequest();
if (!_Request.ApplyFolderIsEmpty)
CalcFilesToDeleteInApply();
if (!_Request.ApplyFolderIsEmpty)
CalcFilesToDeleteInApply();
if (!_Request.DownloadFolderIsEmpty)
CalcFilesToApplyInDownload();
if (!_Request.DownloadFolderIsEmpty)
CalcFilesToApplyInDownload();
CalcDownloadSize();
CalcDownloadSize();
}
catch(Exception e)
{
throw new HideClientUpdateException("Erstellprozess gescheitert", e);
}
}
private static void ReadUpdateConfig(out string default_version, out string special_version)
{
string path = GetUpdateConfigPath();
try
{
var reader = new UpdateConfigReader(path, _Tenant);
default_version = reader.GetDefaultVersion();
special_version = reader.GetSpecificVersion();
}
catch(Exception e)
{
throw new HideClientUpdateException($"Konnte UpdateConfig File für \"{_Tenant}\" nicht lesen.", e);
}
}
private static string GetUpdateConfigPath()
{
try
{
return ServerFilePaths.UpdateConfigPath;
}
catch (Exception e)
{
throw new HideClientUpdateException($"Konnte UpdateConfig Path für \"{_Tenant}\" nicht lesen.", e);
}
_Response.HasToDo = _Response.HasToDo();
}
private static void CalcFullPackage()
@@ -122,6 +88,7 @@ namespace BeWo.Service.ServiceUtils.Update
_Response.FilesToRequest.Add(file);
}
}
private static void CalcFilesToDeleteInApply()
{
foreach (var file in _Request.ApplyPackage.Files)
@@ -129,13 +96,14 @@ namespace BeWo.Service.ServiceUtils.Update
// Datei wird gebraucht
if (_Response.CurrentPackage.ContainsPlanerFile(file))
continue;
if (_Response.FilesToDeleteInApply is null)
_Response.FilesToDeleteInApply = new List<UpdateFileDC>();
_Response.FilesToDeleteInApply.Add(file);
}
}
private static void CalcFilesToApplyInDownload()
{
foreach (var file in _Request.DownloadedFiles)
@@ -150,6 +118,7 @@ namespace BeWo.Service.ServiceUtils.Update
_Response.FilesToApply.Add(file);
}
}
private static void CalcDownloadSize()
{
if (_Response.FilesToRequest is null || !_Response.FilesToRequest.Any())
@@ -166,13 +135,20 @@ namespace BeWo.Service.ServiceUtils.Update
_Response.DownloadSize = count;
}
private static List<UpdateFileDC> getVersionDefaultFiles(string version) => getPlanerFiles(ServerFilePaths.GetVersionDefaultFolderPath(version), UpdateFileSource.VersionDefault, false);
private static List<UpdateFileDC> getVersionTenantFiles(string version, string tenant) => getPlanerFiles(ServerFilePaths.GetVersionTenantFolderPath(version, tenant), UpdateFileSource.VersionTenant, true);
private static List<UpdateFileDC> getSpecialTenantFiles(string tenant) => getPlanerFiles(ServerFilePaths.GetSpecialTenantFolderPath(tenant), UpdateFileSource.OverrideTenant, true);
private static List<UpdateFileDC> getVersionDefaultFiles(string version)
=> getPlanerFiles(ServerFilePaths.GetSourceFolderPath(UpdateFileSource.VersionDefault, version, null),
UpdateFileSource.VersionDefault, false);
private static List<UpdateFileDC> getVersionTenantFiles(string version, string tenant)
=> getPlanerFiles(ServerFilePaths.GetSourceFolderPath(UpdateFileSource.VersionTenant, version, tenant),
UpdateFileSource.VersionTenant, true);
private static List<UpdateFileDC> getSpecialTenantFiles(string tenant)
=> getPlanerFiles(ServerFilePaths.GetSourceFolderPath(UpdateFileSource.OverrideTenant, null, tenant),
UpdateFileSource.OverrideTenant, true);
private static List<UpdateFileDC> getPlanerFiles(string path, UpdateFileSource source, bool ignoreOnError)
{
if (!Directory.Exists(path)) {
if (!Directory.Exists(path))
{
if (ignoreOnError)
return new List<UpdateFileDC>();
else
@@ -190,6 +166,9 @@ namespace BeWo.Service.ServiceUtils.Update
if (update.GetExtensionType() == ".xml")
return true;
if (update.GetExtensionType() == ".pdb")
return true;
return false;
}
}

View File

@@ -0,0 +1,201 @@
using BeWo.Data;
using BeWo.Service.ServiceProxy;
using BS.SharedLauncher.DataContract;
using BS.SharedLauncher.Enums;
using BS.SharedLauncher.Exceptions;
using BS.SharedLauncher.Information;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace BeWo.Service.ServiceUtils.Update
{
public static class UpdateRequestValidator
{
private static string GETSERVER_URL = "https://support.bewoplaner.de/api/getserver.php?k={0}&t=0";
public static string Tenant => MultitenancyOperationContextExt.Current.Tenant;
public static void ValidatePlanRequest(UpdatePlanRequest request)
{
ValidateLogin(request);
if (!TryValidatePlanRequestProperties(request))
throw new HideClientUpdateException("Kann Request nicht bestätigen");
}
public static void ValidateFileRequest(UpdateFileRequest request)
{
if (!TryValidateFileRequestProperties(request))
throw new HideClientUpdateException("Kann Request nicht bestätigen");
if (!TryValidateVersion(request, Tenant))
throw new HideClientUpdateException("Kann Request nicht bestätigen");
if (!TryValidateSource(request))
throw new HideClientUpdateException("Kann Request nicht bestätigen");
ValidateSession(request, Tenant);
}
private static bool TryValidatePlanRequestProperties(UpdatePlanRequest request)
{
if (request.PlanerRootFolderExists)
{
// ...
}
else
{
// Root Folder ex. nicht
if (request.DownloadFolderExists)
return false;
if (!request.DownloadFolderIsEmpty)
return false;
if (request.ApplyFolderExists)
return false;
if (!request.ApplyFolderIsEmpty)
return false;
}
return true;
}
private static void ValidateLogin(UpdatePlanRequest request) => ValidateLogin(request.Login);
private static void ValidateLogin(LoginDC login) => ValidateLogin(login.Username, login.Password, Tenant, login.Pin, login.ClientID);
private static void ValidateLogin(string username, string password, string tenant, string pin, string clientid)
{
string server_address = string.Empty;
try
{
SessionInformation.Login.Username = username;
SessionInformation.Login.Password = password;
SessionInformation.Login.Tenant = tenant;
server_address = GetServerFromTenant();
#if DEBUG
server_address = "http://localhost:3777/Host";
#endif
ServiceFacade.UpdateServerAddresses(server_address);
var result = ServiceFacade.DoLauncherServiceSync(x => x.IsUserValid(username, password, pin, clientid, true));
if (result != UserValidationResult.UserValid)
throw new HideClientUpdateException("Kann Anmeldung nicht bestätigen! Result: " + result.ToString());
}
catch (Exception e)
{
throw new HideClientUpdateException("Kann Anmeldung nicht bestätigen! ", e);
}
}
private static bool TryValidateFileRequestProperties(UpdateFileRequest request)
{
if (string.IsNullOrWhiteSpace(request.UpdateSessionId))
return false;
if (string.IsNullOrWhiteSpace(request.Version))
return false;
if (request.UpdateFile is null)
return false;
if (string.IsNullOrWhiteSpace(request.UpdateFile.RelativePath))
return false;
return true;
}
private static bool TryValidateVersion(UpdateFileRequest request, string tenant)
{
var version_config = UpdateConfigReader.GetValidVersion(tenant);
return request.Version == version_config;
}
private static bool TryValidateSource(UpdateFileRequest request)
{
switch (request.UpdateFile.Source)
{
case UpdateFileSource.Invalid:
return false;
case UpdateFileSource.VersionDefault:
break;
case UpdateFileSource.VersionTenant:
break;
case UpdateFileSource.VersionUser:
return false;
case UpdateFileSource.OverrideTenant:
break;
case UpdateFileSource.OverrideUser:
return false;
default:
return false;
}
return true;
}
private static void ValidateSession(UpdateFileRequest request, string tenant)
{
var error = TryValidateSession(request, tenant);
if (!string.IsNullOrWhiteSpace(error))
throw new HideClientUpdateException(error);
}
private static string TryValidateSession(UpdateFileRequest request, string tenant)
{
var session = UpdateServerSessionManager.CurrentSession(request.UpdateSessionId);
if (session is null)
return $"Session \"{request.UpdateSessionId}\" nicht verfügbar";
if (session.Tenant != tenant)
return $"Tenant konnte nicht bestätigt werden. {session.Tenant} != {tenant}";
if (!session.FileLimiterDict.ContainsKey(
request.UpdateFile.RelativePath))
return $"Angefragte Datei nicht verfügbar. Anfrage an \"{request.UpdateFile.RelativePath}\"";
if (session.IsTimeouted)
return $"Session \"{request.UpdateSessionId}\" nicht mehr verfügbar - Timeout";
return null;
}
private static string GetServerFromTenant(string tenant = null)
{
if (tenant is null)
tenant = SessionInformation.Login.Tenant;
if (tenant == "demo")
return null;
try
{
String url = String.Format(GETSERVER_URL, tenant);
using (WebClient client = new WebClient())
{
//MessageBox.Show(hostAddress);
byte[] response = client.UploadValues(url, "POST", new NameValueCollection());
String server = System.Text.Encoding.ASCII.GetString(response);
return $"https://{server}/service";
}
}
catch (Exception ex)
{
throw new HideClientUpdateException("Login konnte nicht verifiziert werden.", ex);
}
}
}
}

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BeWo.Service.ServiceUtils.Update
{
public class UpdateServerSession
{
public string Id { get; set; }
public string Tenant { get; set; }
public DateTime Created { get; set; }
public DateTime Timeout { get; set; }
public Dictionary<string, UpdateFileLimiter> FileLimiterDict { get; set; }
public bool IsTimeouted => Timeout < DateTime.Now;
}
}

View File

@@ -0,0 +1,145 @@
using BS.SharedLauncher.DataContract;
using BS.SharedLauncher.Exceptions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace BeWo.Service.ServiceUtils.Update
{
public static class UpdateServerSessionManager
{
private static string _Lock => string.Empty;
private static readonly Dictionary<string, UpdateServerSession> _UpdateServerSessions = new Dictionary<string, UpdateServerSession>();
public static UpdateServerSession CurrentSession(string session_id)
{
try
{
Monitor.Enter(_Lock);
return _UpdateServerSessions.TryGetValue(session_id, out var session) ? session : null;
}
catch (Exception e)
{
throw new FaultException(e.StackTrace + e.InnerException != null ? e.InnerException.Message : string.Empty);
}
finally
{
Monitor.Exit(_Lock);
}
}
public static string GenerateUniqueSessionId()
{
var session_id = Guid.NewGuid().ToString();
if (_UpdateServerSessions.ContainsKey(session_id))
return GenerateUniqueSessionId();
return session_id;
}
public static void CreateSession(UpdatePlanResponse res, string tenant)
{
try
{
Monitor.Enter(_Lock);
var session_id = GenerateUniqueSessionId();
if (_UpdateServerSessions.ContainsKey(session_id))
throw new UpdateException("session id generation error");
var session = new UpdateServerSession()
{
Id = session_id,
Tenant = tenant,
Created = DateTime.Now,
Timeout = DateTime.Now.AddMinutes(10),
FileLimiterDict = res.FilesToRequest.ToDictionary(file => file.RelativePath, file => new UpdateFileLimiter()
{
RequestsLeft = 5,
UpdateFile = file
})
};
_UpdateServerSessions.Add(session_id, session);
res.Session_Id = session_id;
}
finally
{
Monitor.Exit(_Lock);
}
}
public static void CloseSession(string session_id)
{
try
{
Monitor.Enter(_Lock);
_UpdateServerSessions.Remove(session_id);
CheckForTimeoutSessions();
}
finally
{
Monitor.Exit(_Lock);
}
}
public static void CheckForTimeoutSessions()
{
try
{
Monitor.Enter(_Lock);
foreach (var key_pair in _UpdateServerSessions)
{
var session_id = key_pair.Key;
var session = key_pair.Value;
if (session.IsTimeouted)
_UpdateServerSessions.Remove(session_id);
}
}
finally
{
Monitor.Exit(_Lock);
}
}
public static void LoadAbsolutePath(UpdateFileRequest request)
{
try
{
Monitor.Enter(_Lock);
var file_id = request.UpdateFile.RelativePath;
var session_id = request.UpdateSessionId;
var session = _UpdateServerSessions[session_id];
var limiter = session.FileLimiterDict[file_id];
request.UpdateFile.AbsolutePath = limiter.UpdateFile.AbsolutePath;
limiter.RequestsLeft--;
if (!limiter.CanRequestMore)
session.FileLimiterDict.Remove(file_id);
if (!session.FileLimiterDict.Any())
CloseSession(session_id);
}
finally
{
Monitor.Exit(_Lock);
}
}
}
}

View File

@@ -18,18 +18,19 @@ namespace BS.SharedLauncher.DataContract
}
public UpdateFileRequest(string version) : base()
public UpdateFileRequest(string version, string session_id) : base()
{
Version = version;
UpdateSessionId = session_id;
}
[DataMember]
public string Version { get; set; }
[DataMember]
public UpdateFileDC UpdateFile { get; set; }
public string UpdateSessionId { get; set; }
[DataMember]
public LoginDC Login { get; set; }
public UpdateFileDC UpdateFile { get; set; }
}
}

View File

@@ -21,9 +21,15 @@ namespace BS.SharedLauncher.DataContract
}
[DataMember]
public string Session_Id { get; set; }
[DataMember]
public UpdatePlanDC CurrentPackage { get; set; }
[DataMember]
public bool HasToDo { get; set; }
[DataMember]
public List<UpdateFileDC> FilesToRequest { get; set; }