示例#1
0
        public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
        {
            ISaslClient saslClient = evt.ProtocolSession.SaslClient;

            if (saslClient == null)
            {
                throw new AMQException("No SASL client set up - cannot proceed with authentication");
            }


            ConnectionSecureBody body = (ConnectionSecureBody)evt.Method;

            try
            {
                // Evaluate server challenge
                byte[] response = saslClient.EvaluateChallenge(body.Challenge);
                // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0)
                // TODO: Connect this to the session version obtained from ProtocolInitiation for this session.
                // Be aware of possible changes to parameter order as versions change.
                AMQFrame responseFrame = ConnectionSecureOkBody.CreateAMQFrame(
                    evt.ChannelId, response);
                evt.ProtocolSession.WriteFrame(responseFrame);
            } catch (SaslException e)
            {
                throw new AMQException("Error processing SASL challenge: " + e, e);
            }
        }
示例#2
0
        public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
        {
            _logger.Debug("ConnectionTune frame received");
            ConnectionTuneBody frame   = (ConnectionTuneBody)evt.Method;
            AMQProtocolSession session = evt.ProtocolSession;

            ConnectionTuneParameters parameters = session.ConnectionTuneParameters;

            if (parameters == null)
            {
                parameters = new ConnectionTuneParameters();
            }

            _logger.Debug(String.Format("ConnectionTune.heartbeat = {0}.", frame.Heartbeat));

            parameters.FrameMax              = frame.FrameMax;
            parameters.Heartbeat             = frame.Heartbeat;
            session.ConnectionTuneParameters = parameters;

            stateManager.ChangeState(AMQState.CONNECTION_NOT_OPENED);
            session.WriteFrame(ConnectionTuneOkBody.CreateAMQFrame(
                                   evt.ChannelId, frame.ChannelMax, frame.FrameMax, frame.Heartbeat));
            session.WriteFrame(ConnectionOpenBody.CreateAMQFrame(
                                   evt.ChannelId, session.AMQConnection.VirtualHost, null, true));

            if (frame.Heartbeat > 0)
            {
                evt.ProtocolSession.AMQConnection.StartHeartBeatThread(frame.Heartbeat);
            }
        }
        public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
        {
            _logger.Debug("ConnectionClose frame received");
            ConnectionCloseBody method = (ConnectionCloseBody)evt.Method;

            int    errorCode = method.ReplyCode;
            String reason    = method.ReplyText;

            // send CloseOK
            evt.ProtocolSession.WriteFrame(ConnectionCloseOkBody.CreateAMQFrame(evt.ChannelId));

            if (errorCode != AMQConstant.REPLY_SUCCESS.Code)
            {
                if (errorCode == AMQConstant.NOT_ALLOWED.Code)
                {
                    _logger.Info("Authentication Error: " + Thread.CurrentThread.Name);
                    evt.ProtocolSession.CloseProtocolSession();

                    //todo this is a bit of a fudge (could be conssidered such as each new connection needs a new state manager or at least a fresh state.
                    stateManager.ChangeState(AMQState.CONNECTION_NOT_STARTED);

                    throw new AMQAuthenticationException(errorCode, reason);
                }
                else
                {
                    _logger.Info("Connection close received with error code " + errorCode);
                    throw new AMQConnectionClosedException(errorCode, "Error: " + reason);
                }
            }
            // this actually closes the connection in the case where it is not an error.
            evt.ProtocolSession.CloseProtocolSession();
            stateManager.ChangeState(AMQState.CONNECTION_CLOSED);
        }
示例#4
0
        public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
        {
            UnprocessedMessage msg = new UnprocessedMessage();

            msg.DeliverBody = (BasicDeliverBody)evt.Method;
            msg.ChannelId   = evt.ChannelId;
            _logger.Debug("New JmsDeliver method received");
            evt.ProtocolSession.UnprocessedMessageReceived(msg);
        }
        public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
        {
            QueueDeleteOkBody body = (QueueDeleteOkBody)evt.Method;

            if (body != null)
            {
                _logger.InfoFormat("Received Queue.Delete-Ok message, message count {0}", body.MessageCount);
            }
        }
        public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
        {
            _logger.Debug("New Basic.Return method received");
            UnprocessedMessage msg = new UnprocessedMessage();

            msg.DeliverBody = null;
            msg.BounceBody  = (BasicReturnBody)evt.Method;
            msg.ChannelId   = evt.ChannelId;

            evt.ProtocolSession.UnprocessedMessageReceived(msg);
        }
        public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
        {
            ConnectionStartBody body = (ConnectionStartBody)evt.Method;
            AMQProtocolSession  ps   = evt.ProtocolSession;

            try
            {
                if (body.Mechanisms == null)
                {
                    throw new AMQException("mechanism not specified in ConnectionStart method frame");
                }
                string mechanisms        = Encoding.UTF8.GetString(body.Mechanisms);
                string selectedMechanism = ChooseMechanism(mechanisms);
                if (selectedMechanism == null)
                {
                    throw new AMQException("No supported security mechanism found, passed: " + mechanisms);
                }

                byte[] saslResponse = DoAuthentication(selectedMechanism, ps);

                if (body.Locales == null)
                {
                    throw new AMQException("Locales is not defined in Connection Start method");
                }
                string   allLocales = Encoding.ASCII.GetString(body.Locales);
                string[] locales    = allLocales.Split(' ');
                string   selectedLocale;
                if (locales != null && locales.Length > 0)
                {
                    selectedLocale = locales[0];
                }
                else
                {
                    throw new AMQException("No locales sent from server, passed: " + locales);
                }

                stateManager.ChangeState(AMQState.CONNECTION_NOT_TUNED);
                FieldTable clientProperties = new FieldTable();
                clientProperties["product"]  = "Apache.Qpid.NET";
                clientProperties["version"]  = "1.0";
                clientProperties["platform"] = GetFullSystemInfo();
                clientProperties["instance"] = ps.ClientID;
                AMQFrame frame = ConnectionStartOkBody.CreateAMQFrame(
                    evt.ChannelId, clientProperties, selectedMechanism,
                    saslResponse, selectedLocale);
                ps.WriteFrame(frame);
            }
            catch (Exception e)
            {
                throw new AMQException(_log, "Unable to decode data: " + e, e);
            }
        }
        private void MakeBrokerConnection(IBrokerInfo brokerDetail)
        {
            try
            {
                _stateManager     = new AMQStateManager();
                _protocolListener = new AMQProtocolListener(this, _stateManager);
                _protocolListener.AddFrameListener(_stateManager);

                /*
                 * // Currently there is only one transport option - BlockingSocket.
                 * String assemblyName = "Apache.Qpid.Client.Transport.Socket.Blocking.dll";
                 * String transportType = "Apache.Qpid.Client.Transport.Socket.Blocking.BlockingSocketTransport";
                 *
                 * // Load the transport assembly dynamically.
                 * _transport = LoadTransportFromAssembly(brokerDetail.getHost(), brokerDetail.getPort(), assemblyName, transportType);
                 */

                _transport = new BlockingSocketTransport();

                // Connect.
                _transport.Connect(brokerDetail, this);
                _protocolWriter  = new ProtocolWriter(_transport.ProtocolWriter, _protocolListener);
                _protocolSession = new AMQProtocolSession(_transport.ProtocolWriter, _transport, this);
                _protocolListener.ProtocolSession = _protocolSession;

                // Now start the connection "handshake".
                _transport.ProtocolWriter.Write(new ProtocolInitiation());

                // Blocks until the connection has been opened.
                _stateManager.AttainState(AMQState.CONNECTION_OPEN);

                _failoverPolicy.attainedConnection();

                // XXX: Again this should be changed to a suitable notify.
                _connected = true;
            }
            catch (AMQException e)
            {
                _lastAMQException = e;
                throw; // rethrow
            }
        }
示例#9
0
        public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
        {
            _logger.Debug("ChannelClose method received");
            ChannelCloseBody method = (ChannelCloseBody)evt.Method;

            int    errorCode = method.ReplyCode;
            string reason    = method.ReplyText;

            if (_logger.IsDebugEnabled)
            {
                _logger.Debug("Channel close reply code: " + errorCode + ", reason: " + reason);
            }

            AMQFrame frame = ChannelCloseOkBody.CreateAMQFrame(evt.ChannelId);

            evt.ProtocolSession.WriteFrame(frame);

            if (errorCode != AMQConstant.REPLY_SUCCESS.Code)
            {
                _logger.Debug("Channel close received with errorCode " + errorCode + ", throwing exception");
                if (errorCode == AMQConstant.NO_CONSUMERS.Code)
                {
                    throw new AMQNoConsumersException(reason);
                }
                if (errorCode == AMQConstant.NO_ROUTE.Code)
                {
                    throw new AMQNoRouteException(reason);
                }
                if (errorCode == AMQConstant.INVALID_ARGUMENT.Code)
                {
                    throw new AMQInvalidArgumentException(reason);
                }
                if (errorCode == AMQConstant.INVALID_ROUTING_KEY.Code)
                {
                    throw new AMQInvalidRoutingKeyException(reason);
                }
                // any other
                throw new AMQChannelClosedException(errorCode, "Error: " + reason);
            }
            evt.ProtocolSession.ChannelClosed(evt.ChannelId, errorCode, reason);
        }
 public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
 {
     /*_logger.Info("ConnectionRedirect frame received");
      * ConnectionRedirectBody method = (ConnectionRedirectBody) evt.Method;
      *
      * // the host is in the form hostname:port with the port being optional
      * int portIndex = method.Host.IndexOf(':');
      * String host;
      * int port;
      * if (portIndex == -1)
      * {
      *  host = method.Host;
      *  port = DEFAULT_REDIRECT_PORT;
      * }
      * else
      * {
      *  host = method.Host.Substring(0, portIndex);
      *  port = Int32.Parse(method.Host.Substring(portIndex + 1));
      * }
      * evt.ProtocolSession.Failover(host, port);*/
 }
        public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
        {
            _logger.Debug("ConnectionCloseOk frame received");
//            ConnectionCloseOkBody method = (ConnectionCloseOkBody)evt.Method;
            stateManager.ChangeState(AMQState.CONNECTION_CLOSED);
        }
示例#12
0
 public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
 {
     stateManager.ChangeState(AMQState.CONNECTION_OPEN);
 }
示例#13
0
 public AMQProtocolListener(AMQConnection connection, AMQStateManager stateManager)
 {
     _connection      = connection;
     _stateManager    = stateManager;
     _failoverHandler = new FailoverHandler(connection);
 }
示例#14
0
        public void Run()
        {
            if (Thread.CurrentThread.IsBackground)
            {
                throw new InvalidOperationException("FailoverHandler must Run on a non-background thread.");
            }

            AMQProtocolListener pl = _connection.ProtocolListener;

            pl.FailoverLatch = new ManualResetEvent(false);

            // We wake up listeners. If they can handle failover, they will extend the
            // FailoverSupport class and will in turn block on the latch until failover
            // has completed before retrying the operation
            _connection.ProtocolListener.PropagateExceptionToWaiters(new FailoverException("Failing over about to start"));

            // Since failover impacts several structures we protect them all with a single mutex. These structures
            // are also in child objects of the connection. This allows us to manipulate them without affecting
            // client code which runs in a separate thread.
            lock (_connection.FailoverMutex)
            {
                _log.Info("Starting failover process");

                // We switch in a new state manager temporarily so that the interaction to get to the "connection open"
                // state works, without us having to terminate any existing "state waiters". We could theoretically
                // have a state waiter waiting until the connection is closed for some reason. Or in future we may have
                // a slightly more complex state model therefore I felt it was worthwhile doing this.
                AMQStateManager existingStateManager = _connection.ProtocolListener.StateManager;
                _connection.ProtocolListener.StateManager = new AMQStateManager();
                if (!_connection.FirePreFailover(_host != null))
                {
                    _connection.ProtocolListener.StateManager = existingStateManager;
                    if (_host != null)
                    {
                        _connection.ExceptionReceived(new AMQDisconnectedException("Redirect was vetoed by client"));
                    }
                    else
                    {
                        _connection.ExceptionReceived(new AMQDisconnectedException("Failover was vetoed by client"));
                    }
                    pl.FailoverLatch.Set();
                    pl.FailoverLatch = null;
                    return;
                }
                bool failoverSucceeded;
                // when host is non null we have a specified failover host otherwise we all the client to cycle through
                // all specified hosts

                // if _host has value then we are performing a redirect.
                if (_host != null)
                {
                    // todo: fix SSL support!
                    failoverSucceeded = _connection.AttemptReconnection(_host, _port, null);
                }
                else
                {
                    failoverSucceeded = _connection.AttemptReconnection();
                }

                // XXX: at this point it appears that we are going to set StateManager to existingStateManager in
                // XXX: both paths of control.
                if (!failoverSucceeded)
                {
                    _connection.ProtocolListener.StateManager = existingStateManager;
                    _connection.ExceptionReceived(
                        new AMQDisconnectedException("Server closed connection and no failover " +
                                                     "was successful"));
                }
                else
                {
                    _connection.ProtocolListener.StateManager = existingStateManager;
                    try
                    {
                        if (_connection.FirePreResubscribe())
                        {
                            _log.Info("Resubscribing on new connection");
                            _connection.ResubscribeChannels();
                        }
                        else
                        {
                            _log.Info("Client vetoed automatic resubscription");
                        }
                        _connection.FireFailoverComplete();
                        _connection.ProtocolListener.FailoverState = FailoverState.NOT_STARTED;
                        _log.Info("Connection failover completed successfully");
                    }
                    catch (Exception e)
                    {
                        _log.Info("Failover process failed - exception being propagated by protocol handler");
                        _connection.ProtocolListener.FailoverState = FailoverState.FAILED;
                        try
                        {
                            _connection.ProtocolListener.OnException(e);
                        }
                        catch (Exception ex)
                        {
                            _log.Error("Error notifying protocol session of error: " + ex, ex);
                        }
                    }
                }
            }
            pl.FailoverLatch.Set();
        }