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); } }
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); }
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 } }
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); }
public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt) { stateManager.ChangeState(AMQState.CONNECTION_OPEN); }
public AMQProtocolListener(AMQConnection connection, AMQStateManager stateManager) { _connection = connection; _stateManager = stateManager; _failoverHandler = new FailoverHandler(connection); }
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(); }