/// <summary> /// Close the warehouse. /// This function issues terminate trigger to all resources and stores. /// </summary> /// <returns>True, if no problem occurred.</returns> public static AsyncReply <bool> Close() { var bag = new AsyncBag <bool>(); foreach (var resource in resources.Values) { IResource r; if (resource.TryGetTarget(out r)) { if (!(r is IStore)) { bag.Add(r.Trigger(ResourceTrigger.Terminate)); } } } foreach (var store in stores) { bag.Add(store.Key.Trigger(ResourceTrigger.Terminate)); } foreach (var resource in resources.Values) { IResource r; if (resource.TryGetTarget(out r)) { if (!(r is IStore)) { bag.Add(r.Trigger(ResourceTrigger.SystemTerminated)); } } } foreach (var store in stores) { bag.Add(store.Key.Trigger(ResourceTrigger.SystemTerminated)); } bag.Seal(); var rt = new AsyncReply <bool>(); bag.Then((x) => { foreach (var b in x) { if (!b) { rt.Trigger(false); return; } } rt.Trigger(true); }); return(rt); }
public static AsyncReply TypedListParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence) { var rt = new AsyncBag <object>(); // get the type var(hdrCs, rep) = RepresentationType.Parse(data, offset); offset += hdrCs; length -= hdrCs; var runtimeType = rep.GetRuntimeType(); rt.ArrayType = runtimeType; while (length > 0) { var(cs, reply) = Codec.Parse(data, offset, connection, requestSequence); rt.Add(reply); if (cs > 0) { offset += (uint)cs; length -= (uint)cs; } else { throw new Exception("Error while parsing structured data"); } } rt.Seal(); return(rt); }
public AsyncBag <T> Children <T>(IResource resource, string name) where T : IResource { if (resource == this) { IFindFluent <BsonDocument, BsonDocument> match; if (name == null) { match = resourcesCollection.Find(x => (x["parents"] as BsonArray).Contains(this.Instance.Name)); } else { match = resourcesCollection.Find(x => (x["parents"] as BsonArray).Contains(this.Instance.Name) && x["name"] == name); } var st = match.ToList().Select(x => x["_id"].ToString()).ToArray(); var bag = new AsyncBag <T>(); foreach (var s in st) { var r = Fetch <T>(s); if (r.Ready && r.Result == null) { continue; } bag.Add(r); } bag.Seal(); return(bag); } else { var children = (string[])resource.Instance.Variables["children"]; if (children == null) { return(new AsyncBag <T>(null)); } var rt = new AsyncBag <T>(); foreach (var child in children) { var r = Warehouse.Get <T>(child); if (r is AsyncReply <T> ) { rt.Add(r);// (AsyncReply<T>)r); } } rt.Seal(); return(rt); } }
public AsyncBag <T> Parents <T>(IResource resource, string name) where T : IResource { if (resource == this) { return(new AsyncBag <T>(null)); } else { var parents = (string[])resource.Instance.Variables["parents"]; if (parents == null) { return(new AsyncBag <T>(null)); } var rt = new AsyncBag <T>(); foreach (var parent in parents) { var r = Warehouse.Get <T>(parent); if (r is AsyncReply <T> ) { rt.Add(r);// (AsyncReply<T>)r); } } rt.Seal(); return(rt); } }
public AsyncReply <KeyList <PropertyTemplate, PropertyValue[]> > GetRecord(IResource resource, DateTime fromDate, DateTime toDate) { var properties = resource.Instance.Template.Properties.Where(x => x.Storage == StorageMode.Recordable).ToList(); var reply = new AsyncReply <KeyList <PropertyTemplate, PropertyValue[]> >(); AsyncBag <PropertyValue[]> bag = new AsyncBag <PropertyValue[]>(); foreach (var p in properties) { bag.Add(GetPropertyRecordByDate(resource, p.Name, fromDate, toDate)); } bag.Seal(); bag.Then(x => { var list = new KeyList <PropertyTemplate, PropertyValue[]>(); for (var i = 0; i < x.Length; i++) { list.Add(properties[i], x[i]); } reply.Trigger(list); }); return(reply); }
public static AsyncReply TupleParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence) { var results = new AsyncBag <object>(); var rt = new AsyncReply(); var tupleSize = data[offset++]; length--; var types = new List <Type>(); for (var i = 0; i < tupleSize; i++) { var(cs, rep) = RepresentationType.Parse(data, offset); types.Add(rep.GetRuntimeType()); offset += cs; length -= cs; } while (length > 0) { var(cs, reply) = Codec.Parse(data, offset, connection, requestSequence); results.Add(reply); if (cs > 0) { offset += (uint)cs; length -= (uint)cs; } else { throw new Exception("Error while parsing structured data"); } } results.Seal(); results.Then(ar => { if (ar.Length == 2) { var type = typeof(ValueTuple <,>).MakeGenericType(types.ToArray()); rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1])); } else if (ar.Length == 3) { var type = typeof(ValueTuple <, ,>).MakeGenericType(types.ToArray()); rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1], ar[2])); } else if (ar.Length == 4) { var type = typeof(ValueTuple <, , ,>).MakeGenericType(types.ToArray()); rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1], ar[2], ar[3])); } }); return(rt); }
/// <summary> /// Open the warehouse. /// This function issues the initialize trigger to all stores and resources. /// </summary> /// <returns>True, if no problem occurred.</returns> public static AsyncReply <bool> Open() { var bag = new AsyncBag <bool>(); foreach (var store in stores) { bag.Add(store.Trigger(ResourceTrigger.Initialize)); } bag.Seal(); var rt = new AsyncReply <bool>(); bag.Then((x) => { foreach (var b in x) { if (!b) { rt.Trigger(false); return; } } var rBag = new AsyncBag <bool>(); foreach (var rk in resources) { rBag.Add(rk.Value.Trigger(ResourceTrigger.SystemInitialized)); } rBag.Seal(); rBag.Then(y => { foreach (var b in y) { if (!b) { rt.Trigger(false); return; } } rt.Trigger(true); storeIsOpen = true; }); }); return(rt); }
public static AsyncReply TypedMapParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence) { // get key type var(keyCs, keyRepType) = RepresentationType.Parse(data, offset); offset += keyCs; length -= keyCs; var(valueCs, valueRepType) = RepresentationType.Parse(data, offset); offset += valueCs; length -= valueCs; var map = (IMap)Activator.CreateInstance(typeof(Map <,>).MakeGenericType(keyRepType.GetRuntimeType(), valueRepType.GetRuntimeType())); var rt = new AsyncReply(); var results = new AsyncBag <object>(); while (length > 0) { var(cs, reply) = Codec.Parse(data, offset, connection, requestSequence); results.Add(reply); if (cs > 0) { offset += (uint)cs; length -= (uint)cs; } else { throw new Exception("Error while parsing structured data"); } } results.Seal(); results.Then(ar => { for (var i = 0; i < ar.Length; i += 2) { map.Add(ar[i], ar[i + 1]); } rt.Trigger(map); }); return(rt); }
public AsyncReply <bool> Trigger(ResourceTrigger trigger) { if (trigger == ResourceTrigger.Initialize) { var filter = new BsonDocument(); var list = resourcesCollection.Find(filter).ToList(); Console.WriteLine(list.Count); // if (list.Count == 0) // return new AsyncBag<IResource>(new IResource[0]); var bag = new AsyncBag <IResource>(); for (var i = 0; i < list.Count; i++) { Console.WriteLine("Loading {0}/{1}", i, list.Count); bag.Add(Get("id/" + list[i]["_id"].AsObjectId.ToString())); } bag.Seal(); var rt = new AsyncReply <bool>(); bag.Then((x) => { rt.Trigger(true); }); return(rt); } else if (trigger == ResourceTrigger.Terminate) { // save all resources foreach (var resource in resources.Values) { SaveResource(resource); } return(new AsyncReply <bool>(true)); } else { return(new AsyncReply <bool>(true)); } }
public static AsyncReply <KeyList <PropertyTemplate, PropertyValue[]> > HistoryParser(byte[] data, uint offset, uint length, IResource resource, DistributedConnection connection, uint[] requestSequence) { //var count = (int)toAge - (int)fromAge; var list = new KeyList <PropertyTemplate, PropertyValue[]>(); var reply = new AsyncReply <KeyList <PropertyTemplate, PropertyValue[]> >(); var bagOfBags = new AsyncBag <PropertyValue[]>(); var ends = offset + length; while (offset < ends) { var index = data[offset++]; var pt = resource.Instance.Template.GetPropertyTemplateByIndex(index); list.Add(pt, null); var cs = data.GetUInt32(offset, Endian.Little); offset += 4; var(len, pv) = PropertyValueParser(data, offset, connection, requestSequence); bagOfBags.Add(pv);// ParsePropertyValueArray(data, offset, cs, connection)); offset += len; } bagOfBags.Seal(); bagOfBags.Then(x => { for (var i = 0; i < list.Count; i++) { list[list.Keys.ElementAt(i)] = x[i]; } reply.Trigger(list); }); return(reply); }
public AsyncReply <PropertyValue[]> GetPropertyRecordByDate(IResource resource, string propertyName, DateTime fromDate, DateTime toDate) { var objectId = resource.Instance.Attributes["objectId"].ToString(); var record = this.database.GetCollection <BsonDocument>("record_" + objectId); var builder = Builders <BsonDocument> .Filter; var filter = builder.Gte("date", fromDate) & builder.Lte("date", toDate) & builder.Eq("property", propertyName); var reply = new AsyncReply <PropertyValue[]>(); record.FindAsync(filter).ContinueWith((x) => { var values = ((Task <IAsyncCursor <BsonDocument> >)x).Result.ToList(); var bag = new AsyncBag <object>(); foreach (var v in values) { bag.Add(Parse(v["value"])); } bag.Seal(); bag.Then((results) => { var list = new List <PropertyValue>(); for (var i = 0; i < results.Length; i++) { list.Add(new PropertyValue(results[i], (ulong)values[i]["age"].AsInt64, values[i]["date"].ToUniversalTime())); } reply.Trigger(list.ToArray()); }); }); return(reply); }
/// <summary> /// Parse an array of bytes into an array of varialbes. /// </summary> /// <param name="data">Array of bytes.</param> /// <param name="offset">Zero-indexed offset.</param> /// <param name="length">Number of bytes to parse.</param> /// <param name="connection">DistributedConnection is required to fetch resources.</param> /// <returns>Array of variables.</returns> public static AsyncBag <object> ParseVarArray(byte[] data, uint offset, uint length, DistributedConnection connection) { var rt = new AsyncBag <object>(); while (length > 0) { uint cs; rt.Add(Parse(data, offset, out cs, connection)); if (cs > 0) { offset += (uint)cs; length -= (uint)cs; } else { throw new Exception("Error while parsing structured data"); } } rt.Seal(); return(rt); }
/// <summary> /// Parse an array of PropertyValue. /// </summary> /// <param name="data">Array of bytes.</param> /// <param name="offset">Zero-indexed offset.</param> /// <param name="length">Number of bytes to parse.</param> /// <param name="connection">DistributedConnection is required to fetch resources.</param> /// <param name="ageIncluded">Whether property age is represented in the data.</param> /// <returns></returns> public static AsyncBag <PropertyValue> ParsePropertyValueArray(byte[] data, uint offset, uint length, DistributedConnection connection)//, bool ageIncluded = true) { var rt = new AsyncBag <PropertyValue>(); while (length > 0) { uint cs; rt.Add(ParsePropertyValue(data, offset, out cs, connection));//, ageIncluded)); if (cs > 0) { offset += (uint)cs; length -= (uint)cs; } else { throw new Exception("Error while parsing ValueInfo structured data"); } } rt.Seal(); return(rt); }
public static AsyncBag <object> ListParser(byte[] data, uint offset, uint length, DistributedConnection connection, uint[] requestSequence) { var rt = new AsyncBag <object>(); while (length > 0) { var(cs, reply) = Codec.Parse(data, offset, connection, requestSequence); rt.Add(reply); if (cs > 0) { offset += (uint)cs; length -= (uint)cs; } else { throw new Exception("Error while parsing structured data"); } } rt.Seal(); return(rt); }
AsyncReply <IResource> Fetch(string id) { var filter = Builders <BsonDocument> .Filter.Eq("_id", new BsonObjectId(new ObjectId(id))); var list = resourcesCollection.Find(filter).ToList(); if (list.Count == 0) { return(new AsyncReply <IResource>(null)); } var document = list[0]; IResource resource = (IResource)Activator.CreateInstance(Type.GetType(document["classname"].AsString)); resources.Add(document["_id"].AsObjectId.ToString(), resource); Warehouse.Put(resource, document["name"].AsString, this); var parents = document["parents"].AsBsonArray; var children = document["children"].AsBsonArray; //var managers = document["managers"].AsBsonArray; var attributes = Parse(document["attributes"]).Then(x => { resource.Instance.SetAttributes(x as Structure); }); var bag = new AsyncBag <object>(); foreach (var p in parents) { var ap = Warehouse.Get(p.AsString); bag.Add(ap); ap.Then((x) => { if (!resource.Instance.Parents.Contains(x)) { resource.Instance.Parents.Add(x); } }); } foreach (var c in children) { var ac = Warehouse.Get(c.AsString); bag.Add(ac); ac.Then((x) => { if (!resource.Instance.Children.Contains(x)) { resource.Instance.Children.Add(x); } }); } /* * // load managers * foreach(var m in managers) * { * IPermissionsManager pm = (IPermissionsManager)Activator.CreateInstance(Type.GetType(m["classname"].AsString)); * var sr = Parse(m["settings"]); * bag.Add(sr); * sr.Then((x) => * { * pm.Initialize((Structure)x, resource); * resource.Instance.Managers.Add(pm); * }); * } */ // Load values var values = document["values"].AsBsonDocument; foreach (var v in values) { var valueInfo = v.Value as BsonDocument; var av = Parse(valueInfo["value"]); bag.Add(av); av.Then((x) => { resource.Instance.LoadProperty(v.Name, (ulong)valueInfo["age"].AsInt64, valueInfo["modification"].ToUniversalTime(), x); }); } bag.Seal(); var rt = new AsyncReply <IResource>(); bag.Then((x) => { rt.Trigger(resource); }); return(rt); }
/// <summary> /// Parse an array of structures /// </summary> /// <param name="data">Bytes array</param> /// <param name="offset">Zero-indexed offset</param> /// <param name="length">Number of bytes to parse</param> /// <param name="connection">DistributedConnection is required in case a structure in the array holds items at the other end</param> /// <returns>Array of structures</returns> public static AsyncBag <Structure> ParseStructureArray(byte[] data, uint offset, uint length, DistributedConnection connection) { var reply = new AsyncBag <Structure>(); if (length == 0) { reply.Seal(); return(reply); } var end = offset + length; var result = (StructureComparisonResult)data[offset++]; AsyncReply previous = null; // string[] previousKeys = null; // DataType[] previousTypes = null; Structure.StructureMetadata metadata = new Structure.StructureMetadata(); if (result == StructureComparisonResult.Null) { previous = new AsyncReply <Structure>(null); } else if (result == StructureComparisonResult.Structure) { uint cs = data.GetUInt32(offset); offset += 4; previous = ParseStructure(data, offset, cs, connection, out metadata); offset += cs; } reply.Add(previous); while (offset < end) { result = (StructureComparisonResult)data[offset++]; if (result == StructureComparisonResult.Null) { previous = new AsyncReply <Structure>(null); } else if (result == StructureComparisonResult.Structure) { uint cs = data.GetUInt32(offset); offset += 4; previous = ParseStructure(data, offset, cs, connection, out metadata);// out previousKeys, out previousTypes); offset += cs; } else if (result == StructureComparisonResult.StructureSameKeys) { uint cs = data.GetUInt32(offset); offset += 4; previous = ParseStructure(data, offset, cs, connection, out metadata, metadata.Keys); offset += cs; } else if (result == StructureComparisonResult.StructureSameTypes) { uint cs = data.GetUInt32(offset); offset += 4; previous = ParseStructure(data, offset, cs, connection, out metadata, metadata.Keys, metadata.Types); offset += cs; } reply.Add(previous); } reply.Seal(); return(reply); }
AsyncReply Parse(BsonValue value) { if (value.BsonType == BsonType.Document) { var doc = value.AsBsonDocument; if (doc["type"] == 0) { return(Warehouse.Get(doc["link"].AsString)); } // structure else if (doc["type"] == 1) { var bag = new AsyncBag <object>(); var rt = new AsyncReply <Structure>(); var bs = (BsonDocument)doc["values"].AsBsonDocument; var s = new Structure(); foreach (var v in bs) { bag.Add(Parse(v.Value)); } bag.Seal(); bag.Then((x) => { for (var i = 0; i < x.Length; i++) { s[bs.GetElement(i).Name] = x[i]; } rt.Trigger(s); }); return(rt); } else { return(new AsyncReply(null)); } } else if (value.BsonType == BsonType.Array) { var array = value.AsBsonArray; var bag = new AsyncBag <object>(); foreach (var v in array) { bag.Add(Parse(v)); } bag.Seal(); return(bag); } else if (value.BsonType == BsonType.DateTime) { return(new AsyncReply(value.ToUniversalTime())); } else { return(new AsyncReply(value.RawValue)); } }
/// <summary> /// Parse a structure /// </summary> /// <param name="data">Bytes array</param> /// <param name="offset">Zero-indexed offset.</param> /// <param name="length">Number of bytes to parse.</param> /// <param name="connection">DistributedConnection is required in case a structure in the array holds items at the other end.</param> /// <param name="parsedKeys">Array to store keys in.</param> /// <param name="parsedTypes">Array to store DataTypes in.</param> /// <param name="keys">Array of keys, in case the data doesn't include keys</param> /// <param name="types">Array of DataTypes, in case the data doesn't include DataTypes</param> /// <returns>Structure</returns> public static AsyncReply <Structure> ParseStructure(byte[] data, uint offset, uint length, DistributedConnection connection, out Structure.StructureMetadata metadata, string[] keys = null, DataType[] types = null)// out string[] parsedKeys, out DataType[] parsedTypes, string[] keys = null, DataType[] types = null) { var reply = new AsyncReply <Structure>(); var bag = new AsyncBag <object>(); var keylist = new List <string>(); var typelist = new List <DataType>(); if (keys == null) { while (length > 0) { var len = data[offset++]; keylist.Add(data.GetString(offset, len)); offset += len; typelist.Add((DataType)data[offset]); uint rt; bag.Add(Codec.Parse(data, offset, out rt, connection)); length -= rt + len + 1; offset += rt; } } else if (types == null) { keylist.AddRange(keys); while (length > 0) { typelist.Add((DataType)data[offset]); uint rt; bag.Add(Codec.Parse(data, offset, out rt, connection)); length -= rt; offset += rt; } } else { keylist.AddRange(keys); typelist.AddRange(types); var i = 0; while (length > 0) { uint rt; bag.Add(Codec.Parse(data, offset, out rt, connection, types[i])); length -= rt; offset += rt; i++; } } bag.Seal(); bag.Then((res) => { // compose the list var s = new Structure(); for (var i = 0; i < keylist.Count; i++) { s[keylist[i]] = res[i]; } reply.Trigger(s); }); metadata = new Structure.StructureMetadata() { Keys = keylist.ToArray(), Types = typelist.ToArray() }; return(reply); }
/// <summary> /// Parse an array of bytes into array of resources /// </summary> /// <param name="data">Array of bytes.</param> /// <param name="length">Number of bytes to parse.</param> /// <param name="offset">Zero-indexed offset.</param> /// <param name="connection">DistributedConnection is required to fetch resources.</param> /// <returns>Array of resources.</returns> public static AsyncBag <IResource> ParseResourceArray(byte[] data, uint offset, uint length, DistributedConnection connection) { var reply = new AsyncBag <IResource>(); if (length == 0) { reply.Seal(); return(reply); } var end = offset + length; // var result = (ResourceComparisonResult)data[offset++]; AsyncReply previous = null; if (result == ResourceComparisonResult.Null) { previous = new AsyncReply <IResource>(null); } else if (result == ResourceComparisonResult.Local) { previous = Warehouse.Get(data.GetUInt32(offset)); offset += 4; } else if (result == ResourceComparisonResult.Distributed) { previous = connection.Fetch(data.GetUInt32(offset)); offset += 4; } reply.Add(previous); while (offset < end) { result = (ResourceComparisonResult)data[offset++]; AsyncReply current = null; if (result == ResourceComparisonResult.Null) { current = new AsyncReply <IResource>(null); } else if (result == ResourceComparisonResult.Same) { current = previous; } else if (result == ResourceComparisonResult.Local) { current = Warehouse.Get(data.GetUInt32(offset)); offset += 4; } else if (result == ResourceComparisonResult.Distributed) { current = connection.Fetch(data.GetUInt32(offset)); offset += 4; } reply.Add(current); previous = current; } reply.Seal(); return(reply); }