Author: gaohoward
Date: 2011-10-12 04:32:14 -0400 (Wed, 12 Oct 2011)
New Revision: 11519
Added:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/FrameEventListener.java
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/HornetQStompException.java
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/SimpleBytes.java
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompVersions.java
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/VersionedStompFrameHandler.java
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameHandlerV10.java
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameV10.java
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameHandlerV11.java
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameV11.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractClientStompFrame.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractStompClientConnection.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrame.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV10.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV11.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnection.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionFactory.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV10.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV11.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactory.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryFactory.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV10.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV11.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestBase2.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestV11.java
Removed:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompException.java
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameHandlerV10.java
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameV10.java
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameHandlerV11.java
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameV11.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractClientStompFrame.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractStompClientConnection.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrame.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV10.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV11.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnection.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionFactory.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV10.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV11.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactory.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryFactory.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV10.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV11.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestBase2.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestV11.java
Modified:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/core/impl/CoreSessionCallback.java
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/Stomp.java
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompConnection.java
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompDecoder.java
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompFrame.java
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompProtocolManager.java
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompSession.java
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompSubscription.java
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompUtils.java
trunk/hornetq-core/src/main/java/org/hornetq/core/server/HornetQServers.java
trunk/hornetq-core/src/main/java/org/hornetq/spi/core/security/HornetQSecurityManagerImpl.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompConnectionCleanupTest.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompTest.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompTestBase.java
Log:
stomp 1.1 impl
Modified:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/core/impl/CoreSessionCallback.java
===================================================================
---
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/core/impl/CoreSessionCallback.java 2011-10-12
08:04:52 UTC (rev 11518)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/core/impl/CoreSessionCallback.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -72,7 +72,7 @@
public int sendMessage(ServerMessage message, long consumerID, int deliveryCount)
{
Packet packet = new SessionReceiveMessage(consumerID, message, deliveryCount);
-
+
channel.sendBatched(packet);
int size = packet.getPacketSize();
Copied:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/FrameEventListener.java
(from rev 11517,
branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/FrameEventListener.java)
===================================================================
---
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/FrameEventListener.java
(rev 0)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/FrameEventListener.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,31 @@
+/**
+ *
+ * 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.hornetq.core.protocol.stomp;
+
+/**
+ *
+ * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
+ */
+public interface FrameEventListener
+{
+
+ void replySent(StompFrame reply);
+
+ void requestAccepted(StompFrame request);
+
+}
Copied:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/HornetQStompException.java
(from rev 11517,
branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/HornetQStompException.java)
===================================================================
---
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/HornetQStompException.java
(rev 0)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/HornetQStompException.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat 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.hornetq.core.protocol.stomp;
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
+ */
+public class HornetQStompException extends Exception {
+
+ private static final long serialVersionUID = -274452327574950068L;
+
+ private List<Header> headers = new ArrayList<Header>(10);
+ private String body;
+ private VersionedStompFrameHandler handler;
+ private boolean disconnect;
+
+ public HornetQStompException(StompConnection connection, String msg)
+ {
+ super(msg);
+ handler = connection.getFrameHandler();
+ }
+ public HornetQStompException(String msg)
+ {
+ super(msg);
+ }
+
+ public HornetQStompException(String msg, Throwable t)
+ {
+ super(msg, t);
+ this.body = t.getMessage();
+ }
+
+ public HornetQStompException(Throwable t)
+ {
+ super(t);
+ }
+
+ public void addHeader(String header, String value)
+ {
+ headers.add(new Header(header, value));
+ }
+
+ public void setBody(String body)
+ {
+ this.body = body;
+ }
+
+ public StompFrame getFrame()
+ {
+ StompFrame frame = null;
+ if (handler == null)
+ {
+ frame = new StompFrame("ERROR");
+ frame.addHeader("message", this.getMessage());
+ if (body != null)
+ {
+ try
+ {
+ frame.setByteBody(body.getBytes("UTF-8"));
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ }
+ }
+ else
+ {
+ frame.setByteBody(new byte[0]);
+ }
+ }
+ else
+ {
+ frame = handler.createStompFrame("ERROR");
+ frame.addHeader("message", this.getMessage());
+ }
+ frame.setNeedsDisconnect(disconnect);
+ return frame;
+ }
+
+ private class Header
+ {
+ public String key;
+ public String val;
+
+ public Header(String key, String val)
+ {
+ this.key = key;
+ this.val = val;
+ }
+ }
+
+ public void setDisconnect(boolean b)
+ {
+ disconnect = b;
+ }
+}
Copied: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/SimpleBytes.java
(from rev 11517,
branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/SimpleBytes.java)
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/SimpleBytes.java
(rev 0)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/SimpleBytes.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,44 @@
+package org.hornetq.core.protocol.stomp;
+
+import java.io.UnsupportedEncodingException;
+
+
+public class SimpleBytes
+{
+ private int step;
+ private byte[] contents;
+ private int index;
+
+ public SimpleBytes(int initCapacity)
+ {
+ this.step = initCapacity;
+ contents = new byte[initCapacity];
+ index = 0;
+ }
+
+ public String getString() throws UnsupportedEncodingException
+ {
+ if (index == 0) return "";
+ byte[] realData = new byte[index];
+ System.arraycopy(contents, 0, realData, 0, realData.length);
+
+ return new String(realData, "UTF-8");
+ }
+
+ public void reset()
+ {
+ index = 0;
+ }
+
+ public void append(byte b)
+ {
+ if (index >= contents.length)
+ {
+ //grow
+ byte[] newBuffer = new byte[contents.length + step];
+ System.arraycopy(contents, 0, newBuffer, 0, contents.length);
+ contents = newBuffer;
+ }
+ contents[index++] = b;
+ }
+}
Modified: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/Stomp.java
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/Stomp.java 2011-10-12
08:04:52 UTC (rev 11518)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/Stomp.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -40,12 +40,6 @@
String UNSUBSCRIBE = "UNSUBSCRIBE";
- String BEGIN_TRANSACTION = "BEGIN";
-
- String COMMIT_TRANSACTION = "COMMIT";
-
- String ABORT_TRANSACTION = "ABORT";
-
String BEGIN = "BEGIN";
String COMMIT = "COMMIT";
@@ -53,6 +47,11 @@
String ABORT = "ABORT";
String ACK = "ACK";
+
+ //1.1
+ String NACK = "NACK";
+
+ String STOMP = "STOMP";
}
public interface Responses
@@ -76,6 +75,10 @@
String CONTENT_LENGTH = "content-length";
+ String ACCEPT_VERSION = "accept-version";
+
+ String CONTENT_TYPE = "content-type";
+
public interface Response
{
String RECEIPT_ID = "receipt-id";
@@ -140,6 +143,8 @@
String AUTO = "auto";
String CLIENT = "client";
+
+ String CLIENT_INDIVIDUAL = "client-individual";
}
}
@@ -159,11 +164,21 @@
String CLIENT_ID = "client-id";
String REQUEST_ID = "request-id";
+
+ //1.1
+ String ACCEPT_VERSION = "accept-version";
+ String HOST = "host";
+
+ Object HEART_BEAT = "heart-beat";
}
public interface Error
{
+ //1.0 only
String MESSAGE = "message";
+
+ //1.1
+ String VERSION = "version";
}
public interface Connected
@@ -171,11 +186,21 @@
String SESSION = "session";
String RESPONSE_ID = "response-id";
+
+ //1.1
+ String VERSION = "version";
+
+ String SERVER = "server";
+
+ String HEART_BEAT = "heart-beat";
}
public interface Ack
{
String MESSAGE_ID = "message-id";
+
+ //1.1
+ String SUBSCRIPTION = "subscription";
}
}
}
Modified:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompConnection.java
===================================================================
---
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompConnection.java 2011-10-12
08:04:52 UTC (rev 11518)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompConnection.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -15,7 +15,10 @@
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
import java.util.concurrent.CopyOnWriteArrayList;
import org.hornetq.api.core.HornetQBuffer;
@@ -24,6 +27,8 @@
import org.hornetq.core.logging.Logger;
import org.hornetq.core.remoting.CloseListener;
import org.hornetq.core.remoting.FailureListener;
+import org.hornetq.core.server.ServerMessage;
+import org.hornetq.core.server.impl.ServerMessageImpl;
import org.hornetq.spi.core.protocol.RemotingConnection;
import org.hornetq.spi.core.remoting.Acceptor;
import org.hornetq.spi.core.remoting.Connection;
@@ -37,8 +42,9 @@
*/
public class StompConnection implements RemotingConnection
{
-
private static final Logger log = Logger.getLogger(StompConnection.class);
+
+ protected static final String CONNECTION_ID_PROP = "__HQ_CID";
private final StompProtocolManager manager;
@@ -50,13 +56,14 @@
private String clientID;
+ //this means login is valid. (stomp connection ok)
private boolean valid;
private boolean destroyed = false;
private final long creationTime;
- private StompDecoder decoder = new StompDecoder();
+ private StompDecoder decoder;
private final Acceptor acceptorUsed;
@@ -67,6 +74,17 @@
private final Object failLock = new Object();
private volatile boolean dataReceived;
+
+ private StompVersions version;
+
+ private VersionedStompFrameHandler frameHandler;
+
+ //this means the version negotiation done.
+ private boolean initialized;
+
+ private FrameEventListener stompListener;
+
+ private final Object sendLock = new Object();
public StompDecoder getDecoder()
{
@@ -79,6 +97,8 @@
this.manager = manager;
+ this.decoder = new StompDecoder(this);
+
this.creationTime = System.currentTimeMillis();
this.acceptorUsed = acceptorUsed;
@@ -189,7 +209,10 @@
internalClose();
- callClosingListeners();
+ synchronized(sendLock)
+ {
+ callClosingListeners();
+ }
}
Acceptor getAcceptorUsed()
@@ -204,10 +227,6 @@
manager.cleanup(this);
}
- public void disconnect()
- {
- }
-
public void fail(final HornetQException me)
{
synchronized (failLock)
@@ -359,4 +378,356 @@
}
}
+ /*
+ * accept-version value takes form of "v1,v2,v3..."
+ * we need to return the highest supported version
+ */
+ public void negotiateVersion(StompFrame frame) throws HornetQStompException
+ {
+ String acceptVersion = frame.getHeader(Stomp.Headers.ACCEPT_VERSION);
+
+ if (acceptVersion == null)
+ {
+ this.version = StompVersions.V1_0;
+ }
+ else
+ {
+ Set<String> requestVersions = new HashSet<String>();
+ StringTokenizer tokenizer = new StringTokenizer(acceptVersion, ",");
+ while (tokenizer.hasMoreTokens())
+ {
+ requestVersions.add(tokenizer.nextToken());
+ }
+
+ if (requestVersions.contains("1.1"))
+ {
+ this.version = StompVersions.V1_1;
+ }
+ else if (requestVersions.contains("1.0"))
+ {
+ this.version = StompVersions.V1_0;
+ }
+ else
+ {
+ //not a supported version!
+ HornetQStompException error = new HornetQStompException("Stomp versions
not supported: " + acceptVersion);
+ error.addHeader("version", acceptVersion);
+ error.addHeader("content-type", "text/plain");
+ error.setBody("Supported protocol version are " +
manager.getSupportedVersionsAsString());
+ error.setDisconnect(true);
+ throw error;
+ }
+ log.error("------------------ negotiated version is " +
this.version);
+ }
+
+ this.frameHandler = VersionedStompFrameHandler.getHandler(this, this.version);
+ this.initialized = true;
+ }
+
+ //reject if the host doesn't match
+ public void setHost(String host) throws HornetQStompException
+ {
+ if (host == null)
+ {
+ HornetQStompException error = new HornetQStompException("Header host is
null");
+ error.setBody("Cannot accept null as host");
+ throw error;
+ }
+
+ String localHost = manager.getVirtualHostName();
+ if (!host.equals(localHost))
+ {
+ HornetQStompException error = new HornetQStompException("Header host
doesn't match server host");
+ error.setBody("host " + host + " doesn't match server host
name");
+ throw error;
+ }
+ }
+
+ public void handleFrame(StompFrame request)
+ {
+ StompFrame reply = null;
+
+ if (stompListener != null)
+ {
+ stompListener.requestAccepted(request);
+ }
+
+ String cmd = request.getCommand();
+ try
+ {
+ if (!initialized)
+ {
+ if ( ! (Stomp.Commands.CONNECT.equals(cmd) ||
Stomp.Commands.STOMP.equals(cmd)))
+ {
+ throw new HornetQStompException("Connection hasn't been
established.");
+ }
+ //decide version
+ negotiateVersion(request);
+ }
+ reply = frameHandler.handleFrame(request);
+ }
+ catch (HornetQStompException e)
+ {
+ reply = e.getFrame();
+ }
+
+ if (reply != null)
+ {
+ sendFrame(reply);
+ }
+
+ if (Stomp.Commands.DISCONNECT.equals(cmd))
+ {
+ this.disconnect();
+ }
+ }
+
+ public void sendFrame(StompFrame frame)
+ {
+ manager.sendReply(this, frame);
+ }
+
+ public boolean validateUser(String login, String passcode)
+ {
+ this.valid = manager.validateUser(login, passcode);
+ if (valid)
+ {
+ this.login = login;
+ this.passcode = passcode;
+ }
+ return valid;
+ }
+
+ public ServerMessageImpl createServerMessage()
+ {
+ return manager.createServerMessage();
+ }
+
+ public StompSession getSession(String txID) throws HornetQStompException
+ {
+ StompSession session = null;
+ try
+ {
+ if (txID == null)
+ {
+ session = manager.getSession(this);
+ }
+ else
+ {
+ session = manager.getTransactedSession(this, txID);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new HornetQStompException("Exception getting session", e);
+ }
+
+ return session;
+ }
+
+ public void validate() throws HornetQStompException
+ {
+ if (!this.valid)
+ {
+ throw new HornetQStompException("Connection is not valid.");
+ }
+ }
+
+ public void sendServerMessage(ServerMessageImpl message, String txID) throws
HornetQStompException
+ {
+ StompSession stompSession = getSession(txID);
+
+ if (stompSession.isNoLocal())
+ {
+ message.putStringProperty(CONNECTION_ID_PROP, getID().toString());
+ }
+ try
+ {
+ stompSession.getSession().send(message, true);
+ }
+ catch (Exception e)
+ {
+ throw new HornetQStompException("Error sending message " + message,
e);
+ }
+ }
+
+ @Override
+ public void disconnect()
+ {
+ destroy();
+ }
+
+ public void beginTransaction(String txID) throws HornetQStompException
+ {
+ try
+ {
+ manager.beginTransaction(this, txID);
+ }
+ catch (HornetQStompException e)
+ {
+ throw e;
+ }
+ catch (Exception e)
+ {
+ throw new HornetQStompException("Error beginning a transaction: " +
txID, e);
+ }
+ }
+
+ public void commitTransaction(String txID) throws HornetQStompException
+ {
+ try
+ {
+ manager.commitTransaction(this, txID);
+ }
+ catch (Exception e)
+ {
+ throw new HornetQStompException("Error committing " + txID, e);
+ }
+ }
+
+ public void abortTransaction(String txID) throws HornetQStompException
+ {
+ try
+ {
+ manager.abortTransaction(this, txID);
+ }
+ catch (HornetQStompException e)
+ {
+ throw e;
+ }
+ catch (Exception e)
+ {
+ throw new HornetQStompException("Error aborting " + txID, e);
+ }
+ }
+
+ public void subscribe(String destination, String selector, String ack,
+ String id, String durableSubscriptionName, boolean noLocal) throws
HornetQStompException
+ {
+ if (noLocal)
+ {
+ String noLocalFilter = CONNECTION_ID_PROP + " <> '" +
getID().toString() + "'";
+ if (selector == null)
+ {
+ selector = noLocalFilter;
+ }
+ else
+ {
+ selector += " AND " + noLocalFilter;
+ }
+ }
+
+ if (ack == null)
+ {
+ ack = Stomp.Headers.Subscribe.AckModeValues.AUTO;
+ }
+
+ String subscriptionID = null;
+ if (id != null)
+ {
+ subscriptionID = id;
+ }
+ else
+ {
+ if (destination == null)
+ {
+ throw new HornetQStompException("Client must set destination or id
header to a SUBSCRIBE command");
+ }
+ subscriptionID = "subscription/" + destination;
+ }
+
+ try
+ {
+ manager.createSubscription(this, subscriptionID, durableSubscriptionName,
destination, selector, ack, noLocal);
+ }
+ catch (HornetQStompException e)
+ {
+ throw e;
+ }
+ catch (Exception e)
+ {
+ throw new HornetQStompException("Error creating subscription " +
subscriptionID, e);
+ }
+ }
+
+ public void unsubscribe(String subscriptionID) throws HornetQStompException
+ {
+ try
+ {
+ manager.unsubscribe(this, subscriptionID);
+ }
+ catch (HornetQStompException e)
+ {
+ throw e;
+ }
+ catch (Exception e)
+ {
+ throw new HornetQStompException("Error unsubscripting " +
subscriptionID, e);
+ }
+ }
+
+ public void acknowledge(String messageID, String subscriptionID) throws
HornetQStompException
+ {
+ try
+ {
+ manager.acknowledge(this, messageID, subscriptionID);
+ }
+ catch (HornetQStompException e)
+ {
+ throw e;
+ }
+ catch (Exception e)
+ {
+ throw new HornetQStompException("Error acknowledging message " +
messageID, e);
+ }
+ }
+
+ public String getVersion()
+ {
+ return String.valueOf(version);
+ }
+
+ public String getHornetQServerName()
+ {
+ //hard coded, review later.
+ return "HornetQ/2.2.5 HornetQ Messaging Engine";
+ }
+
+ public StompFrame createStompMessage(ServerMessage serverMessage,
+ StompSubscription subscription, int deliveryCount) throws Exception
+ {
+ return frameHandler.createMessageFrame(serverMessage, subscription,
deliveryCount);
+ }
+
+ public void addStompEventListener(FrameEventListener listener)
+ {
+ this.stompListener = listener;
+ }
+
+ //send a ping stomp frame
+ public void ping(StompFrame pingFrame)
+ {
+ manager.sendReply(this, pingFrame);
+ }
+
+ public void physicalSend(StompFrame frame) throws Exception
+ {
+ HornetQBuffer buffer = frame.toHornetQBuffer();
+
+ synchronized (sendLock)
+ {
+ getTransportConnection().write(buffer, false, false);
+ }
+
+ if (stompListener != null)
+ {
+ stompListener.replySent(frame);
+ }
+
+ }
+
+ public VersionedStompFrameHandler getFrameHandler()
+ {
+ return this.frameHandler;
+ }
}
Modified:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompDecoder.java
===================================================================
---
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompDecoder.java 2011-10-12
08:04:52 UTC (rev 11518)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompDecoder.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -30,116 +30,142 @@
{
private static final Logger log = Logger.getLogger(StompDecoder.class);
- private static final boolean TRIM_LEADING_HEADER_VALUE_WHITESPACE = true;
+ public static final boolean TRIM_LEADING_HEADER_VALUE_WHITESPACE = true;
- private static final String COMMAND_ABORT = "ABORT";
+ public static final String COMMAND_ABORT = "ABORT";
- private static final int COMMAND_ABORT_LENGTH = COMMAND_ABORT.length();
+ public static final int COMMAND_ABORT_LENGTH = COMMAND_ABORT.length();
- private static final String COMMAND_ACK = "ACK";
+ public static final String COMMAND_ACK = "ACK";
- private static final int COMMAND_ACK_LENGTH = COMMAND_ACK.length();
+ public static final int COMMAND_ACK_LENGTH = COMMAND_ACK.length();
- private static final String COMMAND_BEGIN = "BEGIN";
+ public static final String COMMAND_NACK = "NACK";
- private static final int COMMAND_BEGIN_LENGTH = COMMAND_BEGIN.length();
+ public static final int COMMAND_NACK_LENGTH = COMMAND_NACK.length();
- private static final String COMMAND_COMMIT = "COMMIT";
+ public static final String COMMAND_BEGIN = "BEGIN";
- private static final int COMMAND_COMMIT_LENGTH = COMMAND_COMMIT.length();
+ public static final int COMMAND_BEGIN_LENGTH = COMMAND_BEGIN.length();
- private static final String COMMAND_CONNECT = "CONNECT";
+ public static final String COMMAND_COMMIT = "COMMIT";
- private static final int COMMAND_CONNECT_LENGTH = COMMAND_CONNECT.length();
+ public static final int COMMAND_COMMIT_LENGTH = COMMAND_COMMIT.length();
- private static final String COMMAND_DISCONNECT = "DISCONNECT";
+ public static final String COMMAND_CONNECT = "CONNECT";
- private static final int COMMAND_DISCONNECT_LENGTH = COMMAND_DISCONNECT.length();
+ public static final int COMMAND_CONNECT_LENGTH = COMMAND_CONNECT.length();
- private static final String COMMAND_SEND = "SEND";
+ public static final String COMMAND_DISCONNECT = "DISCONNECT";
- private static final int COMMAND_SEND_LENGTH = COMMAND_SEND.length();
+ public static final int COMMAND_DISCONNECT_LENGTH = COMMAND_DISCONNECT.length();
- private static final String COMMAND_SUBSCRIBE = "SUBSCRIBE";
+ public static final String COMMAND_SEND = "SEND";
- private static final int COMMAND_SUBSCRIBE_LENGTH = COMMAND_SUBSCRIBE.length();
+ public static final int COMMAND_SEND_LENGTH = COMMAND_SEND.length();
- private static final String COMMAND_UNSUBSCRIBE = "UNSUBSCRIBE";
+ public static final String COMMAND_STOMP = "STOMP";
- private static final int COMMAND_UNSUBSCRIBE_LENGTH = COMMAND_UNSUBSCRIBE.length();
+ public static final int COMMAND_STOMP_LENGTH = COMMAND_STOMP.length();
+ public static final String COMMAND_SUBSCRIBE = "SUBSCRIBE";
+
+ public static final int COMMAND_SUBSCRIBE_LENGTH = COMMAND_SUBSCRIBE.length();
+
+ public static final String COMMAND_UNSUBSCRIBE = "UNSUBSCRIBE";
+
+ public static final int COMMAND_UNSUBSCRIBE_LENGTH = COMMAND_UNSUBSCRIBE.length();
+
/**** added by meddy, 27 april 2011, handle header parser for reply to websocket
protocol ****/
- private static final String COMMAND_CONNECTED = "CONNECTED";
+ public static final String COMMAND_CONNECTED = "CONNECTED";
- private static final int COMMAND_CONNECTED_LENGTH = COMMAND_CONNECTED.length();
+ public static final int COMMAND_CONNECTED_LENGTH = COMMAND_CONNECTED.length();
- private static final String COMMAND_MESSAGE = "MESSAGE";
+ public static final String COMMAND_MESSAGE = "MESSAGE";
- private static final int COMMAND_MESSAGE_LENGTH = COMMAND_MESSAGE.length();
+ public static final int COMMAND_MESSAGE_LENGTH = COMMAND_MESSAGE.length();
- private static final String COMMAND_ERROR = "ERROR";
+ public static final String COMMAND_ERROR = "ERROR";
- private static final int COMMAND_ERROR_LENGTH = COMMAND_ERROR.length();
+ public static final int COMMAND_ERROR_LENGTH = COMMAND_ERROR.length();
- private static final String COMMAND_RECEIPT = "RECEIPT";
+ public static final String COMMAND_RECEIPT = "RECEIPT";
- private static final int COMMAND_RECEIPT_LENGTH = COMMAND_RECEIPT.length();
+ public static final int COMMAND_RECEIPT_LENGTH = COMMAND_RECEIPT.length();
/**** end ****/
- private static final byte A = (byte)'A';
+ public static final byte A = (byte)'A';
- private static final byte B = (byte)'B';
+ public static final byte B = (byte)'B';
- private static final byte C = (byte)'C';
+ public static final byte C = (byte)'C';
- private static final byte D = (byte)'D';
+ public static final byte D = (byte)'D';
- private static final byte E = (byte)'E';
+ public static final byte E = (byte)'E';
- private static final byte M = (byte)'M';
+ public static final byte T = (byte)'T';
- private static final byte S = (byte)'S';
+ public static final byte M = (byte)'M';
+
+ public static final byte S = (byte)'S';
- private static final byte R = (byte)'R';
+ public static final byte R = (byte)'R';
- private static final byte U = (byte)'U';
+ public static final byte U = (byte)'U';
- private static final byte HEADER_SEPARATOR = (byte)':';
+ public static final byte N = (byte)'N';
+
+ public static final byte LN = (byte)'n';
- private static final byte NEW_LINE = (byte)'\n';
+ public static final byte HEADER_SEPARATOR = (byte)':';
- private static final byte SPACE = (byte)' ';
+ public static final byte NEW_LINE = (byte)'\n';
- private static final byte TAB = (byte)'\t';
+ public static final byte SPACE = (byte)' ';
- private static String CONTENT_LENGTH_HEADER_NAME = "content-length";
+ public static final byte TAB = (byte)'\t';
- private byte[] workingBuffer = new byte[1024];
+ public static final String CONTENT_TYPE_HEADER_NAME = "content-type";
- private int pos;
+ public static String CONTENT_LENGTH_HEADER_NAME = "content-length";
- private int data;
+ public byte[] workingBuffer = new byte[1024];
- private String command;
+ public int pos;
- private Map<String, Object> headers;
+ public int data;
- private int headerBytesCopyStart;
+ public String command;
- private boolean readingHeaders;
+ public Map<String, String> headers;
- private boolean headerValueWhitespace;
+ public int headerBytesCopyStart;
- private boolean inHeaderName;
+ public boolean readingHeaders;
- private String headerName;
+ public boolean headerValueWhitespace;
- private boolean whiteSpaceOnly;
+ public boolean inHeaderName;
- private int contentLength;
+ public String headerName;
- private int bodyStart;
+ public boolean whiteSpaceOnly;
+ public int contentLength;
+
+ public String contentType;
+
+ public int bodyStart;
+
+ public StompConnection connection;
+
+ public StompDecoder(StompConnection stompConnection)
+ {
+ this.connection = stompConnection;
+ init();
+ }
+
public StompDecoder()
{
init();
@@ -156,13 +182,25 @@
* followed by an empty line
* followed by an optional message body
* terminated with a null character
+ *
+ * Note: to support both 1.0 and 1.1, we just assemble a
+ * standard StompFrame and let the versioned handler to do more
+ * spec specific job (like trimming, escaping etc).
*/
public synchronized StompFrame decode(final HornetQBuffer buffer) throws Exception
{
- //log.info("got buff " + buffer.readableBytes());
+ if (connection != null && connection.isValid())
+ {
+ VersionedStompFrameHandler handler = connection.getFrameHandler();
+ return handler.decode(this, buffer);
+ }
- long start = System.nanoTime();
-
+ return defaultDecode(buffer);
+ }
+
+ public StompFrame defaultDecode(final HornetQBuffer buffer) throws
HornetQStompException
+ {
+
int readable = buffer.readableBytes();
if (data + readable >= workingBuffer.length)
@@ -338,6 +376,16 @@
// SEND
command = COMMAND_SEND;
}
+ else if (workingBuffer[offset + 1] == T)
+ {
+ if (!tryIncrement(offset + COMMAND_STOMP_LENGTH + 1))
+ {
+ return null;
+ }
+
+ // SEND
+ command = COMMAND_STOMP;
+ }
else
{
if (!tryIncrement(offset + COMMAND_SUBSCRIBE_LENGTH + 1))
@@ -375,8 +423,6 @@
throwInvalid();
}
}
-
- long commandTime = System.nanoTime() - start;
if (readingHeaders)
{
@@ -482,8 +528,6 @@
}
}
}
-
- long headersTime = System.nanoTime() - start - commandTime;
// Now the body
@@ -526,8 +570,6 @@
}
}
-
-
if (content != null)
{
if (data > pos)
@@ -546,34 +588,28 @@
StompFrame ret = new StompFrame(command, headers, content);
init();
-
- // log.info("decoded");
-
- long bodyTime = System.nanoTime() - start - headersTime - commandTime;
-
- // log.info("command: "+ commandTime + " headers: " +
headersTime + " body: " + bodyTime);
return ret;
}
else
{
return null;
- }
+ }
}
- private void throwInvalid() throws StompException
+ public void throwInvalid() throws HornetQStompException
{
- throw new StompException("Invalid STOMP frame: " +
this.dumpByteArray(workingBuffer));
+ throw new HornetQStompException("Invalid STOMP frame: " +
this.dumpByteArray(workingBuffer));
}
- private void init()
+ public void init()
{
pos = 0;
command = null;
+
+ headers = new HashMap<String, String>();
- headers = new HashMap<String, Object>();
-
this.headerBytesCopyStart = -1;
readingHeaders = true;
@@ -588,10 +624,12 @@
contentLength = -1;
+ contentType = null;
+
bodyStart = -1;
}
- private void resizeWorking(final int newSize)
+ public void resizeWorking(final int newSize)
{
byte[] oldBuffer = workingBuffer;
@@ -600,7 +638,7 @@
System.arraycopy(oldBuffer, 0, workingBuffer, 0, oldBuffer.length);
}
- private boolean tryIncrement(final int length)
+ public boolean tryIncrement(final int length)
{
if (pos + length >= data)
{
Deleted:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompException.java
===================================================================
---
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompException.java 2011-10-12
08:04:52 UTC (rev 11518)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompException.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -1,57 +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.hornetq.core.protocol.stomp;
-
-import java.io.IOException;
-
-/**
- * @author <a href="http://hiramchirino.com">chirino</a>
- */
-class StompException extends IOException
-{
- private static final long serialVersionUID = -2869735532997332242L;
-
- private final boolean fatal;
-
- public StompException()
- {
- this(null);
- }
-
- public StompException(String s)
- {
- this(s, false);
- }
-
- public StompException(String s, boolean fatal)
- {
- this(s, fatal, null);
- }
-
- public StompException(String s, boolean fatal, Throwable cause)
- {
- super(s);
- this.fatal = fatal;
- initCause(cause);
- }
-
- public boolean isFatal()
- {
- return fatal;
- }
-}
Modified:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompFrame.java
===================================================================
---
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompFrame.java 2011-10-12
08:04:52 UTC (rev 11518)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompFrame.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -17,6 +17,11 @@
*/
package org.hornetq.core.protocol.stomp;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -31,36 +36,46 @@
* @author Tim Fox
*
*/
-class StompFrame
+public class StompFrame
{
- private static final Logger log = Logger.getLogger(StompFrame.class);
+ protected static final Logger log = Logger.getLogger(StompFrame.class);
- public static final byte[] NO_DATA = new byte[] {};
+ protected static final byte[] NO_DATA = new byte[] {};
- private static final byte[] END_OF_FRAME = new byte[] { 0, '\n' };
+ protected static final byte[] END_OF_FRAME = new byte[] { 0, '\n' };
- private final String command;
+ protected String command;
- private final Map<String, Object> headers;
+ protected Map<String, String> headers;
- private final byte[] content;
+ protected String body;
+
+ protected byte[] bytesBody;
- private HornetQBuffer buffer = null;
+ protected HornetQBuffer buffer = null;
- private int size;
+ protected int size;
- public StompFrame(String command, Map<String, Object> headers, byte[] data)
+ protected boolean disconnect;
+
+ public StompFrame(String command)
{
+ this(command, false);
+ }
+
+ public StompFrame(String command, boolean disconnect)
+ {
this.command = command;
- this.headers = headers;
- this.content = data;
+ this.headers = new LinkedHashMap<String, String>();
+ this.disconnect = disconnect;
}
- public StompFrame(String command, Map<String, Object> headers)
+ public StompFrame(String command, Map<String, String> headers,
+ byte[] content)
{
this.command = command;
this.headers = headers;
- this.content = NO_DATA;
+ this.bytesBody = content;
}
public String getCommand()
@@ -68,16 +83,6 @@
return command;
}
- public byte[] getContent()
- {
- return content;
- }
-
- public Map<String, Object> getHeaders()
- {
- return headers;
- }
-
public int getEncodedSize() throws Exception
{
if (buffer == null)
@@ -90,33 +95,39 @@
@Override
public String toString()
{
- return "StompFrame[command=" + command + ", headers=" + headers
+ ", content-length=" + content.length + "]";
+ return "StompFrame[command=" + command + ", headers=" + headers
+ ", content= " + this.body + " bytes " + this.bytesBody;
}
public String asString()
{
String out = command + '\n';
- for (Entry<String, Object> header : headers.entrySet())
+ for (Entry<String, String> header : headers.entrySet())
{
out += header.getKey() + ": " + header.getValue() + '\n';
}
out += '\n';
- out += new String(content);
+ out += body;
return out;
}
-
public HornetQBuffer toHornetQBuffer() throws Exception
{
if (buffer == null)
{
- buffer = HornetQBuffers.dynamicBuffer(content.length + 512);
+ if (bytesBody != null)
+ {
+ buffer = HornetQBuffers.dynamicBuffer(bytesBody.length + 512);
+ }
+ else
+ {
+ buffer = HornetQBuffers.dynamicBuffer(512);
+ }
StringBuffer head = new StringBuffer();
head.append(command);
head.append(Stomp.NEWLINE);
// Output the headers.
- for (Map.Entry<String, Object> header : headers.entrySet())
+ for (Map.Entry<String, String> header : headers.entrySet())
{
head.append(header.getKey());
head.append(Stomp.Headers.SEPARATOR);
@@ -127,11 +138,132 @@
head.append(Stomp.NEWLINE);
buffer.writeBytes(head.toString().getBytes("UTF-8"));
- buffer.writeBytes(content);
+ if (bytesBody != null)
+ {
+ buffer.writeBytes(bytesBody);
+ }
buffer.writeBytes(END_OF_FRAME);
size = buffer.writerIndex();
}
return buffer;
}
+
+ public String getHeader(String key)
+ {
+ return headers.get(key);
+ }
+
+ public void addHeader(String key, String val)
+ {
+ headers.put(key, val);
+ }
+
+ public Map<String, String> getHeadersMap()
+ {
+ return headers;
+ }
+
+ public static class Header
+ {
+ public String key;
+ public String val;
+
+ public Header(String key, String val)
+ {
+ this.key = key;
+ this.val = val;
+ }
+
+ public String getEscapedKey()
+ {
+ return escape(key);
+ }
+
+ public String getEscapedValue()
+ {
+ return escape(val);
+ }
+
+ public static String escape(String str)
+ {
+ int len = str.length();
+
+ char[] buffer = new char[2*len];
+ int iBuffer = 0;
+ for (int i = 0; i < len; i++)
+ {
+ char c = str.charAt(i);
+ if (c == '\n')
+ {
+ buffer[iBuffer++] = '\\';
+ buffer[iBuffer] = 'n';
+ }
+ else if (c == '\\')
+ {
+ buffer[iBuffer++] = '\\';
+ buffer[iBuffer] = '\\';
+ }
+ else if (c == ':')
+ {
+ buffer[iBuffer++] = '\\';
+ buffer[iBuffer] = ':';
+ }
+ else
+ {
+ buffer[iBuffer] = c;
+ }
+ iBuffer++;
+ }
+
+ char[] total = new char[iBuffer];
+ System.arraycopy(buffer, 0, total, 0, iBuffer);
+
+ return new String(total);
+ }
+ }
+
+ public void setBody(String body) throws UnsupportedEncodingException
+ {
+ this.body = body;
+ this.bytesBody = body.getBytes("UTF-8");
+ }
+
+ public boolean hasHeader(String key)
+ {
+ return headers.containsKey(key);
+ }
+
+ public String getBody() throws UnsupportedEncodingException
+ {
+ if (body == null)
+ {
+ if (bytesBody != null)
+ {
+ body = new String(bytesBody, "UTF-8");
+ }
+ }
+ return body;
+ }
+
+ //Since 1.1, there is a content-type header that needs to take care of
+ public byte[] getBodyAsBytes() throws UnsupportedEncodingException
+ {
+ return bytesBody;
+ }
+
+ public boolean needsDisconnect()
+ {
+ return disconnect;
+ }
+
+ public void setByteBody(byte[] content)
+ {
+ this.bytesBody = content;
+ }
+
+ public void setNeedsDisconnect(boolean b)
+ {
+ disconnect = b;
+ }
}
Modified:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompProtocolManager.java
===================================================================
---
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompProtocolManager.java 2011-10-12
08:04:52 UTC (rev 11518)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompProtocolManager.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -13,22 +13,18 @@
package org.hornetq.core.protocol.stomp;
-import java.io.ByteArrayOutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Set;
import java.util.concurrent.Executor;
import org.hornetq.api.core.HornetQBuffer;
import org.hornetq.api.core.HornetQException;
import org.hornetq.api.core.Interceptor;
-import org.hornetq.api.core.Message;
-import org.hornetq.api.core.SimpleString;
+import org.hornetq.api.core.TransportConfiguration;
import org.hornetq.api.core.client.HornetQClient;
import org.hornetq.core.journal.IOAsyncTask;
import org.hornetq.core.logging.Logger;
@@ -54,9 +50,6 @@
private static final Logger log = Logger.getLogger(StompProtocolManager.class);
- // TODO use same value than HornetQConnection
- private static final String CONNECTION_ID_PROP = "__HQ_CID";
-
// Attributes ----------------------------------------------------
private final HornetQServer server;
@@ -70,36 +63,6 @@
// Static --------------------------------------------------------
- private static StompFrame createError(Exception e, StompFrame request)
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- try
- {
- // Let the stomp client know about any protocol errors.
- PrintWriter stream = new PrintWriter(new OutputStreamWriter(baos,
"UTF-8"));
- e.printStackTrace(stream);
- stream.close();
-
- Map<String, Object> headers = new HashMap<String, Object>();
- headers.put(Stomp.Headers.Error.MESSAGE, e.getMessage());
-
- final String receiptId =
(String)request.getHeaders().get(Stomp.Headers.RECEIPT_REQUESTED);
- if (receiptId != null)
- {
- headers.put(Stomp.Headers.Response.RECEIPT_ID, receiptId);
- }
-
- byte[] payload = baos.toByteArray();
- headers.put(Stomp.Headers.CONTENT_LENGTH, payload.length);
- return new StompFrame(Stomp.Responses.ERROR, headers, payload);
- }
- catch (UnsupportedEncodingException ex)
- {
- log.warn("Unable to create ERROR frame from the exception", ex);
- return null;
- }
- }
-
// Constructors --------------------------------------------------
public StompProtocolManager(final HornetQServer server, final List<Interceptor>
interceptors)
@@ -114,7 +77,7 @@
{
StompConnection conn = new StompConnection(acceptorUsed, connection, this);
- // Note that STOMP has no heartbeat, so if connection ttl is non zero, data must
continue to be sent or connection
+ // Note that STOMP 1.0 has no heartbeat, so if connection ttl is non zero, data
must continue to be sent or connection
// will be timed out and closed!
long ttl = server.getConfiguration().getConnectionTTLOverride();
@@ -144,19 +107,15 @@
public void handleBuffer(final RemotingConnection connection, final HornetQBuffer
buffer)
{
- long start = System.nanoTime();
StompConnection conn = (StompConnection)connection;
conn.setDataReceived();
StompDecoder decoder = conn.getDecoder();
-
- // log.info("in handle");
do
{
StompFrame request;
-
try
{
request = decoder.decode(buffer);
@@ -164,7 +123,6 @@
catch (Exception e)
{
log.error("Failed to decode", e);
-
return;
}
@@ -175,93 +133,13 @@
try
{
- String command = request.getCommand();
-
- StompFrame response = null;
-
- if (Stomp.Commands.CONNECT.equals(command))
- {
- response = onConnect(request, conn);
- }
- else if (Stomp.Commands.DISCONNECT.equals(command))
- {
- response = onDisconnect(request, conn);
- }
- else if (Stomp.Commands.SEND.equals(command))
- {
- response = onSend(request, conn);
- }
- else if (Stomp.Commands.SUBSCRIBE.equals(command))
- {
- response = onSubscribe(request, conn);
- }
- else if (Stomp.Commands.UNSUBSCRIBE.equals(command))
- {
- response = onUnsubscribe(request, conn);
- }
- else if (Stomp.Commands.ACK.equals(command))
- {
- response = onAck(request, conn);
- }
- else if (Stomp.Commands.BEGIN.equals(command))
- {
- response = onBegin(request, server, conn);
- }
- else if (Stomp.Commands.COMMIT.equals(command))
- {
- response = onCommit(request, conn);
- }
- else if (Stomp.Commands.ABORT.equals(command))
- {
- response = onAbort(request, conn);
- }
- else
- {
- log.error("Unsupported Stomp frame: " + request);
- response = new StompFrame(Stomp.Responses.ERROR,
- new HashMap<String, Object>(),
- ("Unsupported frame: " +
command).getBytes());
- }
-
- if (request.getHeaders().containsKey(Stomp.Headers.RECEIPT_REQUESTED))
- {
- if (response == null)
- {
- Map<String, Object> h = new HashMap<String, Object>();
- response = new StompFrame(Stomp.Responses.RECEIPT, h);
- }
- response.getHeaders().put(Stomp.Headers.Response.RECEIPT_ID,
-
request.getHeaders().get(Stomp.Headers.RECEIPT_REQUESTED));
- }
-
- if (response != null)
- {
- sendReply(conn, response);
- }
-
- if (Stomp.Commands.DISCONNECT.equals(command))
- {
- conn.destroy();
- }
+ conn.handleFrame(request);
}
- catch (Exception e)
- {
- e.printStackTrace();
- StompFrame error = createError(e, request);
- if (error != null)
- {
- sendReply(conn, error);
- }
- }
finally
{
server.getStorageManager().clearContext();
}
} while (decoder.hasBytes());
-
- long end = System.nanoTime();
-
- // log.info("handle took " + (end-start));
}
// Public --------------------------------------------------------
@@ -274,7 +152,7 @@
}
synchronized (connection)
{
- if (connection.isDestroyed() || !connection.isValid())
+ if (connection.isDestroyed())
{
log.warn("Connection closed " + connection);
return;
@@ -282,8 +160,7 @@
try
{
- HornetQBuffer buffer = frame.toHornetQBuffer();
- connection.getTransportConnection().write(buffer, false, false);
+ connection.physicalSend(frame);
}
catch (Exception e)
{
@@ -298,182 +175,8 @@
// Private -------------------------------------------------------
- private StompFrame onSubscribe(StompFrame frame, StompConnection connection) throws
Exception
+ public StompSession getSession(StompConnection connection) throws Exception
{
- Map<String, Object> headers = frame.getHeaders();
- String destination = (String)headers.get(Stomp.Headers.Subscribe.DESTINATION);
- String selector = (String)headers.get(Stomp.Headers.Subscribe.SELECTOR);
- String ack = (String)headers.get(Stomp.Headers.Subscribe.ACK_MODE);
- String id = (String)headers.get(Stomp.Headers.Subscribe.ID);
- String durableSubscriptionName =
(String)headers.get(Stomp.Headers.Subscribe.DURABLE_SUBSCRIBER_NAME);
- boolean noLocal = false;
- if (headers.containsKey(Stomp.Headers.Subscribe.NO_LOCAL))
- {
- noLocal =
Boolean.parseBoolean((String)headers.get(Stomp.Headers.Subscribe.NO_LOCAL));
- }
- if (noLocal)
- {
- String noLocalFilter = CONNECTION_ID_PROP + " <> '" +
connection.getID().toString() + "'";
- if (selector == null)
- {
- selector = noLocalFilter;
- }
- else
- {
- selector += " AND " + noLocalFilter;
- }
- }
- if (ack == null)
- {
- ack = Stomp.Headers.Subscribe.AckModeValues.AUTO;
- }
- String subscriptionID = null;
- if (id != null)
- {
- subscriptionID = id;
- }
- else
- {
- if (destination == null)
- {
- throw new StompException("Client must set destination or id header to a
SUBSCRIBE command");
- }
- subscriptionID = "subscription/" + destination;
- }
- StompSession stompSession = getSession(connection);
- stompSession.setNoLocal(noLocal);
- if (stompSession.containsSubscription(subscriptionID))
- {
- throw new StompException("There already is a subscription for: " +
subscriptionID +
- ". Either use unique subscription IDs or do not
create multiple subscriptions for the same destination");
- }
- long consumerID = server.getStorageManager().generateUniqueID();
- String clientID = (connection.getClientID() != null) ? connection.getClientID() :
null;
- stompSession.addSubscription(consumerID,
- subscriptionID,
- clientID,
- durableSubscriptionName,
- destination,
- selector,
- ack);
-
- return null;
- }
-
- private StompFrame onUnsubscribe(StompFrame frame, StompConnection connection) throws
Exception
- {
- Map<String, Object> headers = frame.getHeaders();
- String destination = (String)headers.get(Stomp.Headers.Unsubscribe.DESTINATION);
- String id = (String)headers.get(Stomp.Headers.Unsubscribe.ID);
-
- String subscriptionID = null;
- if (id != null)
- {
- subscriptionID = id;
- }
- else
- {
- if (destination == null)
- {
- throw new StompException("Must specify the subscription's id or the
destination you are unsubscribing from");
- }
- subscriptionID = "subscription/" + destination;
- }
-
- StompSession stompSession = getSession(connection);
- boolean unsubscribed = stompSession.unsubscribe(subscriptionID);
- if (!unsubscribed)
- {
- throw new StompException("Cannot unsubscribe as no subscription exists for
id: " + subscriptionID);
- }
- return null;
- }
-
- private StompFrame onAck(StompFrame frame, StompConnection connection) throws
Exception
- {
- Map<String, Object> headers = frame.getHeaders();
- String messageID = (String)headers.get(Stomp.Headers.Ack.MESSAGE_ID);
- String txID = (String)headers.get(Stomp.Headers.TRANSACTION);
- StompSession stompSession = null;
- if (txID != null)
- {
- log.warn("Transactional acknowledgement is not supported");
- }
- stompSession = getSession(connection);
- stompSession.acknowledge(messageID);
-
- return null;
- }
-
- private StompFrame onBegin(StompFrame frame, HornetQServer server, StompConnection
connection) throws Exception
- {
- Map<String, Object> headers = frame.getHeaders();
- String txID = (String)headers.get(Stomp.Headers.TRANSACTION);
- if (txID == null)
- {
- throw new StompException("transaction header is mandatory to BEGIN a
transaction");
- }
- if (transactedSessions.containsKey(txID))
- {
- throw new StompException("Transaction already started: " + txID);
- }
- // create the transacted session
- getTransactedSession(connection, txID);
-
- return null;
- }
-
- private StompFrame onCommit(StompFrame frame, StompConnection connection) throws
Exception
- {
- Map<String, Object> headers = frame.getHeaders();
- String txID = (String)headers.get(Stomp.Headers.TRANSACTION);
- if (txID == null)
- {
- throw new StompException("transaction header is mandatory to COMMIT a
transaction");
- }
-
- StompSession session = getTransactedSession(connection, txID);
- if (session == null)
- {
- throw new StompException("No transaction started: " + txID);
- }
- transactedSessions.remove(txID);
- session.getSession().commit();
-
- return null;
- }
-
- private StompFrame onAbort(StompFrame frame, StompConnection connection) throws
Exception
- {
- Map<String, Object> headers = frame.getHeaders();
- String txID = (String)headers.get(Stomp.Headers.TRANSACTION);
- if (txID == null)
- {
- throw new StompException("transaction header is mandatory to ABORT a
transaction");
- }
-
- StompSession session = getTransactedSession(connection, txID);
-
- if (session == null)
- {
- throw new StompException("No transaction started: " + txID);
- }
- transactedSessions.remove(txID);
- session.getSession().rollback(false);
-
- return null;
- }
-
- private void checkConnected(StompConnection connection) throws StompException
- {
- if (!connection.isValid())
- {
- throw new StompException("Not connected");
- }
- }
-
- private StompSession getSession(StompConnection connection) throws Exception
- {
StompSession stompSession = sessions.get(connection.getID());
if (stompSession == null)
{
@@ -498,7 +201,7 @@
return stompSession;
}
- private StompSession getTransactedSession(StompConnection connection, String txID)
throws Exception
+ public StompSession getTransactedSession(StompConnection connection, String txID)
throws Exception
{
StompSession stompSession = transactedSessions.get(txID);
if (stompSession == null)
@@ -523,84 +226,6 @@
return stompSession;
}
- private StompFrame onDisconnect(StompFrame frame, StompConnection connection) throws
Exception
- {
- cleanup(connection);
- return null;
- }
-
- private StompFrame onSend(StompFrame frame, StompConnection connection) throws
Exception
- {
- checkConnected(connection);
- Map<String, Object> headers = frame.getHeaders();
- String destination = (String)headers.remove(Stomp.Headers.Send.DESTINATION);
- String txID = (String)headers.remove(Stomp.Headers.TRANSACTION);
- long timestamp = System.currentTimeMillis();
-
- ServerMessageImpl message = new
ServerMessageImpl(server.getStorageManager().generateUniqueID(), 512);
- message.setTimestamp(timestamp);
- message.setAddress(SimpleString.toSimpleString(destination));
- StompUtils.copyStandardHeadersFromFrameToMessage(frame, message);
- if (headers.containsKey(Stomp.Headers.CONTENT_LENGTH))
- {
- message.setType(Message.BYTES_TYPE);
- message.getBodyBuffer().writeBytes(frame.getContent());
- }
- else
- {
- message.setType(Message.TEXT_TYPE);
- String text = new String(frame.getContent(), "UTF-8");
-
message.getBodyBuffer().writeNullableSimpleString(SimpleString.toSimpleString(text));
- }
-
- StompSession stompSession = null;
- if (txID == null)
- {
- stompSession = getSession(connection);
- }
- else
- {
- stompSession = getTransactedSession(connection, txID);
- }
- if (stompSession.isNoLocal())
- {
- message.putStringProperty(CONNECTION_ID_PROP, connection.getID().toString());
- }
- stompSession.getSession().send(message, true);
-
- return null;
- }
-
- private StompFrame onConnect(StompFrame frame, final StompConnection connection)
throws Exception
- {
- Map<String, Object> headers = frame.getHeaders();
- String login = (String)headers.get(Stomp.Headers.Connect.LOGIN);
- String passcode = (String)headers.get(Stomp.Headers.Connect.PASSCODE);
- String clientID = (String)headers.get(Stomp.Headers.Connect.CLIENT_ID);
- String requestID = (String)headers.get(Stomp.Headers.Connect.REQUEST_ID);
-
- HornetQSecurityManager sm = server.getSecurityManager();
-
- // The sm will be null case security is not enabled...
- if (sm != null)
- {
- sm.validateUser(login, passcode);
- }
-
- connection.setLogin(login);
- connection.setPasscode(passcode);
- connection.setClientID(clientID);
- connection.setValid(true);
-
- HashMap<String, Object> h = new HashMap<String, Object>();
- h.put(Stomp.Headers.Connected.SESSION, connection.getID());
- if (requestID != null)
- {
- h.put(Stomp.Headers.Connected.RESPONSE_ID, requestID);
- }
- return new StompFrame(Stomp.Responses.CONNECTED, h);
- }
-
public void cleanup(final StompConnection connection)
{
connection.setValid(false);
@@ -648,15 +273,18 @@
});
}
- private void sendReply(final StompConnection connection, final StompFrame frame)
+ public void sendReply(final StompConnection connection, final StompFrame frame)
{
server.getStorageManager().afterCompleteOperations(new IOAsyncTask()
{
public void onError(final int errorCode, final String errorMessage)
{
log.warn("Error processing IOCallback code = " + errorCode + "
message = " + errorMessage);
+
+ HornetQStompException e = new HornetQStompException("Error sending
reply",
+ new HornetQException(errorCode, errorMessage));
- StompFrame error = createError(new HornetQException(errorCode, errorMessage),
frame);
+ StompFrame error = e.getFrame();
send(connection, error);
}
@@ -666,5 +294,108 @@
}
});
}
+
+ public String getSupportedVersionsAsString()
+ {
+ return "v1.0 v1.1";
+ }
+
+ public String getVirtualHostName()
+ {
+ return "hornetq";
+ }
+
+ public boolean validateUser(String login, String passcode)
+ {
+ boolean validated = true;
+
+ HornetQSecurityManager sm = server.getSecurityManager();
+
+ // The sm will be null case security is not enabled...
+ if (sm != null)
+ {
+ validated = sm.validateUser(login, passcode);
+ }
+
+ return validated;
+ }
+
+ public ServerMessageImpl createServerMessage()
+ {
+ return new ServerMessageImpl(server.getStorageManager().generateUniqueID(), 512);
+ }
+
+ public void commitTransaction(StompConnection connection, String txID) throws
Exception
+ {
+ StompSession session = getTransactedSession(connection, txID);
+ if (session == null)
+ {
+ throw new HornetQStompException("No transaction started: " + txID);
+ }
+ transactedSessions.remove(txID);
+ session.getSession().commit();
+ }
+
+ public void abortTransaction(StompConnection connection, String txID) throws
Exception
+ {
+ StompSession session = getTransactedSession(connection, txID);
+ if (session == null)
+ {
+ throw new HornetQStompException("No transaction started: " + txID);
+ }
+ transactedSessions.remove(txID);
+ session.getSession().rollback(false);
+ }
// Inner classes -------------------------------------------------
+
+ public void createSubscription(StompConnection connection,
+ String subscriptionID, String durableSubscriptionName,
+ String destination, String selector, String ack, boolean noLocal) throws
Exception
+ {
+ StompSession stompSession = getSession(connection);
+ stompSession.setNoLocal(noLocal);
+ if (stompSession.containsSubscription(subscriptionID))
+ {
+ throw new HornetQStompException("There already is a subscription for:
" + subscriptionID +
+ ". Either use unique subscription IDs or do not
create multiple subscriptions for the same destination");
+ }
+ long consumerID = server.getStorageManager().generateUniqueID();
+ String clientID = (connection.getClientID() != null) ? connection.getClientID() :
null;
+ stompSession.addSubscription(consumerID,
+ subscriptionID,
+ clientID,
+ durableSubscriptionName,
+ destination,
+ selector,
+ ack);
+ }
+
+ public void unsubscribe(StompConnection connection,
+ String subscriptionID) throws Exception
+ {
+ StompSession stompSession = getSession(connection);
+ boolean unsubscribed = stompSession.unsubscribe(subscriptionID);
+ if (!unsubscribed)
+ {
+ throw new HornetQStompException("Cannot unsubscribe as no subscription
exists for id: " + subscriptionID);
+ }
+ }
+
+ public void acknowledge(StompConnection connection, String messageID, String
subscriptionID) throws Exception
+ {
+ StompSession stompSession = getSession(connection);
+ stompSession.acknowledge(messageID, subscriptionID);
+ }
+
+ public void beginTransaction(StompConnection connection, String txID) throws
Exception
+ {
+ log.error("-------------------------------begin tx: " + txID);
+ if (transactedSessions.containsKey(txID))
+ {
+ log.error("------------------------------Error, tx already exist!");
+ throw new HornetQStompException(connection, "Transaction already started:
" + txID);
+ }
+ // create the transacted session
+ getTransactedSession(connection, txID);
+ }
}
Modified:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompSession.java
===================================================================
---
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompSession.java 2011-10-12
08:04:52 UTC (rev 11518)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompSession.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -43,7 +43,7 @@
*
* @author <a href="mailto:jmesnil@redhat.com">Jeff Mesnil</a>
*/
-class StompSession implements SessionCallback
+public class StompSession implements SessionCallback
{
private static final Logger log = Logger.getLogger(StompSession.class);
@@ -94,11 +94,11 @@
{
StompSubscription subscription = subscriptions.get(consumerID);
- StompFrame frame = createFrame(serverMessage, deliveryCount, subscription);
+ StompFrame frame = connection.createStompMessage(serverMessage, subscription,
deliveryCount);
int length = frame.getEncodedSize();
- if (subscription.isAutoACK())
+ if (subscription.getAck().equals(Stomp.Headers.Subscribe.AckModeValues.AUTO))
{
session.acknowledge(consumerID, serverMessage.getMessageID());
session.commit();
@@ -122,57 +122,6 @@
}
- /**
- * @param serverMessage
- * @param deliveryCount
- * @param subscription
- * @return
- * @throws UnsupportedEncodingException
- * @throws Exception
- */
- private StompFrame createFrame(ServerMessage serverMessage, int deliveryCount,
StompSubscription subscription) throws UnsupportedEncodingException,
-
Exception
- {
- synchronized (serverMessage)
- {
- Map<String, Object> headers = new HashMap<String, Object>();
- headers.put(Stomp.Headers.Message.DESTINATION,
serverMessage.getAddress().toString());
- if (subscription.getID() != null)
- {
- headers.put(Stomp.Headers.Message.SUBSCRIPTION, subscription.getID());
- }
-
- HornetQBuffer buffer = serverMessage.getBodyBuffer();
-
- int bodyPos = serverMessage.getEndOfBodyPosition() == -1 ? buffer.writerIndex()
- :
serverMessage.getEndOfBodyPosition();
- int size = bodyPos - buffer.readerIndex();
- buffer.readerIndex(MessageImpl.BUFFER_HEADER_SPACE + DataConstants.SIZE_INT);
- byte[] data = new byte[size];
- if (serverMessage.containsProperty(Stomp.Headers.CONTENT_LENGTH) ||
serverMessage.getType() == Message.BYTES_TYPE)
- {
- headers.put(Headers.CONTENT_LENGTH, data.length);
- buffer.readBytes(data);
- }
- else
- {
- SimpleString text = buffer.readNullableSimpleString();
- if (text != null)
- {
- data = text.toString().getBytes("UTF-8");
- }
- else
- {
- data = new byte[0];
- }
- }
- serverMessage.getBodyBuffer().resetReaderIndex();
- StompFrame frame = new StompFrame(Stomp.Responses.MESSAGE, headers, data);
- StompUtils.copyStandardHeadersFromMessageToFrame(serverMessage, frame,
deliveryCount);
- return frame;
- }
- }
-
public int sendLargeMessageContinuation(long consumerID, byte[] body, boolean
continues, boolean requiresResponse)
{
return 0;
@@ -197,24 +146,44 @@
connection.getTransportConnection().removeReadyListener(listener);
}
- public void acknowledge(String messageID) throws Exception
+ public void acknowledge(String messageID, String subscriptionID) throws Exception
{
long id = Long.parseLong(messageID);
Pair<Long, Integer> pair = messagesToAck.remove(id);
- if (pair != null)
+ if (pair == null)
{
- long consumerID = pair.getA();
- int credits = pair.getB();
-
- if (this.consumerCredits != -1)
+ throw new HornetQStompException("failed to ack because no message with id:
" + id);
+ }
+
+ long consumerID = pair.getA();
+ int credits = pair.getB();
+
+ StompSubscription sub = subscriptions.get(consumerID);
+
+ if (subscriptionID != null)
+ {
+ if (!sub.getID().equals(subscriptionID))
{
- session.receiveConsumerCredits(consumerID, credits);
+ throw new HornetQStompException("subscription id " + subscriptionID
+ " does not match " + sub.getID());
}
-
+ }
+
+ if (this.consumerCredits != -1)
+ {
+ session.receiveConsumerCredits(consumerID, credits);
+ }
+
+ if (sub.getAck().equals(Stomp.Headers.Subscribe.AckModeValues.CLIENT_INDIVIDUAL))
+ {
+ session.individualAcknowledge(consumerID, id);
+ }
+ else
+ {
session.acknowledge(consumerID, id);
- session.commit();
}
+
+ session.commit();
}
public void addSubscription(long consumerID,
@@ -250,10 +219,10 @@
}
session.createConsumer(consumerID, queue, SimpleString.toSimpleString(selector),
false);
- StompSubscription subscription = new StompSubscription(subscriptionID,
ack.equals(Stomp.Headers.Subscribe.AckModeValues.AUTO));
+ StompSubscription subscription = new StompSubscription(subscriptionID, ack);
subscriptions.put(consumerID, subscription);
- if (subscription.isAutoACK())
+ if (subscription.getAck().equals(Stomp.Headers.Subscribe.AckModeValues.AUTO))
{
session.receiveConsumerCredits(consumerID, -1);
}
@@ -317,4 +286,4 @@
{
this.noLocal = noLocal;
}
-}
\ No newline at end of file
+}
Modified:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompSubscription.java
===================================================================
---
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompSubscription.java 2011-10-12
08:04:52 UTC (rev 11518)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompSubscription.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -28,23 +28,23 @@
private final String subID;
- private final boolean autoACK;
+ private final String ack;
// Static --------------------------------------------------------
// Constructors --------------------------------------------------
- public StompSubscription(String subID, boolean ack)
+ public StompSubscription(String subID, String ack)
{
this.subID = subID;
- this.autoACK = ack;
+ this.ack = ack;
}
// Public --------------------------------------------------------
- public boolean isAutoACK()
+ public String getAck()
{
- return autoACK;
+ return ack;
}
public String getID()
@@ -55,7 +55,7 @@
@Override
public String toString()
{
- return "StompSubscription[id=" + subID + ", autoACK=" + autoACK
+ "]";
+ return "StompSubscription[id=" + subID + ", ack=" + ack +
"]";
}
// Package protected ---------------------------------------------
Modified:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompUtils.java
===================================================================
---
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompUtils.java 2011-10-12
08:04:52 UTC (rev 11518)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompUtils.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -32,7 +32,7 @@
*
*
*/
-class StompUtils
+public class StompUtils
{
// Constants -----------------------------------------------------
private static final String DEFAULT_MESSAGE_PRIORITY= "4";
@@ -46,8 +46,8 @@
public static void copyStandardHeadersFromFrameToMessage(StompFrame frame,
ServerMessageImpl msg) throws Exception
{
- Map<String, Object> headers = new HashMap<String,
Object>(frame.getHeaders());
-
+ Map<String, String> headers = new HashMap<String,
String>(frame.getHeadersMap());
+
String priority = (String)headers.remove(Stomp.Headers.Send.PRIORITY);
if (priority != null)
{
@@ -82,10 +82,10 @@
}
// now the general headers
- for (Iterator<Map.Entry<String, Object>> iter =
headers.entrySet().iterator(); iter.hasNext();)
+ for (Iterator<Map.Entry<String, String>> iter =
headers.entrySet().iterator(); iter.hasNext();)
{
- Map.Entry<String, Object> entry = iter.next();
- String name = (String)entry.getKey();
+ Map.Entry<String, String> entry = iter.next();
+ String name = entry.getKey();
Object value = entry.getValue();
msg.putObjectProperty(name, value);
}
@@ -93,41 +93,42 @@
public static void copyStandardHeadersFromMessageToFrame(MessageInternal message,
StompFrame command, int deliveryCount) throws Exception
{
- final Map<String, Object> headers = command.getHeaders();
- headers.put(Stomp.Headers.Message.DESTINATION, message.getAddress().toString());
- headers.put(Stomp.Headers.Message.MESSAGE_ID, message.getMessageID());
+ command.addHeader(Stomp.Headers.Message.MESSAGE_ID,
String.valueOf(message.getMessageID()));
+ command.addHeader(Stomp.Headers.Message.DESTINATION,
message.getAddress().toString());
if (message.getObjectProperty("JMSCorrelationID") != null)
{
- headers.put(Stomp.Headers.Message.CORRELATION_ID,
message.getObjectProperty("JMSCorrelationID"));
+ command.addHeader(Stomp.Headers.Message.CORRELATION_ID,
message.getObjectProperty("JMSCorrelationID").toString());
}
- headers.put(Stomp.Headers.Message.EXPIRATION_TIME, "" +
message.getExpiration());
- headers.put(Stomp.Headers.Message.REDELIVERED, deliveryCount > 1);
- headers.put(Stomp.Headers.Message.PRORITY, "" + message.getPriority());
+ command.addHeader(Stomp.Headers.Message.EXPIRATION_TIME, "" +
message.getExpiration());
+ command.addHeader(Stomp.Headers.Message.REDELIVERED, String.valueOf(deliveryCount
> 1));
+ command.addHeader(Stomp.Headers.Message.PRORITY, "" +
message.getPriority());
if (message.getStringProperty(ClientMessageImpl.REPLYTO_HEADER_NAME) != null)
{
- headers.put(Stomp.Headers.Message.REPLY_TO,
+ command.addHeader(Stomp.Headers.Message.REPLY_TO,
message.getStringProperty(ClientMessageImpl.REPLYTO_HEADER_NAME));
}
- headers.put(Stomp.Headers.Message.TIMESTAMP, "" +
message.getTimestamp());
+ command.addHeader(Stomp.Headers.Message.TIMESTAMP, "" +
message.getTimestamp());
if (message.getObjectProperty("JMSType") != null)
{
- headers.put(Stomp.Headers.Message.TYPE,
message.getObjectProperty("JMSType"));
+ command.addHeader(Stomp.Headers.Message.TYPE,
message.getObjectProperty("JMSType").toString());
}
// now lets add all the message headers
Set<SimpleString> names = message.getPropertyNames();
for (SimpleString name : names)
{
+ String value = name.toString();
if (name.equals(ClientMessageImpl.REPLYTO_HEADER_NAME) ||
- name.toString().equals("JMSType") ||
- name.toString().equals("JMSCorrelationID"))
+ value.equals("JMSType") ||
+ value.equals("JMSCorrelationID") ||
+ value.equals(Stomp.Headers.Message.DESTINATION))
{
continue;
}
- headers.put(name.toString(), message.getObjectProperty(name));
+ command.addHeader(name.toString(), message.getObjectProperty(name).toString());
}
}
// Constructors --------------------------------------------------
Copied:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompVersions.java (from
rev 11517,
branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompVersions.java)
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompVersions.java
(rev 0)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompVersions.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat 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.hornetq.core.protocol.stomp;
+
+/**
+ * Stomp Spec Versions
+ *
+ * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
+ *
+ */
+public enum StompVersions
+{
+ V1_0,
+ V1_1;
+
+ public String toString()
+ {
+ if (this == V1_0)
+ {
+ return "1.0";
+ }
+ return "1.1";
+ }
+}
Copied:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/VersionedStompFrameHandler.java
(from rev 11517,
branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/VersionedStompFrameHandler.java)
===================================================================
---
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/VersionedStompFrameHandler.java
(rev 0)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/VersionedStompFrameHandler.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat 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.hornetq.core.protocol.stomp;
+
+import java.io.UnsupportedEncodingException;
+
+import org.hornetq.api.core.HornetQBuffer;
+import org.hornetq.core.logging.Logger;
+import org.hornetq.core.protocol.stomp.v10.StompFrameHandlerV10;
+import org.hornetq.core.protocol.stomp.v11.StompFrameHandlerV11;
+import org.hornetq.core.server.ServerMessage;
+
+/**
+ *
+ * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
+ */
+public abstract class VersionedStompFrameHandler
+{
+ private static final Logger log = Logger.getLogger(VersionedStompFrameHandler.class);
+
+ protected StompConnection connection;
+
+ public static VersionedStompFrameHandler getHandler(StompConnection connection,
StompVersions version)
+ {
+ if (version == StompVersions.V1_0)
+ {
+ return new StompFrameHandlerV10(connection);
+ }
+ if (version == StompVersions.V1_1)
+ {
+ return new StompFrameHandlerV11(connection);
+ }
+ return null;
+ }
+
+ public StompFrame handleFrame(StompFrame request)
+ {
+ StompFrame response = null;
+
+ if (Stomp.Commands.SEND.equals(request.getCommand()))
+ {
+ response = onSend(request);
+ }
+ else if (Stomp.Commands.ACK.equals(request.getCommand()))
+ {
+ response = onAck(request);
+ }
+ else if (Stomp.Commands.NACK.equals(request.getCommand()))
+ {
+ response = onNack(request);
+ }
+ else if (Stomp.Commands.BEGIN.equals(request.getCommand()))
+ {
+ response = onBegin(request);
+ }
+ else if (Stomp.Commands.COMMIT.equals(request.getCommand()))
+ {
+ response = onCommit(request);
+ }
+ else if (Stomp.Commands.ABORT.equals(request.getCommand()))
+ {
+ response = onAbort(request);
+ }
+ else if (Stomp.Commands.SUBSCRIBE.equals(request.getCommand()))
+ {
+ response = onSubscribe(request);
+ }
+ else if (Stomp.Commands.UNSUBSCRIBE.equals(request.getCommand()))
+ {
+ response = onUnsubscribe(request);
+ }
+ else if (Stomp.Commands.CONNECT.equals(request.getCommand()))
+ {
+ response = onConnect(request);
+ }
+ else if (Stomp.Commands.STOMP.equals(request.getCommand()))
+ {
+ response = onStomp(request);
+ }
+ else if (Stomp.Commands.DISCONNECT.equals(request.getCommand()))
+ {
+ response = onDisconnect(request);
+ }
+ else
+ {
+ response = onUnknown(request.getCommand());
+ }
+
+ if (response == null)
+ {
+ response = postprocess(request);
+ }
+ else
+ {
+ if (request.hasHeader(Stomp.Headers.RECEIPT_REQUESTED))
+ {
+ response.addHeader(Stomp.Headers.Response.RECEIPT_ID,
request.getHeader(Stomp.Headers.RECEIPT_REQUESTED));
+ }
+ }
+
+ return response;
+ }
+
+ public abstract StompFrame onConnect(StompFrame frame);
+ public abstract StompFrame onDisconnect(StompFrame frame);
+ public abstract StompFrame onSend(StompFrame frame);
+ public abstract StompFrame onAck(StompFrame request);
+ public abstract StompFrame onBegin(StompFrame frame);
+ public abstract StompFrame onCommit(StompFrame request);
+ public abstract StompFrame onAbort(StompFrame request);
+ public abstract StompFrame onSubscribe(StompFrame request);
+ public abstract StompFrame onUnsubscribe(StompFrame request);
+ public abstract StompFrame onStomp(StompFrame request);
+ public abstract StompFrame onNack(StompFrame request);
+
+ public StompFrame onUnknown(String command)
+ {
+ StompFrame response = new HornetQStompException("Unsupported command " +
command).getFrame();
+ return response;
+ }
+
+ public StompFrame handleReceipt(String receiptID)
+ {
+ StompFrame receipt = new StompFrame(Stomp.Responses.RECEIPT);
+ receipt.addHeader(Stomp.Headers.Response.RECEIPT_ID, receiptID);
+
+ return receipt;
+ }
+
+ public abstract StompFrame postprocess(StompFrame request);
+
+ public abstract StompFrame createMessageFrame(ServerMessage serverMessage,
+ StompSubscription subscription, int deliveryCount) throws Exception;
+
+ public abstract StompFrame createStompFrame(String command);
+
+ public abstract StompFrame decode(StompDecoder decoder, final HornetQBuffer buffer)
throws HornetQStompException;
+
+}
Deleted:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameHandlerV10.java
===================================================================
---
branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameHandlerV10.java 2011-10-12
02:27:00 UTC (rev 11517)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameHandlerV10.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -1,415 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat 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.hornetq.core.protocol.stomp.v10;
-
-import java.io.UnsupportedEncodingException;
-import java.util.Map;
-
-import org.hornetq.api.core.HornetQBuffer;
-import org.hornetq.api.core.Message;
-import org.hornetq.api.core.SimpleString;
-import org.hornetq.core.logging.Logger;
-import org.hornetq.core.message.impl.MessageImpl;
-import org.hornetq.core.protocol.stomp.FrameEventListener;
-import org.hornetq.core.protocol.stomp.HornetQStompException;
-import org.hornetq.core.protocol.stomp.Stomp;
-import org.hornetq.core.protocol.stomp.StompConnection;
-import org.hornetq.core.protocol.stomp.StompDecoder;
-import org.hornetq.core.protocol.stomp.StompFrame;
-import org.hornetq.core.protocol.stomp.StompSubscription;
-import org.hornetq.core.protocol.stomp.StompUtils;
-import org.hornetq.core.protocol.stomp.VersionedStompFrameHandler;
-import org.hornetq.core.protocol.stomp.Stomp.Headers;
-import org.hornetq.core.server.ServerMessage;
-import org.hornetq.core.server.impl.ServerMessageImpl;
-import org.hornetq.utils.DataConstants;
-
-/**
-*
-* @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
-*/
-public class StompFrameHandlerV10 extends VersionedStompFrameHandler implements
FrameEventListener
-{
- private static final Logger log = Logger.getLogger(StompFrameHandlerV10.class);
-
- public StompFrameHandlerV10(StompConnection connection)
- {
- this.connection = connection;
- connection.addStompEventListener(this);
- }
-
- @Override
- public StompFrame onConnect(StompFrame frame)
- {
- StompFrame response = null;
- Map<String, String> headers = frame.getHeadersMap();
- String login = (String)headers.get(Stomp.Headers.Connect.LOGIN);
- String passcode = (String)headers.get(Stomp.Headers.Connect.PASSCODE);
- String clientID = (String)headers.get(Stomp.Headers.Connect.CLIENT_ID);
- String requestID = (String)headers.get(Stomp.Headers.Connect.REQUEST_ID);
-
- if (connection.validateUser(login, passcode))
- {
- connection.setClientID(clientID);
- connection.setValid(true);
-
- response = new StompFrameV10(Stomp.Responses.CONNECTED);
-
- if (frame.hasHeader(Stomp.Headers.ACCEPT_VERSION))
- {
- response.addHeader(Stomp.Headers.Connected.VERSION, "1.0");
- }
-
- response.addHeader(Stomp.Headers.Connected.SESSION,
connection.getID().toString());
-
- if (requestID != null)
- {
- response.addHeader(Stomp.Headers.Connected.RESPONSE_ID, requestID);
- }
- }
- else
- {
- //not valid
- response = new StompFrameV10(Stomp.Responses.ERROR);
- response.addHeader(Stomp.Headers.Error.MESSAGE, "Failed to connect");
- try
- {
- response.setBody("The login account is not valid.");
- }
- catch (UnsupportedEncodingException e)
- {
- log.error("Encoding problem", e);
- }
- }
- return response;
- }
-
- @Override
- public StompFrame onDisconnect(StompFrame frame)
- {
- return null;
- }
-
- @Override
- public StompFrame onSend(StompFrame frame)
- {
- StompFrame response = null;
- try
- {
- connection.validate();
- String destination = frame.getHeader(Stomp.Headers.Send.DESTINATION);
- String txID = frame.getHeader(Stomp.Headers.TRANSACTION);
-
- long timestamp = System.currentTimeMillis();
-
- ServerMessageImpl message = connection.createServerMessage();
- message.setTimestamp(timestamp);
- message.setAddress(SimpleString.toSimpleString(destination));
- StompUtils.copyStandardHeadersFromFrameToMessage(frame, message);
- if (frame.hasHeader(Stomp.Headers.CONTENT_LENGTH))
- {
- message.setType(Message.BYTES_TYPE);
- message.getBodyBuffer().writeBytes(frame.getBodyAsBytes());
- }
- else
- {
- message.setType(Message.TEXT_TYPE);
- String text = frame.getBody();
-
message.getBodyBuffer().writeNullableSimpleString(SimpleString.toSimpleString(text));
- }
-
- connection.sendServerMessage(message, txID);
- }
- catch (HornetQStompException e)
- {
- response = e.getFrame();
- }
- catch (Exception e)
- {
- response = new HornetQStompException("Error handling send",
e).getFrame();
- }
-
- return response;
- }
-
- @Override
- public StompFrame onBegin(StompFrame frame)
- {
- StompFrame response = null;
- String txID = frame.getHeader(Stomp.Headers.TRANSACTION);
- if (txID == null)
- {
- response = new HornetQStompException("Need a transaction id to
begin").getFrame();
- }
- else
- {
- try
- {
- connection.beginTransaction(txID);
- }
- catch (HornetQStompException e)
- {
- response = e.getFrame();
- }
- }
- return response;
- }
-
- @Override
- public StompFrame onCommit(StompFrame request)
- {
- StompFrame response = null;
-
- String txID = request.getHeader(Stomp.Headers.TRANSACTION);
- if (txID == null)
- {
- response = new HornetQStompException("transaction header is mandatory to
COMMIT a transaction").getFrame();
- return response;
- }
-
- try
- {
- connection.commitTransaction(txID);
- }
- catch (HornetQStompException e)
- {
- response = e.getFrame();
- }
- return response;
- }
-
- @Override
- public StompFrame onAbort(StompFrame request)
- {
- StompFrame response = null;
- String txID = request.getHeader(Stomp.Headers.TRANSACTION);
-
- if (txID == null)
- {
- response = new HornetQStompException("transaction header is mandatory to
ABORT a transaction").getFrame();
- return response;
- }
-
- try
- {
- connection.abortTransaction(txID);
- }
- catch (HornetQStompException e)
- {
- response = e.getFrame();
- }
-
- return response;
- }
-
- @Override
- public StompFrame onSubscribe(StompFrame request)
- {
- StompFrame response = null;
- String destination = request.getHeader(Stomp.Headers.Subscribe.DESTINATION);
-
- String selector = request.getHeader(Stomp.Headers.Subscribe.SELECTOR);
- String ack = request.getHeader(Stomp.Headers.Subscribe.ACK_MODE);
- String id = request.getHeader(Stomp.Headers.Subscribe.ID);
- String durableSubscriptionName =
request.getHeader(Stomp.Headers.Subscribe.DURABLE_SUBSCRIBER_NAME);
- boolean noLocal = false;
-
- if (request.hasHeader(Stomp.Headers.Subscribe.NO_LOCAL))
- {
- noLocal =
Boolean.parseBoolean(request.getHeader(Stomp.Headers.Subscribe.NO_LOCAL));
- }
-
- try
- {
- connection.subscribe(destination, selector, ack, id, durableSubscriptionName,
noLocal);
- }
- catch (HornetQStompException e)
- {
- response = e.getFrame();
- }
-
- return response;
- }
-
- @Override
- public StompFrame onUnsubscribe(StompFrame request)
- {
- StompFrame response = null;
- String destination = request.getHeader(Stomp.Headers.Unsubscribe.DESTINATION);
- String id = request.getHeader(Stomp.Headers.Unsubscribe.ID);
-
- String subscriptionID = null;
- if (id != null)
- {
- subscriptionID = id;
- }
- else
- {
- if (destination == null)
- {
- response = new HornetQStompException("Must specify the
subscription's id or " +
- "the destination you are unsubscribing from").getFrame();
- return response;
- }
- subscriptionID = "subscription/" + destination;
- }
-
- try
- {
- connection.unsubscribe(subscriptionID);
- }
- catch (HornetQStompException e)
- {
- return e.getFrame();
- }
- return response;
- }
-
- @Override
- public StompFrame onAck(StompFrame request)
- {
- StompFrame response = null;
-
- String messageID = request.getHeader(Stomp.Headers.Ack.MESSAGE_ID);
- String txID = request.getHeader(Stomp.Headers.TRANSACTION);
-
- if (txID != null)
- {
- log.warn("Transactional acknowledgement is not supported");
- }
-
- try
- {
- connection.acknowledge(messageID, null);
- }
- catch (HornetQStompException e)
- {
- response = e.getFrame();
- }
-
- return response;
- }
-
- @Override
- public StompFrame onStomp(StompFrame request)
- {
- return onUnknown(request.getCommand());
- }
-
- @Override
- public StompFrame onNack(StompFrame request)
- {
- return onUnknown(request.getCommand());
- }
-
- @Override
- public StompFrame createMessageFrame(ServerMessage serverMessage,
- StompSubscription subscription, int deliveryCount) throws Exception
- {
- StompFrame frame = new StompFrame(Stomp.Responses.MESSAGE);
-
- if (subscription.getID() != null)
- {
- frame.addHeader(Stomp.Headers.Message.SUBSCRIPTION, subscription.getID());
- }
-
- synchronized(serverMessage)
- {
-
- HornetQBuffer buffer = serverMessage.getBodyBuffer();
-
- int bodyPos = serverMessage.getEndOfBodyPosition() == -1 ? buffer.writerIndex()
- :
serverMessage.getEndOfBodyPosition();
- int size = bodyPos - buffer.readerIndex();
- buffer.readerIndex(MessageImpl.BUFFER_HEADER_SPACE + DataConstants.SIZE_INT);
- byte[] data = new byte[size];
-
- if (serverMessage.containsProperty(Stomp.Headers.CONTENT_LENGTH) ||
serverMessage.getType() == Message.BYTES_TYPE)
- {
- frame.addHeader(Headers.CONTENT_LENGTH, String.valueOf(data.length));
- buffer.readBytes(data);
- }
- else
- {
- SimpleString text = buffer.readNullableSimpleString();
- if (text != null)
- {
- data = text.toString().getBytes("UTF-8");
- }
- else
- {
- data = new byte[0];
- }
- }
- frame.setByteBody(data);
-
- serverMessage.getBodyBuffer().resetReaderIndex();
-
- StompUtils.copyStandardHeadersFromMessageToFrame(serverMessage, frame,
deliveryCount);
- }
-
- return frame;
-
- }
-
- @Override
- public StompFrame createStompFrame(String command)
- {
- return new StompFrameV10(command);
- }
-
- public StompFrame decode(StompDecoder decoder, final HornetQBuffer buffer) throws
HornetQStompException
- {
- return decoder.defaultDecode(buffer);
- }
-
- @Override
- public void replySent(StompFrame reply)
- {
- if (reply.needsDisconnect())
- {
- connection.destroy();
- }
- }
-
- @Override
- public void requestAccepted(StompFrame request)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public StompFrame postprocess(StompFrame request)
- {
- StompFrame response = null;
- if (request.hasHeader(Stomp.Headers.RECEIPT_REQUESTED))
- {
- response = handleReceipt(request.getHeader(Stomp.Headers.RECEIPT_REQUESTED));
- if (request.getCommand().equals(Stomp.Commands.DISCONNECT))
- {
- response.setNeedsDisconnect(true);
- }
- }
- else
- {
- //request null, disconnect if so.
- if (request.getCommand().equals(Stomp.Commands.DISCONNECT))
- {
- this.connection.disconnect();
- }
- }
- return response;
- }
-
-}
Copied:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameHandlerV10.java
(from rev 11517,
branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameHandlerV10.java)
===================================================================
---
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameHandlerV10.java
(rev 0)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameHandlerV10.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,415 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat 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.hornetq.core.protocol.stomp.v10;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Map;
+
+import org.hornetq.api.core.HornetQBuffer;
+import org.hornetq.api.core.Message;
+import org.hornetq.api.core.SimpleString;
+import org.hornetq.core.logging.Logger;
+import org.hornetq.core.message.impl.MessageImpl;
+import org.hornetq.core.protocol.stomp.FrameEventListener;
+import org.hornetq.core.protocol.stomp.HornetQStompException;
+import org.hornetq.core.protocol.stomp.Stomp;
+import org.hornetq.core.protocol.stomp.StompConnection;
+import org.hornetq.core.protocol.stomp.StompDecoder;
+import org.hornetq.core.protocol.stomp.StompFrame;
+import org.hornetq.core.protocol.stomp.StompSubscription;
+import org.hornetq.core.protocol.stomp.StompUtils;
+import org.hornetq.core.protocol.stomp.VersionedStompFrameHandler;
+import org.hornetq.core.protocol.stomp.Stomp.Headers;
+import org.hornetq.core.server.ServerMessage;
+import org.hornetq.core.server.impl.ServerMessageImpl;
+import org.hornetq.utils.DataConstants;
+
+/**
+*
+* @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
+*/
+public class StompFrameHandlerV10 extends VersionedStompFrameHandler implements
FrameEventListener
+{
+ private static final Logger log = Logger.getLogger(StompFrameHandlerV10.class);
+
+ public StompFrameHandlerV10(StompConnection connection)
+ {
+ this.connection = connection;
+ connection.addStompEventListener(this);
+ }
+
+ @Override
+ public StompFrame onConnect(StompFrame frame)
+ {
+ StompFrame response = null;
+ Map<String, String> headers = frame.getHeadersMap();
+ String login = (String)headers.get(Stomp.Headers.Connect.LOGIN);
+ String passcode = (String)headers.get(Stomp.Headers.Connect.PASSCODE);
+ String clientID = (String)headers.get(Stomp.Headers.Connect.CLIENT_ID);
+ String requestID = (String)headers.get(Stomp.Headers.Connect.REQUEST_ID);
+
+ if (connection.validateUser(login, passcode))
+ {
+ connection.setClientID(clientID);
+ connection.setValid(true);
+
+ response = new StompFrameV10(Stomp.Responses.CONNECTED);
+
+ if (frame.hasHeader(Stomp.Headers.ACCEPT_VERSION))
+ {
+ response.addHeader(Stomp.Headers.Connected.VERSION, "1.0");
+ }
+
+ response.addHeader(Stomp.Headers.Connected.SESSION,
connection.getID().toString());
+
+ if (requestID != null)
+ {
+ response.addHeader(Stomp.Headers.Connected.RESPONSE_ID, requestID);
+ }
+ }
+ else
+ {
+ //not valid
+ response = new StompFrameV10(Stomp.Responses.ERROR);
+ response.addHeader(Stomp.Headers.Error.MESSAGE, "Failed to connect");
+ try
+ {
+ response.setBody("The login account is not valid.");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ log.error("Encoding problem", e);
+ }
+ }
+ return response;
+ }
+
+ @Override
+ public StompFrame onDisconnect(StompFrame frame)
+ {
+ return null;
+ }
+
+ @Override
+ public StompFrame onSend(StompFrame frame)
+ {
+ StompFrame response = null;
+ try
+ {
+ connection.validate();
+ String destination = frame.getHeader(Stomp.Headers.Send.DESTINATION);
+ String txID = frame.getHeader(Stomp.Headers.TRANSACTION);
+
+ long timestamp = System.currentTimeMillis();
+
+ ServerMessageImpl message = connection.createServerMessage();
+ message.setTimestamp(timestamp);
+ message.setAddress(SimpleString.toSimpleString(destination));
+ StompUtils.copyStandardHeadersFromFrameToMessage(frame, message);
+ if (frame.hasHeader(Stomp.Headers.CONTENT_LENGTH))
+ {
+ message.setType(Message.BYTES_TYPE);
+ message.getBodyBuffer().writeBytes(frame.getBodyAsBytes());
+ }
+ else
+ {
+ message.setType(Message.TEXT_TYPE);
+ String text = frame.getBody();
+
message.getBodyBuffer().writeNullableSimpleString(SimpleString.toSimpleString(text));
+ }
+
+ connection.sendServerMessage(message, txID);
+ }
+ catch (HornetQStompException e)
+ {
+ response = e.getFrame();
+ }
+ catch (Exception e)
+ {
+ response = new HornetQStompException("Error handling send",
e).getFrame();
+ }
+
+ return response;
+ }
+
+ @Override
+ public StompFrame onBegin(StompFrame frame)
+ {
+ StompFrame response = null;
+ String txID = frame.getHeader(Stomp.Headers.TRANSACTION);
+ if (txID == null)
+ {
+ response = new HornetQStompException("Need a transaction id to
begin").getFrame();
+ }
+ else
+ {
+ try
+ {
+ connection.beginTransaction(txID);
+ }
+ catch (HornetQStompException e)
+ {
+ response = e.getFrame();
+ }
+ }
+ return response;
+ }
+
+ @Override
+ public StompFrame onCommit(StompFrame request)
+ {
+ StompFrame response = null;
+
+ String txID = request.getHeader(Stomp.Headers.TRANSACTION);
+ if (txID == null)
+ {
+ response = new HornetQStompException("transaction header is mandatory to
COMMIT a transaction").getFrame();
+ return response;
+ }
+
+ try
+ {
+ connection.commitTransaction(txID);
+ }
+ catch (HornetQStompException e)
+ {
+ response = e.getFrame();
+ }
+ return response;
+ }
+
+ @Override
+ public StompFrame onAbort(StompFrame request)
+ {
+ StompFrame response = null;
+ String txID = request.getHeader(Stomp.Headers.TRANSACTION);
+
+ if (txID == null)
+ {
+ response = new HornetQStompException("transaction header is mandatory to
ABORT a transaction").getFrame();
+ return response;
+ }
+
+ try
+ {
+ connection.abortTransaction(txID);
+ }
+ catch (HornetQStompException e)
+ {
+ response = e.getFrame();
+ }
+
+ return response;
+ }
+
+ @Override
+ public StompFrame onSubscribe(StompFrame request)
+ {
+ StompFrame response = null;
+ String destination = request.getHeader(Stomp.Headers.Subscribe.DESTINATION);
+
+ String selector = request.getHeader(Stomp.Headers.Subscribe.SELECTOR);
+ String ack = request.getHeader(Stomp.Headers.Subscribe.ACK_MODE);
+ String id = request.getHeader(Stomp.Headers.Subscribe.ID);
+ String durableSubscriptionName =
request.getHeader(Stomp.Headers.Subscribe.DURABLE_SUBSCRIBER_NAME);
+ boolean noLocal = false;
+
+ if (request.hasHeader(Stomp.Headers.Subscribe.NO_LOCAL))
+ {
+ noLocal =
Boolean.parseBoolean(request.getHeader(Stomp.Headers.Subscribe.NO_LOCAL));
+ }
+
+ try
+ {
+ connection.subscribe(destination, selector, ack, id, durableSubscriptionName,
noLocal);
+ }
+ catch (HornetQStompException e)
+ {
+ response = e.getFrame();
+ }
+
+ return response;
+ }
+
+ @Override
+ public StompFrame onUnsubscribe(StompFrame request)
+ {
+ StompFrame response = null;
+ String destination = request.getHeader(Stomp.Headers.Unsubscribe.DESTINATION);
+ String id = request.getHeader(Stomp.Headers.Unsubscribe.ID);
+
+ String subscriptionID = null;
+ if (id != null)
+ {
+ subscriptionID = id;
+ }
+ else
+ {
+ if (destination == null)
+ {
+ response = new HornetQStompException("Must specify the
subscription's id or " +
+ "the destination you are unsubscribing from").getFrame();
+ return response;
+ }
+ subscriptionID = "subscription/" + destination;
+ }
+
+ try
+ {
+ connection.unsubscribe(subscriptionID);
+ }
+ catch (HornetQStompException e)
+ {
+ return e.getFrame();
+ }
+ return response;
+ }
+
+ @Override
+ public StompFrame onAck(StompFrame request)
+ {
+ StompFrame response = null;
+
+ String messageID = request.getHeader(Stomp.Headers.Ack.MESSAGE_ID);
+ String txID = request.getHeader(Stomp.Headers.TRANSACTION);
+
+ if (txID != null)
+ {
+ log.warn("Transactional acknowledgement is not supported");
+ }
+
+ try
+ {
+ connection.acknowledge(messageID, null);
+ }
+ catch (HornetQStompException e)
+ {
+ response = e.getFrame();
+ }
+
+ return response;
+ }
+
+ @Override
+ public StompFrame onStomp(StompFrame request)
+ {
+ return onUnknown(request.getCommand());
+ }
+
+ @Override
+ public StompFrame onNack(StompFrame request)
+ {
+ return onUnknown(request.getCommand());
+ }
+
+ @Override
+ public StompFrame createMessageFrame(ServerMessage serverMessage,
+ StompSubscription subscription, int deliveryCount) throws Exception
+ {
+ StompFrame frame = new StompFrame(Stomp.Responses.MESSAGE);
+
+ if (subscription.getID() != null)
+ {
+ frame.addHeader(Stomp.Headers.Message.SUBSCRIPTION, subscription.getID());
+ }
+
+ synchronized(serverMessage)
+ {
+
+ HornetQBuffer buffer = serverMessage.getBodyBuffer();
+
+ int bodyPos = serverMessage.getEndOfBodyPosition() == -1 ? buffer.writerIndex()
+ :
serverMessage.getEndOfBodyPosition();
+ int size = bodyPos - buffer.readerIndex();
+ buffer.readerIndex(MessageImpl.BUFFER_HEADER_SPACE + DataConstants.SIZE_INT);
+ byte[] data = new byte[size];
+
+ if (serverMessage.containsProperty(Stomp.Headers.CONTENT_LENGTH) ||
serverMessage.getType() == Message.BYTES_TYPE)
+ {
+ frame.addHeader(Headers.CONTENT_LENGTH, String.valueOf(data.length));
+ buffer.readBytes(data);
+ }
+ else
+ {
+ SimpleString text = buffer.readNullableSimpleString();
+ if (text != null)
+ {
+ data = text.toString().getBytes("UTF-8");
+ }
+ else
+ {
+ data = new byte[0];
+ }
+ }
+ frame.setByteBody(data);
+
+ serverMessage.getBodyBuffer().resetReaderIndex();
+
+ StompUtils.copyStandardHeadersFromMessageToFrame(serverMessage, frame,
deliveryCount);
+ }
+
+ return frame;
+
+ }
+
+ @Override
+ public StompFrame createStompFrame(String command)
+ {
+ return new StompFrameV10(command);
+ }
+
+ public StompFrame decode(StompDecoder decoder, final HornetQBuffer buffer) throws
HornetQStompException
+ {
+ return decoder.defaultDecode(buffer);
+ }
+
+ @Override
+ public void replySent(StompFrame reply)
+ {
+ if (reply.needsDisconnect())
+ {
+ connection.destroy();
+ }
+ }
+
+ @Override
+ public void requestAccepted(StompFrame request)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public StompFrame postprocess(StompFrame request)
+ {
+ StompFrame response = null;
+ if (request.hasHeader(Stomp.Headers.RECEIPT_REQUESTED))
+ {
+ response = handleReceipt(request.getHeader(Stomp.Headers.RECEIPT_REQUESTED));
+ if (request.getCommand().equals(Stomp.Commands.DISCONNECT))
+ {
+ response.setNeedsDisconnect(true);
+ }
+ }
+ else
+ {
+ //request null, disconnect if so.
+ if (request.getCommand().equals(Stomp.Commands.DISCONNECT))
+ {
+ this.connection.disconnect();
+ }
+ }
+ return response;
+ }
+
+}
Deleted:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameV10.java
===================================================================
---
branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameV10.java 2011-10-12
02:27:00 UTC (rev 11517)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameV10.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -1,28 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat 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.hornetq.core.protocol.stomp.v10;
-
-import org.hornetq.core.protocol.stomp.StompFrame;
-
-/**
- *
- * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
- */
-public class StompFrameV10 extends StompFrame
-{
- public StompFrameV10(String command)
- {
- super(command);
- }
-
-}
Copied:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameV10.java
(from rev 11517,
branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameV10.java)
===================================================================
---
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameV10.java
(rev 0)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameV10.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat 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.hornetq.core.protocol.stomp.v10;
+
+import org.hornetq.core.protocol.stomp.StompFrame;
+
+/**
+ *
+ * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
+ */
+public class StompFrameV10 extends StompFrame
+{
+ public StompFrameV10(String command)
+ {
+ super(command);
+ }
+
+}
Deleted:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameHandlerV11.java
===================================================================
---
branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameHandlerV11.java 2011-10-12
02:27:00 UTC (rev 11517)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameHandlerV11.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -1,1109 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat 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.hornetq.core.protocol.stomp.v11;
-
-import java.io.UnsupportedEncodingException;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.hornetq.api.core.HornetQBuffer;
-import org.hornetq.api.core.HornetQBuffers;
-import org.hornetq.api.core.Message;
-import org.hornetq.api.core.SimpleString;
-import org.hornetq.core.logging.Logger;
-import org.hornetq.core.message.impl.MessageImpl;
-import org.hornetq.core.protocol.stomp.FrameEventListener;
-import org.hornetq.core.protocol.stomp.HornetQStompException;
-import org.hornetq.core.protocol.stomp.SimpleBytes;
-import org.hornetq.core.protocol.stomp.Stomp;
-import org.hornetq.core.protocol.stomp.StompConnection;
-import org.hornetq.core.protocol.stomp.StompDecoder;
-import org.hornetq.core.protocol.stomp.StompFrame;
-import org.hornetq.core.protocol.stomp.StompSubscription;
-import org.hornetq.core.protocol.stomp.StompUtils;
-import org.hornetq.core.protocol.stomp.VersionedStompFrameHandler;
-import org.hornetq.core.server.ServerMessage;
-import org.hornetq.core.server.impl.ServerMessageImpl;
-import org.hornetq.utils.DataConstants;
-
-/**
- *
- * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
- */
-public class StompFrameHandlerV11 extends VersionedStompFrameHandler implements
FrameEventListener
-{
- private static final Logger log = Logger.getLogger(StompFrameHandlerV11.class);
-
- private static final char ESC_CHAR = '\\';
-
- private HeartBeater heartBeater;
-
- public StompFrameHandlerV11(StompConnection connection)
- {
- this.connection = connection;
- connection.addStompEventListener(this);
- }
-
- @Override
- public StompFrame onConnect(StompFrame frame)
- {
- StompFrame response = null;
- Map<String, String> headers = frame.getHeadersMap();
- String login = headers.get(Stomp.Headers.Connect.LOGIN);
- String passcode = headers.get(Stomp.Headers.Connect.PASSCODE);
- String clientID = headers.get(Stomp.Headers.Connect.CLIENT_ID);
- String requestID = headers.get(Stomp.Headers.Connect.REQUEST_ID);
-
- try
- {
- if (connection.validateUser(login, passcode))
- {
- connection.setClientID(clientID);
- connection.setValid(true);
-
- response = new StompFrameV11(Stomp.Responses.CONNECTED);
-
- // version
- response.addHeader(Stomp.Headers.Connected.VERSION,
- connection.getVersion());
-
- // session
- response.addHeader(Stomp.Headers.Connected.SESSION, connection
- .getID().toString());
-
- // server
- response.addHeader(Stomp.Headers.Connected.SERVER,
- connection.getHornetQServerName());
-
- if (requestID != null)
- {
- response.addHeader(Stomp.Headers.Connected.RESPONSE_ID,
- requestID);
- }
-
- // heart-beat. We need to start after connected frame has been sent.
- // otherwise the client may receive heart-beat before it receives
- // connected frame.
- String heartBeat = headers.get(Stomp.Headers.Connect.HEART_BEAT);
-
- if (heartBeat != null)
- {
- handleHeartBeat(heartBeat);
- if (heartBeater == null)
- {
- response.addHeader(Stomp.Headers.Connected.HEART_BEAT,
"0,0");
- }
- else
- {
- response.addHeader(Stomp.Headers.Connected.HEART_BEAT,
heartBeater.getServerHeartBeatValue());
- }
- }
- }
- else
- {
- // not valid
- response = new StompFrame(Stomp.Responses.ERROR, true);
- response.addHeader(Stomp.Headers.Error.VERSION, "1.0,1.1");
-
- response.setBody("Supported protocol versions are 1.0 and 1.1");
- }
- }
- catch (HornetQStompException e)
- {
- response = e.getFrame();
- }
- catch (UnsupportedEncodingException e)
- {
- response = new HornetQStompException("Encoding error.",
e).getFrame();
- }
- return response;
- }
-
- //ping parameters, hard-code for now
- //the server can support min 20 milliseconds and receive ping at 100 milliseconds
(20,100)
- private void handleHeartBeat(String heartBeatHeader) throws HornetQStompException
- {
- String[] params = heartBeatHeader.split(",");
- if (params.length != 2)
- {
- throw new HornetQStompException("Incorrect heartbeat header " +
heartBeatHeader);
- }
-
- //client ping
- long minPingInterval = Long.valueOf(params[0]);
- //client receive ping
- long minAcceptInterval = Long.valueOf(params[1]);
-
- if ((minPingInterval != 0) || (minAcceptInterval != 0))
- {
- heartBeater = new HeartBeater(minPingInterval, minAcceptInterval);
- }
- }
-
- @Override
- public StompFrame onDisconnect(StompFrame frame)
- {
- if (this.heartBeater != null)
- {
- heartBeater.shutdown();
- try
- {
- heartBeater.join();
- }
- catch (InterruptedException e)
- {
- log.warn("Interrupted while waiting for heart beater to die", e);
- }
- }
- return null;
- }
-
- @Override
- public StompFrame postprocess(StompFrame request)
- {
- StompFrame response = null;
- if (request.hasHeader(Stomp.Headers.RECEIPT_REQUESTED))
- {
- response = handleReceipt(request.getHeader(Stomp.Headers.RECEIPT_REQUESTED));
- if (request.getCommand().equals(Stomp.Commands.DISCONNECT))
- {
- response.setNeedsDisconnect(true);
- }
- }
- else
- {
- //request null, disconnect if so.
- if (request.getCommand().equals(Stomp.Commands.DISCONNECT))
- {
- this.connection.disconnect();
- }
- }
- return response;
- }
-
- @Override
- public StompFrame onSend(StompFrame frame)
- {
- StompFrame response = null;
- try
- {
- connection.validate();
- String destination = frame.getHeader(Stomp.Headers.Send.DESTINATION);
- String txID = frame.getHeader(Stomp.Headers.TRANSACTION);
-
- long timestamp = System.currentTimeMillis();
-
- ServerMessageImpl message = connection.createServerMessage();
- message.setTimestamp(timestamp);
- message.setAddress(SimpleString.toSimpleString(destination));
- StompUtils.copyStandardHeadersFromFrameToMessage(frame, message);
- if (frame.hasHeader(Stomp.Headers.CONTENT_LENGTH))
- {
- message.setType(Message.BYTES_TYPE);
- message.getBodyBuffer().writeBytes(frame.getBodyAsBytes());
- }
- else
- {
- message.setType(Message.TEXT_TYPE);
- String text = frame.getBody();
-
message.getBodyBuffer().writeNullableSimpleString(SimpleString.toSimpleString(text));
- }
-
- connection.sendServerMessage(message, txID);
- }
- catch (HornetQStompException e)
- {
- response = e.getFrame();
- }
- catch (Exception e)
- {
- response = new HornetQStompException("Error handling send",
e).getFrame();
- }
-
- return response;
- }
-
- @Override
- public StompFrame onBegin(StompFrame frame)
- {
- StompFrame response = null;
- String txID = frame.getHeader(Stomp.Headers.TRANSACTION);
- if (txID == null)
- {
- response = new HornetQStompException("Need a transaction id to
begin").getFrame();
- }
- else
- {
- try
- {
- connection.beginTransaction(txID);
- }
- catch (HornetQStompException e)
- {
- response = e.getFrame();
- }
- }
- return response;
- }
-
- @Override
- public StompFrame onCommit(StompFrame request)
- {
- StompFrame response = null;
-
- String txID = request.getHeader(Stomp.Headers.TRANSACTION);
- if (txID == null)
- {
- response = new HornetQStompException("transaction header is mandatory to
COMMIT a transaction").getFrame();
- return response;
- }
-
- try
- {
- connection.commitTransaction(txID);
- }
- catch (HornetQStompException e)
- {
- response = e.getFrame();
- }
- return response;
- }
-
- @Override
- public StompFrame onAbort(StompFrame request)
- {
- StompFrame response = null;
- String txID = request.getHeader(Stomp.Headers.TRANSACTION);
-
- if (txID == null)
- {
- response = new HornetQStompException("transaction header is mandatory to
ABORT a transaction").getFrame();
- return response;
- }
-
- try
- {
- connection.abortTransaction(txID);
- }
- catch (HornetQStompException e)
- {
- response = e.getFrame();
- }
-
- return response;
- }
-
- @Override
- public StompFrame onSubscribe(StompFrame request)
- {
- StompFrame response = null;
- String destination = request.getHeader(Stomp.Headers.Subscribe.DESTINATION);
-
- String selector = request.getHeader(Stomp.Headers.Subscribe.SELECTOR);
- String ack = request.getHeader(Stomp.Headers.Subscribe.ACK_MODE);
- String id = request.getHeader(Stomp.Headers.Subscribe.ID);
- String durableSubscriptionName =
request.getHeader(Stomp.Headers.Subscribe.DURABLE_SUBSCRIBER_NAME);
- boolean noLocal = false;
-
- if (request.hasHeader(Stomp.Headers.Subscribe.NO_LOCAL))
- {
- noLocal =
Boolean.parseBoolean(request.getHeader(Stomp.Headers.Subscribe.NO_LOCAL));
- }
-
- try
- {
- connection.subscribe(destination, selector, ack, id, durableSubscriptionName,
noLocal);
- }
- catch (HornetQStompException e)
- {
- response = e.getFrame();
- }
-
- return response;
- }
-
- @Override
- public StompFrame onUnsubscribe(StompFrame request)
- {
- StompFrame response = null;
- //unsubscribe in 1.1 only needs id header
- String id = request.getHeader(Stomp.Headers.Unsubscribe.ID);
-
- String subscriptionID = null;
- if (id != null)
- {
- subscriptionID = id;
- }
- else
- {
- response = new HornetQStompException("Must specify the subscription's
id").getFrame();
- return response;
- }
-
- try
- {
- connection.unsubscribe(subscriptionID);
- }
- catch (HornetQStompException e)
- {
- response = e.getFrame();
- }
- return response;
- }
-
- @Override
- public StompFrame onAck(StompFrame request)
- {
- StompFrame response = null;
-
- String messageID = request.getHeader(Stomp.Headers.Ack.MESSAGE_ID);
- String txID = request.getHeader(Stomp.Headers.TRANSACTION);
- String subscriptionID = request.getHeader(Stomp.Headers.Ack.SUBSCRIPTION);
-
- if (txID != null)
- {
- log.warn("Transactional acknowledgement is not supported");
- }
-
- if (subscriptionID == null)
- {
- response = new HornetQStompException("subscription header is
required").getFrame();
- return response;
- }
-
- try
- {
- connection.acknowledge(messageID, subscriptionID);
- }
- catch (HornetQStompException e)
- {
- response = e.getFrame();
- }
-
- return response;
- }
-
- @Override
- public StompFrame onStomp(StompFrame request)
- {
- if (!connection.isValid())
- {
- return onConnect(request);
- }
- return null;
- }
-
- @Override
- public StompFrame onNack(StompFrame request)
- {
- //this eventually means discard the message (it never be redelivered again).
- //we can consider supporting redeliver to a different sub.
- return onAck(request);
- }
-
- @Override
- public StompFrame createMessageFrame(ServerMessage serverMessage,
- StompSubscription subscription, int deliveryCount)
- throws Exception
- {
- StompFrame frame = new StompFrameV11(Stomp.Responses.MESSAGE);
-
- if (subscription.getID() != null)
- {
- frame.addHeader(Stomp.Headers.Message.SUBSCRIPTION, subscription.getID());
- }
-
- HornetQBuffer buffer = serverMessage.getBodyBuffer();
-
- int bodyPos = serverMessage.getEndOfBodyPosition() == -1 ? buffer.writerIndex()
- :
serverMessage.getEndOfBodyPosition();
- int size = bodyPos - buffer.readerIndex();
- buffer.readerIndex(MessageImpl.BUFFER_HEADER_SPACE + DataConstants.SIZE_INT);
- byte[] data = new byte[size];
- if (serverMessage.containsProperty(Stomp.Headers.CONTENT_LENGTH) ||
serverMessage.getType() == Message.BYTES_TYPE)
- {
- frame.addHeader(Stomp.Headers.CONTENT_LENGTH, String.valueOf(data.length));
- buffer.readBytes(data);
- }
- else
- {
- SimpleString text = buffer.readNullableSimpleString();
- if (text != null)
- {
- data = text.toString().getBytes("UTF-8");
- }
- else
- {
- data = new byte[0];
- }
- }
-
- frame.setByteBody(data);
-
- serverMessage.getBodyBuffer().resetReaderIndex();
-
- StompUtils.copyStandardHeadersFromMessageToFrame(serverMessage, frame,
deliveryCount);
-
- return frame;
-
- }
-
- @Override
- public void replySent(StompFrame reply)
- {
- if (reply.getCommand().equals(Stomp.Responses.CONNECTED))
- {
- //kick off the pinger
- startHeartBeat();
- }
-
- if (reply.needsDisconnect())
- {
- connection.disconnect();
- }
- else
- {
- //update ping
- if (heartBeater != null)
- {
- heartBeater.pinged();
- }
- }
- }
-
- private void startHeartBeat()
- {
- if (heartBeater != null)
- {
- heartBeater.start();
- }
- }
-
- public StompFrame createPingFrame() throws UnsupportedEncodingException
- {
- StompFrame frame = new StompFrame(Stomp.Commands.STOMP);
- frame.setBody("\n");
- return frame;
- }
-
- //server heart beat
- //algorithm:
- //(a) server ping: if server hasn't sent any frame within serverPing
- //interval, send a ping.
- //(b) accept ping: if server hasn't received any frame within
- // 2*serverAcceptPing, disconnect!
- private class HeartBeater extends Thread
- {
- final int MIN_SERVER_PING = 500;
- final int MIN_CLIENT_PING = 500;
-
- long serverPing = 0;
- long serverAcceptPing = 0;
- volatile boolean shutdown = false;
- AtomicLong lastPingTime = new AtomicLong(0);
- AtomicLong lastAccepted = new AtomicLong(0);
- StompFrame pingFrame;
-
- public HeartBeater(long clientPing, long clientAcceptPing)
- {
- if (clientPing != 0)
- {
- serverAcceptPing = clientPing > MIN_CLIENT_PING ? clientPing :
MIN_CLIENT_PING;
- }
-
- if (clientAcceptPing != 0)
- {
- serverPing = clientAcceptPing > MIN_SERVER_PING ? clientAcceptPing :
MIN_SERVER_PING;
- }
- }
-
- public synchronized void shutdown()
- {
- shutdown = true;
- this.notify();
- }
-
- public String getServerHeartBeatValue()
- {
- return String.valueOf(serverPing) + "," +
String.valueOf(serverAcceptPing);
- }
-
- public void pinged()
- {
- lastPingTime.set(System.currentTimeMillis());
- }
-
- public void run()
- {
- lastAccepted.set(System.currentTimeMillis());
- try
- {
- pingFrame = createPingFrame();
- }
- catch (UnsupportedEncodingException e1)
- {
- log.error("Cannot create ping frame due to encoding problem.",
e1);
- }
-
- synchronized (this)
- {
- while (!shutdown)
- {
- long dur1 = 0;
- long dur2 = 0;
-
- if (serverPing != 0)
- {
- dur1 = System.currentTimeMillis() - lastPingTime.get();
- if (dur1 >= serverPing)
- {
- lastPingTime.set(System.currentTimeMillis());
- connection.ping(pingFrame);
- dur1 = 0;
- }
- }
-
- if (serverAcceptPing != 0)
- {
- dur2 = System.currentTimeMillis() - lastAccepted.get();
-
- if (dur2 > (2 * serverAcceptPing))
- {
- connection.disconnect();
- shutdown = true;
- break;
- }
- }
-
- long waitTime1 = 0;
- long waitTime2 = 0;
-
- if (serverPing > 0)
- {
- waitTime1 = serverPing - dur1;
- }
-
- if (serverAcceptPing > 0)
- {
- waitTime2 = serverAcceptPing * 2 - dur2;
- }
-
- long waitTime = 10l;
-
- if ((waitTime1 > 0) && (waitTime1 > 0))
- {
- waitTime = waitTime1 < waitTime2 ? waitTime1 : waitTime2;
- }
- else if (waitTime1 > 0)
- {
- waitTime = waitTime1;
- }
- else if (waitTime2 > 0)
- {
- waitTime = waitTime2;
- }
-
- try
- {
- this.wait(waitTime);
- }
- catch (InterruptedException e)
- {
- }
- }
- }
- }
-
- public void pingAccepted()
- {
- this.lastAccepted.set(System.currentTimeMillis());
- }
- }
-
- @Override
- public void requestAccepted(StompFrame request)
- {
- if (heartBeater != null)
- {
- heartBeater.pingAccepted();
- }
- }
-
- @Override
- public StompFrame createStompFrame(String command)
- {
- return new StompFrameV11(command);
- }
-
- //all frame except CONNECT are decoded here.
- public StompFrame decode(StompDecoder decoder, final HornetQBuffer buffer) throws
HornetQStompException
- {
- int readable = buffer.readableBytes();
-
- if (decoder.data + readable >= decoder.workingBuffer.length)
- {
- decoder.resizeWorking(decoder.data + readable);
- }
-
- buffer.readBytes(decoder.workingBuffer, decoder.data, readable);
-
- decoder.data += readable;
-
- if (decoder.command == null)
- {
- if (decoder.data < 4)
- {
- // Need at least four bytes to identify the command
- // - up to 3 bytes for the command name + potentially another byte for a
leading \n
-
- return null;
- }
-
- int offset;
-
- if (decoder.workingBuffer[0] == StompDecoder.NEW_LINE)
- {
- // Yuck, some badly behaved STOMP clients add a \n *after* the terminating
NUL char at the end of the
- // STOMP
- // frame this can manifest as an extra \n at the beginning when the next
STOMP frame is read - we need to
- // deal
- // with this
- offset = 1;
- }
- else
- {
- offset = 0;
- }
-
- byte b = decoder.workingBuffer[offset];
-
- switch (b)
- {
- case StompDecoder.A:
- {
- if (decoder.workingBuffer[offset + 1] == StompDecoder.B)
- {
- if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_ABORT_LENGTH +
1))
- {
- return null;
- }
-
- // ABORT
- decoder.command = StompDecoder.COMMAND_ABORT;
- }
- else
- {
- if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_ACK_LENGTH +
1))
- {
- return null;
- }
-
- // ACK
- decoder.command = StompDecoder.COMMAND_ACK;
- }
- break;
- }
- case StompDecoder.B:
- {
- if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_BEGIN_LENGTH +
1))
- {
- return null;
- }
-
- // BEGIN
- decoder.command = StompDecoder.COMMAND_BEGIN;
-
- break;
- }
- case StompDecoder.C:
- {
- if (decoder.workingBuffer[offset + 2] == StompDecoder.M)
- {
- if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_COMMIT_LENGTH +
1))
- {
- return null;
- }
-
- // COMMIT
- decoder.command = StompDecoder.COMMAND_COMMIT;
- }
- /**** added by meddy, 27 april 2011, handle header parser for reply to
websocket protocol ****/
- else if (decoder.workingBuffer[offset+7] == StompDecoder.E)
- {
- if (!decoder.tryIncrement(offset +
StompDecoder.COMMAND_CONNECTED_LENGTH + 1))
- {
- return null;
- }
-
- // CONNECTED
- decoder.command = StompDecoder.COMMAND_CONNECTED;
- }
- /**** end ****/
- else
- {
- if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_CONNECT_LENGTH
+ 1))
- {
- return null;
- }
-
- // CONNECT
- decoder.command = StompDecoder.COMMAND_CONNECT;
- }
- break;
- }
- case StompDecoder.D:
- {
- if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_DISCONNECT_LENGTH
+ 1))
- {
- return null;
- }
-
- // DISCONNECT
- decoder.command = StompDecoder.COMMAND_DISCONNECT;
-
- break;
- }
- case StompDecoder.R:
- {
- if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_RECEIPT_LENGTH +
1))
- {
- return null;
- }
-
- // RECEIPT
- decoder.command = StompDecoder.COMMAND_RECEIPT;
-
- break;
- }
- /**** added by meddy, 27 april 2011, handle header parser for reply to
websocket protocol ****/
- case StompDecoder.E:
- {
- if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_ERROR_LENGTH +
1))
- {
- return null;
- }
-
- // ERROR
- decoder.command = StompDecoder.COMMAND_ERROR;
-
- break;
- }
- case StompDecoder.M:
- {
- if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_MESSAGE_LENGTH +
1))
- {
- return null;
- }
-
- // MESSAGE
- decoder.command = StompDecoder.COMMAND_MESSAGE;
-
- break;
- }
- /**** end ****/
- case StompDecoder.S:
- {
- if (decoder.workingBuffer[offset + 1] == StompDecoder.E)
- {
- if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_SEND_LENGTH +
1))
- {
- return null;
- }
-
- // SEND
- decoder.command = StompDecoder.COMMAND_SEND;
- }
- else if (decoder.workingBuffer[offset + 1] == StompDecoder.U)
- {
- if (!decoder.tryIncrement(offset +
StompDecoder.COMMAND_SUBSCRIBE_LENGTH + 1))
- {
- return null;
- }
-
- // SUBSCRIBE
- decoder.command = StompDecoder.COMMAND_SUBSCRIBE;
- }
- else
- {
- if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_STOMP_LENGTH +
1))
- {
- return null;
- }
-
- // SUBSCRIBE
- decoder.command = StompDecoder.COMMAND_STOMP;
- }
- break;
- }
- case StompDecoder.U:
- {
- if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_UNSUBSCRIBE_LENGTH
+ 1))
- {
- return null;
- }
-
- // UNSUBSCRIBE
- decoder.command = StompDecoder.COMMAND_UNSUBSCRIBE;
-
- break;
- }
- case StompDecoder.N:
- {
- if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_NACK_LENGTH + 1))
- {
- return null;
- }
- //NACK
- decoder.command = StompDecoder.COMMAND_NACK;
- break;
- }
- default:
- {
- decoder.throwInvalid();
- }
- }
-
- // Sanity check
-
- if (decoder.workingBuffer[decoder.pos - 1] != StompDecoder.NEW_LINE)
- {
- decoder.throwInvalid();
- }
- }
-
- if (decoder.readingHeaders)
- {
- if (decoder.headerBytesCopyStart == -1)
- {
- decoder.headerBytesCopyStart = decoder.pos;
- }
-
- // Now the headers
-
- boolean isEscaping = false;
- SimpleBytes holder = new SimpleBytes(1024);
-
- outer: while (true)
- {
- byte b = decoder.workingBuffer[decoder.pos++];
-
- switch (b)
- {
- //escaping
- case ESC_CHAR:
- {
- if (isEscaping)
- {
- //this is a backslash
- holder.append(b);
- isEscaping = false;
- }
- else
- {
- //begin escaping
- isEscaping = true;
- }
- break;
- }
- case StompDecoder.HEADER_SEPARATOR:
- {
- if (isEscaping)
- {
- //a colon
- holder.append(b);
- isEscaping = false;
- }
- else
- {
- if (decoder.inHeaderName)
- {
- try
- {
- decoder.headerName = holder.getString();
- }
- catch (UnsupportedEncodingException e)
- {
- throw new HornetQStompException("Encoding
exception", e);
- }
-
- holder.reset();
-
- decoder.inHeaderName = false;
-
- decoder.headerBytesCopyStart = decoder.pos;
-
- decoder.headerValueWhitespace = true;
- }
- }
-
- decoder.whiteSpaceOnly = false;
-
- break;
- }
- case StompDecoder.LN:
- {
- if (isEscaping)
- {
- holder.append(StompDecoder.NEW_LINE);
- isEscaping = false;
- }
- else
- {
- holder.append(b);
- }
- break;
- }
- case StompDecoder.NEW_LINE:
- {
- if (decoder.whiteSpaceOnly)
- {
- // Headers are terminated by a blank line
- decoder.readingHeaders = false;
-
- break outer;
- }
-
- String headerValue;
- try
- {
- headerValue = holder.getString();
- }
- catch (UnsupportedEncodingException e)
- {
- throw new HornetQStompException("Encoding exception.",
e);
- }
- holder.reset();
-
- decoder.headers.put(decoder.headerName, headerValue);
-
- if
(decoder.headerName.equals(StompDecoder.CONTENT_LENGTH_HEADER_NAME))
- {
- decoder.contentLength = Integer.parseInt(headerValue);
- }
-
- if (decoder.headerName.equals(StompDecoder.CONTENT_TYPE_HEADER_NAME))
- {
- decoder.contentType = headerValue;
- }
-
- decoder.whiteSpaceOnly = true;
-
- decoder.headerBytesCopyStart = decoder.pos;
-
- decoder.inHeaderName = true;
-
- decoder.headerValueWhitespace = false;
-
- break;
- }
- default:
- {
- decoder.whiteSpaceOnly = false;
-
- decoder.headerValueWhitespace = false;
-
- holder.append(b);
- }
- }
- if (decoder.pos == decoder.data)
- {
- // Run out of data
-
- return null;
- }
- }
- }
-
- // Now the body
-
- byte[] content = null;
-
- if (decoder.contentLength != -1)
- {
- if (decoder.pos + decoder.contentLength + 1 > decoder.data)
- {
- // Need more bytes
- }
- else
- {
- content = new byte[decoder.contentLength];
-
- System.arraycopy(decoder.workingBuffer, decoder.pos, content, 0,
decoder.contentLength);
-
- decoder.pos += decoder.contentLength + 1;
-
- //drain all the rest
- if (decoder.bodyStart == -1)
- {
- decoder.bodyStart = decoder.pos;
- }
-
- while (decoder.pos < decoder.data)
- {
- if (decoder.workingBuffer[decoder.pos++] == 0)
- {
- break;
- }
- }
- }
- }
- else
- {
- // Need to scan for terminating NUL
-
- if (decoder.bodyStart == -1)
- {
- decoder.bodyStart = decoder.pos;
- }
-
- while (decoder.pos < decoder.data)
- {
- if (decoder.workingBuffer[decoder.pos++] == 0)
- {
- content = new byte[decoder.pos - decoder.bodyStart - 1];
-
- System.arraycopy(decoder.workingBuffer, decoder.bodyStart, content, 0,
content.length);
-
- break;
- }
- }
- }
-
- if (content != null)
- {
- if (decoder.data > decoder.pos)
- {
- if (decoder.workingBuffer[decoder.pos] == StompDecoder.NEW_LINE)
decoder.pos++;
-
- if (decoder.data > decoder.pos)
- // More data still in the buffer from the next packet
- System.arraycopy(decoder.workingBuffer, decoder.pos, decoder.workingBuffer,
0, decoder.data - decoder.pos);
- }
-
- decoder.data = decoder.data - decoder.pos;
-
- // reset
-
- StompFrame ret = new StompFrameV11(decoder.command, decoder.headers, content);
-
- decoder.init();
-
- return ret;
- }
- else
- {
- return null;
- }
- }
-
-}
Copied:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameHandlerV11.java
(from rev 11517,
branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameHandlerV11.java)
===================================================================
---
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameHandlerV11.java
(rev 0)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameHandlerV11.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,1109 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat 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.hornetq.core.protocol.stomp.v11;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.hornetq.api.core.HornetQBuffer;
+import org.hornetq.api.core.HornetQBuffers;
+import org.hornetq.api.core.Message;
+import org.hornetq.api.core.SimpleString;
+import org.hornetq.core.logging.Logger;
+import org.hornetq.core.message.impl.MessageImpl;
+import org.hornetq.core.protocol.stomp.FrameEventListener;
+import org.hornetq.core.protocol.stomp.HornetQStompException;
+import org.hornetq.core.protocol.stomp.SimpleBytes;
+import org.hornetq.core.protocol.stomp.Stomp;
+import org.hornetq.core.protocol.stomp.StompConnection;
+import org.hornetq.core.protocol.stomp.StompDecoder;
+import org.hornetq.core.protocol.stomp.StompFrame;
+import org.hornetq.core.protocol.stomp.StompSubscription;
+import org.hornetq.core.protocol.stomp.StompUtils;
+import org.hornetq.core.protocol.stomp.VersionedStompFrameHandler;
+import org.hornetq.core.server.ServerMessage;
+import org.hornetq.core.server.impl.ServerMessageImpl;
+import org.hornetq.utils.DataConstants;
+
+/**
+ *
+ * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
+ */
+public class StompFrameHandlerV11 extends VersionedStompFrameHandler implements
FrameEventListener
+{
+ private static final Logger log = Logger.getLogger(StompFrameHandlerV11.class);
+
+ private static final char ESC_CHAR = '\\';
+
+ private HeartBeater heartBeater;
+
+ public StompFrameHandlerV11(StompConnection connection)
+ {
+ this.connection = connection;
+ connection.addStompEventListener(this);
+ }
+
+ @Override
+ public StompFrame onConnect(StompFrame frame)
+ {
+ StompFrame response = null;
+ Map<String, String> headers = frame.getHeadersMap();
+ String login = headers.get(Stomp.Headers.Connect.LOGIN);
+ String passcode = headers.get(Stomp.Headers.Connect.PASSCODE);
+ String clientID = headers.get(Stomp.Headers.Connect.CLIENT_ID);
+ String requestID = headers.get(Stomp.Headers.Connect.REQUEST_ID);
+
+ try
+ {
+ if (connection.validateUser(login, passcode))
+ {
+ connection.setClientID(clientID);
+ connection.setValid(true);
+
+ response = new StompFrameV11(Stomp.Responses.CONNECTED);
+
+ // version
+ response.addHeader(Stomp.Headers.Connected.VERSION,
+ connection.getVersion());
+
+ // session
+ response.addHeader(Stomp.Headers.Connected.SESSION, connection
+ .getID().toString());
+
+ // server
+ response.addHeader(Stomp.Headers.Connected.SERVER,
+ connection.getHornetQServerName());
+
+ if (requestID != null)
+ {
+ response.addHeader(Stomp.Headers.Connected.RESPONSE_ID,
+ requestID);
+ }
+
+ // heart-beat. We need to start after connected frame has been sent.
+ // otherwise the client may receive heart-beat before it receives
+ // connected frame.
+ String heartBeat = headers.get(Stomp.Headers.Connect.HEART_BEAT);
+
+ if (heartBeat != null)
+ {
+ handleHeartBeat(heartBeat);
+ if (heartBeater == null)
+ {
+ response.addHeader(Stomp.Headers.Connected.HEART_BEAT,
"0,0");
+ }
+ else
+ {
+ response.addHeader(Stomp.Headers.Connected.HEART_BEAT,
heartBeater.getServerHeartBeatValue());
+ }
+ }
+ }
+ else
+ {
+ // not valid
+ response = new StompFrame(Stomp.Responses.ERROR, true);
+ response.addHeader(Stomp.Headers.Error.VERSION, "1.0,1.1");
+
+ response.setBody("Supported protocol versions are 1.0 and 1.1");
+ }
+ }
+ catch (HornetQStompException e)
+ {
+ response = e.getFrame();
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ response = new HornetQStompException("Encoding error.",
e).getFrame();
+ }
+ return response;
+ }
+
+ //ping parameters, hard-code for now
+ //the server can support min 20 milliseconds and receive ping at 100 milliseconds
(20,100)
+ private void handleHeartBeat(String heartBeatHeader) throws HornetQStompException
+ {
+ String[] params = heartBeatHeader.split(",");
+ if (params.length != 2)
+ {
+ throw new HornetQStompException("Incorrect heartbeat header " +
heartBeatHeader);
+ }
+
+ //client ping
+ long minPingInterval = Long.valueOf(params[0]);
+ //client receive ping
+ long minAcceptInterval = Long.valueOf(params[1]);
+
+ if ((minPingInterval != 0) || (minAcceptInterval != 0))
+ {
+ heartBeater = new HeartBeater(minPingInterval, minAcceptInterval);
+ }
+ }
+
+ @Override
+ public StompFrame onDisconnect(StompFrame frame)
+ {
+ if (this.heartBeater != null)
+ {
+ heartBeater.shutdown();
+ try
+ {
+ heartBeater.join();
+ }
+ catch (InterruptedException e)
+ {
+ log.warn("Interrupted while waiting for heart beater to die", e);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public StompFrame postprocess(StompFrame request)
+ {
+ StompFrame response = null;
+ if (request.hasHeader(Stomp.Headers.RECEIPT_REQUESTED))
+ {
+ response = handleReceipt(request.getHeader(Stomp.Headers.RECEIPT_REQUESTED));
+ if (request.getCommand().equals(Stomp.Commands.DISCONNECT))
+ {
+ response.setNeedsDisconnect(true);
+ }
+ }
+ else
+ {
+ //request null, disconnect if so.
+ if (request.getCommand().equals(Stomp.Commands.DISCONNECT))
+ {
+ this.connection.disconnect();
+ }
+ }
+ return response;
+ }
+
+ @Override
+ public StompFrame onSend(StompFrame frame)
+ {
+ StompFrame response = null;
+ try
+ {
+ connection.validate();
+ String destination = frame.getHeader(Stomp.Headers.Send.DESTINATION);
+ String txID = frame.getHeader(Stomp.Headers.TRANSACTION);
+
+ long timestamp = System.currentTimeMillis();
+
+ ServerMessageImpl message = connection.createServerMessage();
+ message.setTimestamp(timestamp);
+ message.setAddress(SimpleString.toSimpleString(destination));
+ StompUtils.copyStandardHeadersFromFrameToMessage(frame, message);
+ if (frame.hasHeader(Stomp.Headers.CONTENT_LENGTH))
+ {
+ message.setType(Message.BYTES_TYPE);
+ message.getBodyBuffer().writeBytes(frame.getBodyAsBytes());
+ }
+ else
+ {
+ message.setType(Message.TEXT_TYPE);
+ String text = frame.getBody();
+
message.getBodyBuffer().writeNullableSimpleString(SimpleString.toSimpleString(text));
+ }
+
+ connection.sendServerMessage(message, txID);
+ }
+ catch (HornetQStompException e)
+ {
+ response = e.getFrame();
+ }
+ catch (Exception e)
+ {
+ response = new HornetQStompException("Error handling send",
e).getFrame();
+ }
+
+ return response;
+ }
+
+ @Override
+ public StompFrame onBegin(StompFrame frame)
+ {
+ StompFrame response = null;
+ String txID = frame.getHeader(Stomp.Headers.TRANSACTION);
+ if (txID == null)
+ {
+ response = new HornetQStompException("Need a transaction id to
begin").getFrame();
+ }
+ else
+ {
+ try
+ {
+ connection.beginTransaction(txID);
+ }
+ catch (HornetQStompException e)
+ {
+ response = e.getFrame();
+ }
+ }
+ return response;
+ }
+
+ @Override
+ public StompFrame onCommit(StompFrame request)
+ {
+ StompFrame response = null;
+
+ String txID = request.getHeader(Stomp.Headers.TRANSACTION);
+ if (txID == null)
+ {
+ response = new HornetQStompException("transaction header is mandatory to
COMMIT a transaction").getFrame();
+ return response;
+ }
+
+ try
+ {
+ connection.commitTransaction(txID);
+ }
+ catch (HornetQStompException e)
+ {
+ response = e.getFrame();
+ }
+ return response;
+ }
+
+ @Override
+ public StompFrame onAbort(StompFrame request)
+ {
+ StompFrame response = null;
+ String txID = request.getHeader(Stomp.Headers.TRANSACTION);
+
+ if (txID == null)
+ {
+ response = new HornetQStompException("transaction header is mandatory to
ABORT a transaction").getFrame();
+ return response;
+ }
+
+ try
+ {
+ connection.abortTransaction(txID);
+ }
+ catch (HornetQStompException e)
+ {
+ response = e.getFrame();
+ }
+
+ return response;
+ }
+
+ @Override
+ public StompFrame onSubscribe(StompFrame request)
+ {
+ StompFrame response = null;
+ String destination = request.getHeader(Stomp.Headers.Subscribe.DESTINATION);
+
+ String selector = request.getHeader(Stomp.Headers.Subscribe.SELECTOR);
+ String ack = request.getHeader(Stomp.Headers.Subscribe.ACK_MODE);
+ String id = request.getHeader(Stomp.Headers.Subscribe.ID);
+ String durableSubscriptionName =
request.getHeader(Stomp.Headers.Subscribe.DURABLE_SUBSCRIBER_NAME);
+ boolean noLocal = false;
+
+ if (request.hasHeader(Stomp.Headers.Subscribe.NO_LOCAL))
+ {
+ noLocal =
Boolean.parseBoolean(request.getHeader(Stomp.Headers.Subscribe.NO_LOCAL));
+ }
+
+ try
+ {
+ connection.subscribe(destination, selector, ack, id, durableSubscriptionName,
noLocal);
+ }
+ catch (HornetQStompException e)
+ {
+ response = e.getFrame();
+ }
+
+ return response;
+ }
+
+ @Override
+ public StompFrame onUnsubscribe(StompFrame request)
+ {
+ StompFrame response = null;
+ //unsubscribe in 1.1 only needs id header
+ String id = request.getHeader(Stomp.Headers.Unsubscribe.ID);
+
+ String subscriptionID = null;
+ if (id != null)
+ {
+ subscriptionID = id;
+ }
+ else
+ {
+ response = new HornetQStompException("Must specify the subscription's
id").getFrame();
+ return response;
+ }
+
+ try
+ {
+ connection.unsubscribe(subscriptionID);
+ }
+ catch (HornetQStompException e)
+ {
+ response = e.getFrame();
+ }
+ return response;
+ }
+
+ @Override
+ public StompFrame onAck(StompFrame request)
+ {
+ StompFrame response = null;
+
+ String messageID = request.getHeader(Stomp.Headers.Ack.MESSAGE_ID);
+ String txID = request.getHeader(Stomp.Headers.TRANSACTION);
+ String subscriptionID = request.getHeader(Stomp.Headers.Ack.SUBSCRIPTION);
+
+ if (txID != null)
+ {
+ log.warn("Transactional acknowledgement is not supported");
+ }
+
+ if (subscriptionID == null)
+ {
+ response = new HornetQStompException("subscription header is
required").getFrame();
+ return response;
+ }
+
+ try
+ {
+ connection.acknowledge(messageID, subscriptionID);
+ }
+ catch (HornetQStompException e)
+ {
+ response = e.getFrame();
+ }
+
+ return response;
+ }
+
+ @Override
+ public StompFrame onStomp(StompFrame request)
+ {
+ if (!connection.isValid())
+ {
+ return onConnect(request);
+ }
+ return null;
+ }
+
+ @Override
+ public StompFrame onNack(StompFrame request)
+ {
+ //this eventually means discard the message (it never be redelivered again).
+ //we can consider supporting redeliver to a different sub.
+ return onAck(request);
+ }
+
+ @Override
+ public StompFrame createMessageFrame(ServerMessage serverMessage,
+ StompSubscription subscription, int deliveryCount)
+ throws Exception
+ {
+ StompFrame frame = new StompFrameV11(Stomp.Responses.MESSAGE);
+
+ if (subscription.getID() != null)
+ {
+ frame.addHeader(Stomp.Headers.Message.SUBSCRIPTION, subscription.getID());
+ }
+
+ HornetQBuffer buffer = serverMessage.getBodyBuffer();
+
+ int bodyPos = serverMessage.getEndOfBodyPosition() == -1 ? buffer.writerIndex()
+ :
serverMessage.getEndOfBodyPosition();
+ int size = bodyPos - buffer.readerIndex();
+ buffer.readerIndex(MessageImpl.BUFFER_HEADER_SPACE + DataConstants.SIZE_INT);
+ byte[] data = new byte[size];
+ if (serverMessage.containsProperty(Stomp.Headers.CONTENT_LENGTH) ||
serverMessage.getType() == Message.BYTES_TYPE)
+ {
+ frame.addHeader(Stomp.Headers.CONTENT_LENGTH, String.valueOf(data.length));
+ buffer.readBytes(data);
+ }
+ else
+ {
+ SimpleString text = buffer.readNullableSimpleString();
+ if (text != null)
+ {
+ data = text.toString().getBytes("UTF-8");
+ }
+ else
+ {
+ data = new byte[0];
+ }
+ }
+
+ frame.setByteBody(data);
+
+ serverMessage.getBodyBuffer().resetReaderIndex();
+
+ StompUtils.copyStandardHeadersFromMessageToFrame(serverMessage, frame,
deliveryCount);
+
+ return frame;
+
+ }
+
+ @Override
+ public void replySent(StompFrame reply)
+ {
+ if (reply.getCommand().equals(Stomp.Responses.CONNECTED))
+ {
+ //kick off the pinger
+ startHeartBeat();
+ }
+
+ if (reply.needsDisconnect())
+ {
+ connection.disconnect();
+ }
+ else
+ {
+ //update ping
+ if (heartBeater != null)
+ {
+ heartBeater.pinged();
+ }
+ }
+ }
+
+ private void startHeartBeat()
+ {
+ if (heartBeater != null)
+ {
+ heartBeater.start();
+ }
+ }
+
+ public StompFrame createPingFrame() throws UnsupportedEncodingException
+ {
+ StompFrame frame = new StompFrame(Stomp.Commands.STOMP);
+ frame.setBody("\n");
+ return frame;
+ }
+
+ //server heart beat
+ //algorithm:
+ //(a) server ping: if server hasn't sent any frame within serverPing
+ //interval, send a ping.
+ //(b) accept ping: if server hasn't received any frame within
+ // 2*serverAcceptPing, disconnect!
+ private class HeartBeater extends Thread
+ {
+ final int MIN_SERVER_PING = 500;
+ final int MIN_CLIENT_PING = 500;
+
+ long serverPing = 0;
+ long serverAcceptPing = 0;
+ volatile boolean shutdown = false;
+ AtomicLong lastPingTime = new AtomicLong(0);
+ AtomicLong lastAccepted = new AtomicLong(0);
+ StompFrame pingFrame;
+
+ public HeartBeater(long clientPing, long clientAcceptPing)
+ {
+ if (clientPing != 0)
+ {
+ serverAcceptPing = clientPing > MIN_CLIENT_PING ? clientPing :
MIN_CLIENT_PING;
+ }
+
+ if (clientAcceptPing != 0)
+ {
+ serverPing = clientAcceptPing > MIN_SERVER_PING ? clientAcceptPing :
MIN_SERVER_PING;
+ }
+ }
+
+ public synchronized void shutdown()
+ {
+ shutdown = true;
+ this.notify();
+ }
+
+ public String getServerHeartBeatValue()
+ {
+ return String.valueOf(serverPing) + "," +
String.valueOf(serverAcceptPing);
+ }
+
+ public void pinged()
+ {
+ lastPingTime.set(System.currentTimeMillis());
+ }
+
+ public void run()
+ {
+ lastAccepted.set(System.currentTimeMillis());
+ try
+ {
+ pingFrame = createPingFrame();
+ }
+ catch (UnsupportedEncodingException e1)
+ {
+ log.error("Cannot create ping frame due to encoding problem.",
e1);
+ }
+
+ synchronized (this)
+ {
+ while (!shutdown)
+ {
+ long dur1 = 0;
+ long dur2 = 0;
+
+ if (serverPing != 0)
+ {
+ dur1 = System.currentTimeMillis() - lastPingTime.get();
+ if (dur1 >= serverPing)
+ {
+ lastPingTime.set(System.currentTimeMillis());
+ connection.ping(pingFrame);
+ dur1 = 0;
+ }
+ }
+
+ if (serverAcceptPing != 0)
+ {
+ dur2 = System.currentTimeMillis() - lastAccepted.get();
+
+ if (dur2 > (2 * serverAcceptPing))
+ {
+ connection.disconnect();
+ shutdown = true;
+ break;
+ }
+ }
+
+ long waitTime1 = 0;
+ long waitTime2 = 0;
+
+ if (serverPing > 0)
+ {
+ waitTime1 = serverPing - dur1;
+ }
+
+ if (serverAcceptPing > 0)
+ {
+ waitTime2 = serverAcceptPing * 2 - dur2;
+ }
+
+ long waitTime = 10l;
+
+ if ((waitTime1 > 0) && (waitTime1 > 0))
+ {
+ waitTime = waitTime1 < waitTime2 ? waitTime1 : waitTime2;
+ }
+ else if (waitTime1 > 0)
+ {
+ waitTime = waitTime1;
+ }
+ else if (waitTime2 > 0)
+ {
+ waitTime = waitTime2;
+ }
+
+ try
+ {
+ this.wait(waitTime);
+ }
+ catch (InterruptedException e)
+ {
+ }
+ }
+ }
+ }
+
+ public void pingAccepted()
+ {
+ this.lastAccepted.set(System.currentTimeMillis());
+ }
+ }
+
+ @Override
+ public void requestAccepted(StompFrame request)
+ {
+ if (heartBeater != null)
+ {
+ heartBeater.pingAccepted();
+ }
+ }
+
+ @Override
+ public StompFrame createStompFrame(String command)
+ {
+ return new StompFrameV11(command);
+ }
+
+ //all frame except CONNECT are decoded here.
+ public StompFrame decode(StompDecoder decoder, final HornetQBuffer buffer) throws
HornetQStompException
+ {
+ int readable = buffer.readableBytes();
+
+ if (decoder.data + readable >= decoder.workingBuffer.length)
+ {
+ decoder.resizeWorking(decoder.data + readable);
+ }
+
+ buffer.readBytes(decoder.workingBuffer, decoder.data, readable);
+
+ decoder.data += readable;
+
+ if (decoder.command == null)
+ {
+ if (decoder.data < 4)
+ {
+ // Need at least four bytes to identify the command
+ // - up to 3 bytes for the command name + potentially another byte for a
leading \n
+
+ return null;
+ }
+
+ int offset;
+
+ if (decoder.workingBuffer[0] == StompDecoder.NEW_LINE)
+ {
+ // Yuck, some badly behaved STOMP clients add a \n *after* the terminating
NUL char at the end of the
+ // STOMP
+ // frame this can manifest as an extra \n at the beginning when the next
STOMP frame is read - we need to
+ // deal
+ // with this
+ offset = 1;
+ }
+ else
+ {
+ offset = 0;
+ }
+
+ byte b = decoder.workingBuffer[offset];
+
+ switch (b)
+ {
+ case StompDecoder.A:
+ {
+ if (decoder.workingBuffer[offset + 1] == StompDecoder.B)
+ {
+ if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_ABORT_LENGTH +
1))
+ {
+ return null;
+ }
+
+ // ABORT
+ decoder.command = StompDecoder.COMMAND_ABORT;
+ }
+ else
+ {
+ if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_ACK_LENGTH +
1))
+ {
+ return null;
+ }
+
+ // ACK
+ decoder.command = StompDecoder.COMMAND_ACK;
+ }
+ break;
+ }
+ case StompDecoder.B:
+ {
+ if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_BEGIN_LENGTH +
1))
+ {
+ return null;
+ }
+
+ // BEGIN
+ decoder.command = StompDecoder.COMMAND_BEGIN;
+
+ break;
+ }
+ case StompDecoder.C:
+ {
+ if (decoder.workingBuffer[offset + 2] == StompDecoder.M)
+ {
+ if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_COMMIT_LENGTH +
1))
+ {
+ return null;
+ }
+
+ // COMMIT
+ decoder.command = StompDecoder.COMMAND_COMMIT;
+ }
+ /**** added by meddy, 27 april 2011, handle header parser for reply to
websocket protocol ****/
+ else if (decoder.workingBuffer[offset+7] == StompDecoder.E)
+ {
+ if (!decoder.tryIncrement(offset +
StompDecoder.COMMAND_CONNECTED_LENGTH + 1))
+ {
+ return null;
+ }
+
+ // CONNECTED
+ decoder.command = StompDecoder.COMMAND_CONNECTED;
+ }
+ /**** end ****/
+ else
+ {
+ if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_CONNECT_LENGTH
+ 1))
+ {
+ return null;
+ }
+
+ // CONNECT
+ decoder.command = StompDecoder.COMMAND_CONNECT;
+ }
+ break;
+ }
+ case StompDecoder.D:
+ {
+ if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_DISCONNECT_LENGTH
+ 1))
+ {
+ return null;
+ }
+
+ // DISCONNECT
+ decoder.command = StompDecoder.COMMAND_DISCONNECT;
+
+ break;
+ }
+ case StompDecoder.R:
+ {
+ if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_RECEIPT_LENGTH +
1))
+ {
+ return null;
+ }
+
+ // RECEIPT
+ decoder.command = StompDecoder.COMMAND_RECEIPT;
+
+ break;
+ }
+ /**** added by meddy, 27 april 2011, handle header parser for reply to
websocket protocol ****/
+ case StompDecoder.E:
+ {
+ if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_ERROR_LENGTH +
1))
+ {
+ return null;
+ }
+
+ // ERROR
+ decoder.command = StompDecoder.COMMAND_ERROR;
+
+ break;
+ }
+ case StompDecoder.M:
+ {
+ if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_MESSAGE_LENGTH +
1))
+ {
+ return null;
+ }
+
+ // MESSAGE
+ decoder.command = StompDecoder.COMMAND_MESSAGE;
+
+ break;
+ }
+ /**** end ****/
+ case StompDecoder.S:
+ {
+ if (decoder.workingBuffer[offset + 1] == StompDecoder.E)
+ {
+ if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_SEND_LENGTH +
1))
+ {
+ return null;
+ }
+
+ // SEND
+ decoder.command = StompDecoder.COMMAND_SEND;
+ }
+ else if (decoder.workingBuffer[offset + 1] == StompDecoder.U)
+ {
+ if (!decoder.tryIncrement(offset +
StompDecoder.COMMAND_SUBSCRIBE_LENGTH + 1))
+ {
+ return null;
+ }
+
+ // SUBSCRIBE
+ decoder.command = StompDecoder.COMMAND_SUBSCRIBE;
+ }
+ else
+ {
+ if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_STOMP_LENGTH +
1))
+ {
+ return null;
+ }
+
+ // SUBSCRIBE
+ decoder.command = StompDecoder.COMMAND_STOMP;
+ }
+ break;
+ }
+ case StompDecoder.U:
+ {
+ if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_UNSUBSCRIBE_LENGTH
+ 1))
+ {
+ return null;
+ }
+
+ // UNSUBSCRIBE
+ decoder.command = StompDecoder.COMMAND_UNSUBSCRIBE;
+
+ break;
+ }
+ case StompDecoder.N:
+ {
+ if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_NACK_LENGTH + 1))
+ {
+ return null;
+ }
+ //NACK
+ decoder.command = StompDecoder.COMMAND_NACK;
+ break;
+ }
+ default:
+ {
+ decoder.throwInvalid();
+ }
+ }
+
+ // Sanity check
+
+ if (decoder.workingBuffer[decoder.pos - 1] != StompDecoder.NEW_LINE)
+ {
+ decoder.throwInvalid();
+ }
+ }
+
+ if (decoder.readingHeaders)
+ {
+ if (decoder.headerBytesCopyStart == -1)
+ {
+ decoder.headerBytesCopyStart = decoder.pos;
+ }
+
+ // Now the headers
+
+ boolean isEscaping = false;
+ SimpleBytes holder = new SimpleBytes(1024);
+
+ outer: while (true)
+ {
+ byte b = decoder.workingBuffer[decoder.pos++];
+
+ switch (b)
+ {
+ //escaping
+ case ESC_CHAR:
+ {
+ if (isEscaping)
+ {
+ //this is a backslash
+ holder.append(b);
+ isEscaping = false;
+ }
+ else
+ {
+ //begin escaping
+ isEscaping = true;
+ }
+ break;
+ }
+ case StompDecoder.HEADER_SEPARATOR:
+ {
+ if (isEscaping)
+ {
+ //a colon
+ holder.append(b);
+ isEscaping = false;
+ }
+ else
+ {
+ if (decoder.inHeaderName)
+ {
+ try
+ {
+ decoder.headerName = holder.getString();
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ throw new HornetQStompException("Encoding
exception", e);
+ }
+
+ holder.reset();
+
+ decoder.inHeaderName = false;
+
+ decoder.headerBytesCopyStart = decoder.pos;
+
+ decoder.headerValueWhitespace = true;
+ }
+ }
+
+ decoder.whiteSpaceOnly = false;
+
+ break;
+ }
+ case StompDecoder.LN:
+ {
+ if (isEscaping)
+ {
+ holder.append(StompDecoder.NEW_LINE);
+ isEscaping = false;
+ }
+ else
+ {
+ holder.append(b);
+ }
+ break;
+ }
+ case StompDecoder.NEW_LINE:
+ {
+ if (decoder.whiteSpaceOnly)
+ {
+ // Headers are terminated by a blank line
+ decoder.readingHeaders = false;
+
+ break outer;
+ }
+
+ String headerValue;
+ try
+ {
+ headerValue = holder.getString();
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ throw new HornetQStompException("Encoding exception.",
e);
+ }
+ holder.reset();
+
+ decoder.headers.put(decoder.headerName, headerValue);
+
+ if
(decoder.headerName.equals(StompDecoder.CONTENT_LENGTH_HEADER_NAME))
+ {
+ decoder.contentLength = Integer.parseInt(headerValue);
+ }
+
+ if (decoder.headerName.equals(StompDecoder.CONTENT_TYPE_HEADER_NAME))
+ {
+ decoder.contentType = headerValue;
+ }
+
+ decoder.whiteSpaceOnly = true;
+
+ decoder.headerBytesCopyStart = decoder.pos;
+
+ decoder.inHeaderName = true;
+
+ decoder.headerValueWhitespace = false;
+
+ break;
+ }
+ default:
+ {
+ decoder.whiteSpaceOnly = false;
+
+ decoder.headerValueWhitespace = false;
+
+ holder.append(b);
+ }
+ }
+ if (decoder.pos == decoder.data)
+ {
+ // Run out of data
+
+ return null;
+ }
+ }
+ }
+
+ // Now the body
+
+ byte[] content = null;
+
+ if (decoder.contentLength != -1)
+ {
+ if (decoder.pos + decoder.contentLength + 1 > decoder.data)
+ {
+ // Need more bytes
+ }
+ else
+ {
+ content = new byte[decoder.contentLength];
+
+ System.arraycopy(decoder.workingBuffer, decoder.pos, content, 0,
decoder.contentLength);
+
+ decoder.pos += decoder.contentLength + 1;
+
+ //drain all the rest
+ if (decoder.bodyStart == -1)
+ {
+ decoder.bodyStart = decoder.pos;
+ }
+
+ while (decoder.pos < decoder.data)
+ {
+ if (decoder.workingBuffer[decoder.pos++] == 0)
+ {
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ // Need to scan for terminating NUL
+
+ if (decoder.bodyStart == -1)
+ {
+ decoder.bodyStart = decoder.pos;
+ }
+
+ while (decoder.pos < decoder.data)
+ {
+ if (decoder.workingBuffer[decoder.pos++] == 0)
+ {
+ content = new byte[decoder.pos - decoder.bodyStart - 1];
+
+ System.arraycopy(decoder.workingBuffer, decoder.bodyStart, content, 0,
content.length);
+
+ break;
+ }
+ }
+ }
+
+ if (content != null)
+ {
+ if (decoder.data > decoder.pos)
+ {
+ if (decoder.workingBuffer[decoder.pos] == StompDecoder.NEW_LINE)
decoder.pos++;
+
+ if (decoder.data > decoder.pos)
+ // More data still in the buffer from the next packet
+ System.arraycopy(decoder.workingBuffer, decoder.pos, decoder.workingBuffer,
0, decoder.data - decoder.pos);
+ }
+
+ decoder.data = decoder.data - decoder.pos;
+
+ // reset
+
+ StompFrame ret = new StompFrameV11(decoder.command, decoder.headers, content);
+
+ decoder.init();
+
+ return ret;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+}
Deleted:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameV11.java
===================================================================
---
branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameV11.java 2011-10-12
02:27:00 UTC (rev 11517)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameV11.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -1,103 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat 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.hornetq.core.protocol.stomp.v11;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.hornetq.api.core.HornetQBuffer;
-import org.hornetq.api.core.HornetQBuffers;
-import org.hornetq.core.protocol.stomp.HornetQStompException;
-import org.hornetq.core.protocol.stomp.SimpleBytes;
-import org.hornetq.core.protocol.stomp.Stomp;
-import org.hornetq.core.protocol.stomp.StompFrame;
-import org.hornetq.core.protocol.stomp.StompFrame.Header;
-
-/**
- *
- * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
- */
-public class StompFrameV11 extends StompFrame
-{
- //stomp 1.1 talks about repetitive headers.
- private List<Header> allHeaders = new ArrayList<Header>();
- private String contentType;
-
- public StompFrameV11(String command, Map<String, String> headers, byte[]
content)
- {
- super(command, headers, content);
- }
-
- public StompFrameV11(String command)
- {
- super(command);
- }
-
- @Override
- public HornetQBuffer toHornetQBuffer() throws Exception
- {
- if (buffer == null)
- {
- if (bytesBody != null)
- {
- buffer = HornetQBuffers.dynamicBuffer(bytesBody.length + 512);
- }
- else
- {
- buffer = HornetQBuffers.dynamicBuffer(512);
- }
-
- StringBuffer head = new StringBuffer();
- head.append(command);
- head.append(Stomp.NEWLINE);
- // Output the headers.
- for (Header h : allHeaders)
- {
- head.append(h.getEscapedKey());
- head.append(Stomp.Headers.SEPARATOR);
- head.append(h.getEscapedValue());
- head.append(Stomp.NEWLINE);
- }
- // Add a newline to separate the headers from the content.
- head.append(Stomp.NEWLINE);
-
- buffer.writeBytes(head.toString().getBytes("UTF-8"));
- if (bytesBody != null)
- {
- buffer.writeBytes(bytesBody);
- }
-
- buffer.writeBytes(END_OF_FRAME);
-
- size = buffer.writerIndex();
- }
- return buffer;
- }
-
- @Override
- public void addHeader(String key, String val)
- {
- if (!headers.containsKey(key))
- {
- headers.put(key, val);
- allHeaders.add(new Header(key, val));
- }
- else if (!key.equals(Stomp.Headers.CONTENT_LENGTH))
- {
- allHeaders.add(new Header(key, val));
- }
- }
-
-
-}
Copied:
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameV11.java
(from rev 11517,
branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameV11.java)
===================================================================
---
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameV11.java
(rev 0)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameV11.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat 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.hornetq.core.protocol.stomp.v11;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.hornetq.api.core.HornetQBuffer;
+import org.hornetq.api.core.HornetQBuffers;
+import org.hornetq.core.protocol.stomp.HornetQStompException;
+import org.hornetq.core.protocol.stomp.SimpleBytes;
+import org.hornetq.core.protocol.stomp.Stomp;
+import org.hornetq.core.protocol.stomp.StompFrame;
+import org.hornetq.core.protocol.stomp.StompFrame.Header;
+
+/**
+ *
+ * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
+ */
+public class StompFrameV11 extends StompFrame
+{
+ //stomp 1.1 talks about repetitive headers.
+ private List<Header> allHeaders = new ArrayList<Header>();
+ private String contentType;
+
+ public StompFrameV11(String command, Map<String, String> headers, byte[]
content)
+ {
+ super(command, headers, content);
+ }
+
+ public StompFrameV11(String command)
+ {
+ super(command);
+ }
+
+ @Override
+ public HornetQBuffer toHornetQBuffer() throws Exception
+ {
+ if (buffer == null)
+ {
+ if (bytesBody != null)
+ {
+ buffer = HornetQBuffers.dynamicBuffer(bytesBody.length + 512);
+ }
+ else
+ {
+ buffer = HornetQBuffers.dynamicBuffer(512);
+ }
+
+ StringBuffer head = new StringBuffer();
+ head.append(command);
+ head.append(Stomp.NEWLINE);
+ // Output the headers.
+ for (Header h : allHeaders)
+ {
+ head.append(h.getEscapedKey());
+ head.append(Stomp.Headers.SEPARATOR);
+ head.append(h.getEscapedValue());
+ head.append(Stomp.NEWLINE);
+ }
+ // Add a newline to separate the headers from the content.
+ head.append(Stomp.NEWLINE);
+
+ buffer.writeBytes(head.toString().getBytes("UTF-8"));
+ if (bytesBody != null)
+ {
+ buffer.writeBytes(bytesBody);
+ }
+
+ buffer.writeBytes(END_OF_FRAME);
+
+ size = buffer.writerIndex();
+ }
+ return buffer;
+ }
+
+ @Override
+ public void addHeader(String key, String val)
+ {
+ if (!headers.containsKey(key))
+ {
+ headers.put(key, val);
+ allHeaders.add(new Header(key, val));
+ }
+ else if (!key.equals(Stomp.Headers.CONTENT_LENGTH))
+ {
+ allHeaders.add(new Header(key, val));
+ }
+ }
+
+
+}
Modified: trunk/hornetq-core/src/main/java/org/hornetq/core/server/HornetQServers.java
===================================================================
---
trunk/hornetq-core/src/main/java/org/hornetq/core/server/HornetQServers.java 2011-10-12
08:04:52 UTC (rev 11518)
+++
trunk/hornetq-core/src/main/java/org/hornetq/core/server/HornetQServers.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -93,4 +93,19 @@
return server;
}
+ public static HornetQServer newHornetQServer(Configuration config,
+ String defUser, String defPass)
+ {
+ HornetQSecurityManager securityManager = new HornetQSecurityManagerImpl();
+
+ securityManager.addUser(defUser, defPass);
+
+ HornetQServer server = HornetQServers.newHornetQServer(config,
+
ManagementFactory.getPlatformMBeanServer(),
+ securityManager,
+ config.isPersistenceEnabled());
+
+ return server;
+ }
+
}
Modified:
trunk/hornetq-core/src/main/java/org/hornetq/spi/core/security/HornetQSecurityManagerImpl.java
===================================================================
---
trunk/hornetq-core/src/main/java/org/hornetq/spi/core/security/HornetQSecurityManagerImpl.java 2011-10-12
08:04:52 UTC (rev 11518)
+++
trunk/hornetq-core/src/main/java/org/hornetq/spi/core/security/HornetQSecurityManagerImpl.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -119,6 +119,7 @@
public void addUser(final String user, final String password)
{
+ log.error("-------------------------------adding user: " + user + "
password " + password);
if (user == null)
{
throw new IllegalArgumentException("User cannot be null");
Modified:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompConnectionCleanupTest.java
===================================================================
---
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompConnectionCleanupTest.java 2011-10-12
08:04:52 UTC (rev 11518)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompConnectionCleanupTest.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -39,6 +39,8 @@
frame = receiveFrame(10000);
//We send and consumer a message to ensure a STOMP connection and server session is
created
+
+ System.out.println("Received frame: " + frame);
Assert.assertTrue(frame.startsWith("CONNECTED"));
Modified:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompTest.java
===================================================================
---
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompTest.java 2011-10-12
08:04:52 UTC (rev 11518)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompTest.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -192,7 +192,6 @@
public void testSendMessageWithReceipt() throws Exception
{
-
MessageConsumer consumer = session.createConsumer(queue);
String frame = "CONNECT\n" + "login: brianm\n" +
"passcode: wombats\n\n" + Stomp.NULL;
@@ -370,12 +369,13 @@
frame = receiveFrame(100000);
Assert.assertTrue(frame.startsWith("CONNECTED"));
- frame = "SUBSCRIBE\n" + "destination:" + getQueuePrefix() +
getQueueName() + "\n" + "ack:auto\n\n" + Stomp.NULL;
+ frame = "SUBSCRIBE\n" + "destination:" + getQueuePrefix() +
getQueueName() + "\n" + "ack:auto\n\nfff" + Stomp.NULL;
sendFrame(frame);
sendMessage(getName());
frame = receiveFrame(10000);
+ System.out.println("-------- frame received: " + frame);
Assert.assertTrue(frame.startsWith("MESSAGE"));
Assert.assertTrue(frame.indexOf("destination:") > 0);
Assert.assertTrue(frame.indexOf(getName()) > 0);
@@ -406,6 +406,9 @@
sendMessage(payload, queue);
frame = receiveFrame(10000);
+
+ System.out.println("Message: " + frame);
+
Assert.assertTrue(frame.startsWith("MESSAGE"));
Pattern cl = Pattern.compile("Content-length:\\s*(\\d+)",
Pattern.CASE_INSENSITIVE);
Modified:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompTestBase.java
===================================================================
---
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompTestBase.java 2011-10-12
08:04:52 UTC (rev 11518)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompTestBase.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -39,7 +39,6 @@
import org.hornetq.api.core.TransportConfiguration;
import org.hornetq.core.config.Configuration;
-import org.hornetq.core.config.impl.ConfigurationImpl;
import org.hornetq.core.logging.Logger;
import org.hornetq.core.remoting.impl.invm.InVMAcceptorFactory;
import org.hornetq.core.remoting.impl.invm.InVMConnectorFactory;
@@ -80,7 +79,11 @@
protected JMSServerManager server;
+ protected String defUser = "brianm";
+ protected String defPass = "wombats";
+
+
// Implementation methods
// -------------------------------------------------------------------------
@@ -121,7 +124,7 @@
TransportConfiguration stompTransport = new
TransportConfiguration(NettyAcceptorFactory.class.getName(), params);
config.getAcceptorConfigurations().add(stompTransport);
config.getAcceptorConfigurations().add(new
TransportConfiguration(InVMAcceptorFactory.class.getName()));
- HornetQServer hornetQServer = HornetQServers.newHornetQServer(config);
+ HornetQServer hornetQServer = HornetQServers.newHornetQServer(config, defUser,
defPass);
JMSConfiguration jmsConfig = new JMSConfigurationImpl();
jmsConfig.getQueueConfigurations()
Deleted:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractClientStompFrame.java
===================================================================
---
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractClientStompFrame.java 2011-10-12
02:27:00 UTC (rev 11517)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractClientStompFrame.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -1,184 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat 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.hornetq.tests.integration.stomp.util;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-/**
- *
- * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
- *
- */
-public class AbstractClientStompFrame implements ClientStompFrame
-{
- protected static final String HEADER_RECEIPT = "receipt";
-
- protected String command;
- protected List<Header> headers = new ArrayList<Header>();
- protected Set<String> headerKeys = new HashSet<String>();
- protected String body;
-
- public AbstractClientStompFrame(String command)
- {
- this.command = command;
- }
-
- public String toString()
- {
- StringBuffer sb = new StringBuffer("Frame: <" + command +
">" + "\n");
- Iterator<Header> iter = headers.iterator();
- while (iter.hasNext())
- {
- Header h = iter.next();
- sb.append(h.key + ":" + h.val + "\n");
- }
- sb.append("\n");
- sb.append("<body>" + body + "<body>");
- return sb.toString();
- }
-
- @Override
- public ByteBuffer toByteBuffer() throws UnsupportedEncodingException
- {
- StringBuffer sb = new StringBuffer();
- sb.append(command + "\n");
- int n = headers.size();
- for (int i = 0; i < n; i++)
- {
- sb.append(headers.get(i).key + ":" + headers.get(i).val +
"\n");
- }
- sb.append("\n");
- if (body != null)
- {
- sb.append(body);
- }
- sb.append((char)0);
-
- String data = sb.toString();
-
- byte[] byteValue = data.getBytes("UTF-8");
-
- ByteBuffer buffer = ByteBuffer.allocateDirect(byteValue.length);
- buffer.put(byteValue);
-
- buffer.rewind();
- return buffer;
- }
-
- @Override
- public ByteBuffer toByteBufferWithExtra(String str) throws
UnsupportedEncodingException
- {
- StringBuffer sb = new StringBuffer();
- sb.append(command + "\n");
- int n = headers.size();
- for (int i = 0; i < n; i++)
- {
- sb.append(headers.get(i).key + ":" + headers.get(i).val +
"\n");
- }
- sb.append("\n");
- if (body != null)
- {
- sb.append(body);
- }
- sb.append((char)0);
- sb.append(str);
-
- String data = sb.toString();
-
- byte[] byteValue = data.getBytes("UTF-8");
-
- ByteBuffer buffer = ByteBuffer.allocateDirect(byteValue.length);
- buffer.put(byteValue);
-
- buffer.rewind();
- return buffer;
- }
-
- @Override
- public boolean needsReply()
- {
- if ("CONNECT".equals(command) || headerKeys.contains(HEADER_RECEIPT))
- {
- return true;
- }
- return false;
- }
-
- @Override
- public void setCommand(String command)
- {
- this.command = command;
- }
-
- @Override
- public void addHeader(String key, String val)
- {
- headers.add(new Header(key, val));
- headerKeys.add(key);
- }
-
- @Override
- public void setBody(String body)
- {
- this.body = body;
- }
-
- @Override
- public String getBody()
- {
- return body;
- }
-
- private class Header
- {
- public String key;
- public String val;
-
- public Header(String key, String val)
- {
- this.key = key;
- this.val = val;
- }
- }
-
- @Override
- public String getCommand()
- {
- return command;
- }
-
- @Override
- public String getHeader(String header)
- {
- if (headerKeys.contains(header))
- {
- Iterator<Header> iter = headers.iterator();
- while (iter.hasNext())
- {
- Header h = iter.next();
- if (h.key.equals(header))
- {
- return h.val;
- }
- }
- }
- return null;
- }
-
-}
Copied:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractClientStompFrame.java
(from rev 11517,
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractClientStompFrame.java)
===================================================================
---
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractClientStompFrame.java
(rev 0)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractClientStompFrame.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat 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.hornetq.tests.integration.stomp.util;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ *
+ * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
+ *
+ */
+public class AbstractClientStompFrame implements ClientStompFrame
+{
+ protected static final String HEADER_RECEIPT = "receipt";
+
+ protected String command;
+ protected List<Header> headers = new ArrayList<Header>();
+ protected Set<String> headerKeys = new HashSet<String>();
+ protected String body;
+
+ public AbstractClientStompFrame(String command)
+ {
+ this.command = command;
+ }
+
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer("Frame: <" + command +
">" + "\n");
+ Iterator<Header> iter = headers.iterator();
+ while (iter.hasNext())
+ {
+ Header h = iter.next();
+ sb.append(h.key + ":" + h.val + "\n");
+ }
+ sb.append("\n");
+ sb.append("<body>" + body + "<body>");
+ return sb.toString();
+ }
+
+ @Override
+ public ByteBuffer toByteBuffer() throws UnsupportedEncodingException
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append(command + "\n");
+ int n = headers.size();
+ for (int i = 0; i < n; i++)
+ {
+ sb.append(headers.get(i).key + ":" + headers.get(i).val +
"\n");
+ }
+ sb.append("\n");
+ if (body != null)
+ {
+ sb.append(body);
+ }
+ sb.append((char)0);
+
+ String data = sb.toString();
+
+ byte[] byteValue = data.getBytes("UTF-8");
+
+ ByteBuffer buffer = ByteBuffer.allocateDirect(byteValue.length);
+ buffer.put(byteValue);
+
+ buffer.rewind();
+ return buffer;
+ }
+
+ @Override
+ public ByteBuffer toByteBufferWithExtra(String str) throws
UnsupportedEncodingException
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append(command + "\n");
+ int n = headers.size();
+ for (int i = 0; i < n; i++)
+ {
+ sb.append(headers.get(i).key + ":" + headers.get(i).val +
"\n");
+ }
+ sb.append("\n");
+ if (body != null)
+ {
+ sb.append(body);
+ }
+ sb.append((char)0);
+ sb.append(str);
+
+ String data = sb.toString();
+
+ byte[] byteValue = data.getBytes("UTF-8");
+
+ ByteBuffer buffer = ByteBuffer.allocateDirect(byteValue.length);
+ buffer.put(byteValue);
+
+ buffer.rewind();
+ return buffer;
+ }
+
+ @Override
+ public boolean needsReply()
+ {
+ if ("CONNECT".equals(command) || headerKeys.contains(HEADER_RECEIPT))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void setCommand(String command)
+ {
+ this.command = command;
+ }
+
+ @Override
+ public void addHeader(String key, String val)
+ {
+ headers.add(new Header(key, val));
+ headerKeys.add(key);
+ }
+
+ @Override
+ public void setBody(String body)
+ {
+ this.body = body;
+ }
+
+ @Override
+ public String getBody()
+ {
+ return body;
+ }
+
+ private class Header
+ {
+ public String key;
+ public String val;
+
+ public Header(String key, String val)
+ {
+ this.key = key;
+ this.val = val;
+ }
+ }
+
+ @Override
+ public String getCommand()
+ {
+ return command;
+ }
+
+ @Override
+ public String getHeader(String header)
+ {
+ if (headerKeys.contains(header))
+ {
+ Iterator<Header> iter = headers.iterator();
+ while (iter.hasNext())
+ {
+ Header h = iter.next();
+ if (h.key.equals(header))
+ {
+ return h.val;
+ }
+ }
+ }
+ return null;
+ }
+
+}
Deleted:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractStompClientConnection.java
===================================================================
---
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractStompClientConnection.java 2011-10-12
02:27:00 UTC (rev 11517)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractStompClientConnection.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -1,291 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat 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.hornetq.tests.integration.stomp.util;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.SocketChannel;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-/**
- *
- * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
- *
- */
-public abstract class AbstractStompClientConnection implements StompClientConnection
-{
- protected static final String CONNECT_COMMAND = "CONNECT";
- protected static final String CONNECTED_COMMAND = "CONNECTED";
- protected static final String DISCONNECT_COMMAND = "DISCONNECT";
-
- protected static final String LOGIN_HEADER = "login";
- protected static final String PASSCODE_HEADER = "passcode";
-
- //ext
- protected static final String CLIENT_ID_HEADER = "client-id";
-
-
- protected String version;
- protected String host;
- protected int port;
- protected String username;
- protected String passcode;
- protected StompFrameFactory factory;
- protected SocketChannel socketChannel;
- protected ByteBuffer readBuffer;
-
- protected List<Byte> receiveList;
-
- protected BlockingQueue<ClientStompFrame> frameQueue = new
LinkedBlockingQueue<ClientStompFrame>();
-
- protected boolean connected = false;
-
- public AbstractStompClientConnection(String version, String host, int port) throws
IOException
- {
- this.version = version;
- this.host = host;
- this.port = port;
- this.factory = StompFrameFactoryFactory.getFactory(version);
-
- initSocket();
- }
-
- private void initSocket() throws IOException
- {
- socketChannel = SocketChannel.open();
- socketChannel.configureBlocking(true);
- InetSocketAddress remoteAddr = new InetSocketAddress(host, port);
- socketChannel.connect(remoteAddr);
-
- startReaderThread();
- }
-
- private void startReaderThread()
- {
- readBuffer = ByteBuffer.allocateDirect(10240);
- receiveList = new ArrayList<Byte>(10240);
-
- new ReaderThread().start();
- }
-
- public ClientStompFrame sendFrame(ClientStompFrame frame) throws IOException,
InterruptedException
- {
- ClientStompFrame response = null;
- ByteBuffer buffer = frame.toByteBuffer();
- while (buffer.remaining() > 0)
- {
- socketChannel.write(buffer);
- }
-
- //now response
- if (frame.needsReply())
- {
- response = receiveFrame();
-
- //filter out server ping
- while (response != null)
- {
- if (response.getCommand().equals("STOMP"))
- {
- response = receiveFrame();
- }
- else
- {
- break;
- }
- }
- }
- return response;
- }
-
- public ClientStompFrame sendWickedFrame(ClientStompFrame frame) throws IOException,
InterruptedException
- {
- ClientStompFrame response = null;
- ByteBuffer buffer = frame.toByteBufferWithExtra("\n");
-
- while (buffer.remaining() > 0)
- {
- socketChannel.write(buffer);
- }
-
- //now response
- if (frame.needsReply())
- {
- response = receiveFrame();
-
- //filter out server ping
- while (response != null)
- {
- if (response.getCommand().equals("STOMP"))
- {
- response = receiveFrame();
- }
- else
- {
- break;
- }
- }
- }
- return response;
- }
-
- public ClientStompFrame receiveFrame() throws InterruptedException
- {
- return frameQueue.poll(10, TimeUnit.SECONDS);
- }
-
- public ClientStompFrame receiveFrame(long timeout) throws InterruptedException
- {
- return frameQueue.poll(timeout, TimeUnit.MILLISECONDS);
- }
-
- //put bytes to byte array.
- private void receiveBytes(int n) throws UnsupportedEncodingException
- {
- readBuffer.rewind();
- for (int i = 0; i < n; i++)
- {
- byte b = readBuffer.get();
- if (b == 0)
- {
- //a new frame got.
- int sz = receiveList.size();
- if (sz > 0)
- {
- byte[] frameBytes = new byte[sz];
- for (int j = 0; j < sz; j++)
- {
- frameBytes[j] = receiveList.get(j);
- }
- ClientStompFrame frame = factory.createFrame(new String(frameBytes,
"UTF-8"));
-
- if (validateFrame(frame))
- {
- frameQueue.offer(frame);
- receiveList.clear();
- }
- else
- {
- receiveList.add(b);
- }
- }
- }
- else
- {
- receiveList.add(b);
- }
- }
- //clear readbuffer
- readBuffer.rewind();
- }
-
- private boolean validateFrame(ClientStompFrame f) throws UnsupportedEncodingException
- {
- String h = f.getHeader("content-length");
- if (h != null)
- {
- int len = Integer.valueOf(h);
- if (f.getBody().getBytes("UTF-8").length < len)
- {
- return false;
- }
- }
- return true;
- }
-
- protected void close() throws IOException
- {
- socketChannel.close();
- }
-
- private class ReaderThread extends Thread
- {
- public void run()
- {
- try
- {
- int n = socketChannel.read(readBuffer);
-
- while (n >= 0)
- {
- if (n > 0)
- {
- receiveBytes(n);
- }
- n = socketChannel.read(readBuffer);
- }
- //peer closed
- close();
-
- }
- catch (IOException e)
- {
- try
- {
- close();
- }
- catch (IOException e1)
- {
- //ignore
- }
- }
- }
- }
-
- public void connect() throws Exception
- {
- connect(null, null);
- }
-
- public void destroy()
- {
- try
- {
- close();
- }
- catch (IOException e)
- {
- }
- finally
- {
- this.connected = false;
- }
- }
-
- public void connect(String username, String password) throws Exception
- {
- throw new RuntimeException("connect method not implemented!");
- }
-
- public boolean isConnected()
- {
- return connected;
- }
-
- public String getVersion()
- {
- return version;
- }
-
- public int getFrameQueueSize()
- {
- return this.frameQueue.size();
- }
-
-}
Copied:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractStompClientConnection.java
(from rev 11517,
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractStompClientConnection.java)
===================================================================
---
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractStompClientConnection.java
(rev 0)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractStompClientConnection.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,291 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat 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.hornetq.tests.integration.stomp.util;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ *
+ * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
+ *
+ */
+public abstract class AbstractStompClientConnection implements StompClientConnection
+{
+ protected static final String CONNECT_COMMAND = "CONNECT";
+ protected static final String CONNECTED_COMMAND = "CONNECTED";
+ protected static final String DISCONNECT_COMMAND = "DISCONNECT";
+
+ protected static final String LOGIN_HEADER = "login";
+ protected static final String PASSCODE_HEADER = "passcode";
+
+ //ext
+ protected static final String CLIENT_ID_HEADER = "client-id";
+
+
+ protected String version;
+ protected String host;
+ protected int port;
+ protected String username;
+ protected String passcode;
+ protected StompFrameFactory factory;
+ protected SocketChannel socketChannel;
+ protected ByteBuffer readBuffer;
+
+ protected List<Byte> receiveList;
+
+ protected BlockingQueue<ClientStompFrame> frameQueue = new
LinkedBlockingQueue<ClientStompFrame>();
+
+ protected boolean connected = false;
+
+ public AbstractStompClientConnection(String version, String host, int port) throws
IOException
+ {
+ this.version = version;
+ this.host = host;
+ this.port = port;
+ this.factory = StompFrameFactoryFactory.getFactory(version);
+
+ initSocket();
+ }
+
+ private void initSocket() throws IOException
+ {
+ socketChannel = SocketChannel.open();
+ socketChannel.configureBlocking(true);
+ InetSocketAddress remoteAddr = new InetSocketAddress(host, port);
+ socketChannel.connect(remoteAddr);
+
+ startReaderThread();
+ }
+
+ private void startReaderThread()
+ {
+ readBuffer = ByteBuffer.allocateDirect(10240);
+ receiveList = new ArrayList<Byte>(10240);
+
+ new ReaderThread().start();
+ }
+
+ public ClientStompFrame sendFrame(ClientStompFrame frame) throws IOException,
InterruptedException
+ {
+ ClientStompFrame response = null;
+ ByteBuffer buffer = frame.toByteBuffer();
+ while (buffer.remaining() > 0)
+ {
+ socketChannel.write(buffer);
+ }
+
+ //now response
+ if (frame.needsReply())
+ {
+ response = receiveFrame();
+
+ //filter out server ping
+ while (response != null)
+ {
+ if (response.getCommand().equals("STOMP"))
+ {
+ response = receiveFrame();
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ return response;
+ }
+
+ public ClientStompFrame sendWickedFrame(ClientStompFrame frame) throws IOException,
InterruptedException
+ {
+ ClientStompFrame response = null;
+ ByteBuffer buffer = frame.toByteBufferWithExtra("\n");
+
+ while (buffer.remaining() > 0)
+ {
+ socketChannel.write(buffer);
+ }
+
+ //now response
+ if (frame.needsReply())
+ {
+ response = receiveFrame();
+
+ //filter out server ping
+ while (response != null)
+ {
+ if (response.getCommand().equals("STOMP"))
+ {
+ response = receiveFrame();
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ return response;
+ }
+
+ public ClientStompFrame receiveFrame() throws InterruptedException
+ {
+ return frameQueue.poll(10, TimeUnit.SECONDS);
+ }
+
+ public ClientStompFrame receiveFrame(long timeout) throws InterruptedException
+ {
+ return frameQueue.poll(timeout, TimeUnit.MILLISECONDS);
+ }
+
+ //put bytes to byte array.
+ private void receiveBytes(int n) throws UnsupportedEncodingException
+ {
+ readBuffer.rewind();
+ for (int i = 0; i < n; i++)
+ {
+ byte b = readBuffer.get();
+ if (b == 0)
+ {
+ //a new frame got.
+ int sz = receiveList.size();
+ if (sz > 0)
+ {
+ byte[] frameBytes = new byte[sz];
+ for (int j = 0; j < sz; j++)
+ {
+ frameBytes[j] = receiveList.get(j);
+ }
+ ClientStompFrame frame = factory.createFrame(new String(frameBytes,
"UTF-8"));
+
+ if (validateFrame(frame))
+ {
+ frameQueue.offer(frame);
+ receiveList.clear();
+ }
+ else
+ {
+ receiveList.add(b);
+ }
+ }
+ }
+ else
+ {
+ receiveList.add(b);
+ }
+ }
+ //clear readbuffer
+ readBuffer.rewind();
+ }
+
+ private boolean validateFrame(ClientStompFrame f) throws UnsupportedEncodingException
+ {
+ String h = f.getHeader("content-length");
+ if (h != null)
+ {
+ int len = Integer.valueOf(h);
+ if (f.getBody().getBytes("UTF-8").length < len)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ protected void close() throws IOException
+ {
+ socketChannel.close();
+ }
+
+ private class ReaderThread extends Thread
+ {
+ public void run()
+ {
+ try
+ {
+ int n = socketChannel.read(readBuffer);
+
+ while (n >= 0)
+ {
+ if (n > 0)
+ {
+ receiveBytes(n);
+ }
+ n = socketChannel.read(readBuffer);
+ }
+ //peer closed
+ close();
+
+ }
+ catch (IOException e)
+ {
+ try
+ {
+ close();
+ }
+ catch (IOException e1)
+ {
+ //ignore
+ }
+ }
+ }
+ }
+
+ public void connect() throws Exception
+ {
+ connect(null, null);
+ }
+
+ public void destroy()
+ {
+ try
+ {
+ close();
+ }
+ catch (IOException e)
+ {
+ }
+ finally
+ {
+ this.connected = false;
+ }
+ }
+
+ public void connect(String username, String password) throws Exception
+ {
+ throw new RuntimeException("connect method not implemented!");
+ }
+
+ public boolean isConnected()
+ {
+ return connected;
+ }
+
+ public String getVersion()
+ {
+ return version;
+ }
+
+ public int getFrameQueueSize()
+ {
+ return this.frameQueue.size();
+ }
+
+}
Deleted:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrame.java
===================================================================
---
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrame.java 2011-10-12
02:27:00 UTC (rev 11517)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrame.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -1,45 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat 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.hornetq.tests.integration.stomp.util;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-
-/**
- *
- * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
- *
- * pls use factory to create frames.
- */
-public interface ClientStompFrame
-{
-
- public ByteBuffer toByteBuffer() throws UnsupportedEncodingException;
-
- public boolean needsReply();
-
- public void setCommand(String command);
-
- public void addHeader(String string, String string2);
-
- public void setBody(String string);
-
- public String getCommand();
-
- public String getHeader(String header);
-
- public String getBody();
-
- public ByteBuffer toByteBufferWithExtra(String str) throws
UnsupportedEncodingException;
-
-}
Copied:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrame.java
(from rev 11517,
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrame.java)
===================================================================
---
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrame.java
(rev 0)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrame.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat 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.hornetq.tests.integration.stomp.util;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+
+/**
+ *
+ * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
+ *
+ * pls use factory to create frames.
+ */
+public interface ClientStompFrame
+{
+
+ public ByteBuffer toByteBuffer() throws UnsupportedEncodingException;
+
+ public boolean needsReply();
+
+ public void setCommand(String command);
+
+ public void addHeader(String string, String string2);
+
+ public void setBody(String string);
+
+ public String getCommand();
+
+ public String getHeader(String header);
+
+ public String getBody();
+
+ public ByteBuffer toByteBufferWithExtra(String str) throws
UnsupportedEncodingException;
+
+}
Deleted:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV10.java
===================================================================
---
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV10.java 2011-10-12
02:27:00 UTC (rev 11517)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV10.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -1,29 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat 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.hornetq.tests.integration.stomp.util;
-
-/**
- *
- * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
- *
- * pls use factory to create frames.
- */
-public class ClientStompFrameV10 extends AbstractClientStompFrame
-{
-
- public ClientStompFrameV10(String command)
- {
- super(command);
- }
-
-}
Copied:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV10.java
(from rev 11517,
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV10.java)
===================================================================
---
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV10.java
(rev 0)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV10.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat 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.hornetq.tests.integration.stomp.util;
+
+/**
+ *
+ * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
+ *
+ * pls use factory to create frames.
+ */
+public class ClientStompFrameV10 extends AbstractClientStompFrame
+{
+
+ public ClientStompFrameV10(String command)
+ {
+ super(command);
+ }
+
+}
Deleted:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV11.java
===================================================================
---
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV11.java 2011-10-12
02:27:00 UTC (rev 11517)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV11.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -1,46 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat 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.hornetq.tests.integration.stomp.util;
-
-/**
- *
- * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
- *
- * pls use factory to create frames.
- */
-public class ClientStompFrameV11 extends AbstractClientStompFrame
-{
- boolean forceOneway = false;
-
- public ClientStompFrameV11(String command)
- {
- super(command);
- }
-
- public void setForceOneway()
- {
- forceOneway = true;
- }
-
- @Override
- public boolean needsReply()
- {
- if (forceOneway) return false;
-
- if ("CONNECT".equals(command) || "STOMP".equals(command) ||
headerKeys.contains(HEADER_RECEIPT))
- {
- return true;
- }
- return false;
- }
-}
Copied:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV11.java
(from rev 11517,
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV11.java)
===================================================================
---
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV11.java
(rev 0)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV11.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat 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.hornetq.tests.integration.stomp.util;
+
+/**
+ *
+ * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
+ *
+ * pls use factory to create frames.
+ */
+public class ClientStompFrameV11 extends AbstractClientStompFrame
+{
+ boolean forceOneway = false;
+
+ public ClientStompFrameV11(String command)
+ {
+ super(command);
+ }
+
+ public void setForceOneway()
+ {
+ forceOneway = true;
+ }
+
+ @Override
+ public boolean needsReply()
+ {
+ if (forceOneway) return false;
+
+ if ("CONNECT".equals(command) || "STOMP".equals(command) ||
headerKeys.contains(HEADER_RECEIPT))
+ {
+ return true;
+ }
+ return false;
+ }
+}
Deleted:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnection.java
===================================================================
---
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnection.java 2011-10-12
02:27:00 UTC (rev 11517)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnection.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -1,57 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat 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.hornetq.tests.integration.stomp.util;
-
-import java.io.IOException;
-
-/**
- *
- * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
- *
- * pls use factory to create frames.
- */
-public interface StompClientConnection
-{
- ClientStompFrame sendFrame(ClientStompFrame frame) throws IOException,
InterruptedException;
-
- ClientStompFrame receiveFrame() throws InterruptedException;
-
- ClientStompFrame receiveFrame(long timeout) throws InterruptedException;;
-
- void connect() throws Exception;
-
- void disconnect() throws IOException, InterruptedException;
-
- void connect(String defUser, String defPass) throws Exception;
-
- void connect(String defUser, String defPass, String clientId) throws Exception;
-
- boolean isConnected();
-
- String getVersion();
-
- ClientStompFrame createFrame(String command);
-
- //number of frames at the queue
- int getFrameQueueSize();
-
- void startPinger(long interval);
-
- void stopPinger();
-
- void destroy();
-
- ClientStompFrame sendWickedFrame(ClientStompFrame frame) throws IOException,
InterruptedException;
-
-}
-
Copied:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnection.java
(from rev 11517,
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnection.java)
===================================================================
---
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnection.java
(rev 0)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnection.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat 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.hornetq.tests.integration.stomp.util;
+
+import java.io.IOException;
+
+/**
+ *
+ * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
+ *
+ * pls use factory to create frames.
+ */
+public interface StompClientConnection
+{
+ ClientStompFrame sendFrame(ClientStompFrame frame) throws IOException,
InterruptedException;
+
+ ClientStompFrame receiveFrame() throws InterruptedException;
+
+ ClientStompFrame receiveFrame(long timeout) throws InterruptedException;;
+
+ void connect() throws Exception;
+
+ void disconnect() throws IOException, InterruptedException;
+
+ void connect(String defUser, String defPass) throws Exception;
+
+ void connect(String defUser, String defPass, String clientId) throws Exception;
+
+ boolean isConnected();
+
+ String getVersion();
+
+ ClientStompFrame createFrame(String command);
+
+ //number of frames at the queue
+ int getFrameQueueSize();
+
+ void startPinger(long interval);
+
+ void stopPinger();
+
+ void destroy();
+
+ ClientStompFrame sendWickedFrame(ClientStompFrame frame) throws IOException,
InterruptedException;
+
+}
+
Deleted:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionFactory.java
===================================================================
---
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionFactory.java 2011-10-12
02:27:00 UTC (rev 11517)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionFactory.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -1,52 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat 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.hornetq.tests.integration.stomp.util;
-
-import java.io.IOException;
-
-/**
- *
- * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
- *
- */
-public class StompClientConnectionFactory
-{
- //create a raw connection to the host.
- public static StompClientConnection createClientConnection(String version, String
host, int port) throws IOException
- {
- if ("1.0".equals(version))
- {
- return new StompClientConnectionV10(host, port);
- }
- if ("1.1".equals(version))
- {
- return new StompClientConnectionV11(host, port);
- }
- return null;
- }
-
- public static void main(String[] args) throws Exception
- {
- StompClientConnection connection =
StompClientConnectionFactory.createClientConnection("1.0",
"localhost", 61613);
-
- System.out.println("created a new connection: " + connection);
-
- connection.connect();
-
- System.out.println("connected.");
-
- connection.disconnect();
- System.out.println("Simple stomp client works.");
-
- }
-}
Copied:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionFactory.java
(from rev 11517,
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionFactory.java)
===================================================================
---
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionFactory.java
(rev 0)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionFactory.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat 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.hornetq.tests.integration.stomp.util;
+
+import java.io.IOException;
+
+/**
+ *
+ * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
+ *
+ */
+public class StompClientConnectionFactory
+{
+ //create a raw connection to the host.
+ public static StompClientConnection createClientConnection(String version, String
host, int port) throws IOException
+ {
+ if ("1.0".equals(version))
+ {
+ return new StompClientConnectionV10(host, port);
+ }
+ if ("1.1".equals(version))
+ {
+ return new StompClientConnectionV11(host, port);
+ }
+ return null;
+ }
+
+ public static void main(String[] args) throws Exception
+ {
+ StompClientConnection connection =
StompClientConnectionFactory.createClientConnection("1.0",
"localhost", 61613);
+
+ System.out.println("created a new connection: " + connection);
+
+ connection.connect();
+
+ System.out.println("connected.");
+
+ connection.disconnect();
+ System.out.println("Simple stomp client works.");
+
+ }
+}
Deleted:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV10.java
===================================================================
---
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV10.java 2011-10-12
02:27:00 UTC (rev 11517)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV10.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -1,101 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat 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.hornetq.tests.integration.stomp.util;
-
-import java.io.IOException;
-
-/**
- *
- * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
- *
- * pls use factory to create frames.
- */
-public class StompClientConnectionV10 extends AbstractStompClientConnection
-{
-
- public StompClientConnectionV10(String host, int port) throws IOException
- {
- super("1.0", host, port);
- }
-
- public void connect(String username, String passcode) throws IOException,
InterruptedException
- {
- ClientStompFrame frame = factory.newFrame(CONNECT_COMMAND);
- frame.addHeader(LOGIN_HEADER, username);
- frame.addHeader(PASSCODE_HEADER, passcode);
-
- ClientStompFrame response = this.sendFrame(frame);
-
- if (response.getCommand().equals(CONNECTED_COMMAND))
- {
- connected = true;
- }
- else
- {
- System.out.println("Connection failed with: " + response);
- connected = false;
- }
- }
-
- public void connect(String username, String passcode, String clientID) throws
IOException, InterruptedException
- {
- ClientStompFrame frame = factory.newFrame(CONNECT_COMMAND);
- frame.addHeader(LOGIN_HEADER, username);
- frame.addHeader(PASSCODE_HEADER, passcode);
- frame.addHeader(CLIENT_ID_HEADER, clientID);
-
- ClientStompFrame response = this.sendFrame(frame);
-
- if (response.getCommand().equals(CONNECTED_COMMAND))
- {
- connected = true;
- }
- else
- {
- System.out.println("Connection failed with: " + response);
- connected = false;
- }
- }
-
- @Override
- public void disconnect() throws IOException, InterruptedException
- {
- ClientStompFrame frame = factory.newFrame(DISCONNECT_COMMAND);
- this.sendFrame(frame);
-
- close();
-
- connected = false;
- }
-
- @Override
- public ClientStompFrame createFrame(
- String command)
- {
- return new ClientStompFrameV10(command);
- }
-
- @Override
- public void startPinger(long interval)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void stopPinger()
- {
- // TODO Auto-generated method stub
-
- }
-}
Copied:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV10.java
(from rev 11517,
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV10.java)
===================================================================
---
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV10.java
(rev 0)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV10.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat 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.hornetq.tests.integration.stomp.util;
+
+import java.io.IOException;
+
+/**
+ *
+ * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
+ *
+ * pls use factory to create frames.
+ */
+public class StompClientConnectionV10 extends AbstractStompClientConnection
+{
+
+ public StompClientConnectionV10(String host, int port) throws IOException
+ {
+ super("1.0", host, port);
+ }
+
+ public void connect(String username, String passcode) throws IOException,
InterruptedException
+ {
+ ClientStompFrame frame = factory.newFrame(CONNECT_COMMAND);
+ frame.addHeader(LOGIN_HEADER, username);
+ frame.addHeader(PASSCODE_HEADER, passcode);
+
+ ClientStompFrame response = this.sendFrame(frame);
+
+ if (response.getCommand().equals(CONNECTED_COMMAND))
+ {
+ connected = true;
+ }
+ else
+ {
+ System.out.println("Connection failed with: " + response);
+ connected = false;
+ }
+ }
+
+ public void connect(String username, String passcode, String clientID) throws
IOException, InterruptedException
+ {
+ ClientStompFrame frame = factory.newFrame(CONNECT_COMMAND);
+ frame.addHeader(LOGIN_HEADER, username);
+ frame.addHeader(PASSCODE_HEADER, passcode);
+ frame.addHeader(CLIENT_ID_HEADER, clientID);
+
+ ClientStompFrame response = this.sendFrame(frame);
+
+ if (response.getCommand().equals(CONNECTED_COMMAND))
+ {
+ connected = true;
+ }
+ else
+ {
+ System.out.println("Connection failed with: " + response);
+ connected = false;
+ }
+ }
+
+ @Override
+ public void disconnect() throws IOException, InterruptedException
+ {
+ ClientStompFrame frame = factory.newFrame(DISCONNECT_COMMAND);
+ this.sendFrame(frame);
+
+ close();
+
+ connected = false;
+ }
+
+ @Override
+ public ClientStompFrame createFrame(
+ String command)
+ {
+ return new ClientStompFrameV10(command);
+ }
+
+ @Override
+ public void startPinger(long interval)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void stopPinger()
+ {
+ // TODO Auto-generated method stub
+
+ }
+}
Deleted:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV11.java
===================================================================
---
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV11.java 2011-10-12
02:27:00 UTC (rev 11517)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV11.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -1,227 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat 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.hornetq.tests.integration.stomp.util;
-
-import java.io.IOException;
-
-/**
- *
- * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
- *
- */
-public class StompClientConnectionV11 extends AbstractStompClientConnection
-{
- public static final String STOMP_COMMAND = "STOMP";
-
- public static final String ACCEPT_HEADER = "accept-version";
- public static final String HOST_HEADER = "host";
- public static final String VERSION_HEADER = "version";
- public static final String RECEIPT_HEADER = "receipt";
-
- private Pinger pinger;
-
- public StompClientConnectionV11(String host, int port) throws IOException
- {
- super("1.1", host, port);
- }
-
- public void connect(String username, String passcode) throws IOException,
InterruptedException
- {
- ClientStompFrame frame = factory.newFrame(CONNECT_COMMAND);
- frame.addHeader(ACCEPT_HEADER, "1.1");
- frame.addHeader(HOST_HEADER, "localhost");
- if (username != null)
- {
- frame.addHeader(LOGIN_HEADER, username);
- frame.addHeader(PASSCODE_HEADER, passcode);
- }
-
- ClientStompFrame response = this.sendFrame(frame);
-
- if (response.getCommand().equals(CONNECTED_COMMAND))
- {
- String version = response.getHeader(VERSION_HEADER);
- assert(version.equals("1.1"));
-
- this.username = username;
- this.passcode = passcode;
- this.connected = true;
- }
- else
- {
- connected = false;
- }
- }
-
- public void connect(String username, String passcode, String clientID) throws
IOException, InterruptedException
- {
- ClientStompFrame frame = factory.newFrame(CONNECT_COMMAND);
- frame.addHeader(ACCEPT_HEADER, "1.1");
- frame.addHeader(HOST_HEADER, "localhost");
- frame.addHeader(CLIENT_ID_HEADER, clientID);
-
- if (username != null)
- {
- frame.addHeader(LOGIN_HEADER, username);
- frame.addHeader(PASSCODE_HEADER, passcode);
- }
-
- ClientStompFrame response = this.sendFrame(frame);
-
- if (response.getCommand().equals(CONNECTED_COMMAND))
- {
- String version = response.getHeader(VERSION_HEADER);
- assert(version.equals("1.1"));
-
- this.username = username;
- this.passcode = passcode;
- this.connected = true;
- }
- else
- {
- connected = false;
- }
- }
-
- public void connect1(String username, String passcode) throws IOException,
InterruptedException
- {
- ClientStompFrame frame = factory.newFrame(STOMP_COMMAND);
- frame.addHeader(ACCEPT_HEADER, "1.0,1.1");
- frame.addHeader(HOST_HEADER, "127.0.0.1");
- if (username != null)
- {
- frame.addHeader(LOGIN_HEADER, username);
- frame.addHeader(PASSCODE_HEADER, passcode);
- }
-
- ClientStompFrame response = this.sendFrame(frame);
-
- if (response.getCommand().equals(CONNECTED_COMMAND))
- {
- String version = response.getHeader(VERSION_HEADER);
- assert(version.equals("1.1"));
-
- this.username = username;
- this.passcode = passcode;
- this.connected = true;
- }
- else
- {
- System.out.println("Connection failed with frame " + response);
- connected = false;
- }
- }
-
- @Override
- public void disconnect() throws IOException, InterruptedException
- {
- stopPinger();
- ClientStompFrame frame = factory.newFrame(DISCONNECT_COMMAND);
- frame.addHeader("receipt", "1");
-
- ClientStompFrame result = this.sendFrame(frame);
-
- if (result == null || (!"RECEIPT".equals(result.getCommand())) ||
(!"1".equals(result.getHeader("receipt-id"))))
- {
- throw new IOException("Disconnect failed! " + result);
- }
-
- close();
-
- connected = false;
- }
-
- @Override
- public ClientStompFrame createFrame(String command)
- {
- return new ClientStompFrameV11(command);
- }
-
- @Override
- public void startPinger(long interval)
- {
- pinger = new Pinger(interval);
- pinger.startPing();
- }
-
- @Override
- public void stopPinger()
- {
- if (pinger != null)
- {
- pinger.stopPing();
- try
- {
- pinger.join();
- }
- catch (InterruptedException e)
- {
- e.printStackTrace();
- }
- pinger = null;
- }
- }
-
- private class Pinger extends Thread
- {
- long pingInterval;
- ClientStompFrameV11 pingFrame;
- volatile boolean stop = false;
-
- public Pinger(long interval)
- {
- this.pingInterval = interval;
- pingFrame = (ClientStompFrameV11) createFrame("STOMP");
- pingFrame.setBody("\n");
- pingFrame.setForceOneway();
- }
-
- public void startPing()
- {
- start();
- }
-
- public synchronized void stopPing()
- {
- stop = true;
- this.notify();
- }
-
- public void run()
- {
- synchronized (this)
- {
- while (!stop)
- {
- try
- {
- System.out.println("============sending ping");
-
- sendFrame(pingFrame);
-
- System.out.println("Pinged " + pingFrame);
-
- this.wait(pingInterval);
- }
- catch (Exception e)
- {
- stop = true;
- e.printStackTrace();
- }
- }
- System.out.println("Pinger stopped");
- }
- }
- }
-
-}
Copied:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV11.java
(from rev 11517,
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV11.java)
===================================================================
---
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV11.java
(rev 0)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV11.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat 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.hornetq.tests.integration.stomp.util;
+
+import java.io.IOException;
+
+/**
+ *
+ * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
+ *
+ */
+public class StompClientConnectionV11 extends AbstractStompClientConnection
+{
+ public static final String STOMP_COMMAND = "STOMP";
+
+ public static final String ACCEPT_HEADER = "accept-version";
+ public static final String HOST_HEADER = "host";
+ public static final String VERSION_HEADER = "version";
+ public static final String RECEIPT_HEADER = "receipt";
+
+ private Pinger pinger;
+
+ public StompClientConnectionV11(String host, int port) throws IOException
+ {
+ super("1.1", host, port);
+ }
+
+ public void connect(String username, String passcode) throws IOException,
InterruptedException
+ {
+ ClientStompFrame frame = factory.newFrame(CONNECT_COMMAND);
+ frame.addHeader(ACCEPT_HEADER, "1.1");
+ frame.addHeader(HOST_HEADER, "localhost");
+ if (username != null)
+ {
+ frame.addHeader(LOGIN_HEADER, username);
+ frame.addHeader(PASSCODE_HEADER, passcode);
+ }
+
+ ClientStompFrame response = this.sendFrame(frame);
+
+ if (response.getCommand().equals(CONNECTED_COMMAND))
+ {
+ String version = response.getHeader(VERSION_HEADER);
+ assert(version.equals("1.1"));
+
+ this.username = username;
+ this.passcode = passcode;
+ this.connected = true;
+ }
+ else
+ {
+ connected = false;
+ }
+ }
+
+ public void connect(String username, String passcode, String clientID) throws
IOException, InterruptedException
+ {
+ ClientStompFrame frame = factory.newFrame(CONNECT_COMMAND);
+ frame.addHeader(ACCEPT_HEADER, "1.1");
+ frame.addHeader(HOST_HEADER, "localhost");
+ frame.addHeader(CLIENT_ID_HEADER, clientID);
+
+ if (username != null)
+ {
+ frame.addHeader(LOGIN_HEADER, username);
+ frame.addHeader(PASSCODE_HEADER, passcode);
+ }
+
+ ClientStompFrame response = this.sendFrame(frame);
+
+ if (response.getCommand().equals(CONNECTED_COMMAND))
+ {
+ String version = response.getHeader(VERSION_HEADER);
+ assert(version.equals("1.1"));
+
+ this.username = username;
+ this.passcode = passcode;
+ this.connected = true;
+ }
+ else
+ {
+ connected = false;
+ }
+ }
+
+ public void connect1(String username, String passcode) throws IOException,
InterruptedException
+ {
+ ClientStompFrame frame = factory.newFrame(STOMP_COMMAND);
+ frame.addHeader(ACCEPT_HEADER, "1.0,1.1");
+ frame.addHeader(HOST_HEADER, "127.0.0.1");
+ if (username != null)
+ {
+ frame.addHeader(LOGIN_HEADER, username);
+ frame.addHeader(PASSCODE_HEADER, passcode);
+ }
+
+ ClientStompFrame response = this.sendFrame(frame);
+
+ if (response.getCommand().equals(CONNECTED_COMMAND))
+ {
+ String version = response.getHeader(VERSION_HEADER);
+ assert(version.equals("1.1"));
+
+ this.username = username;
+ this.passcode = passcode;
+ this.connected = true;
+ }
+ else
+ {
+ System.out.println("Connection failed with frame " + response);
+ connected = false;
+ }
+ }
+
+ @Override
+ public void disconnect() throws IOException, InterruptedException
+ {
+ stopPinger();
+ ClientStompFrame frame = factory.newFrame(DISCONNECT_COMMAND);
+ frame.addHeader("receipt", "1");
+
+ ClientStompFrame result = this.sendFrame(frame);
+
+ if (result == null || (!"RECEIPT".equals(result.getCommand())) ||
(!"1".equals(result.getHeader("receipt-id"))))
+ {
+ throw new IOException("Disconnect failed! " + result);
+ }
+
+ close();
+
+ connected = false;
+ }
+
+ @Override
+ public ClientStompFrame createFrame(String command)
+ {
+ return new ClientStompFrameV11(command);
+ }
+
+ @Override
+ public void startPinger(long interval)
+ {
+ pinger = new Pinger(interval);
+ pinger.startPing();
+ }
+
+ @Override
+ public void stopPinger()
+ {
+ if (pinger != null)
+ {
+ pinger.stopPing();
+ try
+ {
+ pinger.join();
+ }
+ catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ pinger = null;
+ }
+ }
+
+ private class Pinger extends Thread
+ {
+ long pingInterval;
+ ClientStompFrameV11 pingFrame;
+ volatile boolean stop = false;
+
+ public Pinger(long interval)
+ {
+ this.pingInterval = interval;
+ pingFrame = (ClientStompFrameV11) createFrame("STOMP");
+ pingFrame.setBody("\n");
+ pingFrame.setForceOneway();
+ }
+
+ public void startPing()
+ {
+ start();
+ }
+
+ public synchronized void stopPing()
+ {
+ stop = true;
+ this.notify();
+ }
+
+ public void run()
+ {
+ synchronized (this)
+ {
+ while (!stop)
+ {
+ try
+ {
+ System.out.println("============sending ping");
+
+ sendFrame(pingFrame);
+
+ System.out.println("Pinged " + pingFrame);
+
+ this.wait(pingInterval);
+ }
+ catch (Exception e)
+ {
+ stop = true;
+ e.printStackTrace();
+ }
+ }
+ System.out.println("Pinger stopped");
+ }
+ }
+ }
+
+}
Deleted:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactory.java
===================================================================
---
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactory.java 2011-10-12
02:27:00 UTC (rev 11517)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactory.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -1,27 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat 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.hornetq.tests.integration.stomp.util;
-
-/**
- *
- * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
- *
- */
-public interface StompFrameFactory
-{
-
- ClientStompFrame createFrame(String data);
-
- ClientStompFrame newFrame(String command);
-
-}
Copied:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactory.java
(from rev 11517,
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactory.java)
===================================================================
---
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactory.java
(rev 0)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactory.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat 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.hornetq.tests.integration.stomp.util;
+
+/**
+ *
+ * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
+ *
+ */
+public interface StompFrameFactory
+{
+
+ ClientStompFrame createFrame(String data);
+
+ ClientStompFrame newFrame(String command);
+
+}
Deleted:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryFactory.java
===================================================================
---
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryFactory.java 2011-10-12
02:27:00 UTC (rev 11517)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryFactory.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -1,37 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat 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.hornetq.tests.integration.stomp.util;
-
-/**
- *
- * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
- *
- */
-public class StompFrameFactoryFactory
-{
- public static StompFrameFactory getFactory(String version)
- {
- if ("1.0".equals(version))
- {
- return new StompFrameFactoryV10();
- }
-
- if ("1.1".equals(version))
- {
- return new StompFrameFactoryV11();
- }
-
- return null;
- }
-
-}
Copied:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryFactory.java
(from rev 11517,
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryFactory.java)
===================================================================
---
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryFactory.java
(rev 0)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryFactory.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat 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.hornetq.tests.integration.stomp.util;
+
+/**
+ *
+ * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
+ *
+ */
+public class StompFrameFactoryFactory
+{
+ public static StompFrameFactory getFactory(String version)
+ {
+ if ("1.0".equals(version))
+ {
+ return new StompFrameFactoryV10();
+ }
+
+ if ("1.1".equals(version))
+ {
+ return new StompFrameFactoryV11();
+ }
+
+ return null;
+ }
+
+}
Deleted:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV10.java
===================================================================
---
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV10.java 2011-10-12
02:27:00 UTC (rev 11517)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV10.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -1,71 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat 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.hornetq.tests.integration.stomp.util;
-
-import java.util.StringTokenizer;
-
-/**
- *
- * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
- *
- * 1.0 frames
- *
- * 1. CONNECT
- * 2. CONNECTED
- * 3. SEND
- * 4. SUBSCRIBE
- * 5. UNSUBSCRIBE
- * 6. BEGIN
- * 7. COMMIT
- * 8. ACK
- * 9. ABORT
- * 10. DISCONNECT
- * 11. MESSAGE
- * 12. RECEIPT
- * 13. ERROR
- */
-public class StompFrameFactoryV10 implements StompFrameFactory
-{
-
- public ClientStompFrame createFrame(String data)
- {
- //split the string at "\n\n"
- String[] dataFields = data.split("\n\n");
-
- StringTokenizer tokenizer = new StringTokenizer(dataFields[0], "\n");
-
- String command = tokenizer.nextToken();
- ClientStompFrame frame = new ClientStompFrameV10(command);
-
- while (tokenizer.hasMoreTokens())
- {
- String header = tokenizer.nextToken();
- String[] fields = header.split(":");
- frame.addHeader(fields[0], fields[1]);
- }
-
- //body (without null byte)
- if (dataFields.length == 2)
- {
- frame.setBody(dataFields[1]);
- }
- return frame;
- }
-
- @Override
- public ClientStompFrame newFrame(String command)
- {
- return new ClientStompFrameV10(command);
- }
-
-}
Copied:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV10.java
(from rev 11517,
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV10.java)
===================================================================
---
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV10.java
(rev 0)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV10.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat 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.hornetq.tests.integration.stomp.util;
+
+import java.util.StringTokenizer;
+
+/**
+ *
+ * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
+ *
+ * 1.0 frames
+ *
+ * 1. CONNECT
+ * 2. CONNECTED
+ * 3. SEND
+ * 4. SUBSCRIBE
+ * 5. UNSUBSCRIBE
+ * 6. BEGIN
+ * 7. COMMIT
+ * 8. ACK
+ * 9. ABORT
+ * 10. DISCONNECT
+ * 11. MESSAGE
+ * 12. RECEIPT
+ * 13. ERROR
+ */
+public class StompFrameFactoryV10 implements StompFrameFactory
+{
+
+ public ClientStompFrame createFrame(String data)
+ {
+ //split the string at "\n\n"
+ String[] dataFields = data.split("\n\n");
+
+ StringTokenizer tokenizer = new StringTokenizer(dataFields[0], "\n");
+
+ String command = tokenizer.nextToken();
+ ClientStompFrame frame = new ClientStompFrameV10(command);
+
+ while (tokenizer.hasMoreTokens())
+ {
+ String header = tokenizer.nextToken();
+ String[] fields = header.split(":");
+ frame.addHeader(fields[0], fields[1]);
+ }
+
+ //body (without null byte)
+ if (dataFields.length == 2)
+ {
+ frame.setBody(dataFields[1]);
+ }
+ return frame;
+ }
+
+ @Override
+ public ClientStompFrame newFrame(String command)
+ {
+ return new ClientStompFrameV10(command);
+ }
+
+}
Deleted:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV11.java
===================================================================
---
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV11.java 2011-10-12
02:27:00 UTC (rev 11517)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV11.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -1,182 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat 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.hornetq.tests.integration.stomp.util;
-
-import java.io.UnsupportedEncodingException;
-import java.util.StringTokenizer;
-
-import org.hornetq.core.protocol.stomp.HornetQStompException;
-import org.hornetq.core.protocol.stomp.StompDecoder;
-
-/**
- *
- * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
- *
- * 1.1 frames
- *
- * 1. CONNECT/STOMP(new)
- * 2. CONNECTED
- * 3. SEND
- * 4. SUBSCRIBE
- * 5. UNSUBSCRIBE
- * 6. BEGIN
- * 7. COMMIT
- * 8. ACK
- * 9. NACK (new)
- * 10. ABORT
- * 11. DISCONNECT
- * 12. MESSAGE
- * 13. RECEIPT
- * 14. ERROR
- */
-public class StompFrameFactoryV11 implements StompFrameFactory
-{
-
- @Override
-
- public ClientStompFrame createFrame(final String data)
- {
- //split the string at "\n\n"
- String[] dataFields = data.split("\n\n");
-
- StringTokenizer tokenizer = new StringTokenizer(dataFields[0], "\n");
-
- String command = tokenizer.nextToken();
- ClientStompFrame frame = new ClientStompFrameV11(command);
-
- while (tokenizer.hasMoreTokens())
- {
- String header = tokenizer.nextToken();
- String[] fields = splitHeader(header);
- frame.addHeader(fields[0], fields[1]);
- }
-
- //body (without null byte)
- if (dataFields.length == 2)
- {
- frame.setBody(dataFields[1]);
- }
- return frame;
- }
-
- //find true :
- private String[] splitHeader(String header)
- {
- StringBuffer sbKey = new StringBuffer();
- StringBuffer sbVal = new StringBuffer();
- boolean isEsc = false;
- boolean isKey = true;
-
- for (int i = 0; i < header.length(); i++)
- {
- char b = header.charAt(i);
-
- switch (b)
- {
- //escaping
- case '\\':
- {
- if (isEsc)
- {
- //this is a backslash
- if (isKey)
- {
- sbKey.append(b);
- }
- else
- {
- sbVal.append(b);
- }
- isEsc = false;
- }
- else
- {
- //begin escaping
- isEsc = true;
- }
- break;
- }
- case ':':
- {
- if (isEsc)
- {
- if (isKey)
- {
- sbKey.append(b);
- }
- else
- {
- sbVal.append(b);
- }
- isEsc = false;
- }
- else
- {
- isKey = false;
- }
- break;
- }
- case 'n':
- {
- if (isEsc)
- {
- if (isKey)
- {
- sbKey.append('\n');
- }
- else
- {
- sbVal.append('\n');
- }
- isEsc = false;
- }
- else
- {
- if (isKey)
- {
- sbKey.append(b);
- }
- else
- {
- sbVal.append(b);
- }
- }
- break;
- }
- default:
- {
- if (isKey)
- {
- sbKey.append(b);
- }
- else
- {
- sbVal.append(b);
- }
- }
- }
- }
- String[] result = new String[2];
- result[0] = sbKey.toString();
- result[1] = sbVal.toString();
-
- return result;
- }
-
- @Override
- public ClientStompFrame newFrame(String command)
- {
- return new ClientStompFrameV11(command);
- }
-
-}
Copied:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV11.java
(from rev 11517,
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV11.java)
===================================================================
---
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV11.java
(rev 0)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV11.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat 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.hornetq.tests.integration.stomp.util;
+
+import java.io.UnsupportedEncodingException;
+import java.util.StringTokenizer;
+
+import org.hornetq.core.protocol.stomp.HornetQStompException;
+import org.hornetq.core.protocol.stomp.StompDecoder;
+
+/**
+ *
+ * @author <a href="mailto:hgao@redhat.com">Howard Gao</a>
+ *
+ * 1.1 frames
+ *
+ * 1. CONNECT/STOMP(new)
+ * 2. CONNECTED
+ * 3. SEND
+ * 4. SUBSCRIBE
+ * 5. UNSUBSCRIBE
+ * 6. BEGIN
+ * 7. COMMIT
+ * 8. ACK
+ * 9. NACK (new)
+ * 10. ABORT
+ * 11. DISCONNECT
+ * 12. MESSAGE
+ * 13. RECEIPT
+ * 14. ERROR
+ */
+public class StompFrameFactoryV11 implements StompFrameFactory
+{
+
+ @Override
+
+ public ClientStompFrame createFrame(final String data)
+ {
+ //split the string at "\n\n"
+ String[] dataFields = data.split("\n\n");
+
+ StringTokenizer tokenizer = new StringTokenizer(dataFields[0], "\n");
+
+ String command = tokenizer.nextToken();
+ ClientStompFrame frame = new ClientStompFrameV11(command);
+
+ while (tokenizer.hasMoreTokens())
+ {
+ String header = tokenizer.nextToken();
+ String[] fields = splitHeader(header);
+ frame.addHeader(fields[0], fields[1]);
+ }
+
+ //body (without null byte)
+ if (dataFields.length == 2)
+ {
+ frame.setBody(dataFields[1]);
+ }
+ return frame;
+ }
+
+ //find true :
+ private String[] splitHeader(String header)
+ {
+ StringBuffer sbKey = new StringBuffer();
+ StringBuffer sbVal = new StringBuffer();
+ boolean isEsc = false;
+ boolean isKey = true;
+
+ for (int i = 0; i < header.length(); i++)
+ {
+ char b = header.charAt(i);
+
+ switch (b)
+ {
+ //escaping
+ case '\\':
+ {
+ if (isEsc)
+ {
+ //this is a backslash
+ if (isKey)
+ {
+ sbKey.append(b);
+ }
+ else
+ {
+ sbVal.append(b);
+ }
+ isEsc = false;
+ }
+ else
+ {
+ //begin escaping
+ isEsc = true;
+ }
+ break;
+ }
+ case ':':
+ {
+ if (isEsc)
+ {
+ if (isKey)
+ {
+ sbKey.append(b);
+ }
+ else
+ {
+ sbVal.append(b);
+ }
+ isEsc = false;
+ }
+ else
+ {
+ isKey = false;
+ }
+ break;
+ }
+ case 'n':
+ {
+ if (isEsc)
+ {
+ if (isKey)
+ {
+ sbKey.append('\n');
+ }
+ else
+ {
+ sbVal.append('\n');
+ }
+ isEsc = false;
+ }
+ else
+ {
+ if (isKey)
+ {
+ sbKey.append(b);
+ }
+ else
+ {
+ sbVal.append(b);
+ }
+ }
+ break;
+ }
+ default:
+ {
+ if (isKey)
+ {
+ sbKey.append(b);
+ }
+ else
+ {
+ sbVal.append(b);
+ }
+ }
+ }
+ }
+ String[] result = new String[2];
+ result[0] = sbKey.toString();
+ result[1] = sbVal.toString();
+
+ return result;
+ }
+
+ @Override
+ public ClientStompFrame newFrame(String command)
+ {
+ return new ClientStompFrameV11(command);
+ }
+
+}
Deleted:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestBase2.java
===================================================================
---
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestBase2.java 2011-10-12
02:27:00 UTC (rev 11517)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestBase2.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -1,188 +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.hornetq.tests.integration.stomp.v11;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.jms.BytesMessage;
-import javax.jms.Connection;
-import javax.jms.ConnectionFactory;
-import javax.jms.Destination;
-import javax.jms.MessageProducer;
-import javax.jms.Queue;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-import javax.jms.Topic;
-
-import org.hornetq.api.core.TransportConfiguration;
-import org.hornetq.core.config.Configuration;
-import org.hornetq.core.logging.Logger;
-import org.hornetq.core.remoting.impl.invm.InVMAcceptorFactory;
-import org.hornetq.core.remoting.impl.invm.InVMConnectorFactory;
-import org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory;
-import org.hornetq.core.remoting.impl.netty.TransportConstants;
-import org.hornetq.core.server.HornetQServer;
-import org.hornetq.core.server.HornetQServers;
-import org.hornetq.jms.client.HornetQJMSConnectionFactory;
-import org.hornetq.jms.server.JMSServerManager;
-import org.hornetq.jms.server.config.JMSConfiguration;
-import org.hornetq.jms.server.config.impl.JMSConfigurationImpl;
-import org.hornetq.jms.server.config.impl.JMSQueueConfigurationImpl;
-import org.hornetq.jms.server.config.impl.TopicConfigurationImpl;
-import org.hornetq.jms.server.impl.JMSServerManagerImpl;
-import org.hornetq.spi.core.protocol.ProtocolType;
-import org.hornetq.tests.unit.util.InVMContext;
-import org.hornetq.tests.util.UnitTestCase;
-
-public abstract class StompTestBase2 extends UnitTestCase
-{
- private static final transient Logger log = Logger.getLogger(StompTestBase2.class);
-
- protected String hostname = "127.0.0.1";
-
- protected int port = 61613;
-
- private ConnectionFactory connectionFactory;
-
- private Connection connection;
-
- protected Session session;
-
- protected Queue queue;
-
- protected Topic topic;
-
- protected JMSServerManager server;
-
- protected String defUser = "brianm";
-
- protected String defPass = "wombats";
-
-
-
- // Implementation methods
- // -------------------------------------------------------------------------
- protected void setUp() throws Exception
- {
- super.setUp();
-
- server = createServer();
- server.start();
- connectionFactory = createConnectionFactory();
-
- connection = connectionFactory.createConnection();
- session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- queue = session.createQueue(getQueueName());
- topic = session.createTopic(getTopicName());
- connection.start();
- }
-
- /**
- * @return
- * @throws Exception
- */
- protected JMSServerManager createServer() throws Exception
- {
- Configuration config = createBasicConfig();
- config.setSecurityEnabled(false);
- config.setPersistenceEnabled(false);
-
- Map<String, Object> params = new HashMap<String, Object>();
- params.put(TransportConstants.PROTOCOL_PROP_NAME, ProtocolType.STOMP.toString());
- params.put(TransportConstants.PORT_PROP_NAME,
TransportConstants.DEFAULT_STOMP_PORT);
- TransportConfiguration stompTransport = new
TransportConfiguration(NettyAcceptorFactory.class.getName(), params);
- config.getAcceptorConfigurations().add(stompTransport);
- config.getAcceptorConfigurations().add(new
TransportConfiguration(InVMAcceptorFactory.class.getName()));
- HornetQServer hornetQServer = HornetQServers.newHornetQServer(config, defUser,
defPass);
-
- JMSConfiguration jmsConfig = new JMSConfigurationImpl();
- jmsConfig.getQueueConfigurations()
- .add(new JMSQueueConfigurationImpl(getQueueName(), null, false,
getQueueName()));
- jmsConfig.getTopicConfigurations().add(new TopicConfigurationImpl(getTopicName(),
getTopicName()));
- server = new JMSServerManagerImpl(hornetQServer, jmsConfig);
- server.setContext(new InVMContext());
- return server;
- }
-
- protected void tearDown() throws Exception
- {
- connection.close();
-
- server.stop();
-
- super.tearDown();
- }
-
- protected ConnectionFactory createConnectionFactory()
- {
- return new HornetQJMSConnectionFactory(false, new
TransportConfiguration(InVMConnectorFactory.class.getName()));
- }
-
- protected String getQueueName()
- {
- return "test";
- }
-
- protected String getQueuePrefix()
- {
- return "jms.queue.";
- }
-
- protected String getTopicName()
- {
- return "testtopic";
- }
-
- protected String getTopicPrefix()
- {
- return "jms.topic.";
- }
-
- public void sendMessage(String msg) throws Exception
- {
- sendMessage(msg, queue);
- }
-
- public void sendMessage(String msg, Destination destination) throws Exception
- {
- MessageProducer producer = session.createProducer(destination);
- TextMessage message = session.createTextMessage(msg);
- producer.send(message);
- }
-
- public void sendMessage(byte[] data, Destination destination) throws Exception
- {
- sendMessage(data, "foo", "xyz", destination);
- }
-
- public void sendMessage(String msg, String propertyName, String propertyValue) throws
Exception
- {
- sendMessage(msg.getBytes("UTF-8"), propertyName, propertyValue, queue);
- }
-
- public void sendMessage(byte[] data, String propertyName, String propertyValue,
Destination destination) throws Exception
- {
- MessageProducer producer = session.createProducer(destination);
- BytesMessage message = session.createBytesMessage();
- message.setStringProperty(propertyName, propertyValue);
- message.writeBytes(data);
- producer.send(message);
- }
-
-}
Copied:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestBase2.java
(from rev 11517,
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestBase2.java)
===================================================================
---
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestBase2.java
(rev 0)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestBase2.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,188 @@
+/**
+ *
+ * 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.hornetq.tests.integration.stomp.v11;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jms.BytesMessage;
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.Destination;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+
+import org.hornetq.api.core.TransportConfiguration;
+import org.hornetq.core.config.Configuration;
+import org.hornetq.core.logging.Logger;
+import org.hornetq.core.remoting.impl.invm.InVMAcceptorFactory;
+import org.hornetq.core.remoting.impl.invm.InVMConnectorFactory;
+import org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory;
+import org.hornetq.core.remoting.impl.netty.TransportConstants;
+import org.hornetq.core.server.HornetQServer;
+import org.hornetq.core.server.HornetQServers;
+import org.hornetq.jms.client.HornetQJMSConnectionFactory;
+import org.hornetq.jms.server.JMSServerManager;
+import org.hornetq.jms.server.config.JMSConfiguration;
+import org.hornetq.jms.server.config.impl.JMSConfigurationImpl;
+import org.hornetq.jms.server.config.impl.JMSQueueConfigurationImpl;
+import org.hornetq.jms.server.config.impl.TopicConfigurationImpl;
+import org.hornetq.jms.server.impl.JMSServerManagerImpl;
+import org.hornetq.spi.core.protocol.ProtocolType;
+import org.hornetq.tests.unit.util.InVMContext;
+import org.hornetq.tests.util.UnitTestCase;
+
+public abstract class StompTestBase2 extends UnitTestCase
+{
+ private static final transient Logger log = Logger.getLogger(StompTestBase2.class);
+
+ protected String hostname = "127.0.0.1";
+
+ protected int port = 61613;
+
+ private ConnectionFactory connectionFactory;
+
+ private Connection connection;
+
+ protected Session session;
+
+ protected Queue queue;
+
+ protected Topic topic;
+
+ protected JMSServerManager server;
+
+ protected String defUser = "brianm";
+
+ protected String defPass = "wombats";
+
+
+
+ // Implementation methods
+ // -------------------------------------------------------------------------
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ server = createServer();
+ server.start();
+ connectionFactory = createConnectionFactory();
+
+ connection = connectionFactory.createConnection();
+ session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ queue = session.createQueue(getQueueName());
+ topic = session.createTopic(getTopicName());
+ connection.start();
+ }
+
+ /**
+ * @return
+ * @throws Exception
+ */
+ protected JMSServerManager createServer() throws Exception
+ {
+ Configuration config = createBasicConfig();
+ config.setSecurityEnabled(false);
+ config.setPersistenceEnabled(false);
+
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.put(TransportConstants.PROTOCOL_PROP_NAME, ProtocolType.STOMP.toString());
+ params.put(TransportConstants.PORT_PROP_NAME,
TransportConstants.DEFAULT_STOMP_PORT);
+ TransportConfiguration stompTransport = new
TransportConfiguration(NettyAcceptorFactory.class.getName(), params);
+ config.getAcceptorConfigurations().add(stompTransport);
+ config.getAcceptorConfigurations().add(new
TransportConfiguration(InVMAcceptorFactory.class.getName()));
+ HornetQServer hornetQServer = HornetQServers.newHornetQServer(config, defUser,
defPass);
+
+ JMSConfiguration jmsConfig = new JMSConfigurationImpl();
+ jmsConfig.getQueueConfigurations()
+ .add(new JMSQueueConfigurationImpl(getQueueName(), null, false,
getQueueName()));
+ jmsConfig.getTopicConfigurations().add(new TopicConfigurationImpl(getTopicName(),
getTopicName()));
+ server = new JMSServerManagerImpl(hornetQServer, jmsConfig);
+ server.setContext(new InVMContext());
+ return server;
+ }
+
+ protected void tearDown() throws Exception
+ {
+ connection.close();
+
+ server.stop();
+
+ super.tearDown();
+ }
+
+ protected ConnectionFactory createConnectionFactory()
+ {
+ return new HornetQJMSConnectionFactory(false, new
TransportConfiguration(InVMConnectorFactory.class.getName()));
+ }
+
+ protected String getQueueName()
+ {
+ return "test";
+ }
+
+ protected String getQueuePrefix()
+ {
+ return "jms.queue.";
+ }
+
+ protected String getTopicName()
+ {
+ return "testtopic";
+ }
+
+ protected String getTopicPrefix()
+ {
+ return "jms.topic.";
+ }
+
+ public void sendMessage(String msg) throws Exception
+ {
+ sendMessage(msg, queue);
+ }
+
+ public void sendMessage(String msg, Destination destination) throws Exception
+ {
+ MessageProducer producer = session.createProducer(destination);
+ TextMessage message = session.createTextMessage(msg);
+ producer.send(message);
+ }
+
+ public void sendMessage(byte[] data, Destination destination) throws Exception
+ {
+ sendMessage(data, "foo", "xyz", destination);
+ }
+
+ public void sendMessage(String msg, String propertyName, String propertyValue) throws
Exception
+ {
+ sendMessage(msg.getBytes("UTF-8"), propertyName, propertyValue, queue);
+ }
+
+ public void sendMessage(byte[] data, String propertyName, String propertyValue,
Destination destination) throws Exception
+ {
+ MessageProducer producer = session.createProducer(destination);
+ BytesMessage message = session.createBytesMessage();
+ message.setStringProperty(propertyName, propertyValue);
+ message.writeBytes(data);
+ producer.send(message);
+ }
+
+}
Deleted:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestV11.java
===================================================================
---
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestV11.java 2011-10-12
02:27:00 UTC (rev 11517)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestV11.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -1,2021 +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.hornetq.tests.integration.stomp.v11;
-
-import java.io.IOException;
-import java.nio.channels.ClosedChannelException;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import javax.jms.BytesMessage;
-import javax.jms.DeliveryMode;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageListener;
-import javax.jms.MessageProducer;
-import javax.jms.TextMessage;
-
-import junit.framework.Assert;
-
-import org.hornetq.core.logging.Logger;
-import org.hornetq.tests.integration.stomp.util.ClientStompFrame;
-import org.hornetq.tests.integration.stomp.util.StompClientConnection;
-import org.hornetq.tests.integration.stomp.util.StompClientConnectionFactory;
-import org.hornetq.tests.integration.stomp.util.StompClientConnectionV11;
-
-/*
- *
- */
-public class StompTestV11 extends StompTestBase2
-{
- private static final transient Logger log = Logger.getLogger(StompTestV11.class);
-
- private StompClientConnection connV11;
-
- protected void setUp() throws Exception
- {
- super.setUp();
- connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
- }
-
- protected void tearDown() throws Exception
- {
- if (connV11.isConnected())
- {
- connV11.disconnect();
- }
- super.tearDown();
- }
-
- public void testConnection() throws Exception
- {
- StompClientConnection connection =
StompClientConnectionFactory.createClientConnection("1.0", hostname, port);
-
- connection.connect(defUser, defPass);
-
- assertTrue(connection.isConnected());
-
- assertEquals("1.0", connection.getVersion());
-
- connection.disconnect();
-
- connection = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
-
- connection.connect(defUser, defPass);
-
- assertTrue(connection.isConnected());
-
- assertEquals("1.1", connection.getVersion());
-
- connection.disconnect();
-
- connection = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
-
- connection.connect();
-
- assertFalse(connection.isConnected());
-
- //new way of connection
- StompClientConnectionV11 conn = (StompClientConnectionV11)
StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
- conn.connect1(defUser, defPass);
-
- assertTrue(conn.isConnected());
-
- conn.disconnect();
- }
-
- public void testNegotiation() throws Exception
- {
- // case 1 accept-version absent. It is a 1.0 connect
- ClientStompFrame frame = connV11.createFrame("CONNECT");
- frame.addHeader("host", "127.0.0.1");
- frame.addHeader("login", this.defUser);
- frame.addHeader("passcode", this.defPass);
-
- ClientStompFrame reply = connV11.sendFrame(frame);
-
- assertEquals("CONNECTED", reply.getCommand());
-
- //reply headers: version, session, server
- assertEquals(null, reply.getHeader("version"));
-
- connV11.disconnect();
-
- // case 2 accept-version=1.0, result: 1.0
- connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
- frame = connV11.createFrame("CONNECT");
- frame.addHeader("accept-version", "1.0");
- frame.addHeader("host", "127.0.0.1");
- frame.addHeader("login", this.defUser);
- frame.addHeader("passcode", this.defPass);
-
- reply = connV11.sendFrame(frame);
-
- assertEquals("CONNECTED", reply.getCommand());
-
- //reply headers: version, session, server
- assertEquals("1.0", reply.getHeader("version"));
-
- connV11.disconnect();
-
- // case 3 accept-version=1.1, result: 1.1
- connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
- frame = connV11.createFrame("CONNECT");
- frame.addHeader("accept-version", "1.1");
- frame.addHeader("host", "127.0.0.1");
- frame.addHeader("login", this.defUser);
- frame.addHeader("passcode", this.defPass);
-
- reply = connV11.sendFrame(frame);
-
- assertEquals("CONNECTED", reply.getCommand());
-
- //reply headers: version, session, server
- assertEquals("1.1", reply.getHeader("version"));
-
- connV11.disconnect();
-
- // case 4 accept-version=1.0,1.1,1.2, result 1.1
- connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
- frame = connV11.createFrame("CONNECT");
- frame.addHeader("accept-version", "1.0,1.1,1.2");
- frame.addHeader("host", "127.0.0.1");
- frame.addHeader("login", this.defUser);
- frame.addHeader("passcode", this.defPass);
-
- reply = connV11.sendFrame(frame);
-
- assertEquals("CONNECTED", reply.getCommand());
-
- //reply headers: version, session, server
- assertEquals("1.1", reply.getHeader("version"));
-
- connV11.disconnect();
-
- // case 5 accept-version=1.2, result error
- connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
- frame = connV11.createFrame("CONNECT");
- frame.addHeader("accept-version", "1.2");
- frame.addHeader("host", "127.0.0.1");
- frame.addHeader("login", this.defUser);
- frame.addHeader("passcode", this.defPass);
-
- reply = connV11.sendFrame(frame);
-
- assertEquals("ERROR", reply.getCommand());
-
- System.out.println("Got error frame " + reply);
-
- }
-
- public void testSendAndReceive() throws Exception
- {
- connV11.connect(defUser, defPass);
- ClientStompFrame frame = connV11.createFrame("SEND");
- frame.addHeader("destination", getQueuePrefix() + getQueueName());
- frame.addHeader("content-type", "text/plain");
- frame.setBody("Hello World 1!");
-
- ClientStompFrame response = connV11.sendFrame(frame);
-
- assertNull(response);
-
- frame.addHeader("receipt", "1234");
- frame.setBody("Hello World 2!");
-
- response = connV11.sendFrame(frame);
-
- assertNotNull(response);
-
- assertEquals("RECEIPT", response.getCommand());
-
- assertEquals("1234", response.getHeader("receipt-id"));
-
- //subscribe
- StompClientConnection newConn =
StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
- newConn.connect(defUser, defPass);
-
- ClientStompFrame subFrame = newConn.createFrame("SUBSCRIBE");
- subFrame.addHeader("id", "a-sub");
- subFrame.addHeader("destination", getQueuePrefix() + getQueueName());
- subFrame.addHeader("ack", "auto");
-
- newConn.sendFrame(subFrame);
-
- frame = newConn.receiveFrame();
-
- System.out.println("received " + frame);
-
- assertEquals("MESSAGE", frame.getCommand());
-
- assertEquals("a-sub", frame.getHeader("subscription"));
-
- assertNotNull(frame.getHeader("message-id"));
-
- assertEquals(getQueuePrefix() + getQueueName(),
frame.getHeader("destination"));
-
- assertEquals("Hello World 1!", frame.getBody());
-
- frame = newConn.receiveFrame();
-
- System.out.println("received " + frame);
-
- //unsub
- ClientStompFrame unsubFrame = newConn.createFrame("UNSUBSCRIBE");
- unsubFrame.addHeader("id", "a-sub");
-
- newConn.disconnect();
- }
-
- public void testHeaderContentType() throws Exception
- {
- connV11.connect(defUser, defPass);
- ClientStompFrame frame = connV11.createFrame("SEND");
- frame.addHeader("destination", getQueuePrefix() + getQueueName());
- frame.addHeader("content-type", "application/xml");
- frame.setBody("Hello World 1!");
-
- connV11.sendFrame(frame);
-
- //subscribe
- StompClientConnection newConn =
StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
- newConn.connect(defUser, defPass);
-
- ClientStompFrame subFrame = newConn.createFrame("SUBSCRIBE");
- subFrame.addHeader("id", "a-sub");
- subFrame.addHeader("destination", getQueuePrefix() + getQueueName());
- subFrame.addHeader("ack", "auto");
-
- newConn.sendFrame(subFrame);
-
- frame = newConn.receiveFrame();
-
- System.out.println("received " + frame);
-
- assertEquals("MESSAGE", frame.getCommand());
-
- assertEquals("application/xml",
frame.getHeader("content-type"));
-
- //unsub
- ClientStompFrame unsubFrame = newConn.createFrame("UNSUBSCRIBE");
- unsubFrame.addHeader("id", "a-sub");
-
- newConn.disconnect();
- }
-
- public void testHeaderContentLength() throws Exception
- {
- connV11.connect(defUser, defPass);
- ClientStompFrame frame = connV11.createFrame("SEND");
-
- String body = "Hello World 1!";
- String cLen = String.valueOf(body.getBytes("UTF-8").length);
-
- frame.addHeader("destination", getQueuePrefix() + getQueueName());
- frame.addHeader("content-type", "application/xml");
- frame.addHeader("content-length", cLen);
- frame.setBody(body + "extra");
-
- connV11.sendFrame(frame);
-
- //subscribe
- StompClientConnection newConn =
StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
- newConn.connect(defUser, defPass);
-
- ClientStompFrame subFrame = newConn.createFrame("SUBSCRIBE");
- subFrame.addHeader("id", "a-sub");
- subFrame.addHeader("destination", getQueuePrefix() + getQueueName());
- subFrame.addHeader("ack", "auto");
-
- newConn.sendFrame(subFrame);
-
- frame = newConn.receiveFrame();
-
- System.out.println("received " + frame);
-
- assertEquals("MESSAGE", frame.getCommand());
-
- assertEquals(cLen, frame.getHeader("content-length"));
-
- //unsub
- ClientStompFrame unsubFrame = newConn.createFrame("UNSUBSCRIBE");
- unsubFrame.addHeader("id", "a-sub");
-
- newConn.disconnect();
- }
-
- public void testHeaderEncoding() throws Exception
- {
- connV11.connect(defUser, defPass);
- ClientStompFrame frame = connV11.createFrame("SEND");
-
- String body = "Hello World 1!";
- String cLen = String.valueOf(body.getBytes("UTF-8").length);
-
- frame.addHeader("destination", getQueuePrefix() + getQueueName());
- frame.addHeader("content-type", "application/xml");
- frame.addHeader("content-length", cLen);
- String hKey = "special-header\\\\\\n\\:";
- String hVal = "\\:\\\\\\ngood";
- frame.addHeader(hKey, hVal);
-
- System.out.println("key: |" + hKey + "| val: |" + hVal);
-
- frame.setBody(body);
-
- connV11.sendFrame(frame);
-
- //subscribe
- StompClientConnection newConn =
StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
- newConn.connect(defUser, defPass);
-
- ClientStompFrame subFrame = newConn.createFrame("SUBSCRIBE");
- subFrame.addHeader("id", "a-sub");
- subFrame.addHeader("destination", getQueuePrefix() + getQueueName());
- subFrame.addHeader("ack", "auto");
-
- newConn.sendFrame(subFrame);
-
- frame = newConn.receiveFrame();
-
- System.out.println("received " + frame);
-
- assertEquals("MESSAGE", frame.getCommand());
-
- String value = frame.getHeader("special-header" + "\\" +
"\n" + ":");
-
- assertEquals(":" + "\\" + "\n" + "good",
value);
-
- //unsub
- ClientStompFrame unsubFrame = newConn.createFrame("UNSUBSCRIBE");
- unsubFrame.addHeader("id", "a-sub");
-
- newConn.disconnect();
- }
-
- public void testHeartBeat() throws Exception
- {
- //no heart beat at all if heat-beat absent
- ClientStompFrame frame = connV11.createFrame("CONNECT");
- frame.addHeader("host", "127.0.0.1");
- frame.addHeader("login", this.defUser);
- frame.addHeader("passcode", this.defPass);
-
- ClientStompFrame reply = connV11.sendFrame(frame);
-
- assertEquals("CONNECTED", reply.getCommand());
-
- Thread.sleep(5000);
-
- assertEquals(0, connV11.getFrameQueueSize());
-
- connV11.disconnect();
-
- //no heart beat for (0,0)
- connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
- frame = connV11.createFrame("CONNECT");
- frame.addHeader("host", "127.0.0.1");
- frame.addHeader("login", this.defUser);
- frame.addHeader("passcode", this.defPass);
- frame.addHeader("heart-beat", "0,0");
- frame.addHeader("accept-version", "1.0,1.1");
-
- reply = connV11.sendFrame(frame);
-
- assertEquals("CONNECTED", reply.getCommand());
-
- assertEquals("0,0", reply.getHeader("heart-beat"));
-
- Thread.sleep(5000);
-
- assertEquals(0, connV11.getFrameQueueSize());
-
- connV11.disconnect();
-
- //heart-beat (1,0), should receive a min client ping accepted by server
- connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
- frame = connV11.createFrame("CONNECT");
- frame.addHeader("host", "127.0.0.1");
- frame.addHeader("login", this.defUser);
- frame.addHeader("passcode", this.defPass);
- frame.addHeader("heart-beat", "1,0");
- frame.addHeader("accept-version", "1.0,1.1");
-
- reply = connV11.sendFrame(frame);
-
- assertEquals("CONNECTED", reply.getCommand());
-
- assertEquals("0,500", reply.getHeader("heart-beat"));
-
- Thread.sleep(2000);
-
- //now server side should be disconnected because we didn't send ping for 2 sec
- frame = connV11.createFrame("SEND");
- frame.addHeader("destination", getQueuePrefix() + getQueueName());
- frame.addHeader("content-type", "text/plain");
- frame.setBody("Hello World");
-
- //send will fail
- try
- {
- connV11.sendFrame(frame);
- fail("connection should have been destroyed by now");
- }
- catch (IOException e)
- {
- //ignore
- }
-
- //heart-beat (1,0), start a ping, then send a message, should be ok.
- connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
- frame = connV11.createFrame("CONNECT");
- frame.addHeader("host", "127.0.0.1");
- frame.addHeader("login", this.defUser);
- frame.addHeader("passcode", this.defPass);
- frame.addHeader("heart-beat", "1,0");
- frame.addHeader("accept-version", "1.0,1.1");
-
- reply = connV11.sendFrame(frame);
-
- assertEquals("CONNECTED", reply.getCommand());
-
- assertEquals("0,500", reply.getHeader("heart-beat"));
-
- System.out.println("========== start pinger!");
-
- connV11.startPinger(500);
-
- Thread.sleep(2000);
-
- //now server side should be disconnected because we didn't send ping for 2 sec
- frame = connV11.createFrame("SEND");
- frame.addHeader("destination", getQueuePrefix() + getQueueName());
- frame.addHeader("content-type", "text/plain");
- frame.setBody("Hello World");
-
- //send will be ok
- connV11.sendFrame(frame);
-
- connV11.stopPinger();
-
- connV11.disconnect();
-
- }
-
- //server ping
- public void testHeartBeat2() throws Exception
- {
- //heart-beat (1,1)
- ClientStompFrame frame = connV11.createFrame("CONNECT");
- frame.addHeader("host", "127.0.0.1");
- frame.addHeader("login", this.defUser);
- frame.addHeader("passcode", this.defPass);
- frame.addHeader("heart-beat", "1,1");
- frame.addHeader("accept-version", "1.0,1.1");
-
- ClientStompFrame reply = connV11.sendFrame(frame);
-
- assertEquals("CONNECTED", reply.getCommand());
-
- assertEquals("500,500", reply.getHeader("heart-beat"));
-
- connV11.disconnect();
-
- //heart-beat (500,1000)
- connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
- frame = connV11.createFrame("CONNECT");
- frame.addHeader("host", "127.0.0.1");
- frame.addHeader("login", this.defUser);
- frame.addHeader("passcode", this.defPass);
- frame.addHeader("heart-beat", "500,1000");
- frame.addHeader("accept-version", "1.0,1.1");
-
- reply = connV11.sendFrame(frame);
-
- assertEquals("CONNECTED", reply.getCommand());
-
- assertEquals("1000,500", reply.getHeader("heart-beat"));
-
- System.out.println("========== start pinger!");
-
- connV11.startPinger(500);
-
- Thread.sleep(10000);
-
- //now check the frame size
- int size = connV11.getFrameQueueSize();
-
- System.out.println("ping received: " + size);
-
- assertTrue(size > 5);
-
- //now server side should be disconnected because we didn't send ping for 2 sec
- frame = connV11.createFrame("SEND");
- frame.addHeader("destination", getQueuePrefix() + getQueueName());
- frame.addHeader("content-type", "text/plain");
- frame.setBody("Hello World");
-
- //send will be ok
- connV11.sendFrame(frame);
-
- connV11.stopPinger();
-
- connV11.disconnect();
-
- }
-
- public void testNack() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- subscribe(connV11, "sub1", "client");
-
- sendMessage(getName());
-
- ClientStompFrame frame = connV11.receiveFrame();
-
- String messageID = frame.getHeader("message-id");
-
- System.out.println("Received message with id " + messageID);
-
- nack(connV11, "sub1", messageID);
-
- unsubscribe(connV11, "sub1");
-
- connV11.disconnect();
-
- //Nack makes the message be dropped.
- MessageConsumer consumer = session.createConsumer(queue);
- Message message = consumer.receive(1000);
- Assert.assertNull(message);
- }
-
- public void testNackWithWrongSubId() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- subscribe(connV11, "sub1", "client");
-
- sendMessage(getName());
-
- ClientStompFrame frame = connV11.receiveFrame();
-
- String messageID = frame.getHeader("message-id");
-
- System.out.println("Received message with id " + messageID);
-
- nack(connV11, "sub2", messageID);
-
- ClientStompFrame error = connV11.receiveFrame();
-
- System.out.println("Receiver error: " + error);
-
- unsubscribe(connV11, "sub1");
-
- connV11.disconnect();
-
- //message should be still there
- MessageConsumer consumer = session.createConsumer(queue);
- Message message = consumer.receive(1000);
- Assert.assertNotNull(message);
- }
-
- public void testNackWithWrongMessageId() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- subscribe(connV11, "sub1", "client");
-
- sendMessage(getName());
-
- ClientStompFrame frame = connV11.receiveFrame();
-
- String messageID = frame.getHeader("message-id");
-
- System.out.println("Received message with id " + messageID);
-
- nack(connV11, "sub2", "someother");
-
- ClientStompFrame error = connV11.receiveFrame();
-
- System.out.println("Receiver error: " + error);
-
- unsubscribe(connV11, "sub1");
-
- connV11.disconnect();
-
- //message should still there
- MessageConsumer consumer = session.createConsumer(queue);
- Message message = consumer.receive(1000);
- Assert.assertNotNull(message);
- }
-
-
- public void testAck() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- subscribe(connV11, "sub1", "client");
-
- sendMessage(getName());
-
- ClientStompFrame frame = connV11.receiveFrame();
-
- String messageID = frame.getHeader("message-id");
-
- System.out.println("Received message with id " + messageID);
-
- ack(connV11, "sub1", messageID, null);
-
- unsubscribe(connV11, "sub1");
-
- connV11.disconnect();
-
- //Nack makes the message be dropped.
- MessageConsumer consumer = session.createConsumer(queue);
- Message message = consumer.receive(1000);
- Assert.assertNull(message);
- }
-
- public void testAckWithWrongSubId() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- subscribe(connV11, "sub1", "client");
-
- sendMessage(getName());
-
- ClientStompFrame frame = connV11.receiveFrame();
-
- String messageID = frame.getHeader("message-id");
-
- System.out.println("Received message with id " + messageID);
-
- ack(connV11, "sub2", messageID, null);
-
- ClientStompFrame error = connV11.receiveFrame();
-
- System.out.println("Receiver error: " + error);
-
- unsubscribe(connV11, "sub1");
-
- connV11.disconnect();
-
- //message should be still there
- MessageConsumer consumer = session.createConsumer(queue);
- Message message = consumer.receive(1000);
- Assert.assertNotNull(message);
- }
-
- public void testAckWithWrongMessageId() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- subscribe(connV11, "sub1", "client");
-
- sendMessage(getName());
-
- ClientStompFrame frame = connV11.receiveFrame();
-
- String messageID = frame.getHeader("message-id");
-
- System.out.println("Received message with id " + messageID);
-
- ack(connV11, "sub2", "someother", null);
-
- ClientStompFrame error = connV11.receiveFrame();
-
- System.out.println("Receiver error: " + error);
-
- unsubscribe(connV11, "sub1");
-
- connV11.disconnect();
-
- //message should still there
- MessageConsumer consumer = session.createConsumer(queue);
- Message message = consumer.receive(1000);
- Assert.assertNotNull(message);
- }
-
- public void testErrorWithReceipt() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- subscribe(connV11, "sub1", "client");
-
- sendMessage(getName());
-
- ClientStompFrame frame = connV11.receiveFrame();
-
- String messageID = frame.getHeader("message-id");
-
- System.out.println("Received message with id " + messageID);
-
- ClientStompFrame ackFrame = connV11.createFrame("ACK");
- //give it a wrong sub id
- ackFrame.addHeader("subscription", "sub2");
- ackFrame.addHeader("message-id", messageID);
- ackFrame.addHeader("receipt", "answer-me");
-
- ClientStompFrame error = connV11.sendFrame(ackFrame);
-
- System.out.println("Receiver error: " + error);
-
- assertEquals("ERROR", error.getCommand());
-
- assertEquals("answer-me", error.getHeader("receipt-id"));
-
- unsubscribe(connV11, "sub1");
-
- connV11.disconnect();
-
- //message should still there
- MessageConsumer consumer = session.createConsumer(queue);
- Message message = consumer.receive(1000);
- Assert.assertNotNull(message);
- }
-
- public void testErrorWithReceipt2() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- subscribe(connV11, "sub1", "client");
-
- sendMessage(getName());
-
- ClientStompFrame frame = connV11.receiveFrame();
-
- String messageID = frame.getHeader("message-id");
-
- System.out.println("Received message with id " + messageID);
-
- ClientStompFrame ackFrame = connV11.createFrame("ACK");
- //give it a wrong sub id
- ackFrame.addHeader("subscription", "sub1");
- ackFrame.addHeader("message-id", String.valueOf(Long.valueOf(messageID) +
1));
- ackFrame.addHeader("receipt", "answer-me");
-
- ClientStompFrame error = connV11.sendFrame(ackFrame);
-
- System.out.println("Receiver error: " + error);
-
- assertEquals("ERROR", error.getCommand());
-
- assertEquals("answer-me", error.getHeader("receipt-id"));
-
- unsubscribe(connV11, "sub1");
-
- connV11.disconnect();
-
- //message should still there
- MessageConsumer consumer = session.createConsumer(queue);
- Message message = consumer.receive(1000);
- Assert.assertNotNull(message);
- }
-
- public void testAckModeClient() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- subscribe(connV11, "sub1", "client");
-
- int num = 50;
- //send a bunch of messages
- for (int i = 0; i < num; i++)
- {
- this.sendMessage("client-ack" + i);
- }
-
- ClientStompFrame frame = null;
-
- for (int i = 0; i < num; i++)
- {
- frame = connV11.receiveFrame();
- assertNotNull(frame);
- }
-
- //ack the last
- this.ack(connV11, "sub1", frame);
-
- unsubscribe(connV11, "sub1");
-
- connV11.disconnect();
-
- //no messages can be received.
- MessageConsumer consumer = session.createConsumer(queue);
- Message message = consumer.receive(1000);
- Assert.assertNull(message);
- }
-
- public void testAckModeClient2() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- subscribe(connV11, "sub1", "client");
-
- int num = 50;
- //send a bunch of messages
- for (int i = 0; i < num; i++)
- {
- this.sendMessage("client-ack" + i);
- }
-
- ClientStompFrame frame = null;
-
- for (int i = 0; i < num; i++)
- {
- frame = connV11.receiveFrame();
- assertNotNull(frame);
-
- //ack the 49th
- if (i == num - 2)
- {
- this.ack(connV11, "sub1", frame);
- }
- }
-
- unsubscribe(connV11, "sub1");
-
- connV11.disconnect();
-
- //no messages can be received.
- MessageConsumer consumer = session.createConsumer(queue);
- Message message = consumer.receive(1000);
- Assert.assertNotNull(message);
- message = consumer.receive(1000);
- Assert.assertNull(message);
- }
-
- public void testAckModeAuto() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- subscribe(connV11, "sub1", "auto");
-
- int num = 50;
- //send a bunch of messages
- for (int i = 0; i < num; i++)
- {
- this.sendMessage("auto-ack" + i);
- }
-
- ClientStompFrame frame = null;
-
- for (int i = 0; i < num; i++)
- {
- frame = connV11.receiveFrame();
- assertNotNull(frame);
- }
-
- unsubscribe(connV11, "sub1");
-
- connV11.disconnect();
-
- //no messages can be received.
- MessageConsumer consumer = session.createConsumer(queue);
- Message message = consumer.receive(1000);
- Assert.assertNull(message);
- }
-
- public void testAckModeClientIndividual() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- subscribe(connV11, "sub1", "client-individual");
-
- int num = 50;
- //send a bunch of messages
- for (int i = 0; i < num; i++)
- {
- this.sendMessage("client-individual-ack" + i);
- }
-
- ClientStompFrame frame = null;
-
- for (int i = 0; i < num; i++)
- {
- frame = connV11.receiveFrame();
- assertNotNull(frame);
-
- System.out.println(i + " == received: " + frame);
- //ack on even numbers
- if (i%2 == 0)
- {
- this.ack(connV11, "sub1", frame);
- }
- }
-
- unsubscribe(connV11, "sub1");
-
- connV11.disconnect();
-
- //no messages can be received.
- MessageConsumer consumer = session.createConsumer(queue);
-
- TextMessage message = null;
- for (int i = 0; i < num/2; i++)
- {
- message = (TextMessage) consumer.receive(1000);
- Assert.assertNotNull(message);
- System.out.println("Legal: " + message.getText());
- }
-
- message = (TextMessage) consumer.receive(1000);
-
- Assert.assertNull(message);
- }
-
- public void testTwoSubscribers() throws Exception
- {
- connV11.connect(defUser, defPass, "myclientid");
-
- this.subscribeTopic(connV11, "sub1", "auto", null);
-
- StompClientConnection newConn =
StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
- newConn.connect(defUser, defPass, "myclientid2");
-
- this.subscribeTopic(newConn, "sub2", "auto", null);
-
- ClientStompFrame frame = connV11.createFrame("SEND");
- frame.addHeader("destination", getTopicPrefix() + getTopicName());
-
- frame.setBody("Hello World");
-
- connV11.sendFrame(frame);
-
- // receive message from socket
- frame = connV11.receiveFrame(1000);
-
- System.out.println("received frame : " + frame);
- assertEquals("Hello World", frame.getBody());
- assertEquals("sub1", frame.getHeader("subscription"));
-
- frame = newConn.receiveFrame(1000);
-
- System.out.println("received 2 frame : " + frame);
- assertEquals("Hello World", frame.getBody());
- assertEquals("sub2", frame.getHeader("subscription"));
-
- // remove suscription
- this.unsubscribe(connV11, "sub1", true);
- this.unsubscribe(newConn, "sub2", true);
-
- connV11.disconnect();
- newConn.disconnect();
- }
-
- public void testSendAndReceiveOnDifferentConnections() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- ClientStompFrame sendFrame = connV11.createFrame("SEND");
- sendFrame.addHeader("destination", getQueuePrefix() + getQueueName());
- sendFrame.setBody("Hello World");
-
- connV11.sendFrame(sendFrame);
-
- StompClientConnection connV11_2 =
StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
- connV11_2.connect(defUser, defPass);
-
- this.subscribe(connV11_2, "sub1", "auto");
-
- ClientStompFrame frame = connV11_2.receiveFrame(2000);
-
- assertEquals("MESSAGE", frame.getCommand());
- assertEquals("Hello World", frame.getBody());
-
- connV11.disconnect();
- connV11_2.disconnect();
- }
-
- //----------------Note: tests below are adapted from StompTest
-
- public void testBeginSameTransactionTwice() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- beginTransaction(connV11, "tx1");
-
- beginTransaction(connV11, "tx1");
-
- ClientStompFrame f = connV11.receiveFrame();
- Assert.assertTrue(f.getCommand().equals("ERROR"));
- }
-
- public void testBodyWithUTF8() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- this.subscribe(connV11, getName(), "auto");
-
- String text = "A" + "\u00ea" + "\u00f1" +
"\u00fc" + "C";
- System.out.println(text);
- sendMessage(text);
-
- ClientStompFrame frame = connV11.receiveFrame();
- System.out.println(frame);
- Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
- Assert.assertNotNull(frame.getHeader("destination"));
- Assert.assertTrue(frame.getBody().equals(text));
-
- connV11.disconnect();
- }
-
- public void testClientAckNotPartOfTransaction() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- this.subscribe(connV11, getName(), "client");
-
- sendMessage(getName());
-
- ClientStompFrame frame = connV11.receiveFrame();
-
- Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
- Assert.assertNotNull(frame.getHeader("destination"));
- Assert.assertTrue(frame.getBody().equals(getName()));
- Assert.assertNotNull(frame.getHeader("message-id"));
-
- String messageID = frame.getHeader("message-id");
-
- beginTransaction(connV11, "tx1");
-
- this.ack(connV11, getName(), messageID, "tx1");
-
- abortTransaction(connV11, "tx1");
-
- frame = connV11.receiveFrame();
-
- assertNull(frame);
-
- this.unsubscribe(connV11, getName());
-
- connV11.disconnect();
- }
-
- public void testDisconnectAndError() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- this.subscribe(connV11, getName(), "client");
-
- ClientStompFrame frame = connV11.createFrame("DISCONNECT");
- frame.addHeader("receipt", "1");
-
- ClientStompFrame result = connV11.sendFrame(frame);
-
- if (result == null || (!"RECEIPT".equals(result.getCommand())) ||
(!"1".equals(result.getHeader("receipt-id"))))
- {
- fail("Disconnect failed! " + result);
- }
-
- // sending a message will result in an error
- ClientStompFrame sendFrame = connV11.createFrame("SEND");
- sendFrame.addHeader("destination", getQueuePrefix() + getQueueName());
- sendFrame.setBody("Hello World");
-
- try
- {
- connV11.sendFrame(sendFrame);
- fail("connection should have been closed by server.");
- }
- catch (ClosedChannelException e)
- {
- //ok.
- }
-
- connV11.destroy();
- }
-
- public void testDurableSubscriber() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- this.subscribe(connV11, "sub1", "client", getName());
-
- this.subscribe(connV11, "sub1", "client", getName());
-
- ClientStompFrame frame = connV11.receiveFrame();
- Assert.assertTrue(frame.getCommand().equals("ERROR"));
-
- connV11.disconnect();
- }
-
- public void testDurableSubscriberWithReconnection() throws Exception
- {
- connV11.connect(defUser, defPass, "myclientid");
-
- this.subscribeTopic(connV11, "sub1", "auto", getName());
-
- ClientStompFrame frame = connV11.createFrame("DISCONNECT");
- frame.addHeader("receipt", "1");
-
- ClientStompFrame result = connV11.sendFrame(frame);
-
- if (result == null || (!"RECEIPT".equals(result.getCommand())) ||
(!"1".equals(result.getHeader("receipt-id"))))
- {
- fail("Disconnect failed! " + result);
- }
-
- // send the message when the durable subscriber is disconnected
- sendMessage(getName(), topic);
-
- connV11.destroy();
- connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
- connV11.connect(defUser, defPass, "myclientid");
-
- this.subscribeTopic(connV11, "sub1", "auto", getName());
-
- // we must have received the message
- frame = connV11.receiveFrame();
-
- Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
- Assert.assertNotNull(frame.getHeader("destination"));
- Assert.assertEquals(getName(), frame.getBody());
-
- this.unsubscribe(connV11, "sub1");
-
- connV11.disconnect();
- }
-
- public void testJMSXGroupIdCanBeSet() throws Exception
- {
- MessageConsumer consumer = session.createConsumer(queue);
-
- connV11.connect(defUser, defPass);
-
- ClientStompFrame frame = connV11.createFrame("SEND");
- frame.addHeader("destination", getQueuePrefix() + getQueueName());
- frame.addHeader("JMSXGroupID", "TEST");
- frame.setBody("Hello World");
-
- connV11.sendFrame(frame);
-
- TextMessage message = (TextMessage)consumer.receive(1000);
- Assert.assertNotNull(message);
- Assert.assertEquals("Hello World", message.getText());
- // differ from StompConnect
- Assert.assertEquals("TEST",
message.getStringProperty("JMSXGroupID"));
- }
-
- public void testMessagesAreInOrder() throws Exception
- {
- int ctr = 10;
- String[] data = new String[ctr];
-
- connV11.connect(defUser, defPass);
-
- this.subscribe(connV11, "sub1", "auto");
-
- for (int i = 0; i < ctr; ++i)
- {
- data[i] = getName() + i;
- sendMessage(data[i]);
- }
-
- ClientStompFrame frame = null;
-
- for (int i = 0; i < ctr; ++i)
- {
- frame = connV11.receiveFrame();
- Assert.assertTrue("Message not in order",
frame.getBody().equals(data[i]));
- }
-
- for (int i = 0; i < ctr; ++i)
- {
- data[i] = getName() + ":second:" + i;
- sendMessage(data[i]);
- }
-
- for (int i = 0; i < ctr; ++i)
- {
- frame = connV11.receiveFrame();
- Assert.assertTrue("Message not in order",
frame.getBody().equals(data[i]));
- }
-
- connV11.disconnect();
- }
-
- public void testSubscribeWithAutoAckAndSelector() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- this.subscribe(connV11, "sub1", "auto", null, "foo =
'zzz'");
-
- sendMessage("Ignored message", "foo", "1234");
- sendMessage("Real message", "foo", "zzz");
-
- ClientStompFrame frame = connV11.receiveFrame();
-
- Assert.assertTrue("Should have received the real message but got: " +
frame, frame.getBody().equals("Real message"));
-
- connV11.disconnect();
- }
-
- public void testRedeliveryWithClientAck() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- this.subscribe(connV11, "subId", "client");
-
- sendMessage(getName());
-
- ClientStompFrame frame = connV11.receiveFrame();
-
- assertTrue(frame.getCommand().equals("MESSAGE"));
-
- connV11.disconnect();
-
- // message should be received since message was not acknowledged
- MessageConsumer consumer = session.createConsumer(queue);
- Message message = consumer.receive(1000);
- Assert.assertNotNull(message);
- Assert.assertTrue(message.getJMSRedelivered());
- }
-
- public void testSendManyMessages() throws Exception
- {
- MessageConsumer consumer = session.createConsumer(queue);
-
- connV11.connect(defUser, defPass);
-
- int count = 1000;
- final CountDownLatch latch = new CountDownLatch(count);
- consumer.setMessageListener(new MessageListener()
- {
- public void onMessage(Message arg0)
- {
- latch.countDown();
- }
- });
-
- ClientStompFrame frame = connV11.createFrame("SEND");
- frame.addHeader("destination", getQueuePrefix() + getQueueName());
- frame.setBody("Hello World");
-
- for (int i = 1; i <= count; i++)
- {
- connV11.sendFrame(frame);
- }
-
- assertTrue(latch.await(60, TimeUnit.SECONDS));
-
- connV11.disconnect();
- }
-
- public void testSendMessage() throws Exception
- {
- MessageConsumer consumer = session.createConsumer(queue);
-
- connV11.connect(defUser, defPass);
-
- ClientStompFrame frame = connV11.createFrame("SEND");
- frame.addHeader("destination", getQueuePrefix() + getQueueName());
- frame.setBody("Hello World");
-
- connV11.sendFrame(frame);
-
- TextMessage message = (TextMessage)consumer.receive(1000);
- Assert.assertNotNull(message);
- Assert.assertEquals("Hello World", message.getText());
- // Assert default priority 4 is used when priority header is not set
- Assert.assertEquals("getJMSPriority", 4, message.getJMSPriority());
-
- // Make sure that the timestamp is valid - should
- // be very close to the current time.
- long tnow = System.currentTimeMillis();
- long tmsg = message.getJMSTimestamp();
- Assert.assertTrue(Math.abs(tnow - tmsg) < 1000);
- }
-
- public void testSendMessageWithContentLength() throws Exception
- {
- MessageConsumer consumer = session.createConsumer(queue);
-
- connV11.connect(defUser, defPass);
-
- byte[] data = new byte[] { 1, 0, 0, 4 };
-
- ClientStompFrame frame = connV11.createFrame("SEND");
-
- frame.addHeader("destination", getQueuePrefix() + getQueueName());
- frame.setBody(new String(data, "UTF-8"));
-
- frame.addHeader("content-length", String.valueOf(data.length));
-
- connV11.sendFrame(frame);
-
- BytesMessage message = (BytesMessage)consumer.receive(10000);
- Assert.assertNotNull(message);
-
- assertEquals(data.length, message.getBodyLength());
- assertEquals(data[0], message.readByte());
- assertEquals(data[1], message.readByte());
- assertEquals(data[2], message.readByte());
- assertEquals(data[3], message.readByte());
- }
-
- public void testSendMessageWithCustomHeadersAndSelector() throws Exception
- {
- MessageConsumer consumer = session.createConsumer(queue, "foo =
'abc'");
-
- connV11.connect(defUser, defPass);
-
- ClientStompFrame frame = connV11.createFrame("SEND");
- frame.addHeader("foo", "abc");
- frame.addHeader("bar", "123");
-
- frame.addHeader("destination", getQueuePrefix() + getQueueName());
- frame.setBody("Hello World");
-
- connV11.sendFrame(frame);
-
- TextMessage message = (TextMessage)consumer.receive(1000);
- Assert.assertNotNull(message);
- Assert.assertEquals("Hello World", message.getText());
- Assert.assertEquals("foo", "abc",
message.getStringProperty("foo"));
- Assert.assertEquals("bar", "123",
message.getStringProperty("bar"));
- }
-
- public void testSendMessageWithLeadingNewLine() throws Exception
- {
- MessageConsumer consumer = session.createConsumer(queue);
-
- connV11.connect(defUser, defPass);
-
- ClientStompFrame frame = connV11.createFrame("SEND");
-
- frame.addHeader("destination", getQueuePrefix() + getQueueName());
- frame.setBody("Hello World");
-
- connV11.sendWickedFrame(frame);
-
- TextMessage message = (TextMessage)consumer.receive(1000);
- Assert.assertNotNull(message);
- Assert.assertEquals("Hello World", message.getText());
-
- // Make sure that the timestamp is valid - should
- // be very close to the current time.
- long tnow = System.currentTimeMillis();
- long tmsg = message.getJMSTimestamp();
- Assert.assertTrue(Math.abs(tnow - tmsg) < 1000);
-
- assertNull(consumer.receive(1000));
-
- connV11.disconnect();
- }
-
- public void testSendMessageWithReceipt() throws Exception
- {
- MessageConsumer consumer = session.createConsumer(queue);
-
- connV11.connect(defUser, defPass);
-
- ClientStompFrame frame = connV11.createFrame("SEND");
- frame.addHeader("destination", getQueuePrefix() + getQueueName());
- frame.addHeader("receipt", "1234");
- frame.setBody("Hello World");
-
- frame = connV11.sendFrame(frame);
-
- assertTrue(frame.getCommand().equals("RECEIPT"));
- assertEquals("1234", frame.getHeader("receipt-id"));
-
- TextMessage message = (TextMessage)consumer.receive(1000);
- Assert.assertNotNull(message);
- Assert.assertEquals("Hello World", message.getText());
-
- // Make sure that the timestamp is valid - should
- // be very close to the current time.
- long tnow = System.currentTimeMillis();
- long tmsg = message.getJMSTimestamp();
- Assert.assertTrue(Math.abs(tnow - tmsg) < 1000);
-
- connV11.disconnect();
- }
-
- public void testSendMessageWithStandardHeaders() throws Exception
- {
- MessageConsumer consumer = session.createConsumer(queue);
-
- connV11.connect(defUser, defPass);
-
- ClientStompFrame frame = connV11.createFrame("SEND");
- frame.addHeader("destination", getQueuePrefix() + getQueueName());
- frame.addHeader("correlation-id", "c123");
- frame.addHeader("persistent", "true");
- frame.addHeader("priority", "3");
- frame.addHeader("type", "t345");
- frame.addHeader("JMSXGroupID", "abc");
- frame.addHeader("foo", "abc");
- frame.addHeader("bar", "123");
-
- frame.setBody("Hello World");
-
- frame = connV11.sendFrame(frame);
-
- TextMessage message = (TextMessage)consumer.receive(1000);
- Assert.assertNotNull(message);
- Assert.assertEquals("Hello World", message.getText());
- Assert.assertEquals("JMSCorrelationID", "c123",
message.getJMSCorrelationID());
- Assert.assertEquals("getJMSType", "t345",
message.getJMSType());
- Assert.assertEquals("getJMSPriority", 3, message.getJMSPriority());
- Assert.assertEquals(DeliveryMode.PERSISTENT, message.getJMSDeliveryMode());
- Assert.assertEquals("foo", "abc",
message.getStringProperty("foo"));
- Assert.assertEquals("bar", "123",
message.getStringProperty("bar"));
-
- Assert.assertEquals("JMSXGroupID", "abc",
message.getStringProperty("JMSXGroupID"));
-
- connV11.disconnect();
- }
-
- public void testSubscribeToTopic() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- this.subscribeTopic(connV11, "sub1", null, null, true);
-
- sendMessage(getName(), topic);
-
- ClientStompFrame frame = connV11.receiveFrame();
-
- Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
- Assert.assertTrue(frame.getHeader("destination").equals(getTopicPrefix()
+ getTopicName()));
- Assert.assertTrue(frame.getBody().equals(getName()));
-
- this.unsubscribe(connV11, "sub1", true);
-
- sendMessage(getName(), topic);
-
- frame = connV11.receiveFrame(1000);
- assertNull(frame);
-
- connV11.disconnect();
- }
-
- public void testSubscribeToTopicWithNoLocal() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- this.subscribeTopic(connV11, "sub1", null, null, true, true);
-
- // send a message on the same connection => it should not be received
- ClientStompFrame frame = connV11.createFrame("SEND");
- frame.addHeader("destination", getTopicPrefix() + getTopicName());
-
- frame.setBody("Hello World");
-
- connV11.sendFrame(frame);
-
- frame = connV11.receiveFrame(2000);
-
- assertNull(frame);
-
- // send message on another JMS connection => it should be received
- sendMessage(getName(), topic);
-
- frame = connV11.receiveFrame();
-
- Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
- Assert.assertTrue(frame.getHeader("destination").equals(getTopicPrefix()
+ getTopicName()));
- Assert.assertTrue(frame.getBody().equals(getName()));
-
- this.unsubscribe(connV11, "sub1");
-
- connV11.disconnect();
- }
-
- public void testSubscribeWithAutoAck() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- this.subscribe(connV11, "sub1", "auto");
-
- sendMessage(getName());
-
- ClientStompFrame frame = connV11.receiveFrame();
-
- Assert.assertEquals("MESSAGE", frame.getCommand());
- Assert.assertNotNull(frame.getHeader("destination"));
- Assert.assertEquals(getName(), frame.getBody());
-
- connV11.disconnect();
-
- // message should not be received as it was auto-acked
- MessageConsumer consumer = session.createConsumer(queue);
- Message message = consumer.receive(1000);
- Assert.assertNull(message);
- }
-
- public void testSubscribeWithAutoAckAndBytesMessage() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- this.subscribe(connV11, "sub1", "auto");
-
- byte[] payload = new byte[] { 1, 2, 3, 4, 5 };
- sendMessage(payload, queue);
-
- ClientStompFrame frame = connV11.receiveFrame();
-
- assertEquals("MESSAGE", frame.getCommand());
-
- System.out.println("Message: " + frame);
-
- assertEquals("5", frame.getHeader("content-length"));
-
- assertEquals(null, frame.getHeader("type"));
-
- assertEquals(frame.getBody(), new String(payload, "UTF-8"));
-
- connV11.disconnect();
- }
-
- public void testSubscribeWithClientAck() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- this.subscribe(connV11, "sub1", "client");
-
- sendMessage(getName());
-
- ClientStompFrame frame = connV11.receiveFrame();
-
- this.ack(connV11, "sub1", frame);
-
- connV11.disconnect();
-
- // message should not be received since message was acknowledged by the client
- MessageConsumer consumer = session.createConsumer(queue);
- Message message = consumer.receive(1000);
- Assert.assertNull(message);
- }
-
- public void
testSubscribeWithClientAckThenConsumingAgainWithAutoAckWithExplicitDisconnect() throws
Exception
- {
- assertSubscribeWithClientAckThenConsumeWithAutoAck(true);
- }
-
- public void
testSubscribeWithClientAckThenConsumingAgainWithAutoAckWithNoDisconnectFrame() throws
Exception
- {
- assertSubscribeWithClientAckThenConsumeWithAutoAck(false);
- }
-
- public void testSubscribeWithID() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- this.subscribe(connV11, "mysubid", "auto");
-
- sendMessage(getName());
-
- ClientStompFrame frame = connV11.receiveFrame();
-
- Assert.assertTrue(frame.getHeader("subscription") != null);
-
- connV11.disconnect();
- }
-
- public void testSubscribeWithMessageSentWithProperties() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- this.subscribe(connV11, "sub1", "auto");
-
- MessageProducer producer = session.createProducer(queue);
- BytesMessage message = session.createBytesMessage();
- message.setStringProperty("S", "value");
- message.setBooleanProperty("n", false);
- message.setByteProperty("byte", (byte)9);
- message.setDoubleProperty("d", 2.0);
- message.setFloatProperty("f", (float)6.0);
- message.setIntProperty("i", 10);
- message.setLongProperty("l", 121);
- message.setShortProperty("s", (short)12);
- message.writeBytes("Hello World".getBytes("UTF-8"));
- producer.send(message);
-
- ClientStompFrame frame = connV11.receiveFrame();
- Assert.assertNotNull(frame);
-
- Assert.assertTrue(frame.getHeader("S") != null);
- Assert.assertTrue(frame.getHeader("n") != null);
- Assert.assertTrue(frame.getHeader("byte") != null);
- Assert.assertTrue(frame.getHeader("d") != null);
- Assert.assertTrue(frame.getHeader("f") != null);
- Assert.assertTrue(frame.getHeader("i") != null);
- Assert.assertTrue(frame.getHeader("l") != null);
- Assert.assertTrue(frame.getHeader("s") != null);
- Assert.assertEquals("Hello World", frame.getBody());
-
- connV11.disconnect();
- }
-
- public void testSuccessiveTransactionsWithSameID() throws Exception
- {
- MessageConsumer consumer = session.createConsumer(queue);
-
- connV11.connect(defUser, defPass);
-
- // first tx
- this.beginTransaction(connV11, "tx1");
-
- ClientStompFrame frame = connV11.createFrame("SEND");
- frame.addHeader("destination", getQueuePrefix() + getQueueName());
- frame.addHeader("transaction", "tx1");
- frame.setBody("Hello World");
-
- connV11.sendFrame(frame);
-
- this.commitTransaction(connV11, "tx1");
-
- Message message = consumer.receive(1000);
- Assert.assertNotNull("Should have received a message", message);
-
- // 2nd tx with same tx ID
- this.beginTransaction(connV11, "tx1");
-
- frame = connV11.createFrame("SEND");
- frame.addHeader("destination", getQueuePrefix() + getQueueName());
- frame.addHeader("transaction", "tx1");
-
- frame.setBody("Hello World");
-
- connV11.sendFrame(frame);
-
- this.commitTransaction(connV11, "tx1");
-
- message = consumer.receive(1000);
- Assert.assertNotNull("Should have received a message", message);
-
- connV11.disconnect();
- }
-
- public void testTransactionCommit() throws Exception
- {
- MessageConsumer consumer = session.createConsumer(queue);
-
- connV11.connect(defUser, defPass);
-
- this.beginTransaction(connV11, "tx1");
-
- ClientStompFrame frame = connV11.createFrame("SEND");
- frame.addHeader("destination", getQueuePrefix() + getQueueName());
- frame.addHeader("transaction", "tx1");
- frame.addHeader("receipt", "123");
- frame.setBody("Hello World");
-
- frame = connV11.sendFrame(frame);
-
- assertEquals("123", frame.getHeader("receipt-id"));
-
- // check the message is not committed
- assertNull(consumer.receive(100));
-
- this.commitTransaction(connV11, "tx1", true);
-
- Message message = consumer.receive(1000);
- Assert.assertNotNull("Should have received a message", message);
-
- connV11.disconnect();
- }
-
- public void testTransactionRollback() throws Exception
- {
- MessageConsumer consumer = session.createConsumer(queue);
-
- connV11.connect(defUser, defPass);
-
- this.beginTransaction(connV11, "tx1");
-
- ClientStompFrame frame = connV11.createFrame("SEND");
- frame.addHeader("destination", getQueuePrefix() + getQueueName());
- frame.addHeader("transaction", "tx1");
-
- frame.setBody("first message");
-
- connV11.sendFrame(frame);
-
- // rollback first message
- this.abortTransaction(connV11, "tx1");
-
- this.beginTransaction(connV11, "tx1");
-
- frame = connV11.createFrame("SEND");
- frame.addHeader("destination", getQueuePrefix() + getQueueName());
- frame.addHeader("transaction", "tx1");
-
- frame.setBody("second message");
-
- connV11.sendFrame(frame);
-
- this.commitTransaction(connV11, "tx1", true);
-
- // only second msg should be received since first msg was rolled back
- TextMessage message = (TextMessage)consumer.receive(1000);
- Assert.assertNotNull(message);
- Assert.assertEquals("second message", message.getText());
-
- connV11.disconnect();
- }
-
- public void testUnsubscribe() throws Exception
- {
- connV11.connect(defUser, defPass);
-
- this.subscribe(connV11, "sub1", "auto");
-
- // send a message to our queue
- sendMessage("first message");
-
- // receive message from socket
- ClientStompFrame frame = connV11.receiveFrame();
-
- Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
-
- // remove suscription
- this.unsubscribe(connV11, "sub1", true);
-
- // send a message to our queue
- sendMessage("second message");
-
- frame = connV11.receiveFrame(1000);
- assertNull(frame);
-
- connV11.disconnect();
- }
-
- //-----------------private help methods
-
- private void abortTransaction(StompClientConnection conn, String txID) throws
IOException, InterruptedException
- {
- ClientStompFrame abortFrame = conn.createFrame("ABORT");
- abortFrame.addHeader("transaction", txID);
-
- conn.sendFrame(abortFrame);
- }
-
- private void beginTransaction(StompClientConnection conn, String txID) throws
IOException, InterruptedException
- {
- ClientStompFrame beginFrame = conn.createFrame("BEGIN");
- beginFrame.addHeader("transaction", txID);
-
- conn.sendFrame(beginFrame);
- }
-
- private void commitTransaction(StompClientConnection conn, String txID) throws
IOException, InterruptedException
- {
- commitTransaction(conn, txID, false);
- }
-
- private void commitTransaction(StompClientConnection conn, String txID, boolean
receipt) throws IOException, InterruptedException
- {
- ClientStompFrame beginFrame = conn.createFrame("COMMIT");
- beginFrame.addHeader("transaction", txID);
- if (receipt)
- {
- beginFrame.addHeader("receipt", "1234");
- }
- ClientStompFrame resp = conn.sendFrame(beginFrame);
- if (receipt)
- {
- assertEquals("1234", resp.getHeader("receipt-id"));
- }
- }
-
- private void ack(StompClientConnection conn, String subId,
- ClientStompFrame frame) throws IOException, InterruptedException
- {
- String messageID = frame.getHeader("message-id");
-
- ClientStompFrame ackFrame = conn.createFrame("ACK");
-
- ackFrame.addHeader("subscription", subId);
- ackFrame.addHeader("message-id", messageID);
-
- ClientStompFrame response = conn.sendFrame(ackFrame);
- if (response != null)
- {
- throw new IOException("failed to ack " + response);
- }
- }
-
- private void ack(StompClientConnection conn, String subId, String mid, String txID)
throws IOException, InterruptedException
- {
- ClientStompFrame ackFrame = conn.createFrame("ACK");
- ackFrame.addHeader("subscription", subId);
- ackFrame.addHeader("message-id", mid);
- if (txID != null)
- {
- ackFrame.addHeader("transaction", txID);
- }
-
- conn.sendFrame(ackFrame);
- }
-
- private void nack(StompClientConnection conn, String subId, String mid) throws
IOException, InterruptedException
- {
- ClientStompFrame ackFrame = conn.createFrame("NACK");
- ackFrame.addHeader("subscription", subId);
- ackFrame.addHeader("message-id", mid);
-
- conn.sendFrame(ackFrame);
- }
-
- private void subscribe(StompClientConnection conn, String subId, String ack) throws
IOException, InterruptedException
- {
- subscribe(conn, subId, ack, null, null);
- }
-
- private void subscribe(StompClientConnection conn, String subId,
- String ack, String durableId) throws IOException, InterruptedException
- {
- subscribe(conn, subId, ack, durableId, null);
- }
-
- private void subscribe(StompClientConnection conn, String subId,
- String ack, String durableId, boolean receipt) throws IOException,
InterruptedException
- {
- subscribe(conn, subId, ack, durableId, null, receipt);
- }
-
- private void subscribe(StompClientConnection conn, String subId, String ack,
- String durableId, String selector) throws IOException,
- InterruptedException
- {
- subscribe(conn, subId, ack, durableId, selector, false);
- }
-
- private void subscribe(StompClientConnection conn, String subId,
- String ack, String durableId, String selector, boolean receipt) throws
IOException, InterruptedException
- {
- ClientStompFrame subFrame = conn.createFrame("SUBSCRIBE");
- subFrame.addHeader("id", subId);
- subFrame.addHeader("destination", getQueuePrefix() + getQueueName());
- if (ack != null)
- {
- subFrame.addHeader("ack", ack);
- }
- if (durableId != null)
- {
- subFrame.addHeader("durable-subscriber-name", durableId);
- }
- if (selector != null)
- {
- subFrame.addHeader("selector", selector);
- }
- if (receipt)
- {
- subFrame.addHeader("receipt", "1234");
- }
-
- subFrame = conn.sendFrame(subFrame);
-
- if (receipt)
- {
- assertEquals("1234", subFrame.getHeader("receipt-id"));
- }
- }
-
- private void subscribeTopic(StompClientConnection conn, String subId,
- String ack, String durableId) throws IOException, InterruptedException
- {
- subscribeTopic(conn, subId, ack, durableId, false);
- }
-
- private void subscribeTopic(StompClientConnection conn, String subId,
- String ack, String durableId, boolean receipt) throws IOException,
InterruptedException
- {
- subscribeTopic(conn, subId, ack, durableId, receipt, false);
- }
-
- private void subscribeTopic(StompClientConnection conn, String subId,
- String ack, String durableId, boolean receipt, boolean noLocal) throws
IOException, InterruptedException
- {
- ClientStompFrame subFrame = conn.createFrame("SUBSCRIBE");
- subFrame.addHeader("id", subId);
- subFrame.addHeader("destination", getTopicPrefix() + getTopicName());
- if (ack != null)
- {
- subFrame.addHeader("ack", ack);
- }
- if (durableId != null)
- {
- subFrame.addHeader("durable-subscriber-name", durableId);
- }
- if (receipt)
- {
- subFrame.addHeader("receipt", "1234");
- }
- if (noLocal)
- {
- subFrame.addHeader("no-local", "true");
- }
-
- ClientStompFrame frame = conn.sendFrame(subFrame);
-
- if (receipt)
- {
- assertTrue(frame.getHeader("receipt-id").equals("1234"));
- }
- }
-
- private void unsubscribe(StompClientConnection conn, String subId) throws IOException,
InterruptedException
- {
- ClientStompFrame subFrame = conn.createFrame("UNSUBSCRIBE");
- subFrame.addHeader("id", subId);
-
- conn.sendFrame(subFrame);
- }
-
- private void unsubscribe(StompClientConnection conn, String subId,
- boolean receipt) throws IOException, InterruptedException
- {
- ClientStompFrame subFrame = conn.createFrame("UNSUBSCRIBE");
- subFrame.addHeader("id", subId);
-
- if (receipt)
- {
- subFrame.addHeader("receipt", "4321");
- }
-
- ClientStompFrame f = conn.sendFrame(subFrame);
-
- if (receipt)
- {
- System.out.println("response: " + f);
- assertEquals("RECEIPT", f.getCommand());
- assertEquals("4321", f.getHeader("receipt-id"));
- }
- }
-
- protected void assertSubscribeWithClientAckThenConsumeWithAutoAck(boolean
sendDisconnect) throws Exception
- {
- connV11.connect(defUser, defPass);
-
- this.subscribe(connV11, "sub1", "client");
-
- sendMessage(getName());
-
- ClientStompFrame frame = connV11.receiveFrame();
-
- Assert.assertEquals("MESSAGE", frame.getCommand());
-
- log.info("Reconnecting!");
-
- if (sendDisconnect)
- {
- connV11.disconnect();
- connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
- }
- else
- {
- connV11.destroy();
- connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
- }
-
- // message should be received since message was not acknowledged
- connV11.connect(defUser, defPass);
-
- this.subscribe(connV11, "sub1", null);
-
- frame = connV11.receiveFrame();
- Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
-
- connV11.disconnect();
-
- // now lets make sure we don't see the message again
- connV11.destroy();
- connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
- connV11.connect(defUser, defPass);
-
- this.subscribe(connV11, "sub1", null, null, true);
-
- sendMessage("shouldBeNextMessage");
-
- frame = connV11.receiveFrame();
- Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
- Assert.assertEquals("shouldBeNextMessage", frame.getBody());
- }
-
-}
-
-
-
-
-
Copied:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestV11.java
(from rev 11517,
branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestV11.java)
===================================================================
---
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestV11.java
(rev 0)
+++
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestV11.java 2011-10-12
08:32:14 UTC (rev 11519)
@@ -0,0 +1,2021 @@
+/**
+ *
+ * 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.hornetq.tests.integration.stomp.v11;
+
+import java.io.IOException;
+import java.nio.channels.ClosedChannelException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.jms.BytesMessage;
+import javax.jms.DeliveryMode;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
+import javax.jms.MessageProducer;
+import javax.jms.TextMessage;
+
+import junit.framework.Assert;
+
+import org.hornetq.core.logging.Logger;
+import org.hornetq.tests.integration.stomp.util.ClientStompFrame;
+import org.hornetq.tests.integration.stomp.util.StompClientConnection;
+import org.hornetq.tests.integration.stomp.util.StompClientConnectionFactory;
+import org.hornetq.tests.integration.stomp.util.StompClientConnectionV11;
+
+/*
+ *
+ */
+public class StompTestV11 extends StompTestBase2
+{
+ private static final transient Logger log = Logger.getLogger(StompTestV11.class);
+
+ private StompClientConnection connV11;
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
+ }
+
+ protected void tearDown() throws Exception
+ {
+ if (connV11.isConnected())
+ {
+ connV11.disconnect();
+ }
+ super.tearDown();
+ }
+
+ public void testConnection() throws Exception
+ {
+ StompClientConnection connection =
StompClientConnectionFactory.createClientConnection("1.0", hostname, port);
+
+ connection.connect(defUser, defPass);
+
+ assertTrue(connection.isConnected());
+
+ assertEquals("1.0", connection.getVersion());
+
+ connection.disconnect();
+
+ connection = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
+
+ connection.connect(defUser, defPass);
+
+ assertTrue(connection.isConnected());
+
+ assertEquals("1.1", connection.getVersion());
+
+ connection.disconnect();
+
+ connection = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
+
+ connection.connect();
+
+ assertFalse(connection.isConnected());
+
+ //new way of connection
+ StompClientConnectionV11 conn = (StompClientConnectionV11)
StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+ conn.connect1(defUser, defPass);
+
+ assertTrue(conn.isConnected());
+
+ conn.disconnect();
+ }
+
+ public void testNegotiation() throws Exception
+ {
+ // case 1 accept-version absent. It is a 1.0 connect
+ ClientStompFrame frame = connV11.createFrame("CONNECT");
+ frame.addHeader("host", "127.0.0.1");
+ frame.addHeader("login", this.defUser);
+ frame.addHeader("passcode", this.defPass);
+
+ ClientStompFrame reply = connV11.sendFrame(frame);
+
+ assertEquals("CONNECTED", reply.getCommand());
+
+ //reply headers: version, session, server
+ assertEquals(null, reply.getHeader("version"));
+
+ connV11.disconnect();
+
+ // case 2 accept-version=1.0, result: 1.0
+ connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
+ frame = connV11.createFrame("CONNECT");
+ frame.addHeader("accept-version", "1.0");
+ frame.addHeader("host", "127.0.0.1");
+ frame.addHeader("login", this.defUser);
+ frame.addHeader("passcode", this.defPass);
+
+ reply = connV11.sendFrame(frame);
+
+ assertEquals("CONNECTED", reply.getCommand());
+
+ //reply headers: version, session, server
+ assertEquals("1.0", reply.getHeader("version"));
+
+ connV11.disconnect();
+
+ // case 3 accept-version=1.1, result: 1.1
+ connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
+ frame = connV11.createFrame("CONNECT");
+ frame.addHeader("accept-version", "1.1");
+ frame.addHeader("host", "127.0.0.1");
+ frame.addHeader("login", this.defUser);
+ frame.addHeader("passcode", this.defPass);
+
+ reply = connV11.sendFrame(frame);
+
+ assertEquals("CONNECTED", reply.getCommand());
+
+ //reply headers: version, session, server
+ assertEquals("1.1", reply.getHeader("version"));
+
+ connV11.disconnect();
+
+ // case 4 accept-version=1.0,1.1,1.2, result 1.1
+ connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
+ frame = connV11.createFrame("CONNECT");
+ frame.addHeader("accept-version", "1.0,1.1,1.2");
+ frame.addHeader("host", "127.0.0.1");
+ frame.addHeader("login", this.defUser);
+ frame.addHeader("passcode", this.defPass);
+
+ reply = connV11.sendFrame(frame);
+
+ assertEquals("CONNECTED", reply.getCommand());
+
+ //reply headers: version, session, server
+ assertEquals("1.1", reply.getHeader("version"));
+
+ connV11.disconnect();
+
+ // case 5 accept-version=1.2, result error
+ connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
+ frame = connV11.createFrame("CONNECT");
+ frame.addHeader("accept-version", "1.2");
+ frame.addHeader("host", "127.0.0.1");
+ frame.addHeader("login", this.defUser);
+ frame.addHeader("passcode", this.defPass);
+
+ reply = connV11.sendFrame(frame);
+
+ assertEquals("ERROR", reply.getCommand());
+
+ System.out.println("Got error frame " + reply);
+
+ }
+
+ public void testSendAndReceive() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+ ClientStompFrame frame = connV11.createFrame("SEND");
+ frame.addHeader("destination", getQueuePrefix() + getQueueName());
+ frame.addHeader("content-type", "text/plain");
+ frame.setBody("Hello World 1!");
+
+ ClientStompFrame response = connV11.sendFrame(frame);
+
+ assertNull(response);
+
+ frame.addHeader("receipt", "1234");
+ frame.setBody("Hello World 2!");
+
+ response = connV11.sendFrame(frame);
+
+ assertNotNull(response);
+
+ assertEquals("RECEIPT", response.getCommand());
+
+ assertEquals("1234", response.getHeader("receipt-id"));
+
+ //subscribe
+ StompClientConnection newConn =
StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+ newConn.connect(defUser, defPass);
+
+ ClientStompFrame subFrame = newConn.createFrame("SUBSCRIBE");
+ subFrame.addHeader("id", "a-sub");
+ subFrame.addHeader("destination", getQueuePrefix() + getQueueName());
+ subFrame.addHeader("ack", "auto");
+
+ newConn.sendFrame(subFrame);
+
+ frame = newConn.receiveFrame();
+
+ System.out.println("received " + frame);
+
+ assertEquals("MESSAGE", frame.getCommand());
+
+ assertEquals("a-sub", frame.getHeader("subscription"));
+
+ assertNotNull(frame.getHeader("message-id"));
+
+ assertEquals(getQueuePrefix() + getQueueName(),
frame.getHeader("destination"));
+
+ assertEquals("Hello World 1!", frame.getBody());
+
+ frame = newConn.receiveFrame();
+
+ System.out.println("received " + frame);
+
+ //unsub
+ ClientStompFrame unsubFrame = newConn.createFrame("UNSUBSCRIBE");
+ unsubFrame.addHeader("id", "a-sub");
+
+ newConn.disconnect();
+ }
+
+ public void testHeaderContentType() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+ ClientStompFrame frame = connV11.createFrame("SEND");
+ frame.addHeader("destination", getQueuePrefix() + getQueueName());
+ frame.addHeader("content-type", "application/xml");
+ frame.setBody("Hello World 1!");
+
+ connV11.sendFrame(frame);
+
+ //subscribe
+ StompClientConnection newConn =
StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+ newConn.connect(defUser, defPass);
+
+ ClientStompFrame subFrame = newConn.createFrame("SUBSCRIBE");
+ subFrame.addHeader("id", "a-sub");
+ subFrame.addHeader("destination", getQueuePrefix() + getQueueName());
+ subFrame.addHeader("ack", "auto");
+
+ newConn.sendFrame(subFrame);
+
+ frame = newConn.receiveFrame();
+
+ System.out.println("received " + frame);
+
+ assertEquals("MESSAGE", frame.getCommand());
+
+ assertEquals("application/xml",
frame.getHeader("content-type"));
+
+ //unsub
+ ClientStompFrame unsubFrame = newConn.createFrame("UNSUBSCRIBE");
+ unsubFrame.addHeader("id", "a-sub");
+
+ newConn.disconnect();
+ }
+
+ public void testHeaderContentLength() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+ ClientStompFrame frame = connV11.createFrame("SEND");
+
+ String body = "Hello World 1!";
+ String cLen = String.valueOf(body.getBytes("UTF-8").length);
+
+ frame.addHeader("destination", getQueuePrefix() + getQueueName());
+ frame.addHeader("content-type", "application/xml");
+ frame.addHeader("content-length", cLen);
+ frame.setBody(body + "extra");
+
+ connV11.sendFrame(frame);
+
+ //subscribe
+ StompClientConnection newConn =
StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+ newConn.connect(defUser, defPass);
+
+ ClientStompFrame subFrame = newConn.createFrame("SUBSCRIBE");
+ subFrame.addHeader("id", "a-sub");
+ subFrame.addHeader("destination", getQueuePrefix() + getQueueName());
+ subFrame.addHeader("ack", "auto");
+
+ newConn.sendFrame(subFrame);
+
+ frame = newConn.receiveFrame();
+
+ System.out.println("received " + frame);
+
+ assertEquals("MESSAGE", frame.getCommand());
+
+ assertEquals(cLen, frame.getHeader("content-length"));
+
+ //unsub
+ ClientStompFrame unsubFrame = newConn.createFrame("UNSUBSCRIBE");
+ unsubFrame.addHeader("id", "a-sub");
+
+ newConn.disconnect();
+ }
+
+ public void testHeaderEncoding() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+ ClientStompFrame frame = connV11.createFrame("SEND");
+
+ String body = "Hello World 1!";
+ String cLen = String.valueOf(body.getBytes("UTF-8").length);
+
+ frame.addHeader("destination", getQueuePrefix() + getQueueName());
+ frame.addHeader("content-type", "application/xml");
+ frame.addHeader("content-length", cLen);
+ String hKey = "special-header\\\\\\n\\:";
+ String hVal = "\\:\\\\\\ngood";
+ frame.addHeader(hKey, hVal);
+
+ System.out.println("key: |" + hKey + "| val: |" + hVal);
+
+ frame.setBody(body);
+
+ connV11.sendFrame(frame);
+
+ //subscribe
+ StompClientConnection newConn =
StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+ newConn.connect(defUser, defPass);
+
+ ClientStompFrame subFrame = newConn.createFrame("SUBSCRIBE");
+ subFrame.addHeader("id", "a-sub");
+ subFrame.addHeader("destination", getQueuePrefix() + getQueueName());
+ subFrame.addHeader("ack", "auto");
+
+ newConn.sendFrame(subFrame);
+
+ frame = newConn.receiveFrame();
+
+ System.out.println("received " + frame);
+
+ assertEquals("MESSAGE", frame.getCommand());
+
+ String value = frame.getHeader("special-header" + "\\" +
"\n" + ":");
+
+ assertEquals(":" + "\\" + "\n" + "good",
value);
+
+ //unsub
+ ClientStompFrame unsubFrame = newConn.createFrame("UNSUBSCRIBE");
+ unsubFrame.addHeader("id", "a-sub");
+
+ newConn.disconnect();
+ }
+
+ public void testHeartBeat() throws Exception
+ {
+ //no heart beat at all if heat-beat absent
+ ClientStompFrame frame = connV11.createFrame("CONNECT");
+ frame.addHeader("host", "127.0.0.1");
+ frame.addHeader("login", this.defUser);
+ frame.addHeader("passcode", this.defPass);
+
+ ClientStompFrame reply = connV11.sendFrame(frame);
+
+ assertEquals("CONNECTED", reply.getCommand());
+
+ Thread.sleep(5000);
+
+ assertEquals(0, connV11.getFrameQueueSize());
+
+ connV11.disconnect();
+
+ //no heart beat for (0,0)
+ connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
+ frame = connV11.createFrame("CONNECT");
+ frame.addHeader("host", "127.0.0.1");
+ frame.addHeader("login", this.defUser);
+ frame.addHeader("passcode", this.defPass);
+ frame.addHeader("heart-beat", "0,0");
+ frame.addHeader("accept-version", "1.0,1.1");
+
+ reply = connV11.sendFrame(frame);
+
+ assertEquals("CONNECTED", reply.getCommand());
+
+ assertEquals("0,0", reply.getHeader("heart-beat"));
+
+ Thread.sleep(5000);
+
+ assertEquals(0, connV11.getFrameQueueSize());
+
+ connV11.disconnect();
+
+ //heart-beat (1,0), should receive a min client ping accepted by server
+ connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
+ frame = connV11.createFrame("CONNECT");
+ frame.addHeader("host", "127.0.0.1");
+ frame.addHeader("login", this.defUser);
+ frame.addHeader("passcode", this.defPass);
+ frame.addHeader("heart-beat", "1,0");
+ frame.addHeader("accept-version", "1.0,1.1");
+
+ reply = connV11.sendFrame(frame);
+
+ assertEquals("CONNECTED", reply.getCommand());
+
+ assertEquals("0,500", reply.getHeader("heart-beat"));
+
+ Thread.sleep(2000);
+
+ //now server side should be disconnected because we didn't send ping for 2 sec
+ frame = connV11.createFrame("SEND");
+ frame.addHeader("destination", getQueuePrefix() + getQueueName());
+ frame.addHeader("content-type", "text/plain");
+ frame.setBody("Hello World");
+
+ //send will fail
+ try
+ {
+ connV11.sendFrame(frame);
+ fail("connection should have been destroyed by now");
+ }
+ catch (IOException e)
+ {
+ //ignore
+ }
+
+ //heart-beat (1,0), start a ping, then send a message, should be ok.
+ connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
+ frame = connV11.createFrame("CONNECT");
+ frame.addHeader("host", "127.0.0.1");
+ frame.addHeader("login", this.defUser);
+ frame.addHeader("passcode", this.defPass);
+ frame.addHeader("heart-beat", "1,0");
+ frame.addHeader("accept-version", "1.0,1.1");
+
+ reply = connV11.sendFrame(frame);
+
+ assertEquals("CONNECTED", reply.getCommand());
+
+ assertEquals("0,500", reply.getHeader("heart-beat"));
+
+ System.out.println("========== start pinger!");
+
+ connV11.startPinger(500);
+
+ Thread.sleep(2000);
+
+ //now server side should be disconnected because we didn't send ping for 2 sec
+ frame = connV11.createFrame("SEND");
+ frame.addHeader("destination", getQueuePrefix() + getQueueName());
+ frame.addHeader("content-type", "text/plain");
+ frame.setBody("Hello World");
+
+ //send will be ok
+ connV11.sendFrame(frame);
+
+ connV11.stopPinger();
+
+ connV11.disconnect();
+
+ }
+
+ //server ping
+ public void testHeartBeat2() throws Exception
+ {
+ //heart-beat (1,1)
+ ClientStompFrame frame = connV11.createFrame("CONNECT");
+ frame.addHeader("host", "127.0.0.1");
+ frame.addHeader("login", this.defUser);
+ frame.addHeader("passcode", this.defPass);
+ frame.addHeader("heart-beat", "1,1");
+ frame.addHeader("accept-version", "1.0,1.1");
+
+ ClientStompFrame reply = connV11.sendFrame(frame);
+
+ assertEquals("CONNECTED", reply.getCommand());
+
+ assertEquals("500,500", reply.getHeader("heart-beat"));
+
+ connV11.disconnect();
+
+ //heart-beat (500,1000)
+ connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
+ frame = connV11.createFrame("CONNECT");
+ frame.addHeader("host", "127.0.0.1");
+ frame.addHeader("login", this.defUser);
+ frame.addHeader("passcode", this.defPass);
+ frame.addHeader("heart-beat", "500,1000");
+ frame.addHeader("accept-version", "1.0,1.1");
+
+ reply = connV11.sendFrame(frame);
+
+ assertEquals("CONNECTED", reply.getCommand());
+
+ assertEquals("1000,500", reply.getHeader("heart-beat"));
+
+ System.out.println("========== start pinger!");
+
+ connV11.startPinger(500);
+
+ Thread.sleep(10000);
+
+ //now check the frame size
+ int size = connV11.getFrameQueueSize();
+
+ System.out.println("ping received: " + size);
+
+ assertTrue(size > 5);
+
+ //now server side should be disconnected because we didn't send ping for 2 sec
+ frame = connV11.createFrame("SEND");
+ frame.addHeader("destination", getQueuePrefix() + getQueueName());
+ frame.addHeader("content-type", "text/plain");
+ frame.setBody("Hello World");
+
+ //send will be ok
+ connV11.sendFrame(frame);
+
+ connV11.stopPinger();
+
+ connV11.disconnect();
+
+ }
+
+ public void testNack() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ subscribe(connV11, "sub1", "client");
+
+ sendMessage(getName());
+
+ ClientStompFrame frame = connV11.receiveFrame();
+
+ String messageID = frame.getHeader("message-id");
+
+ System.out.println("Received message with id " + messageID);
+
+ nack(connV11, "sub1", messageID);
+
+ unsubscribe(connV11, "sub1");
+
+ connV11.disconnect();
+
+ //Nack makes the message be dropped.
+ MessageConsumer consumer = session.createConsumer(queue);
+ Message message = consumer.receive(1000);
+ Assert.assertNull(message);
+ }
+
+ public void testNackWithWrongSubId() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ subscribe(connV11, "sub1", "client");
+
+ sendMessage(getName());
+
+ ClientStompFrame frame = connV11.receiveFrame();
+
+ String messageID = frame.getHeader("message-id");
+
+ System.out.println("Received message with id " + messageID);
+
+ nack(connV11, "sub2", messageID);
+
+ ClientStompFrame error = connV11.receiveFrame();
+
+ System.out.println("Receiver error: " + error);
+
+ unsubscribe(connV11, "sub1");
+
+ connV11.disconnect();
+
+ //message should be still there
+ MessageConsumer consumer = session.createConsumer(queue);
+ Message message = consumer.receive(1000);
+ Assert.assertNotNull(message);
+ }
+
+ public void testNackWithWrongMessageId() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ subscribe(connV11, "sub1", "client");
+
+ sendMessage(getName());
+
+ ClientStompFrame frame = connV11.receiveFrame();
+
+ String messageID = frame.getHeader("message-id");
+
+ System.out.println("Received message with id " + messageID);
+
+ nack(connV11, "sub2", "someother");
+
+ ClientStompFrame error = connV11.receiveFrame();
+
+ System.out.println("Receiver error: " + error);
+
+ unsubscribe(connV11, "sub1");
+
+ connV11.disconnect();
+
+ //message should still there
+ MessageConsumer consumer = session.createConsumer(queue);
+ Message message = consumer.receive(1000);
+ Assert.assertNotNull(message);
+ }
+
+
+ public void testAck() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ subscribe(connV11, "sub1", "client");
+
+ sendMessage(getName());
+
+ ClientStompFrame frame = connV11.receiveFrame();
+
+ String messageID = frame.getHeader("message-id");
+
+ System.out.println("Received message with id " + messageID);
+
+ ack(connV11, "sub1", messageID, null);
+
+ unsubscribe(connV11, "sub1");
+
+ connV11.disconnect();
+
+ //Nack makes the message be dropped.
+ MessageConsumer consumer = session.createConsumer(queue);
+ Message message = consumer.receive(1000);
+ Assert.assertNull(message);
+ }
+
+ public void testAckWithWrongSubId() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ subscribe(connV11, "sub1", "client");
+
+ sendMessage(getName());
+
+ ClientStompFrame frame = connV11.receiveFrame();
+
+ String messageID = frame.getHeader("message-id");
+
+ System.out.println("Received message with id " + messageID);
+
+ ack(connV11, "sub2", messageID, null);
+
+ ClientStompFrame error = connV11.receiveFrame();
+
+ System.out.println("Receiver error: " + error);
+
+ unsubscribe(connV11, "sub1");
+
+ connV11.disconnect();
+
+ //message should be still there
+ MessageConsumer consumer = session.createConsumer(queue);
+ Message message = consumer.receive(1000);
+ Assert.assertNotNull(message);
+ }
+
+ public void testAckWithWrongMessageId() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ subscribe(connV11, "sub1", "client");
+
+ sendMessage(getName());
+
+ ClientStompFrame frame = connV11.receiveFrame();
+
+ String messageID = frame.getHeader("message-id");
+
+ System.out.println("Received message with id " + messageID);
+
+ ack(connV11, "sub2", "someother", null);
+
+ ClientStompFrame error = connV11.receiveFrame();
+
+ System.out.println("Receiver error: " + error);
+
+ unsubscribe(connV11, "sub1");
+
+ connV11.disconnect();
+
+ //message should still there
+ MessageConsumer consumer = session.createConsumer(queue);
+ Message message = consumer.receive(1000);
+ Assert.assertNotNull(message);
+ }
+
+ public void testErrorWithReceipt() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ subscribe(connV11, "sub1", "client");
+
+ sendMessage(getName());
+
+ ClientStompFrame frame = connV11.receiveFrame();
+
+ String messageID = frame.getHeader("message-id");
+
+ System.out.println("Received message with id " + messageID);
+
+ ClientStompFrame ackFrame = connV11.createFrame("ACK");
+ //give it a wrong sub id
+ ackFrame.addHeader("subscription", "sub2");
+ ackFrame.addHeader("message-id", messageID);
+ ackFrame.addHeader("receipt", "answer-me");
+
+ ClientStompFrame error = connV11.sendFrame(ackFrame);
+
+ System.out.println("Receiver error: " + error);
+
+ assertEquals("ERROR", error.getCommand());
+
+ assertEquals("answer-me", error.getHeader("receipt-id"));
+
+ unsubscribe(connV11, "sub1");
+
+ connV11.disconnect();
+
+ //message should still there
+ MessageConsumer consumer = session.createConsumer(queue);
+ Message message = consumer.receive(1000);
+ Assert.assertNotNull(message);
+ }
+
+ public void testErrorWithReceipt2() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ subscribe(connV11, "sub1", "client");
+
+ sendMessage(getName());
+
+ ClientStompFrame frame = connV11.receiveFrame();
+
+ String messageID = frame.getHeader("message-id");
+
+ System.out.println("Received message with id " + messageID);
+
+ ClientStompFrame ackFrame = connV11.createFrame("ACK");
+ //give it a wrong sub id
+ ackFrame.addHeader("subscription", "sub1");
+ ackFrame.addHeader("message-id", String.valueOf(Long.valueOf(messageID) +
1));
+ ackFrame.addHeader("receipt", "answer-me");
+
+ ClientStompFrame error = connV11.sendFrame(ackFrame);
+
+ System.out.println("Receiver error: " + error);
+
+ assertEquals("ERROR", error.getCommand());
+
+ assertEquals("answer-me", error.getHeader("receipt-id"));
+
+ unsubscribe(connV11, "sub1");
+
+ connV11.disconnect();
+
+ //message should still there
+ MessageConsumer consumer = session.createConsumer(queue);
+ Message message = consumer.receive(1000);
+ Assert.assertNotNull(message);
+ }
+
+ public void testAckModeClient() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ subscribe(connV11, "sub1", "client");
+
+ int num = 50;
+ //send a bunch of messages
+ for (int i = 0; i < num; i++)
+ {
+ this.sendMessage("client-ack" + i);
+ }
+
+ ClientStompFrame frame = null;
+
+ for (int i = 0; i < num; i++)
+ {
+ frame = connV11.receiveFrame();
+ assertNotNull(frame);
+ }
+
+ //ack the last
+ this.ack(connV11, "sub1", frame);
+
+ unsubscribe(connV11, "sub1");
+
+ connV11.disconnect();
+
+ //no messages can be received.
+ MessageConsumer consumer = session.createConsumer(queue);
+ Message message = consumer.receive(1000);
+ Assert.assertNull(message);
+ }
+
+ public void testAckModeClient2() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ subscribe(connV11, "sub1", "client");
+
+ int num = 50;
+ //send a bunch of messages
+ for (int i = 0; i < num; i++)
+ {
+ this.sendMessage("client-ack" + i);
+ }
+
+ ClientStompFrame frame = null;
+
+ for (int i = 0; i < num; i++)
+ {
+ frame = connV11.receiveFrame();
+ assertNotNull(frame);
+
+ //ack the 49th
+ if (i == num - 2)
+ {
+ this.ack(connV11, "sub1", frame);
+ }
+ }
+
+ unsubscribe(connV11, "sub1");
+
+ connV11.disconnect();
+
+ //no messages can be received.
+ MessageConsumer consumer = session.createConsumer(queue);
+ Message message = consumer.receive(1000);
+ Assert.assertNotNull(message);
+ message = consumer.receive(1000);
+ Assert.assertNull(message);
+ }
+
+ public void testAckModeAuto() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ subscribe(connV11, "sub1", "auto");
+
+ int num = 50;
+ //send a bunch of messages
+ for (int i = 0; i < num; i++)
+ {
+ this.sendMessage("auto-ack" + i);
+ }
+
+ ClientStompFrame frame = null;
+
+ for (int i = 0; i < num; i++)
+ {
+ frame = connV11.receiveFrame();
+ assertNotNull(frame);
+ }
+
+ unsubscribe(connV11, "sub1");
+
+ connV11.disconnect();
+
+ //no messages can be received.
+ MessageConsumer consumer = session.createConsumer(queue);
+ Message message = consumer.receive(1000);
+ Assert.assertNull(message);
+ }
+
+ public void testAckModeClientIndividual() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ subscribe(connV11, "sub1", "client-individual");
+
+ int num = 50;
+ //send a bunch of messages
+ for (int i = 0; i < num; i++)
+ {
+ this.sendMessage("client-individual-ack" + i);
+ }
+
+ ClientStompFrame frame = null;
+
+ for (int i = 0; i < num; i++)
+ {
+ frame = connV11.receiveFrame();
+ assertNotNull(frame);
+
+ System.out.println(i + " == received: " + frame);
+ //ack on even numbers
+ if (i%2 == 0)
+ {
+ this.ack(connV11, "sub1", frame);
+ }
+ }
+
+ unsubscribe(connV11, "sub1");
+
+ connV11.disconnect();
+
+ //no messages can be received.
+ MessageConsumer consumer = session.createConsumer(queue);
+
+ TextMessage message = null;
+ for (int i = 0; i < num/2; i++)
+ {
+ message = (TextMessage) consumer.receive(1000);
+ Assert.assertNotNull(message);
+ System.out.println("Legal: " + message.getText());
+ }
+
+ message = (TextMessage) consumer.receive(1000);
+
+ Assert.assertNull(message);
+ }
+
+ public void testTwoSubscribers() throws Exception
+ {
+ connV11.connect(defUser, defPass, "myclientid");
+
+ this.subscribeTopic(connV11, "sub1", "auto", null);
+
+ StompClientConnection newConn =
StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+ newConn.connect(defUser, defPass, "myclientid2");
+
+ this.subscribeTopic(newConn, "sub2", "auto", null);
+
+ ClientStompFrame frame = connV11.createFrame("SEND");
+ frame.addHeader("destination", getTopicPrefix() + getTopicName());
+
+ frame.setBody("Hello World");
+
+ connV11.sendFrame(frame);
+
+ // receive message from socket
+ frame = connV11.receiveFrame(1000);
+
+ System.out.println("received frame : " + frame);
+ assertEquals("Hello World", frame.getBody());
+ assertEquals("sub1", frame.getHeader("subscription"));
+
+ frame = newConn.receiveFrame(1000);
+
+ System.out.println("received 2 frame : " + frame);
+ assertEquals("Hello World", frame.getBody());
+ assertEquals("sub2", frame.getHeader("subscription"));
+
+ // remove suscription
+ this.unsubscribe(connV11, "sub1", true);
+ this.unsubscribe(newConn, "sub2", true);
+
+ connV11.disconnect();
+ newConn.disconnect();
+ }
+
+ public void testSendAndReceiveOnDifferentConnections() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ ClientStompFrame sendFrame = connV11.createFrame("SEND");
+ sendFrame.addHeader("destination", getQueuePrefix() + getQueueName());
+ sendFrame.setBody("Hello World");
+
+ connV11.sendFrame(sendFrame);
+
+ StompClientConnection connV11_2 =
StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+ connV11_2.connect(defUser, defPass);
+
+ this.subscribe(connV11_2, "sub1", "auto");
+
+ ClientStompFrame frame = connV11_2.receiveFrame(2000);
+
+ assertEquals("MESSAGE", frame.getCommand());
+ assertEquals("Hello World", frame.getBody());
+
+ connV11.disconnect();
+ connV11_2.disconnect();
+ }
+
+ //----------------Note: tests below are adapted from StompTest
+
+ public void testBeginSameTransactionTwice() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ beginTransaction(connV11, "tx1");
+
+ beginTransaction(connV11, "tx1");
+
+ ClientStompFrame f = connV11.receiveFrame();
+ Assert.assertTrue(f.getCommand().equals("ERROR"));
+ }
+
+ public void testBodyWithUTF8() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ this.subscribe(connV11, getName(), "auto");
+
+ String text = "A" + "\u00ea" + "\u00f1" +
"\u00fc" + "C";
+ System.out.println(text);
+ sendMessage(text);
+
+ ClientStompFrame frame = connV11.receiveFrame();
+ System.out.println(frame);
+ Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
+ Assert.assertNotNull(frame.getHeader("destination"));
+ Assert.assertTrue(frame.getBody().equals(text));
+
+ connV11.disconnect();
+ }
+
+ public void testClientAckNotPartOfTransaction() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ this.subscribe(connV11, getName(), "client");
+
+ sendMessage(getName());
+
+ ClientStompFrame frame = connV11.receiveFrame();
+
+ Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
+ Assert.assertNotNull(frame.getHeader("destination"));
+ Assert.assertTrue(frame.getBody().equals(getName()));
+ Assert.assertNotNull(frame.getHeader("message-id"));
+
+ String messageID = frame.getHeader("message-id");
+
+ beginTransaction(connV11, "tx1");
+
+ this.ack(connV11, getName(), messageID, "tx1");
+
+ abortTransaction(connV11, "tx1");
+
+ frame = connV11.receiveFrame();
+
+ assertNull(frame);
+
+ this.unsubscribe(connV11, getName());
+
+ connV11.disconnect();
+ }
+
+ public void testDisconnectAndError() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ this.subscribe(connV11, getName(), "client");
+
+ ClientStompFrame frame = connV11.createFrame("DISCONNECT");
+ frame.addHeader("receipt", "1");
+
+ ClientStompFrame result = connV11.sendFrame(frame);
+
+ if (result == null || (!"RECEIPT".equals(result.getCommand())) ||
(!"1".equals(result.getHeader("receipt-id"))))
+ {
+ fail("Disconnect failed! " + result);
+ }
+
+ // sending a message will result in an error
+ ClientStompFrame sendFrame = connV11.createFrame("SEND");
+ sendFrame.addHeader("destination", getQueuePrefix() + getQueueName());
+ sendFrame.setBody("Hello World");
+
+ try
+ {
+ connV11.sendFrame(sendFrame);
+ fail("connection should have been closed by server.");
+ }
+ catch (ClosedChannelException e)
+ {
+ //ok.
+ }
+
+ connV11.destroy();
+ }
+
+ public void testDurableSubscriber() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ this.subscribe(connV11, "sub1", "client", getName());
+
+ this.subscribe(connV11, "sub1", "client", getName());
+
+ ClientStompFrame frame = connV11.receiveFrame();
+ Assert.assertTrue(frame.getCommand().equals("ERROR"));
+
+ connV11.disconnect();
+ }
+
+ public void testDurableSubscriberWithReconnection() throws Exception
+ {
+ connV11.connect(defUser, defPass, "myclientid");
+
+ this.subscribeTopic(connV11, "sub1", "auto", getName());
+
+ ClientStompFrame frame = connV11.createFrame("DISCONNECT");
+ frame.addHeader("receipt", "1");
+
+ ClientStompFrame result = connV11.sendFrame(frame);
+
+ if (result == null || (!"RECEIPT".equals(result.getCommand())) ||
(!"1".equals(result.getHeader("receipt-id"))))
+ {
+ fail("Disconnect failed! " + result);
+ }
+
+ // send the message when the durable subscriber is disconnected
+ sendMessage(getName(), topic);
+
+ connV11.destroy();
+ connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
+ connV11.connect(defUser, defPass, "myclientid");
+
+ this.subscribeTopic(connV11, "sub1", "auto", getName());
+
+ // we must have received the message
+ frame = connV11.receiveFrame();
+
+ Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
+ Assert.assertNotNull(frame.getHeader("destination"));
+ Assert.assertEquals(getName(), frame.getBody());
+
+ this.unsubscribe(connV11, "sub1");
+
+ connV11.disconnect();
+ }
+
+ public void testJMSXGroupIdCanBeSet() throws Exception
+ {
+ MessageConsumer consumer = session.createConsumer(queue);
+
+ connV11.connect(defUser, defPass);
+
+ ClientStompFrame frame = connV11.createFrame("SEND");
+ frame.addHeader("destination", getQueuePrefix() + getQueueName());
+ frame.addHeader("JMSXGroupID", "TEST");
+ frame.setBody("Hello World");
+
+ connV11.sendFrame(frame);
+
+ TextMessage message = (TextMessage)consumer.receive(1000);
+ Assert.assertNotNull(message);
+ Assert.assertEquals("Hello World", message.getText());
+ // differ from StompConnect
+ Assert.assertEquals("TEST",
message.getStringProperty("JMSXGroupID"));
+ }
+
+ public void testMessagesAreInOrder() throws Exception
+ {
+ int ctr = 10;
+ String[] data = new String[ctr];
+
+ connV11.connect(defUser, defPass);
+
+ this.subscribe(connV11, "sub1", "auto");
+
+ for (int i = 0; i < ctr; ++i)
+ {
+ data[i] = getName() + i;
+ sendMessage(data[i]);
+ }
+
+ ClientStompFrame frame = null;
+
+ for (int i = 0; i < ctr; ++i)
+ {
+ frame = connV11.receiveFrame();
+ Assert.assertTrue("Message not in order",
frame.getBody().equals(data[i]));
+ }
+
+ for (int i = 0; i < ctr; ++i)
+ {
+ data[i] = getName() + ":second:" + i;
+ sendMessage(data[i]);
+ }
+
+ for (int i = 0; i < ctr; ++i)
+ {
+ frame = connV11.receiveFrame();
+ Assert.assertTrue("Message not in order",
frame.getBody().equals(data[i]));
+ }
+
+ connV11.disconnect();
+ }
+
+ public void testSubscribeWithAutoAckAndSelector() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ this.subscribe(connV11, "sub1", "auto", null, "foo =
'zzz'");
+
+ sendMessage("Ignored message", "foo", "1234");
+ sendMessage("Real message", "foo", "zzz");
+
+ ClientStompFrame frame = connV11.receiveFrame();
+
+ Assert.assertTrue("Should have received the real message but got: " +
frame, frame.getBody().equals("Real message"));
+
+ connV11.disconnect();
+ }
+
+ public void testRedeliveryWithClientAck() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ this.subscribe(connV11, "subId", "client");
+
+ sendMessage(getName());
+
+ ClientStompFrame frame = connV11.receiveFrame();
+
+ assertTrue(frame.getCommand().equals("MESSAGE"));
+
+ connV11.disconnect();
+
+ // message should be received since message was not acknowledged
+ MessageConsumer consumer = session.createConsumer(queue);
+ Message message = consumer.receive(1000);
+ Assert.assertNotNull(message);
+ Assert.assertTrue(message.getJMSRedelivered());
+ }
+
+ public void testSendManyMessages() throws Exception
+ {
+ MessageConsumer consumer = session.createConsumer(queue);
+
+ connV11.connect(defUser, defPass);
+
+ int count = 1000;
+ final CountDownLatch latch = new CountDownLatch(count);
+ consumer.setMessageListener(new MessageListener()
+ {
+ public void onMessage(Message arg0)
+ {
+ latch.countDown();
+ }
+ });
+
+ ClientStompFrame frame = connV11.createFrame("SEND");
+ frame.addHeader("destination", getQueuePrefix() + getQueueName());
+ frame.setBody("Hello World");
+
+ for (int i = 1; i <= count; i++)
+ {
+ connV11.sendFrame(frame);
+ }
+
+ assertTrue(latch.await(60, TimeUnit.SECONDS));
+
+ connV11.disconnect();
+ }
+
+ public void testSendMessage() throws Exception
+ {
+ MessageConsumer consumer = session.createConsumer(queue);
+
+ connV11.connect(defUser, defPass);
+
+ ClientStompFrame frame = connV11.createFrame("SEND");
+ frame.addHeader("destination", getQueuePrefix() + getQueueName());
+ frame.setBody("Hello World");
+
+ connV11.sendFrame(frame);
+
+ TextMessage message = (TextMessage)consumer.receive(1000);
+ Assert.assertNotNull(message);
+ Assert.assertEquals("Hello World", message.getText());
+ // Assert default priority 4 is used when priority header is not set
+ Assert.assertEquals("getJMSPriority", 4, message.getJMSPriority());
+
+ // Make sure that the timestamp is valid - should
+ // be very close to the current time.
+ long tnow = System.currentTimeMillis();
+ long tmsg = message.getJMSTimestamp();
+ Assert.assertTrue(Math.abs(tnow - tmsg) < 1000);
+ }
+
+ public void testSendMessageWithContentLength() throws Exception
+ {
+ MessageConsumer consumer = session.createConsumer(queue);
+
+ connV11.connect(defUser, defPass);
+
+ byte[] data = new byte[] { 1, 0, 0, 4 };
+
+ ClientStompFrame frame = connV11.createFrame("SEND");
+
+ frame.addHeader("destination", getQueuePrefix() + getQueueName());
+ frame.setBody(new String(data, "UTF-8"));
+
+ frame.addHeader("content-length", String.valueOf(data.length));
+
+ connV11.sendFrame(frame);
+
+ BytesMessage message = (BytesMessage)consumer.receive(10000);
+ Assert.assertNotNull(message);
+
+ assertEquals(data.length, message.getBodyLength());
+ assertEquals(data[0], message.readByte());
+ assertEquals(data[1], message.readByte());
+ assertEquals(data[2], message.readByte());
+ assertEquals(data[3], message.readByte());
+ }
+
+ public void testSendMessageWithCustomHeadersAndSelector() throws Exception
+ {
+ MessageConsumer consumer = session.createConsumer(queue, "foo =
'abc'");
+
+ connV11.connect(defUser, defPass);
+
+ ClientStompFrame frame = connV11.createFrame("SEND");
+ frame.addHeader("foo", "abc");
+ frame.addHeader("bar", "123");
+
+ frame.addHeader("destination", getQueuePrefix() + getQueueName());
+ frame.setBody("Hello World");
+
+ connV11.sendFrame(frame);
+
+ TextMessage message = (TextMessage)consumer.receive(1000);
+ Assert.assertNotNull(message);
+ Assert.assertEquals("Hello World", message.getText());
+ Assert.assertEquals("foo", "abc",
message.getStringProperty("foo"));
+ Assert.assertEquals("bar", "123",
message.getStringProperty("bar"));
+ }
+
+ public void testSendMessageWithLeadingNewLine() throws Exception
+ {
+ MessageConsumer consumer = session.createConsumer(queue);
+
+ connV11.connect(defUser, defPass);
+
+ ClientStompFrame frame = connV11.createFrame("SEND");
+
+ frame.addHeader("destination", getQueuePrefix() + getQueueName());
+ frame.setBody("Hello World");
+
+ connV11.sendWickedFrame(frame);
+
+ TextMessage message = (TextMessage)consumer.receive(1000);
+ Assert.assertNotNull(message);
+ Assert.assertEquals("Hello World", message.getText());
+
+ // Make sure that the timestamp is valid - should
+ // be very close to the current time.
+ long tnow = System.currentTimeMillis();
+ long tmsg = message.getJMSTimestamp();
+ Assert.assertTrue(Math.abs(tnow - tmsg) < 1000);
+
+ assertNull(consumer.receive(1000));
+
+ connV11.disconnect();
+ }
+
+ public void testSendMessageWithReceipt() throws Exception
+ {
+ MessageConsumer consumer = session.createConsumer(queue);
+
+ connV11.connect(defUser, defPass);
+
+ ClientStompFrame frame = connV11.createFrame("SEND");
+ frame.addHeader("destination", getQueuePrefix() + getQueueName());
+ frame.addHeader("receipt", "1234");
+ frame.setBody("Hello World");
+
+ frame = connV11.sendFrame(frame);
+
+ assertTrue(frame.getCommand().equals("RECEIPT"));
+ assertEquals("1234", frame.getHeader("receipt-id"));
+
+ TextMessage message = (TextMessage)consumer.receive(1000);
+ Assert.assertNotNull(message);
+ Assert.assertEquals("Hello World", message.getText());
+
+ // Make sure that the timestamp is valid - should
+ // be very close to the current time.
+ long tnow = System.currentTimeMillis();
+ long tmsg = message.getJMSTimestamp();
+ Assert.assertTrue(Math.abs(tnow - tmsg) < 1000);
+
+ connV11.disconnect();
+ }
+
+ public void testSendMessageWithStandardHeaders() throws Exception
+ {
+ MessageConsumer consumer = session.createConsumer(queue);
+
+ connV11.connect(defUser, defPass);
+
+ ClientStompFrame frame = connV11.createFrame("SEND");
+ frame.addHeader("destination", getQueuePrefix() + getQueueName());
+ frame.addHeader("correlation-id", "c123");
+ frame.addHeader("persistent", "true");
+ frame.addHeader("priority", "3");
+ frame.addHeader("type", "t345");
+ frame.addHeader("JMSXGroupID", "abc");
+ frame.addHeader("foo", "abc");
+ frame.addHeader("bar", "123");
+
+ frame.setBody("Hello World");
+
+ frame = connV11.sendFrame(frame);
+
+ TextMessage message = (TextMessage)consumer.receive(1000);
+ Assert.assertNotNull(message);
+ Assert.assertEquals("Hello World", message.getText());
+ Assert.assertEquals("JMSCorrelationID", "c123",
message.getJMSCorrelationID());
+ Assert.assertEquals("getJMSType", "t345",
message.getJMSType());
+ Assert.assertEquals("getJMSPriority", 3, message.getJMSPriority());
+ Assert.assertEquals(DeliveryMode.PERSISTENT, message.getJMSDeliveryMode());
+ Assert.assertEquals("foo", "abc",
message.getStringProperty("foo"));
+ Assert.assertEquals("bar", "123",
message.getStringProperty("bar"));
+
+ Assert.assertEquals("JMSXGroupID", "abc",
message.getStringProperty("JMSXGroupID"));
+
+ connV11.disconnect();
+ }
+
+ public void testSubscribeToTopic() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ this.subscribeTopic(connV11, "sub1", null, null, true);
+
+ sendMessage(getName(), topic);
+
+ ClientStompFrame frame = connV11.receiveFrame();
+
+ Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
+ Assert.assertTrue(frame.getHeader("destination").equals(getTopicPrefix()
+ getTopicName()));
+ Assert.assertTrue(frame.getBody().equals(getName()));
+
+ this.unsubscribe(connV11, "sub1", true);
+
+ sendMessage(getName(), topic);
+
+ frame = connV11.receiveFrame(1000);
+ assertNull(frame);
+
+ connV11.disconnect();
+ }
+
+ public void testSubscribeToTopicWithNoLocal() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ this.subscribeTopic(connV11, "sub1", null, null, true, true);
+
+ // send a message on the same connection => it should not be received
+ ClientStompFrame frame = connV11.createFrame("SEND");
+ frame.addHeader("destination", getTopicPrefix() + getTopicName());
+
+ frame.setBody("Hello World");
+
+ connV11.sendFrame(frame);
+
+ frame = connV11.receiveFrame(2000);
+
+ assertNull(frame);
+
+ // send message on another JMS connection => it should be received
+ sendMessage(getName(), topic);
+
+ frame = connV11.receiveFrame();
+
+ Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
+ Assert.assertTrue(frame.getHeader("destination").equals(getTopicPrefix()
+ getTopicName()));
+ Assert.assertTrue(frame.getBody().equals(getName()));
+
+ this.unsubscribe(connV11, "sub1");
+
+ connV11.disconnect();
+ }
+
+ public void testSubscribeWithAutoAck() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ this.subscribe(connV11, "sub1", "auto");
+
+ sendMessage(getName());
+
+ ClientStompFrame frame = connV11.receiveFrame();
+
+ Assert.assertEquals("MESSAGE", frame.getCommand());
+ Assert.assertNotNull(frame.getHeader("destination"));
+ Assert.assertEquals(getName(), frame.getBody());
+
+ connV11.disconnect();
+
+ // message should not be received as it was auto-acked
+ MessageConsumer consumer = session.createConsumer(queue);
+ Message message = consumer.receive(1000);
+ Assert.assertNull(message);
+ }
+
+ public void testSubscribeWithAutoAckAndBytesMessage() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ this.subscribe(connV11, "sub1", "auto");
+
+ byte[] payload = new byte[] { 1, 2, 3, 4, 5 };
+ sendMessage(payload, queue);
+
+ ClientStompFrame frame = connV11.receiveFrame();
+
+ assertEquals("MESSAGE", frame.getCommand());
+
+ System.out.println("Message: " + frame);
+
+ assertEquals("5", frame.getHeader("content-length"));
+
+ assertEquals(null, frame.getHeader("type"));
+
+ assertEquals(frame.getBody(), new String(payload, "UTF-8"));
+
+ connV11.disconnect();
+ }
+
+ public void testSubscribeWithClientAck() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ this.subscribe(connV11, "sub1", "client");
+
+ sendMessage(getName());
+
+ ClientStompFrame frame = connV11.receiveFrame();
+
+ this.ack(connV11, "sub1", frame);
+
+ connV11.disconnect();
+
+ // message should not be received since message was acknowledged by the client
+ MessageConsumer consumer = session.createConsumer(queue);
+ Message message = consumer.receive(1000);
+ Assert.assertNull(message);
+ }
+
+ public void
testSubscribeWithClientAckThenConsumingAgainWithAutoAckWithExplicitDisconnect() throws
Exception
+ {
+ assertSubscribeWithClientAckThenConsumeWithAutoAck(true);
+ }
+
+ public void
testSubscribeWithClientAckThenConsumingAgainWithAutoAckWithNoDisconnectFrame() throws
Exception
+ {
+ assertSubscribeWithClientAckThenConsumeWithAutoAck(false);
+ }
+
+ public void testSubscribeWithID() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ this.subscribe(connV11, "mysubid", "auto");
+
+ sendMessage(getName());
+
+ ClientStompFrame frame = connV11.receiveFrame();
+
+ Assert.assertTrue(frame.getHeader("subscription") != null);
+
+ connV11.disconnect();
+ }
+
+ public void testSubscribeWithMessageSentWithProperties() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ this.subscribe(connV11, "sub1", "auto");
+
+ MessageProducer producer = session.createProducer(queue);
+ BytesMessage message = session.createBytesMessage();
+ message.setStringProperty("S", "value");
+ message.setBooleanProperty("n", false);
+ message.setByteProperty("byte", (byte)9);
+ message.setDoubleProperty("d", 2.0);
+ message.setFloatProperty("f", (float)6.0);
+ message.setIntProperty("i", 10);
+ message.setLongProperty("l", 121);
+ message.setShortProperty("s", (short)12);
+ message.writeBytes("Hello World".getBytes("UTF-8"));
+ producer.send(message);
+
+ ClientStompFrame frame = connV11.receiveFrame();
+ Assert.assertNotNull(frame);
+
+ Assert.assertTrue(frame.getHeader("S") != null);
+ Assert.assertTrue(frame.getHeader("n") != null);
+ Assert.assertTrue(frame.getHeader("byte") != null);
+ Assert.assertTrue(frame.getHeader("d") != null);
+ Assert.assertTrue(frame.getHeader("f") != null);
+ Assert.assertTrue(frame.getHeader("i") != null);
+ Assert.assertTrue(frame.getHeader("l") != null);
+ Assert.assertTrue(frame.getHeader("s") != null);
+ Assert.assertEquals("Hello World", frame.getBody());
+
+ connV11.disconnect();
+ }
+
+ public void testSuccessiveTransactionsWithSameID() throws Exception
+ {
+ MessageConsumer consumer = session.createConsumer(queue);
+
+ connV11.connect(defUser, defPass);
+
+ // first tx
+ this.beginTransaction(connV11, "tx1");
+
+ ClientStompFrame frame = connV11.createFrame("SEND");
+ frame.addHeader("destination", getQueuePrefix() + getQueueName());
+ frame.addHeader("transaction", "tx1");
+ frame.setBody("Hello World");
+
+ connV11.sendFrame(frame);
+
+ this.commitTransaction(connV11, "tx1");
+
+ Message message = consumer.receive(1000);
+ Assert.assertNotNull("Should have received a message", message);
+
+ // 2nd tx with same tx ID
+ this.beginTransaction(connV11, "tx1");
+
+ frame = connV11.createFrame("SEND");
+ frame.addHeader("destination", getQueuePrefix() + getQueueName());
+ frame.addHeader("transaction", "tx1");
+
+ frame.setBody("Hello World");
+
+ connV11.sendFrame(frame);
+
+ this.commitTransaction(connV11, "tx1");
+
+ message = consumer.receive(1000);
+ Assert.assertNotNull("Should have received a message", message);
+
+ connV11.disconnect();
+ }
+
+ public void testTransactionCommit() throws Exception
+ {
+ MessageConsumer consumer = session.createConsumer(queue);
+
+ connV11.connect(defUser, defPass);
+
+ this.beginTransaction(connV11, "tx1");
+
+ ClientStompFrame frame = connV11.createFrame("SEND");
+ frame.addHeader("destination", getQueuePrefix() + getQueueName());
+ frame.addHeader("transaction", "tx1");
+ frame.addHeader("receipt", "123");
+ frame.setBody("Hello World");
+
+ frame = connV11.sendFrame(frame);
+
+ assertEquals("123", frame.getHeader("receipt-id"));
+
+ // check the message is not committed
+ assertNull(consumer.receive(100));
+
+ this.commitTransaction(connV11, "tx1", true);
+
+ Message message = consumer.receive(1000);
+ Assert.assertNotNull("Should have received a message", message);
+
+ connV11.disconnect();
+ }
+
+ public void testTransactionRollback() throws Exception
+ {
+ MessageConsumer consumer = session.createConsumer(queue);
+
+ connV11.connect(defUser, defPass);
+
+ this.beginTransaction(connV11, "tx1");
+
+ ClientStompFrame frame = connV11.createFrame("SEND");
+ frame.addHeader("destination", getQueuePrefix() + getQueueName());
+ frame.addHeader("transaction", "tx1");
+
+ frame.setBody("first message");
+
+ connV11.sendFrame(frame);
+
+ // rollback first message
+ this.abortTransaction(connV11, "tx1");
+
+ this.beginTransaction(connV11, "tx1");
+
+ frame = connV11.createFrame("SEND");
+ frame.addHeader("destination", getQueuePrefix() + getQueueName());
+ frame.addHeader("transaction", "tx1");
+
+ frame.setBody("second message");
+
+ connV11.sendFrame(frame);
+
+ this.commitTransaction(connV11, "tx1", true);
+
+ // only second msg should be received since first msg was rolled back
+ TextMessage message = (TextMessage)consumer.receive(1000);
+ Assert.assertNotNull(message);
+ Assert.assertEquals("second message", message.getText());
+
+ connV11.disconnect();
+ }
+
+ public void testUnsubscribe() throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ this.subscribe(connV11, "sub1", "auto");
+
+ // send a message to our queue
+ sendMessage("first message");
+
+ // receive message from socket
+ ClientStompFrame frame = connV11.receiveFrame();
+
+ Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
+
+ // remove suscription
+ this.unsubscribe(connV11, "sub1", true);
+
+ // send a message to our queue
+ sendMessage("second message");
+
+ frame = connV11.receiveFrame(1000);
+ assertNull(frame);
+
+ connV11.disconnect();
+ }
+
+ //-----------------private help methods
+
+ private void abortTransaction(StompClientConnection conn, String txID) throws
IOException, InterruptedException
+ {
+ ClientStompFrame abortFrame = conn.createFrame("ABORT");
+ abortFrame.addHeader("transaction", txID);
+
+ conn.sendFrame(abortFrame);
+ }
+
+ private void beginTransaction(StompClientConnection conn, String txID) throws
IOException, InterruptedException
+ {
+ ClientStompFrame beginFrame = conn.createFrame("BEGIN");
+ beginFrame.addHeader("transaction", txID);
+
+ conn.sendFrame(beginFrame);
+ }
+
+ private void commitTransaction(StompClientConnection conn, String txID) throws
IOException, InterruptedException
+ {
+ commitTransaction(conn, txID, false);
+ }
+
+ private void commitTransaction(StompClientConnection conn, String txID, boolean
receipt) throws IOException, InterruptedException
+ {
+ ClientStompFrame beginFrame = conn.createFrame("COMMIT");
+ beginFrame.addHeader("transaction", txID);
+ if (receipt)
+ {
+ beginFrame.addHeader("receipt", "1234");
+ }
+ ClientStompFrame resp = conn.sendFrame(beginFrame);
+ if (receipt)
+ {
+ assertEquals("1234", resp.getHeader("receipt-id"));
+ }
+ }
+
+ private void ack(StompClientConnection conn, String subId,
+ ClientStompFrame frame) throws IOException, InterruptedException
+ {
+ String messageID = frame.getHeader("message-id");
+
+ ClientStompFrame ackFrame = conn.createFrame("ACK");
+
+ ackFrame.addHeader("subscription", subId);
+ ackFrame.addHeader("message-id", messageID);
+
+ ClientStompFrame response = conn.sendFrame(ackFrame);
+ if (response != null)
+ {
+ throw new IOException("failed to ack " + response);
+ }
+ }
+
+ private void ack(StompClientConnection conn, String subId, String mid, String txID)
throws IOException, InterruptedException
+ {
+ ClientStompFrame ackFrame = conn.createFrame("ACK");
+ ackFrame.addHeader("subscription", subId);
+ ackFrame.addHeader("message-id", mid);
+ if (txID != null)
+ {
+ ackFrame.addHeader("transaction", txID);
+ }
+
+ conn.sendFrame(ackFrame);
+ }
+
+ private void nack(StompClientConnection conn, String subId, String mid) throws
IOException, InterruptedException
+ {
+ ClientStompFrame ackFrame = conn.createFrame("NACK");
+ ackFrame.addHeader("subscription", subId);
+ ackFrame.addHeader("message-id", mid);
+
+ conn.sendFrame(ackFrame);
+ }
+
+ private void subscribe(StompClientConnection conn, String subId, String ack) throws
IOException, InterruptedException
+ {
+ subscribe(conn, subId, ack, null, null);
+ }
+
+ private void subscribe(StompClientConnection conn, String subId,
+ String ack, String durableId) throws IOException, InterruptedException
+ {
+ subscribe(conn, subId, ack, durableId, null);
+ }
+
+ private void subscribe(StompClientConnection conn, String subId,
+ String ack, String durableId, boolean receipt) throws IOException,
InterruptedException
+ {
+ subscribe(conn, subId, ack, durableId, null, receipt);
+ }
+
+ private void subscribe(StompClientConnection conn, String subId, String ack,
+ String durableId, String selector) throws IOException,
+ InterruptedException
+ {
+ subscribe(conn, subId, ack, durableId, selector, false);
+ }
+
+ private void subscribe(StompClientConnection conn, String subId,
+ String ack, String durableId, String selector, boolean receipt) throws
IOException, InterruptedException
+ {
+ ClientStompFrame subFrame = conn.createFrame("SUBSCRIBE");
+ subFrame.addHeader("id", subId);
+ subFrame.addHeader("destination", getQueuePrefix() + getQueueName());
+ if (ack != null)
+ {
+ subFrame.addHeader("ack", ack);
+ }
+ if (durableId != null)
+ {
+ subFrame.addHeader("durable-subscriber-name", durableId);
+ }
+ if (selector != null)
+ {
+ subFrame.addHeader("selector", selector);
+ }
+ if (receipt)
+ {
+ subFrame.addHeader("receipt", "1234");
+ }
+
+ subFrame = conn.sendFrame(subFrame);
+
+ if (receipt)
+ {
+ assertEquals("1234", subFrame.getHeader("receipt-id"));
+ }
+ }
+
+ private void subscribeTopic(StompClientConnection conn, String subId,
+ String ack, String durableId) throws IOException, InterruptedException
+ {
+ subscribeTopic(conn, subId, ack, durableId, false);
+ }
+
+ private void subscribeTopic(StompClientConnection conn, String subId,
+ String ack, String durableId, boolean receipt) throws IOException,
InterruptedException
+ {
+ subscribeTopic(conn, subId, ack, durableId, receipt, false);
+ }
+
+ private void subscribeTopic(StompClientConnection conn, String subId,
+ String ack, String durableId, boolean receipt, boolean noLocal) throws
IOException, InterruptedException
+ {
+ ClientStompFrame subFrame = conn.createFrame("SUBSCRIBE");
+ subFrame.addHeader("id", subId);
+ subFrame.addHeader("destination", getTopicPrefix() + getTopicName());
+ if (ack != null)
+ {
+ subFrame.addHeader("ack", ack);
+ }
+ if (durableId != null)
+ {
+ subFrame.addHeader("durable-subscriber-name", durableId);
+ }
+ if (receipt)
+ {
+ subFrame.addHeader("receipt", "1234");
+ }
+ if (noLocal)
+ {
+ subFrame.addHeader("no-local", "true");
+ }
+
+ ClientStompFrame frame = conn.sendFrame(subFrame);
+
+ if (receipt)
+ {
+ assertTrue(frame.getHeader("receipt-id").equals("1234"));
+ }
+ }
+
+ private void unsubscribe(StompClientConnection conn, String subId) throws IOException,
InterruptedException
+ {
+ ClientStompFrame subFrame = conn.createFrame("UNSUBSCRIBE");
+ subFrame.addHeader("id", subId);
+
+ conn.sendFrame(subFrame);
+ }
+
+ private void unsubscribe(StompClientConnection conn, String subId,
+ boolean receipt) throws IOException, InterruptedException
+ {
+ ClientStompFrame subFrame = conn.createFrame("UNSUBSCRIBE");
+ subFrame.addHeader("id", subId);
+
+ if (receipt)
+ {
+ subFrame.addHeader("receipt", "4321");
+ }
+
+ ClientStompFrame f = conn.sendFrame(subFrame);
+
+ if (receipt)
+ {
+ System.out.println("response: " + f);
+ assertEquals("RECEIPT", f.getCommand());
+ assertEquals("4321", f.getHeader("receipt-id"));
+ }
+ }
+
+ protected void assertSubscribeWithClientAckThenConsumeWithAutoAck(boolean
sendDisconnect) throws Exception
+ {
+ connV11.connect(defUser, defPass);
+
+ this.subscribe(connV11, "sub1", "client");
+
+ sendMessage(getName());
+
+ ClientStompFrame frame = connV11.receiveFrame();
+
+ Assert.assertEquals("MESSAGE", frame.getCommand());
+
+ log.info("Reconnecting!");
+
+ if (sendDisconnect)
+ {
+ connV11.disconnect();
+ connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
+ }
+ else
+ {
+ connV11.destroy();
+ connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
+ }
+
+ // message should be received since message was not acknowledged
+ connV11.connect(defUser, defPass);
+
+ this.subscribe(connV11, "sub1", null);
+
+ frame = connV11.receiveFrame();
+ Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
+
+ connV11.disconnect();
+
+ // now lets make sure we don't see the message again
+ connV11.destroy();
+ connV11 = StompClientConnectionFactory.createClientConnection("1.1",
hostname, port);
+ connV11.connect(defUser, defPass);
+
+ this.subscribe(connV11, "sub1", null, null, true);
+
+ sendMessage("shouldBeNextMessage");
+
+ frame = connV11.receiveFrame();
+ Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
+ Assert.assertEquals("shouldBeNextMessage", frame.getBody());
+ }
+
+}
+
+
+
+
+