001 /*
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements. See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership. The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License. You may obtain a copy of the License at
010 *
011 * http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied. See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 *
020 */
021 package org.apache.qpid.client.handler;
022
023 import org.apache.qpid.AMQConnectionClosedException;
024 import org.apache.qpid.AMQException;
025 import org.apache.qpid.client.AMQAuthenticationException;
026 import org.apache.qpid.client.protocol.AMQProtocolSession;
027 import org.apache.qpid.client.state.AMQState;
028 import org.apache.qpid.client.state.StateAwareMethodListener;
029 import org.apache.qpid.framing.AMQShortString;
030 import org.apache.qpid.framing.ConnectionCloseBody;
031 import org.apache.qpid.framing.ConnectionCloseOkBody;
032 import org.apache.qpid.protocol.AMQConstant;
033
034 import org.slf4j.Logger;
035 import org.slf4j.LoggerFactory;
036
037 public class ConnectionCloseMethodHandler implements StateAwareMethodListener<ConnectionCloseBody>
038 {
039 private static final Logger _logger = LoggerFactory.getLogger(ConnectionCloseMethodHandler.class);
040
041 private static ConnectionCloseMethodHandler _handler = new ConnectionCloseMethodHandler();
042
043 public static ConnectionCloseMethodHandler getInstance()
044 {
045 return _handler;
046 }
047
048 private ConnectionCloseMethodHandler()
049 {
050 }
051
052 public void methodReceived(AMQProtocolSession session, ConnectionCloseBody method, int channelId)
053 throws AMQException
054 {
055 _logger.info("ConnectionClose frame received");
056
057 // does it matter
058 // stateManager.changeState(AMQState.CONNECTION_CLOSING);
059
060 AMQConstant errorCode = AMQConstant.getConstant(method.getReplyCode());
061 AMQShortString reason = method.getReplyText();
062
063 AMQException error = null;
064
065 try
066 {
067
068 ConnectionCloseOkBody closeOkBody = session.getMethodRegistry().createConnectionCloseOkBody();
069 // TODO: check whether channel id of zero is appropriate
070 // Be aware of possible changes to parameter order as versions change.
071 session.writeFrame(closeOkBody.generateFrame(0));
072
073 if (errorCode != AMQConstant.REPLY_SUCCESS)
074 {
075 if (errorCode == AMQConstant.NOT_ALLOWED || (errorCode == AMQConstant.ACCESS_REFUSED))
076 {
077 _logger.info("Error :" + errorCode + ":" + Thread.currentThread().getName());
078
079 error = new AMQAuthenticationException(errorCode, reason == null ? null : reason.toString(), null);
080 }
081 else
082 {
083 _logger.info("Connection close received with error code " + errorCode);
084
085 error = new AMQConnectionClosedException(errorCode, "Error: " + reason, null);
086 }
087 }
088 }
089 finally
090 {
091
092 if (error != null)
093 {
094 session.notifyError(error);
095 }
096
097 // Close the protocol Session, including any open TCP connections
098 session.closeProtocolSession();
099
100 // Closing the session should not introduce a race condition as this thread will continue to propgate any
101 // exception in to the exceptionCaught method of the SessionHandler.
102 // Any sessionClosed event should occur after this.
103 }
104 }
105
106 }
|