diff options
Diffstat (limited to 'client/src')
102 files changed, 0 insertions, 14554 deletions
diff --git a/client/src/log4j.properties b/client/src/log4j.properties deleted file mode 100644 index 371cfb6d61..0000000000 --- a/client/src/log4j.properties +++ /dev/null @@ -1,28 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# -log4j.rootLogger=${root.logging.level} - - -log4j.logger.org.apache.qpid=${amqj.logging.level}, console -log4j.additivity.org.apache.qpid=false - -log4j.appender.console=org.apache.log4j.ConsoleAppender -log4j.appender.console.Threshold=info -log4j.appender.console.layout=org.apache.log4j.PatternLayout -log4j.appender.console.layout.ConversionPattern=%t %d %p [%c{4}] %m%n diff --git a/client/src/org/apache/qpid/client/AMQAuthenticationException.java b/client/src/org/apache/qpid/client/AMQAuthenticationException.java deleted file mode 100644 index 74462a8d19..0000000000 --- a/client/src/org/apache/qpid/client/AMQAuthenticationException.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import org.apache.qpid.AMQException; -import org.apache.qpid.protocol.AMQConstant; - -public class AMQAuthenticationException extends AMQException -{ - public AMQAuthenticationException(int error, String msg) - { - super(error,msg); - } -} diff --git a/client/src/org/apache/qpid/client/AMQBrokerDetails.java b/client/src/org/apache/qpid/client/AMQBrokerDetails.java deleted file mode 100644 index 7cabc667c1..0000000000 --- a/client/src/org/apache/qpid/client/AMQBrokerDetails.java +++ /dev/null @@ -1,304 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import org.apache.qpid.jms.BrokerDetails; -import org.apache.qpid.url.URLHelper; -import org.apache.qpid.url.URLSyntaxException; - -import java.util.HashMap; -import java.net.URISyntaxException; -import java.net.URI; - -public class AMQBrokerDetails implements BrokerDetails -{ - private String _host; - private int _port; - private String _transport; - - private HashMap<String, String> _options; - - public AMQBrokerDetails() - { - _options = new HashMap<String, String>(); - } - - public AMQBrokerDetails(String url) throws URLSyntaxException - { - this(); - // URL should be of format tcp://host:port?option='value',option='value' - try - { - URI connection = new URI(url); - - String transport = connection.getScheme(); - - // Handles some defaults to minimise changes to existing broker URLS e.g. localhost - if (transport != null) - { - //todo this list of valid transports should be enumerated somewhere - if ((!(transport.equalsIgnoreCase("vm") || - transport.equalsIgnoreCase("tcp")))) - { - if (transport.equalsIgnoreCase("localhost")) - { - connection = new URI(DEFAULT_TRANSPORT + "://" + url); - transport = connection.getScheme(); - } - else - { - if (url.charAt(transport.length()) == ':' && url.charAt(transport.length()+1) != '/' ) - { - //Then most likely we have a host:port value - connection = new URI(DEFAULT_TRANSPORT + "://" + url); - transport = connection.getScheme(); - } - else - { - URLHelper.parseError(0, transport.length(), "Unknown transport", url); - } - } - } - } - else - { - //Default the transport - connection = new URI(DEFAULT_TRANSPORT + "://" + url); - transport = connection.getScheme(); - } - - if (transport == null) - { - URLHelper.parseError(-1, "Unknown transport:'" + transport + "'" + - " In broker URL:'" + url + "' Format: " + URL_FORMAT_EXAMPLE, ""); - } - - setTransport(transport); - - String host = connection.getHost(); - - // Fix for Java 1.5 - if (host == null) - { - host = ""; - } - - setHost(host); - - int port = connection.getPort(); - - if (port == -1) - { - // Another fix for Java 1.5 URI handling - String auth = connection.getAuthority(); - - if (auth != null && auth.startsWith(":")) - { - setPort(Integer.parseInt(auth.substring(1))); - } - else - { - setPort(DEFAULT_PORT); - } - } - else - { - setPort(port); - } - - String queryString = connection.getQuery(); - - URLHelper.parseOptions(_options, queryString); - - //Fragment is #string (not used) - } - catch (URISyntaxException uris) - { - if (uris instanceof URLSyntaxException) - { - throw (URLSyntaxException) uris; - } - - URLHelper.parseError(uris.getIndex(), uris.getReason(), uris.getInput()); - } - } - - public AMQBrokerDetails(String host, int port, boolean useSSL) - { - _host = host; - _port = port; - - if (useSSL) - { - setOption(OPTIONS_SSL, "true"); - } - } - - public String getHost() - { - return _host; - } - - public void setHost(String _host) - { - this._host = _host; - } - - public int getPort() - { - return _port; - } - - public void setPort(int _port) - { - this._port = _port; - } - - public String getTransport() - { - return _transport; - } - - public void setTransport(String _transport) - { - this._transport = _transport; - } - - - public String getOption(String key) - { - return _options.get(key); - } - - public void setOption(String key, String value) - { - _options.put(key, value); - } - - public long getTimeout() - { - if (_options.containsKey(OPTIONS_CONNECT_TIMEOUT)) - { - try - { - return Long.parseLong(_options.get(OPTIONS_CONNECT_TIMEOUT)); - } - catch (NumberFormatException nfe) - { - //Do nothing as we will use the default below. - } - } - - return BrokerDetails.DEFAULT_CONNECT_TIMEOUT; - } - - public void setTimeout(long timeout) - { - setOption(OPTIONS_CONNECT_TIMEOUT, Long.toString(timeout)); - } - - public String toString() - { - StringBuffer sb = new StringBuffer(); - - sb.append(_transport); - sb.append("://"); - - if (!(_transport.equalsIgnoreCase("vm"))) - { - sb.append(_host); - } - - sb.append(':'); - sb.append(_port); - - sb.append(printOptionsURL()); - - return sb.toString(); - } - - public boolean equals(Object o) - { - if (!(o instanceof BrokerDetails)) - { - return false; - } - - BrokerDetails bd = (BrokerDetails) o; - - return _host.equalsIgnoreCase(bd.getHost()) && - (_port == bd.getPort()) && - _transport.equalsIgnoreCase(bd.getTransport()) && - (useSSL() == bd.useSSL()); - - //todo do we need to compare all the options as well? - } - - private String printOptionsURL() - { - StringBuffer optionsURL = new StringBuffer(); - - optionsURL.append('?'); - - if (!(_options.isEmpty())) - { - - for (String key : _options.keySet()) - { - optionsURL.append(key); - - optionsURL.append("='"); - - optionsURL.append(_options.get(key)); - - optionsURL.append("'"); - - optionsURL.append(URLHelper.DEFAULT_OPTION_SEPERATOR); - } - } - - //remove the extra DEFAULT_OPTION_SEPERATOR or the '?' if there are no options - optionsURL.deleteCharAt(optionsURL.length() - 1); - - return optionsURL.toString(); - } - - public boolean useSSL() - { - // To be friendly to users we should be case insensitive. - // or simply force users to conform to OPTIONS_SSL - // todo make case insensitive by trying ssl Ssl sSl ssL SSl SsL sSL SSL - - if (_options.containsKey(OPTIONS_SSL)) - { - return _options.get(OPTIONS_SSL).equalsIgnoreCase("true"); - } - - return USE_SSL_DEFAULT; - } - - public void useSSL(boolean ssl) - { - setOption(OPTIONS_SSL, Boolean.toString(ssl)); - } - - -} diff --git a/client/src/org/apache/qpid/client/AMQConnection.java b/client/src/org/apache/qpid/client/AMQConnection.java deleted file mode 100644 index 98db26d0c4..0000000000 --- a/client/src/org/apache/qpid/client/AMQConnection.java +++ /dev/null @@ -1,974 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQConnectionException; -import org.apache.qpid.AMQException; -import org.apache.qpid.AMQUndeliveredException; -import org.apache.qpid.AMQUnresolvedAddressException; -import org.apache.qpid.client.failover.FailoverSupport; -import org.apache.qpid.client.protocol.AMQProtocolHandler; -import org.apache.qpid.client.state.AMQState; -import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.framing.BasicQosBody; -import org.apache.qpid.framing.BasicQosOkBody; -import org.apache.qpid.framing.ChannelOpenBody; -import org.apache.qpid.framing.ChannelOpenOkBody; -import org.apache.qpid.framing.TxSelectBody; -import org.apache.qpid.framing.TxSelectOkBody; -import org.apache.qpid.jms.BrokerDetails; -import org.apache.qpid.jms.ChannelLimitReachedException; -import org.apache.qpid.jms.Connection; -import org.apache.qpid.jms.ConnectionListener; -import org.apache.qpid.jms.ConnectionURL; -import org.apache.qpid.jms.FailoverPolicy; -import org.apache.qpid.url.URLSyntaxException; - -import javax.jms.*; -import javax.naming.NamingException; -import javax.naming.Reference; -import javax.naming.Referenceable; -import javax.naming.StringRefAddr; -import java.io.IOException; -import java.net.ConnectException; -import java.nio.channels.UnresolvedAddressException; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; - -public class AMQConnection extends Closeable implements Connection, QueueConnection, TopicConnection, Referenceable -{ - private static final Logger _logger = Logger.getLogger(AMQConnection.class); - - private AtomicInteger _idFactory = new AtomicInteger(0); - - /** - * This is the "root" mutex that must be held when doing anything that could be impacted by failover. - * This must be held by any child objects of this connection such as the session, producers and consumers. - */ - private final Object _failoverMutex = new Object(); - - /** - * A channel is roughly analogous to a session. The server can negotiate the maximum number of channels - * per session and we must prevent the client from opening too many. Zero means unlimited. - */ - private long _maximumChannelCount; - - /** - * The maximum size of frame supported by the server - */ - private long _maximumFrameSize; - - /** - * The protocol handler dispatches protocol events for this connection. For example, when the connection is dropped - * the handler deals with this. It also deals with the initial dispatch of any protocol frames to their appropriate - * handler. - */ - private AMQProtocolHandler _protocolHandler; - - /** - * Maps from session id (Integer) to AMQSession instance - */ - private final Map _sessions = new LinkedHashMap(); //fixme this is map is replicated in amqprotocolsession as _channelId2SessionMap - - private String _clientName; - - /** - * The user name to use for authentication - */ - private String _username; - - /** - * The password to use for authentication - */ - private String _password; - - /** - * The virtual path to connect to on the AMQ server - */ - private String _virtualHost; - - private ExceptionListener _exceptionListener; - - private ConnectionListener _connectionListener; - - private ConnectionURL _connectionURL; - - /** - * Whether this connection is started, i.e. whether messages are flowing to consumers. It has no meaning for - * message publication. - */ - private boolean _started; - - /** - * Policy dictating how to failover - */ - private FailoverPolicy _failoverPolicy; - - /* - * _Connected should be refactored with a suitable wait object. - */ - private boolean _connected; - - /* - * The last error code that occured on the connection. Used to return the correct exception to the client - */ - private AMQException _lastAMQException = null; - - public AMQConnection(String broker, String username, String password, - String clientName, String virtualHost) throws AMQException, URLSyntaxException - { - this(new AMQConnectionURL(ConnectionURL.AMQ_PROTOCOL + "://" + - username + ":" + password + "@" + clientName + - virtualHost + "?brokerlist='" + broker + "'")); - } - - public AMQConnection(String host, int port, String username, String password, - String clientName, String virtualHost) throws AMQException, URLSyntaxException - { - this(host, port, false, username, password, clientName, virtualHost); - } - - public AMQConnection(String host, int port, boolean useSSL, String username, String password, - String clientName, String virtualHost) throws AMQException, URLSyntaxException - { - this(new AMQConnectionURL(useSSL ? - ConnectionURL.AMQ_PROTOCOL + "://" + - username + ":" + password + "@" + clientName + - virtualHost + "?brokerlist='tcp://" + host + ":" + port + "'" - + "," + ConnectionURL.OPTIONS_SSL + "='true'" : - ConnectionURL.AMQ_PROTOCOL + "://" + - username + ":" + password + "@" + clientName + - virtualHost + "?brokerlist='tcp://" + host + ":" + port + "'" - + "," + ConnectionURL.OPTIONS_SSL + "='false'" - )); - } - - public AMQConnection(String connection) throws AMQException, URLSyntaxException - { - this(new AMQConnectionURL(connection)); - } - - public AMQConnection(ConnectionURL connectionURL) throws AMQException - { - _logger.info("Connection:" + connectionURL); - - if (connectionURL == null) - { - throw new IllegalArgumentException("Connection must be specified"); - } - - _connectionURL = connectionURL; - - _clientName = connectionURL.getClientName(); - _username = connectionURL.getUsername(); - _password = connectionURL.getPassword(); - _virtualHost = connectionURL.getVirtualHost(); - - _failoverPolicy = new FailoverPolicy(connectionURL); - - _protocolHandler = new AMQProtocolHandler(this); - - // We are not currently connected - _connected = false; - - - Exception lastException = new Exception(); - lastException.initCause(new ConnectException()); - - while (lastException != null && checkException(lastException) && _failoverPolicy.failoverAllowed()) - { - try - { - makeBrokerConnection(_failoverPolicy.getNextBrokerDetails()); - lastException = null; - } - catch (Exception e) - { - lastException = e; - - _logger.info("Unable to connect to broker at " + _failoverPolicy.getCurrentBrokerDetails(), e.getCause()); - } - } - - _logger.debug("Are we connected:" + _connected); - - // Then the Failover Thread will handle conneciton - if (_failoverPolicy.failoverAllowed()) - { - //TODO this needs to be redone so that we are not spinning. - // A suitable object should be set that is then waited on - // and only notified when a connection is made or when - // the AMQConnection gets closed. - while (!_connected && !_closed.get()) - { - try - { - _logger.debug("Sleeping."); - Thread.sleep(100); - } - catch (InterruptedException ie) - { - _logger.debug("Woken up."); - } - } - if (!_failoverPolicy.failoverAllowed() || _failoverPolicy.getCurrentBrokerDetails() == null) - { - if (_lastAMQException != null) - { - throw _lastAMQException; - } - } - } - else - { - String message = null; - - if (lastException != null) - { - if (lastException.getCause() != null) - { - message = lastException.getCause().getMessage(); - } - else - { - message = lastException.getMessage(); - } - } - - if (message == null || message.equals("")) - { - message = "Unable to Connect"; - } - - AMQException e = new AMQConnectionException(message); - - if (lastException != null) - { - if (lastException instanceof UnresolvedAddressException) - { - e = new AMQUnresolvedAddressException(message, _failoverPolicy.getCurrentBrokerDetails().toString()); - } - e.initCause(lastException); - } - - throw e; - } - } - - protected boolean checkException(Throwable thrown) - { - Throwable cause = thrown.getCause(); - - if (cause == null) - { - cause = thrown; - } - - return ((cause instanceof ConnectException) || (cause instanceof UnresolvedAddressException)); - } - - protected AMQConnection(String username, String password, String clientName, String virtualHost) - { - _clientName = clientName; - _username = username; - _password = password; - _virtualHost = virtualHost; - } - - private void makeBrokerConnection(BrokerDetails brokerDetail) throws IOException, AMQException - { - try - { - TransportConnection.getInstance(brokerDetail).connect(_protocolHandler, brokerDetail); - // this blocks until the connection has been set up or when an error - // has prevented the connection being set up - _protocolHandler.attainState(AMQState.CONNECTION_OPEN); - _failoverPolicy.attainedConnection(); - - //Again this should be changed to a suitable notify - _connected = true; - } - catch (AMQException e) - { - _lastAMQException = e; - throw e; - } - } - - public boolean attemptReconnection(String host, int port, boolean useSSL) - { - BrokerDetails bd = new AMQBrokerDetails(host, port, useSSL); - - _failoverPolicy.setBroker(bd); - - try - { - makeBrokerConnection(bd); - return true; - } - catch (Exception e) - { - _logger.info("Unable to connect to broker at " + bd); - attemptReconnection(); - } - return false; - } - - public boolean attemptReconnection() - { - while (_failoverPolicy.failoverAllowed()) - { - try - { - makeBrokerConnection(_failoverPolicy.getNextBrokerDetails()); - return true; - } - catch (Exception e) - { - if (!(e instanceof AMQException)) - { - _logger.info("Unable to connect to broker at " + _failoverPolicy.getCurrentBrokerDetails(), e); - } - else - { - _logger.info(e.getMessage() + ":Unable to connect to broker at " + _failoverPolicy.getCurrentBrokerDetails()); - } - } - } - - //connection unsuccessful - return false; - } - - /** - * Get the details of the currently active broker - * - * @return null if no broker is active (i.e. no successful connection has been made, or - * the BrokerDetail instance otherwise - */ - public BrokerDetails getActiveBrokerDetails() - { - return _failoverPolicy.getCurrentBrokerDetails(); - } - - public boolean failoverAllowed() - { - return _failoverPolicy.failoverAllowed(); - } - - public Session createSession(final boolean transacted, final int acknowledgeMode) throws JMSException - { - return createSession(transacted, acknowledgeMode, AMQSession.DEFAULT_PREFETCH_HIGH_MARK); - } - - public org.apache.qpid.jms.Session createSession(final boolean transacted, final int acknowledgeMode, - final int prefetch) throws JMSException - { - return createSession(transacted, acknowledgeMode, prefetch, prefetch); - } - - public org.apache.qpid.jms.Session createSession(final boolean transacted, final int acknowledgeMode, - final int prefetchHigh, final int prefetchLow) throws JMSException - { - checkNotClosed(); - if (channelLimitReached()) - { - throw new ChannelLimitReachedException(_maximumChannelCount); - } - else - { - return (org.apache.qpid.jms.Session) new FailoverSupport() - { - public Object operation() throws JMSException - { - int channelId = _idFactory.incrementAndGet(); - - if (_logger.isDebugEnabled()) - { - _logger.debug("Write channel open frame for channel id " + channelId); - } - - // We must create the session and register it before actually sending the frame to the server to - // open it, so that there is no window where we could receive data on the channel and not be set - // up to handle it appropriately. - AMQSession session = new AMQSession(AMQConnection.this, channelId, transacted, acknowledgeMode, - prefetchHigh, prefetchLow); - _protocolHandler.addSessionByChannel(channelId, session); - registerSession(channelId, session); - - boolean success = false; - try - { - createChannelOverWire(channelId, prefetchHigh, prefetchLow, transacted); - success = true; - } - catch (AMQException e) - { - JMSException jmse = new JMSException("Error creating session: " + e); - jmse.setLinkedException(e); - throw jmse; - } - finally - { - if (!success) - { - _protocolHandler.removeSessionByChannel(channelId); - deregisterSession(channelId); - } - } - - if (_started) - { - session.start(); - } - return session; - } - }.execute(this); - } - } - - private void createChannelOverWire(int channelId, int prefetchHigh, int prefetchLow, boolean transacted) - throws AMQException - { - _protocolHandler.syncWrite( - ChannelOpenBody.createAMQFrame(channelId, null), ChannelOpenOkBody.class); - - //todo send low water mark when protocol allows. - _protocolHandler.syncWrite( - BasicQosBody.createAMQFrame(channelId, 0, prefetchHigh, false), - BasicQosOkBody.class); - - if (transacted) - { - if (_logger.isDebugEnabled()) - { - _logger.debug("Issuing TxSelect for " + channelId); - } - _protocolHandler.syncWrite(TxSelectBody.createAMQFrame(channelId), TxSelectOkBody.class); - } - } - - private void reopenChannel(int channelId, int prefetchHigh, int prefetchLow, boolean transacted) throws AMQException - { - try - { - createChannelOverWire(channelId, prefetchHigh, prefetchLow, transacted); - } - catch (AMQException e) - { - _protocolHandler.removeSessionByChannel(channelId); - deregisterSession(channelId); - throw new AMQException("Error reopening channel " + channelId + " after failover: " + e); - } - } - - - public void setFailoverPolicy(FailoverPolicy policy) - { - _failoverPolicy = policy; - } - - public FailoverPolicy getFailoverPolicy() - { - return _failoverPolicy; - } - - /** - * Returns an AMQQueueSessionAdaptor which wraps an AMQSession and throws IllegalStateExceptions - * where specified in the JMS spec - * @param transacted - * @param acknowledgeMode - * @return QueueSession - * @throws JMSException - */ - public QueueSession createQueueSession(boolean transacted, int acknowledgeMode) throws JMSException - { - return new AMQQueueSessionAdaptor(createSession(transacted, acknowledgeMode)); - } - - /** - * Returns an AMQTopicSessionAdapter which wraps an AMQSession and throws IllegalStateExceptions - * where specified in the JMS spec - * @param transacted - * @param acknowledgeMode - * @return TopicSession - * @throws JMSException - */ - public TopicSession createTopicSession(boolean transacted, int acknowledgeMode) throws JMSException - { - return new AMQTopicSessionAdaptor(createSession(transacted, acknowledgeMode)); - } - - private boolean channelLimitReached() - { - return _maximumChannelCount != 0 && _sessions.size() == _maximumChannelCount; - } - - public String getClientID() throws JMSException - { - checkNotClosed(); - return _clientName; - } - - public void setClientID(String clientID) throws JMSException - { - checkNotClosed(); - _clientName = clientID; - } - - public ConnectionMetaData getMetaData() throws JMSException - { - checkNotClosed(); - // TODO Auto-generated method stub - return null; - } - - public ExceptionListener getExceptionListener() throws JMSException - { - checkNotClosed(); - return _exceptionListener; - } - - public void setExceptionListener(ExceptionListener listener) throws JMSException - { - checkNotClosed(); - _exceptionListener = listener; - } - - /** - * Start the connection, i.e. start flowing messages. Note that this method must be called only from a single thread - * and is not thread safe (which is legal according to the JMS specification). - * - * @throws JMSException - */ - public void start() throws JMSException - { - checkNotClosed(); - if (!_started) - { - final Iterator it = _sessions.entrySet().iterator(); - while (it.hasNext()) - { - final AMQSession s = (AMQSession) ((Map.Entry) it.next()).getValue(); - s.start(); - } - _started = true; - } - } - - public void stop() throws JMSException - { - checkNotClosed(); - - if (_started) - { - for (Iterator i = _sessions.values().iterator(); i.hasNext();) - { - ((AMQSession) i.next()).stop(); - } - _started = false; - } - } - - public void close() throws JMSException - { - synchronized(getFailoverMutex()) - { - if (!_closed.getAndSet(true)) - { - try - { - closeAllSessions(null); - _protocolHandler.closeConnection(); - } - catch (AMQException e) - { - throw new JMSException("Error closing connection: " + e); - } - } - } - } - - /** - * Marks all sessions and their children as closed without sending any protocol messages. Useful when - * you need to mark objects "visible" in userland as closed after failover or other significant event that - * impacts the connection. - * <p/> - * The caller must hold the failover mutex before calling this method. - */ - private void markAllSessionsClosed() - { - final LinkedList sessionCopy = new LinkedList(_sessions.values()); - final Iterator it = sessionCopy.iterator(); - while (it.hasNext()) - { - final AMQSession session = (AMQSession) it.next(); - - session.markClosed(); - } - _sessions.clear(); - } - - /** - * Close all the sessions, either due to normal connection closure or due to an error occurring. - * - * @param cause if not null, the error that is causing this shutdown - * <p/> - * The caller must hold the failover mutex before calling this method. - */ - private void closeAllSessions(Throwable cause) throws JMSException - { - final LinkedList sessionCopy = new LinkedList(_sessions.values()); - final Iterator it = sessionCopy.iterator(); - JMSException sessionException = null; - while (it.hasNext()) - { - final AMQSession session = (AMQSession) it.next(); - if (cause != null) - { - session.closed(cause); - } - else - { - try - { - session.close(); - } - catch (JMSException e) - { - _logger.error("Error closing session: " + e); - sessionException = e; - } - } - } - _sessions.clear(); - if (sessionException != null) - { - throw sessionException; - } - } - - public ConnectionConsumer createConnectionConsumer(Destination destination, String messageSelector, - ServerSessionPool sessionPool, - int maxMessages) throws JMSException - { - checkNotClosed(); - return null; - } - - public ConnectionConsumer createConnectionConsumer(Queue queue, String messageSelector, - ServerSessionPool sessionPool, - int maxMessages) throws JMSException - { - checkNotClosed(); - return null; - } - - public ConnectionConsumer createConnectionConsumer(Topic topic, String messageSelector, - ServerSessionPool sessionPool, - int maxMessages) throws JMSException - { - checkNotClosed(); - return null; - } - - public ConnectionConsumer createDurableConnectionConsumer(Topic topic, String subscriptionName, - String messageSelector, ServerSessionPool sessionPool, - int maxMessages) - throws JMSException - { - // TODO Auto-generated method stub - checkNotClosed(); - return null; - } - - public long getMaximumChannelCount() throws JMSException - { - checkNotClosed(); - return _maximumChannelCount; - } - - public void setConnectionListener(ConnectionListener listener) - { - _connectionListener = listener; - } - - public ConnectionListener getConnectionListener() - { - return _connectionListener; - } - - public void setMaximumChannelCount(long maximumChannelCount) - { - _maximumChannelCount = maximumChannelCount; - } - - public void setMaximumFrameSize(long frameMax) - { - _maximumFrameSize = frameMax; - } - - public long getMaximumFrameSize() - { - return _maximumFrameSize; - } - - public Map getSessions() - { - return _sessions; - } - - public String getUsername() - { - return _username; - } - - public String getPassword() - { - return _password; - } - - public String getVirtualHost() - { - return _virtualHost; - } - - public AMQProtocolHandler getProtocolHandler() - { - return _protocolHandler; - } - - public void bytesSent(long writtenBytes) - { - if (_connectionListener != null) - { - _connectionListener.bytesSent(writtenBytes); - } - } - - public void bytesReceived(long receivedBytes) - { - if (_connectionListener != null) - { - _connectionListener.bytesReceived(receivedBytes); - } - } - - /** - * Fire the preFailover event to the registered connection listener (if any) - * - * @param redirect true if this is the result of a redirect request rather than a connection error - * @return true if no listener or listener does not veto change - */ - public boolean firePreFailover(boolean redirect) - { - boolean proceed = true; - if (_connectionListener != null) - { - proceed = _connectionListener.preFailover(redirect); - } - return proceed; - } - - /** - * Fire the preResubscribe event to the registered connection listener (if any). If the listener - * vetoes resubscription then all the sessions are closed. - * - * @return true if no listener or listener does not veto resubscription. - * @throws JMSException - */ - public boolean firePreResubscribe() throws JMSException - { - if (_connectionListener != null) - { - boolean resubscribe = _connectionListener.preResubscribe(); - if (!resubscribe) - { - markAllSessionsClosed(); - } - return resubscribe; - } - else - { - return true; - } - } - - /** - * Fires a failover complete event to the registered connection listener (if any). - */ - public void fireFailoverComplete() - { - if (_connectionListener != null) - { - _connectionListener.failoverComplete(); - } - } - - /** - * In order to protect the consistency of the connection and its child sessions, consumers and producers, - * the "failover mutex" must be held when doing any operations that could be corrupted during failover. - * - * @return a mutex. Guaranteed never to change for the lifetime of this connection even if failover occurs. - */ - public final Object getFailoverMutex() - { - return _failoverMutex; - } - - /** - * If failover is taking place this will block until it has completed. If failover - * is not taking place it will return immediately. - * - * @throws InterruptedException - */ - public void blockUntilNotFailingOver() throws InterruptedException - { - _protocolHandler.blockUntilNotFailingOver(); - } - - /** - * Invoked by the AMQProtocolSession when a protocol session exception has occurred. - * This method sends the exception to a JMS exception listener, if configured, and - * propagates the exception to sessions, which in turn will propagate to consumers. - * This allows synchronous consumers to have exceptions thrown to them. - * - * @param cause the exception - */ - public void exceptionReceived(Throwable cause) - { - - _logger.debug("Connection Close done by:" + Thread.currentThread().getName()); - _logger.debug("exceptionReceived is ", cause); - - final JMSException je; - if (cause instanceof JMSException) - { - je = (JMSException) cause; - } - else - { - je = new JMSException("Exception thrown against " + toString() + ": " + cause); - if (cause instanceof Exception) - { - je.setLinkedException((Exception) cause); - } - } - - // in the case of an IOException, MINA has closed the protocol session so we set _closed to true - // so that any generic client code that tries to close the connection will not mess up this error - // handling sequence - if (cause instanceof IOException) - { - _closed.set(true); - } - - if (_exceptionListener != null) - { - _exceptionListener.onException(je); - } - - if (!(cause instanceof AMQUndeliveredException) && !(cause instanceof AMQAuthenticationException)) - { - try - { - _logger.info("Closing AMQConnection due to :" + cause.getMessage()); - _closed.set(true); - closeAllSessions(cause); // FIXME: when doing this end up with RejectedExecutionException from executor. - } - catch (JMSException e) - { - _logger.error("Error closing all sessions: " + e, e); - } - - } - else - { - _logger.info("Not a hard-error connection not closing."); - } - } - - void registerSession(int channelId, AMQSession session) - { - _sessions.put(channelId, session); - } - - void deregisterSession(int channelId) - { - _sessions.remove(channelId); - } - - /** - * For all sessions, and for all consumers in those sessions, resubscribe. This is called during failover handling. - * The caller must hold the failover mutex before calling this method. - */ - public void resubscribeSessions() throws JMSException, AMQException - { - ArrayList sessions = new ArrayList(_sessions.values()); - _logger.info(MessageFormat.format("Resubscribing sessions = {0} sessions.size={1}", sessions, sessions.size())); // FIXME: remove? - for (Iterator it = sessions.iterator(); it.hasNext();) - { - AMQSession s = (AMQSession) it.next(); - _protocolHandler.addSessionByChannel(s.getChannelId(), s); - reopenChannel(s.getChannelId(), s.getDefaultPrefetchHigh(), s.getDefaultPrefetchLow(), s.getTransacted()); - s.resubscribe(); - } - } - - public String toString() - { - StringBuffer buf = new StringBuffer("AMQConnection:\n"); - if (_failoverPolicy.getCurrentBrokerDetails() == null) - { - buf.append("No active broker connection"); - } - else - { - BrokerDetails bd = _failoverPolicy.getCurrentBrokerDetails(); - buf.append("Host: ").append(String.valueOf(bd.getHost())); - buf.append("\nPort: ").append(String.valueOf(bd.getPort())); - } - buf.append("\nVirtual Host: ").append(String.valueOf(_virtualHost)); - buf.append("\nClient ID: ").append(String.valueOf(_clientName)); - buf.append("\nActive session count: ").append(_sessions == null ? 0 : _sessions.size()); - return buf.toString(); - } - - public String toURL() - { - return _connectionURL.toString(); - } - - public Reference getReference() throws NamingException - { - return new Reference( - AMQConnection.class.getName(), - new StringRefAddr(AMQConnection.class.getName(), toURL()), - AMQConnectionFactory.class.getName(), - null); // factory location - } -} diff --git a/client/src/org/apache/qpid/client/AMQConnectionFactory.java b/client/src/org/apache/qpid/client/AMQConnectionFactory.java deleted file mode 100644 index 6829769b69..0000000000 --- a/client/src/org/apache/qpid/client/AMQConnectionFactory.java +++ /dev/null @@ -1,361 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import org.apache.qpid.AMQException; -import org.apache.qpid.url.AMQBindingURL; -import org.apache.qpid.url.URLSyntaxException; -import org.apache.qpid.jms.ConnectionURL; - -import javax.jms.*; -import javax.jms.Connection; -import javax.naming.*; -import javax.naming.spi.ObjectFactory; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Hashtable; - - -public class AMQConnectionFactory implements ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory, ObjectFactory, Referenceable -{ - private String _host; - private int _port; - private String _defaultUsername; - private String _defaultPassword; - private String _virtualPath; - - private ConnectionURL _connectionDetails; - - - public AMQConnectionFactory() - { - } - - public AMQConnectionFactory(String url) throws URLSyntaxException - { - _connectionDetails = new AMQConnectionURL(url); - } - - public AMQConnectionFactory(ConnectionURL url) - { - _connectionDetails = url; - } - - public AMQConnectionFactory(String broker, String username, String password, - String clientName, String virtualHost) throws URLSyntaxException - { - this(new AMQConnectionURL(ConnectionURL.AMQ_PROTOCOL + "://" + - username + ":" + password + "@" + clientName + - virtualHost + "?brokerlist='" + broker + "'")); - } - - public AMQConnectionFactory(String host, int port, String virtualPath) - { - this(host, port, "guest", "guest", virtualPath); - } - - public AMQConnectionFactory(String host, int port, String defaultUsername, String defaultPassword, - String virtualPath) - { - _host = host; - _port = port; - _defaultUsername = defaultUsername; - _defaultPassword = defaultPassword; - _virtualPath = virtualPath; - -//todo when setting Host/Port has been resolved then we can use this otherwise those methods won't work with the following line. -// _connectionDetails = new AMQConnectionURL( -// ConnectionURL.AMQ_PROTOCOL + "://" + -// _defaultUsername + ":" + _defaultPassword + "@" + -// virtualPath + "?brokerlist='tcp://" + host + ":" + port + "'"); - } - - /** - * @return The _defaultPassword. - */ - public final String getDefaultPassword(String password) - { - if (_connectionDetails != null) - { - return _connectionDetails.getPassword(); - } - else - { - return _defaultPassword; - } - } - - /** - * @param password The _defaultPassword to set. - */ - public final void setDefaultPassword(String password) - { - if (_connectionDetails != null) - { - _connectionDetails.setPassword(password); - } - _defaultPassword = password; - } - - /** - * @return The _defaultPassword. - */ - public final String getDefaultUsername(String password) - { - if (_connectionDetails != null) - { - return _connectionDetails.getUsername(); - } - else - { - return _defaultUsername; - } - } - - /** - * @param username The _defaultUsername to set. - */ - public final void setDefaultUsername(String username) - { - if (_connectionDetails != null) - { - _connectionDetails.setUsername(username); - } - _defaultUsername = username; - } - - /** - * @return The _host . - */ - public final String getHost() - { - //todo this doesn't make sense in a multi broker URL as we have no current as that is done by AMQConnection - return _host; - } - - /** - * @param host The _host to set. - */ - public final void setHost(String host) - { - //todo if _connectionDetails is set then run _connectionDetails.addBrokerDetails() - // Should perhaps have this method changed to setBroker(host,port) - _host = host; - } - - /** - * @return _port The _port to set. - */ - public final int getPort() - { - //todo see getHost - return _port; - } - - /** - * @param port The port to set. - */ - public final void setPort(int port) - { - //todo see setHost - _port = port; - } - - /** - * @return he _virtualPath. - */ - public final String getVirtualPath() - { - if (_connectionDetails != null) - { - return _connectionDetails.getVirtualHost(); - } - else - { - return _virtualPath; - } - } - - /** - * @param path The _virtualPath to set. - */ - public final void setVirtualPath(String path) - { - if (_connectionDetails != null) - { - _connectionDetails.setVirtualHost(path); - } - - _virtualPath = path; - } - - static String getUniqueClientID() - { - try - { - InetAddress addr = InetAddress.getLocalHost(); - return addr.getHostName() + System.currentTimeMillis(); - } - catch (UnknownHostException e) - { - return null; - } - } - - public Connection createConnection() throws JMSException - { - try - { - if (_connectionDetails != null) - { - if (_connectionDetails.getClientName() == null || _connectionDetails.getClientName().equals("")) - { - _connectionDetails.setClientName(getUniqueClientID()); - } - return new AMQConnection(_connectionDetails); - } - else - { - return new AMQConnection(_host, _port, _defaultUsername, _defaultPassword, getUniqueClientID(), - _virtualPath); - } - } - catch (Exception e) - { - JMSException jmse = new JMSException("Error creating connection: " + e.getMessage()); - jmse.setLinkedException(e); - throw jmse; - } - - - } - - public Connection createConnection(String userName, String password) throws JMSException - { - try - { - return new AMQConnection(_host, _port, userName, password, getUniqueClientID(), _virtualPath); - } - catch (Exception e) - { - JMSException jmse = new JMSException("Error creating connection: " + e.getMessage()); - jmse.setLinkedException(e); - throw jmse; - } - } - - public QueueConnection createQueueConnection() throws JMSException - { - return (QueueConnection) createConnection(); - } - - public QueueConnection createQueueConnection(String username, String password) throws JMSException - { - return (QueueConnection) createConnection(username, password); - } - - public TopicConnection createTopicConnection() throws JMSException - { - return (TopicConnection) createConnection(); - } - - public TopicConnection createTopicConnection(String username, String password) throws JMSException - { - return (TopicConnection) createConnection(username, password); - } - - - public ConnectionURL getConnectionURL() - { - return _connectionDetails; - } - - /** - * JNDI interface to create objects from References. - * - * @param obj The Reference from JNDI - * @param name - * @param ctx - * @param env - * @return AMQConnection,AMQTopic,AMQQueue, or AMQConnectionFactory. - * @throws Exception - */ - public Object getObjectInstance(Object obj, Name name, Context ctx, - Hashtable env) throws Exception - { - if (obj instanceof Reference) - { - Reference ref = (Reference) obj; - - if (ref.getClassName().equals(AMQConnection.class.getName())) - { - RefAddr addr = ref.get(AMQConnection.class.getName()); - - if (addr != null) - { - return new AMQConnection((String) addr.getContent()); - } - } - - if (ref.getClassName().equals(AMQQueue.class.getName())) - { - RefAddr addr = ref.get(AMQQueue.class.getName()); - - if (addr != null) - { - return new AMQQueue(new AMQBindingURL((String) addr.getContent()).getQueueName()); - } - } - - if (ref.getClassName().equals(AMQTopic.class.getName())) - { - RefAddr addr = ref.get(AMQTopic.class.getName()); - - if (addr != null) - { - return new AMQTopic(new AMQBindingURL((String) addr.getContent()).getDestinationName()); - } - } - - if (ref.getClassName().equals(AMQConnectionFactory.class.getName())) - { - RefAddr addr = ref.get(AMQConnectionFactory.class.getName()); - - if (addr != null) - { - return new AMQConnectionFactory(new AMQConnectionURL((String) addr.getContent())); - } - } - - } - return null; - } - - - public Reference getReference() throws NamingException - { - return new Reference( - AMQConnectionFactory.class.getName(), - new StringRefAddr(AMQConnectionFactory.class.getName(), _connectionDetails.getURL()), - AMQConnectionFactory.class.getName(), - null); // factory location - } -} diff --git a/client/src/org/apache/qpid/client/AMQConnectionURL.java b/client/src/org/apache/qpid/client/AMQConnectionURL.java deleted file mode 100644 index c134c2093b..0000000000 --- a/client/src/org/apache/qpid/client/AMQConnectionURL.java +++ /dev/null @@ -1,402 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import org.apache.qpid.jms.BrokerDetails; -import org.apache.qpid.jms.ConnectionURL; -import org.apache.qpid.url.URLHelper; -import org.apache.qpid.url.URLSyntaxException; - -import java.util.*; -import java.net.URI; -import java.net.URISyntaxException; - -public class AMQConnectionURL implements ConnectionURL -{ - private String _url; - private String _failoverMethod; - private HashMap<String, String> _failoverOptions; - private HashMap<String, String> _options; - private List<BrokerDetails> _brokers; - private String _clientName; - private String _username; - private String _password; - private String _virtualHost; - - public AMQConnectionURL(String fullURL) throws URLSyntaxException - { - _url = fullURL; - _options = new HashMap<String, String>(); - _brokers = new LinkedList<BrokerDetails>(); - _failoverOptions = new HashMap<String, String>(); - - // Connection URL format - //amqp://[user:pass@][clientid]/virtualhost?brokerlist='tcp://host:port?option=\'value\',option=\'value\';vm://:3/virtualpath?option=\'value\'',failover='method?option=\'value\',option='value''" - // Options are of course optional except for requiring a single broker in the broker list. - try - { - URI connection = new URI(fullURL); - - if (connection.getScheme() == null || !(connection.getScheme().equalsIgnoreCase(AMQ_PROTOCOL))) - { - throw new URISyntaxException(fullURL, "Not an AMQP URL"); - } - - if (connection.getHost() == null || connection.getHost().equals("")) - { - String uid = AMQConnectionFactory.getUniqueClientID(); - if (uid == null) - { - URLHelper.parseError(-1, "Client Name not specified", fullURL); - } - else - { - setClientName(uid); - } - - } - else - { - setClientName(connection.getHost()); - } - - String userInfo = connection.getUserInfo(); - - if (userInfo == null) - { - //Fix for Java 1.5 which doesn't parse UserInfo for non http URIs - userInfo = connection.getAuthority(); - - if (userInfo != null) - { - int atIndex = userInfo.indexOf('@'); - - if (atIndex != -1) - { - userInfo = userInfo.substring(0, atIndex); - } - else - { - userInfo = null; - } - } - - } - - if (userInfo == null) - { - URLHelper.parseError(AMQ_PROTOCOL.length() + 3, - "User information not found on url", fullURL); - } - else - { - parseUserInfo(userInfo); - } - String virtualHost = connection.getPath(); - - if (virtualHost != null && (!virtualHost.equals(""))) - { - setVirtualHost(virtualHost); - } - else - { - int authLength = connection.getAuthority().length(); - int start = AMQ_PROTOCOL.length() + 3; - int testIndex = start + authLength; - if (testIndex < fullURL.length() && fullURL.charAt(testIndex) == '?') - { - URLHelper.parseError(start, testIndex - start, "Virtual host found", fullURL); - } - else - { - URLHelper.parseError(-1, "Virtual host not specified", fullURL); - } - - } - - - URLHelper.parseOptions(_options, connection.getQuery()); - - processOptions(); - - //Fragment is #string (not used) - //System.out.println(connection.getFragment()); - - } - catch (URISyntaxException uris) - { - if (uris instanceof URLSyntaxException) - { - throw (URLSyntaxException) uris; - } - - int slash = fullURL.indexOf("\\"); - - if (slash == -1) - { - URLHelper.parseError(uris.getIndex(), uris.getReason(), uris.getInput()); - } - else - { - if (slash != 0 && fullURL.charAt(slash - 1) == ':') - { - URLHelper.parseError(slash - 2, fullURL.indexOf('?') - slash + 2, "Virtual host looks like a windows path, forward slash not allowed in URL", fullURL); - } - else - { - URLHelper.parseError(slash, "Forward slash not allowed in URL", fullURL); - } - } - - } - } - - private void parseUserInfo(String userinfo) throws URLSyntaxException - { - //user info = user:pass - - int colonIndex = userinfo.indexOf(':'); - - if (colonIndex == -1) - { - URLHelper.parseError(AMQ_PROTOCOL.length() + 3, userinfo.length(), - "Null password in user information not allowed.", _url); - } - else - { - setUsername(userinfo.substring(0, colonIndex)); - setPassword(userinfo.substring(colonIndex + 1)); - } - - } - - private void processOptions() throws URLSyntaxException - { - if (_options.containsKey(OPTIONS_BROKERLIST)) - { - String brokerlist = _options.get(OPTIONS_BROKERLIST); - - //brokerlist tcp://host:port?option='value',option='value';vm://:3/virtualpath?option='value' - StringTokenizer st = new StringTokenizer(brokerlist, "" + URLHelper.BROKER_SEPARATOR); - - while (st.hasMoreTokens()) - { - String broker = st.nextToken(); - - _brokers.add(new AMQBrokerDetails(broker)); - } - - _options.remove(OPTIONS_BROKERLIST); - } - - if (_options.containsKey(OPTIONS_FAILOVER)) - { - String failover = _options.get(OPTIONS_FAILOVER); - - // failover='method?option='value',option='value'' - - int methodIndex = failover.indexOf('?'); - - if (methodIndex > -1) - { - _failoverMethod = failover.substring(0, methodIndex); - URLHelper.parseOptions(_failoverOptions, failover.substring(methodIndex + 1)); - } - else - { - _failoverMethod = failover; - } - - _options.remove(OPTIONS_FAILOVER); - } - } - - public String getURL() - { - return _url; - } - - public String getFailoverMethod() - { - return _failoverMethod; - } - - public String getFailoverOption(String key) - { - return _failoverOptions.get(key); - } - - public void setFailoverOption(String key, String value) - { - _failoverOptions.put(key, value); - } - - public int getBrokerCount() - { - return _brokers.size(); - } - - public BrokerDetails getBrokerDetails(int index) - { - if (index < _brokers.size()) - { - return _brokers.get(index); - } - else - { - return null; - } - } - - public void addBrokerDetails(BrokerDetails broker) - { - if (!(_brokers.contains(broker))) - { - _brokers.add(broker); - } - } - - public List<BrokerDetails> getAllBrokerDetails() - { - return _brokers; - } - - public String getClientName() - { - return _clientName; - } - - public void setClientName(String clientName) - { - _clientName = clientName; - } - - public String getUsername() - { - return _username; - } - - public void setUsername(String username) - { - _username = username; - } - - public String getPassword() - { - return _password; - } - - public void setPassword(String password) - { - _password = password; - } - - public String getVirtualHost() - { - return _virtualHost; - } - - public void setVirtualHost(String virtuaHost) - { - _virtualHost = virtuaHost; - } - - public String getOption(String key) - { - return _options.get(key); - } - - public void setOption(String key, String value) - { - _options.put(key, value); - } - - public String toString() - { - StringBuffer sb = new StringBuffer(); - - sb.append(AMQ_PROTOCOL); - sb.append("://"); - - if (_username != null) - { - sb.append(_username); - - if (_password != null) - { - sb.append(':'); - sb.append(_password); - } - - sb.append('@'); - } - - sb.append(_clientName); - - sb.append(_virtualHost); - - sb.append(optionsToString()); - - return sb.toString(); - } - - private String optionsToString() - { - StringBuffer sb = new StringBuffer(); - - sb.append("?" + OPTIONS_BROKERLIST + "='"); - - for (BrokerDetails service : _brokers) - { - sb.append(service.toString()); - sb.append(';'); - } - - sb.deleteCharAt(sb.length() - 1); - sb.append("'"); - - if (_failoverMethod != null) - { - sb.append(URLHelper.DEFAULT_OPTION_SEPERATOR); - sb.append(OPTIONS_FAILOVER + "='"); - sb.append(_failoverMethod); - sb.append(URLHelper.printOptions(_failoverOptions)); - sb.append("'"); - } - - return sb.toString(); - } - - - public static void main(String[] args) throws URLSyntaxException - { - - String url2 = "amqp://ritchiem:bob@temp?brokerlist='tcp://localhost:5672;jcp://fancyserver:3000/',failover='roundrobin'"; - //"amqp://user:pass@clientid/virtualhost?brokerlist='tcp://host:1?option1=\'value\',option2=\'value\';vm://:3?option1=\'value\'',failover='method?option1=\'value\',option2='value''"; - - ConnectionURL connectionurl2 = new AMQConnectionURL(url2); - - System.out.println(url2); - System.out.println(connectionurl2); - - } - -} diff --git a/client/src/org/apache/qpid/client/AMQDestination.java b/client/src/org/apache/qpid/client/AMQDestination.java deleted file mode 100644 index 6401e3b23f..0000000000 --- a/client/src/org/apache/qpid/client/AMQDestination.java +++ /dev/null @@ -1,285 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import org.apache.qpid.url.BindingURL; -import org.apache.qpid.url.AMQBindingURL; -import org.apache.qpid.url.URLSyntaxException; -import org.apache.qpid.url.URLHelper; -import org.apache.qpid.exchange.ExchangeDefaults; - -import javax.naming.Reference; -import javax.naming.NamingException; -import javax.naming.StringRefAddr; -import javax.naming.Referenceable; -import javax.jms.Destination; - - -public abstract class AMQDestination implements Destination, Referenceable -{ - protected final String _exchangeName; - - protected final String _exchangeClass; - - protected final String _destinationName; - - protected boolean _isDurable; - - protected final boolean _isExclusive; - - protected final boolean _isAutoDelete; - - protected String _queueName; - - protected AMQDestination(String url) throws URLSyntaxException - { - this(new AMQBindingURL(url)); - } - - protected AMQDestination(BindingURL binding) - { - _exchangeName = binding.getExchangeName(); - _exchangeClass = binding.getExchangeClass(); - _destinationName = binding.getDestinationName(); - - _isExclusive = Boolean.parseBoolean(binding.getOption(BindingURL.OPTION_EXCLUSIVE)); - _isAutoDelete = Boolean.parseBoolean(binding.getOption(BindingURL.OPTION_AUTODELETE)); - _isDurable = Boolean.parseBoolean(binding.getOption(BindingURL.OPTION_DURABLE)); - _queueName = binding.getQueueName(); - } - - protected AMQDestination(String exchangeName, String exchangeClass, String destinationName, String queueName) - { - this(exchangeName, exchangeClass, destinationName, false, false, queueName); - } - - protected AMQDestination(String exchangeName, String exchangeClass, String destinationName) - { - this(exchangeName, exchangeClass, destinationName, false, false, null); - } - - protected AMQDestination(String exchangeName, String exchangeClass, String destinationName, boolean isExclusive, - boolean isAutoDelete, String queueName) - { - if (destinationName == null) - { - throw new IllegalArgumentException("Destination name must not be null"); - } - if (exchangeName == null) - { - throw new IllegalArgumentException("Exchange name must not be null"); - } - if (exchangeClass == null) - { - throw new IllegalArgumentException("Exchange class must not be null"); - } - _exchangeName = exchangeName; - _exchangeClass = exchangeClass; - _destinationName = destinationName; - _isExclusive = isExclusive; - _isAutoDelete = isAutoDelete; - _queueName = queueName; - } - - public abstract String getEncodedName(); - - public boolean isDurable() - { - return _isDurable; - } - - public String getExchangeName() - { - return _exchangeName; - } - - public String getExchangeClass() - { - return _exchangeClass; - } - - public boolean isTopic() - { - return ExchangeDefaults.TOPIC_EXCHANGE_NAME.equals(_exchangeName); - } - - public boolean isQueue() - { - return ExchangeDefaults.DIRECT_EXCHANGE_NAME.equals(_exchangeName); - } - - public String getDestinationName() - { - return _destinationName; - } - - public String getQueueName() - { - return _queueName; - } - - public void setQueueName(String queueName) - { - _queueName = queueName; - } - - public abstract String getRoutingKey(); - - public boolean isExclusive() - { - return _isExclusive; - } - - public boolean isAutoDelete() - { - return _isAutoDelete; - } - - public abstract boolean isNameRequired(); - - public String toString() - { - return toURL(); - - /* - return "Destination: " + _destinationName + ", " + - "Queue Name: " + _queueName + ", Exchange: " + _exchangeName + - ", Exchange class: " + _exchangeClass + ", Exclusive: " + _isExclusive + - ", AutoDelete: " + _isAutoDelete + ", Routing Key: " + getRoutingKey(); - */ - } - - public String toURL() - { - StringBuffer sb = new StringBuffer(); - - sb.append(_exchangeClass); - sb.append("://"); - sb.append(_exchangeName); - - sb.append("/"); - - if (_destinationName != null) - { - sb.append(_destinationName); - } - - sb.append("/"); - - if (_queueName != null) - { - sb.append(_queueName); - } - - sb.append("?"); - - if (_isDurable) - { - sb.append(BindingURL.OPTION_DURABLE); - sb.append("='true'"); - sb.append(URLHelper.DEFAULT_OPTION_SEPERATOR); - } - - if (_isExclusive) - { - sb.append(BindingURL.OPTION_EXCLUSIVE); - sb.append("='true'"); - sb.append(URLHelper.DEFAULT_OPTION_SEPERATOR); - } - - if (_isAutoDelete) - { - sb.append(BindingURL.OPTION_AUTODELETE); - sb.append("='true'"); - sb.append(URLHelper.DEFAULT_OPTION_SEPERATOR); - } - - //remove the last char '?' if there is no options , ',' if there are. - sb.deleteCharAt(sb.length() - 1); - - return sb.toString(); - } - - public boolean equals(Object o) - { - if (this == o) - { - return true; - } - if (o == null || getClass() != o.getClass()) - { - return false; - } - - final AMQDestination that = (AMQDestination) o; - - if (!_destinationName.equals(that._destinationName)) - { - return false; - } - if (!_exchangeClass.equals(that._exchangeClass)) - { - return false; - } - if (!_exchangeName.equals(that._exchangeName)) - { - return false; - } - if ((_queueName == null && that._queueName != null) || - (_queueName != null && !_queueName.equals(that._queueName))) - { - return false; - } - if (_isExclusive != that._isExclusive) - { - return false; - } - if (_isAutoDelete != that._isAutoDelete) - { - return false; - } - return true; - } - - public int hashCode() - { - int result; - result = _exchangeName.hashCode(); - result = 29 * result + _exchangeClass.hashCode(); - result = 29 * result + _destinationName.hashCode(); - if (_queueName != null) - { - result = 29 * result + _queueName.hashCode(); - } - result = result * (_isExclusive ? 13 : 7); - result = result * (_isAutoDelete ? 13 : 7); - return result; - } - - public Reference getReference() throws NamingException - { - return new Reference( - this.getClass().getName(), - new StringRefAddr(this.getClass().getName(), toURL()), - AMQConnectionFactory.class.getName(), - null); // factory location - } -} diff --git a/client/src/org/apache/qpid/client/AMQHeadersExchange.java b/client/src/org/apache/qpid/client/AMQHeadersExchange.java deleted file mode 100644 index c5bae6e1fa..0000000000 --- a/client/src/org/apache/qpid/client/AMQHeadersExchange.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import org.apache.qpid.exchange.ExchangeDefaults; -import org.apache.qpid.url.BindingURL; - -/** - * A destination backed by a headers exchange - */ -public class AMQHeadersExchange extends AMQDestination -{ - public AMQHeadersExchange(BindingURL binding) - { - this(binding.getExchangeName()); - } - - public AMQHeadersExchange(String queueName) - { - super(queueName, ExchangeDefaults.HEADERS_EXCHANGE_CLASS, queueName, true, true, null); - } - - public String getEncodedName() - { - return getDestinationName(); - } - - public String getRoutingKey() - { - return getDestinationName(); - } - - public boolean isNameRequired() - { - //Not sure what the best approach is here, probably to treat this like a topic - //and allow server to generate names. As it is AMQ specific it doesn't need to - //fit the JMS API expectations so this is not as yet critical. - return false; - } -} diff --git a/client/src/org/apache/qpid/client/AMQNoConsumersException.java b/client/src/org/apache/qpid/client/AMQNoConsumersException.java deleted file mode 100644 index 277e3f7eaf..0000000000 --- a/client/src/org/apache/qpid/client/AMQNoConsumersException.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import org.apache.qpid.AMQUndeliveredException; -import org.apache.qpid.protocol.AMQConstant; - - -public class AMQNoConsumersException extends AMQUndeliveredException -{ - public AMQNoConsumersException(String msg, Object bounced) - { - super(AMQConstant.NO_CONSUMERS.getCode(), msg, bounced); - } - - -} - - diff --git a/client/src/org/apache/qpid/client/AMQNoRouteException.java b/client/src/org/apache/qpid/client/AMQNoRouteException.java deleted file mode 100644 index 0e84ad75f2..0000000000 --- a/client/src/org/apache/qpid/client/AMQNoRouteException.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import org.apache.qpid.AMQUndeliveredException; -import org.apache.qpid.protocol.AMQConstant; - - -public class AMQNoRouteException extends AMQUndeliveredException -{ - public AMQNoRouteException(String msg, Object bounced) - { - super(AMQConstant.NO_ROUTE.getCode(), msg, bounced); - } - - -} - - diff --git a/client/src/org/apache/qpid/client/AMQQueue.java b/client/src/org/apache/qpid/client/AMQQueue.java deleted file mode 100644 index 8304a29e4d..0000000000 --- a/client/src/org/apache/qpid/client/AMQQueue.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import org.apache.qpid.url.BindingURL; -import org.apache.qpid.exchange.ExchangeDefaults; - -import javax.jms.Queue; - -public class AMQQueue extends AMQDestination implements Queue -{ - - /** - * Create a reference to a non temporary queue using a BindingURL object. - * Note this does not actually imply the queue exists. - * @param binding a BindingURL object - */ - public AMQQueue(BindingURL binding) - { - super(binding); - } - - /** - * Create a reference to a non temporary queue. Note this does not actually imply the queue exists. - * @param name the name of the queue - */ - public AMQQueue(String name) - { - this(name, false); - } - - /** - * Create a queue with a specified name. - * - * @param name the destination name (used in the routing key) - * @param temporary if true the broker will generate a queue name, also if true then the queue is autodeleted - * and exclusive - */ - public AMQQueue(String name, boolean temporary) - { - // queue name is set to null indicating that the broker assigns a name in the case of temporary queues - // temporary queues are typically used as response queues - this(name, temporary?null:name, temporary, temporary); - _isDurable = !temporary; - } - - /** - * Create a reference to a queue. Note this does not actually imply the queue exists. - * @param destinationName the queue name - * @param queueName the queue name - * @param exclusive true if the queue should only permit a single consumer - * @param autoDelete true if the queue should be deleted automatically when the last consumers detaches - */ - public AMQQueue(String destinationName, String queueName, boolean exclusive, boolean autoDelete) - { - super(ExchangeDefaults.DIRECT_EXCHANGE_NAME, ExchangeDefaults.DIRECT_EXCHANGE_CLASS, destinationName, exclusive, - autoDelete, queueName); - } - - public String getEncodedName() - { - return 'Q' + getQueueName(); - } - - public String getRoutingKey() - { - return getQueueName(); - } - - public boolean isNameRequired() - { - //If the name is null, we require one to be generated by the client so that it will# - //remain valid if we failover (see BLZ-24) - return getQueueName() == null; - } -} diff --git a/client/src/org/apache/qpid/client/AMQQueueSessionAdaptor.java b/client/src/org/apache/qpid/client/AMQQueueSessionAdaptor.java deleted file mode 100644 index 05071bd2a8..0000000000 --- a/client/src/org/apache/qpid/client/AMQQueueSessionAdaptor.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import javax.jms.*; -import javax.jms.IllegalStateException; -import java.io.Serializable; - -/** - * Need this adaptor class to conform to JMS spec and throw IllegalStateException - * from createDurableSubscriber, unsubscribe, createTopic & createTemporaryTopic - */ -public class AMQQueueSessionAdaptor implements QueueSession -{ - //holds a session for delegation - protected final AMQSession _session; - - /** - * Construct an adaptor with a session to wrap - * @param session - */ - public AMQQueueSessionAdaptor(Session session) - { - _session = (AMQSession) session; - } - - public TemporaryQueue createTemporaryQueue() throws JMSException { - return _session.createTemporaryQueue(); - } - - public Queue createQueue(String string) throws JMSException { - return _session.createQueue(string); - } - - public QueueReceiver createReceiver(Queue queue) throws JMSException { - return _session.createReceiver(queue); - } - - public QueueReceiver createReceiver(Queue queue, String string) throws JMSException { - return _session.createReceiver(queue, string); - } - - public QueueSender createSender(Queue queue) throws JMSException { - return _session.createSender(queue); - } - - public QueueBrowser createBrowser(Queue queue) throws JMSException { - return _session.createBrowser(queue); - } - - public QueueBrowser createBrowser(Queue queue, String string) throws JMSException { - return _session.createBrowser(queue, string); - } - - public BytesMessage createBytesMessage() throws JMSException { - return _session.createBytesMessage(); - } - - public MapMessage createMapMessage() throws JMSException { - return _session.createMapMessage(); - } - - public Message createMessage() throws JMSException { - return _session.createMessage(); - } - - public ObjectMessage createObjectMessage() throws JMSException { - return _session.createObjectMessage(); - } - - public ObjectMessage createObjectMessage(Serializable serializable) throws JMSException { - return _session.createObjectMessage(serializable); - } - - public StreamMessage createStreamMessage() throws JMSException { - return _session.createStreamMessage(); - } - - public TextMessage createTextMessage() throws JMSException { - return _session.createTextMessage(); - } - - public TextMessage createTextMessage(String string) throws JMSException { - return _session.createTextMessage(string); - } - - public boolean getTransacted() throws JMSException { - return _session.getTransacted(); - } - - public int getAcknowledgeMode() throws JMSException { - return _session.getAcknowledgeMode(); - } - - public void commit() throws JMSException { - _session.commit(); - } - - public void rollback() throws JMSException { - _session.rollback(); - } - - public void close() throws JMSException { - _session.close(); - } - - public void recover() throws JMSException { - _session.recover(); - } - - public MessageListener getMessageListener() throws JMSException { - return _session.getMessageListener(); - } - - public void setMessageListener(MessageListener messageListener) throws JMSException { - _session.setMessageListener(messageListener); - } - - public void run() { - _session.run(); - } - - public MessageProducer createProducer(Destination destination) throws JMSException { - return _session.createProducer(destination); - } - - public MessageConsumer createConsumer(Destination destination) throws JMSException { - return _session.createConsumer(destination); - } - - public MessageConsumer createConsumer(Destination destination, String string) throws JMSException { - return _session.createConsumer(destination,string); - } - - public MessageConsumer createConsumer(Destination destination, String string, boolean b) throws JMSException { - return _session.createConsumer(destination,string,b); - } - - //The following methods cannot be called from a QueueSession as per JMS spec - - public Topic createTopic(String string) throws JMSException { - throw new IllegalStateException("Cannot call createTopic from QueueSession"); - } - - public TopicSubscriber createDurableSubscriber(Topic topic, String string) throws JMSException { - throw new IllegalStateException("Cannot call createDurableSubscriber from QueueSession"); - } - - public TopicSubscriber createDurableSubscriber(Topic topic, String string, String string1, boolean b) throws JMSException { - throw new IllegalStateException("Cannot call createDurableSubscriber from QueueSession"); - } - - public TemporaryTopic createTemporaryTopic() throws JMSException { - throw new IllegalStateException("Cannot call createTemporaryTopic from QueueSession"); - } - - public void unsubscribe(String string) throws JMSException { - throw new IllegalStateException("Cannot call unsubscribe from QueueSession"); - } - -} diff --git a/client/src/org/apache/qpid/client/AMQSession.java b/client/src/org/apache/qpid/client/AMQSession.java deleted file mode 100644 index a847658846..0000000000 --- a/client/src/org/apache/qpid/client/AMQSession.java +++ /dev/null @@ -1,1291 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.AMQUndeliveredException; -import org.apache.qpid.client.failover.FailoverSupport; -import org.apache.qpid.client.message.AbstractJMSMessage; -import org.apache.qpid.client.message.MessageFactoryRegistry; -import org.apache.qpid.client.message.UnprocessedMessage; -import org.apache.qpid.client.protocol.AMQProtocolHandler; -import org.apache.qpid.client.util.FlowControllingBlockingQueue; -import org.apache.qpid.framing.*; -import org.apache.qpid.jms.Session; -import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.url.AMQBindingURL; -import org.apache.qpid.url.URLSyntaxException; - -import javax.jms.*; -import javax.jms.IllegalStateException; -import java.io.Serializable; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicBoolean; - -public class AMQSession extends Closeable implements Session, QueueSession, TopicSession -{ - private static final Logger _logger = Logger.getLogger(AMQSession.class); - - public static final int DEFAULT_PREFETCH_HIGH_MARK = 5000; - public static final int DEFAULT_PREFETCH_LOW_MARK = 2500; - - private AMQConnection _connection; - - private boolean _transacted; - - private int _acknowledgeMode; - - private int _channelId; - - private int _defaultPrefetchHighMark = DEFAULT_PREFETCH_HIGH_MARK; - private int _defaultPrefetchLowMark = DEFAULT_PREFETCH_LOW_MARK; - - /** - * Used in the consume method. We generate the consume tag on the client so that we can use the nowait - * feature. - */ - private int _nextTag = 1; - - /** - * This queue is bounded and is used to store messages before being dispatched to the consumer - */ - private final FlowControllingBlockingQueue _queue; - - private Dispatcher _dispatcher; - - private MessageFactoryRegistry _messageFactoryRegistry; - - /** - * Set of all producers created by this session - */ - private Map _producers = new ConcurrentHashMap(); - - /** - * Maps from consumer tag (String) to JMSMessageConsumer instance - */ - private Map _consumers = new ConcurrentHashMap(); - - /** - * Default value for immediate flag used by producers created by this session is false, i.e. a consumer does not - * need to be attached to a queue - */ - protected static final boolean DEFAULT_IMMEDIATE = false; - - /** - * Default value for mandatory flag used by producers created by this sessio is true, i.e. server will not silently - * drop messages where no queue is connected to the exchange for the message - */ - protected static final boolean DEFAULT_MANDATORY = true; - - /** - * The counter of the next producer id. This id is generated by the session and used only to allow the - * producer to identify itself to the session when deregistering itself. - * <p/> - * Access to this id does not require to be synchronized since according to the JMS specification only one - * thread of control is allowed to create producers for any given session instance. - */ - private long _nextProducerId; - - /** - * Track the 'stopped' state of the dispatcher, a session starts in the stopped state. - */ - private volatile AtomicBoolean _stopped = new AtomicBoolean(true); - - /** - * Responsible for decoding a message fragment and passing it to the appropriate message consumer. - */ - private class Dispatcher extends Thread - { - public Dispatcher() - { - super("Dispatcher-Channel-" + _channelId); - } - - public void run() - { - UnprocessedMessage message; - _stopped.set(false); - try - { - while (!_stopped.get() && (message = (UnprocessedMessage) _queue.take()) != null) - { - dispatchMessage(message); - } - } - catch (InterruptedException e) - { - ; - } - - _logger.info("Dispatcher thread terminating for channel " + _channelId); - } - - private void dispatchMessage(UnprocessedMessage message) - { - if (message.deliverBody != null) - { - final BasicMessageConsumer consumer = (BasicMessageConsumer) _consumers.get(message.deliverBody.consumerTag); - - if (consumer == null) - { - _logger.warn("Received a message from queue " + message.deliverBody.consumerTag + " without a handler - ignoring..."); - } - else - { - consumer.notifyMessage(message, _channelId); - } - } - else - { - try - { - // Bounced message is processed here, away from the mina thread - AbstractJMSMessage bouncedMessage = _messageFactoryRegistry.createMessage(0, - false, - message.contentHeader, - message.bodies); - - int errorCode = message.bounceBody.replyCode; - String reason = message.bounceBody.replyText; - _logger.debug("Message returned with error code " + errorCode + " (" + reason + ")"); - - //@TODO should this be moved to an exception handler of sorts. Somewhere errors are converted to correct execeptions. - if (errorCode == AMQConstant.NO_CONSUMERS.getCode()) - { - _connection.exceptionReceived(new AMQNoConsumersException("Error: " + reason, bouncedMessage)); - } - else - { - if (errorCode == AMQConstant.NO_ROUTE.getCode()) - { - _connection.exceptionReceived(new AMQNoRouteException("Error: " + reason, bouncedMessage)); - } - else - { - _connection.exceptionReceived(new AMQUndeliveredException(errorCode, "Error: " + reason, bouncedMessage)); - } - } - } - catch (Exception e) - { - _logger.error("Caught exception trying to raise undelivered message exception (dump follows) - ignoring...", e); - } - } - } - - public void stopDispatcher() - { - _stopped.set(true); - interrupt(); - } - } - - AMQSession(AMQConnection con, int channelId, boolean transacted, int acknowledgeMode, - MessageFactoryRegistry messageFactoryRegistry) - { - this(con, channelId, transacted, acknowledgeMode, messageFactoryRegistry, DEFAULT_PREFETCH_HIGH_MARK, DEFAULT_PREFETCH_LOW_MARK); - } - - AMQSession(AMQConnection con, int channelId, boolean transacted, int acknowledgeMode, - MessageFactoryRegistry messageFactoryRegistry, int defaultPrefetch) - { - this(con, channelId, transacted, acknowledgeMode, messageFactoryRegistry, defaultPrefetch, defaultPrefetch); - } - - AMQSession(AMQConnection con, int channelId, boolean transacted, int acknowledgeMode, - MessageFactoryRegistry messageFactoryRegistry, int defaultPrefetchHighMark, int defaultPrefetchLowMark) - { - _connection = con; - _transacted = transacted; - if (transacted) - { - _acknowledgeMode = javax.jms.Session.SESSION_TRANSACTED; - } - else - { - _acknowledgeMode = acknowledgeMode; - } - _channelId = channelId; - _messageFactoryRegistry = messageFactoryRegistry; - _defaultPrefetchHighMark = defaultPrefetchHighMark; - _defaultPrefetchLowMark = defaultPrefetchLowMark; - - if (_acknowledgeMode == NO_ACKNOWLEDGE) - { - _queue = new FlowControllingBlockingQueue(_defaultPrefetchHighMark, _defaultPrefetchLowMark, - new FlowControllingBlockingQueue.ThresholdListener() - { - public void aboveThreshold(int currentValue) - { - if (_acknowledgeMode == NO_ACKNOWLEDGE) - { - _logger.warn("Above threshold(" + _defaultPrefetchHighMark + ") so suspending channel. Current value is " + currentValue); - suspendChannel(); - } - } - - public void underThreshold(int currentValue) - { - if (_acknowledgeMode == NO_ACKNOWLEDGE) - { - _logger.warn("Below threshold(" + _defaultPrefetchLowMark + ") so unsuspending channel. Current value is " + currentValue); - unsuspendChannel(); - } - } - }); - } - else - { - _queue = new FlowControllingBlockingQueue(_defaultPrefetchHighMark, null); - } - } - - AMQSession(AMQConnection con, int channelId, boolean transacted, int acknowledgeMode) - { - this(con, channelId, transacted, acknowledgeMode, MessageFactoryRegistry.newDefaultRegistry()); - } - - AMQSession(AMQConnection con, int channelId, boolean transacted, int acknowledgeMode, int defaultPrefetch) - { - this(con, channelId, transacted, acknowledgeMode, MessageFactoryRegistry.newDefaultRegistry(), defaultPrefetch); - } - - AMQSession(AMQConnection con, int channelId, boolean transacted, int acknowledgeMode, int defaultPrefetchHigh, int defaultPrefetchLow) - { - this(con, channelId, transacted, acknowledgeMode, MessageFactoryRegistry.newDefaultRegistry(), defaultPrefetchHigh, defaultPrefetchLow); - } - - AMQConnection getAMQConnection() - { - return _connection; - } - - public BytesMessage createBytesMessage() throws JMSException - { - synchronized(_connection.getFailoverMutex()) - { - checkNotClosed(); - try - { - return (BytesMessage) _messageFactoryRegistry.createMessage("application/octet-stream"); - } - catch (AMQException e) - { - throw new JMSException("Unable to create message: " + e); - } - } - } - - public MapMessage createMapMessage() throws JMSException - { - synchronized(_connection.getFailoverMutex()) - { - checkNotClosed(); - try - { - return (MapMessage) _messageFactoryRegistry.createMessage("jms/map-message"); - } - catch (AMQException e) - { - throw new JMSException("Unable to create message: " + e); - } - } - } - - public javax.jms.Message createMessage() throws JMSException - { - synchronized(_connection.getFailoverMutex()) - { - checkNotClosed(); - try - { - return (BytesMessage) _messageFactoryRegistry.createMessage("application/octet-stream"); - } - catch (AMQException e) - { - throw new JMSException("Unable to create message: " + e); - } - } - } - - public ObjectMessage createObjectMessage() throws JMSException - { - synchronized(_connection.getFailoverMutex()) - { - checkNotClosed(); - try - { - return (ObjectMessage) _messageFactoryRegistry.createMessage("application/java-object-stream"); - } - catch (AMQException e) - { - throw new JMSException("Unable to create message: " + e); - } - } - } - - public ObjectMessage createObjectMessage(Serializable object) throws JMSException - { - synchronized(_connection.getFailoverMutex()) - { - checkNotClosed(); - try - { - ObjectMessage msg = (ObjectMessage) _messageFactoryRegistry.createMessage("application/java-object-stream"); - msg.setObject(object); - return msg; - } - catch (AMQException e) - { - throw new JMSException("Unable to create message: " + e); - } - } - } - - public StreamMessage createStreamMessage() throws JMSException - { - checkNotClosed(); - throw new UnsupportedOperationException("Stream messages not supported"); - } - - public TextMessage createTextMessage() throws JMSException - { - synchronized(_connection.getFailoverMutex()) - { - checkNotClosed(); - - try - { - return (TextMessage) _messageFactoryRegistry.createMessage("text/plain"); - } - catch (AMQException e) - { - throw new JMSException("Unable to create text message: " + e); - } - } - } - - public TextMessage createTextMessage(String text) throws JMSException - { - synchronized(_connection.getFailoverMutex()) - { - checkNotClosed(); - try - { - TextMessage msg = (TextMessage) _messageFactoryRegistry.createMessage("text/plain"); - msg.setText(text); - return msg; - } - catch (AMQException e) - { - throw new JMSException("Unable to create text message: " + e); - } - } - } - - public boolean getTransacted() throws JMSException - { - checkNotClosed(); - return _transacted; - } - - public int getAcknowledgeMode() throws JMSException - { - checkNotClosed(); - return _acknowledgeMode; - } - - public void commit() throws JMSException - { - checkTransacted(); - try - { - // Acknowledge up to message last delivered (if any) for each consumer. - //need to send ack for messages delivered to consumers so far - for (Iterator i = _consumers.values().iterator(); i.hasNext();) - { - //Sends acknowledgement to server - ((BasicMessageConsumer) i.next()).acknowledgeLastDelivered(); - } - - // Commits outstanding messages sent and outstanding acknowledgements. - _connection.getProtocolHandler().syncWrite(TxCommitBody.createAMQFrame(_channelId), TxCommitOkBody.class); - } - catch (AMQException e) - { - JMSException exception = new JMSException("Failed to commit: " + e.getMessage()); - exception.setLinkedException(e); - throw exception; - } - } - - public void rollback() throws JMSException - { - checkTransacted(); - try - { - _connection.getProtocolHandler().syncWrite( - TxRollbackBody.createAMQFrame(_channelId), TxRollbackOkBody.class); - } - catch (AMQException e) - { - throw(JMSException) (new JMSException("Failed to rollback: " + e).initCause(e)); - } - } - - public void close() throws JMSException - { - // We must close down all producers and consumers in an orderly fashion. This is the only method - // that can be called from a different thread of control from the one controlling the session - synchronized(_connection.getFailoverMutex()) - { - _closed.set(true); - - // we pass null since this is not an error case - closeProducersAndConsumers(null); - - try - { - _connection.getProtocolHandler().closeSession(this); - final AMQFrame frame = ChannelCloseBody.createAMQFrame( - getChannelId(), AMQConstant.REPLY_SUCCESS.getCode(), "JMS client closing channel", 0, 0); - _connection.getProtocolHandler().syncWrite(frame, ChannelCloseOkBody.class); - // When control resumes at this point, a reply will have been received that - // indicates the broker has closed the channel successfully - - } - catch (AMQException e) - { - throw new JMSException("Error closing session: " + e); - } - finally - { - _connection.deregisterSession(_channelId); - } - } - } - - /** - * Close all producers or consumers. This is called either in the error case or when closing the session normally. - * - * @param amqe the exception, may be null to indicate no error has occurred - */ - private void closeProducersAndConsumers(AMQException amqe) - { - try - { - closeProducers(); - } - catch (JMSException e) - { - _logger.error("Error closing session: " + e, e); - } - try - { - closeConsumers(amqe); - } - catch (JMSException e) - { - _logger.error("Error closing session: " + e, e); - } - } - - /** - * Called when the server initiates the closure of the session - * unilaterally. - * - * @param e the exception that caused this session to be closed. Null causes the - */ - public void closed(Throwable e) - { - synchronized(_connection.getFailoverMutex()) - { - // An AMQException has an error code and message already and will be passed in when closure occurs as a - // result of a channel close request - _closed.set(true); - AMQException amqe; - if (e instanceof AMQException) - { - amqe = (AMQException) e; - } - else - { - amqe = new AMQException(_logger, "Closing session forcibly", e); - } - _connection.deregisterSession(_channelId); - closeProducersAndConsumers(amqe); - } - } - - /** - * Called to mark the session as being closed. Useful when the session needs to be made invalid, e.g. after - * failover when the client has veoted resubscription. - * <p/> - * The caller of this method must already hold the failover mutex. - */ - void markClosed() - { - _closed.set(true); - _connection.deregisterSession(_channelId); - markClosedProducersAndConsumers(); - } - - private void markClosedProducersAndConsumers() - { - try - { - // no need for a markClosed* method in this case since there is no protocol traffic closing a producer - closeProducers(); - } - catch (JMSException e) - { - _logger.error("Error closing session: " + e, e); - } - try - { - markClosedConsumers(); - } - catch (JMSException e) - { - _logger.error("Error closing session: " + e, e); - } - } - - /** - * Called to close message producers cleanly. This may or may <b>not</b> be as a result of an error. There is - * currently no way of propagating errors to message producers (this is a JMS limitation). - */ - private void closeProducers() throws JMSException - { - // we need to clone the list of producers since the close() method updates the _producers collection - // which would result in a concurrent modification exception - final ArrayList clonedProducers = new ArrayList(_producers.values()); - - final Iterator it = clonedProducers.iterator(); - while (it.hasNext()) - { - final BasicMessageProducer prod = (BasicMessageProducer) it.next(); - prod.close(); - } - // at this point the _producers map is empty - } - - /** - * Called to close message consumers cleanly. This may or may <b>not</b> be as a result of an error. - * - * @param error not null if this is a result of an error occurring at the connection level - */ - private void closeConsumers(Throwable error) throws JMSException - { - if (_dispatcher != null) - { - _dispatcher.stopDispatcher(); - } - // we need to clone the list of consumers since the close() method updates the _consumers collection - // which would result in a concurrent modification exception - final ArrayList clonedConsumers = new ArrayList(_consumers.values()); - - final Iterator it = clonedConsumers.iterator(); - while (it.hasNext()) - { - final BasicMessageConsumer con = (BasicMessageConsumer) it.next(); - if (error != null) - { - con.notifyError(error); - } - else - { - con.close(); - } - } - // at this point the _consumers map will be empty - } - - private void markClosedConsumers() throws JMSException - { - if (_dispatcher != null) - { - _dispatcher.stopDispatcher(); - } - // we need to clone the list of consumers since the close() method updates the _consumers collection - // which would result in a concurrent modification exception - final ArrayList clonedConsumers = new ArrayList(_consumers.values()); - - final Iterator it = clonedConsumers.iterator(); - while (it.hasNext()) - { - final BasicMessageConsumer con = (BasicMessageConsumer) it.next(); - con.markClosed(); - } - // at this point the _consumers map will be empty - } - - /** - * Asks the broker to resend all unacknowledged messages for the session. - * - * @throws JMSException - */ - public void recover() throws JMSException - { - checkNotClosed(); - checkNotTransacted(); // throws IllegalStateException if a transacted session - - _connection.getProtocolHandler().writeFrame(BasicRecoverBody.createAMQFrame(_channelId, false)); - } - - public MessageListener getMessageListener() throws JMSException - { - checkNotClosed(); - throw new java.lang.UnsupportedOperationException("MessageListener interface not supported"); - } - - public void setMessageListener(MessageListener listener) throws JMSException - { - checkNotClosed(); - throw new java.lang.UnsupportedOperationException("MessageListener interface not supported"); - } - - public void run() - { - throw new java.lang.UnsupportedOperationException(); - } - - public MessageProducer createProducer(Destination destination, boolean mandatory, - boolean immediate, boolean waitUntilSent) - throws JMSException - { - return createProducerImpl(destination, mandatory, immediate, waitUntilSent); - } - - public MessageProducer createProducer(Destination destination, boolean mandatory, boolean immediate) - throws JMSException - { - return createProducerImpl(destination, mandatory, immediate); - } - - public MessageProducer createProducer(Destination destination, boolean immediate) - throws JMSException - { - return createProducerImpl(destination, DEFAULT_MANDATORY, immediate); - } - - public MessageProducer createProducer(Destination destination) throws JMSException - { - return createProducerImpl(destination, DEFAULT_MANDATORY, DEFAULT_IMMEDIATE); - } - - private org.apache.qpid.jms.MessageProducer createProducerImpl(Destination destination, boolean mandatory, - boolean immediate) - throws JMSException - { - return createProducerImpl(destination, mandatory, immediate, false); - } - - private org.apache.qpid.jms.MessageProducer createProducerImpl(final Destination destination, final boolean mandatory, - final boolean immediate, final boolean waitUntilSent) - throws JMSException - { - return (org.apache.qpid.jms.MessageProducer) new FailoverSupport() - { - public Object operation() throws JMSException - { - checkNotClosed(); - - return new BasicMessageProducer(_connection, (AMQDestination) destination, _transacted, _channelId, - AMQSession.this, _connection.getProtocolHandler(), - getNextProducerId(), immediate, mandatory, waitUntilSent); - } - }.execute(_connection); - } - - /** - * Creates a QueueReceiver - * @param destination - * @return QueueReceiver - a wrapper around our MessageConsumer - * @throws JMSException - */ - public QueueReceiver createQueueReceiver(Destination destination) throws JMSException - { - AMQQueue dest = (AMQQueue) destination; - BasicMessageConsumer consumer = (BasicMessageConsumer) createConsumer(destination); - return new QueueReceiverAdaptor(dest, consumer); - } - - /** - * Creates a QueueReceiver using a message selector - * @param destination - * @param messageSelector - * @return QueueReceiver - a wrapper around our MessageConsumer - * @throws JMSException - */ - public QueueReceiver createQueueReceiver(Destination destination, String messageSelector) throws JMSException - { - AMQQueue dest = (AMQQueue) destination; - BasicMessageConsumer consumer = (BasicMessageConsumer) - createConsumer(destination, messageSelector); - return new QueueReceiverAdaptor(dest, consumer); - } - - public MessageConsumer createConsumer(Destination destination) throws JMSException - { - return createConsumer(destination, _defaultPrefetchHighMark, _defaultPrefetchLowMark, false, false, null); - } - - public MessageConsumer createConsumer(Destination destination, String messageSelector) throws JMSException - { - return createConsumer(destination, _defaultPrefetchHighMark, _defaultPrefetchLowMark, false, false, messageSelector); - } - - public MessageConsumer createConsumer(Destination destination, String messageSelector, boolean noLocal) - throws JMSException - { - return createConsumer(destination, _defaultPrefetchHighMark, _defaultPrefetchLowMark, noLocal, false, messageSelector); - } - - public MessageConsumer createConsumer(Destination destination, - int prefetch, - boolean noLocal, - boolean exclusive, - String selector) throws JMSException - { - return createConsumer(destination, prefetch, prefetch, noLocal, exclusive, selector, null); - } - - - public MessageConsumer createConsumer(Destination destination, - int prefetchHigh, - int prefetchLow, - boolean noLocal, - boolean exclusive, - String selector) throws JMSException - { - return createConsumer(destination, prefetchHigh, prefetchLow, noLocal, exclusive, selector, null); - } - - public MessageConsumer createConsumer(Destination destination, - int prefetch, - boolean noLocal, - boolean exclusive, - String selector, - FieldTable rawSelector) throws JMSException - { - return createConsumerImpl(destination, prefetch, prefetch, noLocal, exclusive, - selector, rawSelector); - } - - public MessageConsumer createConsumer(Destination destination, - int prefetchHigh, - int prefetchLow, - boolean noLocal, - boolean exclusive, - String selector, - FieldTable rawSelector) throws JMSException - { - return createConsumerImpl(destination, prefetchHigh, prefetchLow, noLocal, exclusive, - selector, rawSelector); - } - - protected MessageConsumer createConsumerImpl(final Destination destination, - final int prefetchHigh, - final int prefetchLow, - final boolean noLocal, - final boolean exclusive, - final String selector, - final FieldTable rawSelector) throws JMSException - { - return (org.apache.qpid.jms.MessageConsumer) new FailoverSupport() - { - public Object operation() throws JMSException - { - checkNotClosed(); - - AMQDestination amqd = (AMQDestination) destination; - - final AMQProtocolHandler protocolHandler = _connection.getProtocolHandler(); - // TODO: construct the rawSelector from the selector string if rawSelector == null - final FieldTable ft = new FieldTable(); - //if (rawSelector != null) - // ft.put("headers", rawSelector.getDataAsBytes()); - if (rawSelector != null) - { - ft.putAll(rawSelector); - } - BasicMessageConsumer consumer = new BasicMessageConsumer(_channelId, _connection, amqd, selector, noLocal, - _messageFactoryRegistry, AMQSession.this, - protocolHandler, ft, prefetchHigh, prefetchLow, exclusive, - _acknowledgeMode); - - try - { - registerConsumer(consumer); - } - catch (AMQException e) - { - JMSException ex = new JMSException("Error registering consumer: " + e); - ex.setLinkedException(e); - throw ex; - } - - return consumer; - } - }.execute(_connection); - } - - public void declareExchange(String name, String type) - { - declareExchange(name, type, _connection.getProtocolHandler()); - } - - public void declareExchangeSynch(String name, String type) throws AMQException - { - AMQFrame frame = ExchangeDeclareBody.createAMQFrame(_channelId, 0, name, type, false, false, false, false, false, null); - _connection.getProtocolHandler().syncWrite(frame, ExchangeDeclareOkBody.class); - } - - private void declareExchange(AMQDestination amqd, AMQProtocolHandler protocolHandler) - { - declareExchange(amqd.getExchangeName(), amqd.getExchangeClass(), protocolHandler); - } - - private void declareExchange(String name, String type, AMQProtocolHandler protocolHandler) - { - AMQFrame exchangeDeclare = ExchangeDeclareBody.createAMQFrame(_channelId, 0, name, type, false, false, false, false, true, null); - protocolHandler.writeFrame(exchangeDeclare); - } - - /** - * Declare the queue. - * - * @param amqd - * @param protocolHandler - * @return the queue name. This is useful where the broker is generating a queue name on behalf of the client. - * @throws AMQException - */ - private String declareQueue(AMQDestination amqd, AMQProtocolHandler protocolHandler) throws AMQException - { - // For queues (but not topics) we generate the name in the client rather than the - // server. This allows the name to be reused on failover if required. In general, - // the destination indicates whether it wants a name generated or not. - if (amqd.isNameRequired()) - { - amqd.setQueueName(protocolHandler.generateQueueName()); - } - - AMQFrame queueDeclare = QueueDeclareBody.createAMQFrame(_channelId, 0, amqd.getQueueName(), - false, amqd.isDurable(), amqd.isExclusive(), - amqd.isAutoDelete(), true, null); - - protocolHandler.writeFrame(queueDeclare); - return amqd.getQueueName(); - } - - private void bindQueue(AMQDestination amqd, String queueName, AMQProtocolHandler protocolHandler, FieldTable ft) throws AMQException - { - AMQFrame queueBind = QueueBindBody.createAMQFrame(_channelId, 0, - queueName, amqd.getExchangeName(), - amqd.getRoutingKey(), true, ft); - - protocolHandler.writeFrame(queueBind); - } - - /** - * Register to consume from the queue. - * - * @param queueName - * @return the consumer tag generated by the broker - */ - private String consumeFromQueue(String queueName, AMQProtocolHandler protocolHandler, int prefetchHigh, int prefetchLow, - boolean noLocal, boolean exclusive, int acknowledgeMode) throws AMQException - { - //fixme prefetch values are not used here. Do we need to have them as parametsrs? - //need to generate a consumer tag on the client so we can exploit the nowait flag - String tag = Integer.toString(_nextTag++); - - AMQFrame jmsConsume = BasicConsumeBody.createAMQFrame(_channelId, 0, - queueName, tag, noLocal, - acknowledgeMode == Session.NO_ACKNOWLEDGE, - exclusive, true); - - protocolHandler.writeFrame(jmsConsume); - return tag; - } - - public Queue createQueue(String queueName) throws JMSException - { - if (queueName.indexOf('/') == -1) - { - return new AMQQueue(queueName); - } - else - { - try - { - return new AMQQueue(new AMQBindingURL(queueName)); - } - catch (URLSyntaxException urlse) - { - JMSException jmse = new JMSException(urlse.getReason()); - jmse.setLinkedException(urlse); - - throw jmse; - } - } - } - - /** - * Creates a QueueReceiver wrapping a MessageConsumer - * @param queue - * @return QueueReceiver - * @throws JMSException - */ - public QueueReceiver createReceiver(Queue queue) throws JMSException - { - AMQQueue dest = (AMQQueue) queue; - BasicMessageConsumer consumer = (BasicMessageConsumer) createConsumer(dest); - return new QueueReceiverAdaptor(dest, consumer); - } - - /** - * Creates a QueueReceiver wrapping a MessageConsumer using a message selector - * @param queue - * @param messageSelector - * @return QueueReceiver - * @throws JMSException - */ - public QueueReceiver createReceiver(Queue queue, String messageSelector) throws JMSException - { - AMQQueue dest = (AMQQueue) queue; - BasicMessageConsumer consumer = (BasicMessageConsumer) - createConsumer(dest, messageSelector); - return new QueueReceiverAdaptor(dest, consumer); - } - - public QueueSender createSender(Queue queue) throws JMSException - { - return (QueueSender) createProducer(queue); - } - - public Topic createTopic(String topicName) throws JMSException - { - if (topicName.indexOf('/') == -1) - { - return new AMQTopic(topicName); - } - else - { - try - { - return new AMQTopic(new AMQBindingURL(topicName)); - } - catch (URLSyntaxException urlse) - { - JMSException jmse = new JMSException(urlse.getReason()); - jmse.setLinkedException(urlse); - - throw jmse; - } - } - } - - /** - * Creates a non-durable subscriber - * @param topic - * @return TopicSubscriber - a wrapper round our MessageConsumer - * @throws JMSException - */ - public TopicSubscriber createSubscriber(Topic topic) throws JMSException - { - AMQTopic dest = new AMQTopic(topic.getTopicName()); - return new TopicSubscriberAdaptor(dest, (BasicMessageConsumer) createConsumer(dest)); - } - - /** - * Creates a non-durable subscriber with a message selector - * @param topic - * @param messageSelector - * @param noLocal - * @return TopicSubscriber - a wrapper round our MessageConsumer - * @throws JMSException - */ - public TopicSubscriber createSubscriber(Topic topic, String messageSelector, boolean noLocal) throws JMSException - { - AMQTopic dest = new AMQTopic(topic.getTopicName()); - return new TopicSubscriberAdaptor(dest, (BasicMessageConsumer) createConsumer(dest, messageSelector, noLocal)); - } - - /** - * Note, currently this does not handle reuse of the same name with different topics correctly. - * If a name is reused in creating a new subscriber with a different topic/selecto or no-local - * flag then the subcriber will receive messages matching the old subscription AND the new one. - * The spec states that the new one should replace the old one. - * TODO: fix it. - */ - public TopicSubscriber createDurableSubscriber(Topic topic, String name) throws JMSException - { - AMQTopic dest = new AMQTopic((AMQTopic) topic, _connection.getClientID(), name); - return new TopicSubscriberAdaptor(dest, (BasicMessageConsumer) createConsumer(dest)); - } - - /** - * Note, currently this does not handle reuse of the same name with different topics correctly. - */ - public TopicSubscriber createDurableSubscriber(Topic topic, String name, String messageSelector, boolean noLocal) - throws JMSException - { - AMQTopic dest = new AMQTopic((AMQTopic) topic, _connection.getClientID(), name); - BasicMessageConsumer consumer = (BasicMessageConsumer) createConsumer(dest, messageSelector, noLocal); - return new TopicSubscriberAdaptor(dest, consumer); - } - - public TopicPublisher createPublisher(Topic topic) throws JMSException - { - return (TopicPublisher) createProducer(topic); - } - - public QueueBrowser createBrowser(Queue queue) throws JMSException - { - throw new UnsupportedOperationException("Queue browsing not supported"); - } - - public QueueBrowser createBrowser(Queue queue, String messageSelector) throws JMSException - { - throw new UnsupportedOperationException("Queue browsing not supported"); - } - - public TemporaryQueue createTemporaryQueue() throws JMSException - { - return new AMQTemporaryQueue(); - } - - public TemporaryTopic createTemporaryTopic() throws JMSException - { - return new AMQTemporaryTopic(); - } - - public void unsubscribe(String name) throws JMSException - { - //send a queue.delete for the subscription - String queue = _connection.getClientID() + ":" + name; - AMQFrame frame = QueueDeleteBody.createAMQFrame(_channelId, 0, queue, false, false, true); - _connection.getProtocolHandler().writeFrame(frame); - } - - private void checkTransacted() throws JMSException - { - if (!getTransacted()) - { - throw new IllegalStateException("Session is not transacted"); - } - } - - private void checkNotTransacted() throws JMSException - { - if (getTransacted()) - { - throw new IllegalStateException("Session is transacted"); - } - } - - /** - * Invoked by the MINA IO thread (indirectly) when a message is received from the transport. - * Puts the message onto the queue read by the dispatcher. - * - * @param message the message that has been received - */ - public void messageReceived(UnprocessedMessage message) - { - if (_logger.isDebugEnabled()) - { - _logger.debug("Message received in session with channel id " + _channelId); - } - - _queue.add(message); - } - - /** - * Acknowledge a message or several messages. This method can be called via AbstractJMSMessage or from - * a BasicConsumer. The former where the mode is CLIENT_ACK and the latter where the mode is - * AUTO_ACK or similar. - * - * @param deliveryTag the tag of the last message to be acknowledged - * @param multiple if true will acknowledge all messages up to and including the one specified by the - * delivery tag - */ - public void acknowledgeMessage(long deliveryTag, boolean multiple) - { - final AMQFrame ackFrame = BasicAckBody.createAMQFrame(_channelId, deliveryTag, multiple); - if (_logger.isDebugEnabled()) - { - _logger.debug("Sending ack for delivery tag " + deliveryTag + " on channel " + _channelId); - } - _connection.getProtocolHandler().writeFrame(ackFrame); - } - - public int getDefaultPrefetch() - { - return _defaultPrefetchHighMark; - } - - public int getDefaultPrefetchHigh() - { - return _defaultPrefetchHighMark; - } - - public int getDefaultPrefetchLow() - { - return _defaultPrefetchLowMark; - } - - public int getChannelId() - { - return _channelId; - } - - void start() - { - if (_dispatcher != null) - { - //then we stopped this and are restarting, so signal server to resume delivery - unsuspendChannel(); - } - _dispatcher = new Dispatcher(); - _dispatcher.setDaemon(true); - _dispatcher.start(); - } - - void stop() - { - //stop the server delivering messages to this session - suspendChannel(); - -//stop the dispatcher thread - _stopped.set(true); - } - - boolean isStopped() - { - return _stopped.get(); - } - - /** - * Callers must hold the failover mutex before calling this method. - * - * @param consumer - * @throws AMQException - */ - void registerConsumer(BasicMessageConsumer consumer) throws AMQException - { - AMQDestination amqd = consumer.getDestination(); - - AMQProtocolHandler protocolHandler = _connection.getProtocolHandler(); - - declareExchange(amqd, protocolHandler); - - String queueName = declareQueue(amqd, protocolHandler); - - bindQueue(amqd, queueName, protocolHandler, consumer.getRawSelectorFieldTable()); - - String consumerTag = consumeFromQueue(queueName, protocolHandler, consumer.getPrefetchHigh(), consumer.getPrefetchLow(), - consumer.isNoLocal(), consumer.isExclusive(), consumer.getAcknowledgeMode()); - - consumer.setConsumerTag(consumerTag); - _consumers.put(consumerTag, consumer); - } - - /** - * Called by the MessageConsumer when closing, to deregister the consumer from the - * map from consumerTag to consumer instance. - * - * @param consumerTag the consumer tag, that was broker-generated - */ - void deregisterConsumer(String consumerTag) - { - _consumers.remove(consumerTag); - } - - private void registerProducer(long producerId, MessageProducer producer) - { - _producers.put(new Long(producerId), producer); - } - - void deregisterProducer(long producerId) - { - _producers.remove(new Long(producerId)); - } - - private long getNextProducerId() - { - return ++_nextProducerId; - } - - /** - * Resubscribes all producers and consumers. This is called when performing failover. - * - * @throws AMQException - */ - void resubscribe() throws AMQException - { - resubscribeProducers(); - resubscribeConsumers(); - } - - private void resubscribeProducers() throws AMQException - { - ArrayList producers = new ArrayList(_producers.values()); - _logger.info(MessageFormat.format("Resubscribing producers = {0} producers.size={1}", producers, producers.size())); // FIXME: remove - for (Iterator it = producers.iterator(); it.hasNext();) - { - BasicMessageProducer producer = (BasicMessageProducer) it.next(); - producer.resubscribe(); - } - } - - private void resubscribeConsumers() throws AMQException - { - ArrayList consumers = new ArrayList(_consumers.values()); - _consumers.clear(); - - for (Iterator it = consumers.iterator(); it.hasNext();) - { - BasicMessageConsumer consumer = (BasicMessageConsumer) it.next(); - registerConsumer(consumer); - } - } - - private void suspendChannel() - { - _logger.warn("Suspending channel"); - AMQFrame channelFlowFrame = ChannelFlowBody.createAMQFrame(_channelId, false); - _connection.getProtocolHandler().writeFrame(channelFlowFrame); - } - - private void unsuspendChannel() - { - _logger.warn("Unsuspending channel"); - AMQFrame channelFlowFrame = ChannelFlowBody.createAMQFrame(_channelId, true); - _connection.getProtocolHandler().writeFrame(channelFlowFrame); - } -} diff --git a/client/src/org/apache/qpid/client/AMQTemporaryQueue.java b/client/src/org/apache/qpid/client/AMQTemporaryQueue.java deleted file mode 100644 index 0b12bfb728..0000000000 --- a/client/src/org/apache/qpid/client/AMQTemporaryQueue.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import javax.jms.JMSException; -import javax.jms.TemporaryQueue; - -/** - * AMQ implementation of a TemporaryQueue. - */ -final class AMQTemporaryQueue extends AMQQueue implements TemporaryQueue { - - /** - * Create a new instance of an AMQTemporaryQueue - */ - public AMQTemporaryQueue() { - super("TempQueue" + Long.toString(System.currentTimeMillis()), - null, true, true); - } - - /** - * @see javax.jms.TemporaryQueue#delete() - */ - public void delete() throws JMSException { - throw new UnsupportedOperationException("Delete not supported, " + - "will auto-delete when connection closed"); - } - -} diff --git a/client/src/org/apache/qpid/client/AMQTemporaryTopic.java b/client/src/org/apache/qpid/client/AMQTemporaryTopic.java deleted file mode 100644 index 0ba5cb3c3a..0000000000 --- a/client/src/org/apache/qpid/client/AMQTemporaryTopic.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import javax.jms.JMSException; -import javax.jms.TemporaryTopic; - -/** - * AMQ implementation of TemporaryTopic. - */ -class AMQTemporaryTopic extends AMQTopic implements TemporaryTopic -{ - - /** - * Create new temporary topic. - */ - public AMQTemporaryTopic() - { - super("TempQueue" + Long.toString(System.currentTimeMillis())); - } - - /** - * @see javax.jms.TemporaryTopic#delete() - */ - public void delete() throws JMSException - { - throw new UnsupportedOperationException("Delete not supported, " + - "will auto-delete when connection closed"); - } - -} diff --git a/client/src/org/apache/qpid/client/AMQTopic.java b/client/src/org/apache/qpid/client/AMQTopic.java deleted file mode 100644 index 89727f65b7..0000000000 --- a/client/src/org/apache/qpid/client/AMQTopic.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import org.apache.qpid.url.BindingURL; -import org.apache.qpid.exchange.ExchangeDefaults; - -import javax.jms.JMSException; -import javax.jms.Topic; - -public class AMQTopic extends AMQDestination implements Topic - { - /** - * Constructor for use in creating a topic using a BindingURL. - * - * @param binding The binding url object. - */ - public AMQTopic(BindingURL binding) - { - super(binding); - } - - public AMQTopic(String name) - { - super(ExchangeDefaults.TOPIC_EXCHANGE_NAME, ExchangeDefaults.TOPIC_EXCHANGE_CLASS, name, true, true, null); - _isDurable = false; - } - - /** - * Constructor for use in creating a topic to represent a durable subscription - * @param topic - * @param clientId - * @param subscriptionName - */ - public AMQTopic(AMQTopic topic, String clientId, String subscriptionName) - { - super(ExchangeDefaults.TOPIC_EXCHANGE_NAME, ExchangeDefaults.TOPIC_EXCHANGE_CLASS, topic.getDestinationName(), true, false, clientId + ":" + subscriptionName); - _isDurable = true; - } - - public String getTopicName() throws JMSException - { - return super.getDestinationName(); - } - - public String getEncodedName() - { - return 'T' + getDestinationName(); - } - - public String getRoutingKey() - { - return getDestinationName(); - } - - public boolean isNameRequired() - { - // Topics always rely on a server generated queue name. - return false; - } - - /** - * Override since the queue is always private and we must ensure it remains null. If not, - * reuse of the topic when registering consumers will make all consumers listen on the same (private) queue rather - * than getting their own (private) queue. - * - * This is relatively nasty but it is difficult to come up with a more elegant solution, given - * the requirement in the case on AMQQueue and possibly other AMQDestination subclasses to - * use the underlying queue name even where it is server generated. - */ - public void setQueueName(String queueName) - { - } -} diff --git a/client/src/org/apache/qpid/client/AMQTopicSessionAdaptor.java b/client/src/org/apache/qpid/client/AMQTopicSessionAdaptor.java deleted file mode 100644 index 73613b6923..0000000000 --- a/client/src/org/apache/qpid/client/AMQTopicSessionAdaptor.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import javax.jms.*; -import javax.jms.IllegalStateException; -import java.io.Serializable; - -public class AMQTopicSessionAdaptor implements TopicSession -{ - protected final AMQSession _session; - - public AMQTopicSessionAdaptor(Session session) - { - _session = (AMQSession) session; - } - - public Topic createTopic(String string) throws JMSException { - return _session.createTopic(string); - } - - public TopicSubscriber createSubscriber(Topic topic) throws JMSException { - return _session.createSubscriber(topic); - } - - public TopicSubscriber createSubscriber(Topic topic, String string, boolean b) throws JMSException { - return _session.createSubscriber(topic, string, b); - } - - public TopicSubscriber createDurableSubscriber(Topic topic, String string) throws JMSException { - return _session.createDurableSubscriber(topic, string); - } - - public TopicSubscriber createDurableSubscriber(Topic topic, String string, String string1, boolean b) throws JMSException { - return _session.createDurableSubscriber(topic, string, string1, b); - } - - public TopicPublisher createPublisher(Topic topic) throws JMSException { - return _session.createPublisher(topic); - } - - public TemporaryTopic createTemporaryTopic() throws JMSException { - return _session.createTemporaryTopic(); - } - - public void unsubscribe(String string) throws JMSException { - _session.unsubscribe(string); - } - - public BytesMessage createBytesMessage() throws JMSException { - return _session.createBytesMessage(); - } - - public MapMessage createMapMessage() throws JMSException { - return _session.createMapMessage(); - } - - public Message createMessage() throws JMSException { - return _session.createMessage(); - } - - public ObjectMessage createObjectMessage() throws JMSException { - return _session.createObjectMessage(); - } - - public ObjectMessage createObjectMessage(Serializable serializable) throws JMSException { - return _session.createObjectMessage(); - } - - public StreamMessage createStreamMessage() throws JMSException { - return _session.createStreamMessage(); - } - - public TextMessage createTextMessage() throws JMSException { - return _session.createTextMessage(); - } - - public TextMessage createTextMessage(String string) throws JMSException { - return _session.createTextMessage(); - } - - public boolean getTransacted() throws JMSException { - return _session.getTransacted(); - } - - public int getAcknowledgeMode() throws JMSException { - return _session.getAcknowledgeMode(); - } - - public void commit() throws JMSException { - _session.commit(); - } - - public void rollback() throws JMSException { - _session.rollback(); - } - - public void close() throws JMSException { - _session.close(); - } - - public void recover() throws JMSException { - _session.recover(); - } - - public MessageListener getMessageListener() throws JMSException { - return _session.getMessageListener(); - } - - public void setMessageListener(MessageListener messageListener) throws JMSException { - _session.setMessageListener(messageListener); - } - - public void run() { - _session.run(); - } - - public MessageProducer createProducer(Destination destination) throws JMSException { - return _session.createProducer(destination); - } - - public MessageConsumer createConsumer(Destination destination) throws JMSException { - return _session.createConsumer(destination); - } - - public MessageConsumer createConsumer(Destination destination, String string) throws JMSException { - return _session.createConsumer(destination, string); - } - - public MessageConsumer createConsumer(Destination destination, String string, boolean b) throws JMSException { - return _session.createConsumer(destination, string, b); - } - - //The following methods cannot be called from a TopicSession as per JMS spec - public Queue createQueue(String string) throws JMSException { - throw new IllegalStateException("Cannot call createQueue from TopicSession"); - } - - public QueueBrowser createBrowser(Queue queue) throws JMSException { - throw new IllegalStateException("Cannot call createBrowser from TopicSession"); - } - - public QueueBrowser createBrowser(Queue queue, String string) throws JMSException { - throw new IllegalStateException("Cannot call createBrowser from TopicSession"); - } - - public TemporaryQueue createTemporaryQueue() throws JMSException { - throw new IllegalStateException("Cannot call createTemporaryQueue from TopicSession"); - } - -} diff --git a/client/src/org/apache/qpid/client/BasicMessageConsumer.java b/client/src/org/apache/qpid/client/BasicMessageConsumer.java deleted file mode 100644 index f97ea6bf1e..0000000000 --- a/client/src/org/apache/qpid/client/BasicMessageConsumer.java +++ /dev/null @@ -1,535 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.message.AbstractJMSMessage; -import org.apache.qpid.client.message.MessageFactoryRegistry; -import org.apache.qpid.client.message.UnprocessedMessage; -import org.apache.qpid.client.protocol.AMQProtocolHandler; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.BasicCancelBody; -import org.apache.qpid.framing.BasicCancelOkBody; -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.jms.MessageConsumer; -import org.apache.qpid.jms.Session; - -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; -import java.util.concurrent.SynchronousQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; - -public class BasicMessageConsumer extends Closeable implements MessageConsumer -{ - private static final Logger _logger = Logger.getLogger(BasicMessageConsumer.class); - - /** - * The connection being used by this consumer - */ - private AMQConnection _connection; - - private String _messageSelector; - - private boolean _noLocal; - - private AMQDestination _destination; - - /** - * When true indicates that a blocking receive call is in progress - */ - private final AtomicBoolean _receiving = new AtomicBoolean(false); - /** - * Holds an atomic reference to the listener installed. - */ - private final AtomicReference _messageListener = new AtomicReference(); - - /** - * The consumer tag allows us to close the consumer by sending a jmsCancel method to the - * broker - */ - private String _consumerTag; - - /** - * We need to know the channel id when constructing frames - */ - private int _channelId; - - /** - * Used in the blocking receive methods to receive a message from - * the Session thread. Argument true indicates we want strict FIFO semantics - */ - private final SynchronousQueue _synchronousQueue = new SynchronousQueue(true); - - private MessageFactoryRegistry _messageFactory; - - private AMQSession _session; - - private AMQProtocolHandler _protocolHandler; - - /** - * We need to store the "raw" field table so that we can resubscribe in the event of failover being required - */ - private FieldTable _rawSelectorFieldTable; - - /** - * We store the high water prefetch field in order to be able to reuse it when resubscribing in the event of failover - */ - private int _prefetchHigh; - - /** - * We store the low water prefetch field in order to be able to reuse it when resubscribing in the event of failover - */ - private int _prefetchLow; - - /** - * We store the exclusive field in order to be able to reuse it when resubscribing in the event of failover - */ - private boolean _exclusive; - - /** - * The acknowledge mode in force for this consumer. Note that the AMQP protocol allows different ack modes - * per consumer whereas JMS defines this at the session level, hence why we associate it with the consumer in our - * implementation. - */ - private int _acknowledgeMode; - - /** - * Number of messages unacknowledged in DUPS_OK_ACKNOWLEDGE mode - */ - private int _outstanding; - - /** - * Tag of last message delievered, whoch should be acknowledged on commit in - * transaction mode. - */ - private long _lastDeliveryTag; - - /** - * Switch to enable sending of acknowledgements when using DUPS_OK_ACKNOWLEDGE mode. - * Enabled when _outstannding number of msgs >= _prefetchHigh and disabled at < _prefetchLow - */ - private boolean _dups_ok_acknowledge_send; - - protected BasicMessageConsumer(int channelId, AMQConnection connection, AMQDestination destination, String messageSelector, - boolean noLocal, MessageFactoryRegistry messageFactory, AMQSession session, - AMQProtocolHandler protocolHandler, FieldTable rawSelectorFieldTable, - int prefetchHigh, int prefetchLow, boolean exclusive, int acknowledgeMode) - { - _channelId = channelId; - _connection = connection; - _messageSelector = messageSelector; - _noLocal = noLocal; - _destination = destination; - _messageFactory = messageFactory; - _session = session; - _protocolHandler = protocolHandler; - _rawSelectorFieldTable = rawSelectorFieldTable; - _prefetchHigh = prefetchHigh; - _prefetchLow = prefetchLow; - _exclusive = exclusive; - _acknowledgeMode = acknowledgeMode; - } - - public AMQDestination getDestination() - { - return _destination; - } - - public String getMessageSelector() throws JMSException - { - return _messageSelector; - } - - public MessageListener getMessageListener() throws JMSException - { - return (MessageListener) _messageListener.get(); - } - - public int getAcknowledgeMode() - { - return _acknowledgeMode; - } - - private boolean isMessageListenerSet() - { - return _messageListener.get() != null; - } - - public void setMessageListener(MessageListener messageListener) throws JMSException - { - checkNotClosed(); - - //if the current listener is non-null and the session is not stopped, then - //it is an error to call this method. - - //i.e. it is only valid to call this method if - // - // (a) the session is stopped, in which case the dispatcher is not running - // OR - // (b) the listener is null AND we are not receiving synchronously at present - // - - if (_session.isStopped()) - { - _messageListener.set(messageListener); - _logger.debug("Message listener set for destination " + _destination); - } - else - { - if (_receiving.get()) - { - throw new javax.jms.IllegalStateException("Another thread is already receiving synchronously."); - } - if (!_messageListener.compareAndSet(null, messageListener)) - { - throw new javax.jms.IllegalStateException("Attempt to alter listener while session is started."); - } - _logger.debug("Message listener set for destination " + _destination); - - if (messageListener != null) - { - //handle case where connection has already been started, and the dispatcher is blocked - //doing a put on the _synchronousQueue - Object msg = _synchronousQueue.poll(); - if (msg != null) - { - AbstractJMSMessage jmsMsg = (AbstractJMSMessage) msg; - messageListener.onMessage(jmsMsg); - postDeliver(jmsMsg); - } - } - } - } - - private void acquireReceiving() throws JMSException - { - if (!_receiving.compareAndSet(false, true)) - { - throw new javax.jms.IllegalStateException("Another thread is already receiving."); - } - if (isMessageListenerSet()) - { - throw new javax.jms.IllegalStateException("A listener has already been set."); - } - } - - private void releaseReceiving() - { - _receiving.set(false); - } - - public FieldTable getRawSelectorFieldTable() - { - return _rawSelectorFieldTable; - } - - public int getPrefetch() - { - return _prefetchHigh; - } - - public int getPrefetchHigh() - { - return _prefetchHigh; - } - - public int getPrefetchLow() - { - return _prefetchLow; - } - - public boolean isNoLocal() - { - return _noLocal; - } - - public boolean isExclusive() - { - return _exclusive; - } - - public Message receive() throws JMSException - { - return receive(0); - } - - public Message receive(long l) throws JMSException - { - checkNotClosed(); - - acquireReceiving(); - - try - { - Object o = null; - if (l > 0) - { - o = _synchronousQueue.poll(l, TimeUnit.MILLISECONDS); - } - else - { - o = _synchronousQueue.take(); - } - final AbstractJMSMessage m = returnMessageOrThrow(o); - if (m != null) - { - postDeliver(m); - } - return m; - } - catch (InterruptedException e) - { - return null; - } - finally - { - releaseReceiving(); - } - } - - public Message receiveNoWait() throws JMSException - { - checkNotClosed(); - - acquireReceiving(); - - try - { - Object o = _synchronousQueue.poll(); - final AbstractJMSMessage m = returnMessageOrThrow(o); - if (m != null) - { - postDeliver(m); - } - return m; - } - finally - { - releaseReceiving(); - } - } - - /** - * We can get back either a Message or an exception from the queue. This method examines the argument and deals - * with it by throwing it (if an exception) or returning it (in any other case). - * - * @param o - * @return a message only if o is a Message - * @throws JMSException if the argument is a throwable. If it is a JMSException it is rethrown as is, but if not - * a JMSException is created with the linked exception set appropriately - */ - private AbstractJMSMessage returnMessageOrThrow(Object o) - throws JMSException - { - // errors are passed via the queue too since there is no way of interrupting the poll() via the API. - if (o instanceof Throwable) - { - JMSException e = new JMSException("Message consumer forcibly closed due to error: " + o); - if (o instanceof Exception) - { - e.setLinkedException((Exception) o); - } - throw e; - } - else - { - return (AbstractJMSMessage) o; - } - } - - public void close() throws JMSException - { - synchronized(_connection.getFailoverMutex()) - { - if (!_closed.getAndSet(true)) - { - final AMQFrame cancelFrame = BasicCancelBody.createAMQFrame(_channelId, _consumerTag, false); - - try - { - _protocolHandler.syncWrite(cancelFrame, BasicCancelOkBody.class); - } - catch (AMQException e) - { - _logger.error("Error closing consumer: " + e, e); - throw new JMSException("Error closing consumer: " + e); - } - - deregisterConsumer(); - } - } - } - - /** - * Called when you need to invalidate a consumer. Used for example when failover has occurred and the - * client has vetoed automatic resubscription. - * The caller must hold the failover mutex. - */ - void markClosed() - { - _closed.set(true); - deregisterConsumer(); - } - - /** - * Called from the AMQSession when a message has arrived for this consumer. This methods handles both the case - * of a message listener or a synchronous receive() caller. - * - * @param messageFrame the raw unprocessed mesage - * @param channelId channel on which this message was sent - */ - void notifyMessage(UnprocessedMessage messageFrame, int channelId) - { - if (_logger.isDebugEnabled()) - { - _logger.debug("notifyMessage called with message number " + messageFrame.deliverBody.deliveryTag); - } - try - { - AbstractJMSMessage jmsMessage = _messageFactory.createMessage(messageFrame.deliverBody.deliveryTag, - messageFrame.deliverBody.redelivered, - messageFrame.contentHeader, - messageFrame.bodies); - - _logger.debug("Message is of type: " + jmsMessage.getClass().getName()); - - preDeliver(jmsMessage); - - if (isMessageListenerSet()) - { - //we do not need a lock around the test above, and the dispatch below as it is invalid - //for an application to alter an installed listener while the session is started - getMessageListener().onMessage(jmsMessage); - postDeliver(jmsMessage); - } - else - { - _synchronousQueue.put(jmsMessage); - } - } - catch (Exception e) - { - if (e instanceof InterruptedException) - { - _logger.info("SynchronousQueue.put interupted. Usually result of connection closing"); - } - else - { - _logger.error("Caught exception (dump follows) - ignoring...", e); - } - } - } - - private void preDeliver(AbstractJMSMessage msg) - { - switch (_acknowledgeMode) - { - case Session.PRE_ACKNOWLEDGE: - _session.acknowledgeMessage(msg.getDeliveryTag(), false); - break; - case Session.CLIENT_ACKNOWLEDGE: - // we set the session so that when the user calls acknowledge() it can call the method on session - // to send out the appropriate frame - msg.setAMQSession(_session); - break; - } - } - - private void postDeliver(AbstractJMSMessage msg) - { - switch (_acknowledgeMode) - { - case Session.DUPS_OK_ACKNOWLEDGE: - if (++_outstanding >= _prefetchHigh) - { - _dups_ok_acknowledge_send = true; - } - if (_outstanding <= _prefetchLow) - { - _dups_ok_acknowledge_send = false; - } - - if (_dups_ok_acknowledge_send) - { - _session.acknowledgeMessage(msg.getDeliveryTag(), true); - } - break; - case Session.AUTO_ACKNOWLEDGE: - _session.acknowledgeMessage(msg.getDeliveryTag(), false); - break; - case Session.SESSION_TRANSACTED: - _lastDeliveryTag = msg.getDeliveryTag(); - break; - } - } - - /** - * Acknowledge up to last message delivered (if any). Used when commiting. - */ - void acknowledgeLastDelivered() - { - if (_lastDeliveryTag > 0) - { - _session.acknowledgeMessage(_lastDeliveryTag, true); - _lastDeliveryTag = -1; - } - } - - void notifyError(Throwable cause) - { - _closed.set(true); - - // we have no way of propagating the exception to a message listener - a JMS limitation - so we - // deal with the case where we have a synchronous receive() waiting for a message to arrive - if (!isMessageListenerSet()) - { - // offer only succeeds if there is a thread waiting for an item from the queue - if (_synchronousQueue.offer(cause)) - { - _logger.debug("Passed exception to synchronous queue for propagation to receive()"); - } - } - deregisterConsumer(); - } - - /** - * Perform cleanup to deregister this consumer. This occurs when closing the consumer in both the clean - * case and in the case of an error occurring. - */ - private void deregisterConsumer() - { - _session.deregisterConsumer(_consumerTag); - } - - public String getConsumerTag() - { - return _consumerTag; - } - - public void setConsumerTag(String consumerTag) - { - _consumerTag = consumerTag; - } -} diff --git a/client/src/org/apache/qpid/client/BasicMessageProducer.java b/client/src/org/apache/qpid/client/BasicMessageProducer.java deleted file mode 100644 index 14cafc3558..0000000000 --- a/client/src/org/apache/qpid/client/BasicMessageProducer.java +++ /dev/null @@ -1,484 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import org.apache.log4j.Logger; -import org.apache.mina.common.ByteBuffer; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.message.AbstractJMSMessage; -import org.apache.qpid.client.message.JMSBytesMessage; -import org.apache.qpid.client.protocol.AMQProtocolHandler; -import org.apache.qpid.framing.*; - -import javax.jms.DeliveryMode; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; -import java.io.UnsupportedEncodingException; - -public class BasicMessageProducer extends Closeable implements org.apache.qpid.jms.MessageProducer -{ - protected final Logger _logger = Logger.getLogger(getClass()); - - private AMQConnection _connection; - - /** - * If true, messages will not get a timestamp. - */ - private boolean _disableTimestamps; - - /** - * Priority of messages created by this producer. - */ - private int _messagePriority; - - /** - * Time to live of messages. Specified in milliseconds but AMQ has 1 second resolution. - */ - private long _timeToLive; - - /** - * Delivery mode used for this producer. - */ - private int _deliveryMode = DeliveryMode.PERSISTENT; - - /** - * The Destination used for this consumer, if specified upon creation. - */ - protected AMQDestination _destination; - - /** - * Default encoding used for messages produced by this producer. - */ - private String _encoding; - - /** - * Default encoding used for message produced by this producer. - */ - private String _mimeType; - - private AMQProtocolHandler _protocolHandler; - - /** - * True if this producer was created from a transacted session - */ - private boolean _transacted; - - private int _channelId; - - /** - * This is an id generated by the session and is used to tie individual producers to the session. This means we - * can deregister a producer with the session when the producer is clsoed. We need to be able to tie producers - * to the session so that when an error is propagated to the session it can close the producer (meaning that - * a client that happens to hold onto a producer reference will get an error if he tries to use it subsequently). - */ - private long _producerId; - - /** - * The session used to create this producer - */ - private AMQSession _session; - - private final boolean _immediate; - - private final boolean _mandatory; - - private final boolean _waitUntilSent; - - protected BasicMessageProducer(AMQConnection connection, AMQDestination destination, boolean transacted, - int channelId, AMQSession session, AMQProtocolHandler protocolHandler, - long producerId, boolean immediate, boolean mandatory, boolean waitUntilSent) - { - _connection = connection; - _destination = destination; - _transacted = transacted; - _protocolHandler = protocolHandler; - _channelId = channelId; - _session = session; - _producerId = producerId; - if (destination != null) - { - declareDestination(destination); - } - _immediate = immediate; - _mandatory = mandatory; - _waitUntilSent = waitUntilSent; - } - - void resubscribe() throws AMQException - { - if (_destination != null) - { - declareDestination(_destination); - } - } - - private void declareDestination(AMQDestination destination) - { - // Declare the exchange - // Note that the durable and internal arguments are ignored since passive is set to false - AMQFrame declare = ExchangeDeclareBody.createAMQFrame(_channelId, 0, destination.getExchangeName(), - destination.getExchangeClass(), false, - false, false, false, true, null); - _protocolHandler.writeFrame(declare); - } - - public void setDisableMessageID(boolean b) throws JMSException - { - checkNotClosed(); - // IGNORED - } - - public boolean getDisableMessageID() throws JMSException - { - checkNotClosed(); - // Always false for AMQP - return false; - } - - public void setDisableMessageTimestamp(boolean b) throws JMSException - { - checkNotClosed(); - _disableTimestamps = b; - } - - public boolean getDisableMessageTimestamp() throws JMSException - { - checkNotClosed(); - return _disableTimestamps; - } - - public void setDeliveryMode(int i) throws JMSException - { - checkNotClosed(); - if (i != DeliveryMode.NON_PERSISTENT && i != DeliveryMode.PERSISTENT) - { - throw new JMSException("DeliveryMode must be either NON_PERSISTENT or PERSISTENT. Value of " + i + - " is illegal"); - } - _deliveryMode = i; - } - - public int getDeliveryMode() throws JMSException - { - checkNotClosed(); - return _deliveryMode; - } - - public void setPriority(int i) throws JMSException - { - checkNotClosed(); - if (i < 0 || i > 9) - { - throw new IllegalArgumentException("Priority of " + i + " is illegal. Value must be in range 0 to 9"); - } - _messagePriority = i; - } - - public int getPriority() throws JMSException - { - checkNotClosed(); - return _messagePriority; - } - - public void setTimeToLive(long l) throws JMSException - { - checkNotClosed(); - if (l < 0) - { - throw new IllegalArgumentException("Time to live must be non-negative - supplied value was " + l); - } - _timeToLive = l; - } - - public long getTimeToLive() throws JMSException - { - checkNotClosed(); - return _timeToLive; - } - - public Destination getDestination() throws JMSException - { - checkNotClosed(); - return _destination; - } - - public void close() throws JMSException - { - _closed.set(true); - _session.deregisterProducer(_producerId); - } - - public void send(Message message) throws JMSException - { - synchronized (_connection.getFailoverMutex()) - { - sendImpl(_destination, (AbstractJMSMessage) message, _deliveryMode, _messagePriority, _timeToLive, - _mandatory, _immediate); - } - } - - public void send(Message message, int deliveryMode) throws JMSException - { - synchronized (_connection.getFailoverMutex()) - { - sendImpl(_destination, (AbstractJMSMessage) message, deliveryMode, _messagePriority, _timeToLive, - _mandatory, _immediate); - } - } - - public void send(Message message, int deliveryMode, boolean immediate) throws JMSException - { - synchronized (_connection.getFailoverMutex()) - { - sendImpl(_destination, (AbstractJMSMessage) message, deliveryMode, _messagePriority, _timeToLive, - _mandatory, immediate); - } - } - - public void send(Message message, int deliveryMode, int priority, - long timeToLive) throws JMSException - { - synchronized (_connection.getFailoverMutex()) - { - sendImpl(_destination, (AbstractJMSMessage)message, deliveryMode, priority, timeToLive, _mandatory, - _immediate); - } - } - - public void send(Destination destination, Message message) throws JMSException - { - checkNotClosed(); - synchronized (_connection.getFailoverMutex()) - { - validateDestination(destination); - sendImpl((AMQDestination) destination, (AbstractJMSMessage) message, _deliveryMode, _messagePriority, _timeToLive, - _mandatory, _immediate); - } - } - - public void send(Destination destination, Message message, int deliveryMode, - int priority, long timeToLive) - throws JMSException - { - checkNotClosed(); - synchronized (_connection.getFailoverMutex()) - { - validateDestination(destination); - sendImpl((AMQDestination) destination, (AbstractJMSMessage) message, deliveryMode, priority, timeToLive, - _mandatory, _immediate); - } - } - - public void send(Destination destination, Message message, int deliveryMode, - int priority, long timeToLive, boolean mandatory) - throws JMSException - { - checkNotClosed(); - synchronized (_connection.getFailoverMutex()) - { - validateDestination(destination); - sendImpl((AMQDestination) destination, (AbstractJMSMessage) message, deliveryMode, priority, timeToLive, - mandatory, _immediate); - } - } - - public void send(Destination destination, Message message, int deliveryMode, - int priority, long timeToLive, boolean mandatory, boolean immediate) - throws JMSException - { - checkNotClosed(); - synchronized (_connection.getFailoverMutex()) - { - validateDestination(destination); - sendImpl((AMQDestination) destination, (AbstractJMSMessage) message, deliveryMode, priority, timeToLive, - mandatory, immediate); - } - } - - public void send(Destination destination, Message message, int deliveryMode, - int priority, long timeToLive, boolean mandatory, - boolean immediate, boolean waitUntilSent) - throws JMSException - { - checkNotClosed(); - synchronized (_connection.getFailoverMutex()) - { - validateDestination(destination); - sendImpl((AMQDestination) destination, (AbstractJMSMessage) message, deliveryMode, priority, timeToLive, - mandatory, immediate, waitUntilSent); - } - } - - private void validateDestination(Destination destination) throws JMSException - { - if (!(destination instanceof AMQDestination)) - { - throw new JMSException("Unsupported destination class: " + - (destination != null ? destination.getClass() : null)); - } - declareDestination((AMQDestination)destination); - } - - protected void sendImpl(AMQDestination destination, AbstractJMSMessage message, int deliveryMode, int priority, - long timeToLive, boolean mandatory, boolean immediate) throws JMSException - { - sendImpl(destination, message, deliveryMode, priority, timeToLive, mandatory, immediate, _waitUntilSent); - } - - /** - * The caller of this method must hold the failover mutex. - * @param destination - * @param message - * @param deliveryMode - * @param priority - * @param timeToLive - * @param mandatory - * @param immediate - * @throws JMSException - */ - protected void sendImpl(AMQDestination destination, AbstractJMSMessage message, int deliveryMode, int priority, - long timeToLive, boolean mandatory, boolean immediate, boolean wait) throws JMSException - { - AMQFrame publishFrame = BasicPublishBody.createAMQFrame(_channelId, 0, destination.getExchangeName(), - destination.getRoutingKey(), mandatory, immediate); - - long currentTime = 0; - if (!_disableTimestamps) - { - currentTime = System.currentTimeMillis(); - message.setJMSTimestamp(currentTime); - } - // - // Very nasty temporary hack for GRM-206. Will be altered ASAP. - // - if (message instanceof JMSBytesMessage) - { - JMSBytesMessage msg = (JMSBytesMessage) message; - if (!msg.isReadable()) - { - msg.reset(); - } - } - ByteBuffer payload = message.getData(); - BasicContentHeaderProperties contentHeaderProperties = message.getJmsContentHeaderProperties(); - - if (timeToLive > 0) - { - if (!_disableTimestamps) - { - contentHeaderProperties.setExpiration(currentTime + timeToLive); - } - } - else - { - if (!_disableTimestamps) - { - contentHeaderProperties.setExpiration(0); - } - } - contentHeaderProperties.setDeliveryMode((byte) deliveryMode); - contentHeaderProperties.setPriority((byte) priority); - - int size = payload.limit(); - ContentBody[] contentBodies = createContentBodies(payload); - AMQFrame[] frames = new AMQFrame[2 + contentBodies.length]; - for (int i = 0; i < contentBodies.length; i++) - { - frames[2 + i] = ContentBody.createAMQFrame(_channelId, contentBodies[i]); - } - if (contentBodies.length > 0 && _logger.isDebugEnabled()) - { - _logger.debug("Sending content body frames to " + destination); - } - - // weight argument of zero indicates no child content headers, just bodies - AMQFrame contentHeaderFrame = ContentHeaderBody.createAMQFrame(_channelId, BasicConsumeBody.CLASS_ID, 0, - contentHeaderProperties, - size); - if (_logger.isDebugEnabled()) - { - _logger.debug("Sending content header frame to " + destination); - } - - frames[0] = publishFrame; - frames[1] = contentHeaderFrame; - CompositeAMQDataBlock compositeFrame = new CompositeAMQDataBlock(frames); - _protocolHandler.writeFrame(compositeFrame, wait); - } - - /** - * Create content bodies. This will split a large message into numerous bodies depending on the negotiated - * maximum frame size. - * @param payload - * @return the array of content bodies - */ - private ContentBody[] createContentBodies(ByteBuffer payload) - { - if (payload == null) - { - return null; - } - else if (payload.remaining() == 0) - { - return new ContentBody[0]; - } - // we substract one from the total frame maximum size to account for the end of frame marker in a body frame - // (0xCE byte). - int dataLength = payload.remaining(); - final long framePayloadMax = _session.getAMQConnection().getMaximumFrameSize() - 1; - int lastFrame = (dataLength % framePayloadMax) > 0 ? 1 : 0; - int frameCount = (int) (dataLength / framePayloadMax) + lastFrame; - final ContentBody[] bodies = new ContentBody[frameCount]; - - if (frameCount == 1) - { - bodies[0] = new ContentBody(); - bodies[0].payload = payload; - } - else - { - long remaining = dataLength; - for (int i = 0; i < bodies.length; i++) - { - bodies[i] = new ContentBody(); - payload.position((int)framePayloadMax * i); - int length = (remaining >= framePayloadMax) ? (int)framePayloadMax : (int)remaining; - payload.limit(payload.position() + length); - bodies[i].payload = payload.slice(); - remaining -= length; - } - } - return bodies; - } - - public void setMimeType(String mimeType) throws JMSException - { - checkNotClosed(); - _mimeType = mimeType; - } - - public void setEncoding(String encoding) throws JMSException, UnsupportedEncodingException - { - checkNotClosed(); - _encoding = encoding; - } -} diff --git a/client/src/org/apache/qpid/client/Closeable.java b/client/src/org/apache/qpid/client/Closeable.java deleted file mode 100644 index 873cb55726..0000000000 --- a/client/src/org/apache/qpid/client/Closeable.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import javax.jms.IllegalStateException; -import javax.jms.JMSException; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * Provides support for orderly shutdown of an object. - */ -public abstract class Closeable -{ - /** - * We use an atomic boolean so that we do not have to synchronized access to this flag. Synchronizing - * access to this flag would mean have a synchronized block in every method. - */ - protected final AtomicBoolean _closed = new AtomicBoolean(false); - - protected void checkNotClosed() throws JMSException - { - if (_closed.get()) - { - throw new IllegalStateException("Object " + toString() + " has been closed"); - } - } - - public boolean isClosed() - { - return _closed.get(); - } - - public abstract void close() throws JMSException; -} diff --git a/client/src/org/apache/qpid/client/ConnectionTuneParameters.java b/client/src/org/apache/qpid/client/ConnectionTuneParameters.java deleted file mode 100644 index b1ec7216bc..0000000000 --- a/client/src/org/apache/qpid/client/ConnectionTuneParameters.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -public class ConnectionTuneParameters -{ - private long _frameMax; - - private int _channelMax; - - private int _heartbeat; - - private long _txnLimit; - - public long getFrameMax() - { - return _frameMax; - } - - public void setFrameMax(long frameMax) - { - _frameMax = frameMax; - } - - public int getChannelMax() - { - return _channelMax; - } - - public void setChannelMax(int channelMax) - { - _channelMax = channelMax; - } - - public int getHeartbeat() - { - return _heartbeat; - } - - public void setHeartbeat(int hearbeat) - { - _heartbeat = hearbeat; - } - - public long getTxnLimit() - { - return _txnLimit; - } - - public void setTxnLimit(long txnLimit) - { - _txnLimit = txnLimit; - } -} diff --git a/client/src/org/apache/qpid/client/JmsNotImplementedException.java b/client/src/org/apache/qpid/client/JmsNotImplementedException.java deleted file mode 100644 index 903514c35f..0000000000 --- a/client/src/org/apache/qpid/client/JmsNotImplementedException.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import javax.jms.JMSException; - -public class JmsNotImplementedException extends JMSException -{ - public JmsNotImplementedException() - { - super("Not implemented"); - } -} diff --git a/client/src/org/apache/qpid/client/QueueReceiverAdaptor.java b/client/src/org/apache/qpid/client/QueueReceiverAdaptor.java deleted file mode 100644 index 57e458d833..0000000000 --- a/client/src/org/apache/qpid/client/QueueReceiverAdaptor.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import javax.jms.*; - -/** - * Class that wraps a MessageConsumer for backwards JMS compatibility - * Returned by methods in AMQSession etc - */ -public class QueueReceiverAdaptor implements QueueReceiver { - - protected MessageConsumer _consumer; - protected Queue _queue; - - protected QueueReceiverAdaptor(Queue queue, MessageConsumer consumer) - { - _consumer = consumer; - _queue = queue; - } - - public String getMessageSelector() throws JMSException - { - return _consumer.getMessageSelector(); - } - - public MessageListener getMessageListener() throws JMSException - { - return _consumer.getMessageListener(); - } - - public void setMessageListener(MessageListener messageListener) throws JMSException - { - _consumer.setMessageListener(messageListener); - } - - public Message receive() throws JMSException - { - return _consumer.receive(); - } - - public Message receive(long l) throws JMSException - { - return _consumer.receive(l); - } - - public Message receiveNoWait() throws JMSException - { - return _consumer.receiveNoWait(); - } - - public void close() throws JMSException - { - _consumer.close(); - } - - /** - * Return the queue associated with this receiver - * @return - * @throws JMSException - */ - public Queue getQueue() throws JMSException - { - return _queue; - } - - -} diff --git a/client/src/org/apache/qpid/client/TopicSubscriberAdaptor.java b/client/src/org/apache/qpid/client/TopicSubscriberAdaptor.java deleted file mode 100644 index c776a9943e..0000000000 --- a/client/src/org/apache/qpid/client/TopicSubscriberAdaptor.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client; - -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageListener; -import javax.jms.Topic; -import javax.jms.TopicSubscriber; - -/** - * Wraps a MessageConsumer to fulfill the extended TopicSubscriber contract - * - */ -class TopicSubscriberAdaptor implements TopicSubscriber -{ - private final Topic _topic; - private final MessageConsumer _consumer; - private final boolean _noLocal; - - TopicSubscriberAdaptor(Topic topic, MessageConsumer consumer, boolean noLocal) - { - _topic = topic; - _consumer = consumer; - _noLocal = noLocal; - } - TopicSubscriberAdaptor(Topic topic, BasicMessageConsumer consumer) - { - this(topic, consumer, consumer.isNoLocal()); - } - public Topic getTopic() throws JMSException - { - return _topic; - } - - public boolean getNoLocal() throws JMSException - { - return _noLocal; - } - - public String getMessageSelector() throws JMSException - { - return _consumer.getMessageSelector(); - } - - public MessageListener getMessageListener() throws JMSException - { - return _consumer.getMessageListener(); - } - - public void setMessageListener(MessageListener messageListener) throws JMSException - { - _consumer.setMessageListener(messageListener); - } - - public Message receive() throws JMSException - { - return _consumer.receive(); - } - - public Message receive(long l) throws JMSException - { - return _consumer.receive(l); - } - - public Message receiveNoWait() throws JMSException - { - return _consumer.receiveNoWait(); - } - - public void close() throws JMSException - { - _consumer.close(); - } -} diff --git a/client/src/org/apache/qpid/client/failover/FailoverException.java b/client/src/org/apache/qpid/client/failover/FailoverException.java deleted file mode 100644 index 49377fdc19..0000000000 --- a/client/src/org/apache/qpid/client/failover/FailoverException.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.failover; - -/** - * This exception is thrown when failover is taking place and we need to let other - * parts of the client know about this. - */ -public class FailoverException extends RuntimeException -{ - public FailoverException(String message) - { - super(message); - } -} diff --git a/client/src/org/apache/qpid/client/failover/FailoverHandler.java b/client/src/org/apache/qpid/client/failover/FailoverHandler.java deleted file mode 100644 index 53291a3fd0..0000000000 --- a/client/src/org/apache/qpid/client/failover/FailoverHandler.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.failover; - -import org.apache.mina.common.IoSession; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.failover.FailoverException; -import org.apache.qpid.client.protocol.AMQProtocolHandler; -import org.apache.qpid.client.failover.FailoverState; -import org.apache.qpid.AMQDisconnectedException; -import org.apache.log4j.Logger; - -import java.util.concurrent.CountDownLatch; - -/** - * When failover is required, we need a separate thread to handle the establishment of the new connection and - * the transfer of subscriptions. - * </p> - * The reason this needs to be a separate thread is because you cannot do this work inside the MINA IO processor - * thread. One significant task is the connection setup which involves a protocol exchange until a particular state - * is achieved. However if you do this in the MINA thread, you have to block until the state is achieved which means - * the IO processor is not able to do anything at all. - */ -public class FailoverHandler implements Runnable -{ - private static final Logger _logger = Logger.getLogger(FailoverHandler.class); - - private final IoSession _session; - private AMQProtocolHandler _amqProtocolHandler; - - /** - * Used where forcing the failover host - */ - private String _host; - - /** - * Used where forcing the failover port - */ - private int _port; - - public FailoverHandler(AMQProtocolHandler amqProtocolHandler, IoSession session) - { - _amqProtocolHandler = amqProtocolHandler; - _session = session; - } - - public void run() - { - if (Thread.currentThread().isDaemon()) - { - throw new IllegalStateException("FailoverHandler must run on a non-daemon thread."); - } - //Thread.currentThread().setName("Failover Thread"); - - _amqProtocolHandler.setFailoverLatch(new CountDownLatch(1)); - - // 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 - _amqProtocolHandler.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. - synchronized (_amqProtocolHandler.getConnection().getFailoverMutex()) - { - _logger.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 = _amqProtocolHandler.getStateManager(); - _amqProtocolHandler.setStateManager(new AMQStateManager()); - if (!_amqProtocolHandler.getConnection().firePreFailover(_host != null)) - { - _amqProtocolHandler.setStateManager(existingStateManager); - if (_host != null) - { - _amqProtocolHandler.getConnection().exceptionReceived(new AMQDisconnectedException("Redirect was vetoed by client")); - } - else - { - _amqProtocolHandler.getConnection().exceptionReceived(new AMQDisconnectedException("Failover was vetoed by client")); - } - _amqProtocolHandler.getFailoverLatch().countDown(); - _amqProtocolHandler.setFailoverLatch(null); - return; - } - boolean 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) - { - failoverSucceeded = _amqProtocolHandler.getConnection().attemptReconnection(_host, _port, _amqProtocolHandler.isUseSSL()); - } - else - { - failoverSucceeded = _amqProtocolHandler.getConnection().attemptReconnection(); - } - if (!failoverSucceeded) - { - _amqProtocolHandler.setStateManager(existingStateManager); - _amqProtocolHandler.getConnection().exceptionReceived( - new AMQDisconnectedException("Server closed connection and no failover " + - "was successful")); - } - else - { - _amqProtocolHandler.setStateManager(existingStateManager); - try - { - if (_amqProtocolHandler.getConnection().firePreResubscribe()) - { - _logger.info("Resubscribing on new connection"); - _amqProtocolHandler.getConnection().resubscribeSessions(); - } - else - { - _logger.info("Client vetoed automatic resubscription"); - } - _amqProtocolHandler.getConnection().fireFailoverComplete(); - _amqProtocolHandler.setFailoverState(FailoverState.NOT_STARTED); - _logger.info("Connection failover completed successfully"); - } - catch (Exception e) - { - _logger.info("Failover process failed - exception being propagated by protocol handler"); - _amqProtocolHandler.setFailoverState(FailoverState.FAILED); - try - { - _amqProtocolHandler.exceptionCaught(_session, e); - } - catch (Exception ex) - { - _logger.error("Error notifying protocol session of error: " + ex, ex); - } - } - } - } - _amqProtocolHandler.getFailoverLatch().countDown(); - } - - public String getHost() - { - return _host; - } - - public void setHost(String host) - { - _host = host; - } - - public int getPort() - { - return _port; - } - - public void setPort(int port) - { - _port = port; - } -} diff --git a/client/src/org/apache/qpid/client/failover/FailoverState.java b/client/src/org/apache/qpid/client/failover/FailoverState.java deleted file mode 100644 index e5787439ec..0000000000 --- a/client/src/org/apache/qpid/client/failover/FailoverState.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.failover; - -/** - * Enumeration of failover states. Used to handle failover from within AMQProtocolHandler where MINA events need to be - * dealt with and can happen during failover. - */ -public final class FailoverState -{ - private final String _state; - - /** Failover has not yet been attempted on this connection */ - public static final FailoverState NOT_STARTED = new FailoverState("NOT STARTED"); - - /** Failover has been requested on this connection but has not completed */ - public static final FailoverState IN_PROGRESS = new FailoverState("IN PROGRESS"); - - /** Failover has been attempted and failed */ - public static final FailoverState FAILED = new FailoverState("FAILED"); - - private FailoverState(String state) - { - _state = state; - } - - public String toString() - { - return "FailoverState: " + _state; - } -} diff --git a/client/src/org/apache/qpid/client/failover/FailoverSupport.java b/client/src/org/apache/qpid/client/failover/FailoverSupport.java deleted file mode 100644 index bb7397f194..0000000000 --- a/client/src/org/apache/qpid/client/failover/FailoverSupport.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.failover; - -import org.apache.log4j.Logger; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.failover.FailoverException; - -import javax.jms.JMSException; - -public abstract class FailoverSupport -{ - private static final Logger _log = Logger.getLogger(FailoverSupport.class); - - public Object execute(AMQConnection con) throws JMSException - { - // We wait until we are not in the middle of failover before acquiring the mutex and then proceeding. - // Any method that can potentially block for any reason should use this class so that deadlock will not - // occur. The FailoverException is propagated by the AMQProtocolHandler to any listeners (e.g. frame listeners) - // that might be causing a block. When that happens, the exception is caught here and the mutex is released - // before waiting for the failover to complete (either successfully or unsuccessfully). - while (true) - { - try - { - con.blockUntilNotFailingOver(); - } - catch (InterruptedException e) - { - _log.info("Interrupted: " + e, e); - return null; - } - synchronized (con.getFailoverMutex()) - { - try - { - return operation(); - } - catch (FailoverException e) - { - _log.info("Failover exception caught during operation"); - } - } - } - } - - protected abstract Object operation() throws JMSException; -} diff --git a/client/src/org/apache/qpid/client/handler/BasicDeliverMethodHandler.java b/client/src/org/apache/qpid/client/handler/BasicDeliverMethodHandler.java deleted file mode 100644 index 6e12899204..0000000000 --- a/client/src/org/apache/qpid/client/handler/BasicDeliverMethodHandler.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.handler; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.framing.BasicDeliverBody; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.client.protocol.AMQMethodEvent; -import org.apache.qpid.client.message.UnprocessedMessage; - -public class BasicDeliverMethodHandler implements StateAwareMethodListener -{ - private static final Logger _logger = Logger.getLogger(BasicDeliverMethodHandler.class); - - private static final BasicDeliverMethodHandler _instance = new BasicDeliverMethodHandler(); - - public static BasicDeliverMethodHandler getInstance() - { - return _instance; - } - - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException - { - final UnprocessedMessage msg = new UnprocessedMessage(); - msg.deliverBody = (BasicDeliverBody) evt.getMethod(); - msg.channelId = evt.getChannelId(); - _logger.debug("New JmsDeliver method received"); - evt.getProtocolSession().unprocessedMessageReceived(msg); - } -} diff --git a/client/src/org/apache/qpid/client/handler/BasicReturnMethodHandler.java b/client/src/org/apache/qpid/client/handler/BasicReturnMethodHandler.java deleted file mode 100644 index 8785a96396..0000000000 --- a/client/src/org/apache/qpid/client/handler/BasicReturnMethodHandler.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.handler; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.message.UnprocessedMessage; -import org.apache.qpid.client.protocol.AMQMethodEvent; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.framing.BasicReturnBody; - -public class BasicReturnMethodHandler implements StateAwareMethodListener -{ - private static final Logger _logger = Logger.getLogger(BasicReturnMethodHandler.class); - - private static final BasicReturnMethodHandler _instance = new BasicReturnMethodHandler(); - - public static BasicReturnMethodHandler getInstance() - { - return _instance; - } - - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException - { - _logger.debug("New JmsBounce method received"); - final UnprocessedMessage msg = new UnprocessedMessage(); - msg.deliverBody = null; - msg.bounceBody = (BasicReturnBody) evt.getMethod(); - msg.channelId = evt.getChannelId(); - - evt.getProtocolSession().unprocessedMessageReceived(msg); - } -}
\ No newline at end of file diff --git a/client/src/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java b/client/src/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java deleted file mode 100644 index 2bd93f1508..0000000000 --- a/client/src/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.handler; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQChannelClosedException; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.AMQNoConsumersException; -import org.apache.qpid.client.AMQNoRouteException; -import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.client.protocol.AMQMethodEvent; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.ChannelCloseBody; -import org.apache.qpid.framing.ChannelCloseOkBody; - -public class ChannelCloseMethodHandler implements StateAwareMethodListener -{ - private static final Logger _logger = Logger.getLogger(ChannelCloseMethodHandler.class); - - private static ChannelCloseMethodHandler _handler = new ChannelCloseMethodHandler(); - - public static ChannelCloseMethodHandler getInstance() - { - return _handler; - } - - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException - { - _logger.debug("ChannelClose method received"); - ChannelCloseBody method = (ChannelCloseBody) evt.getMethod(); - - 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.getChannelId()); - evt.getProtocolSession().writeFrame(frame); - if (errorCode != AMQConstant.REPLY_SUCCESS.getCode()) - { - _logger.error("Channel close received with errorCode " + errorCode + ", and reason " + reason); - if (errorCode == AMQConstant.NO_CONSUMERS.getCode()) - { - throw new AMQNoConsumersException("Error: " + reason, null); - } - else - { - if (errorCode == AMQConstant.NO_ROUTE.getCode()) - { - throw new AMQNoRouteException("Error: " + reason, null); - } - else - { - throw new AMQChannelClosedException(errorCode, "Error: " + reason); - } - } - } - evt.getProtocolSession().channelClosed(evt.getChannelId(), errorCode, reason); - } -} diff --git a/client/src/org/apache/qpid/client/handler/ChannelCloseOkMethodHandler.java b/client/src/org/apache/qpid/client/handler/ChannelCloseOkMethodHandler.java deleted file mode 100644 index 383cebbcab..0000000000 --- a/client/src/org/apache/qpid/client/handler/ChannelCloseOkMethodHandler.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.handler; - -import org.apache.qpid.AMQException; -import org.apache.qpid.client.protocol.AMQMethodEvent; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.log4j.Logger; - -public class ChannelCloseOkMethodHandler implements StateAwareMethodListener -{ - private static final Logger _logger = Logger.getLogger(ChannelCloseOkMethodHandler.class); - - private static final ChannelCloseOkMethodHandler _instance = new ChannelCloseOkMethodHandler(); - - public static ChannelCloseOkMethodHandler getInstance() - { - return _instance; - } - - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException - { - _logger.info("Received channel-close-ok for channel-id " + evt.getChannelId()); - - //todo this should do the closure - } -} diff --git a/client/src/org/apache/qpid/client/handler/ChannelFlowOkMethodHandler.java b/client/src/org/apache/qpid/client/handler/ChannelFlowOkMethodHandler.java deleted file mode 100644 index 9a4f7af849..0000000000 --- a/client/src/org/apache/qpid/client/handler/ChannelFlowOkMethodHandler.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.handler; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.protocol.AMQMethodEvent; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.framing.ChannelFlowOkBody; - -public class ChannelFlowOkMethodHandler implements StateAwareMethodListener -{ - private static final Logger _logger = Logger.getLogger(ChannelFlowOkMethodHandler.class); - private static final ChannelFlowOkMethodHandler _instance = new ChannelFlowOkMethodHandler(); - - public static ChannelFlowOkMethodHandler getInstance() - { - return _instance; - } - - private ChannelFlowOkMethodHandler() - { - } - - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException - { - ChannelFlowOkBody method = (ChannelFlowOkBody) evt.getMethod(); - _logger.debug("Received Channel.Flow-Ok message, active = " + method.active); - } -} diff --git a/client/src/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java b/client/src/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java deleted file mode 100644 index dd9fd651c1..0000000000 --- a/client/src/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.handler; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.AMQConnectionClosedException; -import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.client.protocol.AMQMethodEvent; -import org.apache.qpid.client.state.AMQState; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.client.AMQAuthenticationException; -import org.apache.qpid.framing.ConnectionCloseBody; -import org.apache.qpid.framing.ConnectionCloseOkBody; - -public class ConnectionCloseMethodHandler implements StateAwareMethodListener -{ - private static final Logger _logger = Logger.getLogger(ConnectionCloseMethodHandler.class); - - private static ConnectionCloseMethodHandler _handler = new ConnectionCloseMethodHandler(); - - public static ConnectionCloseMethodHandler getInstance() - { - return _handler; - } - - private ConnectionCloseMethodHandler() - { - } - - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException - { - _logger.info("ConnectionClose frame received"); - ConnectionCloseBody method = (ConnectionCloseBody) evt.getMethod(); - - // does it matter - //stateManager.changeState(AMQState.CONNECTION_CLOSING); - - int errorCode = method.replyCode; - String reason = method.replyText; - - // TODO: check whether channel id of zero is appropriate - evt.getProtocolSession().writeFrame(ConnectionCloseOkBody.createAMQFrame((short)0)); - - if (errorCode != 200) - { - if(errorCode == AMQConstant.NOT_ALLOWED.getCode()) - { - _logger.info("Authentication Error:"+Thread.currentThread().getName()); - - evt.getProtocolSession().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.getProtocolSession().closeProtocolSession(); - - stateManager.changeState(AMQState.CONNECTION_CLOSED); - } -} diff --git a/client/src/org/apache/qpid/client/handler/ConnectionOpenOkMethodHandler.java b/client/src/org/apache/qpid/client/handler/ConnectionOpenOkMethodHandler.java deleted file mode 100644 index 8785e7d44e..0000000000 --- a/client/src/org/apache/qpid/client/handler/ConnectionOpenOkMethodHandler.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.handler; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.protocol.AMQMethodEvent; -import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQState; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.framing.ConnectionOpenOkBody; - -public class ConnectionOpenOkMethodHandler implements StateAwareMethodListener -{ - - private static final Logger _logger = Logger.getLogger(ConnectionOpenOkMethodHandler.class); - - private static final ConnectionOpenOkMethodHandler _instance = new ConnectionOpenOkMethodHandler(); - - public static ConnectionOpenOkMethodHandler getInstance() - { - return _instance; - } - - private ConnectionOpenOkMethodHandler() - { - } - - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException - { - AMQProtocolSession session = evt.getProtocolSession(); - ConnectionOpenOkBody method = (ConnectionOpenOkBody) evt.getMethod(); - stateManager.changeState(AMQState.CONNECTION_OPEN); - } - -} diff --git a/client/src/org/apache/qpid/client/handler/ConnectionRedirectMethodHandler.java b/client/src/org/apache/qpid/client/handler/ConnectionRedirectMethodHandler.java deleted file mode 100644 index a658e3e787..0000000000 --- a/client/src/org/apache/qpid/client/handler/ConnectionRedirectMethodHandler.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.handler; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.protocol.AMQMethodEvent; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.framing.ConnectionRedirectBody; - -public class ConnectionRedirectMethodHandler implements StateAwareMethodListener -{ - private static final Logger _logger = Logger.getLogger(ConnectionRedirectMethodHandler.class); - - private static final int DEFAULT_REDIRECT_PORT = 5672; - - private static ConnectionRedirectMethodHandler _handler = new ConnectionRedirectMethodHandler(); - - public static ConnectionRedirectMethodHandler getInstance() - { - return _handler; - } - - private ConnectionRedirectMethodHandler() - { - } - - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException - { - _logger.info("ConnectionRedirect frame received"); - ConnectionRedirectBody method = (ConnectionRedirectBody) evt.getMethod(); - - // 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 = Integer.parseInt(method.host.substring(portIndex + 1)); - } - evt.getProtocolSession().failover(host, port); - } -} diff --git a/client/src/org/apache/qpid/client/handler/ConnectionSecureMethodHandler.java b/client/src/org/apache/qpid/client/handler/ConnectionSecureMethodHandler.java deleted file mode 100644 index fd15faf429..0000000000 --- a/client/src/org/apache/qpid/client/handler/ConnectionSecureMethodHandler.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.handler; - -import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.ConnectionSecureOkBody; -import org.apache.qpid.framing.ConnectionSecureBody; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.client.protocol.AMQMethodEvent; - -import javax.security.sasl.SaslClient; -import javax.security.sasl.SaslException; - -public class ConnectionSecureMethodHandler implements StateAwareMethodListener -{ - private static final ConnectionSecureMethodHandler _instance = new ConnectionSecureMethodHandler(); - - public static ConnectionSecureMethodHandler getInstance() - { - return _instance; - } - - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException - { - SaslClient client = evt.getProtocolSession().getSaslClient(); - if (client == null) - { - throw new AMQException("No SASL client set up - cannot proceed with authentication"); - } - - ConnectionSecureBody body = (ConnectionSecureBody) evt.getMethod(); - - try - { - // Evaluate server challenge - byte[] response = client.evaluateChallenge(body.challenge); - AMQFrame responseFrame = ConnectionSecureOkBody.createAMQFrame(evt.getChannelId(), response); - evt.getProtocolSession().writeFrame(responseFrame); - } - catch (SaslException e) - { - throw new AMQException("Error processing SASL challenge: " + e, e); - } - - - } -} diff --git a/client/src/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java b/client/src/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java deleted file mode 100644 index caef9a3f44..0000000000 --- a/client/src/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.handler; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.protocol.AMQMethodEvent; -import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.security.AMQCallbackHandler; -import org.apache.qpid.client.security.CallbackHandlerRegistry; -import org.apache.qpid.client.state.AMQState; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.framing.ConnectionStartBody; -import org.apache.qpid.framing.ConnectionStartOkBody; -import org.apache.qpid.framing.FieldTable; - -import javax.security.sasl.Sasl; -import javax.security.sasl.SaslClient; -import javax.security.sasl.SaslException; -import java.io.UnsupportedEncodingException; -import java.util.HashSet; -import java.util.StringTokenizer; - -public class ConnectionStartMethodHandler implements StateAwareMethodListener -{ - - private static final Logger _log = Logger.getLogger(ConnectionStartMethodHandler.class); - - private static final ConnectionStartMethodHandler _instance = new ConnectionStartMethodHandler(); - - public static ConnectionStartMethodHandler getInstance() - { - return _instance; - } - - private ConnectionStartMethodHandler() - { - } - - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException - { - ConnectionStartBody body = (ConnectionStartBody) evt.getMethod(); - - try - { - // the mechanism we are going to use - String mechanism; - if (body.mechanisms == null) - { - throw new AMQException("mechanism not specified in ConnectionStart method frame"); - } - else - { - mechanism = chooseMechanism(body.mechanisms); - } - - if (mechanism == null) - { - throw new AMQException("No supported security mechanism found, passed: " + new String(body.mechanisms)); - } - - final AMQProtocolSession ps = evt.getProtocolSession(); - byte[] saslResponse; - try - { - SaslClient sc = Sasl.createSaslClient(new String[]{mechanism}, - null, "AMQP", "localhost", - null, createCallbackHandler(mechanism, ps)); - if (sc == null) - { - throw new AMQException("Client SASL configuration error: no SaslClient could be created for mechanism " + - mechanism + ". Please ensure all factories are registered. See DynamicSaslRegistrar for " + - " details of how to register non-standard SASL client providers."); - } - ps.setSaslClient(sc); - saslResponse = (sc.hasInitialResponse() ? sc.evaluateChallenge(new byte[0]) : null); - } - catch (SaslException e) - { - ps.setSaslClient(null); - throw new AMQException("Unable to create SASL client: " + e, e); - } - - if (body.locales == null) - { - throw new AMQException("Locales is not defined in Connection Start method"); - } - final String locales = new String(body.locales, "utf8"); - final StringTokenizer tokenizer = new StringTokenizer(locales, " "); - String selectedLocale = null; - if (tokenizer.hasMoreTokens()) - { - selectedLocale = tokenizer.nextToken(); - } - else - { - throw new AMQException("No locales sent from server, passed: " + locales); - } - - stateManager.changeState(AMQState.CONNECTION_NOT_TUNED); - FieldTable clientProperties = new FieldTable(); - clientProperties.put("instance", ps.getClientID()); - clientProperties.put("product", "Qpid"); - clientProperties.put("version", "1.0"); - clientProperties.put("platform", getFullSystemInfo()); - ps.writeFrame(ConnectionStartOkBody.createAMQFrame(evt.getChannelId(), clientProperties, mechanism, - saslResponse, selectedLocale)); - } - catch (UnsupportedEncodingException e) - { - throw new AMQException(_log, "Unable to decode data: " + e, e); - } - } - - private String getFullSystemInfo() - { - StringBuffer fullSystemInfo = new StringBuffer(); - fullSystemInfo.append(System.getProperty("java.runtime.name")); - fullSystemInfo.append(", " + System.getProperty("java.runtime.version")); - fullSystemInfo.append(", " + System.getProperty("java.vendor")); - fullSystemInfo.append(", " + System.getProperty("os.arch")); - fullSystemInfo.append(", " + System.getProperty("os.name")); - fullSystemInfo.append(", " + System.getProperty("os.version")); - fullSystemInfo.append(", " + System.getProperty("sun.os.patch.level")); - - return fullSystemInfo.toString(); - } - - private String chooseMechanism(byte[] availableMechanisms) throws UnsupportedEncodingException - { - final String mechanisms = new String(availableMechanisms, "utf8"); - StringTokenizer tokenizer = new StringTokenizer(mechanisms, " "); - HashSet mechanismSet = new HashSet(); - while (tokenizer.hasMoreTokens()) - { - mechanismSet.add(tokenizer.nextToken()); - } - - String preferredMechanisms = CallbackHandlerRegistry.getInstance().getMechanisms(); - StringTokenizer prefTokenizer = new StringTokenizer(preferredMechanisms, " "); - while (prefTokenizer.hasMoreTokens()) - { - String mech = prefTokenizer.nextToken(); - if (mechanismSet.contains(mech)) - { - return mech; - } - } - return null; - } - - private AMQCallbackHandler createCallbackHandler(String mechanism, AMQProtocolSession protocolSession) - throws AMQException - { - Class mechanismClass = CallbackHandlerRegistry.getInstance().getCallbackHandlerClass(mechanism); - try - { - Object instance = mechanismClass.newInstance(); - AMQCallbackHandler cbh = (AMQCallbackHandler) instance; - cbh.initialise(protocolSession); - return cbh; - } - catch (Exception e) - { - throw new AMQException("Unable to create callback handler: " + e, e); - } - } -} diff --git a/client/src/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java b/client/src/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java deleted file mode 100644 index 8fee277392..0000000000 --- a/client/src/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.handler; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.ConnectionTuneParameters; -import org.apache.qpid.client.protocol.AMQMethodEvent; -import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQState; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.framing.ConnectionOpenBody; -import org.apache.qpid.framing.ConnectionTuneBody; -import org.apache.qpid.framing.ConnectionTuneOkBody; -import org.apache.qpid.framing.AMQFrame; - -public class ConnectionTuneMethodHandler implements StateAwareMethodListener -{ - private static final Logger _logger = Logger.getLogger(ConnectionTuneMethodHandler.class); - - private static final ConnectionTuneMethodHandler _instance = new ConnectionTuneMethodHandler(); - - public static ConnectionTuneMethodHandler getInstance() - { - return _instance; - } - - protected ConnectionTuneMethodHandler() - { - } - - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException - { - _logger.debug("ConnectionTune frame received"); - ConnectionTuneBody frame = (ConnectionTuneBody) evt.getMethod(); - AMQProtocolSession session = evt.getProtocolSession(); - - ConnectionTuneParameters params = session.getConnectionTuneParameters(); - if (params == null) - { - params = new ConnectionTuneParameters(); - } - - params.setFrameMax(frame.frameMax); - params.setChannelMax(frame.channelMax); - params.setHeartbeat(Integer.getInteger("amqj.heartbeat.delay", frame.heartbeat)); - session.setConnectionTuneParameters(params); - - stateManager.changeState(AMQState.CONNECTION_NOT_OPENED); - session.writeFrame(createTuneOkFrame(evt.getChannelId(), params)); - session.writeFrame(createConnectionOpenFrame(evt.getChannelId(), session.getAMQConnection().getVirtualHost(), null, true)); - } - - protected AMQFrame createConnectionOpenFrame(int channel, String path, String capabilities, boolean insist) - { - return ConnectionOpenBody.createAMQFrame(channel, path, capabilities, insist); - } - - protected AMQFrame createTuneOkFrame(int channel, ConnectionTuneParameters params) - { - return ConnectionTuneOkBody.createAMQFrame(channel, params.getChannelMax(), params.getFrameMax(), params.getHeartbeat()); - } -} diff --git a/client/src/org/apache/qpid/client/message/AMQMessage.java b/client/src/org/apache/qpid/client/message/AMQMessage.java deleted file mode 100644 index edabed90b3..0000000000 --- a/client/src/org/apache/qpid/client/message/AMQMessage.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.message; - -import org.apache.qpid.framing.ContentHeaderProperties; -import org.apache.qpid.client.AMQSession; - -public class AMQMessage -{ - protected ContentHeaderProperties _contentHeaderProperties; - - /** - * If the acknowledge mode is CLIENT_ACKNOWLEDGE the session is required - */ - protected AMQSession _session; - - protected final long _deliveryTag; - - public AMQMessage(ContentHeaderProperties properties, long deliveryTag) - { - _contentHeaderProperties = properties; - _deliveryTag = deliveryTag; - } - - public AMQMessage(ContentHeaderProperties properties) - { - this(properties, -1); - } - - /** - * The session is set when CLIENT_ACKNOWLEDGE mode is used so that the CHANNEL ACK can be sent when the user - * calls acknowledge() - * @param s the AMQ session that delivered this message - */ - public void setAMQSession(AMQSession s) - { - _session = s; - } - - public AMQSession getAMQSession() - { - return _session; - } - - /** - * Get the AMQ message number assigned to this message - * @return the message number - */ - public long getDeliveryTag() - { - return _deliveryTag; - } -} diff --git a/client/src/org/apache/qpid/client/message/AbstractJMSMessage.java b/client/src/org/apache/qpid/client/message/AbstractJMSMessage.java deleted file mode 100644 index 5d0a30f949..0000000000 --- a/client/src/org/apache/qpid/client/message/AbstractJMSMessage.java +++ /dev/null @@ -1,680 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.message; - -import org.apache.commons.collections.map.ReferenceMap; -import org.apache.mina.common.ByteBuffer; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.AMQDestination; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.client.JmsNotImplementedException; -import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.framing.FieldTableKeyEnumeration; - -import javax.jms.Destination; -import javax.jms.JMSException; -import java.util.Collections; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.Map; - -public abstract class AbstractJMSMessage extends AMQMessage implements javax.jms.Message -{ - private static final Map _destinationCache = Collections.synchronizedMap(new ReferenceMap()); - -// protected Map _messageProperties; - - public static final char BOOLEAN_PROPERTY_PREFIX = 'B'; - public static final char BYTE_PROPERTY_PREFIX = 'b'; - public static final char SHORT_PROPERTY_PREFIX = 's'; - public static final char INT_PROPERTY_PREFIX = 'i'; - public static final char LONG_PROPERTY_PREFIX = 'l'; - public static final char FLOAT_PROPERTY_PREFIX = 'f'; - public static final char DOUBLE_PROPERTY_PREFIX = 'd'; - public static final char STRING_PROPERTY_PREFIX = 'S'; - - protected boolean _redelivered; - - protected ByteBuffer _data; - - protected AbstractJMSMessage(ByteBuffer data) - { - super(new BasicContentHeaderProperties()); - _data = data; - if (_data != null) - { - _data.acquire(); - } - } - - protected AbstractJMSMessage(long deliveryTag, BasicContentHeaderProperties contentHeader, ByteBuffer data) throws AMQException - { - this(contentHeader, deliveryTag); - _data = data; - if (_data != null) - { - _data.acquire(); - } - } - - protected AbstractJMSMessage(BasicContentHeaderProperties contentHeader, long deliveryTag) - { - super(contentHeader, deliveryTag); - } - - public String getJMSMessageID() throws JMSException - { - if (getJmsContentHeaderProperties().getMessageId() == null) - { - getJmsContentHeaderProperties().setMessageId("ID:" + _deliveryTag); - } - return getJmsContentHeaderProperties().getMessageId(); - } - - public void setJMSMessageID(String messageId) throws JMSException - { - getJmsContentHeaderProperties().setMessageId(messageId); - } - - public long getJMSTimestamp() throws JMSException - { - return new Long(getJmsContentHeaderProperties().getTimestamp()).longValue(); - } - - public void setJMSTimestamp(long timestamp) throws JMSException - { - getJmsContentHeaderProperties().setTimestamp(timestamp); - } - - public byte[] getJMSCorrelationIDAsBytes() throws JMSException - { - return getJmsContentHeaderProperties().getCorrelationId().getBytes(); - } - - public void setJMSCorrelationIDAsBytes(byte[] bytes) throws JMSException - { - getJmsContentHeaderProperties().setCorrelationId(new String(bytes)); - } - - public void setJMSCorrelationID(String correlationId) throws JMSException - { - getJmsContentHeaderProperties().setCorrelationId(correlationId); - } - - public String getJMSCorrelationID() throws JMSException - { - return getJmsContentHeaderProperties().getCorrelationId(); - } - - public Destination getJMSReplyTo() throws JMSException - { - String replyToEncoding = getJmsContentHeaderProperties().getReplyTo(); - if (replyToEncoding == null) - { - return null; - } - else - { - Destination dest = (Destination) _destinationCache.get(replyToEncoding); - if (dest == null) - { - char destType = replyToEncoding.charAt(0); - if (destType == 'Q') - { - dest = new AMQQueue(replyToEncoding.substring(1)); - } - else if (destType == 'T') - { - dest = new AMQTopic(replyToEncoding.substring(1)); - } - else - { - throw new JMSException("Illegal value in JMS_ReplyTo property: " + replyToEncoding); - } - _destinationCache.put(replyToEncoding, dest); - } - return dest; - } - } - - public void setJMSReplyTo(Destination destination) throws JMSException - { - if (destination == null) - { - throw new IllegalArgumentException("Null destination not allowed"); - } - if (!(destination instanceof AMQDestination)) - { - throw new IllegalArgumentException("ReplyTo destination my be an AMQ destination - passed argument was type " + - destination.getClass()); - } - final AMQDestination amqd = (AMQDestination) destination; - - final String encodedDestination = amqd.getEncodedName(); - _destinationCache.put(encodedDestination, destination); - getJmsContentHeaderProperties().setReplyTo(encodedDestination); - } - - public Destination getJMSDestination() throws JMSException - { - // TODO: implement this once we have sorted out how to figure out the exchange class - throw new JmsNotImplementedException(); - } - - public void setJMSDestination(Destination destination) throws JMSException - { - throw new JmsNotImplementedException(); - } - - public int getJMSDeliveryMode() throws JMSException - { - return getJmsContentHeaderProperties().getDeliveryMode(); - } - - public void setJMSDeliveryMode(int i) throws JMSException - { - getJmsContentHeaderProperties().setDeliveryMode((byte) i); - } - - public boolean getJMSRedelivered() throws JMSException - { - return _redelivered; - } - - public void setJMSRedelivered(boolean b) throws JMSException - { - _redelivered = b; - } - - public String getJMSType() throws JMSException - { - return getMimeType(); - } - - public void setJMSType(String string) throws JMSException - { - throw new JMSException("Cannot set JMS Type - it is implicitly defined based on message type"); - } - - public long getJMSExpiration() throws JMSException - { - return new Long(getJmsContentHeaderProperties().getExpiration()).longValue(); - } - - public void setJMSExpiration(long l) throws JMSException - { - getJmsContentHeaderProperties().setExpiration(l); - } - - public int getJMSPriority() throws JMSException - { - return getJmsContentHeaderProperties().getPriority(); - } - - public void setJMSPriority(int i) throws JMSException - { - getJmsContentHeaderProperties().setPriority((byte) i); - } - - public void clearProperties() throws JMSException - { - if (getJmsContentHeaderProperties().getHeaders() != null) - { - getJmsContentHeaderProperties().getHeaders().clear(); - } - } - - public boolean propertyExists(String propertyName) throws JMSException - { - checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) - { - return false; - } - else - { - // TODO: fix this - return getJmsContentHeaderProperties().getHeaders().containsKey(STRING_PROPERTY_PREFIX + propertyName); - } - } - - public boolean getBooleanProperty(String propertyName) throws JMSException - { - checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) - { - return Boolean.valueOf(null).booleanValue(); - } - else - { - // store as integer as temporary workaround - //Boolean b = (Boolean) getJmsContentHeaderProperties().headers.get(BOOLEAN_PROPERTY_PREFIX + propertyName); - Long b = (Long) getJmsContentHeaderProperties().getHeaders().get(BOOLEAN_PROPERTY_PREFIX + propertyName); - - if (b == null) - { - return Boolean.valueOf(null).booleanValue(); - } - else - { - return b.longValue() != 0; - } - } - } - - public byte getByteProperty(String propertyName) throws JMSException - { - checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) - { - return Byte.valueOf(null).byteValue(); - } - else - { - Byte b = (Byte) getJmsContentHeaderProperties().getHeaders().get(BYTE_PROPERTY_PREFIX + propertyName); - if (b == null) - { - return Byte.valueOf(null).byteValue(); - } - else - { - return b.byteValue(); - } - } - } - - public short getShortProperty(String propertyName) throws JMSException - { - checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) - { - return Short.valueOf(null).shortValue(); - } - else - { - Short s = (Short) getJmsContentHeaderProperties().getHeaders().get(SHORT_PROPERTY_PREFIX + propertyName); - if (s == null) - { - return Short.valueOf(null).shortValue(); - } - else - { - return s.shortValue(); - } - } - } - - public int getIntProperty(String propertyName) throws JMSException - { - checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) - { - return Integer.valueOf(null).intValue(); - } - else - { - Integer i = (Integer) getJmsContentHeaderProperties().getHeaders().get(INT_PROPERTY_PREFIX + propertyName); - if (i == null) - { - return Integer.valueOf(null).intValue(); - } - else - { - return i.intValue(); - } - } - } - - public long getLongProperty(String propertyName) throws JMSException - { - checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) - { - return Long.valueOf(null).longValue(); - } - else - { - Long l = (Long) getJmsContentHeaderProperties().getHeaders().get(LONG_PROPERTY_PREFIX + propertyName); - if (l == null) - { - // temp - the spec says do this but this throws a NumberFormatException - //return Long.valueOf(null).longValue(); - return 0; - } - else - { - return l.longValue(); - } - } - } - - public float getFloatProperty(String propertyName) throws JMSException - { - checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) - { - return Float.valueOf(null).floatValue(); - } - else - { - final Float f = (Float) getJmsContentHeaderProperties().getHeaders().get(FLOAT_PROPERTY_PREFIX + propertyName); - if (f == null) - { - return Float.valueOf(null).floatValue(); - } - else - { - return f.floatValue(); - } - } - } - - public double getDoubleProperty(String propertyName) throws JMSException - { - checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) - { - return Double.valueOf(null).doubleValue(); - } - else - { - final Double d = (Double) getJmsContentHeaderProperties().getHeaders().get(DOUBLE_PROPERTY_PREFIX + propertyName); - if (d == null) - { - return Double.valueOf(null).doubleValue(); - } - else - { - return d.shortValue(); - } - } - } - - public String getStringProperty(String propertyName) throws JMSException - { - checkPropertyName(propertyName); - if (getJmsContentHeaderProperties().getHeaders() == null) - { - return null; - } - else - { - return (String) getJmsContentHeaderProperties().getHeaders().get(STRING_PROPERTY_PREFIX + propertyName); - } - } - - public Object getObjectProperty(String propertyName) throws JMSException - { - checkPropertyName(propertyName); - throw new JmsNotImplementedException(); - } - - public Enumeration getPropertyNames() throws JMSException - { - return new FieldTableKeyEnumeration(getJmsContentHeaderProperties().getHeaders()) - { - public Object nextElement() - { - String propName = (String) _iterator.next(); - - //The propertyName has a single Char prefix. Skip this. - return propName.substring(1); - } - }; - } - - public void setBooleanProperty(String propertyName, boolean b) throws JMSException - { - checkPropertyName(propertyName); - //getJmsContentHeaderProperties().headers.put(BOOLEAN_PROPERTY_PREFIX + propertyName, Boolean.valueOf(b)); - getJmsContentHeaderProperties().getHeaders().put(BOOLEAN_PROPERTY_PREFIX + propertyName, b ? new Long(1) : new Long(0)); - } - - public void setByteProperty(String propertyName, byte b) throws JMSException - { - checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().put(BYTE_PROPERTY_PREFIX + propertyName, new Byte(b)); - } - - public void setShortProperty(String propertyName, short i) throws JMSException - { - checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().put(SHORT_PROPERTY_PREFIX + propertyName, new Short(i)); - } - - public void setIntProperty(String propertyName, int i) throws JMSException - { - checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().put(INT_PROPERTY_PREFIX + propertyName, new Integer(i)); - } - - public void setLongProperty(String propertyName, long l) throws JMSException - { - checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().put(LONG_PROPERTY_PREFIX + propertyName, new Long(l)); - } - - public void setFloatProperty(String propertyName, float f) throws JMSException - { - checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().put(FLOAT_PROPERTY_PREFIX + propertyName, new Float(f)); - } - - public void setDoubleProperty(String propertyName, double v) throws JMSException - { - checkPropertyName(propertyName); - getJmsContentHeaderProperties().getHeaders().put(DOUBLE_PROPERTY_PREFIX + propertyName, new Double(v)); - } - - public void setStringProperty(String propertyName, String value) throws JMSException - { - checkPropertyName(propertyName); - createPropertyMapIfRequired(); - propertyName = STRING_PROPERTY_PREFIX + propertyName; - getJmsContentHeaderProperties().getHeaders().put(propertyName, value); - } - - private void createPropertyMapIfRequired() - { - if (getJmsContentHeaderProperties().getHeaders() == null) - { - getJmsContentHeaderProperties().setHeaders(new FieldTable()); - } - } - - public void setObjectProperty(String string, Object object) throws JMSException - { - //To change body of implemented methods use File | Settings | File Templates. - } - - public void acknowledge() throws JMSException - { - // the JMS 1.1 spec says in section 3.6 that calls to acknowledge are ignored when client acknowledge - // is not specified. In our case, we only set the session field where client acknowledge mode is specified. - if (_session != null) - { - // we set multiple to true here since acknowledgement implies acknowledge of all previous messages - // received on the session - _session.acknowledgeMessage(_deliveryTag, true); - } - } - - public abstract void clearBody() throws JMSException; - - /** - * Get a String representation of the body of the message. Used in the - * toString() method which outputs this before message properties. - */ - public abstract String toBodyString() throws JMSException; - - public abstract String getMimeType(); - - public String toString() - { - try - { - StringBuffer buf = new StringBuffer("Body:\n"); - buf.append(toBodyString()); - buf.append("\nJMS timestamp: ").append(getJMSTimestamp()); - buf.append("\nJMS expiration: ").append(getJMSExpiration()); - buf.append("\nJMS priority: ").append(getJMSPriority()); - buf.append("\nJMS delivery mode: ").append(getJMSDeliveryMode()); - buf.append("\nJMS reply to: ").append(String.valueOf(getJMSReplyTo())); - buf.append("\nAMQ message number: ").append(_deliveryTag); - buf.append("\nProperties:"); - if (getJmsContentHeaderProperties().getHeaders() == null) - { - buf.append("<NONE>"); - } - else - { - final Iterator it = getJmsContentHeaderProperties().getHeaders().entrySet().iterator(); - while (it.hasNext()) - { - final Map.Entry entry = (Map.Entry) it.next(); - final String propertyName = (String) entry.getKey(); - if (propertyName == null) - { - buf.append("\nInternal error: Property with NULL key defined"); - } - else - { - buf.append('\n').append(propertyName.substring(1)); - - char typeIdentifier = propertyName.charAt(0); - switch (typeIdentifier) - { - case org.apache.qpid.client.message.AbstractJMSMessage.BOOLEAN_PROPERTY_PREFIX: - buf.append("<boolean> "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.BYTE_PROPERTY_PREFIX: - buf.append("<byte> "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.SHORT_PROPERTY_PREFIX: - buf.append("<short> "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.INT_PROPERTY_PREFIX: - buf.append("<int> "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.LONG_PROPERTY_PREFIX: - buf.append("<long> "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.FLOAT_PROPERTY_PREFIX: - buf.append("<float> "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.DOUBLE_PROPERTY_PREFIX: - buf.append("<double> "); - break; - case org.apache.qpid.client.message.AbstractJMSMessage.STRING_PROPERTY_PREFIX: - buf.append("<string> "); - break; - default: - buf.append("<unknown type (identifier " + - typeIdentifier + ") "); - } - buf.append(String.valueOf(entry.getValue())); - } - } - } - return buf.toString(); - } - catch (JMSException e) - { - return e.toString(); - } - } - - public Map getUnderlyingMessagePropertiesMap() - { - return getJmsContentHeaderProperties().getHeaders(); - } - - public void setUnderlyingMessagePropertiesMap(FieldTable messageProperties) - { - getJmsContentHeaderProperties().setHeaders(messageProperties); - } - - private void checkPropertyName(String propertyName) - { - if (propertyName == null) - { - throw new IllegalArgumentException("Property name must not be null"); - } - else if ("".equals(propertyName)) - { - throw new IllegalArgumentException("Property name must not be the empty string"); - } - - if (getJmsContentHeaderProperties().getHeaders() == null) - { - getJmsContentHeaderProperties().setHeaders(new FieldTable()); - } - } - - public FieldTable populateHeadersFromMessageProperties() - { - if (getJmsContentHeaderProperties().getHeaders() == null) - { - return null; - } - else - { - // - // We need to convert every property into a String representation - // Note that type information is preserved in the property name - // - final FieldTable table = new FieldTable(); - final Iterator entries = getJmsContentHeaderProperties().getHeaders().entrySet().iterator(); - while (entries.hasNext()) - { - final Map.Entry entry = (Map.Entry) entries.next(); - final String propertyName = (String) entry.getKey(); - if (propertyName == null) - { - continue; - } - else - { - table.put(propertyName, entry.getValue().toString()); - } - } - return table; - } - } - - public BasicContentHeaderProperties getJmsContentHeaderProperties() - { - return (BasicContentHeaderProperties) _contentHeaderProperties; - } - - public ByteBuffer getData() - { - // make sure we rewind the data just in case any method has moved the - // position beyond the start - if (_data != null) - { - _data.rewind(); - } - return _data; - } -} diff --git a/client/src/org/apache/qpid/client/message/AbstractJMSMessageFactory.java b/client/src/org/apache/qpid/client/message/AbstractJMSMessageFactory.java deleted file mode 100644 index dcff8c348b..0000000000 --- a/client/src/org/apache/qpid/client/message/AbstractJMSMessageFactory.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.message; - -import org.apache.qpid.AMQException; -import org.apache.qpid.framing.ContentBody; -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.log4j.Logger; -import org.apache.mina.common.ByteBuffer; - -import javax.jms.JMSException; -import java.util.Iterator; -import java.util.List; - -public abstract class AbstractJMSMessageFactory implements MessageFactory -{ - private static final Logger _logger = Logger.getLogger(AbstractJMSMessageFactory.class); - - - protected abstract AbstractJMSMessage createMessage(long messageNbr, ByteBuffer data, - ContentHeaderBody contentHeader) throws AMQException; - - protected AbstractJMSMessage createMessageWithBody(long messageNbr, - ContentHeaderBody contentHeader, - List bodies) throws AMQException - { - ByteBuffer data; - - // we optimise the non-fragmented case to avoid copying - if (bodies != null && bodies.size() == 1) - { - _logger.debug("Non-fragmented message body (bodySize=" + contentHeader.bodySize +")"); - data = ((ContentBody)bodies.get(0)).payload; - } - else - { - _logger.debug("Fragmented message body (" + bodies.size() + " frames, bodySize=" + contentHeader.bodySize + ")"); - data = ByteBuffer.allocate((int)contentHeader.bodySize); // XXX: Is cast a problem? - final Iterator it = bodies.iterator(); - while (it.hasNext()) - { - ContentBody cb = (ContentBody) it.next(); - data.put(cb.payload); - cb.payload.release(); - } - data.flip(); - } - _logger.debug("Creating message from buffer with position=" + data.position() + " and remaining=" + data.remaining()); - - return createMessage(messageNbr, data, contentHeader); - } - - public AbstractJMSMessage createMessage(long messageNbr, boolean redelivered, - ContentHeaderBody contentHeader, - List bodies) throws JMSException, AMQException - { - final AbstractJMSMessage msg = createMessageWithBody(messageNbr, contentHeader, bodies); - msg.setJMSRedelivered(redelivered); - return msg; - } - -} diff --git a/client/src/org/apache/qpid/client/message/JMSBytesMessage.java b/client/src/org/apache/qpid/client/message/JMSBytesMessage.java deleted file mode 100644 index df593cbd70..0000000000 --- a/client/src/org/apache/qpid/client/message/JMSBytesMessage.java +++ /dev/null @@ -1,400 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.message; - -import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.AMQException; -import org.apache.mina.common.ByteBuffer; - -import javax.jms.JMSException; -import javax.jms.MessageNotReadableException; -import javax.jms.MessageNotWriteableException; -import javax.jms.MessageEOFException; -import java.io.*; -import java.nio.charset.Charset; -import java.nio.charset.CharacterCodingException; - -public class JMSBytesMessage extends AbstractJMSMessage implements javax.jms.BytesMessage -{ - private static final String MIME_TYPE = "application/octet-stream"; - - private boolean _readable = false; - - /** - * The default initial size of the buffer. The buffer expands automatically. - */ - private static final int DEFAULT_BUFFER_INITIAL_SIZE = 1024; - - JMSBytesMessage() - { - this(null); - } - - /** - * Construct a bytes message with existing data. - * @param data the data that comprises this message. If data is null, you get a 1024 byte buffer that is - * set to auto expand - */ - JMSBytesMessage(ByteBuffer data) - { - super(data); // this instanties a content header - getJmsContentHeaderProperties().setContentType(MIME_TYPE); - - if (_data == null) - { - _data = ByteBuffer.allocate(DEFAULT_BUFFER_INITIAL_SIZE); - _data.setAutoExpand(true); - } - _readable = (data != null); - } - - JMSBytesMessage(long messageNbr, ByteBuffer data, ContentHeaderBody contentHeader) - throws AMQException - { - // TODO: this casting is ugly. Need to review whole ContentHeaderBody idea - super(messageNbr, (BasicContentHeaderProperties) contentHeader.properties, data); - getJmsContentHeaderProperties().setContentType(MIME_TYPE); - _readable = true; - } - - public void clearBody() throws JMSException - { - _data.clear(); - _readable = false; - } - - public String toBodyString() throws JMSException - { - checkReadable(); - try - { - return getText(); - } - catch (IOException e) - { - throw new JMSException(e.toString()); - } - } - - /** - * We reset the stream before and after reading the data. This means that toString() will always output - * the entire message and also that the caller can then immediately start reading as if toString() had - * never been called. - * @return - * @throws IOException - */ - private String getText() throws IOException - { - // this will use the default platform encoding - if (_data == null) - { - return null; - } - int pos = _data.position(); - _data.rewind(); - // one byte left is for the end of frame marker - if (_data.remaining() == 0) - { - // this is really redundant since pos must be zero - _data.position(pos); - return null; - } - else - { - String data = _data.getString(Charset.forName("UTF8").newDecoder()); - _data.position(pos); - return data; - } - } - - public String getMimeType() - { - return MIME_TYPE; - } - - public long getBodyLength() throws JMSException - { - checkReadable(); - return _data.limit(); - } - - private void checkReadable() throws MessageNotReadableException - { - if (!_readable) - { - throw new MessageNotReadableException("You need to call reset() to make the message readable"); - } - } - - /** - * Check that there is at least a certain number of bytes available to read - * @param len the number of bytes - * @throws MessageEOFException if there are less than len bytes available to read - */ - private void checkAvailable(int len) throws MessageEOFException - { - if (_data.remaining() < len) - { - throw new MessageEOFException("Unable to read " + len + " bytes"); - } - } - - private void checkWritable() throws MessageNotWriteableException - { - if (_readable) - { - throw new MessageNotWriteableException("You need to call clearBody() to make the message writable"); - } - } - - public boolean readBoolean() throws JMSException - { - checkReadable(); - checkAvailable(1); - return _data.get() != 0; - } - - public byte readByte() throws JMSException - { - checkReadable(); - checkAvailable(1); - return _data.get(); - } - - public int readUnsignedByte() throws JMSException - { - checkReadable(); - checkAvailable(1); - return _data.getUnsigned(); - } - - public short readShort() throws JMSException - { - checkReadable(); - checkAvailable(2); - return _data.getShort(); - } - - public int readUnsignedShort() throws JMSException - { - checkReadable(); - checkAvailable(2); - return _data.getUnsignedShort(); - } - - /** - * Note that this method reads a unicode character as two bytes from the stream - * @return the character read from the stream - * @throws JMSException - */ - public char readChar() throws JMSException - { - checkReadable(); - checkAvailable(2); - return _data.getChar(); - } - - public int readInt() throws JMSException - { - checkReadable(); - checkAvailable(4); - return _data.getInt(); - } - - public long readLong() throws JMSException - { - checkReadable(); - checkAvailable(8); - return _data.getLong(); - } - - public float readFloat() throws JMSException - { - checkReadable(); - checkAvailable(4); - return _data.getFloat(); - } - - public double readDouble() throws JMSException - { - checkReadable(); - checkAvailable(8); - return _data.getDouble(); - } - - public String readUTF() throws JMSException - { - checkReadable(); - // we check only for one byte since theoretically the string could be only a - // single byte when using UTF-8 encoding - checkAvailable(1); - try - { - return _data.getString(Charset.forName("UTF-8").newDecoder()); - } - catch (CharacterCodingException e) - { - JMSException je = new JMSException("Error decoding byte stream as a UTF8 string: " + e); - je.setLinkedException(e); - throw je; - } - } - - public int readBytes(byte[] bytes) throws JMSException - { - if (bytes == null) - { - throw new IllegalArgumentException("byte array must not be null"); - } - checkReadable(); - int count = (_data.remaining() >= bytes.length ? bytes.length : _data.remaining()); - if (count == 0) - { - return -1; - } - else - { - _data.get(bytes, 0, count); - return count; - } - } - - public int readBytes(byte[] bytes, int maxLength) throws JMSException - { - if (bytes == null) - { - throw new IllegalArgumentException("byte array must not be null"); - } - if (maxLength > bytes.length) - { - throw new IllegalArgumentException("maxLength must be <= bytes.length"); - } - checkReadable(); - int count = (_data.remaining() >= maxLength ? maxLength : _data.remaining()); - if (count == 0) - { - return -1; - } - else - { - _data.get(bytes, 0, count); - return count; - } - } - - public void writeBoolean(boolean b) throws JMSException - { - checkWritable(); - _data.put(b?(byte)1:(byte)0); - } - - public void writeByte(byte b) throws JMSException - { - checkWritable(); - _data.put(b); - } - - public void writeShort(short i) throws JMSException - { - checkWritable(); - _data.putShort(i); - } - - public void writeChar(char c) throws JMSException - { - checkWritable(); - _data.putChar(c); - } - - public void writeInt(int i) throws JMSException - { - checkWritable(); - _data.putInt(i); - } - - public void writeLong(long l) throws JMSException - { - checkWritable(); - _data.putLong(l); - } - - public void writeFloat(float v) throws JMSException - { - checkWritable(); - _data.putFloat(v); - } - - public void writeDouble(double v) throws JMSException - { - checkWritable(); - _data.putDouble(v); - } - - public void writeUTF(String string) throws JMSException - { - checkWritable(); - try - { - _data.putString(string, Charset.forName("UTF-8").newEncoder()); - } - catch (CharacterCodingException e) - { - JMSException ex = new JMSException("Unable to encode string: " + e); - ex.setLinkedException(e); - throw ex; - } - } - - public void writeBytes(byte[] bytes) throws JMSException - { - checkWritable(); - _data.put(bytes); - } - - public void writeBytes(byte[] bytes, int offset, int length) throws JMSException - { - checkWritable(); - _data.put(bytes, offset, length); - } - - public void writeObject(Object object) throws JMSException - { - checkWritable(); - if (object == null) - { - throw new NullPointerException("Argument must not be null"); - } - _data.putObject(object); - } - - public void reset() throws JMSException - { - //checkWritable(); - _data.flip(); - _readable = true; - } - - public boolean isReadable() - { - return _readable; - } -} diff --git a/client/src/org/apache/qpid/client/message/JMSBytesMessageFactory.java b/client/src/org/apache/qpid/client/message/JMSBytesMessageFactory.java deleted file mode 100644 index 6baf5326e5..0000000000 --- a/client/src/org/apache/qpid/client/message/JMSBytesMessageFactory.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.message; - -import org.apache.mina.common.ByteBuffer; -import org.apache.qpid.AMQException; -import org.apache.qpid.framing.ContentHeaderBody; - -import javax.jms.JMSException; - -public class JMSBytesMessageFactory extends AbstractJMSMessageFactory -{ - protected AbstractJMSMessage createMessage(long deliveryTag, ByteBuffer data, ContentHeaderBody contentHeader) throws AMQException - { - return new JMSBytesMessage(deliveryTag, data, contentHeader); - } - - public AbstractJMSMessage createMessage() throws JMSException - { - return new JMSBytesMessage(); - } -} diff --git a/client/src/org/apache/qpid/client/message/JMSObjectMessage.java b/client/src/org/apache/qpid/client/message/JMSObjectMessage.java deleted file mode 100644 index 3c0d9b99c4..0000000000 --- a/client/src/org/apache/qpid/client/message/JMSObjectMessage.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.message; - -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.AMQException; -import org.apache.mina.common.ByteBuffer; - -import javax.jms.ObjectMessage; -import javax.jms.JMSException; -import javax.jms.MessageFormatException; -import javax.jms.MessageNotWriteableException; -import java.io.*; -import java.nio.charset.Charset; -import java.nio.charset.CharacterCodingException; - -public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessage -{ - static final String MIME_TYPE = "application/java-object-stream"; - private final boolean _readonly; - - private static final int DEFAULT_BUFFER_SIZE = 1024; - /** - * Creates empty, writable message for use by producers - */ - JMSObjectMessage() - { - this(null); - } - - private JMSObjectMessage(ByteBuffer data) - { - super(data); - if (data == null) - { - _data = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE); - _data.setAutoExpand(true); - } - _readonly = (data != null); - getJmsContentHeaderProperties().setContentType(MIME_TYPE); - } - - /** - * Creates read only message for delivery to consumers - */ - JMSObjectMessage(long messageNbr, ByteBuffer data, ContentHeaderBody contentHeader) throws AMQException - { - super(messageNbr, (BasicContentHeaderProperties) contentHeader.properties, data); - _readonly = data != null; - } - - public void clearBody() throws JMSException - { - if (_data != null) - { - _data.release(); - } - _data = null; - } - - public String toBodyString() throws JMSException - { - return toString(_data); - } - - public String getMimeType() - { - return MIME_TYPE; - } - - public void setObject(Serializable serializable) throws JMSException - { - if (_readonly) - { - throw new MessageNotWriteableException("Message is not writable."); - } - - if (_data == null) - { - _data = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE); - _data.setAutoExpand(true); - } - try - { - ObjectOutputStream out = new ObjectOutputStream(_data.asOutputStream()); - out.writeObject(serializable); - out.flush(); - out.close(); - _data.rewind(); - } - catch (IOException e) - { - throw new MessageFormatException("Message not serializable: " + e); - } - } - - public Serializable getObject() throws JMSException - { - ObjectInputStream in = null; - if (_data == null) - { - return null; - } - - try - { - in = new ObjectInputStream(_data.asInputStream()); - return (Serializable) in.readObject(); - } - catch (IOException e) - { - throw new MessageFormatException("Could not deserialize message: " + e); - } - catch (ClassNotFoundException e) - { - throw new MessageFormatException("Could not deserialize message: " + e); - } - finally - { - _data.rewind(); - close(in); - } - } - - private static void close(InputStream in) - { - try - { - if (in != null) - { - in.close(); - } - } - catch (IOException ignore) - { - } - } - - private static String toString(ByteBuffer data) - { - if (data == null) - { - return null; - } - int pos = data.position(); - try - { - return data.getString(Charset.forName("UTF8").newDecoder()); - } - catch (CharacterCodingException e) - { - return null; - } - finally - { - data.position(pos); - } - } -} diff --git a/client/src/org/apache/qpid/client/message/JMSObjectMessageFactory.java b/client/src/org/apache/qpid/client/message/JMSObjectMessageFactory.java deleted file mode 100644 index 9d4a11650d..0000000000 --- a/client/src/org/apache/qpid/client/message/JMSObjectMessageFactory.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.message; - -import org.apache.mina.common.ByteBuffer; -import org.apache.qpid.AMQException; -import org.apache.qpid.framing.ContentHeaderBody; - -import javax.jms.JMSException; - -public class JMSObjectMessageFactory extends AbstractJMSMessageFactory -{ - protected AbstractJMSMessage createMessage(long deliveryTag, ByteBuffer data, ContentHeaderBody contentHeader) throws AMQException - { - return new JMSObjectMessage(deliveryTag, data, contentHeader); - } - - public AbstractJMSMessage createMessage() throws JMSException - { - return new JMSObjectMessage(); - } -} diff --git a/client/src/org/apache/qpid/client/message/JMSTextMessage.java b/client/src/org/apache/qpid/client/message/JMSTextMessage.java deleted file mode 100644 index 4983f6b623..0000000000 --- a/client/src/org/apache/qpid/client/message/JMSTextMessage.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.message; - -import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.AMQException; -import org.apache.mina.common.ByteBuffer; - -import javax.jms.JMSException; -import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; -import java.nio.charset.CharacterCodingException; - -public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.TextMessage -{ - private static final String MIME_TYPE = "text/plain"; - - private String _decodedValue; - - JMSTextMessage() throws JMSException - { - this(null, null); - } - - JMSTextMessage(ByteBuffer data, String encoding) throws JMSException - { - super(data); // this instantiates a content header - getJmsContentHeaderProperties().setContentType(MIME_TYPE); - getJmsContentHeaderProperties().setEncoding(encoding); - } - - JMSTextMessage(long deliveryTag, ByteBuffer data, BasicContentHeaderProperties contentHeader) - throws AMQException - { - super(deliveryTag, contentHeader, data); - contentHeader.setContentType(MIME_TYPE); - _data = data; - } - - JMSTextMessage(ByteBuffer data) throws JMSException - { - this(data, null); - } - - JMSTextMessage(String text) throws JMSException - { - super((ByteBuffer)null); - setText(text); - } - - public void clearBody() throws JMSException - { - if (_data != null) - { - _data.release(); - } - _data = null; - _decodedValue = null; - } - - public String toBodyString() throws JMSException - { - return getText(); - } - - public void setData(ByteBuffer data) - { - _data = data; - } - - public String getMimeType() - { - return MIME_TYPE; - } - - public void setText(String string) throws JMSException - { - clearBody(); - try - { - _data = ByteBuffer.allocate(string.length()); - _data.limit(string.length()); - //_data.sweep(); - _data.setAutoExpand(true); - if (getJmsContentHeaderProperties().getEncoding() == null) - { - _data.put(string.getBytes()); - } - else - { - _data.put(string.getBytes(getJmsContentHeaderProperties().getEncoding())); - } - _decodedValue = string; - } - catch (UnsupportedEncodingException e) - { - // should never occur - throw new JMSException("Unable to decode string data"); - } - } - - public String getText() throws JMSException - { - if (_data == null && _decodedValue == null) - { - return null; - } - else if (_decodedValue != null) - { - return _decodedValue; - } - else - { - _data.rewind(); - if (getJmsContentHeaderProperties().getEncoding() != null) - { - try - { - _decodedValue = _data.getString(Charset.forName(getJmsContentHeaderProperties().getEncoding()).newDecoder()); - } - catch (CharacterCodingException e) - { - JMSException je = new JMSException("Could not decode string data: " + e); - je.setLinkedException(e); - throw je; - } - } - else - { - try - { - _decodedValue = _data.getString(Charset.defaultCharset().newDecoder()); - } - catch (CharacterCodingException e) - { - JMSException je = new JMSException("Could not decode string data: " + e); - je.setLinkedException(e); - throw je; - } - } - return _decodedValue; - } - } -} diff --git a/client/src/org/apache/qpid/client/message/JMSTextMessageFactory.java b/client/src/org/apache/qpid/client/message/JMSTextMessageFactory.java deleted file mode 100644 index d554794fdd..0000000000 --- a/client/src/org/apache/qpid/client/message/JMSTextMessageFactory.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.message; - -import org.apache.mina.common.ByteBuffer; -import org.apache.qpid.AMQException; -import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.framing.ContentHeaderBody; - -import javax.jms.JMSException; - -public class JMSTextMessageFactory extends AbstractJMSMessageFactory -{ - - public AbstractJMSMessage createMessage() throws JMSException - { - return new JMSTextMessage(); - } - - protected AbstractJMSMessage createMessage(long deliveryTag, ByteBuffer data, ContentHeaderBody contentHeader) throws AMQException - { - return new JMSTextMessage(deliveryTag, data, (BasicContentHeaderProperties)contentHeader.properties); - } -} diff --git a/client/src/org/apache/qpid/client/message/MessageFactory.java b/client/src/org/apache/qpid/client/message/MessageFactory.java deleted file mode 100644 index 1fb178a1a4..0000000000 --- a/client/src/org/apache/qpid/client/message/MessageFactory.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.message; - -import org.apache.qpid.AMQException; -import org.apache.qpid.framing.ContentHeaderBody; - -import javax.jms.JMSException; -import java.util.List; - - -public interface MessageFactory -{ - AbstractJMSMessage createMessage(long deliveryTag, boolean redelivered, - ContentHeaderBody contentHeader, - List bodies) - throws JMSException, AMQException; - - AbstractJMSMessage createMessage() throws JMSException; -} diff --git a/client/src/org/apache/qpid/client/message/MessageFactoryRegistry.java b/client/src/org/apache/qpid/client/message/MessageFactoryRegistry.java deleted file mode 100644 index e6709adb0d..0000000000 --- a/client/src/org/apache/qpid/client/message/MessageFactoryRegistry.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.message; - -import org.apache.qpid.AMQException; -import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.framing.ContentHeaderBody; - -import javax.jms.JMSException; -import java.util.HashMap; -import java.util.Map; -import java.util.List; - -public class MessageFactoryRegistry -{ - private final Map _mimeToFactoryMap = new HashMap(); - - public void registerFactory(String mimeType, MessageFactory mf) - { - if (mf == null) - { - throw new IllegalArgumentException("Message factory must not be null"); - } - _mimeToFactoryMap.put(mimeType, mf); - } - - public MessageFactory deregisterFactory(String mimeType) - { - return (MessageFactory) _mimeToFactoryMap.remove(mimeType); - } - - /** - * Create a message. This looks up the MIME type from the content header and instantiates the appropriate - * concrete message type. - * @param deliveryTag the AMQ message id - * @param redelivered true if redelivered - * @param contentHeader the content header that was received - * @param bodies a list of ContentBody instances - * @return the message. - * @throws AMQException - * @throws JMSException - */ - public AbstractJMSMessage createMessage(long deliveryTag, boolean redelivered, - ContentHeaderBody contentHeader, - List bodies) throws AMQException, JMSException - { - BasicContentHeaderProperties properties = (BasicContentHeaderProperties) contentHeader.properties; - MessageFactory mf = (MessageFactory) _mimeToFactoryMap.get(properties.getContentType()); - if (mf == null) - { - throw new AMQException("Unsupport MIME type of " + properties.getContentType()); - } - else - { - return mf.createMessage(deliveryTag, redelivered, contentHeader, bodies); - } - } - - public AbstractJMSMessage createMessage(String mimeType) throws AMQException, JMSException - { - if (mimeType == null) - { - throw new IllegalArgumentException("Mime type must not be null"); - } - MessageFactory mf = (MessageFactory) _mimeToFactoryMap.get(mimeType); - if (mf == null) - { - throw new AMQException("Unsupport MIME type of " + mimeType); - } - else - { - return mf.createMessage(); - } - } - - /** - * Construct a new registry with the default message factories registered - * @return a message factory registry - */ - public static MessageFactoryRegistry newDefaultRegistry() - { - MessageFactoryRegistry mf = new MessageFactoryRegistry(); - mf.registerFactory("text/plain", new JMSTextMessageFactory()); - mf.registerFactory("text/xml", new JMSTextMessageFactory()); - mf.registerFactory("application/octet-stream", new JMSBytesMessageFactory()); - mf.registerFactory(JMSObjectMessage.MIME_TYPE, new JMSObjectMessageFactory()); - mf.registerFactory(null, new JMSBytesMessageFactory()); - return mf; - } -} diff --git a/client/src/org/apache/qpid/client/message/UnexpectedBodyReceivedException.java b/client/src/org/apache/qpid/client/message/UnexpectedBodyReceivedException.java deleted file mode 100644 index 735ddc54e8..0000000000 --- a/client/src/org/apache/qpid/client/message/UnexpectedBodyReceivedException.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.message; - -import org.apache.qpid.AMQException; -import org.apache.log4j.Logger; - -public class UnexpectedBodyReceivedException extends AMQException -{ - - public UnexpectedBodyReceivedException(Logger logger, String msg, Throwable t) - { - super(logger, msg, t); - } - - public UnexpectedBodyReceivedException(Logger logger, String msg) - { - super(logger, msg); - } - - public UnexpectedBodyReceivedException(Logger logger, int errorCode, String msg) - { - super(logger, errorCode, msg); - } -} diff --git a/client/src/org/apache/qpid/client/message/UnprocessedMessage.java b/client/src/org/apache/qpid/client/message/UnprocessedMessage.java deleted file mode 100644 index 7d20c32b66..0000000000 --- a/client/src/org/apache/qpid/client/message/UnprocessedMessage.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.message; - -import org.apache.qpid.framing.*; - -import java.util.List; -import java.util.LinkedList; - -/** - * This class contains everything needed to process a JMS message. It assembles the - * deliver body, the content header and the content body/ies. - * - * Note that the actual work of creating a JMS message for the client code's use is done - * outside of the MINA dispatcher thread in order to minimise the amount of work done in - * the MINA dispatcher thread. - * - */ -public class UnprocessedMessage -{ - private long _bytesReceived = 0; - - public BasicDeliverBody deliverBody; - public BasicReturnBody bounceBody; // TODO: check change (gustavo) - public int channelId; - public ContentHeaderBody contentHeader; - - /** - * List of ContentBody instances. Due to fragmentation you don't know how big this will be in general - */ - public List bodies = new LinkedList(); - - public void receiveBody(ContentBody body) throws UnexpectedBodyReceivedException - { - bodies.add(body); - if (body.payload != null) - { - _bytesReceived += body.payload.remaining(); - } - } - - public boolean isAllBodyDataReceived() - { - return _bytesReceived == contentHeader.bodySize; - } -} diff --git a/client/src/org/apache/qpid/client/protocol/AMQMethodEvent.java b/client/src/org/apache/qpid/client/protocol/AMQMethodEvent.java deleted file mode 100644 index 403aa3486e..0000000000 --- a/client/src/org/apache/qpid/client/protocol/AMQMethodEvent.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.protocol; - -import org.apache.qpid.framing.AMQMethodBody; - -public class AMQMethodEvent -{ - private AMQMethodBody _method; - - private int _channelId; - - private AMQProtocolSession _protocolSession; - - public AMQMethodEvent(int channelId, AMQMethodBody method, AMQProtocolSession protocolSession) - { - _channelId = channelId; - _method = method; - _protocolSession = protocolSession; - } - - public AMQMethodBody getMethod() - { - return _method; - } - - public int getChannelId() - { - return _channelId; - } - - public AMQProtocolSession getProtocolSession() - { - return _protocolSession; - } - - public String toString() - { - StringBuffer buf = new StringBuffer("Method event: "); - buf.append("\nChannel id: ").append(_channelId); - buf.append("\nMethod: ").append(_method); - return buf.toString(); - } -} diff --git a/client/src/org/apache/qpid/client/protocol/AMQMethodListener.java b/client/src/org/apache/qpid/client/protocol/AMQMethodListener.java deleted file mode 100644 index 68299033a5..0000000000 --- a/client/src/org/apache/qpid/client/protocol/AMQMethodListener.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.protocol; - -import org.apache.qpid.AMQException; - -public interface AMQMethodListener -{ - /** - * Invoked when a method frame has been received - * @param evt the event - * @return true if the handler has processed the method frame, false otherwise. Note - * that this does not prohibit the method event being delivered to subsequent listeners - * but can be used to determine if nobody has dealt with an incoming method frame. - * @throws AMQException if an error has occurred. This exception will be delivered - * to all registered listeners using the error() method (see below) allowing them to - * perform cleanup if necessary. - */ - boolean methodReceived(AMQMethodEvent evt) throws AMQException; - - /** - * Callback when an error has occurred. Allows listeners to clean up. - * @param e - */ - void error(Exception e); -} diff --git a/client/src/org/apache/qpid/client/protocol/AMQProtocolHandler.java b/client/src/org/apache/qpid/client/protocol/AMQProtocolHandler.java deleted file mode 100644 index eab9084717..0000000000 --- a/client/src/org/apache/qpid/client/protocol/AMQProtocolHandler.java +++ /dev/null @@ -1,553 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.protocol; - -import org.apache.log4j.Logger; -import org.apache.mina.common.IdleStatus; -import org.apache.mina.common.IoHandlerAdapter; -import org.apache.mina.common.IoSession; -import org.apache.mina.filter.SSLFilter; -import org.apache.mina.filter.codec.ProtocolCodecFilter; -import org.apache.qpid.AMQConnectionClosedException; -import org.apache.qpid.AMQDisconnectedException; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.failover.FailoverHandler; -import org.apache.qpid.client.failover.FailoverState; -import org.apache.qpid.client.state.AMQState; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.listener.SpecificMethodFrameListener; -import org.apache.qpid.codec.AMQCodecFactory; -import org.apache.qpid.framing.AMQDataBlock; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.AMQMethodBody; -import org.apache.qpid.framing.ConnectionCloseBody; -import org.apache.qpid.framing.ConnectionCloseOkBody; -import org.apache.qpid.framing.ContentBody; -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.framing.HeartbeatBody; -import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.ssl.BogusSSLContextFactory; - -import java.util.Iterator; -import java.util.concurrent.CopyOnWriteArraySet; -import java.util.concurrent.CountDownLatch; - -public class AMQProtocolHandler extends IoHandlerAdapter -{ - private static final Logger _logger = Logger.getLogger(AMQProtocolHandler.class); - - /** - * The connection that this protocol handler is associated with. There is a 1-1 - * mapping between connection instances and protocol handler instances. - */ - private AMQConnection _connection; - - /** - * Used only when determining whether to add the SSL filter or not. This should be made more - * generic in future since we will potentially have many transport layer options - */ - private boolean _useSSL; - - /** - * Our wrapper for a protocol session that provides access to session values - * in a typesafe manner. - */ - private volatile AMQProtocolSession _protocolSession; - - private AMQStateManager _stateManager = new AMQStateManager(); - - private final CopyOnWriteArraySet _frameListeners = new CopyOnWriteArraySet(); - - /** - * We create the failover handler when the session is created since it needs a reference to the IoSession in order - * to be able to send errors during failover back to the client application. The session won't be available in the - * case where we failing over due to a Connection.Redirect message from the broker. - */ - private FailoverHandler _failoverHandler; - - /** - * This flag is used to track whether failover is being attempted. It is used to prevent the application constantly - * attempting failover where it is failing. - */ - private FailoverState _failoverState = FailoverState.NOT_STARTED; - - private CountDownLatch _failoverLatch; - - public AMQProtocolHandler(AMQConnection con) - { - _connection = con; - - // We add a proxy for the state manager so that we can substitute the state manager easily in this class. - // We substitute the state manager when performing failover - _frameListeners.add(new AMQMethodListener() - { - public boolean methodReceived(AMQMethodEvent evt) throws AMQException - { - return _stateManager.methodReceived(evt); - } - - public void error(Exception e) - { - _stateManager.error(e); - } - }); - } - - public boolean isUseSSL() - { - return _useSSL; - } - - public void setUseSSL(boolean useSSL) - { - _useSSL = useSSL; - } - - public void sessionCreated(IoSession session) throws Exception - { - _logger.debug("Protocol session created for session " + System.identityHashCode(session)); - _failoverHandler = new FailoverHandler(this, session); - - final ProtocolCodecFilter pcf = new ProtocolCodecFilter(new AMQCodecFactory(false)); - - if (Boolean.getBoolean("amqj.shared_read_write_pool")) - { - session.getFilterChain().addBefore("AsynchronousWriteFilter", "protocolFilter", pcf); - } - else - { - session.getFilterChain().addLast("protocolFilter", pcf); - } - // we only add the SSL filter where we have an SSL connection - if (_useSSL) - { - //FIXME: Bogus context cannot be used in production. - SSLFilter sslFilter = new SSLFilter(BogusSSLContextFactory.getInstance(false)); - sslFilter.setUseClientMode(true); - session.getFilterChain().addBefore("protocolFilter", "ssl", sslFilter); - } - - _protocolSession = new AMQProtocolSession(this, session, _connection); - _protocolSession.init(); - } - - public void sessionOpened(IoSession session) throws Exception - { - System.setProperty("foo", "bar"); - } - - /** - * When the broker connection dies we can either get sessionClosed() called or exceptionCaught() followed by - * sessionClosed() depending on whether we were trying to send data at the time of failure. - * - * @param session - * @throws Exception - */ - public void sessionClosed(IoSession session) throws Exception - { - if (_connection.isClosed()) - { - _logger.info("Session closed called by client"); - } - else - { - _logger.info("Session closed called with failover state currently " + _failoverState); - - //reconnetablility was introduced here so as not to disturb the client as they have made their intentions - // known through the policy settings. - - if ((_failoverState != FailoverState.IN_PROGRESS) && _connection.failoverAllowed()) - { - _logger.info("FAILOVER STARTING"); - if (_failoverState == FailoverState.NOT_STARTED) - { - _failoverState = FailoverState.IN_PROGRESS; - startFailoverThread(); - } - else - { - _logger.info("Not starting failover as state currently " + _failoverState); - } - } - else - { - _logger.info("Failover not allowed by policy."); - - if (_logger.isDebugEnabled()) - { - _logger.debug(_connection.getFailoverPolicy().toString()); - } - - if (_failoverState != FailoverState.IN_PROGRESS) - { - _logger.info("sessionClose() not allowed to failover"); - _connection.exceptionReceived( - new AMQDisconnectedException("Server closed connection and reconnection " + - "not permitted.")); - } - else - { - _logger.info("sessionClose() failover in progress"); - } - } - } - - _logger.info("Protocol Session [" + this + "] closed"); - } - - /** - * See {@link FailoverHandler} to see rationale for separate thread. - */ - private void startFailoverThread() - { - Thread failoverThread = new Thread(_failoverHandler); - failoverThread.setName("Failover"); - // Do not inherit daemon-ness from current thread as this can be a daemon - // thread such as a AnonymousIoService thread. - failoverThread.setDaemon(false); - failoverThread.start(); - } - - public void sessionIdle(IoSession session, IdleStatus status) throws Exception - { - _logger.debug("Protocol Session [" + this + ":" + session + "] idle: " + status); - if (IdleStatus.WRITER_IDLE.equals(status)) - { - //write heartbeat frame: - _logger.debug("Sent heartbeat"); - session.write(HeartbeatBody.FRAME); - HeartbeatDiagnostics.sent(); - } - else if (IdleStatus.READER_IDLE.equals(status)) - { - //failover: - HeartbeatDiagnostics.timeout(); - _logger.warn("Timed out while waiting for heartbeat from peer."); - session.close(); - } - } - - public void exceptionCaught(IoSession session, Throwable cause) throws Exception - { - if (_failoverState == FailoverState.NOT_STARTED) - { - //if (!(cause instanceof AMQUndeliveredException) && (!(cause instanceof AMQAuthenticationException))) - if (cause instanceof AMQConnectionClosedException) - { - _logger.info("Exception caught therefore going to attempt failover: " + cause, cause); - // this will attemp failover - - sessionClosed(session); - } - } - // we reach this point if failover was attempted and failed therefore we need to let the calling app - // know since we cannot recover the situation - else if (_failoverState == FailoverState.FAILED) - { - _logger.error("Exception caught by protocol handler: " + cause, cause); - // we notify the state manager of the error in case we have any clients waiting on a state - // change. Those "waiters" will be interrupted and can handle the exception - AMQException amqe = new AMQException("Protocol handler error: " + cause, cause); - propagateExceptionToWaiters(amqe); - _connection.exceptionReceived(cause); - } - } - - /** - * There are two cases where we have other threads potentially blocking for events to be handled by this - * class. These are for the state manager (waiting for a state change) or a frame listener (waiting for a - * particular type of frame to arrive). When an error occurs we need to notify these waiters so that they can - * react appropriately. - * - * @param e the exception to propagate - */ - public void propagateExceptionToWaiters(Exception e) - { - _stateManager.error(e); - final Iterator it = _frameListeners.iterator(); - while (it.hasNext()) - { - final AMQMethodListener ml = (AMQMethodListener) it.next(); - ml.error(e); - } - } - - private static int _messageReceivedCount; - - public void messageReceived(IoSession session, Object message) throws Exception - { - - if (_messageReceivedCount++ % 1000 == 0) - { - _logger.debug("Received " + _messageReceivedCount + " protocol messages"); - } - Iterator it = _frameListeners.iterator(); - AMQFrame frame = (AMQFrame) message; - - HeartbeatDiagnostics.received(frame.bodyFrame instanceof HeartbeatBody); - - if (frame.bodyFrame instanceof AMQMethodBody) - { - if (_logger.isDebugEnabled()) - { - _logger.debug("Method frame received: " + frame); - } - - final AMQMethodEvent evt = new AMQMethodEvent(frame.channel, (AMQMethodBody) frame.bodyFrame, _protocolSession); - try - { - boolean wasAnyoneInterested = false; - while (it.hasNext()) - { - final AMQMethodListener listener = (AMQMethodListener) it.next(); - wasAnyoneInterested = listener.methodReceived(evt) || wasAnyoneInterested; - } - if (!wasAnyoneInterested) - { - throw new AMQException("AMQMethodEvent " + evt + " was not processed by any listener."); - } - } - catch (AMQException e) - { - it = _frameListeners.iterator(); - while (it.hasNext()) - { - final AMQMethodListener listener = (AMQMethodListener) it.next(); - listener.error(e); - } - exceptionCaught(session, e); - } - } - else if (frame.bodyFrame instanceof ContentHeaderBody) - { - _protocolSession.messageContentHeaderReceived(frame.channel, - (ContentHeaderBody) frame.bodyFrame); - } - else if (frame.bodyFrame instanceof ContentBody) - { - _protocolSession.messageContentBodyReceived(frame.channel, - (ContentBody) frame.bodyFrame); - } - else if (frame.bodyFrame instanceof HeartbeatBody) - { - _logger.debug("Received heartbeat"); - } - _connection.bytesReceived(_protocolSession.getIoSession().getReadBytes()); - } - - private static int _messagesOut; - - public void messageSent(IoSession session, Object message) throws Exception - { - if (_messagesOut++ % 1000 == 0) - { - _logger.debug("Sent " + _messagesOut + " protocol messages"); - } - _connection.bytesSent(session.getWrittenBytes()); - if (_logger.isDebugEnabled()) - { - _logger.debug("Sent frame " + message); - } - } - - public void addFrameListener(AMQMethodListener listener) - { - _frameListeners.add(listener); - } - - public void removeFrameListener(AMQMethodListener listener) - { - _frameListeners.remove(listener); - } - - public void attainState(AMQState s) throws AMQException - { - _stateManager.attainState(s); - } - - /** - * Convenience method that writes a frame to the protocol session. Equivalent - * to calling getProtocolSession().write(). - * - * @param frame the frame to write - */ - public void writeFrame(AMQDataBlock frame) - { - _protocolSession.writeFrame(frame); - } - - public void writeFrame(AMQDataBlock frame, boolean wait) - { - _protocolSession.writeFrame(frame, wait); - } - - /** - * Convenience method that writes a frame to the protocol session and waits for - * a particular response. Equivalent to calling getProtocolSession().write() then - * waiting for the response. - * - * @param frame - * @param listener the blocking listener. Note the calling thread will block. - */ - private AMQMethodEvent writeCommandFrameAndWaitForReply(AMQFrame frame, - BlockingMethodFrameListener listener) - throws AMQException - { - try - { - _frameListeners.add(listener); - _protocolSession.writeFrame(frame); - - AMQMethodEvent e = listener.blockForFrame(); - return e; - // When control resumes before this line, a reply will have been received - // that matches the criteria defined in the blocking listener - } - finally - { - // If we don't remove the listener then no-one will - _frameListeners.remove(listener); - } - - } - - /** - * More convenient method to write a frame and wait for it's response. - */ - public AMQMethodEvent syncWrite(AMQFrame frame, Class responseClass) throws AMQException - { - return writeCommandFrameAndWaitForReply(frame, - new SpecificMethodFrameListener(frame.channel, responseClass)); - } - - /** - * Convenience method to register an AMQSession with the protocol handler. Registering - * a session with the protocol handler will ensure that messages are delivered to the - * consumer(s) on that session. - * - * @param channelId the channel id of the session - * @param session the session instance. - */ - public void addSessionByChannel(int channelId, AMQSession session) - { - _protocolSession.addSessionByChannel(channelId, session); - } - - /** - * Convenience method to deregister an AMQSession with the protocol handler. - * - * @param channelId then channel id of the session - */ - public void removeSessionByChannel(int channelId) - { - _protocolSession.removeSessionByChannel(channelId); - } - - public void closeSession(AMQSession session) throws AMQException - { - _protocolSession.closeSession(session); - } - - public void closeConnection() throws AMQException - { - _stateManager.changeState(AMQState.CONNECTION_CLOSING); - - final AMQFrame frame = ConnectionCloseBody.createAMQFrame( - 0, AMQConstant.REPLY_SUCCESS.getCode(), "JMS client is closing the connection.", 0, 0); - syncWrite(frame, ConnectionCloseOkBody.class); - - _protocolSession.closeProtocolSession(); - } - - /** - * @return the number of bytes read from this protocol session - */ - public long getReadBytes() - { - return _protocolSession.getIoSession().getReadBytes(); - } - - /** - * @return the number of bytes written to this protocol session - */ - public long getWrittenBytes() - { - return _protocolSession.getIoSession().getWrittenBytes(); - } - - public void failover(String host, int port) - { - _failoverHandler.setHost(host); - _failoverHandler.setPort(port); - // see javadoc for FailoverHandler to see rationale for separate thread - startFailoverThread(); - } - - public void blockUntilNotFailingOver() throws InterruptedException - { - if (_failoverLatch != null) - { - _failoverLatch.await(); - } - } - - public String generateQueueName() - { - return _protocolSession.generateQueueName(); - } - - public CountDownLatch getFailoverLatch() - { - return _failoverLatch; - } - - public void setFailoverLatch(CountDownLatch failoverLatch) - { - _failoverLatch = failoverLatch; - } - - public AMQConnection getConnection() - { - return _connection; - } - - public AMQStateManager getStateManager() - { - return _stateManager; - } - - public void setStateManager(AMQStateManager stateManager) - { - _stateManager = stateManager; - } - - FailoverState getFailoverState() - { - return _failoverState; - } - - public void setFailoverState(FailoverState failoverState) - { - _failoverState = failoverState; - } -} diff --git a/client/src/org/apache/qpid/client/protocol/AMQProtocolSession.java b/client/src/org/apache/qpid/client/protocol/AMQProtocolSession.java deleted file mode 100644 index a4ed89719b..0000000000 --- a/client/src/org/apache/qpid/client/protocol/AMQProtocolSession.java +++ /dev/null @@ -1,409 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.protocol; - -import org.apache.log4j.Logger; -import org.apache.mina.common.CloseFuture; -import org.apache.mina.common.IdleStatus; -import org.apache.mina.common.IoSession; -import org.apache.mina.common.WriteFuture; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.ConnectionTuneParameters; -import org.apache.qpid.client.message.UnexpectedBodyReceivedException; -import org.apache.qpid.client.message.UnprocessedMessage; -import org.apache.qpid.framing.AMQDataBlock; -import org.apache.qpid.framing.ContentBody; -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.framing.ProtocolInitiation; -import org.apache.qpid.framing.ProtocolVersionList; -import org.apache.commons.lang.StringUtils; - -import javax.jms.JMSException; -import javax.security.sasl.SaslClient; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * Wrapper for protocol session that provides type-safe access to session attributes. - * - * The underlying protocol session is still available but clients should not - * use it to obtain session attributes. - */ -public class AMQProtocolSession implements ProtocolVersionList -{ - - protected static final int LAST_WRITE_FUTURE_JOIN_TIMEOUT = 1000 * 60 * 2; - - protected static final Logger _logger = Logger.getLogger(AMQProtocolSession.class); - - public static final String PROTOCOL_INITIATION_RECEIVED = "ProtocolInitiatiionReceived"; - - protected static final String CONNECTION_TUNE_PARAMETERS = "ConnectionTuneParameters"; - - protected static final String AMQ_CONNECTION = "AMQConnection"; - - protected static final String SASL_CLIENT = "SASLClient"; - - protected final IoSession _minaProtocolSession; - - protected WriteFuture _lastWriteFuture; - - /** - * The handler from which this session was created and which is used to handle protocol events. - * We send failover events to the handler. - */ - protected final AMQProtocolHandler _protocolHandler; - - /** - * Maps from the channel id to the AMQSession that it represents. - */ - protected ConcurrentMap _channelId2SessionMap = new ConcurrentHashMap(); - - protected ConcurrentMap _closingChannels = new ConcurrentHashMap(); - - /** - * Maps from a channel id to an unprocessed message. This is used to tie together the - * JmsDeliverBody (which arrives first) with the subsequent content header and content bodies. - */ - protected ConcurrentMap _channelId2UnprocessedMsgMap = new ConcurrentHashMap(); - - /** - * Counter to ensure unique queue names - */ - protected int _queueId = 1; - protected final Object _queueIdLock = new Object(); - - /** - * No-arg constructor for use by test subclass - has to initialise final vars - * NOT intended for use other then for test - */ - public AMQProtocolSession() - { - _protocolHandler = null; - _minaProtocolSession = null; - } - - public AMQProtocolSession(AMQProtocolHandler protocolHandler, IoSession protocolSession, AMQConnection connection) - { - _protocolHandler = protocolHandler; - _minaProtocolSession = protocolSession; - // properties of the connection are made available to the event handlers - _minaProtocolSession.setAttribute(AMQ_CONNECTION, connection); - } - - public void init() - { - // start the process of setting up the connection. This is the first place that - // data is written to the server. - /* Find last protocol version in protocol version list. Make sure last protocol version - listed in the build file (build-module.xml) is the latest version which will be used - here. */ - int i = pv.length - 1; - _minaProtocolSession.write(new ProtocolInitiation(pv[i][PROTOCOL_MAJOR], pv[i][PROTOCOL_MINOR])); - } - - public String getClientID() - { - try - { - return getAMQConnection().getClientID(); - } - catch (JMSException e) - { - // we never throw a JMSException here - return null; - } - } - - public void setClientID(String clientID) throws JMSException - { - getAMQConnection().setClientID(clientID); - } - - public String getVirtualHost() - { - return getAMQConnection().getVirtualHost(); - } - - public String getUsername() - { - return getAMQConnection().getUsername(); - } - - public String getPassword() - { - return getAMQConnection().getPassword(); - } - - public IoSession getIoSession() - { - return _minaProtocolSession; - } - - public SaslClient getSaslClient() - { - return (SaslClient) _minaProtocolSession.getAttribute(SASL_CLIENT); - } - - /** - * Store the SASL client currently being used for the authentication handshake - * @param client if non-null, stores this in the session. if null clears any existing client - * being stored - */ - public void setSaslClient(SaslClient client) - { - if (client == null) - { - _minaProtocolSession.removeAttribute(SASL_CLIENT); - } - else - { - _minaProtocolSession.setAttribute(SASL_CLIENT, client); - } - } - - public ConnectionTuneParameters getConnectionTuneParameters() - { - return (ConnectionTuneParameters) _minaProtocolSession.getAttribute(CONNECTION_TUNE_PARAMETERS); - } - - public void setConnectionTuneParameters(ConnectionTuneParameters params) - { - _minaProtocolSession.setAttribute(CONNECTION_TUNE_PARAMETERS, params); - AMQConnection con = getAMQConnection(); - con.setMaximumChannelCount(params.getChannelMax()); - con.setMaximumFrameSize(params.getFrameMax()); - initHeartbeats((int) params.getHeartbeat()); - } - - /** - * Callback invoked from the BasicDeliverMethodHandler when a message has been received. - * This is invoked on the MINA dispatcher thread. - * @param message - * @throws AMQException if this was not expected - */ - public void unprocessedMessageReceived(UnprocessedMessage message) throws AMQException - { - _channelId2UnprocessedMsgMap.put(message.channelId, message); - } - - public void messageContentHeaderReceived(int channelId, ContentHeaderBody contentHeader) - throws AMQException - { - UnprocessedMessage msg = (UnprocessedMessage) _channelId2UnprocessedMsgMap.get(channelId); - if (msg == null) - { - throw new AMQException("Error: received content header without having received a BasicDeliver frame first"); - } - if (msg.contentHeader != null) - { - throw new AMQException("Error: received duplicate content header or did not receive correct number of content body frames"); - } - msg.contentHeader = contentHeader; - if (contentHeader.bodySize == 0) - { - deliverMessageToAMQSession(channelId, msg); - } - } - - public void messageContentBodyReceived(int channelId, ContentBody contentBody) throws AMQException - { - UnprocessedMessage msg = (UnprocessedMessage) _channelId2UnprocessedMsgMap.get(channelId); - if (msg == null) - { - throw new AMQException("Error: received content body without having received a JMSDeliver frame first"); - } - if (msg.contentHeader == null) - { - _channelId2UnprocessedMsgMap.remove(channelId); - throw new AMQException("Error: received content body without having received a ContentHeader frame first"); - } - try - { - msg.receiveBody(contentBody); - } - catch (UnexpectedBodyReceivedException e) - { - _channelId2UnprocessedMsgMap.remove(channelId); - throw e; - } - if (msg.isAllBodyDataReceived()) - { - deliverMessageToAMQSession(channelId, msg); - } - } - - /** - * Deliver a message to the appropriate session, removing the unprocessed message - * from our map - * @param channelId the channel id the message should be delivered to - * @param msg the message - */ - private void deliverMessageToAMQSession(int channelId, UnprocessedMessage msg) - { - AMQSession session = (AMQSession) _channelId2SessionMap.get(channelId); - session.messageReceived(msg); - _channelId2UnprocessedMsgMap.remove(channelId); - } - - /** - * Convenience method that writes a frame to the protocol session. Equivalent - * to calling getProtocolSession().write(). - * - * @param frame the frame to write - */ - public void writeFrame(AMQDataBlock frame) - { - writeFrame(frame, false); - } - - public void writeFrame(AMQDataBlock frame, boolean wait) - { - WriteFuture f = _minaProtocolSession.write(frame); - if (wait) - { - f.join(); - } - else - { - _lastWriteFuture = f; - } - } - - public void addSessionByChannel(int channelId, AMQSession session) - { - if (channelId <= 0) - { - throw new IllegalArgumentException("Attempt to register a session with a channel id <= zero"); - } - if (session == null) - { - throw new IllegalArgumentException("Attempt to register a null session"); - } - _logger.debug("Add session with channel id " + channelId); - _channelId2SessionMap.put(channelId, session); - } - - public void removeSessionByChannel(int channelId) - { - if (channelId <= 0) - { - throw new IllegalArgumentException("Attempt to deregister a session with a channel id <= zero"); - } - _logger.debug("Removing session with channelId " + channelId); - _channelId2SessionMap.remove(channelId); - } - - /** - * Starts the process of closing a session - * @param session the AMQSession being closed - */ - public void closeSession(AMQSession session) - { - _logger.debug("closeSession called on protocol session for session " + session.getChannelId()); - final int channelId = session.getChannelId(); - if (channelId <= 0) - { - throw new IllegalArgumentException("Attempt to close a channel with id < 0"); - } - // we need to know when a channel is closing so that we can respond - // with a channel.close frame when we receive any other type of frame - // on that channel - _closingChannels.putIfAbsent(channelId, session); - } - - /** - * Called from the ChannelClose handler when a channel close frame is received. - * This method decides whether this is a response or an initiation. The latter - * case causes the AMQSession to be closed and an exception to be thrown if - * appropriate. - * @param channelId the id of the channel (session) - * @return true if the client must respond to the server, i.e. if the server - * initiated the channel close, false if the channel close is just the server - * responding to the client's earlier request to close the channel. - */ - public boolean channelClosed(int channelId, int code, String text) - { - final Integer chId = channelId; - // if this is not a response to an earlier request to close the channel - if (_closingChannels.remove(chId) == null) - { - final AMQSession session = (AMQSession) _channelId2SessionMap.get(chId); - session.closed(new AMQException(_logger, code, text)); - return true; - } - else - { - return false; - } - } - - public AMQConnection getAMQConnection() - { - return (AMQConnection) _minaProtocolSession.getAttribute(AMQ_CONNECTION); - } - - public void closeProtocolSession() - { - _logger.debug("Waiting for last write to join."); - if (_lastWriteFuture != null) - { - _lastWriteFuture.join(LAST_WRITE_FUTURE_JOIN_TIMEOUT); - } - - _logger.debug("Closing protocol session"); - final CloseFuture future = _minaProtocolSession.close(); - future.join(); - } - - public void failover(String host, int port) - { - _protocolHandler.failover(host, port); - } - - protected String generateQueueName() - { - int id; - synchronized(_queueIdLock) - { - id = _queueId++; - } - //get rid of / and : and ; from address for spec conformance - String localAddress = StringUtils.replaceChars(_minaProtocolSession.getLocalAddress().toString(),"/;:",""); - return "tmp_" + localAddress + "_" + id; - } - - /** - * - * @param delay delay in seconds (not ms) - */ - void initHeartbeats(int delay) - { - if (delay > 0) - { - _minaProtocolSession.setIdleTime(IdleStatus.WRITER_IDLE, delay); - _minaProtocolSession.setIdleTime(IdleStatus.READER_IDLE, HeartbeatConfig.CONFIG.getTimeout(delay)); - HeartbeatDiagnostics.init(delay, HeartbeatConfig.CONFIG.getTimeout(delay)); - } - } -} diff --git a/client/src/org/apache/qpid/client/protocol/BlockingMethodFrameListener.java b/client/src/org/apache/qpid/client/protocol/BlockingMethodFrameListener.java deleted file mode 100644 index 492571b6af..0000000000 --- a/client/src/org/apache/qpid/client/protocol/BlockingMethodFrameListener.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.protocol; - -import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQMethodBody; - -public abstract class BlockingMethodFrameListener implements AMQMethodListener -{ - private volatile boolean _ready = false; - - public abstract boolean processMethod(int channelId, AMQMethodBody frame) throws AMQException; - - private final Object _lock = new Object(); - - /** - * This is set if there is an exception thrown from processCommandFrame and the - * exception is rethrown to the caller of blockForFrame() - */ - private volatile Exception _error; - - protected int _channelId; - - protected AMQMethodEvent _doneEvt = null; - - public BlockingMethodFrameListener(int channelId) - { - _channelId = channelId; - } - - /** - * This method is called by the MINA dispatching thread. Note that it could - * be called before blockForFrame() has been called. - * @param evt the frame event - * @return true if the listener has dealt with this frame - * @throws AMQException - */ - public boolean methodReceived(AMQMethodEvent evt) throws AMQException - { - AMQMethodBody method = evt.getMethod(); - - try - { - boolean ready = (evt.getChannelId() == _channelId) && processMethod(evt.getChannelId(), method); - if (ready) - { - // we only update the flag from inside the synchronized block - // so that the blockForFrame method cannot "miss" an update - it - // will only ever read the flag from within the synchronized block - synchronized (_lock) - { - _doneEvt = evt; - _ready = ready; - _lock.notify(); - } - } - return ready; - } - catch (AMQException e) - { - error(e); - // we rethrow the error here, and the code in the frame dispatcher will go round - // each listener informing them that an exception has been thrown - throw e; - } - } - - /** - * This method is called by the thread that wants to wait for a frame. - */ - public AMQMethodEvent blockForFrame() throws AMQException - { - synchronized (_lock) - { - while (!_ready) - { - try - { - _lock.wait(); - } - catch (InterruptedException e) - { - // IGNORE - } - } - } - if (_error != null) - { - if (_error instanceof AMQException) - { - throw (AMQException)_error; - } - else - { - throw new AMQException("Woken up due to exception", _error); // FIXME: This will wrap FailoverException and prevent it being caught. - } - } - - return _doneEvt; - } - - /** - * This is a callback, called by the MINA dispatcher thread only. It is also called from within this - * class to avoid code repetition but again is only called by the MINA dispatcher thread. - * @param e - */ - public void error(Exception e) - { - // set the error so that the thread that is blocking (against blockForFrame()) - // can pick up the exception and rethrow to the caller - _error = e; - synchronized (_lock) - { - _ready = true; - _lock.notify(); - } - } -} diff --git a/client/src/org/apache/qpid/client/protocol/HeartbeatConfig.java b/client/src/org/apache/qpid/client/protocol/HeartbeatConfig.java deleted file mode 100644 index 6a7462cd0f..0000000000 --- a/client/src/org/apache/qpid/client/protocol/HeartbeatConfig.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.protocol; - -import org.apache.log4j.Logger; - -class HeartbeatConfig -{ - private static final Logger _logger = Logger.getLogger(HeartbeatConfig.class); - static final HeartbeatConfig CONFIG = new HeartbeatConfig(); - - /** - * The factor used to get the timeout from the delay between heartbeats. - */ - private float timeoutFactor = 2; - - HeartbeatConfig() - { - String property = System.getProperty("amqj.heartbeat.timeoutFactor"); - if(property != null) - { - try - { - timeoutFactor = Float.parseFloat(property); - } - catch(NumberFormatException e) - { - _logger.warn("Invalid timeout factor (amqj.heartbeat.timeoutFactor): " + property); - } - } - } - - float getTimeoutFactor() - { - return timeoutFactor; - } - - int getTimeout(int writeDelay) - { - return (int) (timeoutFactor * writeDelay); - } -} diff --git a/client/src/org/apache/qpid/client/protocol/HeartbeatDiagnostics.java b/client/src/org/apache/qpid/client/protocol/HeartbeatDiagnostics.java deleted file mode 100644 index d44faeab04..0000000000 --- a/client/src/org/apache/qpid/client/protocol/HeartbeatDiagnostics.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.protocol; - -class HeartbeatDiagnostics -{ - private static final Diagnostics _impl = init(); - - private static Diagnostics init() - { - return Boolean.getBoolean("amqj.heartbeat.diagnostics") ? new On() : new Off(); - } - - static void sent() - { - _impl.sent(); - } - - static void timeout() - { - _impl.timeout(); - } - - static void received(boolean heartbeat) - { - _impl.received(heartbeat); - } - - static void init(int delay, int timeout) - { - _impl.init(delay, timeout); - } - - private static interface Diagnostics - { - void sent(); - void timeout(); - void received(boolean heartbeat); - void init(int delay, int timeout); - } - - private static class On implements Diagnostics - { - private final String[] messages = new String[50]; - private int i; - - private void save(String msg) - { - messages[i++] = msg; - if(i >= messages.length){ - i = 0;//i.e. a circular buffer - } - } - - public void sent() - { - save(System.currentTimeMillis() + ": sent heartbeat"); - } - - public void timeout() - { - for(int i = 0; i < messages.length; i++) - { - if(messages[i] != null) - { - System.out.println(messages[i]); - } - } - System.out.println(System.currentTimeMillis() + ": timed out"); - } - - public void received(boolean heartbeat) - { - save(System.currentTimeMillis() + ": received " + (heartbeat ? "heartbeat" : "data")); - } - - public void init(int delay, int timeout) - { - System.out.println(System.currentTimeMillis() + ": initialised delay=" + delay + ", timeout=" + timeout); - } - } - - private static class Off implements Diagnostics - { - public void sent() - { - - } - public void timeout() - { - - } - public void received(boolean heartbeat) - { - - } - - public void init(int delay, int timeout) - { - - } - } -} diff --git a/client/src/org/apache/qpid/client/protocol/ProtocolBufferMonitorFilter.java b/client/src/org/apache/qpid/client/protocol/ProtocolBufferMonitorFilter.java deleted file mode 100644 index e70d2ac661..0000000000 --- a/client/src/org/apache/qpid/client/protocol/ProtocolBufferMonitorFilter.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.protocol; - -import org.apache.mina.common.IoFilterAdapter; -import org.apache.mina.common.IoSession; -import org.apache.log4j.Logger; - -/** - * A MINA filter that monitors the numbers of messages pending to be sent by MINA. It outputs a message - * when a threshold has been exceeded, and has a frequency configuration so that messages are not output - * too often. - * - */ -public class ProtocolBufferMonitorFilter extends IoFilterAdapter -{ - private static final Logger _logger = Logger.getLogger(ProtocolBufferMonitorFilter.class); - - public static long DEFAULT_FREQUENCY = 5000; - - public static int DEFAULT_THRESHOLD = 3000; - - private int _bufferedMessages = 0; - - private int _threshold; - - private long _lastMessageOutputTime; - - private long _outputFrequencyInMillis; - - public ProtocolBufferMonitorFilter() - { - _threshold = DEFAULT_THRESHOLD; - _outputFrequencyInMillis = DEFAULT_FREQUENCY; - } - - public ProtocolBufferMonitorFilter(int threshold, long frequency) - { - _threshold = threshold; - _outputFrequencyInMillis = frequency; - } - - public void messageReceived( NextFilter nextFilter, IoSession session, Object message ) throws Exception - { - _bufferedMessages++; - if (_bufferedMessages > _threshold) - { - long now = System.currentTimeMillis(); - if ((now - _lastMessageOutputTime) > _outputFrequencyInMillis) - { - _logger.warn("Protocol message buffer exceeded threshold of " + _threshold + ". Current backlog: " + - _bufferedMessages); - _lastMessageOutputTime = now; - } - } - - nextFilter.messageReceived(session, message); - } - - public void messageSent( NextFilter nextFilter, IoSession session, Object message ) throws Exception - { - _bufferedMessages--; - nextFilter.messageSent(session, message); - } - - public int getBufferedMessages() - { - return _bufferedMessages; - } - - public int getThreshold() - { - return _threshold; - } - - public void setThreshold(int threshold) - { - _threshold = threshold; - } - - public long getOutputFrequencyInMillis() - { - return _outputFrequencyInMillis; - } - - public void setOutputFrequencyInMillis(long outputFrequencyInMillis) - { - _outputFrequencyInMillis = outputFrequencyInMillis; - } - - public long getLastMessageOutputTime() - { - return _lastMessageOutputTime; - } -} diff --git a/client/src/org/apache/qpid/client/security/AMQCallbackHandler.java b/client/src/org/apache/qpid/client/security/AMQCallbackHandler.java deleted file mode 100644 index 72d8bedc06..0000000000 --- a/client/src/org/apache/qpid/client/security/AMQCallbackHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.security; - -import org.apache.qpid.client.protocol.AMQProtocolSession; - -import javax.security.auth.callback.CallbackHandler; - -public interface AMQCallbackHandler extends CallbackHandler -{ - void initialise(AMQProtocolSession protocolSession); -} diff --git a/client/src/org/apache/qpid/client/security/CallbackHandlerRegistry.java b/client/src/org/apache/qpid/client/security/CallbackHandlerRegistry.java deleted file mode 100644 index 9b3b83dc7a..0000000000 --- a/client/src/org/apache/qpid/client/security/CallbackHandlerRegistry.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.security; - -import org.apache.log4j.Logger; - -import java.io.*; -import java.util.*; - -public class CallbackHandlerRegistry -{ - private static final String FILE_PROPERTY = "amq.callbackhandler.properties"; - - private static final Logger _logger = Logger.getLogger(CallbackHandlerRegistry.class); - - private static CallbackHandlerRegistry _instance = new CallbackHandlerRegistry(); - - private Map _mechanismToHandlerClassMap = new HashMap(); - - private String _mechanisms; - - public static CallbackHandlerRegistry getInstance() - { - return _instance; - } - - public Class getCallbackHandlerClass(String mechanism) - { - return (Class) _mechanismToHandlerClassMap.get(mechanism); - } - - public String getMechanisms() - { - return _mechanisms; - } - - private CallbackHandlerRegistry() - { - // first we register any Sasl client factories - DynamicSaslRegistrar.registerSaslProviders(); - - InputStream is = openPropertiesInputStream(); - try - { - Properties props = new Properties(); - props.load(is); - parseProperties(props); - _logger.info("Available SASL mechanisms: " + _mechanisms); - } - catch (IOException e) - { - _logger.error("Error reading properties: " + e, e); - } - finally - { - if (is != null) - { - try - { - is.close(); - - } - catch (IOException e) - { - _logger.error("Unable to close properties stream: " + e, e); - } - } - } - } - - private InputStream openPropertiesInputStream() - { - String filename = System.getProperty(FILE_PROPERTY); - boolean useDefault = true; - InputStream is = null; - if (filename != null) - { - try - { - is = new BufferedInputStream(new FileInputStream(new File(filename))); - useDefault = false; - } - catch (FileNotFoundException e) - { - _logger.error("Unable to read from file " + filename + ": " + e, e); - } - } - - if (useDefault) - { - is = CallbackHandlerRegistry.class.getResourceAsStream("CallbackHandlerRegistry.properties"); - } - - return is; - } - - private void parseProperties(Properties props) - { - Enumeration e = props.propertyNames(); - while (e.hasMoreElements()) - { - String propertyName = (String) e.nextElement(); - int period = propertyName.indexOf("."); - if (period < 0) - { - _logger.warn("Unable to parse property " + propertyName + " when configuring SASL providers"); - continue; - } - String mechanism = propertyName.substring(period + 1); - String className = props.getProperty(propertyName); - Class clazz = null; - try - { - clazz = Class.forName(className); - if (!AMQCallbackHandler.class.isAssignableFrom(clazz)) - { - _logger.warn("SASL provider " + clazz + " does not implement " + AMQCallbackHandler.class + - ". Skipping"); - continue; - } - _mechanismToHandlerClassMap.put(mechanism, clazz); - if (_mechanisms == null) - { - _mechanisms = mechanism; - } - else - { - // one time cost - _mechanisms = _mechanisms + " " + mechanism; - } - } - catch (ClassNotFoundException ex) - { - _logger.warn("Unable to load class " + className + ". Skipping that SASL provider"); - continue; - } - } - } -} diff --git a/client/src/org/apache/qpid/client/security/CallbackHandlerRegistry.properties b/client/src/org/apache/qpid/client/security/CallbackHandlerRegistry.properties deleted file mode 100644 index 50e6f1efaa..0000000000 --- a/client/src/org/apache/qpid/client/security/CallbackHandlerRegistry.properties +++ /dev/null @@ -1,20 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# -CallbackHandler.CRAM-MD5=org.apache.qpid.client.security.UsernamePasswordCallbackHandler -CallbackHandler.PLAIN=org.apache.qpid.client.security.UsernamePasswordCallbackHandler diff --git a/client/src/org/apache/qpid/client/security/DynamicSaslRegistrar.java b/client/src/org/apache/qpid/client/security/DynamicSaslRegistrar.java deleted file mode 100644 index c21dc9e659..0000000000 --- a/client/src/org/apache/qpid/client/security/DynamicSaslRegistrar.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.security; - -import org.apache.log4j.Logger; - -import javax.security.sasl.SaslClientFactory; -import java.io.*; -import java.util.Properties; -import java.util.Enumeration; -import java.util.Map; -import java.util.TreeMap; -import java.security.Security; - -public class DynamicSaslRegistrar -{ - private static final String FILE_PROPERTY = "amq.dynamicsaslregistrar.properties"; - - private static final Logger _logger = Logger.getLogger(DynamicSaslRegistrar.class); - - public static void registerSaslProviders() - { - InputStream is = openPropertiesInputStream(); - try - { - Properties props = new Properties(); - props.load(is); - Map<String, Class<? extends SaslClientFactory>> factories = parseProperties(props); - if (factories.size() > 0) - { - Security.addProvider(new JCAProvider(factories)); - _logger.debug("Dynamic SASL provider added as a security provider"); - } - } - catch (IOException e) - { - _logger.error("Error reading properties: " + e, e); - } - finally - { - if (is != null) - { - try - { - is.close(); - - } - catch (IOException e) - { - _logger.error("Unable to close properties stream: " + e, e); - } - } - } - } - - private static InputStream openPropertiesInputStream() - { - String filename = System.getProperty(FILE_PROPERTY); - boolean useDefault = true; - InputStream is = null; - if (filename != null) - { - try - { - is = new BufferedInputStream(new FileInputStream(new File(filename))); - useDefault = false; - } - catch (FileNotFoundException e) - { - _logger.error("Unable to read from file " + filename + ": " + e, e); - } - } - - if (useDefault) - { - is = CallbackHandlerRegistry.class.getResourceAsStream("DynamicSaslRegistrar.properties"); - } - - return is; - } - - private static Map<String, Class<? extends SaslClientFactory>> parseProperties(Properties props) - { - Enumeration e = props.propertyNames(); - TreeMap<String, Class<? extends SaslClientFactory>> factoriesToRegister = - new TreeMap<String, Class<? extends SaslClientFactory>>(); - while (e.hasMoreElements()) - { - String mechanism = (String) e.nextElement(); - String className = props.getProperty(mechanism); - try - { - Class<?> clazz = Class.forName(className); - if (!(SaslClientFactory.class.isAssignableFrom(clazz))) - { - _logger.error("Class " + clazz + " does not implement " + SaslClientFactory.class + " - skipping"); - continue; - } - factoriesToRegister.put(mechanism, (Class<? extends SaslClientFactory>) clazz); - } - catch (Exception ex) - { - _logger.error("Error instantiating SaslClientFactory calss " + className + " - skipping"); - } - } - return factoriesToRegister; - } - - -} diff --git a/client/src/org/apache/qpid/client/security/DynamicSaslRegistrar.properties b/client/src/org/apache/qpid/client/security/DynamicSaslRegistrar.properties deleted file mode 100644 index ee66664455..0000000000 --- a/client/src/org/apache/qpid/client/security/DynamicSaslRegistrar.properties +++ /dev/null @@ -1,19 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# -AMQPLAIN=org.apache.qpid.client.security.amqplain.AmqPlainSaslClientFactory diff --git a/client/src/org/apache/qpid/client/security/JCAProvider.java b/client/src/org/apache/qpid/client/security/JCAProvider.java deleted file mode 100644 index 9a3b7bf7ab..0000000000 --- a/client/src/org/apache/qpid/client/security/JCAProvider.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.security; - -import javax.security.sasl.SaslClientFactory; -import java.security.Provider; -import java.security.Security; -import java.util.Map; - -public class JCAProvider extends Provider -{ - public JCAProvider(Map<String, Class<? extends SaslClientFactory>> providerMap) - { - super("AMQSASLProvider", 1.0, "A JCA provider that registers all " + - "AMQ SASL providers that want to be registered"); - register(providerMap); - Security.addProvider(this); - } - - private void register(Map<String, Class<? extends SaslClientFactory>> providerMap) - { - for (Map.Entry<String, Class<? extends SaslClientFactory>> me : - providerMap.entrySet()) - { - put("SaslClientFactory." + me.getKey(), me.getValue().getName()); - } - } -} diff --git a/client/src/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java b/client/src/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java deleted file mode 100644 index 7192601b18..0000000000 --- a/client/src/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.security; - -import org.apache.qpid.client.protocol.AMQProtocolSession; - -import javax.security.auth.callback.*; -import java.io.IOException; - -public class UsernamePasswordCallbackHandler implements AMQCallbackHandler -{ - private AMQProtocolSession _protocolSession; - - public void initialise(AMQProtocolSession protocolSession) - { - _protocolSession = protocolSession; - } - - public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException - { - for (int i = 0; i < callbacks.length; i++) - { - Callback cb = callbacks[i]; - if (cb instanceof NameCallback) - { - ((NameCallback)cb).setName(_protocolSession.getUsername()); - } - else if (cb instanceof PasswordCallback) - { - ((PasswordCallback)cb).setPassword(_protocolSession.getPassword().toCharArray()); - } - else - { - throw new UnsupportedCallbackException(cb); - } - } - } -} diff --git a/client/src/org/apache/qpid/client/security/amqplain/AmqPlainSaslClient.java b/client/src/org/apache/qpid/client/security/amqplain/AmqPlainSaslClient.java deleted file mode 100644 index 81d3fb76d5..0000000000 --- a/client/src/org/apache/qpid/client/security/amqplain/AmqPlainSaslClient.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.security.amqplain; - -import org.apache.qpid.framing.FieldTable; - -import javax.security.sasl.SaslClient; -import javax.security.sasl.SaslException; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.NameCallback; -import javax.security.auth.callback.PasswordCallback; -import javax.security.auth.callback.Callback; - -/** - * Implements the "AMQPlain" authentication protocol that uses FieldTables to send username and pwd. - * - */ -public class AmqPlainSaslClient implements SaslClient -{ - /** - * The name of this mechanism - */ - public static final String MECHANISM = "AMQPLAIN"; - - private CallbackHandler _cbh; - - public AmqPlainSaslClient(CallbackHandler cbh) - { - _cbh = cbh; - } - - public String getMechanismName() - { - return "AMQPLAIN"; - } - - public boolean hasInitialResponse() - { - return true; - } - - public byte[] evaluateChallenge(byte[] challenge) throws SaslException - { - // we do not care about the prompt or the default name - NameCallback nameCallback = new NameCallback("prompt", "defaultName"); - PasswordCallback pwdCallback = new PasswordCallback("prompt", false); - Callback[] callbacks = new Callback[]{nameCallback, pwdCallback}; - try - { - _cbh.handle(callbacks); - } - catch (Exception e) - { - throw new SaslException("Error handling SASL callbacks: " + e, e); - } - FieldTable table = new FieldTable(); - table.put("LOGIN", nameCallback.getName()); - table.put("PASSWORD", pwdCallback.getPassword()); - return table.getDataAsBytes(); - } - - public boolean isComplete() - { - return true; - } - - public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException - { - throw new SaslException("Not supported"); - } - - public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException - { - throw new SaslException("Not supported"); - } - - public Object getNegotiatedProperty(String propName) - { - return null; - } - - public void dispose() throws SaslException - { - _cbh = null; - } -} diff --git a/client/src/org/apache/qpid/client/security/amqplain/AmqPlainSaslClientFactory.java b/client/src/org/apache/qpid/client/security/amqplain/AmqPlainSaslClientFactory.java deleted file mode 100644 index 03d765de70..0000000000 --- a/client/src/org/apache/qpid/client/security/amqplain/AmqPlainSaslClientFactory.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.security.amqplain; - -import javax.security.sasl.SaslClientFactory; -import javax.security.sasl.SaslClient; -import javax.security.sasl.SaslException; -import javax.security.sasl.Sasl; -import javax.security.auth.callback.CallbackHandler; -import java.util.Map; - -public class AmqPlainSaslClientFactory implements SaslClientFactory -{ - public SaslClient createSaslClient(String[] mechanisms, String authorizationId, String protocol, String serverName, Map props, CallbackHandler cbh) throws SaslException - { - for (int i = 0; i < mechanisms.length; i++) - { - if (mechanisms[i].equals(AmqPlainSaslClient.MECHANISM)) - { - if (cbh == null) - { - throw new SaslException("CallbackHandler must not be null"); - } - return new AmqPlainSaslClient(cbh); - } - } - return null; - } - - public String[] getMechanismNames(Map props) - { - if (props.containsKey(Sasl.POLICY_NOPLAINTEXT) || - props.containsKey(Sasl.POLICY_NODICTIONARY) || - props.containsKey(Sasl.POLICY_NOACTIVE)) - { - // returned array must be non null according to interface documentation - return new String[0]; - } - else - { - return new String[]{AmqPlainSaslClient.MECHANISM}; - } - } -} diff --git a/client/src/org/apache/qpid/client/state/AMQState.java b/client/src/org/apache/qpid/client/state/AMQState.java deleted file mode 100644 index 4996f59345..0000000000 --- a/client/src/org/apache/qpid/client/state/AMQState.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.state; - -/** - * States used in the AMQ protocol. Used by the finite state machine to determine - * valid responses. - */ -public class AMQState -{ - private final int _id; - - private final String _name; - - private AMQState(int id, String name) - { - _id = id; - _name = name; - } - - public String toString() - { - return "AMQState: id = " + _id + " name: " + _name; - } - - public static final AMQState CONNECTION_NOT_STARTED = new AMQState(1, "CONNECTION_NOT_STARTED"); - - public static final AMQState CONNECTION_NOT_TUNED = new AMQState(2, "CONNECTION_NOT_TUNED"); - - public static final AMQState CONNECTION_NOT_OPENED = new AMQState(3, "CONNECTION_NOT_OPENED"); - - public static final AMQState CONNECTION_OPEN = new AMQState(4, "CONNECTION_OPEN"); - - public static final AMQState CONNECTION_CLOSING = new AMQState(5, "CONNECTION_CLOSING"); - - public static final AMQState CONNECTION_CLOSED = new AMQState(6, "CONNECTION_CLOSED"); - -} diff --git a/client/src/org/apache/qpid/client/state/AMQStateChangedEvent.java b/client/src/org/apache/qpid/client/state/AMQStateChangedEvent.java deleted file mode 100644 index edef54ccd6..0000000000 --- a/client/src/org/apache/qpid/client/state/AMQStateChangedEvent.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.state; - -/** - * An event that is fired when the protocol state has changed. - * - */ -public class AMQStateChangedEvent -{ - private final AMQState _oldState; - - private final AMQState _newState; - - public AMQStateChangedEvent(AMQState oldState, AMQState newState) - { - _oldState = oldState; - _newState = newState; - } - - public AMQState getOldState() - { - return _oldState; - } - - public AMQState getNewState() - { - return _newState; - } -} diff --git a/client/src/org/apache/qpid/client/state/AMQStateListener.java b/client/src/org/apache/qpid/client/state/AMQStateListener.java deleted file mode 100644 index 110471aad0..0000000000 --- a/client/src/org/apache/qpid/client/state/AMQStateListener.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.state; - -public interface AMQStateListener -{ - void stateChanged(AMQStateChangedEvent evt); -} diff --git a/client/src/org/apache/qpid/client/state/AMQStateManager.java b/client/src/org/apache/qpid/client/state/AMQStateManager.java deleted file mode 100644 index ab707bb51d..0000000000 --- a/client/src/org/apache/qpid/client/state/AMQStateManager.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.state; - -import org.apache.qpid.AMQException; -import org.apache.qpid.client.handler.*; -import org.apache.qpid.client.protocol.AMQMethodEvent; -import org.apache.qpid.client.protocol.AMQMethodListener; -import org.apache.qpid.framing.*; -import org.apache.log4j.Logger; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.concurrent.CopyOnWriteArraySet; - -/** - * The state manager is responsible for managing the state of the protocol session. - * <p/> - * For each AMQProtocolHandler there is a separate state manager. - */ -public class AMQStateManager implements AMQMethodListener -{ - private static final Logger _logger = Logger.getLogger(AMQStateManager.class); - - /** - * The current state - */ - private AMQState _currentState; - - /** - * Maps from an AMQState instance to a Map from Class to StateTransitionHandler. - * The class must be a subclass of AMQFrame. - */ - private final Map _state2HandlersMap = new HashMap(); - - private final CopyOnWriteArraySet _stateListeners = new CopyOnWriteArraySet(); - - public AMQStateManager() - { - this(AMQState.CONNECTION_NOT_STARTED, true); - } - - protected AMQStateManager(AMQState state, boolean register) - { - _currentState = state; - if(register) - { - registerListeners(); - } - } - - protected void registerListeners() - { - Map frame2handlerMap = new HashMap(); - - // we need to register a map for the null (i.e. all state) handlers otherwise you get - // a stack overflow in the handler searching code when you present it with a frame for which - // no handlers are registered - // - _state2HandlersMap.put(null, frame2handlerMap); - - frame2handlerMap = new HashMap(); - frame2handlerMap.put(ConnectionStartBody.class, ConnectionStartMethodHandler.getInstance()); - frame2handlerMap.put(ConnectionCloseBody.class, ConnectionCloseMethodHandler.getInstance()); - _state2HandlersMap.put(AMQState.CONNECTION_NOT_STARTED, frame2handlerMap); - - frame2handlerMap = new HashMap(); - frame2handlerMap.put(ConnectionTuneBody.class, ConnectionTuneMethodHandler.getInstance()); - frame2handlerMap.put(ConnectionSecureBody.class, ConnectionSecureMethodHandler.getInstance()); - frame2handlerMap.put(ConnectionCloseBody.class, ConnectionCloseMethodHandler.getInstance()); - _state2HandlersMap.put(AMQState.CONNECTION_NOT_TUNED, frame2handlerMap); - - frame2handlerMap = new HashMap(); - frame2handlerMap.put(ConnectionOpenOkBody.class, ConnectionOpenOkMethodHandler.getInstance()); - frame2handlerMap.put(ConnectionCloseBody.class, ConnectionCloseMethodHandler.getInstance()); - _state2HandlersMap.put(AMQState.CONNECTION_NOT_OPENED, frame2handlerMap); - - // - // ConnectionOpen handlers - // - frame2handlerMap = new HashMap(); - frame2handlerMap.put(ChannelCloseBody.class, ChannelCloseMethodHandler.getInstance()); - frame2handlerMap.put(ChannelCloseOkBody.class, ChannelCloseOkMethodHandler.getInstance()); - frame2handlerMap.put(ConnectionCloseBody.class, ConnectionCloseMethodHandler.getInstance()); - frame2handlerMap.put(BasicDeliverBody.class, BasicDeliverMethodHandler.getInstance()); - frame2handlerMap.put(BasicReturnBody.class, BasicReturnMethodHandler.getInstance()); - frame2handlerMap.put(ChannelFlowOkBody.class, ChannelFlowOkMethodHandler.getInstance()); - _state2HandlersMap.put(AMQState.CONNECTION_OPEN, frame2handlerMap); - } - - public AMQState getCurrentState() - { - return _currentState; - } - - public void changeState(AMQState newState) throws AMQException - { - _logger.debug("State changing to " + newState + " from old state " + _currentState); - final AMQState oldState = _currentState; - _currentState = newState; - - synchronized (_stateListeners) - { - final Iterator it = _stateListeners.iterator(); - while (it.hasNext()) - { - final StateListener l = (StateListener) it.next(); - l.stateChanged(oldState, newState); - } - } - } - - public void error(Exception e) - { - _logger.debug("State manager receive error notification: " + e); - synchronized (_stateListeners) - { - final Iterator it = _stateListeners.iterator(); - while (it.hasNext()) - { - final StateListener l = (StateListener) it.next(); - l.error(e); - } - } - } - - public boolean methodReceived(AMQMethodEvent evt) throws AMQException - { - StateAwareMethodListener handler = findStateTransitionHandler(_currentState, evt.getMethod()); - if (handler != null) - { - handler.methodReceived(this, evt); - return true; - } - return false; - } - - protected StateAwareMethodListener findStateTransitionHandler(AMQState currentState, - AMQMethodBody frame) - throws IllegalStateTransitionException - { - final Class clazz = frame.getClass(); - if (_logger.isDebugEnabled()) - { - _logger.debug("Looking for state transition handler for frame " + clazz); - } - final Map classToHandlerMap = (Map) _state2HandlersMap.get(currentState); - - if (classToHandlerMap == null) - { - // if no specialised per state handler is registered look for a - // handler registered for "all" states - return findStateTransitionHandler(null, frame); - } - final StateAwareMethodListener handler = (StateAwareMethodListener) classToHandlerMap.get(clazz); - if (handler == null) - { - if (currentState == null) - { - _logger.debug("No state transition handler defined for receiving frame " + frame); - return null; - } - else - { - // if no specialised per state handler is registered look for a - // handler registered for "all" states - return findStateTransitionHandler(null, frame); - } - } - else - { - return handler; - } - } - - public void addStateListener(StateListener listener) - { - _logger.debug("Adding state listener"); - _stateListeners.add(listener); - } - - public void removeStateListener(StateListener listener) - { - _stateListeners.remove(listener); - } - - public void attainState(AMQState s) throws AMQException - { - boolean needToWait = false; - StateWaiter sw = null; - synchronized (_stateListeners) - { - if (_currentState != s) - { - _logger.debug("Adding state wait to reach state " + s); - sw = new StateWaiter(s); - addStateListener(sw); - // we use a boolean since we must release the lock before starting to wait - needToWait = true; - } - } - if (needToWait) - { - sw.waituntilStateHasChanged(); - } - // at this point the state will have changed. - } -} diff --git a/client/src/org/apache/qpid/client/state/IllegalStateTransitionException.java b/client/src/org/apache/qpid/client/state/IllegalStateTransitionException.java deleted file mode 100644 index bd1145da9f..0000000000 --- a/client/src/org/apache/qpid/client/state/IllegalStateTransitionException.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.state; - -import org.apache.qpid.AMQException; - -public class IllegalStateTransitionException extends AMQException -{ - private AMQState _originalState; - - private Class _frame; - - public IllegalStateTransitionException(AMQState originalState, Class frame) - { - super("No valid state transition defined for receiving frame " + frame + - " from state " + originalState); - _originalState = originalState; - _frame = frame; - } - - public AMQState getOriginalState() - { - return _originalState; - } - - public Class getFrameClass() - { - return _frame; - } -} diff --git a/client/src/org/apache/qpid/client/state/StateAwareMethodListener.java b/client/src/org/apache/qpid/client/state/StateAwareMethodListener.java deleted file mode 100644 index 37a0f9f376..0000000000 --- a/client/src/org/apache/qpid/client/state/StateAwareMethodListener.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.state; - -import org.apache.qpid.client.protocol.AMQMethodEvent; -import org.apache.qpid.AMQException; - -/** - * A frame listener that is informed of the protocl state when invoked and has - * the opportunity to update state. - * - */ -public interface StateAwareMethodListener -{ - void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException; -} diff --git a/client/src/org/apache/qpid/client/state/StateListener.java b/client/src/org/apache/qpid/client/state/StateListener.java deleted file mode 100644 index df207a0a23..0000000000 --- a/client/src/org/apache/qpid/client/state/StateListener.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.state; - -import org.apache.qpid.AMQException; - -public interface StateListener -{ - void stateChanged(AMQState oldState, AMQState newState) throws AMQException; - - void error(Throwable t); -} diff --git a/client/src/org/apache/qpid/client/state/StateWaiter.java b/client/src/org/apache/qpid/client/state/StateWaiter.java deleted file mode 100644 index 42ae5a7b17..0000000000 --- a/client/src/org/apache/qpid/client/state/StateWaiter.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.state; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; - -/** - * Waits for a particular state to be reached. - * - */ -public class StateWaiter implements StateListener -{ - private static final Logger _logger = Logger.getLogger(StateWaiter.class); - - private final AMQState _state; - - private volatile boolean _newStateAchieved; - - private volatile Throwable _throwable; - - private final Object _monitor = new Object(); - - public StateWaiter(AMQState state) - { - _state = state; - } - - public void waituntilStateHasChanged() throws AMQException - { - synchronized (_monitor) - { - // - // The guard is required in case we are woken up by a spurious - // notify(). - // - while (!_newStateAchieved && _throwable == null) - { - try - { - _logger.debug("State " + _state + " not achieved so waiting..."); - _monitor.wait(); - } - catch (InterruptedException e) - { - _logger.debug("Interrupted exception caught while waiting: " + e, e); - } - } - } - - if (_throwable != null) - { - _logger.debug("Throwable reached state waiter: " + _throwable); - if (_throwable instanceof AMQException) - { - throw (AMQException) _throwable; - } - else - { - throw new AMQException("Error: " + _throwable, _throwable); // FIXME: this will wrap FailoverException in throwable which will prevent it being caught. - } - } - } - - public void stateChanged(AMQState oldState, AMQState newState) - { - synchronized (_monitor) - { - if (_logger.isDebugEnabled()) - { - _logger.debug("stateChanged called"); - } - if (_state == newState) - { - _newStateAchieved = true; - - if (_logger.isDebugEnabled()) - { - _logger.debug("New state reached so notifying monitor"); - } - _monitor.notifyAll(); - } - } - } - - public void error(Throwable t) - { - synchronized (_monitor) - { - if (_logger.isDebugEnabled()) - { - _logger.debug("exceptionThrown called"); - } - - _throwable = t; - _monitor.notifyAll(); - } - } -} diff --git a/client/src/org/apache/qpid/client/state/listener/SpecificMethodFrameListener.java b/client/src/org/apache/qpid/client/state/listener/SpecificMethodFrameListener.java deleted file mode 100644 index 480d73e59e..0000000000 --- a/client/src/org/apache/qpid/client/state/listener/SpecificMethodFrameListener.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.state.listener; - -import org.apache.qpid.client.protocol.BlockingMethodFrameListener; -import org.apache.qpid.framing.AMQMethodBody; -import org.apache.qpid.AMQException; - -public class SpecificMethodFrameListener extends BlockingMethodFrameListener -{ - private final Class _expectedClass; - - public SpecificMethodFrameListener(int channelId, Class expectedClass) - { - super(channelId); - _expectedClass = expectedClass; - } - - public boolean processMethod(int channelId, AMQMethodBody frame) throws AMQException - { - return _expectedClass.isInstance(frame); - } -} diff --git a/client/src/org/apache/qpid/client/transport/AMQNoTransportForProtocolException.java b/client/src/org/apache/qpid/client/transport/AMQNoTransportForProtocolException.java deleted file mode 100644 index 93c17520b0..0000000000 --- a/client/src/org/apache/qpid/client/transport/AMQNoTransportForProtocolException.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.transport; - -import org.apache.qpid.jms.BrokerDetails; -import org.apache.qpid.AMQException; - -public class AMQNoTransportForProtocolException extends AMQTransportConnectionException -{ - BrokerDetails _details; - - public AMQNoTransportForProtocolException(BrokerDetails details) - { - this(details, "No Transport exists for specified broker protocol"); - } - - public AMQNoTransportForProtocolException(BrokerDetails details, String message) - { - super(message); - - _details = details; - } - - public String toString() - { - if (_details != null) - { - return super.toString() + _details.toString(); - } - else - { - return super.toString(); - } - } -} diff --git a/client/src/org/apache/qpid/client/transport/AMQTransportConnectionException.java b/client/src/org/apache/qpid/client/transport/AMQTransportConnectionException.java deleted file mode 100644 index 4b17661bc3..0000000000 --- a/client/src/org/apache/qpid/client/transport/AMQTransportConnectionException.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.transport; - -import org.apache.qpid.AMQException; - -public class AMQTransportConnectionException extends AMQException -{ - public AMQTransportConnectionException(String message) - { - super(message); - - } -} diff --git a/client/src/org/apache/qpid/client/transport/ITransportConnection.java b/client/src/org/apache/qpid/client/transport/ITransportConnection.java deleted file mode 100644 index 7630f59115..0000000000 --- a/client/src/org/apache/qpid/client/transport/ITransportConnection.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.transport; - -import org.apache.qpid.client.protocol.AMQProtocolHandler; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.jms.BrokerDetails; - -import java.io.IOException; - -public interface ITransportConnection -{ - void connect(AMQProtocolHandler protocolHandler, BrokerDetails brokerDetail) - throws IOException; -} diff --git a/client/src/org/apache/qpid/client/transport/SocketTransportConnection.java b/client/src/org/apache/qpid/client/transport/SocketTransportConnection.java deleted file mode 100644 index 78d937f453..0000000000 --- a/client/src/org/apache/qpid/client/transport/SocketTransportConnection.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.transport; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.protocol.AMQProtocolHandler; -import org.apache.qpid.pool.ReadWriteThreadModel; -import org.apache.qpid.jms.BrokerDetails; -import org.apache.log4j.Logger; -import org.apache.mina.common.ByteBuffer; -import org.apache.mina.common.ConnectFuture; -import org.apache.mina.common.IoConnector; -import org.apache.mina.common.SimpleByteBufferAllocator; -import org.apache.mina.transport.socket.nio.SocketConnectorConfig; -import org.apache.mina.transport.socket.nio.SocketSessionConfig; - -import java.io.IOException; -import java.net.InetSocketAddress; - -public class SocketTransportConnection implements ITransportConnection -{ - private static final Logger _logger = Logger.getLogger(SocketTransportConnection.class); - private static final int DEFAULT_BUFFER_SIZE = 32 * 1024; - - private SocketConnectorFactory _socketConnectorFactory; - - static interface SocketConnectorFactory { - IoConnector newSocketConnector(); - } - - public SocketTransportConnection(SocketConnectorFactory socketConnectorFactory) - { - _socketConnectorFactory = socketConnectorFactory; - } - - public void connect(AMQProtocolHandler protocolHandler, BrokerDetails brokerDetail) - throws IOException - { - ByteBuffer.setUseDirectBuffers(Boolean.getBoolean("amqj.enableDirectBuffers")); - - // the MINA default is currently to use the pooled allocator although this may change in future - // once more testing of the performance of the simple allocator has been done - if (!Boolean.getBoolean("amqj.enablePooledAllocator")) - { - ByteBuffer.setAllocator(new SimpleByteBufferAllocator()); - } - - final IoConnector ioConnector = _socketConnectorFactory.newSocketConnector(); - SocketConnectorConfig cfg = (SocketConnectorConfig) ioConnector.getDefaultConfig(); - - // if we do not use our own thread model we get the MINA default which is to use - // its own leader-follower model - boolean readWriteThreading = Boolean.getBoolean("amqj.shared_read_write_pool"); - if (readWriteThreading) - { - cfg.setThreadModel(new ReadWriteThreadModel()); - } - - SocketSessionConfig scfg = (SocketSessionConfig) cfg.getSessionConfig(); - scfg.setTcpNoDelay("true".equalsIgnoreCase(System.getProperty("amqj.tcpNoDelay", "true"))); - scfg.setSendBufferSize(Integer.getInteger("amqj.sendBufferSize", DEFAULT_BUFFER_SIZE)); - _logger.info("send-buffer-size = " + scfg.getSendBufferSize()); - scfg.setReceiveBufferSize(Integer.getInteger("amqj.receiveBufferSize", DEFAULT_BUFFER_SIZE)); - _logger.info("recv-buffer-size = " + scfg.getReceiveBufferSize()); - final InetSocketAddress address = new InetSocketAddress(brokerDetail.getHost(), brokerDetail.getPort()); - protocolHandler.setUseSSL(brokerDetail.useSSL()); - _logger.info("Attempting connection to " + address); - ConnectFuture future = ioConnector.connect(address, protocolHandler); - - // wait for connection to complete - if (future.join(brokerDetail.getTimeout())) - { - // we call getSession which throws an IOException if there has been an error connecting - future.getSession(); - } - else - { - throw new IOException("Timeout waiting for connection."); - } - } -} diff --git a/client/src/org/apache/qpid/client/transport/TransportConnection.java b/client/src/org/apache/qpid/client/transport/TransportConnection.java deleted file mode 100644 index ead8308143..0000000000 --- a/client/src/org/apache/qpid/client/transport/TransportConnection.java +++ /dev/null @@ -1,320 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.transport; - -import org.apache.log4j.Logger; -import org.apache.mina.common.IoConnector; -import org.apache.mina.common.IoHandlerAdapter; -import org.apache.mina.common.IoServiceConfig; - - -import org.apache.mina.transport.vmpipe.VmPipeAcceptor; -import org.apache.mina.transport.vmpipe.VmPipeAddress; -import org.apache.mina.transport.socket.nio.SocketConnector; -import org.apache.qpid.client.AMQBrokerDetails; -import org.apache.qpid.jms.BrokerDetails; -import org.apache.qpid.pool.ReadWriteThreadModel; -import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException; - - -import java.io.IOException; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -/** - * The TransportConnection is a helper class responsible for connecting to an AMQ server. It sets up - * the underlying connector, which currently always uses TCP/IP sockets. It creates the - * "protocol handler" which deals with MINA protocol events. - * <p/> - * Could be extended in future to support different transport types by turning this into concrete class/interface - * combo. - */ -public class TransportConnection -{ - private static ITransportConnection _instance; - - private static Map _inVmPipeAddress = new HashMap(); - private static VmPipeAcceptor _acceptor; - private static int _currentInstance = -1; - private static int _currentVMPort = -1; - - private static final int TCP = 0; - private static final int VM = 1; - - private static Logger _logger = Logger.getLogger(TransportConnection.class); - - private static final String DEFAULT_QPID_SERVER = "org.apache.qpid.server.protocol.AMQPFastProtocolHandler"; - - static - { - _acceptor = new VmPipeAcceptor(); - - IoServiceConfig config = _acceptor.getDefaultConfig(); - - config.setThreadModel(new ReadWriteThreadModel()); - } - - public static ITransportConnection getInstance() throws AMQTransportConnectionException - { - AMQBrokerDetails details = new AMQBrokerDetails(); - details.setTransport(BrokerDetails.TCP); - return getInstance(details); - } - - public static ITransportConnection getInstance(BrokerDetails details) throws AMQTransportConnectionException - { - int transport = getTransport(details.getTransport()); - - if (transport == -1) - - { - throw new AMQNoTransportForProtocolException(details); - } - - if (transport == _currentInstance) - - { - if (transport == VM) - { - if (_currentVMPort == details.getPort()) - { - return _instance; - } - } - else - { - return _instance; - } - } - - _currentInstance = transport; - - switch (transport) - - { - case TCP: - _instance = new SocketTransportConnection(new SocketTransportConnection.SocketConnectorFactory() - { - public IoConnector newSocketConnector() - { - SocketConnector result; - //FIXME - this needs to be sorted to use the new Mina MultiThread SA. - if (Boolean.getBoolean("qpidnio")) - { - _logger.warn("Using Qpid NIO - DISABLED"); -// result = new org.apache.qpid.nio.SocketConnector(); // non-blocking connector - } -// else - { - _logger.warn("Using Mina NIO"); - result = new SocketConnector(); // non-blocking connector - } - - // Don't have the connector's worker thread wait around for other connections (we only use - // one SocketConnector per connection at the moment anyway). This allows short-running - // clients (like unit tests) to complete quickly. - result.setWorkerTimeout(0); - - return result; - } - }); - break; - case VM: - { - _instance = getVMTransport(details, Boolean.getBoolean("amqj.AutoCreateVMBroker")); - break; - } - } - - return _instance; - } - - private static int getTransport(String transport) - { - if (transport.equals(BrokerDetails.TCP)) - { - return TCP; - } - - if (transport.equals(BrokerDetails.VM)) - { - return VM; - } - - return -1; - } - - private static ITransportConnection getVMTransport(BrokerDetails details, boolean AutoCreate) throws AMQVMBrokerCreationException - { - int port = details.getPort(); - - if (!_inVmPipeAddress.containsKey(port)) - { - if (AutoCreate) - { - createVMBroker(port); - } - else - { - throw new AMQVMBrokerCreationException(port, "VM Broker on port " + port + " does not exist. Auto create disabled."); - } - } - - return new VmPipeTransportConnection(port); - } - - - public static void createVMBroker(int port) throws AMQVMBrokerCreationException - { - - - if (!_inVmPipeAddress.containsKey(port)) - { - _logger.info("Creating InVM Qpid.AMQP listening on port " + port); - IoHandlerAdapter provider = null; - try - { - VmPipeAddress pipe = new VmPipeAddress(port); - - provider = createBrokerInstance(port); - - _acceptor.bind(pipe, provider); - - _inVmPipeAddress.put(port, pipe); - _logger.info("Created InVM Qpid.AMQP listening on port " + port); - } - catch (IOException e) - { - _logger.error(e); - - //Try and unbind provider - try - { - VmPipeAddress pipe = new VmPipeAddress(port); - - try - { - _acceptor.unbind(pipe); - } - catch (Exception ignore) - { - //ignore - } - - if (provider == null) - { - provider = createBrokerInstance(port); - } - - _acceptor.bind(pipe, provider); - _inVmPipeAddress.put(port, pipe); - _logger.info("Created InVM Qpid.AMQP listening on port " + port); - } - catch (IOException justUseFirstException) - { - String because; - if (e.getCause() == null) - { - because = e.toString(); - } - else - { - because = e.getCause().toString(); - } - - throw new AMQVMBrokerCreationException(port, because + " Stopped binding of InVM Qpid.AMQP"); - } - } - } - else - { - _logger.info("InVM Qpid.AMQP on port " + port + " already exits."); - } - - } - - private static IoHandlerAdapter createBrokerInstance(int port) throws AMQVMBrokerCreationException - { - String protocolProviderClass = System.getProperty("amqj.protocolprovider.class", DEFAULT_QPID_SERVER); - _logger.info("Creating Qpid protocol provider: " + protocolProviderClass); - - // can't use introspection to get Provider as it is a server class. - // need to go straight to IoHandlerAdapter but that requries the queues and exchange from the ApplicationRegistry which we can't access. - - //get right constructor and pass in instancec ID - "port" - IoHandlerAdapter provider; - try - { - Class[] cnstr = {Integer.class}; - Object[] params = {port}; - provider = (IoHandlerAdapter) Class.forName(protocolProviderClass).getConstructor(cnstr).newInstance(params); - //Give the broker a second to create - _logger.info("Created Instance"); - } - catch (Exception e) - { - _logger.info("Unable to create InVM Qpid.AMQP on port " + port + ". Because: " + e.getCause()); - _logger.error(e); - String because; - if (e.getCause() == null) - { - because = e.toString(); - } - else - { - because = e.getCause().toString(); - } - - - throw new AMQVMBrokerCreationException(port, because + " Stopped InVM Qpid.AMQP creation"); - } - - return provider; - } - - public static void killAllVMBrokers() - { - _logger.info("Killing all VM Brokers"); - _acceptor.unbindAll(); - - Iterator keys = _inVmPipeAddress.keySet().iterator(); - - while (keys.hasNext()) - { - int id = (Integer) keys.next(); - _inVmPipeAddress.remove(id); - } - - } - - public static void killVMBroker(int port) - { - VmPipeAddress pipe = (VmPipeAddress) _inVmPipeAddress.get(port); - if (pipe != null) - { - _logger.info("Killing VM Broker:" + port); - _inVmPipeAddress.remove(port); - _acceptor.unbind(pipe); - } - } - -} diff --git a/client/src/org/apache/qpid/client/transport/VmPipeTransportConnection.java b/client/src/org/apache/qpid/client/transport/VmPipeTransportConnection.java deleted file mode 100644 index 6287d70a56..0000000000 --- a/client/src/org/apache/qpid/client/transport/VmPipeTransportConnection.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.transport; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.protocol.AMQProtocolHandler; -import org.apache.qpid.client.transport.ITransportConnection; -import org.apache.qpid.pool.PoolingFilter; -import org.apache.qpid.pool.ReferenceCountingExecutorService; -import org.apache.qpid.jms.BrokerDetails; -import org.apache.log4j.Logger; -import org.apache.mina.common.ConnectFuture; -import org.apache.mina.common.IoServiceConfig; -import org.apache.mina.transport.vmpipe.VmPipeAddress; -import org.apache.mina.transport.vmpipe.VmPipeConnector; - -import java.io.IOException; - -public class VmPipeTransportConnection implements ITransportConnection -{ - private static final Logger _logger = Logger.getLogger(VmPipeTransportConnection.class); - - private static int _port; - - public VmPipeTransportConnection(int port) - { - _port = port; - } - - public void connect(AMQProtocolHandler protocolHandler, BrokerDetails brokerDetail) throws IOException - { - final VmPipeConnector ioConnector = new VmPipeConnector(); - final IoServiceConfig cfg = ioConnector.getDefaultConfig(); - ReferenceCountingExecutorService executorService = ReferenceCountingExecutorService.getInstance(); - PoolingFilter asyncRead = new PoolingFilter(executorService, PoolingFilter.READ_EVENTS, - "AsynchronousReadFilter"); - cfg.getFilterChain().addFirst("AsynchronousReadFilter", asyncRead); - PoolingFilter asyncWrite = new PoolingFilter(executorService, PoolingFilter.WRITE_EVENTS, - "AsynchronousWriteFilter"); - cfg.getFilterChain().addLast("AsynchronousWriteFilter", asyncWrite); - - final VmPipeAddress address = new VmPipeAddress(_port); - _logger.info("Attempting connection to " + address); - ConnectFuture future = ioConnector.connect(address, protocolHandler); - // wait for connection to complete - future.join(); - // we call getSession which throws an IOException if there has been an error connecting - future.getSession(); - } -} diff --git a/client/src/org/apache/qpid/client/util/FlowControllingBlockingQueue.java b/client/src/org/apache/qpid/client/util/FlowControllingBlockingQueue.java deleted file mode 100644 index 5b7144b524..0000000000 --- a/client/src/org/apache/qpid/client/util/FlowControllingBlockingQueue.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.util; - -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; - -/** - * A blocking queue that emits events above a user specified threshold allowing - * the caller to take action (e.g. flow control) to try to prevent the queue - * growing (much) further. The underlying queue itself is not bounded therefore - * the caller is not obliged to react to the events. - * <p/> - * This implementation is <b>only</b> safe where we have a single thread adding - * items and a single (different) thread removing items. - */ -public class FlowControllingBlockingQueue -{ - /** - * This queue is bounded and is used to store messages before being dispatched to the consumer - */ - private final BlockingQueue _queue = new LinkedBlockingQueue(); - - private final int _flowControlHighThreshold; - private final int _flowControlLowThreshold; - - private final ThresholdListener _listener; - - /** - * We require a separate count so we can track whether we have reached the - * threshold - */ - private int _count; - - public interface ThresholdListener - { - void aboveThreshold(int currentValue); - - void underThreshold(int currentValue); - } - - public FlowControllingBlockingQueue(int threshold, ThresholdListener listener) - { - this(threshold, threshold, listener); - } - - public FlowControllingBlockingQueue(int highThreshold, int lowThreshold, ThresholdListener listener) - { - _flowControlHighThreshold = highThreshold; - _flowControlLowThreshold = lowThreshold; - _listener = listener; - } - - public Object take() throws InterruptedException - { - Object o = _queue.take(); - if (_listener != null) - { - synchronized(_listener) - { - if (_count-- == _flowControlLowThreshold) - { - _listener.underThreshold(_count); - } - } - } - return o; - } - - public void add(Object o) - { - _queue.add(o); - if (_listener != null) - { - synchronized(_listener) - { - if (++_count == _flowControlHighThreshold) - { - _listener.aboveThreshold(_count); - } - } - } - } -} - diff --git a/client/src/org/apache/qpid/client/vmbroker/AMQVMBrokerCreationException.java b/client/src/org/apache/qpid/client/vmbroker/AMQVMBrokerCreationException.java deleted file mode 100644 index 607ddcc26a..0000000000 --- a/client/src/org/apache/qpid/client/vmbroker/AMQVMBrokerCreationException.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.vmbroker; - -import org.apache.qpid.client.transport.AMQTransportConnectionException; - -public class AMQVMBrokerCreationException extends AMQTransportConnectionException -{ - private int _port; - - public AMQVMBrokerCreationException(int port) - { - this(port, "Unable to create vm broker"); - } - - public AMQVMBrokerCreationException(int port, String message) - { - super(message); - _port = port; - } - - public String toString() - { - return super.toString() + " on port " + _port; - } -} diff --git a/client/src/org/apache/qpid/jms/BrokerDetails.java b/client/src/org/apache/qpid/jms/BrokerDetails.java deleted file mode 100644 index 293ce5e82e..0000000000 --- a/client/src/org/apache/qpid/jms/BrokerDetails.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.jms; - -public interface BrokerDetails -{ - - /* - * Known URL Options - * @see ConnectionURL - */ - public static final String OPTIONS_RETRY = "retries"; - public static final String OPTIONS_SSL = ConnectionURL.OPTIONS_SSL; - public static final String OPTIONS_CONNECT_TIMEOUT = "connecttimeout"; - public static final int DEFAULT_PORT = 5672; - - public static final String TCP = "tcp"; - public static final String VM = "vm"; - - public static final String DEFAULT_TRANSPORT = TCP; - - public static final String URL_FORMAT_EXAMPLE = - "<transport>://<hostname>[:<port Default=\"" + DEFAULT_PORT + "\">][?<option>='<value>'[,<option>='<value>']]"; - - public static final long DEFAULT_CONNECT_TIMEOUT = 30000L; - public static final boolean USE_SSL_DEFAULT = false; - - String getHost(); - - void setHost(String host); - - int getPort(); - - void setPort(int port); - - String getTransport(); - - void setTransport(String transport); - - boolean useSSL(); - - void useSSL(boolean ssl); - - String getOption(String key); - - void setOption(String key, String value); - - long getTimeout(); - - void setTimeout(long timeout); - - String toString(); - - boolean equals(Object o); -} diff --git a/client/src/org/apache/qpid/jms/ChannelLimitReachedException.java b/client/src/org/apache/qpid/jms/ChannelLimitReachedException.java deleted file mode 100644 index 3d4a4573ed..0000000000 --- a/client/src/org/apache/qpid/jms/ChannelLimitReachedException.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.jms; - -import javax.jms.ResourceAllocationException; - -/** - * Indicates that the maximum number of sessions per connection limit has been reached. - */ -public class ChannelLimitReachedException extends ResourceAllocationException -{ - private static final String ERROR_CODE = "1"; - - private long _limit; - - public ChannelLimitReachedException(long limit) - { - super("Unable to create session since maximum number of sessions per connection is " + - limit + ". Either close one or more sessions or increase the " + - "maximum number of sessions per connection (or contact your AMQP administrator.", ERROR_CODE); - _limit = limit; - } - - public long getLimit() - { - return _limit; - } -} diff --git a/client/src/org/apache/qpid/jms/Connection.java b/client/src/org/apache/qpid/jms/Connection.java deleted file mode 100644 index 616c6dbbec..0000000000 --- a/client/src/org/apache/qpid/jms/Connection.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.jms; - -import javax.jms.JMSException; - -public interface Connection extends javax.jms.Connection -{ - /** - * @return the maximum number of sessions supported by this Connection - */ - long getMaximumChannelCount() throws JMSException; - - void setConnectionListener(ConnectionListener listener); - - /** - * Get the connection listener that has been registered with this connection, if any - * - * @return the listener or null if none has been set - */ - ConnectionListener getConnectionListener(); - - /** - * Create a session specifying the prefetch limit of messages. - * - * @param transacted - * @param acknowledgeMode - * @param prefetch the maximum number of messages to buffer in the client. This - * applies as a total across all consumers - * @return - * @throws JMSException - */ - org.apache.qpid.jms.Session createSession(boolean transacted, int acknowledgeMode, - int prefetch) throws JMSException; - - - /** - * Create a session specifying the prefetch limit of messages. - * - * @param transacted - * @param acknowledgeMode - * @param prefetchHigh the maximum number of messages to buffer in the client. - * This applies as a total across all consumers - * @param prefetchLow the number of messages that must be in the buffer in the client to renable message flow. - * This applies as a total across all consumers - * @return - * @throws JMSException - */ - org.apache.qpid.jms.Session createSession(boolean transacted, int acknowledgeMode, - int prefetchHigh, int prefetchLow) throws JMSException; -} diff --git a/client/src/org/apache/qpid/jms/ConnectionListener.java b/client/src/org/apache/qpid/jms/ConnectionListener.java deleted file mode 100644 index 11c235901c..0000000000 --- a/client/src/org/apache/qpid/jms/ConnectionListener.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.jms; - -public interface ConnectionListener -{ - /** - * Called when bytes have been transmitted to the server - * @param count the number of bytes sent in total since the connection was opened - */ - void bytesSent(long count); - - /** - * Called when some bytes have been received on a connection - * @param count the number of bytes received in total since the connection was opened - */ - void bytesReceived(long count); - - /** - * Called after the infrastructure has detected that failover is required but before attempting failover. - * @param redirect true if the broker requested redirect. false if failover is occurring due to a connection error. - * @return true to continue failing over, false to veto failover and raise a connection exception - */ - boolean preFailover(boolean redirect); - - /** - * Called after connection has been made to another broker after failover has been started but before - * any resubscription has been done. - * @return true to continue with resubscription, false to prevent automatic resubscription. This is useful in - * cases where the application wants to handle resubscription. Note that in the latter case all sessions, producers - * and consumers are invalidated. - */ - boolean preResubscribe(); - - /** - * Called once failover has completed successfully. This is called irrespective of whether the client has - * vetoed automatic resubscription. - */ - void failoverComplete(); -} diff --git a/client/src/org/apache/qpid/jms/ConnectionURL.java b/client/src/org/apache/qpid/jms/ConnectionURL.java deleted file mode 100644 index caadb0f621..0000000000 --- a/client/src/org/apache/qpid/jms/ConnectionURL.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.jms; - -import java.util.List; - -/** - Connection URL format - amqp://[user:pass@][clientid]/virtualhost?brokerlist='tcp://host:port?option=\'value\'&option=\'value\';vm://:3/virtualpath?option=\'value\''&failover='method?option=\'value\'&option='value''" - Options are of course optional except for requiring a single broker in the broker list. - The option seperator is defined to be either '&' or ',' - */ -public interface ConnectionURL -{ - public static final String AMQ_PROTOCOL = "amqp"; - public static final String OPTIONS_BROKERLIST = "brokerlist"; - public static final String OPTIONS_FAILOVER = "failover"; - public static final String OPTIONS_FAILOVER_CYCLE = "cyclecount"; - public static final String OPTIONS_SSL = "ssl"; - - String getURL(); - - String getFailoverMethod(); - - String getFailoverOption(String key); - - int getBrokerCount(); - - BrokerDetails getBrokerDetails(int index); - - void addBrokerDetails(BrokerDetails broker); - - List<BrokerDetails> getAllBrokerDetails(); - - String getClientName(); - - void setClientName(String clientName); - - String getUsername(); - - void setUsername(String username); - - String getPassword(); - - void setPassword(String password); - - String getVirtualHost(); - - void setVirtualHost(String virtualHost); - - String getOption(String key); - - void setOption(String key, String value); -} diff --git a/client/src/org/apache/qpid/jms/FailoverPolicy.java b/client/src/org/apache/qpid/jms/FailoverPolicy.java deleted file mode 100644 index 63f7a7639e..0000000000 --- a/client/src/org/apache/qpid/jms/FailoverPolicy.java +++ /dev/null @@ -1,319 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.jms; - -import org.apache.qpid.jms.failover.FailoverMethod; -import org.apache.qpid.jms.failover.FailoverRoundRobinServers; -import org.apache.qpid.jms.failover.FailoverSingleServer; -import org.apache.log4j.Logger; - - -public class FailoverPolicy -{ - private static final Logger _logger = Logger.getLogger(FailoverPolicy.class); - - private static final long MINUTE = 60000L; - - private static final long DEFAULT_METHOD_TIMEOUT = 1 * MINUTE; - private static final long DEFAULT_FAILOVER_TIMEOUT = 4 * MINUTE; - - private FailoverMethod _methods[] = new FailoverMethod[1]; - - private int _currentMethod; - - private int _methodsRetries; - - private int _currentRetry; - - private boolean _timing; - - private long _lastMethodTime; - private long _lastFailTime; - - public FailoverPolicy(ConnectionURL connectionDetails) - { - FailoverMethod method; - - //todo This should be integrated in to the connection url when it supports - // multiple strategies. - - _methodsRetries = 0; - - if (connectionDetails.getFailoverMethod() == null) - { - if (connectionDetails.getBrokerCount() > 1) - { - method = new FailoverRoundRobinServers(connectionDetails); - } - else - { - method = new FailoverSingleServer(connectionDetails); - } - } - else - { - String failoverMethod = connectionDetails.getFailoverMethod(); - -/* - if (failoverMethod.equals(FailoverMethod.RANDOM)) - { - //todo write a random connection Failover - } -*/ - if (failoverMethod.equals(FailoverMethod.SINGLE_BROKER)) - { - method = new FailoverRoundRobinServers(connectionDetails); - } - else - { - if (failoverMethod.equals(FailoverMethod.ROUND_ROBIN)) - { - method = new FailoverRoundRobinServers(connectionDetails); - } - else - { - try - { - Class[] constructorSpec = {ConnectionURL.class}; - Object [] params = {connectionDetails}; - - method = (FailoverMethod) ClassLoader.getSystemClassLoader(). - loadClass(failoverMethod). - getConstructor(constructorSpec).newInstance(params); - } - catch (Exception cnfe) - { - throw new IllegalArgumentException("Unknown failover method:" + failoverMethod); - } - } - } - } - - if (method == null) - { - throw new IllegalArgumentException("Unknown failover method specified."); - } - - reset(); - - _methods[_currentMethod] = method; - } - - public FailoverPolicy(FailoverMethod method) - { - this(method, 0); - } - - public FailoverPolicy(FailoverMethod method, int retries) - { - _methodsRetries = retries; - - reset(); - - _methods[_currentMethod] = method; - } - - private void reset() - { - _currentMethod = 0; - _currentRetry = 0; - _timing = false; - - } - - public boolean failoverAllowed() - { - boolean failoverAllowed; - - if (_timing) - { - long now = System.currentTimeMillis(); - - if ((now - _lastMethodTime) >= DEFAULT_METHOD_TIMEOUT) - { - _logger.info("Failover method timeout"); - _lastMethodTime = now; - - if (!nextMethod()) - { - return false; - } - - - } - else - { - if ((now - _lastFailTime) >= DEFAULT_FAILOVER_TIMEOUT) - { - _logger.info("Failover timeout"); - return false; - } - else - { - _lastMethodTime = now; - } - } - } - else - { - _timing = true; - _lastMethodTime = System.currentTimeMillis(); - _lastFailTime = _lastMethodTime; - } - - - if (_methods[_currentMethod].failoverAllowed()) - { - failoverAllowed = true; - } - else - { - if (_currentMethod < (_methods.length - 1)) - { - nextMethod(); - _logger.info("Changing method to " + _methods[_currentMethod].methodName()); - return failoverAllowed(); - } - else - { - return cycleMethods(); - } - } - - return failoverAllowed; - } - - private boolean nextMethod() - { - if (_currentMethod < (_methods.length - 1)) - { - _currentMethod++; - _methods[_currentMethod].reset(); - return true; - } - else - { - return cycleMethods(); - } - } - - private boolean cycleMethods() - { - if (_currentRetry < _methodsRetries) - { - _currentRetry++; - - _currentMethod = 0; - - _logger.info("Retrying methods starting with " + _methods[_currentMethod].methodName()); - _methods[_currentMethod].reset(); - return failoverAllowed(); - } - else - { - _logger.debug("All failover methods exhausted"); - return false; - } - } - - /** - * Notification that connection was successful. - */ - public void attainedConnection() - { - _currentRetry = 0; - - _methods[_currentMethod].attainedConnection(); - - _timing = false; - } - - public BrokerDetails getCurrentBrokerDetails() - { - return _methods[_currentMethod].getCurrentBrokerDetails(); - } - - public BrokerDetails getNextBrokerDetails() - { - return _methods[_currentMethod].getNextBrokerDetails(); - } - - public void setBroker(BrokerDetails broker) - { - _methods[_currentMethod].setBroker(broker); - } - - public void addMethod(FailoverMethod method) - { - int len = _methods.length + 1; - FailoverMethod[] newMethods = new FailoverMethod[len]; - System.arraycopy(_methods, 0, newMethods, 0, _methods.length); - int index = len - 1; - newMethods[index] = method; - _methods = newMethods; - } - - public void setMethodRetries(int retries) - { - _methodsRetries = retries; - } - - public FailoverMethod getCurrentMethod() - { - if (_currentMethod >= 0 && _currentMethod < (_methods.length - 1)) - { - return _methods[_currentMethod]; - } - else - { - return null; - } - } - - public String toString() - { - StringBuffer sb = new StringBuffer(); - - sb.append("Failover Policy:\n"); - - if (failoverAllowed()) - { - sb.append("Failover allowed\n"); - } - else - { - sb.append("Failover not allowed\n"); - } - - sb.append("Failover policy methods\n"); - for (int i = 0; i < _methods.length; i++) - { - - if (i == _currentMethod) - { - sb.append(">"); - } - sb.append(_methods[i].toString()); - } - - return sb.toString(); - } -} diff --git a/client/src/org/apache/qpid/jms/MessageConsumer.java b/client/src/org/apache/qpid/jms/MessageConsumer.java deleted file mode 100644 index caac2b5c1f..0000000000 --- a/client/src/org/apache/qpid/jms/MessageConsumer.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.jms; - -/** - */ -public interface MessageConsumer extends javax.jms.MessageConsumer -{ -} diff --git a/client/src/org/apache/qpid/jms/MessageProducer.java b/client/src/org/apache/qpid/jms/MessageProducer.java deleted file mode 100644 index d73c5eb151..0000000000 --- a/client/src/org/apache/qpid/jms/MessageProducer.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.jms; - -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; -import java.io.UnsupportedEncodingException; - -/** - */ -public interface MessageProducer extends javax.jms.MessageProducer -{ - /** - * Set the default MIME type for messages produced by this producer. This reduces the overhead of each message. - * @param mimeType - */ - void setMimeType(String mimeType) throws JMSException; - - /** - * Set the default encoding for messages produced by this producer. This reduces the overhead of each message. - * @param encoding the encoding as understood by XXXX how do I specify this?? RG - * @throws UnsupportedEncodingException if the encoding is not understood - */ - void setEncoding(String encoding) throws UnsupportedEncodingException, JMSException; - - void send(Destination destination, Message message, int deliveryMode, - int priority, long timeToLive, boolean immediate) - throws JMSException; - - void send(Destination destination, Message message, int deliveryMode, - int priority, long timeToLive, boolean mandatory, boolean immediate) - throws JMSException; -} diff --git a/client/src/org/apache/qpid/jms/Session.java b/client/src/org/apache/qpid/jms/Session.java deleted file mode 100644 index 4b9cbd3339..0000000000 --- a/client/src/org/apache/qpid/jms/Session.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.jms; - -import javax.jms.*; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; - - -public interface Session extends javax.jms.Session -{ - /** - * Indicates that no client acknowledgements are required. Broker assumes that once it has delivered - * a message packet successfully it is acknowledged. - */ - static final int NO_ACKNOWLEDGE = 257; - - /** - * Pre acknowledge means that an ack is sent per message but sent before user code has processed - * the message (i.e. before the onMessage() call or the receive() method has returned). - */ - static final int PRE_ACKNOWLEDGE = 258; - - MessageConsumer createConsumer(Destination destination, - int prefetch, - boolean noLocal, - boolean exclusive, - String selector) throws JMSException; - - MessageConsumer createConsumer(Destination destination, - int prefetchHigh, - int prefetchLow, - boolean noLocal, - boolean exclusive, - String selector) throws JMSException; - - /** - * @return the prefetch value used by default for consumers created on this session. - */ - int getDefaultPrefetch(); - - /** - * @return the High water prefetch value used by default for consumers created on this session. - */ - int getDefaultPrefetchHigh(); - - /** - * @return the Low water prefetch value used by default for consumers created on this session. - */ - int getDefaultPrefetchLow(); - - /** - * Create a producer - * @param destination - * @param mandatory the value of the mandatory flag used by default on the producer - * @param immediate the value of the immediate flag used by default on the producer - * @return - * @throws JMSException - */ - MessageProducer createProducer(Destination destination, boolean mandatory, boolean immediate) - throws JMSException; - - /** - * Create a producer - * @param destination - * @param immediate the value of the immediate flag used by default on the producer - * @return - * @throws JMSException - */ - MessageProducer createProducer(Destination destination, boolean immediate) - throws JMSException; -} diff --git a/client/src/org/apache/qpid/jms/failover/FailoverMethod.java b/client/src/org/apache/qpid/jms/failover/FailoverMethod.java deleted file mode 100644 index d7ec46dea3..0000000000 --- a/client/src/org/apache/qpid/jms/failover/FailoverMethod.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.jms.failover; - -import org.apache.qpid.jms.BrokerDetails; - -public interface FailoverMethod -{ - public static final String SINGLE_BROKER = "singlebroker"; - public static final String ROUND_ROBIN = "roundrobin"; - public static final String RANDOM = "random"; - /** - * Reset the Failover to initial conditions - */ - void reset(); - - /** - * Check if failover is possible for this method - * - * @return true if failover is allowed - */ - boolean failoverAllowed(); - - /** - * Notification to the Failover method that a connection has been attained. - */ - void attainedConnection(); - - /** - * If there is no current BrokerDetails the null will be returned. - * @return The current BrokerDetail value to use - */ - BrokerDetails getCurrentBrokerDetails(); - - /** - * Move to the next BrokerDetails if one is available. - * @return the next BrokerDetail or null if there is none. - */ - BrokerDetails getNextBrokerDetails(); - - /** - * Set the currently active broker to be the new value. - * @param broker The new BrokerDetail value - */ - void setBroker(BrokerDetails broker); - - /** - * Set the retries for this method - * @param maxRetries the maximum number of time to retry this Method - */ - void setRetries(int maxRetries); - - /** - * @return The name of this method for display purposes. - */ - String methodName(); -} diff --git a/client/src/org/apache/qpid/jms/failover/FailoverRoundRobinServers.java b/client/src/org/apache/qpid/jms/failover/FailoverRoundRobinServers.java deleted file mode 100644 index 0d9c5b95c2..0000000000 --- a/client/src/org/apache/qpid/jms/failover/FailoverRoundRobinServers.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.jms.failover; - -import org.apache.qpid.jms.BrokerDetails; -import org.apache.qpid.jms.ConnectionURL; -import org.apache.log4j.Logger; - -public class FailoverRoundRobinServers implements FailoverMethod -{ - private static final Logger _logger = Logger.getLogger(FailoverRoundRobinServers.class); - - /** The default number of times to cycle through all servers */ - public static final int DEFAULT_CYCLE_RETRIES = 0; - /** The default number of times to retry each server */ - public static final int DEFAULT_SERVER_RETRIES = 0; - - /** - * The index into the hostDetails array of the broker to which we are connected - */ - private int _currentBrokerIndex = -1; - - /** - * The number of times to retry connecting for each server - */ - private int _serverRetries; - - /** - * The current number of retry attempts made - */ - private int _currentServerRetry; - - /** - * The number of times to cycle through the servers - */ - private int _cycleRetries; - - /** - * The current number of cycles performed. - */ - private int _currentCycleRetries; - - /** - * Array of BrokerDetail used to make connections. - */ - private ConnectionURL _connectionDetails; - - public FailoverRoundRobinServers(ConnectionURL connectionDetails) - { - if (!(connectionDetails.getBrokerCount() > 0)) - { - throw new IllegalArgumentException("At least one broker details must be specified."); - } - - _connectionDetails = connectionDetails; - - //There is no current broker at startup so set it to -1. - _currentBrokerIndex = -1; - - String cycleRetries = _connectionDetails.getFailoverOption(ConnectionURL.OPTIONS_FAILOVER_CYCLE); - - if (cycleRetries != null) - { - try - { - _cycleRetries = Integer.parseInt(cycleRetries); - } - catch (NumberFormatException nfe) - { - _cycleRetries = DEFAULT_CYCLE_RETRIES; - } - } - - _currentCycleRetries = 0; - - _serverRetries = 0; - _currentServerRetry = -1; - } - - public void reset() - { - _currentBrokerIndex = 0; - _currentCycleRetries = 0; - _currentServerRetry = -1; - } - - public boolean failoverAllowed() - { - return ((_currentCycleRetries < _cycleRetries) - || (_currentServerRetry < _serverRetries) - || (_currentBrokerIndex < (_connectionDetails.getBrokerCount() - 1))); - } - - public void attainedConnection() - { - _currentCycleRetries = 0; - _currentServerRetry = -1; - } - - public BrokerDetails getCurrentBrokerDetails() - { - if (_currentBrokerIndex == -1) - { - return null; - } - - return _connectionDetails.getBrokerDetails(_currentBrokerIndex); - } - - - - public BrokerDetails getNextBrokerDetails() - { - if (_currentBrokerIndex == (_connectionDetails.getBrokerCount() - 1)) - { - if (_currentServerRetry < _serverRetries) - { - if (_currentBrokerIndex == -1) - { - _currentBrokerIndex = 0; - - setBroker(_connectionDetails.getBrokerDetails(_currentBrokerIndex )); - - _logger.info("First run using " + _connectionDetails.getBrokerDetails(_currentBrokerIndex)); - } - else - { - _logger.info("Retrying " + _connectionDetails.getBrokerDetails(_currentBrokerIndex)); - } - - _currentServerRetry++; - } - else - { - _currentCycleRetries++; - //failed to connect to first broker - _currentBrokerIndex = 0; - - setBroker(_connectionDetails.getBrokerDetails(_currentBrokerIndex )); - - // This is zero rather than -1 as we are already retrieving the details. - _currentServerRetry = 0; - } - //else - should force client to stop as max retries has been reached. - } - else - { - if (_currentServerRetry < _serverRetries) - { - if (_currentBrokerIndex == -1) - { - _currentBrokerIndex = 0; - - setBroker(_connectionDetails.getBrokerDetails(_currentBrokerIndex )); - - _logger.info("First run using " + _connectionDetails.getBrokerDetails(_currentBrokerIndex)); - } - else - { - _logger.info("Retrying " + _connectionDetails.getBrokerDetails(_currentBrokerIndex)); - } - _currentServerRetry++; - } - else - { - _currentBrokerIndex++; - - setBroker(_connectionDetails.getBrokerDetails(_currentBrokerIndex )); - // This is zero rather than -1 as we are already retrieving the details. - _currentServerRetry = 0; - } - } - - return _connectionDetails.getBrokerDetails(_currentBrokerIndex); - } - - - public void setBroker(BrokerDetails broker) - { - - _connectionDetails.addBrokerDetails(broker); - - int index = _connectionDetails.getAllBrokerDetails().indexOf(broker); - - String serverRetries = broker.getOption(BrokerDetails.OPTIONS_RETRY); - - if (serverRetries != null) - { - try - { - _serverRetries = Integer.parseInt(serverRetries); - } - catch (NumberFormatException nfe) - { - _serverRetries = DEFAULT_SERVER_RETRIES; - } - } - - _currentServerRetry = -1; - _currentBrokerIndex = index; - } - - public void setRetries(int maxRetries) - { - _cycleRetries = maxRetries; - } - - public String methodName() - { - return "Cycle Servers"; - } - - public String toString() - { - StringBuffer sb = new StringBuffer(); - - sb.append("Cycle Servers:\n"); - - sb.append("Cycle Retries:"); - sb.append(_cycleRetries); - sb.append("\nCurrent Cycle:"); - sb.append(_currentCycleRetries); - sb.append("\nServer Retries:"); - sb.append(_serverRetries); - sb.append("\nCurrent Retry:"); - sb.append(_currentServerRetry); - sb.append("\nCurrent Broker:"); - sb.append(_currentBrokerIndex); - sb.append("\n"); - - for(int i=0; i < _connectionDetails.getBrokerCount() ; i++) - { - if (i == _currentBrokerIndex) - { - sb.append(">"); - } - sb.append(_connectionDetails.getBrokerDetails(i)); - sb.append("\n"); - } - - return sb.toString(); - } -} diff --git a/client/src/org/apache/qpid/jms/failover/FailoverSingleServer.java b/client/src/org/apache/qpid/jms/failover/FailoverSingleServer.java deleted file mode 100644 index 68e6d25be0..0000000000 --- a/client/src/org/apache/qpid/jms/failover/FailoverSingleServer.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.jms.failover; - -import org.apache.qpid.jms.BrokerDetails; -import org.apache.qpid.jms.ConnectionURL; - -public class FailoverSingleServer implements FailoverMethod -{ - /** The default number of times to rety a conection to this server */ - public static final int DEFAULT_SERVER_RETRIES = 1; - - /** - * The details of the Single Server - */ - private BrokerDetails _brokerDetail; - - /** - * The number of times to retry connecting to the sever - */ - private int _retries; - - /** - * The current number of attempts made to the server - */ - private int _currentRetries; - - - public FailoverSingleServer(ConnectionURL connectionDetails) - { - if (connectionDetails.getBrokerCount() > 0) - { - setBroker(connectionDetails.getBrokerDetails(0)); - } - else - { - throw new IllegalArgumentException("BrokerDetails details required for connection."); - } - } - - public FailoverSingleServer(BrokerDetails brokerDetail) - { - setBroker(brokerDetail); - } - - public void reset() - { - _currentRetries = -1; - } - - public boolean failoverAllowed() - { - return _currentRetries < _retries; - } - - public void attainedConnection() - { - reset(); - } - - public BrokerDetails getCurrentBrokerDetails() - { - return _brokerDetail; - } - - public BrokerDetails getNextBrokerDetails() - { - if (_currentRetries == _retries) - { - return null; - } - else - { - if (_currentRetries < _retries) - { - _currentRetries ++; - } - - return _brokerDetail; - } - } - - public void setBroker(BrokerDetails broker) - { - if (broker == null) - { - throw new IllegalArgumentException("BrokerDetails details cannot be null"); - } - _brokerDetail = broker; - - String retries = broker.getOption(BrokerDetails.OPTIONS_RETRY); - if (retries != null) - { - try - { - _retries = Integer.parseInt(retries); - } - catch (NumberFormatException nfe) - { - _retries = DEFAULT_SERVER_RETRIES; - } - } - else - { - _retries = DEFAULT_SERVER_RETRIES; - } - - reset(); - } - - public void setRetries(int retries) - { - _retries = retries; - } - - public String methodName() - { - return "Single Server"; - } - - public String toString() - { - return "SingleServer:\n"+ - "Max Retries:"+_retries+ - "\nCurrent Retry:"+_currentRetries+ - "\n"+_brokerDetail+"\n"; - } - -} diff --git a/client/src/org/apache/qpid/jndi/Example.properties b/client/src/org/apache/qpid/jndi/Example.properties deleted file mode 100644 index c457e94cab..0000000000 --- a/client/src/org/apache/qpid/jndi/Example.properties +++ /dev/null @@ -1,39 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# -java.naming.factory.initial = org.apache.qpid.jndi.PropertiesFileInitialConextFactory - -# use the following property to configure the default connector -#java.naming.provider.url - ignored. - -# register some connection factories -# connectionfactory.[jndiname] = [ConnectionURL] -connectionfactory.local = amqp://guest:guest@clientid/testpath?brokerlist='vm://:1' - -# register some queues in JNDI using the form -# queue.[jndiName] = [physicalName] -queue.MyQueue = example.MyQueue - -# register some topics in JNDI using the form -# topic.[jndiName] = [physicalName] -topic.ibmStocks = stocks.nyse.ibm - -# Register an AMQP destination in JNDI -# NOTE: Qpid currently only supports direct,topics and headers -# destination.[jniName] = [BindingURL] -destination.direct = direct://amq.direct//directQueue diff --git a/client/src/org/apache/qpid/jndi/NameParserImpl.java b/client/src/org/apache/qpid/jndi/NameParserImpl.java deleted file mode 100644 index a3174aec7a..0000000000 --- a/client/src/org/apache/qpid/jndi/NameParserImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.qpid.jndi; - -import javax.naming.CompositeName; -import javax.naming.Name; -import javax.naming.NameParser; -import javax.naming.NamingException; - -/** - * A default implementation of {@link NameParser} - * <p/> - * Based on class from ActiveMQ. - */ -public class NameParserImpl implements NameParser -{ - public Name parse(String name) throws NamingException - { - return new CompositeName(name); - } -} diff --git a/client/src/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java b/client/src/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java deleted file mode 100644 index b0641350ad..0000000000 --- a/client/src/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java +++ /dev/null @@ -1,292 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.jndi; - -import org.apache.log4j.Logger; -import org.apache.qpid.client.AMQConnectionFactory; -import org.apache.qpid.client.AMQHeadersExchange; -import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.client.AMQTopic; -import org.apache.qpid.exchange.ExchangeDefaults; -import org.apache.qpid.url.AMQBindingURL; -import org.apache.qpid.url.BindingURL; -import org.apache.qpid.url.URLSyntaxException; - -import javax.jms.ConnectionFactory; -import javax.jms.Destination; -import javax.jms.Queue; -import javax.jms.Topic; -import javax.naming.Context; -import javax.naming.NamingException; -import javax.naming.spi.InitialContextFactory; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -public class PropertiesFileInitialContextFactory implements InitialContextFactory -{ - protected final Logger _logger = Logger.getLogger(getClass()); - - private String CONNECTION_FACTORY_PREFIX = "connectionfactory."; - private String DESTINATION_PREFIX = "destination."; - private String QUEUE_PREFIX = "queue."; - private String TOPIC_PREFIX = "topic."; - - public Context getInitialContext(Hashtable environment) throws NamingException - { - Map data = new ConcurrentHashMap(); - - createConnectionFactories(data, environment); - - createDestinations(data, environment); - - createQueues(data, environment); - - createTopics(data, environment); - - return createContext(data, environment); - } - - // Implementation methods - //------------------------------------------------------------------------- - protected ReadOnlyContext createContext(Map data, Hashtable environment) - { - return new ReadOnlyContext(environment, data); - } - - protected void createConnectionFactories(Map data, Hashtable environment) - { - for (Iterator iter = environment.entrySet().iterator(); iter.hasNext();) - { - Map.Entry entry = (Map.Entry) iter.next(); - String key = entry.getKey().toString(); - if (key.startsWith(CONNECTION_FACTORY_PREFIX)) - { - String jndiName = key.substring(CONNECTION_FACTORY_PREFIX.length()); - ConnectionFactory cf = createFactory(entry.getValue().toString()); - if (cf != null) - { - data.put(jndiName, cf); - } - } - } - } - - protected void createDestinations(Map data, Hashtable environment) - { - for (Iterator iter = environment.entrySet().iterator(); iter.hasNext();) - { - Map.Entry entry = (Map.Entry) iter.next(); - String key = entry.getKey().toString(); - if (key.startsWith(DESTINATION_PREFIX)) - { - String jndiName = key.substring(DESTINATION_PREFIX.length()); - Destination dest = createDestination(entry.getValue().toString()); - if (dest != null) - { - data.put(jndiName, dest); - } - } - } - } - - protected void createQueues(Map data, Hashtable environment) - { - for (Iterator iter = environment.entrySet().iterator(); iter.hasNext();) - { - Map.Entry entry = (Map.Entry) iter.next(); - String key = entry.getKey().toString(); - if (key.startsWith(QUEUE_PREFIX)) - { - String jndiName = key.substring(QUEUE_PREFIX.length()); - Queue q = createQueue(entry.getValue().toString()); - if (q != null) - { - data.put(jndiName, q); - } - } - } - } - - protected void createTopics(Map data, Hashtable environment) - { - for (Iterator iter = environment.entrySet().iterator(); iter.hasNext();) - { - Map.Entry entry = (Map.Entry) iter.next(); - String key = entry.getKey().toString(); - if (key.startsWith(TOPIC_PREFIX)) - { - String jndiName = key.substring(TOPIC_PREFIX.length()); - Topic t = createTopic(entry.getValue().toString()); - if (t != null) - { - data.put(jndiName, t); - } - } - } - } - - /** - * Factory method to create new Connection Factory instances - */ - protected ConnectionFactory createFactory(String url) - { - try - { - return new AMQConnectionFactory(url); - } - catch (URLSyntaxException urlse) - { - _logger.warn("Unable to createFactories:" + urlse); - } - return null; - } - - /** - * Factory method to create new Destination instances from an AMQP BindingURL - */ - protected Destination createDestination(String bindingURL) - { - AMQBindingURL binding; - try - { - binding = new AMQBindingURL(bindingURL); - } - catch (URLSyntaxException urlse) - { - _logger.warn("Unable to destination:" + urlse); - return null; - } - - if (binding.getExchangeClass().equals(ExchangeDefaults.TOPIC_EXCHANGE_CLASS)) - { - return createTopic(binding); - } - else if (binding.getExchangeClass().equals(ExchangeDefaults.DIRECT_EXCHANGE_CLASS)) - { - return createQueue(binding); - } - else if (binding.getExchangeClass().equals(ExchangeDefaults.HEADERS_EXCHANGE_CLASS)) - { - return createHeaderExchange(binding); - } - - _logger.warn("Binding: '" + binding + "' not supported"); - return null; - } - - /** - * Factory method to create new Queue instances - */ - protected Queue createQueue(Object value) - { - if (value instanceof String) - - { - return new AMQQueue((String) value); - } - else if (value instanceof BindingURL) - - { - return new AMQQueue((BindingURL) value); - } - - return null; - } - - /** - * Factory method to create new Topic instances - */ - protected Topic createTopic(Object value) - { - if (value instanceof String) - { - return new AMQTopic((String) value); - } - else if (value instanceof BindingURL) - - { - return new AMQTopic((BindingURL) value); - } - - return null; - } - - /** - * Factory method to create new HeaderExcahnge instances - */ - protected Destination createHeaderExchange(Object value) - { - if (value instanceof String) - { - return new AMQHeadersExchange((String) value); - } - else if (value instanceof BindingURL) - { - return new AMQHeadersExchange((BindingURL) value); - } - - return null; - } - - // Properties - //------------------------------------------------------------------------- - public String getConnectionPrefix() - { - return CONNECTION_FACTORY_PREFIX; - } - - public void setConnectionPrefix(String connectionPrefix) - { - this.CONNECTION_FACTORY_PREFIX = connectionPrefix; - } - - public String getDestinationPrefix() - { - return DESTINATION_PREFIX; - } - - public void setDestinationPrefix(String destinationPrefix) - { - this.DESTINATION_PREFIX = destinationPrefix; - } - - public String getQueuePrefix() - { - return QUEUE_PREFIX; - } - - public void setQueuePrefix(String queuePrefix) - { - this.QUEUE_PREFIX = queuePrefix; - } - - public String getTopicPrefix() - { - return TOPIC_PREFIX; - } - - public void setTopicPrefix(String topicPrefix) - { - this.TOPIC_PREFIX = topicPrefix; - } -} diff --git a/client/src/org/apache/qpid/jndi/ReadOnlyContext.java b/client/src/org/apache/qpid/jndi/ReadOnlyContext.java deleted file mode 100644 index 1e96e6cf35..0000000000 --- a/client/src/org/apache/qpid/jndi/ReadOnlyContext.java +++ /dev/null @@ -1,497 +0,0 @@ -/** - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.qpid.jndi; - -import javax.naming.*; -import javax.naming.spi.NamingManager; -import java.io.Serializable; -import java.util.Collections; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.Map; - -/** - * Based on class from ActiveMQ. - * A read-only Context - * <p/> - * This version assumes it and all its subcontext are read-only and any attempt - * to modify (e.g. through bind) will result in an OperationNotSupportedException. - * Each Context in the tree builds a cache of the entries in all sub-contexts - * to optimise the performance of lookup. - * </p> - * <p>This implementation is intended to optimise the performance of lookup(String) - * to about the level of a HashMap get. It has been observed that the scheme - * resolution phase performed by the JVM takes considerably longer, so for - * optimum performance lookups should be coded like:</p> - * <code> - * Context componentContext = (Context)new InitialContext().lookup("java:comp"); - * String envEntry = (String) componentContext.lookup("env/myEntry"); - * String envEntry2 = (String) componentContext.lookup("env/myEntry2"); - * </code> - * - * @version $Revision$ $Date$ - */ -public class ReadOnlyContext implements Context, Serializable -{ - private static final long serialVersionUID = -5754338187296859149L; - protected static final NameParser nameParser = new NameParserImpl(); - - protected final Hashtable environment; // environment for this context - protected final Map bindings; // bindings at my level - protected final Map treeBindings; // all bindings under me - - private boolean frozen = false; - private String nameInNamespace = ""; - public static final String SEPARATOR = "/"; - - public ReadOnlyContext() - { - environment = new Hashtable(); - bindings = new HashMap(); - treeBindings = new HashMap(); - } - - public ReadOnlyContext(Hashtable env) - { - if (env == null) - { - this.environment = new Hashtable(); - } - else - { - this.environment = new Hashtable(env); - } - this.bindings = Collections.EMPTY_MAP; - this.treeBindings = Collections.EMPTY_MAP; - } - - public ReadOnlyContext(Hashtable environment, Map bindings) - { - if (environment == null) - { - this.environment = new Hashtable(); - } - else - { - this.environment = new Hashtable(environment); - } - this.bindings = bindings; - treeBindings = new HashMap(); - frozen = true; - } - - public ReadOnlyContext(Hashtable environment, Map bindings, String nameInNamespace) - { - this(environment, bindings); - this.nameInNamespace = nameInNamespace; - } - - protected ReadOnlyContext(ReadOnlyContext clone, Hashtable env) - { - this.bindings = clone.bindings; - this.treeBindings = clone.treeBindings; - this.environment = new Hashtable(env); - } - - protected ReadOnlyContext(ReadOnlyContext clone, Hashtable env, String nameInNamespace) - { - this(clone, env); - this.nameInNamespace = nameInNamespace; - } - - public void freeze() - { - frozen = true; - } - - boolean isFrozen() - { - return frozen; - } - - /** - * internalBind is intended for use only during setup or possibly by suitably synchronized superclasses. - * It binds every possible lookup into a map in each context. To do this, each context - * strips off one name segment and if necessary creates a new context for it. Then it asks that context - * to bind the remaining name. It returns a map containing all the bindings from the next context, plus - * the context it just created (if it in fact created it). (the names are suitably extended by the segment - * originally lopped off). - * - * @param name - * @param value - * @return - * @throws javax.naming.NamingException - */ - protected Map internalBind(String name, Object value) throws NamingException - { - assert name != null && name.length() > 0; - assert!frozen; - - Map newBindings = new HashMap(); - int pos = name.indexOf('/'); - if (pos == -1) - { - if (treeBindings.put(name, value) != null) - { - throw new NamingException("Something already bound at " + name); - } - bindings.put(name, value); - newBindings.put(name, value); - } - else - { - String segment = name.substring(0, pos); - assert segment != null; - assert!segment.equals(""); - Object o = treeBindings.get(segment); - if (o == null) - { - o = newContext(); - treeBindings.put(segment, o); - bindings.put(segment, o); - newBindings.put(segment, o); - } - else if (!(o instanceof ReadOnlyContext)) - { - throw new NamingException("Something already bound where a subcontext should go"); - } - ReadOnlyContext readOnlyContext = (ReadOnlyContext) o; - String remainder = name.substring(pos + 1); - Map subBindings = readOnlyContext.internalBind(remainder, value); - for (Iterator iterator = subBindings.entrySet().iterator(); iterator.hasNext();) - { - Map.Entry entry = (Map.Entry) iterator.next(); - String subName = segment + "/" + (String) entry.getKey(); - Object bound = entry.getValue(); - treeBindings.put(subName, bound); - newBindings.put(subName, bound); - } - } - return newBindings; - } - - protected ReadOnlyContext newContext() - { - return new ReadOnlyContext(); - } - - public Object addToEnvironment(String propName, Object propVal) throws NamingException - { - return environment.put(propName, propVal); - } - - public Hashtable getEnvironment() throws NamingException - { - return (Hashtable) environment.clone(); - } - - public Object removeFromEnvironment(String propName) throws NamingException - { - return environment.remove(propName); - } - - public Object lookup(String name) throws NamingException - { - if (name.length() == 0) - { - return this; - } - Object result = treeBindings.get(name); - if (result == null) - { - result = bindings.get(name); - } - if (result == null) - { - int pos = name.indexOf(':'); - if (pos > 0) - { - String scheme = name.substring(0, pos); - Context ctx = NamingManager.getURLContext(scheme, environment); - if (ctx == null) - { - throw new NamingException("scheme " + scheme + " not recognized"); - } - return ctx.lookup(name); - } - else - { - // Split out the first name of the path - // and look for it in the bindings map. - CompositeName path = new CompositeName(name); - - if (path.size() == 0) - { - return this; - } - else - { - String first = path.get(0); - Object obj = bindings.get(first); - if (obj == null) - { - throw new NameNotFoundException(name); - } - else if (obj instanceof Context && path.size() > 1) - { - Context subContext = (Context) obj; - obj = subContext.lookup(path.getSuffix(1)); - } - return obj; - } - } - } - if (result instanceof LinkRef) - { - LinkRef ref = (LinkRef) result; - result = lookup(ref.getLinkName()); - } - if (result instanceof Reference) - { - try - { - result = NamingManager.getObjectInstance(result, null, null, this.environment); - } - catch (NamingException e) - { - throw e; - } - catch (Exception e) - { - throw(NamingException) new NamingException("could not look up : " + name).initCause(e); - } - } - if (result instanceof ReadOnlyContext) - { - String prefix = getNameInNamespace(); - if (prefix.length() > 0) - { - prefix = prefix + SEPARATOR; - } - result = new ReadOnlyContext((ReadOnlyContext) result, environment, prefix + name); - } - return result; - } - - public Object lookup(Name name) throws NamingException - { - return lookup(name.toString()); - } - - public Object lookupLink(String name) throws NamingException - { - return lookup(name); - } - - public Name composeName(Name name, Name prefix) throws NamingException - { - Name result = (Name) prefix.clone(); - result.addAll(name); - return result; - } - - public String composeName(String name, String prefix) throws NamingException - { - CompositeName result = new CompositeName(prefix); - result.addAll(new CompositeName(name)); - return result.toString(); - } - - public NamingEnumeration list(String name) throws NamingException - { - Object o = lookup(name); - if (o == this) - { - return new ListEnumeration(); - } - else if (o instanceof Context) - { - return ((Context) o).list(""); - } - else - { - throw new NotContextException(); - } - } - - public NamingEnumeration listBindings(String name) throws NamingException - { - Object o = lookup(name); - if (o == this) - { - return new ListBindingEnumeration(); - } - else if (o instanceof Context) - { - return ((Context) o).listBindings(""); - } - else - { - throw new NotContextException(); - } - } - - public Object lookupLink(Name name) throws NamingException - { - return lookupLink(name.toString()); - } - - public NamingEnumeration list(Name name) throws NamingException - { - return list(name.toString()); - } - - public NamingEnumeration listBindings(Name name) throws NamingException - { - return listBindings(name.toString()); - } - - public void bind(Name name, Object obj) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public void bind(String name, Object obj) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public void close() throws NamingException - { - // ignore - } - - public Context createSubcontext(Name name) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public Context createSubcontext(String name) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public void destroySubcontext(Name name) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public void destroySubcontext(String name) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public String getNameInNamespace() throws NamingException - { - return nameInNamespace; - } - - public NameParser getNameParser(Name name) throws NamingException - { - return nameParser; - } - - public NameParser getNameParser(String name) throws NamingException - { - return nameParser; - } - - public void rebind(Name name, Object obj) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public void rebind(String name, Object obj) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public void rename(Name oldName, Name newName) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public void rename(String oldName, String newName) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public void unbind(Name name) throws NamingException - { - throw new OperationNotSupportedException(); - } - - public void unbind(String name) throws NamingException - { - throw new OperationNotSupportedException(); - } - - private abstract class LocalNamingEnumeration implements NamingEnumeration - { - private Iterator i = bindings.entrySet().iterator(); - - public boolean hasMore() throws NamingException - { - return i.hasNext(); - } - - public boolean hasMoreElements() - { - return i.hasNext(); - } - - protected Map.Entry getNext() - { - return (Map.Entry) i.next(); - } - - public void close() throws NamingException - { - } - } - - private class ListEnumeration extends LocalNamingEnumeration - { - public Object next() throws NamingException - { - return nextElement(); - } - - public Object nextElement() - { - Map.Entry entry = getNext(); - return new NameClassPair((String) entry.getKey(), entry.getValue().getClass().getName()); - } - } - - private class ListBindingEnumeration extends LocalNamingEnumeration - { - public Object next() throws NamingException - { - return nextElement(); - } - - public Object nextElement() - { - Map.Entry entry = getNext(); - return new Binding((String) entry.getKey(), entry.getValue()); - } - } -} |