Inheritance: pegasus.eventbus.client.Envelope
        public void Dispatch(AmqpEnvelope env)
        {
            LOG.DebugFormat("Was given an envelope for dispatch. {0}", env);

            lock (_queueLock)
            {
                _eventQueue.Enqueue(env);
            }
        }
        public void Send(IEvent message)
        {
            // I won't send null events!
            if (null == message) { throw new ArgumentNullException("message"); }

            // wrap our message in an AMQP envelope
            AmqpEnvelope env = new AmqpEnvelope(message);

            // locate the correct exchange for this topic
            IExchange exchange = _exchangeLocator.GetExchange(env.Topic);

            // add the appropriate headers
            env.EventType = message.GetType().FullName;
            env.SetHeader(AmqpHeaders.SEND_DATETIME, DateTime.Now.ToString());
            env.SetHeader(AmqpHeaders.REPLY_TO_EXCHANGE, exchange.ToUri());

            // place the envelope on the exchange
            exchange.Publish(env);
        }
 public void Handle_Envelope(AmqpEnvelope env)
 {
     if (null != this.EnvelopeReceived)
     {
         // why am I doing this?  If an event has multiple handlers and one handler
         // throws an exception, the other handlers will not be raised.
         foreach (Delegate callback in this.EnvelopeReceived.GetInvocationList())
         {
             try
             {
                 callback.DynamicInvoke(env);
             }
             catch (Exception ex)
             {
                 LOG.Warn(
                     "Caught an unhandled exception thrown from a client attempting to handle a new envelope",
                     ex);
             }
         }
     }
 }
Exemplo n.º 4
0
        public void Listen()
        {
            ConnectionFactory factory = new ConnectionFactory();
            factory.HostName = _exchange.Hostname;
            factory.VirtualHost = _exchange.VirtualHost;
            factory.Port = AmqpTcpEndpoint.UseDefaultPort;

            _connection = factory.CreateConnection();
            _channel = _connection.CreateModel();

            // declare the exchange
            _channel.ExchangeDeclare(_exchange.Name, ExchangeType.Topic, true);
            // declare the queue
            _queue = _channel.QueueDeclare(_queueName, false, true, false, null);

            // create a basic queueing consumer
            QueueingBasicConsumer consumer = new QueueingBasicConsumer(_channel);
            String consumerTag = _channel.BasicConsume(_queue.QueueName, false, consumer);

            // let anyone interested know that we've started
            this.MarkAsStarted();

            // and consume until we've been disposed
            while (!_isDisposing)
            {
                while (_bindings.Count > 0)
                {
                    try
                    {
                        BasicDeliverEventArgs e = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
                        IBasicProperties props = e.BasicProperties;

                        // create an amqp envelope out of the byte array
                        AmqpEnvelope env = new AmqpEnvelope(e.Body);

                        // do some receipt-specific stuff
                        this.LogAndSetReceiptHeaders(env, props);

                        // raise the envelope to interested clients
                        this.Raise_EnvelopeReceived_Event(env);

                        // wait for the envelope to be marked as processed before getting the next message
                        env.WaitToBeProcessed();

                        // we may want the WaitToBeProcessed method to return a completion type
                        // one day so that we can do smarter things than just "ack", for example,
                        // "nack'ing" events we failed to process.
                        _channel.BasicAck(e.DeliveryTag, false);
                    }
                    catch (EndOfStreamException)
                    {
                        // this happens when we get disconnected somehow.  Typically, this
                        // happens when the process is shutting down.  Let's log this and
                        // not freak out about it.
                        LOG.InfoFormat("Rabbit Queue {0} is no longer listening for new events", _queueName);
                        break;
                    }
                    catch (Exception ex)
                    {
                        // The consumer was removed, either through
                        // channel or connection closure, or through the
                        // action of IModel.BasicCancel().
                        LOG.Error(string.Format(
                            "The Rabbit queue {0} encountered an exception attempting to consume a message.", _queueName
                            ), ex);
                        break;
                    }
                }

                if (_bindings.Count == 0)
                {
                    // avoid a hard-loop
                    Thread.Sleep(100);
                }
            }
        }
Exemplo n.º 5
0
 public void Raise_EnvelopeReceived_Event(AmqpEnvelope env)
 {
     if (null != this.EnvelopeReceived)
     {
         foreach (Delegate callback in this.EnvelopeReceived.GetInvocationList())
         {
             try
             {
                 callback.DynamicInvoke(env);
             }
             catch (Exception ex)
             {
                 LOG.Warn(
                     "Caught an unhandled exception from a client while raising the envelope received event",
                     ex);
             }
         }
     }
 }
Exemplo n.º 6
0
        public void LogAndSetReceiptHeaders(AmqpEnvelope env, IBasicProperties rabbitProps)
        {
            LOG.DebugFormat("Received an envelope from rabbit queue {0} containing an event of topic {1}", _queueName, env.Topic);

            env.Headers.Add(AmqpHeaders.RECEIVE_DATETIME, DateTime.Now.ToString());
            env.Headers.Add(AmqpHeaders.RECEVING_QUEUE, _queueName);

            if (null != rabbitProps)
            {
                env.Headers.Add(AmqpHeaders.REPLY_TO_QUEUE, rabbitProps.ReplyTo);

                // let's carry any string/string properties from the rabbit message in case
                // the client needs them for further use.
                if (null != rabbitProps.Headers)
                {
                    foreach (DictionaryEntry prop in rabbitProps.Headers)
                    {
                        if ((prop.Key is string) && (prop.Value is string))
                        {
                            LOG.DebugFormat("Adding rabbit property {0} with value {1}", prop.Key, prop.Value);
                            env.Headers.Add(prop.Key as string, prop.Value as string);
                        }
                    }
                }
            }
        }
 public void Publish(AmqpEnvelope env)
 {
     this.Publish(env.Serialize(), env.Topic);
 }
        protected void Deliver(AmqpEnvelope env)
        {
            try
            {
                LOG.DebugFormat("Now delivering to client(s): {0}", env);

                IEvent message = env.Open();

                // always check for interceptors first.  They're on a schedule, man.
                if (this.DoesNotIntercept(message))
                {
                    IEnumerable<IEventSubscription> subs = _subscriptions.For(message);

                    foreach (IEventSubscription sub in subs)
                    {
                        try
                        {
                            sub.Handler(message);
                        }
                        catch (Exception ex)
                        {
                            LOG.Error(string.Format("{0}{1}{2}",
                                "The event dispatcher caught an unhandled exception thrown by a client's event handler.  ",
                                "The event dispatcher is fine and message processing will continue, ",
                                "but the client that wanted to handle the event may not have done so."
                                ), ex);
                        }
                    }
                }

                // now, deliver the event to any wiretappers - even though it may have been
                // intercepted as a response for a request
                foreach (IEventSubscription sub in _wiretaps)
                {
                    try
                    {
                        sub.Handler(message);
                    }
                    catch (Exception ex)
                    {
                        LOG.Error(string.Format("{0}{1}{2}",
                            "The event dispatcher caught an unhandled exception thrown by a client's event handler.  ",
                            "The event dispatcher is fine and message processing will continue, ",
                            "but the client that wanted to handle the event may not have done so."
                            ), ex);
                    }
                }
            }
            catch (Exception ex)
            {
                LOG.Error(string.Format("{0}{1}{2}",
                    "The event dispatcher encountered an exception while trying to open an envelope and ",
                    "deliver it to subscribed clients.  The event dispatcher is fine and message processing ",
                    "will continue, but any clients wanting to handle the event will not get it.")
                    , ex);
            }
            finally
            {
                env.MarkAsProcessed();
            }
        }