private static void ProcessCommands(IList<Tuple<IOverlayNodeService, IOverlayStorageService>> services) { Func<string, IOverlayNodeService, OverlayData[]> getStoragePutKeyValuesFromCmd = (string arg, IOverlayNodeService srv) => { var res = new List<OverlayData>(); foreach (var pair in arg.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)) { var pairAttrVal = pair.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries); // assume we have only one overlay level as for now res.Add(new OverlayData { AttrValue = new KeyValuePair<string,object>(pairAttrVal[0].Trim(), pairAttrVal[1].Trim()), OwnerNode = new NodeDescriptor(srv.Node) }); } return res.ToArray(); }; Func<string, string[]> getStorageRemoveKeysFromCmd = (string arg) => { return arg .Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries) .Select(s => s.Trim()) .ToArray(); }; while (true) { var cmd = System.Console.ReadLine(); var operatingSrv = services[Rnd.Next(0, services.Count)]; if (cmd.StartsWith("join")) { var existingNodesInOverlay = services.Select(s => s.Item1.Node).ToArray(); // chord service var nodeWhoJoinsInitInfo = new NodeDescriptor.NodeInitInfo( NetworkHelper.GetLocalIpAddress(), OverlayHelper.GetRandomPortNumber(existingNodesInOverlay.Select(n => n.Port).ToArray()), 1 ); var hashPrv = (IProvider<byte[], long>)SrvPrv.GetService("sha1KeyPrv"); var nodeWhoJoins = new NodeDescriptor( nodeWhoJoinsInitInfo, hashPrv.Provide(OverlayHelper.GetNodeHashArgument(nodeWhoJoinsInitInfo)) ); var nodeWhoJoinsChordService = (IOverlayNodeService)SrvPrv.GetService("chordOverlayNodeService"); nodeWhoJoinsChordService.Bind(new LocalNode(nodeWhoJoins)); nodeWhoJoinsChordService.Join( existingNodesInOverlay[Rnd.Next(0, existingNodesInOverlay.Length)] ); // respective storage service var nodeWhoJoinsStorageService = (IOverlayStorageService)SrvPrv.GetService("mongoDbOverlayStorageService"); nodeWhoJoinsStorageService.Bind(new[] { nodeWhoJoinsChordService }.ToList()); nodeWhoJoinsStorageService.Start(); } else if (cmd == "leave") { var cmdParts = cmd.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); var srvToLeave = services.FirstOrDefault(s => s.Item1.Node.Id == Convert.ToInt64(cmdParts[1])); if (srvToLeave != null) { srvToLeave.Item2.Stop(); srvToLeave.Item1.SendMessage(new OverlayNodeServiceMessage { MsgType = OverlayNodeServiceMessage.MessageType.ExitRequested, WaitForProcessing = true }); } else { System.Console.WriteLine("No such node"); } } else if (cmd == "stop") { break; } else if (cmd.StartsWith("stats")) { var cmdParts = cmd.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); using (var fs = File.Create("generated_stats_" + DateTime.Now.Ticks + ".xml")) { using (var writer = new StreamWriter(fs)) { foreach (var stats in Stats) { writer.WriteLine(String.Join( ";", stats.NodesCount, stats.AVPairsCount, stats.ServiceRegistrationFailsCount, stats.NodesOverAVThresholdCount, stats.AvgRegistrationsPerSecond )); } } } } else if (cmd.StartsWith("populate")) { var cmdParts = cmd.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); PopulateStorage( services, GetServiceDescriptions(cmdParts[1]), cmdParts.Length > 2 ? (int?)Convert.ToInt32(cmdParts[2]) : null ); } else if (cmd.StartsWith("put")) { Func<string, IOverlayNodeService, ServiceDescription> f = (string srvDescr, IOverlayNodeService overlaySrv) => { var res = new ServiceDescription { Name = srvDescr.Substring(0, srvDescr.IndexOf(":")), OwnerNode = overlaySrv.Node, Data = new List<OverlayData>() }; foreach (var pair in srvDescr.Substring(srvDescr.IndexOf(":") + 1).Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)) { var pairAttrVal = pair.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries); // assume we have only one overlay level as for now res.Data.Add( new OverlayData { AttrValue = new KeyValuePair<string,object>(pairAttrVal[0].Trim(), pairAttrVal[1].Trim()), ServiceName = res.Name, OwnerNode = res.OwnerNode } ); } return res; }; var cmdParts = cmd.Substring("put".Length).Trim().Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); var ownerSrv = services.FirstOrDefault(s => s.Item1.Node.Id == Convert.ToInt64(cmdParts[1])); if (ownerSrv != null) { ownerSrv.Item2.PutService(f( cmdParts[1], ownerSrv.Item1 )); } else { System.Console.WriteLine("No such node"); } } else if (cmd.StartsWith("remove")) { operatingSrv.Item2.RemoveService(cmd.Substring("remove".Length).Trim()); } else if (cmd.StartsWith("update")) { var cmdParts = cmd.Substring("update".Length).Split(':', ';'); var addCmdPart = cmdParts[1]; var removeCmdPart = cmd.IndexOf(";") > 0 ? cmdParts[2] : null; operatingSrv.Item2.UpdateService( cmdParts[0].Trim(), String.IsNullOrWhiteSpace(addCmdPart) ? null : getStoragePutKeyValuesFromCmd(addCmdPart, operatingSrv.Item1), String.IsNullOrWhiteSpace(removeCmdPart) ? null : getStorageRemoveKeysFromCmd(removeCmdPart) ); } else if (cmd.StartsWith("get")) { var res = operatingSrv.Item2.GetServices(Query.FromRelex(cmd.Substring("get".Length).Trim()), true); if (res != null && res.IsSuccessful && res.ServicesData.Any()) { System.Console.WriteLine("**************************************************"); System.Console.WriteLine("RESULTS:"); foreach (var r in res.ServicesData) { System.Console.WriteLine("\r\n=============================================================="); System.Console.WriteLine(String.Format("Service name: {0}", r.Name)); foreach (var d in r.Data) { System.Console.WriteLine(String.Format("{0} = {1} (Responsible node: {2})", d.AttrValue.Key, d.GetFormattedValue(), d.ResponsibleNode.ToString())); } System.Console.WriteLine(String.Format("Service owner: {0}", r.OwnerNode.ToString())); System.Console.WriteLine("==============================================================\r\n"); } } else { System.Console.WriteLine(res != null && !res.IsSuccessful ? "Failed" : "No data"); } } } }
private static ServiceDescription[] GetServiceDescriptions(string filename) { IList<ServiceDescription> result = new List<ServiceDescription>(); if (filename.StartsWith("dataset:")) { var datasetArgs = filename.Split(new char[] { ':' }); if (datasetArgs[1] == "uniform") { var prv = (IProvider<IDictionary<string, int>, IList<ServiceDescription>>)SrvPrv.GetService("uniformServiceDatasetPrv"); result = prv.Provide(new Dictionary<string, int> { { "services_amount", Convert.ToInt32(datasetArgs[2])}, { "possible_attributes_amount", Convert.ToInt32(datasetArgs[3])}, { "possible_values_amount", Convert.ToInt32(datasetArgs[4])}, { "attribute_per_service_avg_amount", Convert.ToInt32(datasetArgs[5])}, { "attribute_per_service_amount_variance", Convert.ToInt32(datasetArgs[6])}, { "values_per_attr_avg_amount", Convert.ToInt32(datasetArgs[7])}, { "values_per_attr_amount_variance", Convert.ToInt32(datasetArgs[8])} }); } if (datasetArgs[1] == "skewed") { var prv = (IProvider<IDictionary<string, int>, IList<ServiceDescription>>)SrvPrv.GetService("skewedServiceDatasetPrv"); result = prv.Provide(new Dictionary<string, int> { { "services_amount", Convert.ToInt32(datasetArgs[2])}, { "possible_attributes_amount", Convert.ToInt32(datasetArgs[3])}, { "possible_values_amount", Convert.ToInt32(datasetArgs[4])}, { "attribute_per_service_avg_amount", Convert.ToInt32(datasetArgs[5])}, { "attribute_per_service_amount_variance", Convert.ToInt32(datasetArgs[6])}, { "values_per_attr_avg_amount", Convert.ToInt32(datasetArgs[7])}, { "values_per_attr_amount_variance", Convert.ToInt32(datasetArgs[8])} }); } if (DumpGeneratedServicesToFile) { // write generated dataset to a file using (var fs = File.Create("generated_dataset_" + DateTime.Now.Ticks + ".xml")) { using (var writer = XmlWriter.Create(fs)) { writer.WriteStartDocument(); writer.WriteStartElement("data"); foreach (var s in result) { writer.WriteStartElement("node"); writer.WriteAttributeString("name", s.Name); foreach (var av in s.Data) { writer.WriteStartElement(av.AttrValue.Key); writer.WriteValue(av.AttrValue.Value.ToString()); writer.WriteEndElement(); } writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteEndDocument(); } } } return result.ToArray(); } else { Func<string, string> getValidBooleanString = (string s) => { if (s == "no" || s == "0" || s == "false") { return Boolean.FalseString; } else if (s == "yes" || s == "1" || s == "true") { return Boolean.TrueString; } throw new ArgumentException(String.Format("Value '{0}' cannot be converted to boolean", s)); }; Func<string, Type, string, object> getTypedValue = (string val, Type type, string typeStr) => { string vv = val.Trim(); if (type == typeof(bool)) { vv = getValidBooleanString(vv); } if (typeStr == "time") { vv = Convert.ToString(TimeSpan.Parse(vv).TotalMilliseconds); } return TypeDescriptor.GetConverter(type).ConvertFrom(vv); }; using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.None)) { using (var xmlRdr = XmlReader.Create(fs, new XmlReaderSettings { IgnoreComments = true, IgnoreWhitespace = true })) { var xml = XDocument.Load(xmlRdr); var nodes = xml.Root.Descendants(XName.Get("node")).GroupBy(n => n.Attribute(XName.Get("type"))); foreach (var nodeGr in nodes) { foreach (var srvNode in nodeGr) { var srvDescription = new ServiceDescription { Data = new List<OverlayData>(), Name = nodeGr.Key.Value + "_" + Rnd.Next(1, 1000000) }; var ownerNodeAttr = srvNode.Attribute(XName.Get("owner-node")); if (ownerNodeAttr != null) { srvDescription.OwnerNode = new StubNodeDescriptor(Convert.ToInt64(srvNode.Attribute(XName.Get("owner-node")).Value)); } foreach (var item in srvNode.Descendants()) { var od = new OverlayData { ServiceName = srvDescription.Name, OwnerNode = srvDescription.OwnerNode }; object typedValue = item.Value; if (item.Attribute("type") != null) { var typeStr = item.Attribute("type").Value; var originalTypeStr = typeStr; if (typeStr.StartsWith("array[")) { typeStr = typeStr.Replace("array[", "").Replace("]",""); } Type type = null; switch (typeStr) { case "int" : type = typeof(int); break; case "boolean" : type = typeof(bool); break; case "double" : type = typeof(double); break; case "date" : type = typeof(DateTime); break; case "time" : type = typeof(int); break; } if (type != null) { od.ValueType = new OverlayData.TypeInfo { InternalType = type, IsArray = originalTypeStr.StartsWith("array["), IsTime = typeStr == "time" }; if (od.ValueType.IsArray) { // don't forget to remove '[' and ']' typedValue = item.Value.Substring(1, item.Value.Length - 2) .Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries) .Select(v => getTypedValue(v, od.ValueType.InternalType, typeStr)) .ToArray(); } else { typedValue = getTypedValue(item.Value, od.ValueType.InternalType, typeStr); } } } od.AttrValue = new KeyValuePair<string,object>(item.Name.LocalName, typedValue); srvDescription.Data.Add(od); } result.Add(srvDescription); } } } } return result.ToArray(); } }
private static void PopulateStorage(IList<Tuple<IOverlayNodeService, IOverlayStorageService>> p2pServices, ServiceDescription[] serviceDescriptions, int? avgRegistrationsPerSecond) { var newStats = new Statistics(); System.Console.WriteLine("Populating the data storage..."); DbMgr.Clear(); newStats.NodesCount = p2pServices.Count; newStats.AVPairsCount = serviceDescriptions.SelectMany(x => x.Data.Select(y => y.AttrValue)).Count(); newStats.AvgRegistrationsPerSecond = avgRegistrationsPerSecond; foreach (var srv in serviceDescriptions) { srv.OwnerNode = p2pServices.Select(p => p.Item1.Node).ElementAt(Rnd.Next(p2pServices.Count())); var ownerNodeStorageSrv = p2pServices.Single(s => s.Item2.Node.Equals(srv.OwnerNode)).Item2; var putSrvResult = ownerNodeStorageSrv.PutService(srv); if (!putSrvResult) { newStats.ServiceRegistrationFailsCount++; } if (avgRegistrationsPerSecond.HasValue) { Thread.Sleep((int)Math.Round(GetPoissonInterarrivalDelay(avgRegistrationsPerSecond.Value) * 1000)); } } var allServices = new Dictionary<long, ServiceDescription[]>(); foreach (var storageSrv in p2pServices.Select(x => x.Item2)) { allServices.Add(storageSrv.Node.Id, storageSrv.GetServicesLocal()); } newStats.NodesOverAVThresholdCount = allServices.Count(x => x.Value.Any(y => y.StorageState == ServiceStorageState.Failed)); Stats.Add(newStats); System.Console.WriteLine("Populating the data storage - Finished"); }
public bool PutService(ServiceDescription sd) { // TEMP: put service without performing remove - // 1) it seems 1to affect the overall execution time, 2) the out service operation is not atomic this way so there's a problem with "put service failed" processing // 1. remove all info about service // RemoveService(sd.Name, null); // 2. put new service try { var res = PutService(sd.Data.ToArray(), sd.Name, PutStorageBehavior.Overwrite); return res; } catch (PutServiceException) { return false; } }
public void PutServiceResponsibleNodes(ServiceDescription sd, PutStorageBehavior putBehavior) { LocalStorage.PutServiceResponsibleNodes(sd, putBehavior); }
private BsonDocument GetInsertLocalServiceDescription(ServiceDescription sd) { return new BsonDocument { { ServiceNameFieldName, sd.Name }, { ServiceStorageStateFieldName, Enum.GetName(typeof(ServiceStorageState), sd.StorageState) }, { ServiceDataFieldName, new BsonArray( sd.Data.Select(d => new BsonDocument { { AttributeFieldName, d.AttrValue.Key }, { ValueFieldName, GetTypedBsonValue(d) }, { ResponsibleNodeFieldName, Serializer.Serialize(d.ResponsibleNode) }, { ValueTypeFieldName, GetValueTypeFieldValue(d) } } ).ToArray() )} }; }
private BsonDocument GetInsertServiceResponsibleNodes(ServiceDescription sd) { return new BsonDocument { { ServiceNameFieldName, sd.Name }, { OwnerNodeFieldName, Serializer.Serialize(sd.OwnerNode) }, { ServiceDataFieldName, new BsonArray( sd.Data.Select(d => new BsonDocument { { AttributeFieldName, d.AttrValue.Key }, { ResponsibleNodeFieldName, Serializer.Serialize(d.ResponsibleNode) } } ) ) } }; }
public void PutServiceResponsibleNodes(ServiceDescription sd, PutStorageBehavior putBehavior) { var data = GetServiceDataCollection(); if (putBehavior == PutStorageBehavior.Overwrite) { data.Insert(GetInsertServiceResponsibleNodes(sd)); } else { var serviceDoc = data.FindOne(MongoQueryBuilder.EQ(ServiceNameFieldName, sd.Name)); if (serviceDoc == null) { data.Insert(GetInsertServiceResponsibleNodes(sd)); } else { foreach (var d in sd.Data) { var srvAttrDoc = data.FindOne( MongoQueryBuilder.And( MongoQueryBuilder.EQ(ServiceNameFieldName, sd.Name), MongoQueryBuilder.EQ(String.Format("{0}.{1}", ServiceDataFieldName, AttributeFieldName), d.AttrValue.Key) ) ); if (srvAttrDoc == null) { var srvDocData = serviceDoc[ServiceDataFieldName]; if (srvDocData == null) { serviceDoc[ServiceDataFieldName] = new BsonArray(); } (serviceDoc[ServiceDataFieldName].AsBsonArray).Add(new BsonDocument { { AttributeFieldName, d.AttrValue.Key }, { ResponsibleNodeFieldName, Serializer.Serialize(d.ResponsibleNode) } }); data.Save(serviceDoc); } } } } }
public void PutLocal(ServiceDescription sd, PutStorageBehavior putBehavior) { var data = GetLocalDataCollection(); if (putBehavior == PutStorageBehavior.Overwrite) { data.Insert(GetInsertLocalServiceDescription(sd)); } else if (putBehavior == PutStorageBehavior.Update) { var serviceDoc = data.FindOne(MongoQueryBuilder.EQ(ServiceNameFieldName, sd.Name)); if (serviceDoc == null) { data.Insert(GetInsertLocalServiceDescription(sd)); } else { foreach (var d in sd.Data) { var srvAttrDoc = data.FindOne( MongoQueryBuilder.And( MongoQueryBuilder.EQ(ServiceNameFieldName, sd.Name), MongoQueryBuilder.EQ(String.Format("{0}.{1}", ServiceDataFieldName, AttributeFieldName), d.AttrValue.Key) ) ); if (srvAttrDoc == null) { var srvDocData = serviceDoc[ServiceDataFieldName]; if (srvDocData == null) { serviceDoc[ServiceDataFieldName] = new BsonArray(); } (serviceDoc[ServiceDataFieldName].AsBsonArray).Add(new BsonDocument { { AttributeFieldName, d.AttrValue.Key }, { ValueFieldName, GetTypedBsonValue(d) }, { ResponsibleNodeFieldName, Serializer.Serialize(d.ResponsibleNode) }, { ValueTypeFieldName, GetValueTypeFieldValue(d) }, { ServiceStorageStateFieldName, Enum.GetName(typeof(ServiceStorageState), sd.StorageState) } }); data.Save(serviceDoc); } else { var srvAttrDocData = srvAttrDoc[ServiceDataFieldName].AsBsonArray; foreach (var item in srvAttrDocData) { var itemDoc = item.AsBsonDocument; if (itemDoc[AttributeFieldName].AsString == d.AttrValue.Key) { itemDoc[ValueFieldName] = GetTypedBsonValue(d); itemDoc[ValueTypeFieldName] = GetValueTypeFieldValue(d); itemDoc[ServiceStorageStateFieldName] = Enum.GetName(typeof(ServiceStorageState), sd.StorageState); break; } } data.Save(srvAttrDoc); } } } } }
private static void ProcessCommands(IList<IOverlayNodeService> srvs, IOverlayStorageService stSrv) { CancellationTokenSource showLocalInfoTs = null; var hashPrv = (IProvider<byte[], long>)SrvPrv.GetService("sha1KeyPrv"); Func<string, OverlayData[]> getStoragePutKeyValuesFromCmd = (string arg) => { var res = new List<OverlayData>(); foreach (var pair in arg.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)) { var pairAttrVal = pair.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries); // assume we have only one overlay level as for now res.Add(new OverlayData { AttrValue = new KeyValuePair<string,object>(pairAttrVal[0].Trim(), pairAttrVal[1].Trim()), OwnerNode = new NodeDescriptor(srvs[0].Node) }); } return res.ToArray(); }; Func<string, string[]> getStorageRemoveKeysFromCmd = (string arg) => { return arg .Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries) .Select(s => s.Trim()) .ToArray(); }; while (true) { var cmd = System.Console.ReadLine(); if (cmd.StartsWith("join")) { var cmdParts = cmd.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries); var taskFactory = new TaskFactory(TaskCreationOptions.LongRunning | TaskCreationOptions.AttachedToParent, TaskContinuationOptions.None); if (cmdParts.Length > 1) { var nodeInfo = cmdParts[1].Split(new[] { ":" }, StringSplitOptions.RemoveEmptyEntries); foreach (var srv in srvs) { // TODO: it is possible to wrap each join in a different thread and then wait on all threads so all joins will perform simultaneously var nInit = new NodeDescriptor.NodeInitInfo( cmdParts[1].IndexOf(":") > 0 ? nodeInfo[0] : NetworkHelper.GetLocalIpAddress(), // you could specify only the port number cmdParts[1].IndexOf(":") > 0 ? Convert.ToInt32(nodeInfo[1]) : Convert.ToInt32(nodeInfo[0]), ((LocalNode)srv.Node).OverlayLevel ); srv.Join(new NodeDescriptor( nInit, hashPrv.Provide(OverlayHelper.GetNodeHashArgument(nInit)) )); } } else { foreach (var srv in srvs) { // TODO: it is possible to wrap each join in a different thread and then wait on all threads so all joins will perform simultaneously srv.Join(); } } } else if (cmd == "info") { ShowLocalInfo(srvs); } else if (cmd == "startinfo") { showLocalInfoTs = StartShowLocalInfo(srvs); } else if (cmd == "stopinfo") { StopShowLocalInfo(showLocalInfoTs); } else if (cmd.StartsWith("put")) { Func<string, ServiceDescription> f = (string srvDescr) => { var res = new ServiceDescription { Name = srvDescr.Substring(0, srvDescr.IndexOf(":")), OwnerNode = srvs[0].Node, Data = new List<OverlayData>() }; foreach (var pair in srvDescr.Substring(srvDescr.IndexOf(":") + 1).Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)) { var pairAttrVal = pair.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries); // assume we have only one overlay level as for now res.Data.Add( new OverlayData { AttrValue = new KeyValuePair<string,object>(pairAttrVal[0].Trim(), pairAttrVal[1].Trim()), ServiceName = res.Name, OwnerNode = res.OwnerNode } ); } return res; }; stSrv.PutService(f(cmd.Substring("put".Length).Trim())); } else if (cmd.StartsWith("remove")) { stSrv.RemoveService(cmd.Substring("remove".Length).Trim()); } else if (cmd.StartsWith("update")) { var cmdParts = cmd.Substring("update".Length).Split(':', ';'); var addCmdPart = cmdParts[1]; var removeCmdPart = cmd.IndexOf(";") > 0 ? cmdParts[2] : null; stSrv.UpdateService( cmdParts[0].Trim(), String.IsNullOrWhiteSpace(addCmdPart) ? null : getStoragePutKeyValuesFromCmd(addCmdPart), String.IsNullOrWhiteSpace(removeCmdPart) ? null : getStorageRemoveKeysFromCmd(removeCmdPart) ); } else if (cmd.StartsWith("get")) { var res = stSrv.GetServices(Query.FromRelex(cmd.Substring("get".Length).Trim()), true); if (res != null && res.Any()) { System.Console.WriteLine("RESULTS:"); foreach (var r in res) { System.Console.WriteLine(String.Format("Service name: {0}", r.Name)); foreach (var d in r.Data) { System.Console.WriteLine(String.Format("{0} = {1} (Responsible node: {2})", d.AttrValue.Key, d.AttrValue.Value, d.ResponsibleNode.ToString())); } System.Console.WriteLine(String.Format("Service owner: {0}", r.OwnerNode.ToString())); } } else { System.Console.WriteLine("No data"); } } else if (cmd == "leave") { StopShowLocalInfo(showLocalInfoTs); foreach (var srv in srvs) { // wait until all instance internal threads are done srv.SendMessage(new OverlayNodeServiceMessage { MsgType = OverlayNodeServiceMessage.MessageType.LeaveRequested, WaitForProcessing = true }); } } else if (cmd == "exit") { StopShowLocalInfo(showLocalInfoTs); stSrv.Stop(); foreach (var srv in srvs) { // wait until all instance internal threads are done srv.SendMessage(new OverlayNodeServiceMessage { MsgType = OverlayNodeServiceMessage.MessageType.ExitRequested, WaitForProcessing = true }); } break; } else { System.Console.WriteLine(@" join [<address>:]<port> : Join the network with known node \r\n join: Create new network \r\n info: Show info about local node \r\n puts <servicename>:<attr>=<value>[,<attr>=<value>...]: Put service in the overlay \r\n put <attr>=<value>[,<attr>=<value>...]: Put data in the overlay \r\n removes <servicename>: Remove service data from overlay \r\n remove <attr>[,<attr>...]: Remove data associated with given attribute(s) \r\n update <servicename>:<add_attr>=<value>[,<add_attr>=<value>...];<remove_attr>[,<remove_attr>...]: Update info about service \r\n gets <relex query>: Find services by query \r\n get <relex query>: Find data by query \r\n leave: Leave the network \r\n exit: Exit the application" ); } } }
private static void ProcessCommands(IList<Tuple<IOverlayNodeService, IOverlayStorageService>> services) { Func<string, IOverlayNodeService, OverlayData[]> getStoragePutKeyValuesFromCmd = (string arg, IOverlayNodeService srv) => { var res = new List<OverlayData>(); foreach (var pair in arg.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)) { var pairAttrVal = pair.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries); // assume we have only one overlay level as for now res.Add(new OverlayData { AttrValue = new KeyValuePair<string,object>(pairAttrVal[0].Trim(), pairAttrVal[1].Trim()), OwnerNode = new NodeDescriptor(srv.Node) }); } return res.ToArray(); }; Func<string, string[]> getStorageRemoveKeysFromCmd = (string arg) => { return arg .Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries) .Select(s => s.Trim()) .ToArray(); }; while (true) { var cmd = System.Console.ReadLine(); var operatingSrv = services[Rnd.Next(0, services.Count)]; if (cmd.StartsWith("join")) { var existingNodesInOverlay = services.Select(s => s.Item1.Node).ToArray(); // chord service var nodeWhoJoinsInitInfo = new NodeDescriptor.NodeInitInfo( NetworkHelper.GetLocalIpAddress(), OverlayHelper.GetRandomPortNumber(existingNodesInOverlay.Select(n => n.Port).ToArray()), 1 ); var hashPrv = (IProvider<byte[], long>)SrvPrv.GetService("sha1KeyPrv"); var nodeWhoJoinsId = hashPrv.Provide(OverlayHelper.GetNodeHashArgument(nodeWhoJoinsInitInfo)); var nodeWhoJoinsVm = new Vm( Convert.ToInt32(nodeWhoJoinsId), CloudBroker.getId(), 400, 1, 512, 1000, 10000, "Xen", new CloudletSchedulerTimeShared() ); var nodeWhoJoins = new VmOverlayNode( nodeWhoJoinsInitInfo, nodeWhoJoinsId, nodeWhoJoinsVm ); var nodeWhoJoinsChordService = (IOverlayNodeService)SrvPrv.GetService("chordOverlayNodeService"); nodeWhoJoinsChordService.Bind(new LocalNode(nodeWhoJoins)); nodeWhoJoinsChordService.Join( existingNodesInOverlay[Rnd.Next(0, existingNodesInOverlay.Length)] ); // respective storage service var nodeWhoJoinsStorageService = (IOverlayStorageService)SrvPrv.GetService("mongoDbOverlayStorageService"); nodeWhoJoinsStorageService.Bind(new[] { nodeWhoJoinsChordService }.ToList()); nodeWhoJoinsStorageService.Start(); // add a VM to the broker CloudBroker.scheduleNow( CloudDatacenter.getName(), CloudSimTags.VM_CREATE, nodeWhoJoinsVm ); } else if (cmd == "leave") { var cmdParts = cmd.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); var srvToLeave = services.FirstOrDefault(s => s.Item1.Node.Id == Convert.ToInt64(cmdParts[1])); if (srvToLeave != null) { srvToLeave.Item2.Stop(); srvToLeave.Item1.SendMessage(new OverlayNodeServiceMessage { MsgType = OverlayNodeServiceMessage.MessageType.ExitRequested, WaitForProcessing = true }); // remove a VM for this node CloudBroker.scheduleNow( CloudDatacenter.getName(), CloudSimTags.VM_DESTROY, ((VmOverlayNode)srvToLeave.Item1.Node).OwnedVm ); } else { System.Console.WriteLine("No such node"); } } else if (cmd == "stop") { break; } else if (cmd.StartsWith("put")) { Func<string, IOverlayNodeService, ServiceDescription> f = (string srvDescr, IOverlayNodeService overlaySrv) => { var res = new ServiceDescription { Name = srvDescr.Substring(0, srvDescr.IndexOf(":")), OwnerNode = overlaySrv.Node, Data = new List<OverlayData>() }; foreach (var pair in srvDescr.Substring(srvDescr.IndexOf(":") + 1).Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)) { var pairAttrVal = pair.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries); // assume we have only one overlay level as for now res.Data.Add( new OverlayData { AttrValue = new KeyValuePair<string,object>(pairAttrVal[0].Trim(), pairAttrVal[1].Trim()), ServiceName = res.Name, OwnerNode = res.OwnerNode } ); } return res; }; var cmdParts = cmd.Substring("put".Length).Trim().Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); var ownerSrv = services.FirstOrDefault(s => s.Item1.Node.Id == Convert.ToInt64(cmdParts[1])); if (ownerSrv != null) { ownerSrv.Item2.PutService(f( cmdParts[1], ownerSrv.Item1 )); } else { System.Console.WriteLine("No such node"); } } else if (cmd.StartsWith("remove")) { operatingSrv.Item2.RemoveService(cmd.Substring("remove".Length).Trim()); } else if (cmd.StartsWith("update")) { var cmdParts = cmd.Substring("update".Length).Split(':', ';'); var addCmdPart = cmdParts[1]; var removeCmdPart = cmd.IndexOf(";") > 0 ? cmdParts[2] : null; operatingSrv.Item2.UpdateService( cmdParts[0].Trim(), String.IsNullOrWhiteSpace(addCmdPart) ? null : getStoragePutKeyValuesFromCmd(addCmdPart, operatingSrv.Item1), String.IsNullOrWhiteSpace(removeCmdPart) ? null : getStorageRemoveKeysFromCmd(removeCmdPart) ); } else if (cmd.StartsWith("get")) { var res = operatingSrv.Item2.GetServices(Query.FromRelex(cmd.Substring("get".Length).Trim()), true); if (res != null && res.Any()) { System.Console.WriteLine("**************************************************"); System.Console.WriteLine("RESULTS:"); foreach (var r in res) { System.Console.WriteLine("\r\n=============================================================="); System.Console.WriteLine(String.Format("Service name: {0}", r.Name)); foreach (var d in r.Data) { System.Console.WriteLine(String.Format("{0} = {1} (Responsible node: {2})", d.AttrValue.Key, d.GetFormattedValue(), d.ResponsibleNode.ToString())); } System.Console.WriteLine(String.Format("Service owner: {0}", r.OwnerNode.ToString())); System.Console.WriteLine("==============================================================\r\n"); } } else { System.Console.WriteLine("No data"); } } } }
private static ServiceDescription[] GetServiceDescriptions(string filename) { var result = new List<ServiceDescription>(); Func<string, string> getValidBooleanString = (string s) => { if (s == "no" || s == "0" || s == "false") { return Boolean.FalseString; } else if (s == "yes" || s == "1" || s == "true") { return Boolean.TrueString; } throw new ArgumentException(String.Format("Value '{0}' cannot be converted to boolean", s)); }; Func<string, Type, string, object> getTypedValue = (string val, Type type, string typeStr) => { string vv = val.Trim(); if (type == typeof(bool)) { vv = getValidBooleanString(vv); } if (typeStr == "time") { vv = Convert.ToString(TimeSpan.Parse(vv).TotalMilliseconds); } return TypeDescriptor.GetConverter(type).ConvertFrom(vv); }; using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.None)) { using (var xmlRdr = XmlReader.Create(fs, new XmlReaderSettings { IgnoreComments = true, IgnoreWhitespace = true })) { var xml = XDocument.Load(xmlRdr); var nodes = xml.Root.Descendants(XName.Get("node")); var counter = 1; foreach (var srvNode in nodes) { var srvDescription = new ServiceDescription { Data = new List<OverlayData>(), Name = "CloudService_" + Rnd.Next(1, 1000000), OwnerNode = new StubNodeDescriptor(counter) }; foreach (var item in srvNode.Descendants()) { var od = new OverlayData { ServiceName = srvDescription.Name, OwnerNode = srvDescription.OwnerNode }; object typedValue = item.Value; if (item.Attribute("type") != null) { var typeStr = item.Attribute("type").Value; var originalTypeStr = typeStr; if (typeStr.StartsWith("array[")) { typeStr = typeStr.Replace("array[", "").Replace("]",""); } Type type = null; switch (typeStr) { case "int" : type = typeof(int); break; case "boolean" : type = typeof(bool); break; case "double" : type = typeof(double); break; case "date" : type = typeof(DateTime); break; case "time" : type = typeof(int); break; } if (type != null) { od.ValueType = new OverlayData.TypeInfo { InternalType = type, IsArray = originalTypeStr.StartsWith("array["), IsTime = typeStr == "time" }; if (od.ValueType.IsArray) { // don't forget to remove '[' and ']' typedValue = item.Value.Substring(1, item.Value.Length - 2) .Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries) .Select(v => getTypedValue(v, od.ValueType.InternalType, typeStr)) .ToArray(); } else { typedValue = getTypedValue(item.Value, od.ValueType.InternalType, typeStr); } } } od.AttrValue = new KeyValuePair<string,object>(item.Name.LocalName, typedValue); srvDescription.Data.Add(od); } result.Add(srvDescription); ++counter; } } } return result.ToArray(); }