/// <summary>
        /// Sets up this instance using the specified client controller host name.
        /// </summary>
        /// <param name="clientControllerHostName">Name of the client controller host.</param>
        public static OfficeWorkerActivityController Create(string clientControllerHostName, string instanceId)
        {
            // The office worker is a separate process, so it must make a call up to the client controller to obtain
            // the manifest that will be used for the test.
            SystemManifest manifest = null;

            using (var serviceConnection = ClientControllerServiceConnection.Create(clientControllerHostName))
            {
                var data = serviceConnection.Channel.GetManifest(instanceId);
                manifest = SystemManifest.Deserialize(data);
                manifest.PushToGlobalDataStore(instanceId);
                manifest.PushToGlobalSettings();
                _sessionId    = manifest.SessionId;
                _statusLogger = new VirtualResourceInstanceStatusLogger(_sessionId, Environment.UserName, 0, Enum.GetName(typeof(RuntimeState), 6), false, GlobalDataStore.ResourceInstanceId);
            }


            TraceFactory.Logger.Debug("Resource type: {0}".FormatWith(manifest.ResourceType));
            TraceFactory.Logger.Debug("InstanceId: {0}".FormatWith(GlobalDataStore.ResourceInstanceId));
            TraceFactory.Logger.Debug("UserName: {0}".FormatWith(GlobalDataStore.Credential.UserName));

            FrameworkServicesInitializer.InitializeExecution();

            return(ObjectFactory.Create <OfficeWorkerActivityController>(manifest.ResourceType, clientControllerHostName));
        }
        /// <summary>
        /// Starts the OfficeWorker handler to run the controller as an Office Worker
        /// </summary>
        public void Start()
        {
            // Don't try to catch an error here.  There must be a credential entry in the manifest
            // that aligns with the current user running this process.
            var credential = GlobalDataStore.Credential;

            TraceFactory.Logger.Debug("Opening command service endpoint: {0}".FormatWith(credential.UserName));

            _commandService = CreateServiceHost(credential.Port);
            _commandService.Open();

            TraceFactory.Logger.Debug(_commandService.BaseAddresses[0].AbsoluteUri);

            SubscribeToEventBus();

            Action action = () =>
            {
                // Notify the client controller that the work is setup and ready to go.  This will give
                // the controller an opportunity to perform any system wide setup activities before
                // the worker notifies the dispatcher that it is ready to go.
                using (ClientControllerServiceConnection serviceConnection = ClientControllerServiceConnection.Create(_clientControllerHostName))
                {
                    TraceFactory.Logger.Debug(
                        $"Notifying controller to perform any system wide tasks, waiting to be notified to register. {_commandService.BaseAddresses[0]}");
                    serviceConnection.Channel.NotifyResourceState(_commandService.BaseAddresses[0], RuntimeState.Ready);
                }
            };

            Retry.WhileThrowing(action, 5, TimeSpan.Zero, new List <Type>()
            {
                typeof(TimeoutException)
            });

            TraceFactory.Logger.Debug("Controller started.");
        }
Beispiel #3
0
        private void LoadManifest(ref string instanceId)
        {
            // Get the manifest from the factory
            TraceFactory.Logger.Debug("Attempting to get the manifest from the Factory Service");
            SystemManifest manifest = null;

            using (var clientController = ClientControllerServiceConnection.Create(Environment.MachineName))
            {
                var data = clientController.Channel.GetManifest(instanceId);
                manifest = SystemManifest.Deserialize(data);
            }

            // Cache the definition that corresponds to the resourceId
            var definition = manifest.Resources.GetByType(VirtualResourceType.PerfMonCollector).FirstOrDefault();

            if (definition == null)
            {
                throw new InvalidOperationException("Resource Definition is null.");
            }

            manifest.PushToGlobalSettings();
            manifest.PushToGlobalDataStore(definition.Name);

            _sessionId = manifest.SessionId;

            // get all the resources which are of type perfmoncollector
            var perfMonResources = manifest.Resources.Where(c => c.ResourceType == VirtualResourceType.PerfMonCollector);

            // if we have permoncounter collectors then we read manifest
            if (perfMonResources.Count() > 0)
            {
                ReadManifest(perfMonResources);
            }
            else
            {
                throw new InvalidOperationException("No performance counters to monitor");
            }


            TraceFactory.Logger.Info(Environment.NewLine + manifest.ToString());
        }
Beispiel #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="VirtualResourceHandler" /> class.
        /// </summary>
        /// <param name="manifest">The manifest.</param>
        /// <exception cref="System.ArgumentNullException">manifest</exception>
        protected VirtualResourceHandler(SystemManifest manifest)
        {
            if (manifest == null)
            {
                throw new ArgumentNullException("manifest");
            }

            SystemManifest = manifest;

            if (_clientService == null)
            {
                try
                {
                    _clientService = ClientControllerServiceConnection.CreateServiceHost(this);
                    _clientService.Open();
                    TraceFactory.Logger.Debug("Started Service Host: {0}".FormatWith(_clientService.BaseAddresses[0].AbsoluteUri));
                }
                catch (Exception)
                {
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Copies the logs.
        /// </summary>
        protected void CopyClientControllerLogs()
        {
            TraceFactory.Logger.Debug("Copying additional files from {0}".FormatWith(Machine.Name));
            LogFileDataCollection logFiles = new LogFileDataCollection();

            try
            {
                using (var clientController = ClientControllerServiceConnection.Create(Machine.Name))
                {
                    logFiles = clientController.Channel.GetLogFiles(Manifest.SessionId);
                }
            }
            catch (Exception ex)
            {
                TraceFactory.Logger.Error("Unable to capture client controller log files for {0} : {1}"
                                          .FormatWith(Machine.Name, ex.ToString()));
            }

            if (GlobalSettings.IsDistributedSystem)
            {
                try
                {
                    using (var printMonitor = new WcfClient <IPrintMonitorService>(MessageTransferType.Http, WcfService.PrintMonitor.GetHttpUri(Machine.Name)))
                    {
                        logFiles.Append(printMonitor.Channel.GetLogFiles());
                    }
                }
                catch (Exception ex)
                {
                    TraceFactory.Logger.Error("Unable to capture print monitor log files for {0} : {1}"
                                              .FormatWith(Machine.Name, ex.ToString()));
                }
            }

            TraceFactory.Logger.Debug("Done: {0}".FormatWith(Machine.Name));
            MapElement.UpdateStatus("Logs copied");
            //Write to Log Directory
            logFiles.Write(LogFileReader.DataLogPath(Manifest.SessionId));
        }
Beispiel #6
0
        /// <summary>
        /// Shuts down this resource host
        /// </summary>
        /// <param name="options">The options used to define how the machine is shutdown</param>
        /// <param name="loopState">State of the loop.</param>
        public void Shutdown(ShutdownOptions options, ParallelLoopState loopState)
        {
            _inShutdown = true;

            MapElement.UpdateStatus("Shutdown", RuntimeState.ShuttingDown);

            // If the Machine has not been configured yet, then just return
            if (!Machine.Configured)
            {
                TraceFactory.Logger.Debug("This host is not configured, returning");
                MapElement.UpdateStatus("Offline", RuntimeState.Offline);
                return;
            }

            TraceFactory.Logger.Debug("Shutting down {0}".FormatWith(Machine.Name));

            if (CancelBootup())
            {
                TraceFactory.Logger.Debug("{0} was booting, so just shutdown machine".FormatWith(Machine.Name));
                Machine.Shutdown(options);
            }
            else
            {
                TraceFactory.Logger.Debug("{0} already booted, shutdown resources, then machine".FormatWith(Machine.Name));

                // Create the wait handle first, so that it is decrementing even before the
                // wait occurs.  That way if the resources send their offline state changes
                // this count latch will receive them and appropriately decrement.
                InitializeShutdownWaitHandle();

                try
                {
                    Parallel.ForEach <ResourceInstance>(Resources, r => r.Shutdown(options));
                    WaitForResourcesToShutdown();
                    TraceFactory.Logger.Debug("{0}: All virtual resources now exited".FormatWith(Machine.Name));
                }
                catch (AggregateException ex)
                {
                    TraceFactory.Logger.Error("Error shutting down resources: {0}".FormatWith(ex.ToString()));
                }

                try
                {
                    // If we are in a validated or offline state, then the client VM hasn't fully booted and won't
                    // have a service running to call Cleanup on.  This is just here to speed up the
                    // shutdown process when in this condition.
                    if (options.PerformCleanup && MapElement.State != RuntimeState.Validated && MapElement.State != RuntimeState.Offline)
                    {
                        // Tell the host to cleanup as well.  This will provide an opportunity for a host
                        // to perform any custom clean up items.
                        using (var resourceHostClient = ClientControllerServiceConnection.Create(Machine.Name))
                        {
                            resourceHostClient.Channel.Cleanup();
                            TraceFactory.Logger.Debug("Sent Cleanup signal to {0}".FormatWith(Machine.Name));
                        }
                    }
                }
                catch (Exception ex)
                {
                    TraceFactory.Logger.Error("Unable to call Cleanup: {0}".FormatWith(ex.ToString()));
                }

                try
                {
                    if (options.CopyLogs)
                    {
                        CopyClientControllerLogs();
                    }
                }
                catch (Exception ex)
                {
                    TraceFactory.Logger.Error("Unable to copy Logs: {0}".FormatWith(ex.ToString()));
                }

                try
                {
                    MapElement.UpdateStatus("Powering off");
                    TraceFactory.Logger.Debug("Shutdown machine {0}".FormatWith(Machine.Name));
                    Machine.Shutdown(options);
                    TraceFactory.Logger.Debug("Shutdown machine {0} COMPLETE".FormatWith(Machine.Name));
                    MapElement.UpdateStatus("Shut down");
                }
                catch (Exception ex)
                {
                    TraceFactory.Logger.Error("Unable to shutdown {0}: {1}".FormatWith(Machine.Name, ex.ToString()));
                }
            }

            if (options.ReleaseDeviceReservation)
            {
                try
                {
                    MapElement.UpdateStatus("Release");
                    TraceFactory.Logger.Debug("Machine {0} releasing".FormatWith(Machine.Name));
                    Machine.Release();
                    TraceFactory.Logger.Debug("Machine {0} released".FormatWith(Machine.Name));
                }
                catch (Exception ex)
                {
                    TraceFactory.Logger.Error("Error releasing {0}: {1}".FormatWith(Machine.Name, ex.ToString()));
                }
            }

            MapElement.UpdateStatus("Offline", RuntimeState.Offline);
        }