/// <summary> /// Builds all components in this map. /// </summary> /// <param name="loopState">State of the loop.</param> public override void Stage(ParallelLoopState loopState) { var allQueues = Configuration.ManifestSet.SelectMany(n => n.ActivityPrintQueues.Values.SelectMany(m => m.OfType <RemotePrintQueueInfo>())); foreach (RemotePrintQueueInfo queue in allQueues.GroupBy(n => n.PrintQueueId).Select(n => n.First())) { RemotePrintQueueElements.Add(new RemotePrintQueueElement(queue.QueueName, queue.ServerHostName)); } try { Parallel.ForEach <RemotePrintQueueElement>(RemotePrintQueueElements, (h, l) => h.Stage(l)); if (!SessionMapElement.AllElementsSetTo <RemotePrintQueueElement>(RemotePrintQueueElements, RuntimeState.Available)) { loopState.Break(); return; } MapElement.UpdateStatus("Available", RuntimeState.Available); } catch (AggregateException ex) { MapElement.UpdateStatus(RuntimeState.Error, "Staging error", ex); throw; } }
/// <summary> /// Initializes a new instance of the <see cref="ResourceProfile" /> class. /// </summary> /// <param name="detail">The detail.</param> /// <param name="resourceName">Name of the resource.</param> public ResourceMetadata(string resourceName, ResourceMetadataDetail detail) { ResourceName = resourceName; Detail = detail; //MapElement = new SessionMapElement("{0}:{1}".FormatWith(resourceName, detail.Name), ElementType.ResourceMetadata, detail.MetadataType); MapElement = new SessionMapElement(detail.Name, ElementType.Activity, detail.MetadataType); }
/// <summary> /// Turns on all resource hosts in this map. /// </summary> public override void PowerUp(ParallelLoopState loopState) { try { MapElement.UpdateStatus("Starting", RuntimeState.Starting); TraceFactory.Logger.Debug("Calling PowerUp() in parallel on each Host"); Parallel.ForEach <ResourceHost>(Hosts, (h, l) => h.PowerUp(l)); if (!SessionMapElement.AllElementsSetTo <ResourceHost>(Hosts, RuntimeState.Ready)) { MapElement.UpdateStatus(RuntimeState.Error); loopState.Break(); return; } MapElement.UpdateStatus("Ready", RuntimeState.Ready); } catch (AggregateException ex) { TraceFactory.Logger.Error(ex.Message); // Log the exception at this element level, then throw again to catch it higher MapElement.UpdateStatus(RuntimeState.Error, "Power up error", ex); throw; } }
/// <summary> /// Initializes a new instance of the <see cref="RemotePrintQueueElement"/> class. /// </summary> /// <param name="printQueueName">Name of the print queue.</param> /// <param name="serverName">Name of the server that the print queue is on.</param> public RemotePrintQueueElement(string printQueueName, string serverName) { PrintQueueName = printQueueName; PrintServerName = serverName; MapElement = new SessionMapElement(PrintQueueName, ElementType.RemotePrintQueue, "Remote Print Queue"); }
public override void Validate(ParallelLoopState loopState, SystemManifest manifest, string machineName) { TraceFactory.Logger.Debug("Validating activities for {0} on Machine {1}".FormatWith(Id, machineName)); Parallel.ForEach <ResourceMetadata>(Metadata, (m, l) => m.Validate(l, Id, manifest, machineName)); if (SessionMapElement.AnyElementsSetTo <ResourceMetadata>(Metadata, RuntimeState.Error)) { var elements = SessionMapElement.GetElements <ResourceMetadata>(RuntimeState.Error, Metadata).Select(x => x.Detail.Name); TraceFactory.Logger.Debug("Metadata in ERROR: {0}".FormatWith(string.Join(", ", elements.ToArray()))); TraceFactory.Logger.Debug("Activity validation failed for {0}".FormatWith(Id)); MapElement.UpdateStatus("Activity validation failed", RuntimeState.Error); loopState.Break(); return; } else if (SessionMapElement.AnyElementsSetTo <ResourceMetadata>(Metadata, RuntimeState.Warning)) { var elements = SessionMapElement.GetElements <ResourceMetadata>(RuntimeState.Warning, Metadata).Select(x => x.Detail.Name); TraceFactory.Logger.Debug("Metadata in WARNING: {0}".FormatWith(string.Join(", ", elements.ToArray()))); TraceFactory.Logger.Debug("Activity validation caused a warning for {0}".FormatWith(Id)); MapElement.UpdateStatus("Activity validation caused a warning", RuntimeState.Warning); return; } MapElement.UpdateStatus("Validated", RuntimeState.Validated); }
/// <summary> /// Builds all components in this map. /// </summary> public override void Stage(ParallelLoopState loopState) { Thread.CurrentThread.SetName("Stage-{0}".FormatWith(Thread.CurrentThread.ManagedThreadId)); TraceFactory.Logger.Debug("Entering..."); // Use the index to create an initial unique hostname that will be // replaced during the validation stage with an actual hostname. foreach (var manifest in Configuration.ManifestSet) { ResourceHost host = new ResourceHost(manifest); host.OnResourcesComplete += new EventHandler(ResourceHostsCompleted); Hosts.Add(host); } try { Parallel.ForEach <ResourceHost>(Hosts, (h, l) => h.Stage(l)); if (!SessionMapElement.AllElementsSetTo <ResourceHost>(Hosts, RuntimeState.Available)) { loopState.Break(); return; } } catch (AggregateException ex) { // Log the exception at this element level, then throw again to catch it higher MapElement.UpdateStatus(RuntimeState.Error, "Staging error", ex); throw; } }
/// <summary> /// Updates this instance from a source copy. /// </summary> /// <param name="source">The source.</param> public void UpdateFrom(SessionMapElement source) { Name = source.Name; State = source.State; Message = source.Message; ErrorDetail = source.ErrorDetail; }
/// <summary> /// Initializes all components in this map. /// </summary> public override void Revalidate(ParallelLoopState loopState) { Thread.CurrentThread.SetName("Revalidate-{0}".FormatWith(Thread.CurrentThread.ManagedThreadId)); // If we got into a hard error state (not an aggregate error), we won't be able to recover if (MapElement.State == RuntimeState.Error) { MapElement.UpdateStatus(); return; } MapElement.UpdateStatus("Validating", RuntimeState.Validating); try { Parallel.ForEach <ResourceHost>(Hosts, (h, l) => h.Revalidate(l)); if (!SessionMapElement.AllElementsSetTo <ResourceHost>(Hosts, RuntimeState.Validated)) { MapElement.UpdateStatus(RuntimeState.AggregateError); loopState.Break(); return; } MapElement.UpdateStatus("Validated", RuntimeState.Validated); } catch (AggregateException ex) { // Log the exception at this element level, then throw again to catch it higher MapElement.UpdateStatus(RuntimeState.Error, "Validation error", ex); throw; } }
/// <summary> /// Initializes a new instance of the <see cref="ResourceInstance"/> class. /// </summary> /// <param name="instanceId">The unique key for this instance.</param> /// <param name="detail">The detail information from the <see cref="SystemManifest"/>.</param> public ResourceInstance(string instanceId, ResourceDetailBase detail) { Metadata = new Collection <ResourceMetadata>(); Detail = detail; Id = instanceId; MapElement = new SessionMapElement(instanceId, ElementType.Worker) { ElementSubtype = detail.ResourceType.ToString(), ResourceId = Detail.ResourceId }; Endpoint = null; // Add the metadata detail to the collection foreach (var data in Detail.MetadataDetails) { var metadata = new ResourceMetadata(Id, data); // Clear the message, we will not worry about showing anything at this level. metadata.MapElement.Message = string.Empty; Metadata.Add(metadata); } TraceFactory.Logger.Debug("{0} created".FormatWith(instanceId)); }
private void PublishSessionMapElementHandler(SessionMapElement element) { _lastUpdate = DateTime.Now; LastSessionMapElement = element; if (_mapElementReceived != null) { _mapElementReceived(this, new SessionMapElementEventArgs(element)); } }
/// <summary> /// Executes this resource host, which may mean different things. /// </summary> public void Run(ParallelLoopState loopState) { Parallel.ForEach <ResourceInstance>(Resources, (r, l) => r.Run(l)); if (!SessionMapElement.AllElementsSetTo <ResourceInstance>(Resources, RuntimeState.Running)) { TraceFactory.Logger.Debug("{0}: Not all resources reached a running state".FormatWith(Machine.Name)); loopState.Break(); } MapElement.UpdateStatus("Running", RuntimeState.Running); }
/// <summary> /// Updates the state of the component. /// </summary> /// <param name="element">The state.</param> public void PublishSessionMapElement(SessionMapElement element) { try { ThreadPool.QueueUserWorkItem(t => PublishSessionMapElementHandler(element)); } catch (Exception ex) { TraceFactory.Logger.Error("Exception", ex); throw; } }
/// <summary> /// Initializes all components in this map. /// </summary> public override void Validate(ParallelLoopState loopState) { Thread.CurrentThread.SetName("Validate-{0}".FormatWith(Thread.CurrentThread.ManagedThreadId)); TraceFactory.Logger.Debug("Entering..."); MapElement.UpdateStatus("Validating", RuntimeState.Validating); try { TraceFactory.Logger.Debug("Reserving required VMs"); // Try to allocate all the needed VMs if this fails then an error // state will be sent back to the client. _resourcePool.ReserveMachines(); } catch (Exception ex) { TraceFactory.Logger.Error(ex); MapElement.UpdateStatus(ex.Message, RuntimeState.Error); loopState.Break(); return; } try { // First assign a machine instance to each host. This needs to be done before // calling validate on each host. foreach (var host in Hosts) { TraceFactory.Logger.Debug("Assigning machine {0}".FormatWith(host.Machine.Name)); _resourcePool.AssignMachine(host); } Parallel.ForEach <ResourceHost>(Hosts, (h, l) => h.Validate(l)); // Both "Validated" and "Warning" are valid states to allow the system to continue. if (!SessionMapElement.AllElementsSetTo <ResourceHost>(Hosts, RuntimeState.Validated, RuntimeState.Warning)) { MapElement.UpdateStatus(RuntimeState.AggregateError); loopState.Break(); return; } MapElement.UpdateStatus("Validated", RuntimeState.Validated); } catch (AggregateException ex) { // Log the exception at this element level, then throw again to catch it higher MapElement.UpdateStatus(RuntimeState.Error, "Validation error", ex); throw; } }
private void SetSessionContext(SessionMapElement element) { string sessionId = null; string elementId = null; if (element != null) { sessionId = element.SessionId; elementId = element.Id.ToString(); } TraceFactory.SetSessionContext(sessionId); TraceFactory.SetThreadContextProperty("SessionMapElementId", elementId, false); }
/// <summary> /// Initializes this asset /// </summary> public virtual void Validate(ParallelLoopState loopState) { Thread.CurrentThread.SetName("Validate-{0}".FormatWith(Thread.CurrentThread.ManagedThreadId)); MapElement.UpdateStatus("Validating", RuntimeState.Validating); try { TraceFactory.Logger.Debug("Validating host {0}".FormatWith(Machine.Name)); Machine.Validate(); // In case a new Machine was chosen, update the name of the map element to be consistent. MapElement.Name = Machine.Name; MapElement.UpdateStatus(); Manifest.HostMachine = Machine.Name; } catch (Exception ex) { TraceFactory.Logger.Error(ex); MapElement.UpdateStatus(ex.Message, RuntimeState.Error); loopState.Break(); return; } TraceFactory.Logger.Debug("Now validating each resource running on {0}".FormatWith(Machine.Name)); Parallel.ForEach <ResourceInstance>(Resources, (r, l) => r.Validate(l, Manifest, Machine.Name)); if (SessionMapElement.AnyElementsSetTo <ResourceInstance>(Resources, RuntimeState.Error)) { var elements = SessionMapElement.GetElements <ResourceInstance>(RuntimeState.Error, Resources).Select(x => x.Id); TraceFactory.Logger.Debug("Resources in ERROR: {0}".FormatWith(string.Join(", ", elements.ToArray()))); TraceFactory.Logger.Debug("Resource validation for {0}".FormatWith(Machine.Name)); MapElement.UpdateStatus("Resource validation failed", RuntimeState.Error); loopState.Break(); return; } else if (SessionMapElement.AnyElementsSetTo <ResourceInstance>(Resources, RuntimeState.Warning)) { var elements = SessionMapElement.GetElements <ResourceInstance>(RuntimeState.Warning, Resources).Select(x => x.Id); TraceFactory.Logger.Debug("Resources in WARNING: {0}".FormatWith(string.Join(", ", elements.ToArray()))); TraceFactory.Logger.Debug("Resource validation caused warning on {0}".FormatWith(Machine.Name)); MapElement.UpdateStatus("Resource validation caused a warning", RuntimeState.Warning); return; } MapElement.UpdateStatus("Validated", RuntimeState.Validated); }
/// <summary> /// Builds all components in this map. /// </summary> public override void Stage(ParallelLoopState loopState) { foreach (var asset in Configuration.ManifestSet.SelectMany(x => x.Assets.Devices).Distinct()) { var className = string.Empty; var attribute = ( from a in asset.GetType().GetCustomAttributes(true) where a.GetType() == typeof(AssetHostAttribute) select a as AssetHostAttribute ).FirstOrDefault(); if (attribute != null) { className = "{0}.{1}".FormatWith(GetType().Namespace, attribute.ClassName); } else { var assetName = asset.GetType().Name; var exception = new DispatcherOperationException("Invalid AssetHost class for {0}".FormatWith(assetName)); MapElement.UpdateStatus(RuntimeState.Error, "Invalid asset: ".FormatWith(assetName), exception); } TraceFactory.Logger.Debug(string.Format("Type:{0} Asset: {1}", className, asset.Description)); var assetHost = (AssetHost)Activator.CreateInstance(Type.GetType(className), new object[] { asset }); TraceFactory.Logger.Debug("Adding {0}".FormatWith(assetHost.Asset.AssetId)); Hosts.Add(assetHost); } try { Parallel.ForEach <AssetHost>(Hosts, (h, l) => h.Stage(l)); if (!SessionMapElement.AllElementsSetTo <AssetHost>(Hosts, RuntimeState.Available)) { loopState.Break(); return; } MapElement.UpdateStatus("Available", RuntimeState.Available); } catch (AggregateException ex) { // Log the exception at this element level, the throw again to catch it higher MapElement.UpdateStatus(RuntimeState.Error, "Staging error", ex); throw; } }
private void PublishSessionMapElementHandler(SessionMapElement element, Uri subscriber) { try { using (SessionClientConnection callback = GetConnection(subscriber)) { //TraceFactory.Logger.Debug("PublishSessionMapElement({0}, {1})".FormatWith(element.Name, subscriber.AbsoluteUri)); callback.Channel.PublishSessionMapElement(element); //TraceFactory.Logger.Debug("PublishSessionMapElement({0}, {1})...DONE".FormatWith(element.Name, subscriber.AbsoluteUri)); } } catch (Exception ex) { TraceFactory.Logger.Debug("Error: {0}: {1}".FormatWith(subscriber.AbsoluteUri, ex.Message)); DropSubscriber(subscriber); } }
/// <summary> /// Runs all components in this map. /// </summary> /// <param name="loopState">State of the loop.</param> public override void Run(ParallelLoopState loopState) { try { Parallel.ForEach <RemotePrintQueueElement>(RemotePrintQueueElements, (h, l) => h.Run(l)); if (!SessionMapElement.AllElementsSetTo <RemotePrintQueueElement>(RemotePrintQueueElements, RuntimeState.Running)) { loopState.Break(); } MapElement.UpdateStatus("Running", RuntimeState.Running); } catch (AggregateException ex) { MapElement.UpdateStatus(RuntimeState.Error, "Run error", ex); throw; } }
/// <summary> /// Runs all components in this map. /// </summary> public override void Run(ParallelLoopState loopState) { try { Parallel.ForEach <AssetHost>(Hosts, (h, l) => h.Run(l)); if (!SessionMapElement.AllElementsSetTo <AssetHost>(Hosts, RuntimeState.Running)) { loopState.Break(); } MapElement.UpdateStatus("Running", RuntimeState.Running); } catch (AggregateException ex) { // Log the exception at this element level, the throw again to catch it higher MapElement.UpdateStatus(RuntimeState.Error, "Run error", ex); throw; } }
/// <summary> /// Shuts down all maps using the specified options /// </summary> /// <param name="options">The shutdown options (unused).</param> /// <param name="loopState">State of the loop.</param> public override void Shutdown(ShutdownOptions options, ParallelLoopState loopState) { try { MapElement.UpdateStatus("Shutdown", RuntimeState.ShuttingDown); Parallel.ForEach <RemotePrintQueueElement>(RemotePrintQueueElements, (h, l) => h.Shutdown(options, l)); if (!SessionMapElement.AllElementsSetTo <RemotePrintQueueElement>(RemotePrintQueueElements, RuntimeState.Offline)) { loopState.Break(); } MapElement.UpdateStatus("Offline", RuntimeState.Offline); } catch (AggregateException ex) { MapElement.UpdateStatus(RuntimeState.Error, "Shutdown error", ex); throw; } }
/// <summary> /// Turns on all components in this map. /// </summary> /// <param name="loopState">State of the loop.</param> public override void PowerUp(ParallelLoopState loopState) { try { MapElement.UpdateStatus("Starting", RuntimeState.Starting); Parallel.ForEach <RemotePrintQueueElement>(RemotePrintQueueElements, (h, l) => h.PowerUp(l)); if (!SessionMapElement.AllElementsSetTo <RemotePrintQueueElement>(RemotePrintQueueElements, RuntimeState.Ready)) { loopState.Break(); } MapElement.UpdateStatus("Ready", RuntimeState.Ready); } catch (AggregateException ex) { MapElement.UpdateStatus(RuntimeState.Error, "Power up error", ex); throw; } }
/// <summary> /// Turns on all components in this map. /// </summary> public override void PowerUp(ParallelLoopState loopState) { try { TraceFactory.Logger.Debug("Starting..."); MapElement.UpdateStatus("Starting", RuntimeState.Starting); Parallel.ForEach <AssetHost>(Hosts, (h, l) => h.PowerUp(l)); if (!SessionMapElement.AllElementsSetTo <AssetHost>(Hosts, RuntimeState.Ready)) { loopState.Break(); } MapElement.UpdateStatus("Ready", RuntimeState.Ready); } catch (AggregateException ex) { // Log the exception at this element level, the throw again to catch it higher MapElement.UpdateStatus(RuntimeState.Error, "Power up error", ex); throw; } }
/// <summary> /// Shuts down all maps /// </summary> public override void Shutdown(ShutdownOptions options, ParallelLoopState loopState) { // The shutdown options are not used by the asset map so just ignore them try { MapElement.UpdateStatus("Shutdown", RuntimeState.ShuttingDown); Parallel.ForEach <AssetHost>(Hosts, (h, l) => h.Shutdown(options, l)); if (!SessionMapElement.AllElementsSetTo <AssetHost>(Hosts, RuntimeState.Offline)) { loopState.Break(); } MapElement.UpdateStatus("Offline", RuntimeState.Offline); } catch (AggregateException ex) { // Log the exception at this element level, the throw again to catch it higher MapElement.UpdateStatus(RuntimeState.Error, "Shutdown error", ex); throw; } }
/// <summary> /// Initializes a new instance of the <see cref="ResourceHost" /> class. /// </summary> /// <param name="manifest">The manifest.</param> public ResourceHost(SystemManifest manifest) { Manifest = manifest; // Set the logging thread context if (manifest != null) { TraceFactory.SetThreadContextProperty("SessionId", manifest.SessionId, false); TraceFactory.SetThreadContextProperty("Dispatcher", manifest.Dispatcher, false); } Resources = new Collection <ResourceInstance>(); // Define an empty machine class as simply a placeholder. It will be replaced with an // actual machine class in the validate step. Machine = new HostMachine(manifest); Machine.OnStatusChanged += Machine_OnStatusChanged; // Create a temporary Id for the map element as it won't be set until the machines are created MapElement = new SessionMapElement(Guid.NewGuid().ToString(), ElementType.Machine); MapElement.Enabled = false; }
/// <summary> /// Revalidates the state /// </summary> /// <param name="loopState"></param> public override void Revalidate(ParallelLoopState loopState) { try { MapElement.UpdateStatus("Validating", RuntimeState.Validating); Parallel.ForEach <AssetHost>(Hosts, (h, l) => h.Revalidate(l)); // Used to call Validate() if (SessionMapElement.AnyElementsSetTo(Hosts, RuntimeState.Error, RuntimeState.AggregateError)) { TraceFactory.Logger.Debug("Some elements not validated"); MapElement.UpdateStatus(RuntimeState.AggregateError); loopState.Break(); return; } MapElement.UpdateStatus("Validated", RuntimeState.Validated); } catch (AggregateException ex) { // Log the exception at this element level, the throw again to catch it higher MapElement.UpdateStatus(RuntimeState.Error, "Validation error", ex); throw; } }
/// <summary> /// Initializes all components in this map. /// </summary> /// <param name="loopState">State of the loop.</param> public override void Validate(ParallelLoopState loopState) { try { MapElement.UpdateStatus("Validating", RuntimeState.Validating); Parallel.ForEach <RemotePrintQueueElement>(RemotePrintQueueElements, (h, l) => h.Validate(l)); if (SessionMapElement.AnyElementsSetTo(RemotePrintQueueElements, RuntimeState.Error, RuntimeState.AggregateError)) { TraceFactory.Logger.Error("Some elements not validated"); MapElement.UpdateStatus(RuntimeState.AggregateError); loopState.Break(); return; } MapElement.UpdateStatus("Validated", RuntimeState.Validated); } catch (AggregateException ex) { MapElement.UpdateStatus(RuntimeState.Error, "Validation error", ex); throw; } }
/// <summary> /// Initializes a new instance of the <see cref="AssetHost" /> class. /// </summary> /// <param name="asset">The asset data.</param> /// <param name="name">The name of this host.</param> /// <param name="type">The type of status element.</param> /// <param name="subtype">The subtype.</param> public AssetHost(AssetDetail asset, string name, ElementType type, string subtype) { Asset = asset; MapElement = new SessionMapElement(name, type, subtype); AssetMemoryRetrieved = DateTime.Now.AddDays(-1); }
/// <summary> /// Initializes a new instance of the <see cref="SessionMapObject"/> class. /// </summary> /// <param name="config">The system manifest information.</param> /// <param name="type">The type of element, used by the <see cref="SessionMapElement"/>.</param> public SessionMapObject(SystemManifestAgent config, ElementType type) { Configuration = config; MapElement = new SessionMapElement(type.ToString(), type); }
/// <summary> /// Initializes a new instance of the <see cref="SessionMapObject"/> class. /// </summary> /// <param name="config">The configuration.</param> /// <param name="type">The type.</param> /// <param name="elementName">Name of the element.</param> public SessionMapObject(SystemManifestAgent config, ElementType type, string elementName) { Configuration = config; MapElement = new SessionMapElement(elementName, type); }
/// <summary> /// Initializes a new instance of the <see cref="SessionMapElementEventArgs"/> class. /// </summary> /// <param name="mapElement">The element.</param> public SessionMapElementEventArgs(SessionMapElement mapElement) { MapElement = mapElement; }