123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- using System;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading;
- using InABox.Clients;
- using InABox.Core;
- namespace InABox.Rpc
- {
-
- public class RpcClient<TEntity> : BaseClient<TEntity> where TEntity : Entity, new()
- {
- private IRpcClientTransport _transport;
- private ConcurrentDictionary<Guid, ManualResetEventSlim> _events = new ConcurrentDictionary<Guid, ManualResetEventSlim>();
- private ConcurrentDictionary<Guid, RpcMessage> _responses = new ConcurrentDictionary<Guid, RpcMessage>();
- private const int DefaultRequestTimeout = 5 * 60 * 1000; // 5 minutes
-
- public RpcClient(IRpcClientTransport transport)
- {
- _transport = transport;
- _transport.OnMessage += Transport_Message;
- }
- ~RpcClient()
- {
- _transport.OnMessage -= Transport_Message;
- }
-
- #region TransportManagement
- public override bool IsConnected() => _transport?.IsConnected() == true;
-
- private void Transport_Message(IRpcTransport transport, RpcTransportMessageArgs e)
- {
- if (e.Message != null && e.Message.Command == "Push")
- {
- var push = Serialization.ReadBinary<RpcPush>(e.Message.Payload, BinarySerializationSettings.Latest);
- ClientFactory.PushHandlers.Push(push.Type, push.Object);
- }
- }
- #endregion
- #region Client Interface
- public override DatabaseInfo Info()
- {
- var result = _transport.Send<RpcInfoCommand, RpcInfoParameters, RpcInfoResult>(new RpcInfoParameters());
- return result.Info;
- }
- private static string[]? _types;
- public override IEnumerable<string> SupportedTypes()
- {
- _types ??= CoreUtils.Entities
- .Where(x => x.GetInterfaces().Contains(typeof(IPersistent)))
- .Select(x => x.EntityName().Replace(".", "_"))
- .ToArray();
- return _types;
- }
-
- #region Validate & 2FA
- protected override IValidationData DoValidate(string userid, string password, Guid session = default)
- {
- var parameters = new RpcValidateParameters()
- {
- UserID = userid,
- Password = password,
- PIN = "",
- UsePIN = false,
- SessionID = session,
- Platform = ClientFactory.Platform,
- Version = ClientFactory.Version
- };
- return _transport.Send<RpcValidateCommand, RpcValidateParameters, RpcValidateResult>(parameters);
- }
- protected override IValidationData DoValidate(string pin, Guid session = default)
- {
- var ticks = DateTime.Now.ToUniversalTime().Ticks.ToString();
- var parameters = new RpcValidateParameters()
- {
- UserID = Encryption.Encrypt(ticks, "wCq9rryEJEuHIifYrxRjxg", true),
- Password = Encryption.Encrypt(ticks, "7mhvLnqMwkCAzN+zNGlyyg", true),
- PIN = pin,
- UsePIN = true,
- SessionID = session,
- Platform = ClientFactory.Platform,
- Version = ClientFactory.Version
- };
- return _transport.Send<RpcValidateCommand, RpcValidateParameters, RpcValidateResult>(parameters);
- }
- protected override IValidationData DoValidate(Guid session = default)
- {
- var parameters = new RpcValidateParameters()
- {
- UserID = "",
- Password = "",
- PIN = "",
- UsePIN = false,
- SessionID = session,
- Platform = ClientFactory.Platform,
- Version = ClientFactory.Version
- };
- return _transport.Send<RpcValidateCommand, RpcValidateParameters, RpcValidateResult>(parameters);
- }
-
- protected override bool DoCheck2FA(string code, Guid? session)
- {
- var parameters = new RpcCheck2FAParameters()
- {
- Code = code,
- SessionId = session ?? ClientFactory.SessionID,
- };
- var result = _transport.Send<RpcCheck2FACommand, RpcCheck2FAParameters, RpcCheck2FAResult>(parameters);
- return result.Valid;
- }
-
- #endregion
- protected override CoreTable DoQuery(Filter<TEntity>? filter, Columns<TEntity>? columns, SortOrder<TEntity>? sort = null, CoreRange? range = null)
- {
- var parameters = new RpcQueryParameters()
- {
- Queries = new RpcQueryDefinition[]
- {
- new RpcQueryDefinition()
- {
- Key = typeof(TEntity).EntityName().Split('.').Last(),
- Type = typeof(TEntity),
- Filter = filter,
- Columns = columns,
- Sort = sort,
- Range = range
- }
- }
- };
- var result = _transport.Send<RpcQueryCommand, RpcQueryParameters, RpcQueryResult>(parameters);
- return result.Tables[0].Table;
- }
- protected override TEntity[] DoLoad(Filter<TEntity>? filter = null, SortOrder<TEntity>? sort = null, CoreRange? range = null)
- {
- return DoQuery(filter, null, sort, range)?.ToArray<TEntity>() ?? new TEntity[] { };
- }
-
-
- protected override Dictionary<string, CoreTable> DoQueryMultiple(Dictionary<string, IQueryDef> queries)
- {
- var result = new Dictionary<string, CoreTable>();
-
- var parameters = new RpcQueryParameters()
- {
- Queries = queries.Select(kvp =>
- new RpcQueryDefinition()
- {
- Key = kvp.Key,
- Type = kvp.Value.Type,
- Filter = kvp.Value.Filter,
- Columns = kvp.Value.Columns,
- Sort = kvp.Value.SortOrder,
- Range = kvp.Value.Range
- }
- ).ToArray()
- };
- var response = _transport.Send<RpcQueryCommand, RpcQueryParameters, RpcQueryResult>(parameters);
- foreach (var key in response.Tables)
- result[key.Key] = key.Table;
- return result;
- }
- protected override void DoSave(TEntity entity, string auditnote)
- {
- DoSave(new TEntity[] { entity }, auditnote);
- }
- protected override void DoSave(IEnumerable<TEntity> entities, string auditnote)
- {
- var items = entities.AsArray();
- var parameters = new RpcSaveParameters()
- {
- Type = typeof(TEntity),
- Items = items,
- AuditNote = auditnote
- };
- var result = _transport.Send<RpcSaveCommand, RpcSaveParameters, RpcSaveResult>(parameters);
- for (int i = 0; i < result.Deltas.Length; i++)
- {
- items[i].SetObserving(false);
- foreach (var (key, value) in result.Deltas[i])
- {
- if (CoreUtils.TryGetProperty<TEntity>(key, out var property))
- CoreUtils.SetPropertyValue(items[i], key, CoreUtils.ChangeType(value, property.PropertyType));
- }
- items[i].CommitChanges();
- items[i].SetObserving(true);
- }
- }
- protected override void DoDelete(TEntity entity, string auditnote)
- {
- DoDelete(new TEntity[] { entity }, auditnote);
- }
- protected override void DoDelete(IEnumerable<TEntity> entities, string auditnote)
- {
- var parameters = new RpcDeleteParameters()
- {
- Type = typeof(TEntity),
- IDs = entities.Select(x => x.ID).ToArray(),
- AuditNote = auditnote
- };
- _transport.Send<RpcDeleteCommand, RpcDeleteParameters, RpcDeleteResult>(parameters);
- }
-
- protected override bool DoPing()
- {
- try
- {
- if (!_transport.IsConnected())
- _transport.Connect();
- if (_transport.IsConnected())
- {
- _transport.Send<RpcPingCommand, RpcPingParameters, RpcPingResult>(new RpcPingParameters());
- return true;
- }
- return false;
- }
- catch (Exception)
- {
- return false;
- }
-
- }
- public override string Version()
- {
- return _transport.Send<RpcVersionCommand, RpcVersionParameters, RpcVersionResult>(new RpcVersionParameters()).Version;
- }
- public override byte[]? Installer()
- {
- return _transport.Send<RpcInstallerCommand, RpcInstallerParameters, RpcInstallerResult>(new RpcInstallerParameters()).Installer;
- }
- public override string ReleaseNotes()
- {
- return _transport.Send<RpcReleaseNotesCommand, RpcReleaseNotesParameters, RpcReleaseNotesResult>(new RpcReleaseNotesParameters()).ReleaseNotes;
- }
- #endregion
- }
- }
|