/// <summary>
        /// Reserves all assets associated with this session using the specified key.
        /// </summary>
        /// <param name="sessionId">The session unique identifier.</param>
        /// <param name="reservationKey">The reservation key.</param>
        /// <returns></returns>
        /// <exception cref="System.ServiceModel.EndpointNotFoundException"></exception>
        public AssetDetailCollection Reserve(string sessionId, string reservationKey)
        {
            SetTraceSessionContext(sessionId);
            AssetDetailCollection assetDetails = new AssetDetailCollection();

            foreach (var item in assetDetails)
            {
                TraceFactory.Logger.Debug("Item availability:" + item.Availability);
            }

            if (!_proxyControllers.Contains(sessionId))
            {
                var msg = "Proxy not found for Session Id {0}".FormatWith(sessionId);
                TraceFactory.Logger.Debug(msg);
                throw new EndpointNotFoundException(msg);
            }

            var controller = _proxyControllers[sessionId];

            if (controller.ProxyProcessStarted)
            {
                TraceFactory.Logger.Debug("CallProxy -> Reserve({0})".FormatWith(sessionId));

                Action retryAction = () => assetDetails = controller.Channel.Reserve(reservationKey);
                TraceFactory.Logger.Debug("Returned Reservation");
                try
                {
                    Retry.WhileThrowing
                    (
                        retryAction,
                        10,
                        TimeSpan.FromSeconds(1),
                        new List <Type>()
                    {
                        typeof(EndpointNotFoundException)
                    }
                    );
                }
                catch (Exception ex)
                {
                    var msg = "Error communicating with session proxy for {0} - 1".FormatWith(sessionId);
                    TraceFactory.Logger.Error(msg, ex);
                    var exception = new ApplicationException(msg, ex);
                    EventPublisher.PublishDispatcherException(exception);
                }
            }
            else
            {
                var msg       = "Proxy service not started for session {0} (1)".FormatWith(sessionId);
                var exception = new ApplicationException(msg);
                EventPublisher.PublishDispatcherException(exception);
            }

            TraceFactory.Logger.Debug("Returning asset details");

            return(assetDetails);
        }
 /// <summary>
 /// Let's the dispatcher know that the proxy is started
 /// </summary>
 /// <param name="sessionId">The session identifier.</param>
 public void NotifyProxyStarted(string sessionId)
 {
     SetTraceSessionContext(sessionId);
     // This is called when the new proxy process is up and ready to go.  The proxy will
     // call the ISessionProxyCallback interface to inform the dispatcher that it is running.
     if (_proxyControllers.Contains(sessionId))
     {
         TraceFactory.Logger.Debug("Received signal that proxy process {0} is running".FormatWith(sessionId));
         _proxyControllers[sessionId].ProxyProcessStarted = true;
     }
     else
     {
         EventPublisher.PublishDispatcherException(new OperationCanceledException("Proxy process started for {0} with no visible entry in the dispatcher...".FormatWith(sessionId)));
     }
 }
        private void DoActionHandler(string sessionId, Action <ISessionProxy> action)
        {
            if (!_proxyControllers.Contains(sessionId))
            {
                var msg = "Proxy not found for Session Id {0}".FormatWith(sessionId);
                TraceFactory.Logger.Debug(msg);
                throw new EndpointNotFoundException(msg);
            }

            var controller = _proxyControllers[sessionId];

            TraceFactory.Logger.Debug("{0}: {1}".FormatWith(action.Method.Name, controller.Endpoint.AbsoluteUri));

            if (controller.ProxyProcessStarted)
            {
                Action retryAction = () => action(controller.Channel);

                try
                {
                    Retry.WhileThrowing
                    (
                        retryAction,
                        10,
                        TimeSpan.FromSeconds(5),
                        new List <Type>()
                    {
                        typeof(EndpointNotFoundException)
                    }
                    );
                }
                catch (Exception ex)
                {
                    var msg       = "Error communicating with session proxy for {0} - 2".FormatWith(sessionId);
                    var exception = new ApplicationException(msg);
                    TraceFactory.Logger.Error(msg, ex);
                    EventPublisher.PublishDispatcherException(exception);
                }
            }
            else
            {
                var msg       = "Proxy service not started for session {0} (2)".FormatWith(sessionId);
                var exception = new ApplicationException(msg);
                TraceFactory.Logger.Error(msg);
                EventPublisher.PublishDispatcherException(exception);
            }
        }
 private void CallSessionProxy(string sessionId, Action <ISessionProxy> action, bool useThread = true)
 {
     try
     {
         if (useThread)
         {
             ThreadPool.QueueUserWorkItem(t => DoActionHandler(sessionId, action));
         }
         else
         {
             DoActionHandler(sessionId, action);
         }
     }
     catch (Exception ex)
     {
         var msg       = "Error for session {0} : {1}".FormatWith(sessionId, ex.Message);
         var exception = new ApplicationException(msg, ex);
         EventPublisher.PublishDispatcherException(exception);
     }
 }
        private void CleanupAssetHosts(string sessionId)
        {
            try
            {
                SetTraceSessionContext(sessionId);
                using (AssetInventoryContext context = DbConnect.AssetInventoryContext())
                {
                    var reservedAssets = context.AssetReservations.Where(n => n.SessionId == sessionId).Select(n => n.AssetId).ToList();

                    // Parallel process each Jedi simulator reserved for this session - shut down the host machine.
                    List <DeviceSimulator> jediSimulators = context.Assets.OfType <DeviceSimulator>().Where(n => reservedAssets.Contains(n.AssetId) && n.SimulatorType == "Jedi").ToList();
                    Parallel.ForEach(jediSimulators, a => CleanupAssetHostsHandler(a));
                }

                AssetReservationManager reservationManager = new AssetReservationManager(DbConnect.AssetInventoryConnectionString, "STF Console");
                reservationManager.ReleaseSessionReservations(sessionId);
            }
            catch (Exception ex)
            {
                EventPublisher.PublishDispatcherException(ex);
            }
        }