/// <summary>
        /// Notifies the event.
        /// </summary>
        /// <param name="url">The URL.</param>
        /// <param name="action">The action.</param>
        /// <returns></returns>
        public static EventResponse NotifyEvent(string url, EventAction action) 
        {
            try
            {
                if (log.IsDebugEnabled) log.Debug(string.Format("Sending event [{0}]", action.Notification));
                EventInvocation invoker = Activator.GetObject(typeof(EventInvocation), url) as EventInvocation;
                EventResponse response = invoker.Invoke(action);
                if (log.IsDebugEnabled) log.Debug("Event is successfully sent");
                return response;
            }
            catch (Exception ex)
            {
                log.Error(string.Format("Invocation error: {0}", ex.Message), ex);
            }

            EventResponse defaultResponse = new EventResponse();
            defaultResponse.Status = StringEnum.GetStringValue(EventNotificationResponse.Failed);
            return defaultResponse;
           
        }
        /// <summary>
        /// Starts the messenger.
        /// </summary>
        /// <param name="action">The action.</param>
        private EventResponse StartMessenger(EventAction action)
        {
            string name = action.Values[EventParameter.MessengerName];
            log.InfoFormat("Starting messenger. Name is [{0}]", name);
            EventResponse response = new EventResponse();
            DbMessenger messenger = DbMessenger.SingleOrDefault(m =>m.Name.ToLower() == name.ToLower());
            if (messenger != null)
            {
                // Start to poll incoming message
                if (workerThreads == null) workerThreads = new List<Thread>(1);
                if (pollers == null) pollers = new List<BasePoller>(1);

                // Check if the poller is already started
                if (pollers.Exists(p => p.Name.ToLower() == messenger.Name.ToLower()))
                {
                    log.InfoFormat("Database messenger [{0}] is already started", messenger.Name);
                    return response;
                }

                DatabasePoller poller = new DatabasePoller(messenger, this.messageGatewayService);
                poller.Name = messenger.Name;
                pollers.Add(poller);

                Thread worker = new Thread(new ThreadStart(poller.StartTimer));
                worker.IsBackground = true;
                worker.Name = messenger.Name;
                workerThreads.Add(worker);
                worker.Start();

                log.InfoFormat("Messenger [{0}] is started", name);
            }
            return response;
        }
        /// <summary>
        /// Checks the messenger status.
        /// </summary>
        /// <param name="action">The action.</param>
        private EventResponse CheckMessengerStatus(EventAction action)
        {
            string name = action.Values[EventParameter.MessengerName];
            log.DebugFormat("Check messenger status. Name is [{0}]", name);
            EventResponse response = new EventResponse();

            if (pollers == null || !pollers.Exists(p=> p.Name.ToLower() == name.ToLower()))
            {
                response.Status = StringEnum.GetStringValue(EventNotificationResponse.Failed);
                response.Results.Add(EventParameter.GatewayStatus, StringEnum.GetStringValue(GatewayStatus.Stopped));
            } else 
            {
                response.Results.Add(EventParameter.MessengerStatus, StringEnum.GetStringValue(MessengerStatus.Started));                
            }
            return response;
        }
 /// <summary>
 /// Processes synchronous events
 /// </summary>
 /// <param name="action">The action.</param>
 /// <returns>Event response</returns>
 private EventResponse ProcessSyncEvents(EventAction action)
 {
     EventNotificationType notificationType = (EventNotificationType)StringEnum.Parse(typeof(EventNotificationType), action.Notification);
     if (notificationType == EventNotificationType.QueryGatewayStatus)
     {
         return CheckGatewayStatus(action);
     }
     else if (notificationType == EventNotificationType.QueryWebServerStatus)
     {
         return CheckWebServerStatus(action);
     }
     else if (notificationType == EventNotificationType.QueryMessengerStatus)
     {
         return CheckMessengerStatus(action);
     }
     EventResponse response = new EventResponse();
     response.Status = StringEnum.GetStringValue(EventNotificationResponse.Failed);
     return response;
 }
 private void stopMessengerToolStripMenuItem_Click(object sender, EventArgs e)
 {
     try
     {
         DbMessenger messenger = lvwDbMessenger.SelectedObject as DbMessenger;
         if (messenger != null)
         {
             EventAction action = new EventAction(StringEnum.GetStringValue(EventNotificationType.StopMessenger));
             action.Values.Add(EventParameter.MessengerName, messenger.Name);
             EventResponse response = RemotingHelper.NotifyEvent(ServiceEventListenerUrl, action);
             messenger.Status = StringEnum.GetStringValue(MessengerStatus.Stopping);
             lvwDbMessenger.RefreshObject(messenger);
         }
         else
         {
             FormHelper.ShowInfo(Resources.MsgNoMessengerSelected);
         }
     }
     catch (Exception ex)
     {
         FormHelper.ShowError(ex.Message);
     }
 }
        /// <summary>
        /// Called when [event received].
        /// </summary>
        /// <param name="action">The action.</param>
        /// <returns></returns>
        private EventResponse OnEventReceived(EventAction action)
        {
            // Put the event in a queue and respond immediately
            lock (eventLock)
            {
                // Queue the event and trigger the processing
                eventQueue.Enqueue(action, EventPriority.Normal);
                eventTrigger.Set();

                // Send back the processing
                EventResponse response = new EventResponse();
                response.Status = StringEnum.GetStringValue(EventNotificationResponse.OK);
                return response;
            }
        }
        /// <summary>
        /// Handles the Click event of the btnStart control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btnStart_Click(object sender, EventArgs e)
        {
            try
            {               
                // Perform validation
                if (!FormHelper.ValidateNotEmpty(txtPath, Resources.MsgWebServerPathRequired))
                {
                    return;
                }

                if (!FormHelper.ValidateNotEmpty(txtVirtualPath, Resources.MsgWebServerVirtualPathRequired))
                {
                    return;
                }

                if (!FormHelper.ValidateGreaterThanZero(txtPort, Resources.MsgWebServerPortRequired))
                {
                    return;
                }

                // Save the existing setting to database
                AppConfigSettings.Update(ConfigParameter.WebServerAppPath, txtPath.Text);
                AppConfigSettings.Update(ConfigParameter.WebServerVirtualPath, txtVirtualPath.Text);
                AppConfigSettings.Update(ConfigParameter.WebServerPort, txtPort.Text);
                AppConfigSettings.Update(ConfigParameter.WebServerAutoStart, Convert.ToString(chkAutoStart.Checked));
                EventAction action = new EventAction(StringEnum.GetStringValue(EventNotificationType.StartWebServer));
                EventResponse response = RemotingHelper.NotifyEvent(ServiceEventListenerUrl, action);
                txtStatus.Text = StringEnum.GetStringValue(WebServerStatus.Starting);
            }
            catch (Exception ex)
            {
                FormHelper.ShowError(ex.Message);
            }
        }
 /// <summary>
 /// Handles the Click event of the btnStop control.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
 private void btnStop_Click(object sender, EventArgs e)
 {
     try
     {
         EventAction action = new EventAction(StringEnum.GetStringValue(EventNotificationType.StopWebServer));
         EventResponse response = RemotingHelper.NotifyEvent(ServiceEventListenerUrl, action);
         txtStatus.Text = StringEnum.GetStringValue(WebServerStatus.Stopping);
     }
     catch (Exception ex)
     {
         FormHelper.ShowError(ex.Message);
     }
 }
        /// <summary>
        /// Checks the gateway status.
        /// </summary>
        /// <param name="action">The action.</param>
        /// <returns></returns>
        private EventResponse CheckGatewayStatus(EventAction action)
        {
            string gatewayId = action.Values[EventParameter.GatewayId];
            log.Debug(string.Format("Check gateway status. ID is [{0}]", gatewayId));
            EventResponse response = new EventResponse();
            IGateway gateway;
            if (messageGatewayService.Find(gatewayId, out gateway))
            {
                // Gateway found
                response.Status = StringEnum.GetStringValue(EventNotificationResponse.OK);
                response.Results.Add(EventParameter.GatewayStatus, StringEnum.GetStringValue(gateway.Status));
                if (gateway.Status == GatewayStatus.Started)
                {
                    IMobileGateway mobileGateway = gateway as IMobileGateway;
                    response.Results.Add(EventParameter.GatewayOperator, mobileGateway.NetworkOperator.OperatorInfo);
                    response.Results.Add(EventParameter.GatewaySignalStrength, Convert.ToString(mobileGateway.SignalQuality.SignalStrengthPercent));
                }
            }
            else
            {
                response.Status = StringEnum.GetStringValue(EventNotificationResponse.Failed);
                response.Results.Add(EventParameter.GatewayStatus, StringEnum.GetStringValue(GatewayStatus.Stopped));
            }

            return response;
        }
        /// <summary>
        /// Stops the gateway.
        /// </summary>
        /// <param name="action">The action.</param>
        /// <returns></returns>
        private EventResponse StopGateway(EventAction action)
        {
            string gatewayId = action.Values[EventParameter.GatewayId];
            log.Debug(string.Format("Stop gateway. ID is [{0}]", gatewayId));
            EventResponse response = new EventResponse();

            IGateway gateway;
            if (messageGatewayService.Find(gatewayId, out gateway))
            {
                messageGatewayService.Remove(gatewayId);
            }

            return response;
        }
 /// <summary>
 /// Handles the Click event of the restartChannelToolStripMenuItem control.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
 private void restartChannelToolStripMenuItem_Click(object sender, EventArgs e)
 {
     try
     {
         ChannelStatusView channel = lvwChannelStatus.SelectedObject as ChannelStatusView;
         if (channel != null)
         {
             EventAction action = new EventAction(StringEnum.GetStringValue(EventNotificationType.RestartGateway));
             action.Values.Add(EventParameter.GatewayId, channel.Name);
             EventResponse response = RemotingHelper.NotifyEvent(ServiceEventListenerUrl, action);
             channel.Status = StringEnum.GetStringValue(GatewayStatus.Restart);
             lvwChannelStatus.RefreshObject(channel);
         }
         else
         {
             FormHelper.ShowInfo(Resources.MsgNoChannelSelected);
         }
     }
     catch (Exception ex)
     {
         FormHelper.ShowError(ex.Message);
     }
 }
        /// <summary>
        /// Checks the channels.
        /// </summary>
        private void CheckChannels()
        { 
            try
            {
                List<ChannelStatusView> channels = new List<ChannelStatusView>();
                while (true)
                {
                    channels.Clear();
                    foreach (GatewayConfig gwConfig in GatewayConfig.All().OrderBy(gw => gw.Id))
                    {
                        try
                        {
                            EventAction action = new EventAction(StringEnum.GetStringValue(EventNotificationType.QueryGatewayStatus));
                            action.ActionType = EventAction.Synchronous;
                            action.Values.Add(EventParameter.GatewayId, gwConfig.Id);
                            EventResponse response = RemotingHelper.NotifyEvent(ServiceEventListenerUrl, action);

                            ChannelStatusView channel = new ChannelStatusView();
                            channel.Name = gwConfig.Id;
                            channel.Port = gwConfig.ComPort;

                            if (StringEnum.GetStringValue(EventNotificationResponse.Failed).Equals(response.Status))
                            {
                                channel.Status = StringEnum.GetStringValue(GatewayStatus.Stopped);
                            }
                            else
                            {
                                channel.Status = response.Results[EventParameter.GatewayStatus];
                                channel.Operator = response.Results[EventParameter.GatewayOperator];
                                channel.SignalStrength = response.Results[EventParameter.GatewaySignalStrength];
                            }

                            channels.Add(channel);
                        }
                        catch (Exception ex)
                        {
                            log.Error(string.Format("Error checking channel - [{0}]", gwConfig.Id));
                            log.Error(ex.Message, ex);
                        }
                    }
                    RefreshView(channels);
                    Thread.Sleep(ChannelPollingInterval);
                }
            }
            catch (Exception ex)
            {               
                log.Error(ex.Message, ex);
            }
           
        }
 /// <summary>
 /// Sends the event.
 /// </summary>
 /// <param name="eventListenerUrl">The event listener URL.</param>
 /// <param name="action">The action.</param>
 public static void SendEvent(string eventListenerUrl, EventAction action)
 {
     action.Computer = Environment.MachineName;
     NotifyEvent(eventListenerUrl, action);
 }
        /// <summary>
        /// Stops the messenger.
        /// </summary>
        /// <param name="action">The action.</param>
        /// <returns></returns>
        private EventResponse StopMessenger(EventAction action)
        {
            string name = action.Values[EventParameter.MessengerName];
            if (log.IsDebugEnabled) log.DebugFormat("Stopping messenger. Name is [{0}]", name);
            EventResponse response = new EventResponse();
            DbMessenger messenger = DbMessenger.SingleOrDefault(m => m.Name.ToLower() == name.ToLower());
            if (messenger != null)
            {
                if (pollers == null) return response;

                // Check if the poller is already started
                if (pollers.Exists(p => p.Name.ToLower() == messenger.Name.ToLower()))
                {
                    BasePoller poller = pollers.Find(p => p.Name.ToLower() == messenger.Name.ToLower());
                    pollers.Remove(poller);

                    if (workerThreads != null)
                    {
                        Thread t = workerThreads.Find(w => messenger.Name.ToLower() == w.Name.ToLower());
                        if (t != null)
                        {
                            try
                            {
                                t.Join(ThreadWaitInterval);
                            }
                            catch (Exception ex)
                            {
                                log.Info(string.Format("Aborting thread [{0}]", t.Name), ex);
                                try
                                {
                                    t.Abort();
                                }
                                catch (Exception) { }
                            }
                        }
                    }
                    log.InfoFormat("Messenger [{0}] is stopped", name);
                }
                else
                {
                    log.InfoFormat("Unable to find messenger [{0}]", name);
                }
               
            }
            return response;
        }
 /// <summary>
 /// Checks the web server status.
 /// </summary>
 /// <param name="action">The action.</param>
 /// <returns></returns>
 private EventResponse CheckWebServerStatus(EventAction action)
 {
     EventResponse response = new EventResponse();
     response.Status = StringEnum.GetStringValue(EventNotificationResponse.OK);
     if (webServer != null)
     {
         response.Results.Add(EventParameter.WebServerStatus, StringEnum.GetStringValue(WebServerStatus.Started));
         response.Results.Add(EventParameter.WebServerUrl, webServer.RootUrl);
     }
     else
     {
         response.Results.Add(EventParameter.WebServerStatus, StringEnum.GetStringValue(WebServerStatus.Stopped));
         response.Results.Add(EventParameter.WebServerUrl, string.Empty);
     }
     return response;
 }
        /// <summary>
        /// Starts the gateway.
        /// </summary>
        /// <param name="action">The action.</param>
        /// <returns></returns>
        private EventResponse StartGateway(EventAction action)
        {
            string gatewayId = action.Values[EventParameter.GatewayId];
            if (log.IsDebugEnabled) log.Debug(string.Format("Start gateway. ID is [{0}]", gatewayId));
            EventResponse response = new EventResponse();

            IGateway gateway;

            if (messageGatewayService.Find(gatewayId, out gateway))
            {
                // Check if the status is Stopped/Failed/Restart, if yes, remove and restart
                if (gateway.Status == GatewayStatus.Failed ||
                    gateway.Status == GatewayStatus.Stopped ||
                    gateway.Status == GatewayStatus.Restart)
                {
                    messageGatewayService.Remove(gatewayId);
                    ConnectGateway(gatewayId);
                }
            }
            else
            {
                ConnectGateway(gatewayId);
            }

            return response;
        }
 /// <summary>
 /// Initializes the gateway.
 /// </summary>
 /// <param name="action">The action.</param>
 private void InitializeGateway(EventAction action)
 {
     string gatewayId = action.Values[EventParameter.GatewayId];
     log.Info(string.Format("New gateway [{0}] is added", gatewayId));
     GatewayConfig gwConfig = GatewayConfig.SingleOrDefault(g => g.Id == gatewayId);
     if (gwConfig != null)
     {
         ConnectGateway(gwConfig);
     }
 }
 /// <summary>
 /// Checks the web server status.
 /// </summary>
 private void CheckWebServerStatus()
 {
     try
     {               
         while (true)
         {
             EventAction action = new EventAction(StringEnum.GetStringValue(EventNotificationType.QueryWebServerStatus));
             action.ActionType = EventAction.Synchronous;
             EventResponse response = RemotingHelper.NotifyEvent(ServiceEventListenerUrl, action);
             if (StringEnum.GetStringValue(EventNotificationResponse.OK).Equals(response.Status))
             {
                 string status = response.Results[EventParameter.WebServerStatus];
                 string url = response.Results[EventParameter.WebServerUrl];
                 RefreshView(status, url);
             }
             Thread.Sleep(PollingInterval);
         }
     }
     catch (Exception ex)
     {
         log.Error(ex.Message, ex);
     }
 }
        /// <summary>
        /// Starts the pollers.
        /// </summary>
        private void StartPollers()
        {
            try
            {
                log.Debug("Starting outgoing message poller");

                // Stop all pollers, just in case
                StopPollers();

                // Start to poll incoming message
                if (workerThreads == null) workerThreads = new List<Thread>(1);
                if (pollers == null) pollers = new List<BasePoller>(1);

                OutgoingMessagePoller outgoingMessagePoller = new OutgoingMessagePoller(this.messageGatewayService);
                outgoingMessagePoller.Name = Resources.OutgoingMessagePoller;
                pollers.Add(outgoingMessagePoller);

                Thread worker = new Thread(new ThreadStart(outgoingMessagePoller.StartTimer));
                worker.IsBackground = true;
                worker.Name = Resources.OutgoingMessagePoller;
                workerThreads.Add(worker);
                worker.Start();
                               
                log.Info("Outgoing message poller is started successfully");

                log.Debug("Starting database messengers");
                foreach (DbMessenger messenger in DbMessenger.All())
                {
                    if (messenger.AutoStart)
                    {                       
                        EventAction action = new EventAction(StringEnum.GetStringValue(EventNotificationType.StartMessenger));
                        action.Values.Add(EventParameter.MessengerName, messenger.Name);
                        StartMessenger(action);
                    }
                }

            }
            catch (Exception ex)
            {
                log.Error(string.Format("Error starting pollers: {0}", ex.Message), ex);
                StopPollers(); // calls StopPollers
            }
        }
        /// <summary>
        /// CTLs the channels_ gateway added.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The e.</param>
        private void ctlChannels_GatewayAdded(object sender, GatewayEventHandlerArgs e)
        {
            log.Info(string.Format("New gateway [{0}] is added", e.GatewayId));
            EventAction action = new EventAction(StringEnum.GetStringValue(EventNotificationType.NewGateway));
            action.Values.Add(EventParameter.GatewayId, e.GatewayId);
            RemotingHelper.NotifyEvent(serviceEventListenerUrl, action);

            // Reset the settings in NewMessage user control
            ctlNewMessage.SetupMessageSettings();
        }
        /// <summary>
        /// Called when [event received].
        /// </summary>
        /// <param name="action">The action.</param>
        /// <returns></returns>
        private EventResponse OnEventReceived(EventAction action)
        {
            // Put the event in a queue and respond immediately
            lock (eventLock)
            {
                try
                {
                    if (action.ActionType == EventAction.ASynchronous)
                    {
                        // Queue the event and trigger the processing
                        eventQueue.Enqueue(action, EventPriority.Normal);
                        eventTrigger.Set();

                        // Send back the processing
                        EventResponse response = new EventResponse();
                        response.Status = StringEnum.GetStringValue(EventNotificationResponse.OK);
                        return response;
                    }
                    else
                    {
                        return ProcessSyncEvents(action);
                    }
                }
                catch (Exception ex)
                {
                    log.Error(string.Format("Error processing incoming event - [{0}]", action.ToString()));
                    log.Error(ex.Message, ex);
                }
            }

            return new EventResponse();
        }
        /// <summary>
        /// Invokes the specified action.
        /// </summary>
        /// <param name="action">The action.</param>
        /// <returns></returns>
        public EventResponse Invoke(EventAction action)
        {
            if (EventReceived != null)
                return EventReceived(action);

            return new EventResponse();
        }
        private void CheckMessengers()
        {
            try
            {
                List<DbMessenger> messengers = new List<DbMessenger>();
                while (true)
                {
                    messengers.Clear();
                    foreach (DbMessenger messenger in DbMessenger.All().OrderBy(m=> m.Name))
                    {
                        try
                        {
                            EventAction action = new EventAction(StringEnum.GetStringValue(EventNotificationType.QueryMessengerStatus));
                            action.ActionType = EventAction.Synchronous;
                            action.Values.Add(EventParameter.MessengerName, messenger.Name);
                            EventResponse response = RemotingHelper.NotifyEvent(ServiceEventListenerUrl, action);
                            
                            if (StringEnum.GetStringValue(EventNotificationResponse.Failed).Equals(response.Status))
                            {
                                messenger.Status = StringEnum.GetStringValue(MessengerStatus.Stopped);
                            }
                            else
                            {
                                messenger.Status = response.Results[EventParameter.MessengerStatus];                            
                            }

                            messengers.Add(messenger);
                        }
                        catch (Exception ex)
                        {
                            log.ErrorFormat("Error checking messenger - [{0}]", messenger.Name);
                            log.Error(ex.Message, ex);
                        }
                    }
                    RefreshView(messengers);
                    Thread.Sleep(PollingInterval);
                }
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
            }
           
        }