/// <summary>
        /// Initializes a new instance of the <see cref="ActiveMQCache"/> class.
        /// </summary>
        /// <param name="settings"><see cref="T:TcmCDService.Configuration.Settings" /></param>
        public ActiveMQCache(Settings settings) : base(settings)
        {
            mIdentifier = "ActiveMQ-" + Guid.NewGuid().ToString("D");

            String brokerUrl = settings.Get <String>("brokerUrl");

            if (String.IsNullOrEmpty(brokerUrl))
            {
                throw new ConfigurationErrorsException("ActiveMQCache: BrokerUrl is unconfigured.");
            }

            String topic = settings.Get <String>("topic");

            if (String.IsNullOrEmpty(topic))
            {
                throw new ConfigurationErrorsException("ActiveMQCache: Topic is unconfigured.");
            }

            try
            {
                String username = settings.Get <String>("username");
                String password = settings.Get <String>("password");

                ConnectionFactory connectionFactory = new ConnectionFactory(brokerUrl)
                {
                    ClientId = Identifier,
                    UserName = username,
                    Password = password
                };

                mConnector = connectionFactory.CreateConnection();
                mConnector.ExceptionListener += (Exception exception) =>
                {
                    Logger.Error("ActiveMQCache: Exception while listening.", exception);
                };

                mSession  = mConnector.CreateSession(AcknowledgementMode.DupsOkAcknowledge);
                mConsumer = mSession.CreateConsumer(new ActiveMQTopic(topic), null, true);
                mProducer = mSession.CreateProducer(new ActiveMQTopic(topic));

                mConsumer.Listener += (IMessage message) =>
                {
                    ITextMessage textMessage = message as ITextMessage;

                    if (textMessage != null)
                    {
                        XmlCacheEvent xmlCacheEvent = XmlCacheEvent.FromXml(textMessage.Text);

                        if (xmlCacheEvent != null)
                        {
                            base.OnCacheEvent(xmlCacheEvent.CacheRegion, xmlCacheEvent.Key, xmlCacheEvent.EventType);
                        }
                    }
                };
            }
            catch (Exception ex)
            {
                Logger.Error("ActiveMQCache", ex);
            }
        }
        /// <summary>
        /// Broadcasts the <paramref name="xmlCacheEvent" />
        /// </summary>
        /// <param name="xmlCacheEvent"><see cref="T:TcmCDService.CacheTypes.XmlCacheEvent" /></param>
        private void BroadcastEvent(XmlCacheEvent xmlCacheEvent)
        {
            if (mSession != null && mProducer != null)
            {
                ITextMessage message = mSession.CreateTextMessage(xmlCacheEvent.ToXml());

                message.Properties.SetString("Client", mIdentifier);
                mProducer.Send(message);
            }
        }
        /// <summary>
        /// Broadcasts the <paramref name="xmlCacheEvent" />
        /// </summary>
        /// <param name="xmlCacheEvent"><see cref="T:TcmCDService.CacheTypes.XmlCacheEvent" /></param>
        private void BroadcastEvent(XmlCacheEvent xmlCacheEvent)
        {
            ZeroMQMessage message = new ZeroMQMessage()
            {
                Topic   = mTopic,
                Client  = mIdentifier,
                Content = xmlCacheEvent.ToXml()
            };

            mQueue.Add(message);
        }
        /// <summary>
        /// Broadcasts the <paramref name="xmlCacheEvent" />
        /// </summary>
        /// <param name="xmlCacheEvent"><see cref="T:TcmCDService.CacheTypes.XmlCacheEvent" /></param>
        private void BroadcastEvent(XmlCacheEvent xmlCacheEvent)
        {
            ZeroMQMessage message = new ZeroMQMessage()
            {
                Topic = mTopic,
                Client = mIdentifier,
                Content = xmlCacheEvent.ToXml()
            };

            mQueue.Add(message);
        }
 /// <summary>
 /// Broadcasts a cache event to all other connected clients
 /// </summary>
 /// <param name="cacheRegion"><see cref="T:TcmCDService.CacheTypes.CacheRegion" /></param>
 /// <param name="key">Cache key as <see cref="T:System.Int32" /></param>
 /// <param name="eventType"><see cref="T:TcmCDService.CacheTypes.CacheEventType" /></param>
 public override void BroadcastEvent(CacheRegion cacheRegion, int key, CacheEventType eventType)
 {
     XmlCacheEvent cacheEvent = new XmlCacheEvent(cacheRegion, key, eventType);
     BroadcastEvent(cacheEvent);
 }
        /// <summary>
        /// Broadcasts a cache event to all other connected clients
        /// </summary>
        /// <param name="cacheRegion"><see cref="T:TcmCDService.CacheTypes.CacheRegion" /></param>
        /// <param name="key">Cache key as <see cref="T:System.Int32" /></param>
        /// <param name="eventType"><see cref="T:TcmCDService.CacheTypes.CacheEventType" /></param>
        public override void BroadcastEvent(CacheRegion cacheRegion, int key, CacheEventType eventType)
        {
            XmlCacheEvent cacheEvent = new XmlCacheEvent(cacheRegion, key, eventType);

            BroadcastEvent(cacheEvent);
        }
        private void ReceiveEvents(String subscriptionUri, String topic, CancellationToken cancellationToken)
        {
            using (NetMQContext context = NetMQContext.Create())
            {
                using (NetMQSocket subscriberSocket = context.CreateSubscriberSocket())
                {
                    subscriberSocket.IgnoreErrors = true;
                    subscriberSocket.Connect(subscriptionUri);
                    subscriberSocket.Subscribe(topic);

                    Logger.Info("ZeroMQCache: Connected to subscriptionUri \"{0}\".", subscriptionUri);

                    // Eventhandler delegate to handle receiving messages
                    subscriberSocket.ReceiveReady += (sender, args) =>
                    {
                        try
                        {
                            if (args.ReceiveReady)
                            {
                                // Recieve and relay
                                NetMQMessage netMQmessage = args.Socket.ReceiveMessage();

                                // Recieve the message
                                ZeroMQMessage message = new ZeroMQMessage()
                                {
                                    Topic   = netMQmessage.Pop().ConvertToString(),
                                    Client  = netMQmessage.Pop().ConvertToString(),
                                    Content = netMQmessage.Pop().ConvertToString()
                                };

                                Logger.Debug("ZeroMQCache: Received -> {0}", message.ToString());

                                XmlCacheEvent cacheEvent = XmlCacheEvent.FromXml(message.Content);

                                if (cacheEvent != null)
                                {
                                    OnCacheEvent(cacheEvent.CacheRegion, cacheEvent.Key, cacheEvent.EventType);
                                }
                            }
                        }
                        catch (OperationCanceledException)
                        {
                            // We have been asked to cancel operation
                            return;
                        }
                        catch (Exception ex)
                        {
                            Logger.Error("ZeroMQCache: Error receiving message.", ex);
                        }
                    };

                    while (!cancellationToken.IsCancellationRequested)
                    {
                        try
                        {
                            subscriberSocket.Poll(TimeSpan.FromSeconds(1));
                        }
                        catch (OperationCanceledException)
                        {
                            // We have been asked to cancel operation
                            break;
                        }
                        catch (Exception ex)
                        {
                            Logger.Error("ZeroMQCache: Error polling for messages.", ex);
                        }
                    }

                    // Close socket
                    subscriberSocket.Close();
                }

                context.Terminate();
            }
        }
        private void ReceiveEvents(String submissionUri, String topic, CancellationToken cancellationToken)
        {
            using (NetMQContext context = NetMQContext.Create())
            {
                using (NetMQSocket pullSocket = context.CreatePullSocket())
                {
                    pullSocket.IgnoreErrors = true;
                    pullSocket.Bind(submissionUri);

                    Logger.Info("ZeroMQBroker: Bound to submissionUri \"{0}\".", submissionUri);

                    // Eventhandler delegate to handle receiving messages
                    pullSocket.ReceiveReady += (sender, args) =>
                    {
                        try
                        {
                            if (args.ReceiveReady)
                            {
                                // Recieve and relay
                                NetMQMessage netMQmessage = args.Socket.ReceiveMessage();

                                // Recieve the message
                                ZeroMQMessage message = new ZeroMQMessage()
                                {
                                    Topic   = netMQmessage.Pop().ConvertToString(),
                                    Client  = netMQmessage.Pop().ConvertToString(),
                                    Content = netMQmessage.Pop().ConvertToString()
                                };

                                Logger.Debug("ZeroMQBroker: Received -> {0}", message.ToString());

                                mQueue.Add(message);

                                // ZeroMQBroker relays multiple topics, verify if the message was meant for the current client
                                if (String.Equals(topic, message.Topic, StringComparison.OrdinalIgnoreCase))
                                {
                                    XmlCacheEvent cacheEvent = XmlCacheEvent.FromXml(message.Content);

                                    if (cacheEvent != null)
                                    {
                                        OnCacheEvent(cacheEvent.CacheRegion, cacheEvent.Key, cacheEvent.EventType);
                                    }
                                }
                            }
                        }
                        catch (OperationCanceledException)
                        {
                            // We have been asked to cancel operation
                            return;
                        }
                        catch (Exception ex)
                        {
                            Logger.Error("ZeroMQBroker: Error receiving message.", ex);
                        }
                    };

                    while (!cancellationToken.IsCancellationRequested)
                    {
                        try
                        {
                            pullSocket.Poll(TimeSpan.FromSeconds(1));
                        }
                        catch (OperationCanceledException)
                        {
                            // We have been asked to cancel operation
                            break;
                        }
                        catch (Exception ex)
                        {
                            Logger.Error("ZeroMQBroker: Error polling for messages.", ex);
                        }
                    }

                    // Close socket
                    pullSocket.Close();
                }

                context.Terminate();
            }
        }