2using System.Collections.Generic;
4using System.Reflection;
6using System.Threading.Tasks;
53 private readonly Dictionary<string, NodeStatus> nodeStatus =
new Dictionary<string, NodeStatus>();
54 private readonly Dictionary<string, bool> loading =
new Dictionary<string, bool>();
60 private readonly
bool internalScheduler;
77 this.webServer = WebServer;
78 this.e2eEncryption = E2eEncryption;
86 this.internalScheduler =
false;
91 this.internalScheduler =
true;
94 this.webServer.Register(this.blockResource =
new BlockResource(
"/NL/B", this.provider, this.
client,
this, this.webServer,
"User"));
95 this.blockListResource = this.webServer.Register(
new BlockListResource(
"/NL/L", this.
client, this.webServer,
"User"));
96 this.multiGetResource = this.webServer.Register(
new MultiGetResource(
"/NL/MG", this.
client, this.webServer,
"User"));
115 this.client.OnStateChanged += this.Client_OnStateChanged;
116 this.client.OnPresence += this.Client_OnPresence;
120 Task _ = this.ResendPresences();
129 private async Task ResendPresences()
134 await this.Client_OnPresence(this.
client, e);
144 Task _ = Task.Run(() => this.
SynchronizePeer(PeerStatus,
false,
null));
159 return "Peer not a Neuro-Ledger node.";
163 lock (this.nodeStatus)
176 BareJid = PeerStatus.BareJid
185 lock (this.nodeStatus)
199 if (!(ToDelete is
null))
204 NodeStatus.LastBlockId =
string.Empty;
234 BareJid = e.FromBareJID
260 string[] Features =
new string[e2.
Features.Count];
261 e2.
Features.Keys.CopyTo(Features, 0);
266 PeerStatus.Features = Features;
271 PeerStatus.RequestingCapabilitiesFunction =
string.Empty;
272 PeerStatus.RequestingCapabilitiesNode =
string.Empty;
273 PeerStatus.RequestingCapabilitiesVersion =
string.Empty;
290 PeerStatus.IsSynchronizing =
false;
297 bool IgnoreIfRunning,
bool Repopulate)
309 PeerStatus.IsSynchronizing =
true;
314 DateTime LastReported = DateTime.Now;
320 List<BlockReference> Blocks =
new List<BlockReference>();
321 Dictionary<string, bool> Collections =
new Dictionary<string, bool>();
323 List<KeyValuePair<BlockReference, string>> Bulk =
new List<KeyValuePair<BlockReference, string>>();
329 LastReported = await this.UpdateStatus(LastReported, Status, Callback);
331 XmlElement Result = await this.GetBlockList(
NodeStatus.
BareJid, LastId, MaxCount);
333 if (Result is
null || Result.LocalName !=
"blockReferences" || Result.NamespaceURI !=
NeuroLedgerNamespace)
337 foreach (XmlNode N
in Result.ChildNodes)
344 LastReported = await this.UpdateStatus(LastReported, Status, Callback);
354 Bulk.Add(
new KeyValuePair<BlockReference, string>(Ref,
Event.Url));
355 BulkSize += Ref.
Bytes;
357 if (Bulk.Count >= 100 || BulkSize >= 16 * 1024 * 1024)
359 await this.BulkLoad(
PeerStatus, Bulk.ToArray(), LastReported, Status, Callback,
false, Blocks);
370 More = Count >= MaxCount;
375 await this.BulkLoad(
PeerStatus, Bulk.ToArray(), LastReported, Status, Callback,
false, Blocks);
377 if (Blocks.Count > 0)
381 List<BlockReference> Subset =
new List<BlockReference>();
382 List<ObjectState> ObjectsInBlock =
new List<ObjectState>();
385 foreach (
string Collection
in Collections.Keys)
398 if (Subset.Count == 0)
423 ObjectsInBlock.Reverse();
428 LastReported = await this.UpdateStatus(LastReported, Status, Callback);
447 Log.
Error(
"Unable to enumerate objects in block properly when repairing collection:\r\n\r\n" +
448 ex.Message, TempBlockEnumerator.
Current.FileName,
string.Empty,
string.Empty,
450 new KeyValuePair<string, object>(
"Collection", Collection));
463 ObjectsInBlock.Clear();
473 this.externalEvents?.RaiseCollectionCleared(Collection);
481 Tuple<uint, uint, uint, uint> Counts = await this.provider.
Process(ObjectEvents, Collection);
483 Status.ObjectsAdded += Counts.Item1;
484 Status.ObjectsUpdated += Counts.Item2;
485 Status.ObjectsDeleted += Counts.Item3;
486 Status.ObjectErrors += Counts.Item4;
488 LastReported = await this.UpdateStatus(LastReported, Status, Callback);
499 NodeStatus.LastBlockId = LastId;
511 foreach (
string Source
in Ref.
Sources)
518 Uri Uri =
new Uri(Source);
521 LastReported = await this.UpdateStatus(LastReported, Status, Callback);
522 await this.RetrieveBlock(Ref, Source, Status,
true);
542 foreach (
string Source
in Ref.
Sources)
549 Uri Uri =
new Uri(Source);
552 LastReported = await this.UpdateStatus(LastReported, Status, Callback);
553 await this.RetrieveBlock(Ref, Source, Status,
true);
576 PeerStatus.IsSynchronizing =
false;
580 await this.UpdateStatus(DateTime.MinValue, Status, Callback);
589 bool Unpack, List<BlockReference> Blocks)
596 StringBuilder Csv =
new StringBuilder();
598 foreach (KeyValuePair<BlockReference, string>
Item in Resources)
602 Csv.Append(
Item.Value);
603 Csv.AppendLine(
",application/octet-stream");
608 Encoding.UTF8.GetBytes(Csv.ToString()),
"text/csv; charset=utf-8",
609 new KeyValuePair<string, string>(
"Accept",
"multipart/mixed"));
623 LastReported = await this.UpdateStatus(LastReported, Status, Callback);
626 KeyValuePair<BlockReference, string> P =
Resources[i++];
628 string Url = P.Value;
630 if (!
int.TryParse(Content.
Description, out
int StatusCode))
632 Status?.IncBlockError(Url,
"Invalid content description: " + Content.
Description);
636 if (StatusCode == 200)
641 if (this.provider is
null)
643 Log.
Warning(
"Bulk loading of blocks aborted. Neuro-Ledger closed.");
647 using (MemoryStream ms =
new MemoryStream(Block))
656 Ref.AccessDenied =
false;
660 if (!(Status is
null))
663 Status.LoadedBytes += Ref.
Bytes;
667 await this.UnpackObjects(Ref, Status);
671 else if (StatusCode == HTTP.ForbiddenException.Code ||
672 StatusCode == HTTP.FailedDependencyException.Code)
678 Ref.AccessDenied =
true;
682 if (!(Status is
null))
685 else if (StatusCode == HTTP.NotFoundException.Code)
689 if (Ref.
Creator ==
this.provider.ExternalIdentity &&
690 Content.
Decoded is
string ErrorMsg &&
695 if (!(Status is
null))
699 Status?.IncBlockError(Url, Msg);
703 await this.
client.
Warning(Msg =
"Unable to retrieve block. Trying again later. Error reported: " + StatusCode.ToString() +
", " + Content.
Decoded?.ToString());
704 this.scheduler?.
Add(DateTime.Now.AddHours(1),
this.RetryProcessing,
new object[] { Ref, Url });
706 Status?.IncBlockError(Url, Msg);
713 await this.
client.Error(Msg =
"Unable to retrieve blocks. Error reported: " + ex.Message);
718 private async Task<XmlElement> GetBlockList(
string Jid,
string LastBlockId,
int MaxCount)
720 StringBuilder Url =
new StringBuilder();
722 Url.Append(
"httpx://");
724 Url.Append(
"/NL/L?Max=");
725 Url.Append(MaxCount.ToString());
727 if (!
string.IsNullOrEmpty(LastBlockId))
729 Url.Append(
"&Last=");
730 Url.Append(LastBlockId);
738 XmlDocument Doc =
new XmlDocument();
743 return Doc.DocumentElement;
747 private async Task<DateTime> UpdateStatus(DateTime LastReported,
SynchronizationStatus Status, CallbackAsync<SynchronizationStatus> Callback)
749 DateTime TP = DateTime.Now;
750 if ((TP - LastReported).TotalSeconds > 1)
753 if (!(Callback is
null))
757 await Callback(Status);
761 Status?.IncBlockError(
string.Empty, ex.Message);
769 private async Task GetBlockReferences(
object Sender,
IqEventArgs e)
782 await e.
IqError(
new ForbiddenException(
"You must have an active presence subscription to the node to request information.", e.
IQ));
789 IEnumerable<BlockReference> Blocks;
794 if (
string.IsNullOrEmpty(Last))
806 StringBuilder Xml =
new StringBuilder();
808 Xml.Append(
"<blockReferences xmlns=\"");
813 Xml.Append(
" more=\"true\"");
824 Xml.Append(
"<ref id='");
828 Xml.Append(Convert.ToBase64String(Ref.
Digest));
830 Xml.Append(Convert.ToBase64String(Ref.
Signature));
832 if (!(Ref.
Link is
null))
835 Xml.Append(Convert.ToBase64String(Ref.
Link));
838 Xml.Append(
"' cn='");
840 Xml.Append(
"' cr='");
842 Xml.Append(
"' ct='");
845 if (Ref.
Updated != DateTime.MinValue)
851 if (Ref.
Expires != DateTime.MaxValue)
860 Xml.Append(Ref.
Status.ToString());
864 Xml.Append(
"httpx://");
866 Xml.Append(
"/NL/B/");
869 Xml.Append(Ref.
Bytes.ToString());
873 Xml.Append(
"</blockReferences>");
881 private Task Client_OnStateChanged(
object Sender,
XmppState NewState)
884 Task.Run(() => this.CheckOutgoingEvents());
886 return Task.CompletedTask;
889 private async Task CheckOutgoingEvents()
893 IEnumerable<OutgoingEvent> Events;
908 if (this.pepClient is
null)
931 if (!(this.provider is
null))
933 this.webServer.Unregister(this.blockResource);
934 this.webServer.Unregister(this.blockListResource);
935 this.webServer.Unregister(this.multiGetResource);
940 this.client.OnStateChanged -= this.Client_OnStateChanged;
941 this.client.OnPresence -= this.Client_OnPresence;
950 if (this.internalScheduler)
953 this.scheduler =
null;
956 this.peerStatus =
null;
958 this.provider =
null;
959 this.pepClient =
null;
992 T =
this.Queue(
Event);
994 return Task.CompletedTask;
999 T = this.Queue(
Event);
1001 return Task.CompletedTask;
1009 Event.Created = Block.
Created;
1010 Event.Creator = Block.
Creator;
1011 Event.Digest = Block.
Digest;
1012 Event.Expires = Block.
Expires;
1013 Event.Link = Block.
Link;
1015 Event.Status = Block.
Status;
1016 Event.Updated = Block.
Updated;
1017 Event.Bytes = Block.
Bytes;
1026 this.Fill(
Event, e);
1033 T =
this.Queue(
Event);
1035 return Task.CompletedTask;
1040 T = this.Queue(
Event);
1042 return Task.CompletedTask;
1049 lock (this.processingQueue)
1051 if (this.processing)
1053 this.processingQueue.AddLast(
Event);
1057 this.processing =
true;
1064 await this.Process(
Event,
null);
1070 catch (Exception ex)
1075 lock (this.processingQueue)
1077 if (this.processingQueue.First is
null)
1080 this.processing =
false;
1084 Event = this.processingQueue.First.Value;
1085 this.processingQueue.RemoveFirst();
1089 while (!(
Event is
null));
1093 private readonly LinkedList<BlockAdded> processingQueue =
new LinkedList<BlockAdded>();
1094 private bool processing =
false;
1100 await this.RetrieveBlock(Ref,
Event.Url, Status,
true);
1105 if (!(Status is
null))
1108 Status.TotalBytes +=
Event.Bytes;
1111 Status.First =
Event.Created;
1114 Status.Last =
Event.Created;
1123 Collection =
Event.Collection,
1124 Created =
Event.Created,
1125 Creator =
Event.Creator,
1126 Digest =
Event.Digest,
1127 Expires =
Event.Expires,
1129 Signature =
Event.Signature,
1130 Status =
Event.Status,
1131 Updated =
Event.Updated,
1132 Bytes =
Event.Bytes,
1133 Sources =
new string[] { Event.Url },
1134 AccessDenied =
false,
1140 if (!(Status is
null))
1147 bool Updated =
false;
1148 bool Changed =
false;
1150 if (Ref.
Creator !=
this.provider?.ExternalIdentity &&
1163 Ref.Collection =
Event.Collection;
1164 Ref.Created =
Event.Created;
1165 Ref.Creator =
Event.Creator;
1166 Ref.Expires =
Event.Expires;
1167 Ref.Digest =
Event.Digest;
1168 Ref.Link =
Event.Link;
1169 Ref.Signature =
Event.Signature;
1170 Ref.Status =
Event.Status;
1171 Ref.Updated =
Event.Updated;
1172 Ref.Bytes =
Event.Bytes;
1173 Ref.AccessDenied =
false;
1180 int c = Ref.
Sources?.Length ?? 0;
1182 string[] s =
new string[c + 1];
1184 Array.Copy(Ref.
Sources, 0, s, 0, c);
1191 if (Updated || Changed)
1195 if (!(Status is
null))
1198 if (Changed || !NullIfNotChanged)
1203 else if (
string.IsNullOrEmpty(Ref.
FileName) || !NullIfNotChanged)
1210 private static bool Compare(
byte[] A1,
byte[] A2)
1212 if ((A1 is
null) ^ (A2 is
null))
1218 int i, c = A1.Length;
1222 for (i = 0; i < c; i++)
1233 string FileName = this.provider?.GetFullFileName(Ref.
FileName);
1235 if (
string.IsNullOrEmpty(Ref.
FileName) || !File.Exists(FileName))
1237 string Key = Convert.ToBase64String(Ref.
Digest);
1241 if (this.loading.ContainsKey(Key))
1244 this.loading[Key] =
true;
1247 KeyValuePair<string, TemporaryStream> Resource;
1255 new KeyValuePair<string, string>(
"Accept",
"application/octet-stream"));
1256 File = Resource.Value;
1266 Ref.AccessDenied =
false;
1270 if (!(Status is
null))
1273 Status.LoadedBytes += Ref.
Bytes;
1277 await this.UnpackObjects(Ref, Status);
1281 catch (HTTP.ForbiddenException ex)
1283 string ErrorMessage = await this.GetErrorMessage(ex);
1289 Ref.AccessDenied =
true;
1293 if (!(Status is
null))
1298 catch (HTTP.FailedDependencyException ex)
1300 string ErrorMessage = await this.GetErrorMessage(ex);
1306 Ref.AccessDenied =
true;
1310 if (!(Status is
null))
1315 catch (HTTP.NotFoundException ex)
1317 string ErrorMessage = await this.GetErrorMessage(ex);
1325 if (!(Status is
null))
1331 catch (Exception ex)
1333 await this.
client.
Warning(
"Unable to retrieve block. Trying again later. Error reported: " + ex.Message +
" (" + ex.GetType().FullName +
")");
1334 this.scheduler?.
Add(DateTime.Now.AddHours(1),
this.RetryProcessing,
new object[] { Ref, Url });
1336 Status?.IncBlockError(Url, ex.Message);
1344 this.loading.Remove(Key);
1354 private async Task<string> GetErrorMessage(HTTP.HttpException ex)
1356 object ContentObject = await ex.GetContentObjectAsync();
1357 if (ContentObject is
string s)
1359 else if (!(ex.Content is
null))
1360 return Encoding.UTF8.GetString(ex.Content);
1371 Dictionary<string, bool> UnpackType =
new Dictionary<string, bool>();
1385 if (!UnpackType.TryGetValue(Obj.
TypeName, out
bool UnpackObject))
1389 UnpackType[Obj.
TypeName] = UnpackObject;
1406 this.externalEvents?.RaiseEntryAdded(Obj);
1408 if (!(Status is
null))
1415 catch (Exception ex)
1417 await this.
client.Error(ex.Message);
1420 if (!(Status is
null))
1431 this.externalEvents?.RaiseEntryUpdated(Obj);
1433 if (!(Status is
null))
1436 catch (KeyNotFoundException)
1443 this.externalEvents?.RaiseEntryAdded(Obj);
1445 if (!(Status is
null))
1448 catch (Exception ex)
1450 await this.
client.Error(ex.Message);
1453 if (!(Status is
null))
1457 catch (Exception ex)
1459 await this.
client.Error(ex.Message);
1462 if (!(Status is
null))
1473 this.externalEvents?.RaiseEntryDeleted(Obj);
1475 if (!(Status is
null))
1478 catch (KeyNotFoundException)
1482 catch (Exception ex)
1484 await this.
client.Error(ex.Message);
1487 if (!(Status is
null))
1533 Ref.Unpacked =
true;
1538 private async
void RetryProcessing(
object State)
1545 object[] P = (
object[])State;
1547 string Url = (string)P[1];
1558 await this.RetrieveBlock(Ref, Url,
null,
true);
1563 catch (Exception ex)
1577 return Task.CompletedTask;
1585 return this.blockResource.ProcessRequest(Accept, Response, Ref);
Static class that does BASE64URL encoding (using URL and filename safe alphabet), as defined in RFC46...
static string Encode(byte[] Data)
Converts a binary block of data to a Base64URL-encoded string.
Static class managing encoding and decoding of internet content.
static Task< object > DecodeAsync(string ContentType, byte[] Data, Encoding Encoding, KeyValuePair< string, string >[] Fields, Uri BaseUri)
Decodes an object.
static Task< object > PostAsync(Uri Uri, object Data, params KeyValuePair< string, string >[] Headers)
Posts to a resource, using a Uniform Resource Identifier (or Locator).
static Task< KeyValuePair< string, TemporaryStream > > GetTempStreamAsync(Uri Uri, params KeyValuePair< string, string >[] Headers)
Gets a (possibly big) resource, given its URI.
Represents content embedded in other content.
string Description
Content-Description of embedded object, if defined.
object Decoded
Decoded body of embedded object. ContentType defines how TransferDecoded is transformed into Decoded.
byte[] TransferDecoded
Transformed body of embedded object. TransferEncoding defines how Raw is transformed into TransferDec...
Represents mixed content, encoded with multipart/mixed
Static class managing loading of resources stored as embedded resources or in content files.
const string DefaultContentType
Default content type for XML documents.
Helps with common XML-related tasks.
static string Attribute(XmlElement E, string Name)
Gets the value of an XML attribute.
static string Encode(string s)
Encodes a string for use in XML.
Class representing an event.
Event(DateTime Timestamp, EventType Type, string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Class representing an event.
Static class managing the application event log. Applications and services log events on this static ...
static string CleanStackTrace(string StackTrace)
Cleans a Stack Trace string, removing entries from the asynchronous execution model,...
static void Exception(Exception Exception, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, params KeyValuePair< string, object >[] Tags)
Logs an exception. Event type will be determined by the severity of the exception.
static void Warning(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs a warning event.
static void Error(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs an error event.
Task Information(string Comment)
Called to inform the viewer of something.
Task Warning(string Warning)
Called to inform the viewer of a warning state.
Base class for all HTTP resources.
Implements an HTTP server.
Event arguments for IQ queries.
async Task IqError(string Xml)
Returns an error response to the current request.
async Task IqResult(string Xml)
Returns a response to the current request.
XmlElement Query
Query element, if found, null otherwise.
string FromBareJid
Bare version of the "from" JID.
Event arguments for presence events.
string EntityCapabilityHashFunction
Hash function used in calculation of entity capabilities version of sender. Entity capabilities are d...
string EntityCapabilityNode
Node of entity capabilities of sender. Entity capabilities are defined in XEP-0115: http://xmpp....
bool HasEntityCapabilities
If the presence stanza includes entity capabilities information. Entity capabilities are defined in X...
bool IsOnline
If contact is online.
string EntityCapabilityVersion
Version of entity capabilities of sender. Entity capabilities are defined in XEP-0115: http://xmpp....
string From
From where the presence was received.
string FromBareJID
Bare JID of resource sending the presence.
XmppClient Client
XMPP Client. Is null if event raised by a component.
uint NrBlocks
Number of blocks processed
DateTime First
Earliest block
uint NrNew
Number of new blocks
ulong ObjectsDeleted
Objects deleted
DateTime Last
Latest block
uint NrDenied
Number of blocks denied access to.
ulong ObjectsAdded
Objects added
ulong ObjectsUpdated
Objects updated
uint ObjectErrors
Number of object errors.
uint NrUpdated
Number of updated blocks
uint NrLoaded
Number of blocks loaded
async Task< string > SynchronizePeer(PeerStatus PeerStatus, bool StartFromBeginning, CallbackAsync< SynchronizationStatus > Callback)
Synchronizes blocks hosted by a peer.
const int DefaultTimeoutMs
Default timeout = 2 minutes.
Task ProcessBlockRequest(HTTP.HeaderFields.HttpFieldAccept Accept, HTTP.HttpResponse Response, BlockReference Ref)
TODO
NeuroLedgerProvider Provider
Neuro-Ledger provider.
override string[] Extensions
Implemented extensions.
override void Dispose()
IDisposable.Dispose
const string NeuroLedgerNamespace
http://waher.se/NL
void StopSynchronization(PeerStatus PeerStatus)
Stops synchronization, if such is in progress.
NeuroLedgerClient(XmppClient Client, EndpointSecurity E2eEncryption, HTTP.HttpServer WebServer, NeuroLedgerProvider Provider)
Neuro-Ledger XMPP Client
async Task< PeerStatus > GetPeerStatus(PresenceEventArgs e)
Gets status information related to a peer.
Contains information about current synchronization status for a node in the network.
string LastBlockId
Last Block ID
Contains information about current synchronization status for a peer in the network.
int SynchCounter
Synchronization Counter
bool IsSynchronizing
If a synchronizating process is underway.
string RequestingCapabilitiesFunction
Entity RequestingCapabilities Function being requested
string RequestingCapabilitiesNode
Entity RequestingCapabilities Node being requested
string CapabilitiesFunction
Entity Capabilities Function
string RequestingCapabilitiesVersion
Entity Capabilities Version being requested
bool IsNeuroLedger
If the peer is a Neuro-Ledger node.
string CapabilitiesVersion
Entity Capabilities Version
string CapabilitiesNode
Entity Capabilities Node
Event raised when a block has been added.
Event raised when a block has been deleted.
Abstract base class for Neuro-Ledger block PEP events.
Abstract base class for Neuro-Ledger PEP events.
Outgoing event, waiting to be sent.
Provides authenticated and authorized clients with lists of available blocks.
Provides authenticated and authorized clients with binary blocks.
const string ErrorMsg_BlockFileHasBeenRemoved
Block file has been removed.
Allows a client to get multiple resources in one call
Class managing end-to-end encryption.
Event argument for personal event notification events.
IPersonalEvent PersonalEvent
Parsed personal event, if appropriate type was found.
Client managing the Personal Eventing Protocol (XEP-0163). https://xmpp.org/extensions/xep-0163....
Task Publish(string Node, EventHandlerAsync< ItemResultEventArgs > Callback, object State)
Publishes an item on a node.
void RegisterHandler(Type PersonalEventType, EventHandlerAsync< PersonalEventNotificationEventArgs > Handler)
Registers an event handler of a specific type of personal events.
async Task< string > PublishAsync(string Node)
Publishes an item on a node.
bool UnregisterHandler(Type PersonalEventType, EventHandlerAsync< PersonalEventNotificationEventArgs > Handler)
Unregisters an event handler of a specific type of personal events.
Maintains information about an item in the roster.
Contains information about an item of an entity.
Event arguments for service discovery responses.
Dictionary< string, bool > Features
Features
The sender has sent a stanza containing XML that does not conform to the appropriate schema or that c...
The requesting entity does not possess the necessary permissions to perform an action that only certa...
Manages an XMPP client connection. Implements XMPP, as defined in https://tools.ietf....
XmppState State
Current state of connection.
bool UnregisterIqGetHandler(string LocalName, string Namespace, EventHandlerAsync< IqEventArgs > Handler, bool RemoveNamespaceAsClientFeature)
Unregisters an IQ-Get handler.
IXmppExtension[] Extensions
Registered extensions.
bool Disposed
If the client has been disposed.
Task< ServiceDiscoveryEventArgs > ServiceDiscoveryAsync(string To)
Performs an asynchronous service discovery request
void RegisterIqGetHandler(string LocalName, string Namespace, EventHandlerAsync< IqEventArgs > Handler, bool PublishNamespaceAsClientFeature)
Registers an IQ-Get handler.
RosterItem[] Roster
Items in the roster.
Base class for XMPP Extensions.
bool ClientDisposed
If the client has been disposed.
XmppClient client
XMPP Client used by the extension.
Task Exception(Exception Exception)
Called to inform the viewer of an exception state.
XmppClient Client
XMPP Client.
This attribute defines that objects of this type can be archived, and the time objects can be archive...
Static interface for database persistence. In order to work, a database provider has to be assigned t...
static Task< IPersistentDictionary > GetDictionary(string Collection)
Gets a persistent dictionary containing objects in a collection.
static Task EndBulk()
Ends bulk-processing of data. Must be called once for every call to StartBulk.
static async Task InsertLazy(object Object)
Inserts an object into the database, if unlocked. If locked, object will be inserted at next opportun...
static IDatabaseProvider Provider
Registered database provider.
static Task StartBulk()
Starts bulk-proccessing of data. Must be followed by a call to EndBulk.
static async Task Update(object Object)
Updates an object in the database.
static async Task Delete(object Object)
Deletes an object in the database.
static Task< IEnumerable< object > > Find(string Collection, params string[] SortOrder)
Finds objects in a given collection.
static async Task Insert(object Object)
Inserts an object into the default collection of the database.
static async Task Clear(string CollectionName)
Clears a collection of all objects.
An attempt to insert a key was done, but the key was already there.
This filter selects objects that conform to all child-filters provided.
Custom filter used to filter objects using an external expression.
This filter selects objects that have a named field equal to a given value.
This filter selects objects that have a named field greater than a given value.
Event arguments for block reference events.
BlockReference Block
Block reference.
Optimizes a persistent IPersistentDictionary using a cache.
void DeleteAndDispose()
TODO
Task AddAsync(string key, object value)
TODO
async Task< bool > ContainsKeyAsync(string key)
TODO
async Task AddBlockFile(Stream File, BlockReference BlockReference)
Adds a block file to the ledger.
static bool AreEqual(DateTime TP1, DateTime TP2)
Compares two timestamps, to the millisecond (but not tick) level.
ILedgerExternalEvents ExternalEvents
Interface for reporting external events.
static Task< BlockReference > FindReference(byte[] Digest)
Finds a BlockReference object related to a block, given its digest.
async Task< Tuple< uint, uint, uint, uint > > Process(CachedStringDictionary Records, string CollectionName)
Processes an ordered set of records containing ObjectState objects in a cached string dictionary (for...
Enumeratres through objects available in a series of blocks.
T Current
Gets the element in the collection at the current position of the enumerator.
async Task< bool > MoveNextAsync()
Advances the enumerator to the next element of the collection.
Entry CurrentEntry
Current encoded entry.
static async Task< ObjectEnumerator< T > > Create(IAsyncEnumerator< BlockReference > BlockEnumerator, NeuroLedgerProvider Provider)
Creates an object enumerator from a block enumerator.
Represents an object state.
GenericObject Object
Object
Contains a reference to a block in the ledger.
ulong Bytes
Size of block, in bytes.
bool AccessDenied
If access to the block was denied.
bool Unpacked
If objects in the block have been unpacked.
string[] Sources
Sources of block
byte[] Digest
Digest of block
byte[] Signature
Signature of block
string FileName
Local filename of block
Generic object. Contains a sequence of properties.
string TypeName
Type name.
Implements an in-memory cache.
void Dispose()
IDisposable.Dispose
bool TryGetValue(KeyType Key, out ValueType Value)
Tries to get a value from the cache.
Static class that dynamically manages types and interfaces available in the runtime environment.
static Type GetType(string FullName)
Gets a type, given its full name.
static bool TryGetModuleParameter(string Name, out object Value)
Tries to get a module parameter value.
Manages a temporary stream. Contents is kept in-memory, if below a memory threshold,...
override void Dispose(bool disposing)
Releases the unmanaged resources used by the System.IO.Stream and optionally releases the managed res...
Class that can be used to schedule events in time. It uses a timer to execute tasks at the appointed ...
void Dispose()
IDisposable.Dispose
DateTime Add(DateTime When, ScheduledEventCallback Callback, object State)
Adds an event.
Task Update(object Object)
Updates an object in the database.
Task Delete(object Object)
Deletes an object in the database.
Task Clear(string CollectionName)
Clears a collection of all objects.
Task Insert(object Object)
Inserts an object into the database.
Interface for proxy for reporting changes to the ledger from external sources.
Persistent dictionary that can contain more entries than possible in the internal memory.
Task ClearAsync()
Clears the dictionary.
SubscriptionState
State of a presence subscription.
XmppState
State of XMPP connection.
BlockStatus
Status of the block.
EntryType
Ledger entry type.