You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ma...@apache.org on 2016/09/27 13:54:28 UTC
[01/15] activemq-artemis git commit: ARTEMIS-751 Simplification of
the AMQP implementation
Repository: activemq-artemis
Updated Branches:
refs/heads/master 4e349693f -> 0ac9dbd57
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonTestForHeader.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonTestForHeader.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonTestForHeader.java
deleted file mode 100644
index d23bd5b..0000000
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonTestForHeader.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.tests.integration.proton;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-import java.util.HashMap;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.activemq.artemis.api.core.TransportConfiguration;
-import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
-import org.apache.activemq.artemis.core.server.ActiveMQServer;
-import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
-import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger;
-import org.apache.activemq.artemis.tests.util.Wait;
-import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.fusesource.hawtbuf.Buffer;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class ProtonTestForHeader extends ActiveMQTestBase {
-
- private ActiveMQServer server;
-
- @Override
- @Before
- public void setUp() throws Exception {
- super.setUp();
- server = this.createServer(true, true);
- HashMap<String, Object> params = new HashMap<>();
- params.put(TransportConstants.PORT_PROP_NAME, "5672");
- params.put(TransportConstants.PROTOCOLS_PROP_NAME, "AMQP");
- TransportConfiguration transportConfiguration = new TransportConfiguration(NETTY_ACCEPTOR_FACTORY, params);
-
- server.getConfiguration().getAcceptorConfigurations().add(transportConfiguration);
- server.getConfiguration().setSecurityEnabled(true);
- server.start();
- ActiveMQJAASSecurityManager securityManager = (ActiveMQJAASSecurityManager) server.getSecurityManager();
- securityManager.getConfiguration().addUser("auser", "pass");
- }
-
- @Override
- @After
- public void tearDown() throws Exception {
- try {
- server.stop();
- }
- finally {
- super.tearDown();
- }
- }
-
- @Test
- public void testSimpleBytes() throws Exception {
- final AmqpHeader header = new AmqpHeader();
-
- header.setProtocolId(0);
- header.setMajor(1);
- header.setMinor(0);
- header.setRevision(0);
-
- final ClientConnection connection = new ClientConnection();
- connection.open("localhost", 5672);
- connection.send(header);
-
- AmqpHeader response = connection.readAmqpHeader();
- assertNotNull(response);
- IntegrationTestLogger.LOGGER.info("Broker responded with: " + response);
-
- assertTrue("Broker should have closed client connection", Wait.waitFor(new Wait.Condition() {
-
- @Override
- public boolean isSatisfied() throws Exception {
- try {
- connection.send(header);
- return false;
- }
- catch (Exception e) {
- return true;
- }
- }
- }, TimeUnit.SECONDS.toMillis(15), TimeUnit.MILLISECONDS.toMillis(250)));
- }
-
- private class ClientConnection {
-
- protected static final long RECEIVE_TIMEOUT = 10000;
- protected Socket clientSocket;
-
- public void open(String host, int port) throws IOException {
- clientSocket = new Socket(host, port);
- clientSocket.setTcpNoDelay(true);
- }
-
- public void send(AmqpHeader header) throws Exception {
- IntegrationTestLogger.LOGGER.info("Client sending header: " + header);
- OutputStream outputStream = clientSocket.getOutputStream();
- header.getBuffer().writeTo(outputStream);
- outputStream.flush();
- }
-
- public AmqpHeader readAmqpHeader() throws Exception {
- clientSocket.setSoTimeout((int) RECEIVE_TIMEOUT);
- InputStream is = clientSocket.getInputStream();
-
- byte[] header = new byte[8];
- int read = is.read(header);
- if (read == header.length) {
- return new AmqpHeader(new Buffer(header));
- }
- else {
- return null;
- }
- }
- }
-
- private class AmqpHeader {
-
- final Buffer PREFIX = new Buffer(new byte[]{'A', 'M', 'Q', 'P'});
-
- private Buffer buffer;
-
- AmqpHeader() {
- this(new Buffer(new byte[]{'A', 'M', 'Q', 'P', 0, 1, 0, 0}));
- }
-
- AmqpHeader(Buffer buffer) {
- this(buffer, true);
- }
-
- AmqpHeader(Buffer buffer, boolean validate) {
- setBuffer(buffer, validate);
- }
-
- public int getProtocolId() {
- return buffer.get(4) & 0xFF;
- }
-
- public void setProtocolId(int value) {
- buffer.data[buffer.offset + 4] = (byte) value;
- }
-
- public int getMajor() {
- return buffer.get(5) & 0xFF;
- }
-
- public void setMajor(int value) {
- buffer.data[buffer.offset + 5] = (byte) value;
- }
-
- public int getMinor() {
- return buffer.get(6) & 0xFF;
- }
-
- public void setMinor(int value) {
- buffer.data[buffer.offset + 6] = (byte) value;
- }
-
- public int getRevision() {
- return buffer.get(7) & 0xFF;
- }
-
- public void setRevision(int value) {
- buffer.data[buffer.offset + 7] = (byte) value;
- }
-
- public Buffer getBuffer() {
- return buffer;
- }
-
- public void setBuffer(Buffer value) {
- setBuffer(value, true);
- }
-
- public void setBuffer(Buffer value, boolean validate) {
- if (validate && !value.startsWith(PREFIX) || value.length() != 8) {
- throw new IllegalArgumentException("Not an AMQP header buffer");
- }
- buffer = value.buffer();
- }
-
- public boolean hasValidPrefix() {
- return buffer.startsWith(PREFIX);
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- for (int i = 0; i < buffer.length(); ++i) {
- char value = (char) buffer.get(i);
- if (Character.isLetter(value)) {
- builder.append(value);
- }
- else {
- builder.append(",");
- builder.append((int) value);
- }
- }
- return builder.toString();
- }
- }
-}
[03/15] activemq-artemis git commit: ARTEMIS-751 Simplification of
the AMQP implementation
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTest.java
new file mode 100644
index 0000000..53e676f
--- /dev/null
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTest.java
@@ -0,0 +1,1548 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.tests.integration.amqp;
+
+import static org.apache.activemq.artemis.protocol.amqp.proton.AmqpSupport.contains;
+import static org.apache.activemq.artemis.protocol.amqp.proton.AmqpSupport.DELAYED_DELIVERY;
+import static org.apache.activemq.artemis.protocol.amqp.proton.AmqpSupport.PRODUCT;
+import static org.apache.activemq.artemis.protocol.amqp.proton.AmqpSupport.VERSION;
+
+import javax.jms.BytesMessage;
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.DeliveryMode;
+import javax.jms.Destination;
+import javax.jms.ExceptionListener;
+import javax.jms.InvalidClientIDException;
+import javax.jms.JMSException;
+import javax.jms.MapMessage;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.ObjectMessage;
+import javax.jms.QueueBrowser;
+import javax.jms.ResourceAllocationException;
+import javax.jms.Session;
+import javax.jms.StreamMessage;
+import javax.jms.TemporaryQueue;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+import javax.jms.TopicSession;
+import javax.jms.TopicSubscriber;
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.core.postoffice.Bindings;
+import org.apache.activemq.artemis.core.remoting.CloseListener;
+import org.apache.activemq.artemis.core.server.Queue;
+import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy;
+import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
+import org.apache.activemq.artemis.utils.ByteUtil;
+import org.apache.activemq.artemis.utils.VersionLoader;
+import org.apache.activemq.transport.amqp.client.AmqpClient;
+import org.apache.activemq.transport.amqp.client.AmqpConnection;
+import org.apache.activemq.transport.amqp.client.AmqpMessage;
+import org.apache.activemq.transport.amqp.client.AmqpReceiver;
+import org.apache.activemq.transport.amqp.client.AmqpSender;
+import org.apache.activemq.transport.amqp.client.AmqpSession;
+import org.apache.activemq.transport.amqp.client.AmqpValidator;
+import org.apache.qpid.jms.JmsConnectionFactory;
+import org.apache.qpid.proton.amqp.Symbol;
+import org.apache.qpid.proton.amqp.messaging.AmqpValue;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.apache.activemq.artemis.protocol.amqp.proton.ProtonServerReceiverContext;
+
+@RunWith(Parameterized.class)
+public class ProtonTest extends ProtonTestBase {
+
+ private static final String amqpConnectionUri = "amqp://localhost:5672";
+
+ private static final String tcpAmqpConnectionUri = "tcp://localhost:5672";
+
+ private static final String userName = "guest";
+
+ private static final String password = "guest";
+
+
+ private static final String brokerName = "my-broker";
+
+ private static final long maxSizeBytes = 1 * 1024 * 1024;
+
+ private static final long maxSizeBytesRejectThreshold = 2 * 1024 * 1024;
+
+ private int messagesSent = 0;
+
+ // this will ensure that all tests in this class are run twice,
+ // once with "true" passed to the class' constructor and once with "false"
+ @Parameterized.Parameters(name = "{0}")
+ public static Collection getParameters() {
+
+ // these 3 are for comparison
+ return Arrays.asList(new Object[][]{{"AMQP", 0}, {"AMQP_ANONYMOUS", 3}});
+ }
+
+ ConnectionFactory factory;
+
+ private final int protocol;
+
+ public ProtonTest(String name, int protocol) {
+ this.coreAddress = "jms.queue.exampleQueue";
+ this.protocol = protocol;
+ if (protocol == 0 || protocol == 3) {
+ this.address = coreAddress;
+ }
+ else {
+ this.address = "exampleQueue";
+ }
+ }
+
+ private final String coreAddress;
+ private final String address;
+ private Connection connection;
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+
+ server.createQueue(new SimpleString(coreAddress), new SimpleString(coreAddress), null, true, false);
+ server.createQueue(new SimpleString(coreAddress + "1"), new SimpleString(coreAddress + "1"), null, true, false);
+ server.createQueue(new SimpleString(coreAddress + "2"), new SimpleString(coreAddress + "2"), null, true, false);
+ server.createQueue(new SimpleString(coreAddress + "3"), new SimpleString(coreAddress + "3"), null, true, false);
+ server.createQueue(new SimpleString(coreAddress + "4"), new SimpleString(coreAddress + "4"), null, true, false);
+ server.createQueue(new SimpleString(coreAddress + "5"), new SimpleString(coreAddress + "5"), null, true, false);
+ server.createQueue(new SimpleString(coreAddress + "6"), new SimpleString(coreAddress + "6"), null, true, false);
+ server.createQueue(new SimpleString(coreAddress + "7"), new SimpleString(coreAddress + "7"), null, true, false);
+ server.createQueue(new SimpleString(coreAddress + "8"), new SimpleString(coreAddress + "8"), null, true, false);
+ server.createQueue(new SimpleString(coreAddress + "9"), new SimpleString(coreAddress + "9"), null, true, false);
+ server.createQueue(new SimpleString(coreAddress + "10"), new SimpleString(coreAddress + "10"), null, true, false);
+ server.createQueue(new SimpleString("amqp_testtopic"), new SimpleString("amqp_testtopic"), null, true, false);
+ server.createQueue(new SimpleString("amqp_testtopic" + "1"), new SimpleString("amqp_testtopic" + "1"), null, true, false);
+ server.createQueue(new SimpleString("amqp_testtopic" + "2"), new SimpleString("amqp_testtopic" + "2"), null, true, false);
+ server.createQueue(new SimpleString("amqp_testtopic" + "3"), new SimpleString("amqp_testtopic" + "3"), null, true, false);
+ server.createQueue(new SimpleString("amqp_testtopic" + "4"), new SimpleString("amqp_testtopic" + "4"), null, true, false);
+ server.createQueue(new SimpleString("amqp_testtopic" + "5"), new SimpleString("amqp_testtopic" + "5"), null, true, false);
+ server.createQueue(new SimpleString("amqp_testtopic" + "6"), new SimpleString("amqp_testtopic" + "6"), null, true, false);
+ server.createQueue(new SimpleString("amqp_testtopic" + "7"), new SimpleString("amqp_testtopic" + "7"), null, true, false);
+ server.createQueue(new SimpleString("amqp_testtopic" + "8"), new SimpleString("amqp_testtopic" + "8"), null, true, false);
+ server.createQueue(new SimpleString("amqp_testtopic" + "9"), new SimpleString("amqp_testtopic" + "9"), null, true, false);
+ server.createQueue(new SimpleString("amqp_testtopic" + "10"), new SimpleString("amqp_testtopic" + "10"), null, true, false);
+ connection = createConnection();
+
+ }
+
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ try {
+ Thread.sleep(250);
+ if (connection != null) {
+ connection.close();
+ }
+ }
+ finally {
+ super.tearDown();
+ }
+ }
+
+ @Test
+ public void testDurableSubscriptionUnsubscribe() throws Exception {
+ Connection connection = createConnection("myClientId");
+ try {
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Topic topic = session.createTopic("amqp_testtopic");
+ TopicSubscriber myDurSub = session.createDurableSubscriber(topic, "myDurSub");
+ session.close();
+ connection.close();
+ connection = createConnection("myClientId");
+ session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ myDurSub = session.createDurableSubscriber(topic, "myDurSub");
+ myDurSub.close();
+ Assert.assertNotNull(server.getPostOffice().getBinding(new SimpleString("myClientId:myDurSub")));
+ session.unsubscribe("myDurSub");
+ Assert.assertNull(server.getPostOffice().getBinding(new SimpleString("myClientId:myDurSub")));
+ session.close();
+ connection.close();
+ }
+ finally {
+ if (connection != null) {
+ connection.close();
+ }
+ }
+ }
+
+ @Test
+ public void testTemporarySubscriptionDeleted() throws Exception {
+ try {
+ TopicSession session = (TopicSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Topic topic = session.createTopic("amqp_testtopic");
+ TopicSubscriber myDurSub = session.createSubscriber(topic);
+ Bindings bindingsForAddress = server.getPostOffice().getBindingsForAddress(new SimpleString("amqp_testtopic"));
+ Assert.assertEquals(2, bindingsForAddress.getBindings().size());
+ session.close();
+ final CountDownLatch latch = new CountDownLatch(1);
+ server.getRemotingService().getConnections().iterator().next().addCloseListener(new CloseListener() {
+ @Override
+ public void connectionClosed() {
+ latch.countDown();
+ }
+ });
+ connection.close();
+ latch.await(5, TimeUnit.SECONDS);
+ bindingsForAddress = server.getPostOffice().getBindingsForAddress(new SimpleString("amqp_testtopic"));
+ Assert.assertEquals(1, bindingsForAddress.getBindings().size());
+ }
+ finally {
+ if (connection != null) {
+ connection.close();
+ }
+ }
+ }
+
+ @Test
+ public void testBrokerContainerId() throws Exception {
+ AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
+ AmqpConnection amqpConnection = client.connect();
+ try {
+ assertTrue(brokerName.equals(amqpConnection.getEndpoint().getRemoteContainer()));
+ }
+ finally {
+ amqpConnection.close();
+ }
+ }
+
+ @Test
+ public void testBrokerConnectionProperties() throws Exception {
+ AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
+ AmqpConnection amqpConnection = client.connect();
+ try {
+ Map<Symbol, Object> properties = amqpConnection.getEndpoint().getRemoteProperties();
+ assertTrue(properties != null);
+ if (properties != null) {
+ assertTrue("apache-activemq-artemis".equals(properties.get(Symbol.valueOf("product"))));
+ assertTrue(VersionLoader.getVersion().getFullVersion().equals(properties.get(Symbol.valueOf("version"))));
+ }
+ }
+ finally {
+ amqpConnection.close();
+ }
+ }
+
+ @Test(timeout = 60000)
+ public void testConnectionCarriesExpectedCapabilities() throws Exception {
+ AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
+ assertNotNull(client);
+
+ client.setValidator(new AmqpValidator() {
+
+ @Override
+ public void inspectOpenedResource(org.apache.qpid.proton.engine.Connection connection) {
+
+ Symbol[] offered = connection.getRemoteOfferedCapabilities();
+
+ if (!contains(offered, DELAYED_DELIVERY)) {
+ markAsInvalid("Broker did not indicate it support delayed message delivery");
+ return;
+ }
+
+ Map<Symbol, Object> properties = connection.getRemoteProperties();
+ if (!properties.containsKey(PRODUCT)) {
+ markAsInvalid("Broker did not send a queue product name value");
+ return;
+ }
+
+ if (!properties.containsKey(VERSION)) {
+ markAsInvalid("Broker did not send a queue version value");
+ return;
+ }
+ }
+ });
+
+ AmqpConnection connection = client.connect();
+ try {
+ assertNotNull(connection);
+ connection.getStateInspector().assertValid();
+ }
+ finally {
+ connection.close();
+ }
+ }
+
+ @Test(timeout = 60000)
+ public void testSendWithDeliveryTimeHoldsMessage() throws Exception {
+ AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
+ assertNotNull(client);
+
+ AmqpConnection connection = client.connect();
+ try {
+ AmqpSession session = connection.createSession();
+
+ AmqpSender sender = session.createSender(address);
+ AmqpReceiver receiver = session.createReceiver(address);
+
+ AmqpMessage message = new AmqpMessage();
+ long deliveryTime = System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5);
+ message.setMessageAnnotation("x-opt-delivery-time", deliveryTime);
+ message.setText("Test-Message");
+ sender.send(message);
+
+ // Now try and get the message
+ receiver.flow(1);
+
+ // Shouldn't get this since we delayed the message.
+ assertNull(receiver.receive(5, TimeUnit.SECONDS));
+ }
+ finally {
+ connection.close();
+ }
+ }
+
+ @Test(timeout = 60000)
+ public void testSendWithDeliveryTimeDeliversMessageAfterDelay() throws Exception {
+ AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
+ assertNotNull(client);
+
+ AmqpConnection connection = client.connect();
+ try {
+ AmqpSession session = connection.createSession();
+
+ AmqpSender sender = session.createSender(address);
+ AmqpReceiver receiver = session.createReceiver(address);
+
+ AmqpMessage message = new AmqpMessage();
+ long deliveryTime = System.currentTimeMillis() + 2000;
+ message.setMessageAnnotation("x-opt-delivery-time", deliveryTime);
+ message.setText("Test-Message");
+ sender.send(message);
+
+ // Now try and get the message
+ receiver.flow(1);
+
+ AmqpMessage received = receiver.receive(10, TimeUnit.SECONDS);
+ assertNotNull(received);
+ received.accept();
+ Long msgDeliveryTime = (Long) received.getMessageAnnotation("x-opt-delivery-time");
+ assertNotNull(msgDeliveryTime);
+ assertEquals(deliveryTime, msgDeliveryTime.longValue());
+ }
+ finally {
+ connection.close();
+ }
+ }
+
+ @Test
+ public void testCreditsAreAllocatedOnlyOnceOnLinkCreate() throws Exception {
+ // Only allow 1 credit to be submitted at a time.
+ Field maxCreditAllocation = ProtonServerReceiverContext.class.getDeclaredField("maxCreditAllocation");
+ maxCreditAllocation.setAccessible(true);
+ int originalMaxCreditAllocation = maxCreditAllocation.getInt(null);
+ maxCreditAllocation.setInt(null, 1);
+
+ String destinationAddress = address + 1;
+ AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
+ AmqpConnection amqpConnection = client.connect();
+ try {
+ AmqpSession session = amqpConnection.createSession();
+ AmqpSender sender = session.createSender(destinationAddress);
+ assertTrue(sender.getSender().getCredit() == 1);
+ }
+ finally {
+ amqpConnection.close();
+ maxCreditAllocation.setInt(null, originalMaxCreditAllocation);
+ }
+ }
+
+ @Test
+ public void testTemporaryQueue() throws Throwable {
+
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ TemporaryQueue queue = session.createTemporaryQueue();
+ System.out.println("queue:" + queue.getQueueName());
+ MessageProducer p = session.createProducer(queue);
+
+ TextMessage message = session.createTextMessage();
+ message.setText("Message temporary");
+ p.send(message);
+
+ MessageConsumer cons = session.createConsumer(queue);
+ connection.start();
+
+ message = (TextMessage) cons.receive(5000);
+ Assert.assertNotNull(message);
+ }
+
+ @Test
+ public void testCommitProducer() throws Throwable {
+
+ Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
+ javax.jms.Queue queue = createQueue(address);
+ System.out.println("queue:" + queue.getQueueName());
+ MessageProducer p = session.createProducer(queue);
+ for (int i = 0; i < 10; i++) {
+ TextMessage message = session.createTextMessage();
+ message.setText("Message:" + i);
+ p.send(message);
+ }
+ session.commit();
+ session.close();
+ Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable();
+ Assert.assertEquals(q.getMessageCount(), 10);
+ }
+
+ @Test
+ public void testRollbackProducer() throws Throwable {
+
+ Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
+ javax.jms.Queue queue = createQueue(address);
+ System.out.println("queue:" + queue.getQueueName());
+ MessageProducer p = session.createProducer(queue);
+ for (int i = 0; i < 10; i++) {
+ TextMessage message = session.createTextMessage();
+ message.setText("Message:" + i);
+ p.send(message);
+ }
+ session.rollback();
+ session.close();
+ Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable();
+ Assert.assertEquals(q.getMessageCount(), 0);
+ }
+
+ @Test
+ public void testCommitConsumer() throws Throwable {
+
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ javax.jms.Queue queue = createQueue(address);
+ System.out.println("queue:" + queue.getQueueName());
+ MessageProducer p = session.createProducer(queue);
+ for (int i = 0; i < 10; i++) {
+ TextMessage message = session.createTextMessage();
+ message.setText("Message:" + i);
+ p.send(message);
+ }
+ session.close();
+
+ session = connection.createSession(true, Session.SESSION_TRANSACTED);
+ MessageConsumer cons = session.createConsumer(queue);
+ connection.start();
+
+ for (int i = 0; i < 10; i++) {
+ TextMessage message = (TextMessage) cons.receive(5000);
+ Assert.assertNotNull(message);
+ Assert.assertEquals("Message:" + i, message.getText());
+ }
+ session.commit();
+ Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable();
+ Assert.assertEquals(q.getMessageCount(), 0);
+ }
+
+
+ @Test
+ public void testRollbackConsumer() throws Throwable {
+
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ javax.jms.Queue queue = createQueue(address);
+ System.out.println("queue:" + queue.getQueueName());
+ MessageProducer p = session.createProducer(queue);
+ for (int i = 0; i < 10; i++) {
+ TextMessage message = session.createTextMessage();
+ message.setText("Message:" + i);
+ p.send(message);
+ }
+ session.close();
+
+ session = connection.createSession(true, Session.SESSION_TRANSACTED);
+ MessageConsumer cons = session.createConsumer(queue);
+ connection.start();
+
+ for (int i = 0; i < 10; i++) {
+ TextMessage message = (TextMessage) cons.receive(5000);
+ Assert.assertNotNull(message);
+ Assert.assertEquals("Message:" + i, message.getText());
+ }
+ session.rollback();
+ Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable();
+ Assert.assertEquals(q.getMessageCount(), 10);
+ }
+
+ @Test
+ public void testResourceLimitExceptionOnAddressFull() throws Exception {
+ setAddressFullBlockPolicy();
+ String destinationAddress = address + 1;
+ fillAddress(destinationAddress);
+
+ long addressSize = server.getPagingManager().getPageStore(new SimpleString(destinationAddress)).getAddressSize();
+ assertTrue(addressSize >= maxSizeBytesRejectThreshold);
+ }
+
+ @Test
+ public void testAddressIsBlockedForOtherProdudersWhenFull() throws Exception {
+ setAddressFullBlockPolicy();
+
+ String destinationAddress = address + 1;
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Destination d = session.createQueue(destinationAddress);
+ MessageProducer p = session.createProducer(d);
+
+ fillAddress(destinationAddress);
+
+ Exception e = null;
+ try {
+ p.send(session.createBytesMessage());
+ }
+ catch (ResourceAllocationException rae) {
+ e = rae;
+ }
+ assertTrue(e instanceof ResourceAllocationException);
+ assertTrue(e.getMessage().contains("resource-limit-exceeded"));
+
+ long addressSize = server.getPagingManager().getPageStore(new SimpleString(destinationAddress)).getAddressSize();
+ assertTrue(addressSize >= maxSizeBytesRejectThreshold);
+ }
+
+ @Test
+ public void testCreditsAreNotAllocatedWhenAddressIsFull() throws Exception {
+ setAddressFullBlockPolicy();
+
+ // Only allow 1 credit to be submitted at a time.
+ Field maxCreditAllocation = ProtonServerReceiverContext.class.getDeclaredField("maxCreditAllocation");
+ maxCreditAllocation.setAccessible(true);
+ int originalMaxCreditAllocation = maxCreditAllocation.getInt(null);
+ maxCreditAllocation.setInt(null, 1);
+
+ String destinationAddress = address + 1;
+ AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
+ AmqpConnection amqpConnection = client.connect();
+ try {
+ AmqpSession session = amqpConnection.createSession();
+ AmqpSender sender = session.createSender(destinationAddress);
+
+ // Use blocking send to ensure buffered messages do not interfere with credit.
+ sender.setSendTimeout(-1);
+ sendUntilFull(sender);
+
+ // This should be -1. A single message is buffered in the client, and 0 credit has been allocated.
+ assertTrue(sender.getSender().getCredit() == -1);
+
+ long addressSize = server.getPagingManager().getPageStore(new SimpleString(destinationAddress)).getAddressSize();
+ assertTrue(addressSize >= maxSizeBytes && addressSize <= maxSizeBytesRejectThreshold);
+ }
+ finally {
+ amqpConnection.close();
+ maxCreditAllocation.setInt(null, originalMaxCreditAllocation);
+ }
+ }
+
+ @Test
+ public void testCreditsAreRefreshedWhenAddressIsUnblocked() throws Exception {
+ setAddressFullBlockPolicy();
+
+ String destinationAddress = address + 1;
+ fillAddress(destinationAddress);
+
+ AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
+ AmqpConnection amqpConnection = amqpConnection = client.connect();
+ try {
+ AmqpSession session = amqpConnection.createSession();
+ AmqpSender sender = session.createSender(destinationAddress);
+
+ // Wait for a potential flow frame.
+ Thread.sleep(500);
+ assertEquals(0, sender.getSender().getCredit());
+
+ // Empty Address except for 1 message used later.
+ AmqpReceiver receiver = session.createReceiver(destinationAddress);
+ receiver.flow(100);
+
+ AmqpMessage m;
+ for (int i = 0; i < messagesSent - 1; i++) {
+ m = receiver.receive();
+ m.accept();
+ }
+
+ // Wait for address to unblock and flow frame to arrive
+ Thread.sleep(500);
+
+ assertTrue(sender.getSender().getCredit() >= 0);
+ }
+ finally {
+ amqpConnection.close();
+ }
+ }
+
+ @Test
+ public void testNewLinkAttachAreNotAllocatedCreditsWhenAddressIsBlocked() throws Exception {
+ setAddressFullBlockPolicy();
+
+ fillAddress(address + 1);
+ AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
+ AmqpConnection amqpConnection = client.connect();
+ try {
+ AmqpSession session = amqpConnection.createSession();
+ AmqpSender sender = session.createSender(address + 1);
+ // Wait for a potential flow frame.
+ Thread.sleep(1000);
+ assertEquals(0, sender.getSender().getCredit());
+ }
+ finally {
+ amqpConnection.close();
+ }
+ }
+
+ @Test
+ public void testTxIsRolledBackOnRejectedPreSettledMessage() throws Throwable {
+ setAddressFullBlockPolicy();
+
+ // Create the link attach before filling the address to ensure the link is allocated credit.
+ AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
+ AmqpConnection amqpConnection = client.connect();
+
+ AmqpSession session = amqpConnection.createSession();
+ AmqpSender sender = session.createSender(address);
+ sender.setPresettle(true);
+
+ fillAddress(address);
+
+ final AmqpMessage message = new AmqpMessage();
+ byte[] payload = new byte[50 * 1024];
+ message.setBytes(payload);
+
+ Exception expectedException = null;
+ try {
+ session.begin();
+ sender.send(message);
+ session.commit();
+ }
+ catch (Exception e) {
+ expectedException = e;
+ }
+ finally {
+ amqpConnection.close();
+ }
+
+ assertNotNull(expectedException);
+ assertTrue(expectedException.getMessage().contains("resource-limit-exceeded"));
+ assertTrue(expectedException.getMessage().contains("Address is full: " + address));
+ }
+
+ /**
+ * Fills an address. Careful when using this method. Only use when rejected messages are switched on.
+ * @param address
+ * @return
+ * @throws Exception
+ */
+ private void fillAddress(String address) throws Exception {
+ AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
+ AmqpConnection amqpConnection = client.connect();
+ Exception exception = null;
+ try {
+ AmqpSession session = amqpConnection.createSession();
+ AmqpSender sender = session.createSender(address);
+ sendUntilFull(sender);
+ }
+ catch (Exception e) {
+ exception = e;
+ }
+ finally {
+ amqpConnection.close();
+ }
+
+ // Should receive a rejected error
+ assertNotNull(exception);
+ assertTrue(exception.getMessage().contains("amqp:resource-limit-exceeded"));
+ }
+
+ private void sendUntilFull(final AmqpSender sender) throws Exception {
+ final AmqpMessage message = new AmqpMessage();
+ byte[] payload = new byte[50 * 1024];
+ message.setBytes(payload);
+
+ final int maxMessages = 50;
+ final AtomicInteger sentMessages = new AtomicInteger(0);
+ final Exception[] errors = new Exception[1];
+ final CountDownLatch timeout = new CountDownLatch(1);
+
+ Runnable sendMessages = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ for (int i = 0; i < maxMessages; i++) {
+ sender.send(message);
+ sentMessages.getAndIncrement();
+ }
+ timeout.countDown();
+ }
+ catch (IOException e) {
+ errors[0] = e;
+ }
+ }
+ };
+
+ Thread t = new Thread(sendMessages);
+ t.start();
+
+ timeout.await(5, TimeUnit.SECONDS);
+
+ messagesSent = sentMessages.get();
+ if (errors[0] != null) {
+ throw errors[0];
+ }
+ }
+
+ @Test
+ public void testLinkDetatchErrorIsCorrectWhenQueueDoesNotExists() throws Exception {
+ AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
+ AmqpConnection amqpConnection = client.connect();
+ AmqpSession session = amqpConnection.createSession();
+
+ Exception expectedException = null;
+ try {
+ session.createSender("AnAddressThatDoesNotExist");
+ }
+ catch (Exception e) {
+ expectedException = e;
+ }
+
+ assertNotNull(expectedException);
+ assertTrue(expectedException.getMessage().contains("amqp:not-found"));
+ assertTrue(expectedException.getMessage().contains("target address does not exist"));
+ }
+
+ @Test
+ public void testSendingAndReceivingToQueueWithDifferentAddressAndQueueName() throws Exception {
+
+ String queueName = "TestQueueName";
+ String address = "TestAddress";
+
+ server.createQueue(new SimpleString(address), new SimpleString(queueName), null, true, false);
+
+ AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
+ AmqpConnection amqpConnection = client.connect();
+ AmqpSession session = amqpConnection.createSession();
+ AmqpSender sender = session.createSender(address);
+ AmqpReceiver receiver = session.createReceiver(queueName);
+ receiver.flow(1);
+
+ AmqpMessage message = new AmqpMessage();
+ message.setText("TestPayload");
+ sender.send(message);
+
+ AmqpMessage receivedMessage = receiver.receive();
+ assertNotNull(receivedMessage);
+ }
+
+ @Test
+ public void testManagementQueryOverAMQP() throws Throwable {
+
+ AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
+ AmqpConnection amqpConnection = client.connect();
+ try {
+ String destinationAddress = address + 1;
+ AmqpSession session = amqpConnection.createSession();
+ AmqpSender sender = session.createSender("jms.queue.activemq.management");
+ AmqpReceiver receiver = session.createReceiver(destinationAddress);
+ receiver.flow(10);
+
+ //create request message for getQueueNames query
+ AmqpMessage request = new AmqpMessage();
+ request.setApplicationProperty("_AMQ_ResourceName", "core.server");
+ request.setApplicationProperty("_AMQ_OperationName", "getQueueNames");
+ request.setApplicationProperty("JMSReplyTo", destinationAddress);
+ request.setText("[]");
+
+ sender.send(request);
+ AmqpMessage response = receiver.receive(50, TimeUnit.SECONDS);
+ Assert.assertNotNull(response);
+ assertNotNull(response);
+ Object section = response.getWrappedMessage().getBody();
+ assertTrue(section instanceof AmqpValue);
+ Object value = ((AmqpValue) section).getValue();
+ assertTrue(value instanceof String);
+ assertTrue(((String) value).length() > 0);
+ assertTrue(((String) value).contains(destinationAddress));
+ response.accept();
+ }
+ finally {
+ amqpConnection.close();
+ }
+ }
+
+ @Test
+ public void testReplyTo() throws Throwable {
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ TemporaryQueue queue = session.createTemporaryQueue();
+ MessageProducer p = session.createProducer(queue);
+
+ TextMessage message = session.createTextMessage();
+ message.setText("Message temporary");
+ message.setJMSReplyTo(createQueue(address));
+ p.send(message);
+
+ MessageConsumer cons = session.createConsumer(queue);
+ connection.start();
+
+ message = (TextMessage) cons.receive(5000);
+ Destination jmsReplyTo = message.getJMSReplyTo();
+ Assert.assertNotNull(jmsReplyTo);
+ Assert.assertNotNull(message);
+ }
+
+ @Test
+ public void testReplyToNonJMS() throws Throwable {
+
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ TemporaryQueue queue = session.createTemporaryQueue();
+ System.out.println("queue:" + queue.getQueueName());
+ MessageProducer p = session.createProducer(queue);
+
+ TextMessage message = session.createTextMessage();
+ message.setText("Message temporary");
+ message.setJMSReplyTo(createQueue("someaddress"));
+ p.send(message);
+
+ MessageConsumer cons = session.createConsumer(queue);
+ connection.start();
+
+ message = (TextMessage) cons.receive(5000);
+ Destination jmsReplyTo = message.getJMSReplyTo();
+ Assert.assertNotNull(jmsReplyTo);
+ Assert.assertNotNull(message);
+
+ }
+
+ /*
+ // Uncomment testLoopBrowser to validate the hunging on the test
+ @Test
+ public void testLoopBrowser() throws Throwable {
+ for (int i = 0 ; i < 1000; i++) {
+ System.out.println("#test " + i);
+ testBrowser();
+ tearDown();
+ setUp();
+ }
+ } */
+
+ /**
+ * This test eventually fails because of: https://issues.apache.org/jira/browse/QPID-4901
+ *
+ * @throws Throwable
+ */
+ //@Test // TODO: re-enable this when we can get a version free of QPID-4901 bug
+ public void testBrowser() throws Throwable {
+
+ boolean success = false;
+
+ for (int i = 0; i < 10; i++) {
+ // As this test was hunging, we added a protection here to fail it instead.
+ // it seems something on the qpid client, so this failure belongs to them and we can ignore it on
+ // our side (ActiveMQ)
+ success = runWithTimeout(new RunnerWithEX() {
+ @Override
+ public void run() throws Throwable {
+ int numMessages = 50;
+ javax.jms.Queue queue = createQueue(address);
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageProducer p = session.createProducer(queue);
+ for (int i = 0; i < numMessages; i++) {
+ TextMessage message = session.createTextMessage();
+ message.setText("msg:" + i);
+ p.send(message);
+ }
+
+ connection.close();
+ Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable();
+
+ connection = createConnection();
+ session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ QueueBrowser browser = session.createBrowser(queue);
+ Enumeration enumeration = browser.getEnumeration();
+ int count = 0;
+ while (enumeration.hasMoreElements()) {
+ Message msg = (Message) enumeration.nextElement();
+ Assert.assertNotNull("" + count, msg);
+ Assert.assertTrue("" + msg, msg instanceof TextMessage);
+ String text = ((TextMessage) msg).getText();
+ Assert.assertEquals(text, "msg:" + count++);
+ }
+ Assert.assertEquals(count, numMessages);
+ connection.close();
+ Assert.assertEquals(getMessageCount(q), numMessages);
+ }
+ }, 5000);
+
+ if (success) {
+ break;
+ }
+ else {
+ System.err.println("Had to make it fail!!!");
+ tearDown();
+ setUp();
+ }
+ }
+
+ // There is a bug on the qpid client library currently, we can expect having to interrupt the thread on browsers.
+ // but we can't have it on 10 iterations... something must be broken if that's the case
+ Assert.assertTrue("Test had to interrupt on all occasions.. this is beyond the expected for the test", success);
+ }
+
+ @Test
+ public void testConnection() throws Exception {
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer cons = session.createConsumer(createQueue(address));
+
+ org.apache.activemq.artemis.core.server.Queue serverQueue = server.locateQueue(SimpleString.toSimpleString(coreAddress));
+
+ assertEquals(1, serverQueue.getConsumerCount());
+
+ cons.close();
+
+ for (int i = 0; i < 100 && serverQueue.getConsumerCount() != 0; i++) {
+ Thread.sleep(500);
+ }
+
+ assertEquals(0, serverQueue.getConsumerCount());
+
+ session.close();
+
+ }
+
+ @Test
+ public void testMessagesSentTransactional() throws Exception {
+ int numMessages = 1000;
+ javax.jms.Queue queue = createQueue(address);
+ Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
+ MessageProducer p = session.createProducer(queue);
+ byte[] bytes = new byte[2048];
+ new Random().nextBytes(bytes);
+ for (int i = 0; i < numMessages; i++) {
+ TextMessage message = session.createTextMessage();
+ message.setText("msg:" + i);
+ p.send(message);
+ }
+ session.commit();
+ connection.close();
+ Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable();
+ for (long timeout = System.currentTimeMillis() + 5000; timeout > System.currentTimeMillis() && getMessageCount(q) != numMessages; ) {
+ Thread.sleep(1);
+ }
+ Assert.assertEquals(numMessages, getMessageCount(q));
+ }
+
+ @Test
+ public void testMessagesSentTransactionalRolledBack() throws Exception {
+ int numMessages = 1;
+ javax.jms.Queue queue = createQueue(address);
+ Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
+ MessageProducer p = session.createProducer(queue);
+ byte[] bytes = new byte[2048];
+ new Random().nextBytes(bytes);
+ for (int i = 0; i < numMessages; i++) {
+ TextMessage message = session.createTextMessage();
+ message.setText("msg:" + i);
+ p.send(message);
+ }
+ session.close();
+ connection.close();
+ Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable();
+ Assert.assertEquals(getMessageCount(q), 0);
+ }
+
+ @Test
+ public void testCancelMessages() throws Exception {
+ int numMessages = 10;
+ long time = System.currentTimeMillis();
+ javax.jms.Queue queue = createQueue(address);
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageProducer p = session.createProducer(queue);
+ byte[] bytes = new byte[2048];
+ new Random().nextBytes(bytes);
+ for (int i = 0; i < numMessages; i++) {
+ TextMessage message = session.createTextMessage();
+ message.setText("msg:" + i);
+ p.send(message);
+ }
+ connection.close();
+ Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable();
+
+ for (long timeout = System.currentTimeMillis() + 5000; timeout > System.currentTimeMillis() && getMessageCount(q) != numMessages; ) {
+ Thread.sleep(1);
+ }
+
+ Assert.assertEquals(numMessages, getMessageCount(q));
+ //now create a new connection and receive
+ connection = createConnection();
+ session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageConsumer consumer = session.createConsumer(queue);
+ Thread.sleep(100);
+ consumer.close();
+ connection.close();
+ Assert.assertEquals(numMessages, getMessageCount(q));
+ long taken = (System.currentTimeMillis() - time) / 1000;
+ System.out.println("taken = " + taken);
+ }
+
+ @Test
+ public void testClientAckMessages() throws Exception {
+ int numMessages = 10;
+ long time = System.currentTimeMillis();
+ javax.jms.Queue queue = createQueue(address);
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageProducer p = session.createProducer(queue);
+ byte[] bytes = new byte[2048];
+ new Random().nextBytes(bytes);
+ for (int i = 0; i < numMessages; i++) {
+ TextMessage message = session.createTextMessage();
+ message.setText("msg:" + i);
+ p.send(message);
+ }
+ connection.close();
+ Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable();
+
+ for (long timeout = System.currentTimeMillis() + 5000; timeout > System.currentTimeMillis() && getMessageCount(q) != numMessages; ) {
+ Thread.sleep(1);
+ }
+ Assert.assertEquals(numMessages, getMessageCount(q));
+ //now create a new connection and receive
+ connection = createConnection();
+ session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+ MessageConsumer consumer = session.createConsumer(queue);
+ for (int i = 0; i < numMessages; i++) {
+ Message msg = consumer.receive(5000);
+ if (msg == null) {
+ System.out.println("ProtonTest.testManyMessages");
+ }
+ Assert.assertNotNull("" + i, msg);
+ Assert.assertTrue("" + msg, msg instanceof TextMessage);
+ String text = ((TextMessage) msg).getText();
+ //System.out.println("text = " + text);
+ Assert.assertEquals(text, "msg:" + i);
+ msg.acknowledge();
+ }
+
+ consumer.close();
+ connection.close();
+
+ // Wait for Acks to be processed and message removed from queue.
+ Thread.sleep(500);
+
+ Assert.assertEquals(0, getMessageCount(q));
+ long taken = (System.currentTimeMillis() - time) / 1000;
+ System.out.println("taken = " + taken);
+ }
+
+ @Test
+ public void testMessagesReceivedInParallel() throws Throwable {
+ final int numMessages = 50000;
+ long time = System.currentTimeMillis();
+ final javax.jms.Queue queue = createQueue(address);
+
+ final ArrayList<Throwable> exceptions = new ArrayList<>();
+
+ Thread t = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ Connection connectionConsumer = null;
+ try {
+ // TODO the test may starve if using the same connection (dead lock maybe?)
+ connectionConsumer = createConnection();
+ // connectionConsumer = connection;
+ connectionConsumer.start();
+ Session sessionConsumer = connectionConsumer.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ final MessageConsumer consumer = sessionConsumer.createConsumer(queue);
+
+ long n = 0;
+ int count = numMessages;
+ while (count > 0) {
+ try {
+ if (++n % 1000 == 0) {
+ System.out.println("received " + n + " messages");
+ }
+
+ Message m = consumer.receive(5000);
+ Assert.assertNotNull("Could not receive message count=" + count + " on consumer", m);
+ count--;
+ }
+ catch (JMSException e) {
+ e.printStackTrace();
+ break;
+ }
+ }
+ }
+ catch (Throwable e) {
+ exceptions.add(e);
+ e.printStackTrace();
+ }
+ finally {
+ try {
+ // if the createconnecion wasn't commented out
+ if (connectionConsumer != connection) {
+ connectionConsumer.close();
+ }
+ }
+ catch (Throwable ignored) {
+ // NO OP
+ }
+ }
+ }
+ });
+
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ t.start();
+
+ MessageProducer p = session.createProducer(queue);
+ p.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
+ for (int i = 0; i < numMessages; i++) {
+ BytesMessage message = session.createBytesMessage();
+ message.writeUTF("Hello world!!!!" + i);
+ message.setIntProperty("count", i);
+ p.send(message);
+ }
+ t.join();
+
+ for (Throwable e : exceptions) {
+ throw e;
+ }
+ Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable();
+
+ connection.close();
+ Assert.assertEquals(0, getMessageCount(q));
+
+ long taken = (System.currentTimeMillis() - time);
+ System.out.println("Microbenchamrk ran in " + taken + " milliseconds, sending/receiving " + numMessages);
+
+ double messagesPerSecond = ((double) numMessages / (double) taken) * 1000;
+
+ System.out.println(((int) messagesPerSecond) + " messages per second");
+
+ }
+
+ @Test
+ public void testSimpleBinary() throws Throwable {
+ final int numMessages = 500;
+ long time = System.currentTimeMillis();
+ final javax.jms.Queue queue = createQueue(address);
+
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ byte[] bytes = new byte[0xf + 1];
+ for (int i = 0; i <= 0xf; i++) {
+ bytes[i] = (byte) i;
+ }
+
+ MessageProducer p = session.createProducer(queue);
+ for (int i = 0; i < numMessages; i++) {
+ System.out.println("Sending " + i);
+ BytesMessage message = session.createBytesMessage();
+
+ message.writeBytes(bytes);
+ message.setIntProperty("count", i);
+ p.send(message);
+ }
+
+ Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ final MessageConsumer consumer = sessionConsumer.createConsumer(queue);
+
+ for (int i = 0; i < numMessages; i++) {
+ BytesMessage m = (BytesMessage) consumer.receive(5000);
+ Assert.assertNotNull("Could not receive message count=" + i + " on consumer", m);
+
+ m.reset();
+
+ long size = m.getBodyLength();
+ byte[] bytesReceived = new byte[(int) size];
+ m.readBytes(bytesReceived);
+
+ System.out.println("Received " + ByteUtil.bytesToHex(bytesReceived, 1) + " count - " + m.getIntProperty("count"));
+
+ Assert.assertArrayEquals(bytes, bytesReceived);
+ }
+
+ // assertEquals(0, q.getMessageCount());
+ long taken = (System.currentTimeMillis() - time) / 1000;
+ System.out.println("taken = " + taken);
+ }
+
+ @Test
+ public void testSimpleDefault() throws Throwable {
+ final int numMessages = 500;
+ long time = System.currentTimeMillis();
+ final javax.jms.Queue queue = createQueue(address);
+
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ byte[] bytes = new byte[0xf + 1];
+ for (int i = 0; i <= 0xf; i++) {
+ bytes[i] = (byte) i;
+ }
+
+ MessageProducer p = session.createProducer(queue);
+ for (int i = 0; i < numMessages; i++) {
+ System.out.println("Sending " + i);
+ Message message = session.createMessage();
+
+ message.setIntProperty("count", i);
+ p.send(message);
+ }
+
+ Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ final MessageConsumer consumer = sessionConsumer.createConsumer(queue);
+
+ for (int i = 0; i < numMessages; i++) {
+ Message m = consumer.receive(5000);
+ Assert.assertNotNull("Could not receive message count=" + i + " on consumer", m);
+ }
+
+ // assertEquals(0, q.getMessageCount());
+ long taken = (System.currentTimeMillis() - time) / 1000;
+ System.out.println("taken = " + taken);
+ }
+
+ @Test
+ public void testSimpleMap() throws Throwable {
+ final int numMessages = 100;
+ long time = System.currentTimeMillis();
+ final javax.jms.Queue queue = createQueue(address);
+
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer p = session.createProducer(queue);
+ for (int i = 0; i < numMessages; i++) {
+ System.out.println("Sending " + i);
+ MapMessage message = session.createMapMessage();
+
+ message.setInt("i", i);
+ message.setIntProperty("count", i);
+ p.send(message);
+ }
+
+ Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ final MessageConsumer consumer = sessionConsumer.createConsumer(queue);
+
+ for (int i = 0; i < numMessages; i++) {
+ MapMessage m = (MapMessage) consumer.receive(5000);
+ Assert.assertNotNull("Could not receive message count=" + i + " on consumer", m);
+
+ Assert.assertEquals(i, m.getInt("i"));
+ Assert.assertEquals(i, m.getIntProperty("count"));
+ }
+
+ // assertEquals(0, q.getMessageCount());
+ long taken = (System.currentTimeMillis() - time) / 1000;
+ System.out.println("taken = " + taken);
+ }
+
+ @Test
+ public void testSimpleStream() throws Throwable {
+ final int numMessages = 100;
+ final javax.jms.Queue queue = createQueue(address);
+
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer p = session.createProducer(queue);
+ for (int i = 0; i < numMessages; i++) {
+ StreamMessage message = session.createStreamMessage();
+ message.writeInt(i);
+ message.writeBoolean(true);
+ message.writeString("test");
+ p.send(message);
+ }
+
+ Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ final MessageConsumer consumer = sessionConsumer.createConsumer(queue);
+
+ for (int i = 0; i < numMessages; i++) {
+ StreamMessage m = (StreamMessage) consumer.receive(5000);
+ Assert.assertNotNull("Could not receive message count=" + i + " on consumer", m);
+
+ Assert.assertEquals(i, m.readInt());
+ Assert.assertEquals(true, m.readBoolean());
+ Assert.assertEquals("test", m.readString());
+ }
+
+ }
+
+ @Test
+ public void testSimpleText() throws Throwable {
+ final int numMessages = 100;
+ long time = System.currentTimeMillis();
+ final javax.jms.Queue queue = createQueue(address);
+
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer p = session.createProducer(queue);
+ for (int i = 0; i < numMessages; i++) {
+ System.out.println("Sending " + i);
+ TextMessage message = session.createTextMessage("text" + i);
+ message.setStringProperty("text", "text" + i);
+ p.send(message);
+ }
+
+ Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ final MessageConsumer consumer = sessionConsumer.createConsumer(queue);
+
+ for (int i = 0; i < numMessages; i++) {
+ TextMessage m = (TextMessage) consumer.receive(5000);
+ Assert.assertNotNull("Could not receive message count=" + i + " on consumer", m);
+ Assert.assertEquals("text" + i, m.getText());
+ }
+
+ // assertEquals(0, q.getMessageCount());
+ long taken = (System.currentTimeMillis() - time) / 1000;
+ System.out.println("taken = " + taken);
+ }
+
+ @Test
+ public void testSimpleObject() throws Throwable {
+ final int numMessages = 1;
+ long time = System.currentTimeMillis();
+ final javax.jms.Queue queue = createQueue(address);
+
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer p = session.createProducer(queue);
+ for (int i = 0; i < numMessages; i++) {
+ System.out.println("Sending " + i);
+ ObjectMessage message = session.createObjectMessage(new AnythingSerializable(i));
+ p.send(message);
+ }
+
+ Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ final MessageConsumer consumer = sessionConsumer.createConsumer(queue);
+
+ for (int i = 0; i < numMessages; i++) {
+ ObjectMessage msg = (ObjectMessage) consumer.receive(5000);
+ Assert.assertNotNull("Could not receive message count=" + i + " on consumer", msg);
+
+ AnythingSerializable someSerialThing = (AnythingSerializable) msg.getObject();
+ Assert.assertEquals(i, someSerialThing.getCount());
+ }
+
+ // assertEquals(0, q.getMessageCount());
+ long taken = (System.currentTimeMillis() - time) / 1000;
+ System.out.println("taken = " + taken);
+ }
+
+ @Test
+ public void testSelector() throws Exception {
+ javax.jms.Queue queue = createQueue(address);
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageProducer p = session.createProducer(queue);
+ TextMessage message = session.createTextMessage();
+ message.setText("msg:0");
+ p.send(message);
+ message = session.createTextMessage();
+ message.setText("msg:1");
+ message.setStringProperty("color", "RED");
+ p.send(message);
+ connection.start();
+ MessageConsumer messageConsumer = session.createConsumer(queue, "color = 'RED'");
+ TextMessage m = (TextMessage) messageConsumer.receive(5000);
+ Assert.assertNotNull(m);
+ Assert.assertEquals("msg:1", m.getText());
+ Assert.assertEquals(m.getStringProperty("color"), "RED");
+ connection.close();
+ }
+
+ @Test
+ public void testProperties() throws Exception {
+ javax.jms.Queue queue = createQueue(address);
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageProducer p = session.createProducer(queue);
+ TextMessage message = session.createTextMessage();
+ message.setText("msg:0");
+ message.setBooleanProperty("true", true);
+ message.setBooleanProperty("false", false);
+ message.setStringProperty("foo", "bar");
+ message.setDoubleProperty("double", 66.6);
+ message.setFloatProperty("float", 56.789f);
+ message.setIntProperty("int", 8);
+ message.setByteProperty("byte", (byte) 10);
+ p.send(message);
+ p.send(message);
+ connection.start();
+ MessageConsumer messageConsumer = session.createConsumer(queue);
+ TextMessage m = (TextMessage) messageConsumer.receive(5000);
+ Assert.assertNotNull(m);
+ Assert.assertEquals("msg:0", m.getText());
+ Assert.assertEquals(m.getBooleanProperty("true"), true);
+ Assert.assertEquals(m.getBooleanProperty("false"), false);
+ Assert.assertEquals(m.getStringProperty("foo"), "bar");
+ Assert.assertEquals(m.getDoubleProperty("double"), 66.6, 0.0001);
+ Assert.assertEquals(m.getFloatProperty("float"), 56.789f, 0.0001);
+ Assert.assertEquals(m.getIntProperty("int"), 8);
+ Assert.assertEquals(m.getByteProperty("byte"), (byte) 10);
+ m = (TextMessage) messageConsumer.receive(5000);
+ Assert.assertNotNull(m);
+ connection.close();
+ }
+
+ @Test
+ public void testClientID() throws Exception {
+ Connection testConn1 = createConnection(false);
+ Connection testConn2 = createConnection(false);
+ try {
+ testConn1.setClientID("client-id1");
+ try {
+ testConn1.setClientID("client-id2");
+ fail("didn't get expected exception");
+ }
+ catch (javax.jms.IllegalStateException e) {
+ //expected
+ }
+
+ try {
+ testConn2.setClientID("client-id1");
+ fail("didn't get expected exception");
+ }
+ catch (InvalidClientIDException e) {
+ //expected
+ }
+ }
+ finally {
+ testConn1.close();
+ testConn2.close();
+ }
+
+ try {
+ testConn1 = createConnection(false);
+ testConn2 = createConnection(false);
+ testConn1.setClientID("client-id1");
+ testConn2.setClientID("client-id2");
+ }
+ finally {
+ testConn1.close();
+ testConn2.close();
+ }
+ }
+
+ private javax.jms.Queue createQueue(String address) throws Exception {
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ try {
+ return session.createQueue(address);
+ }
+ finally {
+ session.close();
+ }
+ }
+
+ private Connection createConnection() throws JMSException {
+ return this.createConnection(true);
+ }
+
+ private javax.jms.Connection createConnection(boolean isStart) throws JMSException {
+ Connection connection;
+ if (protocol == 3) {
+ factory = new JmsConnectionFactory(amqpConnectionUri);
+ connection = factory.createConnection();
+ }
+ else if (protocol == 0) {
+ factory = new JmsConnectionFactory(userName, password, amqpConnectionUri);
+ connection = factory.createConnection();
+ }
+ else {
+ Assert.fail("protocol = " + protocol + " not supported");
+ return null; // just to compile, the previous statement will throw an exception
+ }
+ if (isStart) {
+ connection.setExceptionListener(new ExceptionListener() {
+ @Override
+ public void onException(JMSException exception) {
+ exception.printStackTrace();
+ }
+ });
+ connection.start();
+ }
+
+ return connection;
+ }
+
+ private javax.jms.Connection createConnection(String clientId) throws JMSException {
+ Connection connection;
+ if (protocol == 3) {
+ factory = new JmsConnectionFactory(amqpConnectionUri);
+ connection = factory.createConnection();
+ connection.setExceptionListener(new ExceptionListener() {
+ @Override
+ public void onException(JMSException exception) {
+ exception.printStackTrace();
+ }
+ });
+ connection.setClientID(clientId);
+ connection.start();
+ }
+ else if (protocol == 0) {
+ factory = new JmsConnectionFactory(userName, password, amqpConnectionUri);
+ connection = factory.createConnection();
+ connection.setExceptionListener(new ExceptionListener() {
+ @Override
+ public void onException(JMSException exception) {
+ exception.printStackTrace();
+ }
+ });
+ connection.setClientID(clientId);
+ connection.start();
+ }
+ else {
+ Assert.fail("protocol = " + protocol + " not supported");
+ return null; // just to compile, the previous statement will throw an exception
+ }
+
+ return connection;
+ }
+
+
+ private void setAddressFullBlockPolicy() {
+ // For BLOCK tests
+ AddressSettings addressSettings = server.getAddressSettingsRepository().getMatch("#");
+ addressSettings.setAddressFullMessagePolicy(AddressFullMessagePolicy.BLOCK);
+ addressSettings.setMaxSizeBytes(maxSizeBytes);
+ addressSettings.setMaxSizeBytesRejectThreshold(maxSizeBytesRejectThreshold);
+ server.getAddressSettingsRepository().addMatch("#", addressSettings);
+ }
+
+ public static class AnythingSerializable implements Serializable {
+
+ private int count;
+
+ public AnythingSerializable(int count) {
+ this.count = count;
+ }
+
+ public int getCount() {
+ return count;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTestBase.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTestBase.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTestBase.java
new file mode 100644
index 0000000..d6369eb
--- /dev/null
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTestBase.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.tests.integration.amqp;
+
+import org.apache.activemq.artemis.api.core.TransportConfiguration;
+import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy;
+import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.junit.After;
+import org.junit.Before;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ProtonTestBase extends ActiveMQTestBase {
+
+ protected String brokerName = "my-broker";
+ protected ActiveMQServer server;
+
+ protected String tcpAmqpConnectionUri = "tcp://localhost:5672";
+ protected String userName = "guest";
+ protected String password = "guest";
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+
+ server = this.createServer(true, true);
+ HashMap<String, Object> params = new HashMap<>();
+ params.put(TransportConstants.PORT_PROP_NAME, "5672");
+ params.put(TransportConstants.PROTOCOLS_PROP_NAME, "AMQP");
+ HashMap<String, Object> amqpParams = new HashMap<>();
+ configureAmqp(amqpParams);
+ TransportConfiguration transportConfiguration = new TransportConfiguration(NETTY_ACCEPTOR_FACTORY, params, "amqp-acceptor", amqpParams);
+
+ server.getConfiguration().getAcceptorConfigurations().add(transportConfiguration);
+ server.getConfiguration().setName(brokerName);
+
+ // Default Page
+ AddressSettings addressSettings = new AddressSettings();
+ addressSettings.setAddressFullMessagePolicy(AddressFullMessagePolicy.PAGE);
+ server.getConfiguration().getAddressesSettings().put("#", addressSettings);
+
+ server.start();
+ }
+
+ protected void configureAmqp(Map<String, Object> params) {
+ }
+
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ try {
+ server.stop();
+ }
+ finally {
+ super.tearDown();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTestForHeader.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTestForHeader.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTestForHeader.java
new file mode 100644
index 0000000..a50af0d
--- /dev/null
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonTestForHeader.java
@@ -0,0 +1,219 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.tests.integration.amqp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.activemq.artemis.api.core.TransportConfiguration;
+import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
+import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger;
+import org.apache.activemq.artemis.tests.util.Wait;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.fusesource.hawtbuf.Buffer;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ProtonTestForHeader extends ActiveMQTestBase {
+
+ private ActiveMQServer server;
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ server = this.createServer(true, true);
+ HashMap<String, Object> params = new HashMap<>();
+ params.put(TransportConstants.PORT_PROP_NAME, "5672");
+ params.put(TransportConstants.PROTOCOLS_PROP_NAME, "AMQP");
+ TransportConfiguration transportConfiguration = new TransportConfiguration(NETTY_ACCEPTOR_FACTORY, params);
+
+ server.getConfiguration().getAcceptorConfigurations().add(transportConfiguration);
+ server.getConfiguration().setSecurityEnabled(true);
+ server.start();
+ ActiveMQJAASSecurityManager securityManager = (ActiveMQJAASSecurityManager) server.getSecurityManager();
+ securityManager.getConfiguration().addUser("auser", "pass");
+ }
+
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ try {
+ server.stop();
+ }
+ finally {
+ super.tearDown();
+ }
+ }
+
+ @Test
+ public void testSimpleBytes() throws Exception {
+ final AmqpHeader header = new AmqpHeader();
+
+ header.setProtocolId(0);
+ header.setMajor(1);
+ header.setMinor(0);
+ header.setRevision(0);
+
+ final ClientConnection connection = new ClientConnection();
+ connection.open("localhost", 5672);
+ connection.send(header);
+
+ AmqpHeader response = connection.readAmqpHeader();
+ assertNotNull(response);
+ IntegrationTestLogger.LOGGER.info("Broker responded with: " + response);
+
+ assertTrue("Broker should have closed client connection", Wait.waitFor(new Wait.Condition() {
+
+ @Override
+ public boolean isSatisfied() throws Exception {
+ try {
+ connection.send(header);
+ return false;
+ }
+ catch (Exception e) {
+ return true;
+ }
+ }
+ }, TimeUnit.SECONDS.toMillis(15), TimeUnit.MILLISECONDS.toMillis(250)));
+ }
+
+ private class ClientConnection {
+
+ protected static final long RECEIVE_TIMEOUT = 10000;
+ protected Socket clientSocket;
+
+ public void open(String host, int port) throws IOException {
+ clientSocket = new Socket(host, port);
+ clientSocket.setTcpNoDelay(true);
+ }
+
+ public void send(AmqpHeader header) throws Exception {
+ IntegrationTestLogger.LOGGER.info("Client sending header: " + header);
+ OutputStream outputStream = clientSocket.getOutputStream();
+ header.getBuffer().writeTo(outputStream);
+ outputStream.flush();
+ }
+
+ public AmqpHeader readAmqpHeader() throws Exception {
+ clientSocket.setSoTimeout((int) RECEIVE_TIMEOUT);
+ InputStream is = clientSocket.getInputStream();
+
+ byte[] header = new byte[8];
+ int read = is.read(header);
+ if (read == header.length) {
+ return new AmqpHeader(new Buffer(header));
+ }
+ else {
+ return null;
+ }
+ }
+ }
+
+ private class AmqpHeader {
+
+ final Buffer PREFIX = new Buffer(new byte[]{'A', 'M', 'Q', 'P'});
+
+ private Buffer buffer;
+
+ AmqpHeader() {
+ this(new Buffer(new byte[]{'A', 'M', 'Q', 'P', 0, 1, 0, 0}));
+ }
+
+ AmqpHeader(Buffer buffer) {
+ this(buffer, true);
+ }
+
+ AmqpHeader(Buffer buffer, boolean validate) {
+ setBuffer(buffer, validate);
+ }
+
+ public int getProtocolId() {
+ return buffer.get(4) & 0xFF;
+ }
+
+ public void setProtocolId(int value) {
+ buffer.data[buffer.offset + 4] = (byte) value;
+ }
+
+ public int getMajor() {
+ return buffer.get(5) & 0xFF;
+ }
+
+ public void setMajor(int value) {
+ buffer.data[buffer.offset + 5] = (byte) value;
+ }
+
+ public int getMinor() {
+ return buffer.get(6) & 0xFF;
+ }
+
+ public void setMinor(int value) {
+ buffer.data[buffer.offset + 6] = (byte) value;
+ }
+
+ public int getRevision() {
+ return buffer.get(7) & 0xFF;
+ }
+
+ public void setRevision(int value) {
+ buffer.data[buffer.offset + 7] = (byte) value;
+ }
+
+ public Buffer getBuffer() {
+ return buffer;
+ }
+
+ public void setBuffer(Buffer value) {
+ setBuffer(value, true);
+ }
+
+ public void setBuffer(Buffer value, boolean validate) {
+ if (validate && !value.startsWith(PREFIX) || value.length() != 8) {
+ throw new IllegalArgumentException("Not an AMQP header buffer");
+ }
+ buffer = value.buffer();
+ }
+
+ public boolean hasValidPrefix() {
+ return buffer.startsWith(PREFIX);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < buffer.length(); ++i) {
+ char value = (char) buffer.get(i);
+ if (Character.isLetter(value)) {
+ builder.append(value);
+ }
+ else {
+ builder.append(",");
+ builder.append((int) value);
+ }
+ }
+ return builder.toString();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/SendingAndReceivingTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/SendingAndReceivingTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/SendingAndReceivingTest.java
new file mode 100644
index 0000000..0c9783e
--- /dev/null
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/SendingAndReceivingTest.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.tests.integration.amqp;
+
+import java.util.Random;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.apache.qpid.jms.JmsConnectionFactory;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SendingAndReceivingTest extends ActiveMQTestBase {
+
+ private ActiveMQServer server;
+
+ @Before
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ server = createServer(true, true);
+ server.start();
+ }
+
+ @After
+ @Override
+ public void tearDown() throws Exception {
+ try {
+ server.stop();
+ }
+ finally {
+ super.tearDown();
+ }
+ }
+
+ //https://issues.apache.org/jira/browse/ARTEMIS-214
+ @Test
+ public void testSendingBigMessage() throws Exception {
+ Connection connection = null;
+ ConnectionFactory connectionFactory = new JmsConnectionFactory("amqp://localhost:61616");
+
+ try {
+ connection = connectionFactory.createConnection();
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Queue queue = session.createQueue("jms.queue.exampleQueue");
+ MessageProducer sender = session.createProducer(queue);
+
+ String body = createMessage(10240);
+ sender.send(session.createTextMessage(body));
+ connection.start();
+
+ MessageConsumer consumer = session.createConsumer(queue);
+ TextMessage m = (TextMessage) consumer.receive(5000);
+
+ Assert.assertEquals(body, m.getText());
+ }
+ finally {
+ if (connection != null) {
+ connection.close();
+ }
+ }
+ }
+
+ private static String createMessage(int messageSize) {
+ final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ Random rnd = new Random();
+ StringBuilder sb = new StringBuilder(messageSize);
+ for (int j = 0; j < messageSize; j++ ) {
+ sb.append(AB.charAt(rnd.nextInt(AB.length())));
+ }
+ String body = sb.toString();
+ return body;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/jms/SendingAndReceivingTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/jms/SendingAndReceivingTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/jms/SendingAndReceivingTest.java
deleted file mode 100644
index d298267..0000000
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/jms/SendingAndReceivingTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.tests.integration.amqp.jms;
-
-import java.util.Random;
-
-import javax.jms.Connection;
-import javax.jms.ConnectionFactory;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageProducer;
-import javax.jms.Queue;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-
-import org.apache.activemq.artemis.core.server.ActiveMQServer;
-import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.apache.qpid.jms.JmsConnectionFactory;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class SendingAndReceivingTest extends ActiveMQTestBase {
-
- private ActiveMQServer server;
-
- @Before
- @Override
- public void setUp() throws Exception {
- super.setUp();
- server = createServer(true, true);
- server.start();
- }
-
- @After
- @Override
- public void tearDown() throws Exception {
- try {
- server.stop();
- }
- finally {
- super.tearDown();
- }
- }
-
- //https://issues.apache.org/jira/browse/ARTEMIS-214
- @Test
- public void testSendingBigMessage() throws Exception {
- Connection connection = null;
- ConnectionFactory connectionFactory = new JmsConnectionFactory("amqp://localhost:61616");
-
- try {
- connection = connectionFactory.createConnection();
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Queue queue = session.createQueue("jms.queue.exampleQueue");
- MessageProducer sender = session.createProducer(queue);
-
- String body = createMessage(10240);
- sender.send(session.createTextMessage(body));
- connection.start();
-
- MessageConsumer consumer = session.createConsumer(queue);
- TextMessage m = (TextMessage) consumer.receive(5000);
-
- Assert.assertEquals(body, m.getText());
- }
- finally {
- if (connection != null) {
- connection.close();
- }
- }
- }
-
- private static String createMessage(int messageSize) {
- final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- Random rnd = new Random();
- StringBuilder sb = new StringBuilder(messageSize);
- for (int j = 0; j < messageSize; j++ ) {
- sb.append(AB.charAt(rnd.nextInt(AB.length())));
- }
- String body = sb.toString();
- return body;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonMaxFrameSizeTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonMaxFrameSizeTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonMaxFrameSizeTest.java
deleted file mode 100644
index 908285e..0000000
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonMaxFrameSizeTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.tests.integration.proton;
-
-import org.apache.activemq.transport.amqp.client.AmqpClient;
-import org.apache.activemq.transport.amqp.client.AmqpConnection;
-import org.apache.activemq.transport.amqp.client.AmqpMessage;
-import org.apache.activemq.transport.amqp.client.AmqpReceiver;
-import org.apache.activemq.transport.amqp.client.AmqpSender;
-import org.apache.activemq.transport.amqp.client.AmqpSession;
-import org.apache.qpid.proton.amqp.messaging.Data;
-import org.apache.qpid.proton.message.impl.MessageImpl;
-import org.junit.Test;
-
-import java.net.URI;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-public class ProtonMaxFrameSizeTest extends ProtonTestBase {
-
- private static final int FRAME_SIZE = 512;
-
- @Override
- protected void configureAmqp(Map<String, Object> params) {
- params.put("maxFrameSize", FRAME_SIZE);
- }
-
- @Test
- public void testMultipleTransfers() throws Exception {
-
- String testQueueName = "ConnectionFrameSize";
- int nMsgs = 200;
-
- AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
-
-
- AmqpConnection amqpConnection = client.createConnection();
-
- try {
- amqpConnection.connect();
-
- AmqpSession session = amqpConnection.createSession();
- AmqpSender sender = session.createSender("jms.queue." + testQueueName);
-
- final int payload = FRAME_SIZE * 16;
-
- for (int i = 0; i < nMsgs; ++i) {
- AmqpMessage message = createAmqpMessage((byte) 'A', payload);
- sender.send(message);
- }
-
- int count = getMessageCount(server.getPostOffice(), "jms.queue." + testQueueName);
- assertEquals(nMsgs, count);
-
- AmqpReceiver receiver = session.createReceiver("jms.queue." + testQueueName);
- receiver.flow(nMsgs);
-
- for (int i = 0; i < nMsgs; ++i) {
- AmqpMessage message = receiver.receive(5, TimeUnit.SECONDS);
- assertNotNull("failed at " + i, message);
- MessageImpl wrapped = (MessageImpl) message.getWrappedMessage();
- Data data = (Data) wrapped.getBody();
- System.out.println("received : message: " + data.getValue().getLength());
- assertEquals(payload, data.getValue().getLength());
- message.accept();
- }
-
- }
- finally {
- amqpConnection.close();
- }
- }
-
- private AmqpMessage createAmqpMessage(byte value, int payloadSize) {
- AmqpMessage message = new AmqpMessage();
- byte[] payload = new byte[payloadSize];
- for (int i = 0; i < payload.length; i++) {
- payload[i] = value;
- }
- message.setBytes(payload);
- return message;
- }
-
-}
[07/15] activemq-artemis git commit: ARTEMIS-751 Simplification of
the AMQP implementation
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPConnectionContextFactory.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPConnectionContextFactory.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPConnectionContextFactory.java
deleted file mode 100644
index eb2a778..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPConnectionContextFactory.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug;
-
-import java.util.concurrent.Executor;
-import java.util.concurrent.ScheduledExecutorService;
-
-public abstract class AMQPConnectionContextFactory {
-
- /**
- * @return
- */
- public abstract AMQPConnectionContext createConnection(AMQPConnectionCallback connectionCallback,
- String containerId,
- int idleTimeout,
- int maxFrameSize,
- int channelMax,
- Executor dispatchExecutor,
- ScheduledExecutorService scheduledPool);
-
- /**
- * @return
- */
- public abstract AMQPConnectionContext createConnection(AMQPConnectionCallback connectionCallback, Executor dispatchExecutor, ScheduledExecutorService scheduledPool);
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPServerConnectionContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPServerConnectionContext.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPServerConnectionContext.java
deleted file mode 100644
index 518c79e..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPServerConnectionContext.java
+++ /dev/null
@@ -1,21 +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.proton.plug;
-
-public interface AMQPServerConnectionContext extends AMQPConnectionContext {
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPSessionCallback.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPSessionCallback.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPSessionCallback.java
deleted file mode 100644
index 5f3b6dd..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPSessionCallback.java
+++ /dev/null
@@ -1,112 +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.proton.plug;
-
-import io.netty.buffer.ByteBuf;
-import org.apache.activemq.artemis.core.server.QueueQueryResult;
-import org.apache.activemq.artemis.core.transaction.Transaction;
-import org.apache.qpid.proton.amqp.Binary;
-import org.apache.qpid.proton.engine.Delivery;
-import org.apache.qpid.proton.engine.Receiver;
-import org.apache.qpid.proton.message.ProtonJMessage;
-import org.proton.plug.context.ProtonPlugSender;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-
-/**
- * These are methods where the Proton Plug component will call your server
- */
-public interface AMQPSessionCallback {
-
- void init(AMQPSessionContext session, SASLResult saslResult) throws Exception;
-
- void start();
-
- void onFlowConsumer(Object consumer, int credits, boolean drain);
-
- Object createSender(ProtonPlugSender protonSender, String queue, String filer, boolean browserOnly) throws Exception;
-
- void startSender(Object brokerConsumer) throws Exception;
-
- void createTemporaryQueue(String queueName) throws Exception;
-
- void createTemporaryQueue(String address, String queueName, String filter) throws Exception;
-
- void createDurableQueue(String address, String queueName, String filter) throws Exception;
-
- void offerProducerCredit(String address, int credits, int threshold, Receiver receiver);
-
- void deleteQueue(String address) throws Exception;
-
- /**
- * Returns true if a queue is found with matching name, if autoCreate=true and autoCreateJMSQueues is switched on then
- * this method will auto create the queue, with name=queueName, address=queueName, filter=null.
- *
- * @param queueName
- * @param autoCreate
- * @return
- * @throws Exception
- */
- QueueQueryResult queueQuery(String queueName, boolean autoCreate) throws Exception;
-
- boolean bindingQuery(String address) throws Exception;
-
- void closeSender(Object brokerConsumer) throws Exception;
-
- // This one can be a lot improved
- ProtonJMessage encodeMessage(Object message, int deliveryCount) throws Exception;
-
- String tempQueueName();
-
-
- Transaction getTransaction(Binary txid) throws ActiveMQAMQPException;
-
- Binary newTransaction();
-
- void commitTX(Binary txid) throws Exception;
-
- void rollbackTX(Binary txid, boolean lastMessageReceived) throws Exception;
-
- void close() throws Exception;
-
- void ack(Transaction transaction, Object brokerConsumer, Object message) throws Exception;
-
- /**
- * @param brokerConsumer
- * @param message
- * @param updateCounts this identified if the cancel was because of a failure or just cleaning up the
- * client's cache.
- * in some implementations you could call this failed
- */
- void cancel(Object brokerConsumer, Object message, boolean updateCounts) throws Exception;
-
- void resumeDelivery(Object consumer);
-
- /**
- * @param delivery
- * @param address
- * @param messageFormat
- * @param messageEncoded a Heap Buffer ByteBuffer (safe to convert into byte[])
- */
- void serverSend(Transaction transaction,
- Receiver receiver,
- Delivery delivery,
- String address,
- int messageFormat,
- ByteBuf messageEncoded) throws Exception;
-
- String getPubSubPrefix();
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPSessionContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPSessionContext.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPSessionContext.java
deleted file mode 100644
index 66e9c5a..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPSessionContext.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug;
-
-import org.apache.qpid.proton.engine.Receiver;
-import org.apache.qpid.proton.engine.Sender;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-
-public interface AMQPSessionContext {
-
- byte[] getTag();
-
- void replaceTag(byte[] tag);
-
- void close();
-
- void removeSender(Sender sender) throws ActiveMQAMQPException;
-
- void removeReceiver(Receiver receiver);
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AmqpSupport.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AmqpSupport.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AmqpSupport.java
deleted file mode 100644
index 4ddbbcc..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AmqpSupport.java
+++ /dev/null
@@ -1,131 +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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.proton.plug;
-
-import org.apache.qpid.proton.amqp.DescribedType;
-import org.apache.qpid.proton.amqp.Symbol;
-import org.apache.qpid.proton.amqp.UnsignedLong;
-
-import java.util.AbstractMap;
-import java.util.Map;
-
-/**
- * Set of useful methods and definitions used in the AMQP protocol handling
- */
-public class AmqpSupport {
-
- // Identification values used to locating JMS selector types.
- public static final UnsignedLong JMS_SELECTOR_CODE = UnsignedLong.valueOf(0x0000468C00000004L);
- public static final Symbol JMS_SELECTOR_NAME = Symbol.valueOf("apache.org:selector-filter:string");
- public static final Object[] JMS_SELECTOR_FILTER_IDS = new Object[]{JMS_SELECTOR_CODE, JMS_SELECTOR_NAME};
- public static final UnsignedLong NO_LOCAL_CODE = UnsignedLong.valueOf(0x0000468C00000003L);
- public static final Symbol NO_LOCAL_NAME = Symbol.valueOf("apache.org:no-local-filter:list");
- public static final Object[] NO_LOCAL_FILTER_IDS = new Object[]{NO_LOCAL_CODE, NO_LOCAL_NAME};
-
- // Capabilities used to identify destination type in some requests.
- public static final Symbol TEMP_QUEUE_CAPABILITY = Symbol.valueOf("temporary-queue");
- public static final Symbol TEMP_TOPIC_CAPABILITY = Symbol.valueOf("temporary-topic");
-
- // Symbols used to announce connection information to remote peer.
- public static final Symbol INVALID_FIELD = Symbol.valueOf("invalid-field");
- public static final Symbol CONTAINER_ID = Symbol.valueOf("container-id");
-
- // Symbols used to announce connection information to remote peer.
- public static final Symbol ANONYMOUS_RELAY = Symbol.valueOf("ANONYMOUS-RELAY");
- public static final Symbol DELAYED_DELIVERY = Symbol.valueOf("DELAYED_DELIVERY");
- public static final Symbol QUEUE_PREFIX = Symbol.valueOf("queue-prefix");
- public static final Symbol TOPIC_PREFIX = Symbol.valueOf("topic-prefix");
- public static final Symbol CONNECTION_OPEN_FAILED = Symbol.valueOf("amqp:connection-establishment-failed");
- public static final Symbol PRODUCT = Symbol.valueOf("product");
- public static final Symbol VERSION = Symbol.valueOf("version");
- public static final Symbol PLATFORM = Symbol.valueOf("platform");
-
- // Symbols used in configuration of newly opened links.
- public static final Symbol COPY = Symbol.getSymbol("copy");
-
- // Lifetime policy symbols
- public static final Symbol LIFETIME_POLICY = Symbol.valueOf("lifetime-policy");
-
- public static final Symbol SOLE_CONNECTION_CAPABILITY = Symbol.valueOf("sole-connection-for-container");
- /**
- * Search for a given Symbol in a given array of Symbol object.
- *
- * @param symbols
- * the set of Symbols to search.
- * @param key
- * the value to try and find in the Symbol array.
- *
- * @return true if the key is found in the given Symbol array.
- */
- public static boolean contains(Symbol[] symbols, Symbol key) {
- if (symbols == null || symbols.length == 0) {
- return false;
- }
-
- for (Symbol symbol : symbols) {
- if (symbol.equals(key)) {
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Search for a particular filter using a set of known indentification values
- * in the Map of filters.
- *
- * @param filters
- * The filters map that should be searched.
- * @param filterIds
- * The aliases for the target filter to be located.
- *
- * @return the filter if found in the mapping or null if not found.
- */
- public static Map.Entry<Symbol, DescribedType> findFilter(Map<Symbol, Object> filters, Object[] filterIds) {
-
- if (filterIds == null || filterIds.length == 0) {
- StringBuilder ids = new StringBuilder();
- if (filterIds != null) {
- for (Object filterId : filterIds) {
- ids.append(filterId).append(" ");
- }
- }
- throw new IllegalArgumentException("Invalid Filter Ids array passed: " + ids);
- }
-
- if (filters == null || filters.isEmpty()) {
- return null;
- }
-
- for (Map.Entry<Symbol, Object> filter : filters.entrySet()) {
- if (filter.getValue() instanceof DescribedType) {
- DescribedType describedType = ((DescribedType) filter.getValue());
- Object descriptor = describedType.getDescriptor();
-
- for (Object filterId : filterIds) {
- if (descriptor.equals(filterId)) {
- return new AbstractMap.SimpleImmutableEntry<>(filter.getKey(), describedType);
- }
- }
- }
- }
-
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/ClientSASL.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/ClientSASL.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/ClientSASL.java
deleted file mode 100644
index c36fd19..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/ClientSASL.java
+++ /dev/null
@@ -1,24 +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.proton.plug;
-
-public interface ClientSASL {
-
- byte[] getBytes();
-
- String getName();
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/SASLResult.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/SASLResult.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/SASLResult.java
deleted file mode 100644
index f7ff671..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/SASLResult.java
+++ /dev/null
@@ -1,24 +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.proton.plug;
-
-public interface SASLResult {
-
- String getUser();
-
- boolean isSuccess();
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/ServerSASL.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/ServerSASL.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/ServerSASL.java
deleted file mode 100644
index ed1c361..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/ServerSASL.java
+++ /dev/null
@@ -1,24 +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.proton.plug;
-
-public interface ServerSASL {
-
- String getName();
-
- SASLResult processSASL(byte[] bytes);
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/AMQPConstants.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/AMQPConstants.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/AMQPConstants.java
deleted file mode 100644
index 6287c06..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/AMQPConstants.java
+++ /dev/null
@@ -1,36 +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
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * 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.proton.plug.context;
-
-/**
- * Constants derived from the AMQP spec
- */
-public class AMQPConstants {
-
- /*
- * Connection Properties
- * http://docs.oasis-open.org/amqp/core/v1.0/amqp-core-complete-v1.0.pdf#subsection.2.7.1
- * */
- public static class Connection {
-
- public static final int DEFAULT_IDLE_TIMEOUT = -1;
-
- public static final int DEFAULT_MAX_FRAME_SIZE = -1;//it should be according to the spec 4294967295l;
-
- public static final int DEFAULT_CHANNEL_MAX = 65535;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/AbstractConnectionContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/AbstractConnectionContext.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/AbstractConnectionContext.java
deleted file mode 100644
index 120a37b..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/AbstractConnectionContext.java
+++ /dev/null
@@ -1,360 +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.proton.plug.context;
-
-import static org.proton.plug.AmqpSupport.PRODUCT;
-import static org.proton.plug.AmqpSupport.VERSION;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import io.netty.buffer.ByteBuf;
-import org.apache.activemq.artemis.utils.VersionLoader;
-import org.apache.qpid.proton.amqp.Symbol;
-import org.apache.qpid.proton.engine.Connection;
-import org.apache.qpid.proton.engine.Delivery;
-import org.apache.qpid.proton.engine.Link;
-import org.apache.qpid.proton.engine.Session;
-import org.apache.qpid.proton.engine.Transport;
-import org.jboss.logging.Logger;
-import org.proton.plug.AMQPConnectionCallback;
-import org.proton.plug.AMQPConnectionContext;
-import org.proton.plug.SASLResult;
-import org.proton.plug.context.server.ProtonServerSenderContext;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-import org.proton.plug.handler.ProtonHandler;
-import org.proton.plug.handler.impl.DefaultEventHandler;
-import org.proton.plug.util.ByteUtil;
-
-import static org.proton.plug.context.AMQPConstants.Connection.DEFAULT_CHANNEL_MAX;
-import static org.proton.plug.context.AMQPConstants.Connection.DEFAULT_IDLE_TIMEOUT;
-import static org.proton.plug.context.AMQPConstants.Connection.DEFAULT_MAX_FRAME_SIZE;
-
-public abstract class AbstractConnectionContext extends ProtonInitializable implements AMQPConnectionContext {
- private static final Logger log = Logger.getLogger(AbstractConnectionContext.class);
-
- public static final Symbol CONNECTION_OPEN_FAILED = Symbol.valueOf("amqp:connection-establishment-failed");
- public static final String AMQP_CONTAINER_ID = "amqp-container-id";
-
- protected final ProtonHandler handler;
-
- protected AMQPConnectionCallback connectionCallback;
- private final String containerId;
- private final Map<Symbol, Object> connectionProperties = new HashMap<>();
- private final ScheduledExecutorService scheduledPool;
-
- private final Map<Session, AbstractProtonSessionContext> sessions = new ConcurrentHashMap<>();
-
- protected LocalListener listener = new LocalListener();
-
- public AbstractConnectionContext(AMQPConnectionCallback connectionCallback, Executor dispatchExecutor, ScheduledExecutorService scheduledPool) {
- this(connectionCallback, null, DEFAULT_IDLE_TIMEOUT, DEFAULT_MAX_FRAME_SIZE, DEFAULT_CHANNEL_MAX, dispatchExecutor, scheduledPool);
- }
-
- public AbstractConnectionContext(AMQPConnectionCallback connectionCallback,
- String containerId,
- int idleTimeout,
- int maxFrameSize,
- int channelMax,
- Executor dispatchExecutor,
- ScheduledExecutorService scheduledPool) {
- this.connectionCallback = connectionCallback;
- this.containerId = (containerId != null) ? containerId : UUID.randomUUID().toString();
-
- connectionProperties.put(PRODUCT, "apache-activemq-artemis");
- connectionProperties.put(VERSION, VersionLoader.getVersion().getFullVersion());
-
- this.scheduledPool = scheduledPool;
- connectionCallback.setConnection(this);
- this.handler = ProtonHandler.Factory.create(dispatchExecutor);
- Transport transport = handler.getTransport();
- transport.setEmitFlowEventOnSend(false);
- if (idleTimeout > 0) {
- transport.setIdleTimeout(idleTimeout);
- }
- transport.setChannelMax(channelMax);
- transport.setMaxFrameSize(maxFrameSize);
- handler.addEventHandler(listener);
- }
-
- @Override
- public SASLResult getSASLResult() {
- return handler.getSASLResult();
- }
-
- @Override
- public void inputBuffer(ByteBuf buffer) {
- if (log.isTraceEnabled()) {
- ByteUtil.debugFrame(log, "Buffer Received ", buffer);
- }
-
- handler.inputBuffer(buffer);
- }
-
- public void destroy() {
- connectionCallback.close();
- }
-
- /**
- * See comment at {@link org.proton.plug.AMQPConnectionContext#isSyncOnFlush()}
- */
- @Override
- public boolean isSyncOnFlush() {
- return false;
- }
-
- @Override
- public Object getLock() {
- return handler.getLock();
- }
-
- @Override
- public int capacity() {
- return handler.capacity();
- }
-
- @Override
- public void outputDone(int bytes) {
- handler.outputDone(bytes);
- }
-
- @Override
- public void flush() {
- handler.flush();
- }
-
- @Override
- public void close() {
- handler.close();
- }
-
- protected AbstractProtonSessionContext getSessionExtension(Session realSession) throws ActiveMQAMQPException {
- AbstractProtonSessionContext sessionExtension = sessions.get(realSession);
- if (sessionExtension == null) {
- // how this is possible? Log a warn here
- sessionExtension = newSessionExtension(realSession);
- realSession.setContext(sessionExtension);
- sessions.put(realSession, sessionExtension);
- }
- return sessionExtension;
- }
-
- protected abstract void remoteLinkOpened(Link link) throws Exception;
-
- protected abstract AbstractProtonSessionContext newSessionExtension(Session realSession) throws ActiveMQAMQPException;
-
- @Override
- public boolean checkDataReceived() {
- return handler.checkDataReceived();
- }
-
- @Override
- public long getCreationTime() {
- return handler.getCreationTime();
- }
-
- protected void flushBytes() {
- ByteBuf bytes;
- // handler.outputBuffer has the lock
- while ((bytes = handler.outputBuffer()) != null) {
- connectionCallback.onTransport(bytes, AbstractConnectionContext.this);
- }
- }
-
- public String getRemoteContainer() {
- return handler.getConnection().getRemoteContainer();
- }
-
- public String getPubSubPrefix() {
- return null;
- }
-
- protected boolean validateConnection(Connection connection) {
- return true;
- }
-
- protected void initInternal() throws Exception {
- }
-
- // This listener will perform a bunch of things here
- class LocalListener extends DefaultEventHandler {
-
- @Override
- public void onAuthInit(ProtonHandler handler, Connection connection, boolean sasl) {
- if (sasl) {
- handler.createServerSASL(connectionCallback.getSASLMechnisms());
- }
- else {
- if (!connectionCallback.isSupportsAnonymous()) {
- connectionCallback.sendSASLSupported();
- connectionCallback.close();
- handler.close();
- }
- }
- }
-
- @Override
- public void onTransport(Transport transport) {
- flushBytes();
- }
-
- @Override
- public void onRemoteOpen(Connection connection) throws Exception {
- synchronized (getLock()) {
- try {
- initInternal();
- }
- catch (Exception e) {
- log.error("Error init connection", e);
- }
- if (!validateConnection(connection)) {
- connection.close();
- }
- else {
- connection.setContext(AbstractConnectionContext.this);
- connection.setContainer(containerId);
- connection.setProperties(connectionProperties);
- connection.setOfferedCapabilities(getConnectionCapabilitiesOffered());
- connection.open();
- }
- }
- initialise();
-
- /*
- * This can be null which is in effect an empty map, also we really dont need to check this for in bound connections
- * but its here in case we add support for outbound connections.
- * */
- if (connection.getRemoteProperties() == null || !connection.getRemoteProperties().containsKey(CONNECTION_OPEN_FAILED)) {
- long nextKeepAliveTime = handler.tick(true);
- flushBytes();
- if (nextKeepAliveTime > 0 && scheduledPool != null) {
- scheduledPool.schedule(new Runnable() {
- @Override
- public void run() {
- long rescheduleAt = (handler.tick(false) - TimeUnit.NANOSECONDS.toMillis(System.nanoTime()));
- flushBytes();
- if (rescheduleAt > 0) {
- scheduledPool.schedule(this, rescheduleAt, TimeUnit.MILLISECONDS);
- }
- }
- }, (nextKeepAliveTime - TimeUnit.NANOSECONDS.toMillis(System.nanoTime())), TimeUnit.MILLISECONDS);
- }
- }
- }
-
- @Override
- public void onRemoteClose(Connection connection) {
- synchronized (getLock()) {
- connection.close();
- for (AbstractProtonSessionContext protonSession : sessions.values()) {
- protonSession.close();
- }
- sessions.clear();
- }
- // We must force write the channel before we actually destroy the connection
- onTransport(handler.getTransport());
- destroy();
- }
-
- @Override
- public void onLocalOpen(Session session) throws Exception {
- getSessionExtension(session);
- }
-
- @Override
- public void onRemoteOpen(Session session) throws Exception {
- getSessionExtension(session).initialise();
- synchronized (getLock()) {
- session.open();
- }
- }
-
- @Override
- public void onLocalClose(Session session) throws Exception {
- }
-
- @Override
- public void onRemoteClose(Session session) throws Exception {
- synchronized (getLock()) {
- session.close();
- }
-
- AbstractProtonSessionContext sessionContext = (AbstractProtonSessionContext) session.getContext();
- if (sessionContext != null) {
- sessionContext.close();
- sessions.remove(session);
- session.setContext(null);
- }
- }
-
- @Override
- public void onRemoteOpen(Link link) throws Exception {
- remoteLinkOpened(link);
- }
-
- @Override
- public void onFlow(Link link) throws Exception {
- ((ProtonDeliveryHandler) link.getContext()).onFlow(link.getCredit(), link.getDrain());
- }
-
- @Override
- public void onRemoteClose(Link link) throws Exception {
- link.close();
- ProtonDeliveryHandler linkContext = (ProtonDeliveryHandler) link.getContext();
- if (linkContext != null) {
- linkContext.close(true);
- }
- }
-
- @Override
- public void onRemoteDetach(Link link) throws Exception {
- link.detach();
- }
-
- @Override
- public void onDetach(Link link) throws Exception {
- Object context = link.getContext();
- if (context instanceof ProtonServerSenderContext) {
- ProtonServerSenderContext senderContext = (ProtonServerSenderContext) context;
- senderContext.close(false);
- }
- }
-
- @Override
- public void onDelivery(Delivery delivery) throws Exception {
- ProtonDeliveryHandler handler = (ProtonDeliveryHandler) delivery.getLink().getContext();
- if (handler != null) {
- handler.onMessage(delivery);
- }
- else {
- // TODO: logs
-
- System.err.println("Handler is null, can't delivery " + delivery);
- }
- }
- }
-
- @Override
- public Symbol[] getConnectionCapabilitiesOffered() {
- return null;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/AbstractProtonContextSender.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/AbstractProtonContextSender.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/AbstractProtonContextSender.java
deleted file mode 100644
index 29e3459..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/AbstractProtonContextSender.java
+++ /dev/null
@@ -1,153 +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.proton.plug.context;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.PooledByteBufAllocator;
-import org.apache.qpid.proton.amqp.transport.ErrorCondition;
-import org.apache.qpid.proton.amqp.transport.SenderSettleMode;
-import org.apache.qpid.proton.engine.Delivery;
-import org.apache.qpid.proton.engine.Sender;
-import org.apache.qpid.proton.message.ProtonJMessage;
-import org.proton.plug.AMQPSessionCallback;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-import org.proton.plug.util.CreditsSemaphore;
-import org.proton.plug.util.NettyWritable;
-
-/**
- * A this is a wrapper around an ActiveMQ Artemis ServerConsumer for handling outgoing messages and incoming acks via a Proton Sender
- */
-public abstract class AbstractProtonContextSender extends ProtonInitializable implements ProtonDeliveryHandler {
-
- protected final AbstractProtonSessionContext protonSession;
- protected final Sender sender;
- protected final AbstractConnectionContext connection;
- protected boolean closed = false;
- protected final AMQPSessionCallback sessionSPI;
- protected CreditsSemaphore creditsSemaphore = new CreditsSemaphore(0);
-
- public AbstractProtonContextSender(AbstractConnectionContext connection,
- Sender sender,
- AbstractProtonSessionContext protonSession,
- AMQPSessionCallback server) {
- this.connection = connection;
- this.sender = sender;
- this.protonSession = protonSession;
- this.sessionSPI = server;
- }
-
- @Override
- public void onFlow(int credits, boolean drain) {
- this.creditsSemaphore.setCredits(credits);
- }
-
- /*
- * start the session
- * */
- public void start() throws ActiveMQAMQPException {
- sessionSPI.start();
- // protonSession.getServerSession().start();
- }
-
- /*
- * close the session
- * */
- @Override
- public void close(boolean linkRemoteClose) throws ActiveMQAMQPException {
- closed = true;
- protonSession.removeSender(sender);
- synchronized (connection.getLock()) {
- sender.close();
- }
-
- connection.flush();
- }
-
- /*
- * close the session
- * */
- @Override
- public void close(ErrorCondition condition) throws ActiveMQAMQPException {
- closed = true;
- sender.setCondition(condition);
- close(false);
- }
-
- @Override
- /*
- * handle an incoming Ack from Proton, basically pass to ActiveMQ Artemis to handle
- * */ public abstract void onMessage(Delivery delivery) throws ActiveMQAMQPException;
-
- /*
- * check the state of the consumer, i.e. are there any more messages. only really needed for browsers?
- * */
- public void checkState() {
- }
-
- public Sender getSender() {
- return sender;
- }
-
- protected int performSend(ProtonJMessage serverMessage, Object context) {
- if (!creditsSemaphore.tryAcquire()) {
- try {
- creditsSemaphore.acquire();
- }
- catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- // nothing to be done here.. we just keep going
- throw new IllegalStateException(e.getMessage(), e);
- }
- }
-
- //presettle means we can ack the message on the dealer side before we send it, i.e. for browsers
- boolean preSettle = sender.getRemoteSenderSettleMode() == SenderSettleMode.SETTLED;
-
- //we only need a tag if we are going to ack later
- byte[] tag = preSettle ? new byte[0] : protonSession.getTag();
-
- ByteBuf nettyBuffer = PooledByteBufAllocator.DEFAULT.heapBuffer(1024);
- try {
- serverMessage.encode(new NettyWritable(nettyBuffer));
-
- int size = nettyBuffer.writerIndex();
-
- synchronized (connection.getLock()) {
- final Delivery delivery;
- delivery = sender.delivery(tag, 0, tag.length);
- delivery.setContext(context);
-
- // this will avoid a copy.. patch provided by Norman using buffer.array()
- sender.send(nettyBuffer.array(), nettyBuffer.arrayOffset() + nettyBuffer.readerIndex(), nettyBuffer.readableBytes());
-
- if (preSettle) {
- delivery.settle();
- }
- else {
- sender.advance();
- }
- }
-
- connection.flush();
-
- return size;
- }
- finally {
- nettyBuffer.release();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/AbstractProtonReceiverContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/AbstractProtonReceiverContext.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/AbstractProtonReceiverContext.java
deleted file mode 100644
index c210950..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/AbstractProtonReceiverContext.java
+++ /dev/null
@@ -1,88 +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.proton.plug.context;
-
-import org.apache.qpid.proton.amqp.transport.ErrorCondition;
-import org.apache.qpid.proton.engine.Receiver;
-import org.proton.plug.AMQPSessionCallback;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-
-/**
- * handles incoming messages via a Proton Receiver and forwards them to ActiveMQ
- */
-public abstract class AbstractProtonReceiverContext extends ProtonInitializable implements ProtonDeliveryHandler {
-
- protected final AbstractConnectionContext connection;
-
- protected final AbstractProtonSessionContext protonSession;
-
- protected final Receiver receiver;
-
- protected String address;
-
- protected final AMQPSessionCallback sessionSPI;
-
- public AbstractProtonReceiverContext(AMQPSessionCallback sessionSPI,
- AbstractConnectionContext connection,
- AbstractProtonSessionContext protonSession,
- Receiver receiver) {
- this.connection = connection;
- this.protonSession = protonSession;
- this.receiver = receiver;
- this.sessionSPI = sessionSPI;
- }
-
- @Override
- public void close(boolean remoteLinkClose) throws ActiveMQAMQPException {
- protonSession.removeReceiver(receiver);
- }
-
- @Override
- public void close(ErrorCondition condition) throws ActiveMQAMQPException {
- receiver.setCondition(condition);
- close(false);
- }
-
- public void flow(int credits, int threshold) {
- // Use the SessionSPI to allocate producer credits, or default, always allocate credit.
- if (sessionSPI != null) {
- sessionSPI.offerProducerCredit(address, credits, threshold, receiver);
- }
- else {
- synchronized (connection.getLock()) {
- receiver.flow(credits);
- connection.flush();
- }
- }
-
- }
-
- public void drain(int credits) {
- synchronized (connection.getLock()) {
- receiver.drain(credits);
- }
- connection.flush();
- }
-
- public int drained() {
- return receiver.drained();
- }
-
- public boolean isDraining() {
- return receiver.draining();
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/AbstractProtonSessionContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/AbstractProtonSessionContext.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/AbstractProtonSessionContext.java
deleted file mode 100644
index 5c0a626..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/AbstractProtonSessionContext.java
+++ /dev/null
@@ -1,161 +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.proton.plug.context;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.qpid.proton.amqp.transport.ErrorCondition;
-import org.apache.qpid.proton.engine.Receiver;
-import org.apache.qpid.proton.engine.Sender;
-import org.apache.qpid.proton.engine.Session;
-import org.jboss.logging.Logger;
-import org.proton.plug.AMQPSessionCallback;
-import org.proton.plug.AMQPSessionContext;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-import org.proton.plug.exceptions.ActiveMQAMQPInternalErrorException;
-
-/**
- * ProtonSession is a direct representation of the session on the broker.
- * It has a link between a ProtonSession and a Broker or Client Session
- * The Broker Session is linked through the ProtonSessionSPI
- */
-public abstract class AbstractProtonSessionContext extends ProtonInitializable implements AMQPSessionContext {
-
- private static final Logger log = Logger.getLogger(AbstractProtonSessionContext.class);
- protected final AbstractConnectionContext connection;
-
- protected final AMQPSessionCallback sessionSPI;
-
- protected final Session session;
-
- private long currentTag = 0;
-
- protected Map<Receiver, AbstractProtonReceiverContext> receivers = new HashMap<>();
-
- protected Map<Sender, AbstractProtonContextSender> senders = new HashMap<>();
-
- protected boolean closed = false;
-
- public AbstractProtonSessionContext(AMQPSessionCallback sessionSPI,
- AbstractConnectionContext connection,
- Session session) {
- this.connection = connection;
- this.sessionSPI = sessionSPI;
- this.session = session;
- }
-
- @Override
- public void initialise() throws Exception {
- if (!isInitialized()) {
- super.initialise();
-
- if (sessionSPI != null) {
- try {
- sessionSPI.init(this, connection.getSASLResult());
- }
- catch (Exception e) {
- throw new ActiveMQAMQPInternalErrorException(e.getMessage(), e);
- }
- }
- }
- }
-
- /**
- * TODO: maybe it needs to go?
- *
- * @param consumer
- * @param queueName
- */
- public void disconnect(Object consumer, String queueName) {
- AbstractProtonContextSender protonConsumer = senders.remove(consumer);
- if (protonConsumer != null) {
- try {
- protonConsumer.close(false);
- }
- catch (ActiveMQAMQPException e) {
- protonConsumer.getSender().setTarget(null);
- protonConsumer.getSender().setCondition(new ErrorCondition(e.getAmqpError(), e.getMessage()));
- }
- }
- }
-
- @Override
- public byte[] getTag() {
- return Long.toHexString(currentTag++).getBytes();
- }
-
- @Override
- public void replaceTag(byte[] tag) {
- // TODO: do we need to reuse this?
- }
-
- @Override
- public void close() {
- if (closed) {
- return;
- }
-
- // Making a copy to avoid ConcurrentModificationException during the iteration
- Set<AbstractProtonReceiverContext> receiversCopy = new HashSet<>();
- receiversCopy.addAll(receivers.values());
-
- for (AbstractProtonReceiverContext protonProducer : receiversCopy) {
- try {
- protonProducer.close(false);
- }
- catch (Exception e) {
- log.warn(e.getMessage(), e);
- }
- }
- receivers.clear();
-
- Set<AbstractProtonContextSender> protonSendersClone = new HashSet<>();
- protonSendersClone.addAll(senders.values());
-
- for (AbstractProtonContextSender protonConsumer : protonSendersClone) {
- try {
- protonConsumer.close(false);
- }
- catch (Exception e) {
- log.warn(e.getMessage(), e);
- }
- }
- senders.clear();
- try {
- if (sessionSPI != null) {
- sessionSPI.close();
- }
- }
- catch (Exception e) {
- log.warn(e.getMessage(), e);
- }
- closed = true;
- }
-
- @Override
- public void removeSender(Sender sender) throws ActiveMQAMQPException {
- senders.remove(sender);
- }
-
- @Override
- public void removeReceiver(Receiver receiver) {
- receivers.remove(receiver);
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/ProtonDeliveryHandler.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/ProtonDeliveryHandler.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/ProtonDeliveryHandler.java
deleted file mode 100644
index d861394..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/ProtonDeliveryHandler.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.context;
-
-import org.apache.qpid.proton.amqp.transport.ErrorCondition;
-import org.apache.qpid.proton.engine.Delivery;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-
-/**
- * An interface to handle deliveries, either messages, acks or transaction calls
- */
-public interface ProtonDeliveryHandler {
-
- void onFlow(int currentCredits, boolean drain);
-
- void onMessage(Delivery delivery) throws ActiveMQAMQPException;
-
- /*
- * we have to distinguish between a remote close on the link and a close via a connection or session as the latter mean
- * that a link reattach can happen and we need to keep the underlying resource (queue/subscription) around for pub subs
- * */
- void close(boolean remoteLinkClose) throws ActiveMQAMQPException;
-
- void close(ErrorCondition condition) throws ActiveMQAMQPException;
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/ProtonInitializable.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/ProtonInitializable.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/ProtonInitializable.java
deleted file mode 100644
index 266e8b2..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/ProtonInitializable.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.context;
-
-import java.util.concurrent.TimeUnit;
-
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-import org.proton.plug.exceptions.ActiveMQAMQPIllegalStateException;
-import org.proton.plug.exceptions.ActiveMQAMQPTimeoutException;
-import org.proton.plug.util.FutureRunnable;
-
-public class ProtonInitializable {
-
- private Runnable afterInit;
-
- private boolean initialized = false;
-
- public void afterInit(Runnable afterInit) {
- this.afterInit = afterInit;
- }
-
- public boolean isInitialized() {
- return initialized;
- }
-
- public void initialise() throws Exception {
- if (!initialized) {
- initialized = true;
- try {
- if (afterInit != null) {
- afterInit.run();
- }
- }
- finally {
- afterInit = null;
- }
- }
- }
-
- public void waitWithTimeout(FutureRunnable latch) throws ActiveMQAMQPException {
- try {
- // TODO Configure this
- if (!latch.await(30, TimeUnit.SECONDS)) {
- throw new ActiveMQAMQPTimeoutException("Timed out waiting for response");
- }
- }
- catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new ActiveMQAMQPIllegalStateException(e.getMessage());
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/ProtonPlugSender.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/ProtonPlugSender.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/ProtonPlugSender.java
deleted file mode 100644
index 40232ec..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/ProtonPlugSender.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.context;
-
-import org.apache.qpid.proton.engine.Sender;
-
-public interface ProtonPlugSender {
-
- int deliverMessage(Object message, int deliveryCount) throws Exception;
-
- Sender getSender();
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/ProtonTransactionHandler.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/ProtonTransactionHandler.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/ProtonTransactionHandler.java
deleted file mode 100644
index 263d3e6..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/ProtonTransactionHandler.java
+++ /dev/null
@@ -1,143 +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.proton.plug.context;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.PooledByteBufAllocator;
-import org.apache.qpid.proton.amqp.Binary;
-import org.apache.qpid.proton.amqp.Symbol;
-import org.apache.qpid.proton.amqp.messaging.Accepted;
-import org.apache.qpid.proton.amqp.messaging.AmqpValue;
-import org.apache.qpid.proton.amqp.messaging.Rejected;
-import org.apache.qpid.proton.amqp.transaction.Declare;
-import org.apache.qpid.proton.amqp.transaction.Declared;
-import org.apache.qpid.proton.amqp.transaction.Discharge;
-import org.apache.qpid.proton.amqp.transport.ErrorCondition;
-import org.apache.qpid.proton.engine.Delivery;
-import org.apache.qpid.proton.engine.Receiver;
-import org.apache.qpid.proton.message.impl.MessageImpl;
-import org.jboss.logging.Logger;
-import org.proton.plug.AMQPSessionCallback;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-import org.proton.plug.logger.ActiveMQAMQPProtocolMessageBundle;
-
-import static org.proton.plug.util.DeliveryUtil.decodeMessageImpl;
-import static org.proton.plug.util.DeliveryUtil.readDelivery;
-
-/**
- * handles an amqp Coordinator to deal with transaction boundaries etc
- */
-public class ProtonTransactionHandler implements ProtonDeliveryHandler {
-
- private static final Logger log = Logger.getLogger(ProtonTransactionHandler.class);
-
- final AMQPSessionCallback sessionSPI;
-
- public ProtonTransactionHandler(AMQPSessionCallback sessionSPI) {
- this.sessionSPI = sessionSPI;
- }
-
- @Override
- public void onMessage(Delivery delivery) throws ActiveMQAMQPException {
- ByteBuf buffer = PooledByteBufAllocator.DEFAULT.heapBuffer(1024);
-
- final Receiver receiver;
- try {
- receiver = ((Receiver) delivery.getLink());
-
- if (!delivery.isReadable()) {
- return;
- }
-
- readDelivery(receiver, buffer);
-
- receiver.advance();
-
- MessageImpl msg = decodeMessageImpl(buffer);
-
- Object action = ((AmqpValue) msg.getBody()).getValue();
-
- if (action instanceof Declare) {
- Binary txID = sessionSPI.newTransaction();
- Declared declared = new Declared();
- declared.setTxnId(txID);
- delivery.disposition(declared);
- delivery.settle();
- }
- else if (action instanceof Discharge) {
- Discharge discharge = (Discharge) action;
-
- Binary txID = discharge.getTxnId();
- if (discharge.getFail()) {
- try {
- sessionSPI.rollbackTX(txID, true);
- delivery.disposition(new Accepted());
- }
- catch (Exception e) {
- throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorRollingbackCoordinator(e.getMessage());
- }
- }
- else {
- try {
- sessionSPI.commitTX(txID);
- delivery.disposition(new Accepted());
- }
- catch (ActiveMQAMQPException amqpE) {
- throw amqpE;
- }
- catch (Exception e) {
- throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorCommittingCoordinator(e.getMessage());
- }
- }
- }
- }
- catch (ActiveMQAMQPException amqpE) {
- delivery.disposition(createRejected(amqpE.getAmqpError(), amqpE.getMessage()));
- }
- catch (Exception e) {
- log.warn(e.getMessage(), e);
- delivery.disposition(createRejected(Symbol.getSymbol("failed"), e.getMessage()));
- }
- finally {
- delivery.settle();
- buffer.release();
- }
- }
-
- private Rejected createRejected(Symbol amqpError, String message) {
- Rejected rejected = new Rejected();
- ErrorCondition condition = new ErrorCondition();
- condition.setCondition(amqpError);
- condition.setDescription(message);
- rejected.setError(condition);
- return rejected;
- }
-
- @Override
- public void onFlow(int credits, boolean drain) {
- }
-
- @Override
- public void close(boolean linkRemoteClose) throws ActiveMQAMQPException {
- // no op
- }
-
- @Override
- public void close(ErrorCondition condition) throws ActiveMQAMQPException {
- // no op
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/client/ProtonClientConnectionContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/client/ProtonClientConnectionContext.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/client/ProtonClientConnectionContext.java
deleted file mode 100644
index 49d42f9..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/client/ProtonClientConnectionContext.java
+++ /dev/null
@@ -1,107 +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.proton.plug.context.client;
-
-import org.apache.qpid.proton.engine.Link;
-import org.apache.qpid.proton.engine.Session;
-import org.proton.plug.AMQPClientConnectionContext;
-import org.proton.plug.AMQPClientSessionContext;
-import org.proton.plug.ClientSASL;
-import org.proton.plug.AMQPConnectionCallback;
-import org.proton.plug.AMQPSessionCallback;
-import org.proton.plug.context.AbstractConnectionContext;
-import org.proton.plug.context.AbstractProtonSessionContext;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-import org.proton.plug.context.ProtonInitializable;
-import org.proton.plug.util.FutureRunnable;
-
-import java.util.concurrent.Executor;
-import java.util.concurrent.ScheduledExecutorService;
-
-public class ProtonClientConnectionContext extends AbstractConnectionContext implements AMQPClientConnectionContext {
-
- public ProtonClientConnectionContext(AMQPConnectionCallback connectionCallback, Executor dispatchExecutor, ScheduledExecutorService scheduledPool) {
- super(connectionCallback, dispatchExecutor, scheduledPool);
- }
-
- public ProtonClientConnectionContext(AMQPConnectionCallback connectionCallback,
- String containerId,
- int idleTimeout,
- int maxFrameSize,
- int channelMax,
- Executor dispatchExecutor,
- ScheduledExecutorService scheduledPool) {
- super(connectionCallback, containerId, idleTimeout, maxFrameSize, channelMax, dispatchExecutor, scheduledPool);
- }
-
- // Maybe a client interface?
- @Override
- public void clientOpen(ClientSASL sasl) throws Exception {
- FutureRunnable future = new FutureRunnable(1);
- synchronized (handler.getLock()) {
- this.afterInit(future);
- if (sasl != null) {
- handler.createClientSasl(sasl);
- }
- handler.getConnection().open();
- }
-
- flush();
-
- waitWithTimeout(future);
- }
-
- @Override
- public AMQPClientSessionContext createClientSession() throws ActiveMQAMQPException {
-
- FutureRunnable futureRunnable = new FutureRunnable(1);
- ProtonClientSessionContext sessionImpl;
- synchronized (handler.getLock()) {
- Session session = handler.getConnection().session();
- sessionImpl = (ProtonClientSessionContext) getSessionExtension(session);
- sessionImpl.afterInit(futureRunnable);
- session.open();
- }
-
- flush();
- waitWithTimeout(futureRunnable);
-
- return sessionImpl;
- }
-
- @Override
- public void setContainer(String containerID) {
- handler.getConnection().setContainer(containerID);
- }
-
- @Override
- protected AbstractProtonSessionContext newSessionExtension(Session realSession) throws ActiveMQAMQPException {
- AMQPSessionCallback sessionSPI = connectionCallback.createSessionCallback(this);
- AbstractProtonSessionContext protonSession = new ProtonClientSessionContext(sessionSPI, this, realSession);
-
- return protonSession;
-
- }
-
- @Override
- protected void remoteLinkOpened(Link link) throws Exception {
- Object context = link.getContext();
- if (context != null && context instanceof ProtonInitializable) {
- ((ProtonInitializable) context).initialise();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/client/ProtonClientConnectionContextFactory.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/client/ProtonClientConnectionContextFactory.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/client/ProtonClientConnectionContextFactory.java
deleted file mode 100644
index c0c0716..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/client/ProtonClientConnectionContextFactory.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.context.client;
-
-import org.proton.plug.AMQPConnectionContext;
-import org.proton.plug.AMQPConnectionContextFactory;
-import org.proton.plug.AMQPConnectionCallback;
-
-import java.util.concurrent.Executor;
-import java.util.concurrent.ScheduledExecutorService;
-
-public class ProtonClientConnectionContextFactory extends AMQPConnectionContextFactory {
-
- private static final AMQPConnectionContextFactory theInstance = new ProtonClientConnectionContextFactory();
-
- public static AMQPConnectionContextFactory getFactory() {
- return theInstance;
- }
-
- @Override
- public AMQPConnectionContext createConnection(AMQPConnectionCallback connectionCallback, Executor dispatchExecutor, ScheduledExecutorService scheduledPool) {
- return new ProtonClientConnectionContext(connectionCallback, dispatchExecutor, scheduledPool);
- }
-
-
- @Override
- public AMQPConnectionContext createConnection(AMQPConnectionCallback connectionCallback,
- String containerId,
- int idleTimeout,
- int maxFrameSize,
- int channelMax,
- Executor dispatchExecutor,
- ScheduledExecutorService scheduledPool) {
- return new ProtonClientConnectionContext(connectionCallback, containerId, idleTimeout, maxFrameSize, channelMax, dispatchExecutor, scheduledPool);
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/client/ProtonClientContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/client/ProtonClientContext.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/client/ProtonClientContext.java
deleted file mode 100644
index f442b9e..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/client/ProtonClientContext.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.context.client;
-
-import java.util.concurrent.TimeUnit;
-
-import org.apache.qpid.proton.amqp.messaging.Accepted;
-import org.apache.qpid.proton.amqp.transport.SenderSettleMode;
-import org.apache.qpid.proton.engine.Delivery;
-import org.apache.qpid.proton.engine.Sender;
-import org.apache.qpid.proton.message.ProtonJMessage;
-import org.proton.plug.AMQPClientSenderContext;
-import org.proton.plug.AMQPSessionCallback;
-import org.proton.plug.context.AbstractConnectionContext;
-import org.proton.plug.context.AbstractProtonContextSender;
-import org.proton.plug.context.AbstractProtonSessionContext;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-import org.proton.plug.util.FutureRunnable;
-
-public class ProtonClientContext extends AbstractProtonContextSender implements AMQPClientSenderContext {
-
- FutureRunnable catchUpRunnable = new FutureRunnable();
-
- public ProtonClientContext(AbstractConnectionContext connection,
- Sender sender,
- AbstractProtonSessionContext protonSession,
- AMQPSessionCallback server) {
- super(connection, sender, protonSession, server);
- }
-
- @Override
- public void onMessage(Delivery delivery) throws ActiveMQAMQPException {
- if (delivery.getRemoteState() instanceof Accepted) {
- if (delivery.getContext() instanceof FutureRunnable) {
- ((FutureRunnable) delivery.getContext()).countDown();
- }
- }
- }
-
- @Override
- public void send(ProtonJMessage message) {
- if (sender.getSenderSettleMode() != SenderSettleMode.SETTLED) {
- catchUpRunnable.countUp();
- }
- performSend(message, catchUpRunnable);
- }
-
- public boolean sync(long timeout, TimeUnit unit) {
- try {
- return catchUpRunnable.await(timeout, unit);
- }
- catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- return false;
- }
- }
-
- @Override
- public String getAddress() {
- return sender.getRemoteTarget().getAddress();
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/client/ProtonClientReceiverContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/client/ProtonClientReceiverContext.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/client/ProtonClientReceiverContext.java
deleted file mode 100644
index c06ae58..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/client/ProtonClientReceiverContext.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.context.client;
-
-import java.util.concurrent.LinkedBlockingDeque;
-import java.util.concurrent.TimeUnit;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.PooledByteBufAllocator;
-import org.apache.qpid.proton.amqp.messaging.Accepted;
-import org.apache.qpid.proton.engine.Delivery;
-import org.apache.qpid.proton.engine.Receiver;
-import org.apache.qpid.proton.message.ProtonJMessage;
-import org.apache.qpid.proton.message.impl.MessageImpl;
-import org.proton.plug.AMQPClientReceiverContext;
-import org.proton.plug.AMQPSessionCallback;
-import org.proton.plug.context.AbstractConnectionContext;
-import org.proton.plug.context.AbstractProtonReceiverContext;
-import org.proton.plug.context.AbstractProtonSessionContext;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-
-import static org.proton.plug.util.DeliveryUtil.readDelivery;
-import static org.proton.plug.util.DeliveryUtil.decodeMessageImpl;
-
-public class ProtonClientReceiverContext extends AbstractProtonReceiverContext implements AMQPClientReceiverContext {
-
- public ProtonClientReceiverContext(AMQPSessionCallback sessionSPI,
- AbstractConnectionContext connection,
- AbstractProtonSessionContext protonSession,
- Receiver receiver) {
- super(sessionSPI, connection, protonSession, receiver);
- }
-
- @Override
- public void onFlow(int credits, boolean drain) {
- }
-
- LinkedBlockingDeque<MessageImpl> queues = new LinkedBlockingDeque<>();
-
- /*
- * called when Proton receives a message to be delivered via a Delivery.
- *
- * This may be called more than once per deliver so we have to cache the buffer until we have received it all.
- *
- * */
- @Override
- public void onMessage(Delivery delivery) throws ActiveMQAMQPException {
- ByteBuf buffer = PooledByteBufAllocator.DEFAULT.heapBuffer(1024);
- try {
- synchronized (connection.getLock()) {
- readDelivery(receiver, buffer);
- MessageImpl clientMessage = decodeMessageImpl(buffer);
-
- // This second method could be better
- // clientMessage.decode(buffer.nioBuffer());
-
- receiver.advance();
- delivery.disposition(Accepted.getInstance());
- queues.add(clientMessage);
-
- }
- }
- finally {
- buffer.release();
- }
- }
-
- @Override
- public ProtonJMessage receiveMessage(int time, TimeUnit unit) throws Exception {
- return queues.poll(time, unit);
- }
-
- @Override
- public void flow(int credits) {
- flow(credits, Integer.MAX_VALUE);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/client/ProtonClientSessionContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/client/ProtonClientSessionContext.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/client/ProtonClientSessionContext.java
deleted file mode 100644
index 9079dc3..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/client/ProtonClientSessionContext.java
+++ /dev/null
@@ -1,145 +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.proton.plug.context.client;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
-import org.apache.qpid.proton.amqp.Symbol;
-import org.apache.qpid.proton.amqp.messaging.Accepted;
-import org.apache.qpid.proton.amqp.messaging.DeleteOnClose;
-import org.apache.qpid.proton.amqp.messaging.Rejected;
-import org.apache.qpid.proton.amqp.messaging.Source;
-import org.apache.qpid.proton.amqp.messaging.Target;
-import org.apache.qpid.proton.amqp.messaging.TerminusDurability;
-import org.apache.qpid.proton.amqp.messaging.TerminusExpiryPolicy;
-import org.apache.qpid.proton.amqp.transport.SenderSettleMode;
-import org.apache.qpid.proton.engine.Receiver;
-import org.apache.qpid.proton.engine.Sender;
-import org.apache.qpid.proton.engine.Session;
-import org.proton.plug.AMQPClientReceiverContext;
-import org.proton.plug.AMQPClientSenderContext;
-import org.proton.plug.AMQPClientSessionContext;
-import org.proton.plug.AMQPSessionCallback;
-import org.proton.plug.AmqpSupport;
-import org.proton.plug.context.AbstractConnectionContext;
-import org.proton.plug.context.AbstractProtonSessionContext;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-import org.proton.plug.util.FutureRunnable;
-
-public class ProtonClientSessionContext extends AbstractProtonSessionContext implements AMQPClientSessionContext {
-
- public ProtonClientSessionContext(AMQPSessionCallback sessionSPI,
- AbstractConnectionContext connection,
- Session session) {
- super(sessionSPI, connection, session);
- }
-
- @Override
- public AMQPClientSenderContext createSender(String address, boolean preSettled) throws ActiveMQAMQPException {
- FutureRunnable futureRunnable = new FutureRunnable(1);
-
- ProtonClientContext amqpSender;
- synchronized (connection.getLock()) {
- Sender sender = session.sender(address);
- sender.setSenderSettleMode(SenderSettleMode.SETTLED);
- Target target = new Target();
- target.setAddress(address);
- sender.setTarget(target);
- amqpSender = new ProtonClientContext(connection, sender, this, sessionSPI);
- amqpSender.afterInit(futureRunnable);
- sender.setContext(amqpSender);
- sender.open();
- }
-
- connection.flush();
-
- waitWithTimeout(futureRunnable);
- return amqpSender;
- }
-
- @Override
- public AMQPClientSenderContext createDynamicSender(boolean preSettled) throws ActiveMQAMQPException {
- FutureRunnable futureRunnable = new FutureRunnable(1);
-
- ProtonClientContext amqpSender;
- synchronized (connection.getLock()) {
- final String senderName = "Dynamic-" + UUID.randomUUID().toString();
-
- Sender sender = session.sender(senderName);
- sender.setSenderSettleMode(SenderSettleMode.SETTLED);
-
- Symbol[] outcomes = new Symbol[]{Accepted.DESCRIPTOR_SYMBOL, Rejected.DESCRIPTOR_SYMBOL};
- Source source = new Source();
- source.setAddress(senderName);
- source.setOutcomes(outcomes);
-
- Target target = new Target();
- target.setDynamic(true);
- target.setDurable(TerminusDurability.NONE);
- target.setExpiryPolicy(TerminusExpiryPolicy.LINK_DETACH);
-
- // Set the dynamic node lifetime-policy
- Map<Symbol, Object> dynamicNodeProperties = new HashMap<>();
- dynamicNodeProperties.put(AmqpSupport.LIFETIME_POLICY, DeleteOnClose.getInstance());
- target.setDynamicNodeProperties(dynamicNodeProperties);
-
- amqpSender = new ProtonClientContext(connection, sender, this, sessionSPI);
- amqpSender.afterInit(futureRunnable);
- sender.setSource(source);
- sender.setTarget(target);
- sender.setContext(amqpSender);
- sender.open();
- }
-
- connection.flush();
-
- waitWithTimeout(futureRunnable);
- return amqpSender;
- }
-
- @Override
- public AMQPClientReceiverContext createReceiver(String address) throws ActiveMQAMQPException {
- return createReceiver(address, address);
- }
-
- @Override
- public AMQPClientReceiverContext createReceiver(String name, String address) throws ActiveMQAMQPException {
- FutureRunnable futureRunnable = new FutureRunnable(1);
-
- ProtonClientReceiverContext amqpReceiver;
-
- synchronized (connection.getLock()) {
- Receiver receiver = session.receiver(name);
- Source source = new Source();
- source.setAddress(address);
- receiver.setSource(source);
- amqpReceiver = new ProtonClientReceiverContext(sessionSPI, connection, this, receiver);
- receiver.setContext(amqpReceiver);
- amqpReceiver.afterInit(futureRunnable);
- receiver.open();
- }
-
- connection.flush();
-
- waitWithTimeout(futureRunnable);
-
- return amqpReceiver;
-
- }
-}
[06/15] activemq-artemis git commit: ARTEMIS-751 Simplification of
the AMQP implementation
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerConnectionContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerConnectionContext.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerConnectionContext.java
deleted file mode 100644
index 3386732..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerConnectionContext.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.context.server;
-
-import org.apache.qpid.proton.amqp.Symbol;
-import org.apache.qpid.proton.amqp.transaction.Coordinator;
-import org.apache.qpid.proton.engine.Connection;
-import org.apache.qpid.proton.engine.Link;
-import org.apache.qpid.proton.engine.Receiver;
-import org.apache.qpid.proton.engine.Sender;
-import org.apache.qpid.proton.engine.Session;
-import org.proton.plug.AMQPConnectionCallback;
-import org.proton.plug.AMQPServerConnectionContext;
-import org.proton.plug.AMQPSessionCallback;
-import org.proton.plug.context.AbstractConnectionContext;
-import org.proton.plug.context.AbstractProtonSessionContext;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-import org.proton.plug.handler.ExtCapability;
-
-import java.util.concurrent.Executor;
-import java.util.concurrent.ScheduledExecutorService;
-
-public class ProtonServerConnectionContext extends AbstractConnectionContext implements AMQPServerConnectionContext {
-
- public ProtonServerConnectionContext(AMQPConnectionCallback connectionSP, Executor dispatchExecutor, ScheduledExecutorService scheduledPool) {
- super(connectionSP, dispatchExecutor, scheduledPool);
- }
-
- public ProtonServerConnectionContext(AMQPConnectionCallback connectionSP,
- String containerId,
- int idleTimeout,
- int maxFrameSize,
- int channelMax,
- Executor dispatchExecutor,
- ScheduledExecutorService scheduledPool) {
- super(connectionSP, containerId, idleTimeout, maxFrameSize, channelMax, dispatchExecutor, scheduledPool);
- }
-
- @Override
- protected AbstractProtonSessionContext newSessionExtension(Session realSession) throws ActiveMQAMQPException {
- AMQPSessionCallback sessionSPI = connectionCallback.createSessionCallback(this);
- AbstractProtonSessionContext protonSession = new ProtonServerSessionContext(sessionSPI, this, realSession);
-
- return protonSession;
- }
-
- @Override
- protected boolean validateConnection(Connection connection) {
- return connectionCallback.validateConnection(connection, handler.getSASLResult());
- }
-
- @Override
- protected void remoteLinkOpened(Link link) throws Exception {
-
- ProtonServerSessionContext protonSession = (ProtonServerSessionContext) getSessionExtension(link.getSession());
-
- link.setSource(link.getRemoteSource());
- link.setTarget(link.getRemoteTarget());
- if (link instanceof Receiver) {
- Receiver receiver = (Receiver) link;
- if (link.getRemoteTarget() instanceof Coordinator) {
- Coordinator coordinator = (Coordinator) link.getRemoteTarget();
- protonSession.addTransactionHandler(coordinator, receiver);
- }
- else {
- protonSession.addReceiver(receiver);
- }
- }
- else {
- Sender sender = (Sender) link;
- protonSession.addSender(sender);
- sender.offer(1);
- }
- }
-
- @Override
- public Symbol[] getConnectionCapabilitiesOffered() {
- return ExtCapability.getCapabilities();
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerConnectionContextFactory.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerConnectionContextFactory.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerConnectionContextFactory.java
deleted file mode 100644
index d5ab9ea..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerConnectionContextFactory.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.context.server;
-
-import org.proton.plug.AMQPConnectionContextFactory;
-import org.proton.plug.AMQPConnectionCallback;
-import org.proton.plug.AMQPServerConnectionContext;
-
-import java.util.concurrent.Executor;
-import java.util.concurrent.ScheduledExecutorService;
-
-import static org.proton.plug.context.AMQPConstants.Connection.DEFAULT_IDLE_TIMEOUT;
-import static org.proton.plug.context.AMQPConstants.Connection.DEFAULT_CHANNEL_MAX;
-import static org.proton.plug.context.AMQPConstants.Connection.DEFAULT_MAX_FRAME_SIZE;
-
-public class ProtonServerConnectionContextFactory extends AMQPConnectionContextFactory {
-
- private static final ProtonServerConnectionContextFactory theInstance = new ProtonServerConnectionContextFactory();
-
- public static ProtonServerConnectionContextFactory getFactory() {
- return theInstance;
- }
-
- @Override
- public AMQPServerConnectionContext createConnection(AMQPConnectionCallback connectionCallback, Executor dispatchExecutor, ScheduledExecutorService scheduledPool) {
- return createConnection(connectionCallback, null, DEFAULT_IDLE_TIMEOUT, DEFAULT_MAX_FRAME_SIZE, DEFAULT_CHANNEL_MAX, dispatchExecutor, scheduledPool);
- }
-
- @Override
- public AMQPServerConnectionContext createConnection(AMQPConnectionCallback connectionCallback,
- String containerId,
- int idleTimeout,
- int maxFrameSize,
- int channelMax,
- Executor dispatchExecutor,
- ScheduledExecutorService scheduledPool) {
- return new ProtonServerConnectionContext(connectionCallback, containerId, idleTimeout, maxFrameSize, channelMax, dispatchExecutor, scheduledPool);
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerReceiverContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerReceiverContext.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerReceiverContext.java
deleted file mode 100644
index 173ff28..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerReceiverContext.java
+++ /dev/null
@@ -1,161 +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.proton.plug.context.server;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.PooledByteBufAllocator;
-import org.apache.activemq.artemis.core.transaction.Transaction;
-import org.apache.qpid.proton.amqp.Symbol;
-import org.apache.qpid.proton.amqp.messaging.Rejected;
-import org.apache.qpid.proton.amqp.transaction.TransactionalState;
-import org.apache.qpid.proton.amqp.transport.ErrorCondition;
-import org.apache.qpid.proton.engine.Delivery;
-import org.apache.qpid.proton.engine.Receiver;
-import org.jboss.logging.Logger;
-import org.proton.plug.AMQPSessionCallback;
-import org.proton.plug.context.AbstractConnectionContext;
-import org.proton.plug.context.AbstractProtonReceiverContext;
-import org.proton.plug.context.AbstractProtonSessionContext;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-import org.proton.plug.exceptions.ActiveMQAMQPInternalErrorException;
-import org.proton.plug.exceptions.ActiveMQAMQPNotFoundException;
-import org.proton.plug.logger.ActiveMQAMQPProtocolMessageBundle;
-
-import static org.proton.plug.util.DeliveryUtil.readDelivery;
-
-public class ProtonServerReceiverContext extends AbstractProtonReceiverContext {
-
- private static final Logger log = Logger.getLogger(ProtonServerReceiverContext.class);
-
- /*
- The maximum number of credits we will allocate to clients.
- This number is also used by the broker when refresh client credits.
- */
- private static int maxCreditAllocation = 100;
-
- // Used by the broker to decide when to refresh clients credit. This is not used when client requests credit.
- private static int minCreditRefresh = 30;
-
- public ProtonServerReceiverContext(AMQPSessionCallback sessionSPI,
- AbstractConnectionContext connection,
- AbstractProtonSessionContext protonSession,
- Receiver receiver) {
- super(sessionSPI, connection, protonSession, receiver);
- }
-
- @Override
- public void onFlow(int credits, boolean drain) {
- flow(Math.min(credits, maxCreditAllocation), maxCreditAllocation);
- }
-
- @Override
- public void initialise() throws Exception {
- super.initialise();
- org.apache.qpid.proton.amqp.messaging.Target target = (org.apache.qpid.proton.amqp.messaging.Target) receiver.getRemoteTarget();
-
- if (target != null) {
- if (target.getDynamic()) {
- //if dynamic we have to create the node (queue) and set the address on the target, the node is temporary and
- // will be deleted on closing of the session
- address = sessionSPI.tempQueueName();
-
- try {
- sessionSPI.createTemporaryQueue(address);
- }
- catch (Exception e) {
- throw new ActiveMQAMQPInternalErrorException(e.getMessage(), e);
- }
- target.setAddress(address);
- }
- else {
- //if not dynamic then we use the targets address as the address to forward the messages to, however there has to
- //be a queue bound to it so we nee to check this.
- address = target.getAddress();
- if (address == null) {
- throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.targetAddressNotSet();
- }
-
- try {
- if (!sessionSPI.bindingQuery(address)) {
- throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.addressDoesntExist();
- }
- }
- catch (ActiveMQAMQPNotFoundException e) {
- throw e;
- }
- catch (Exception e) {
- throw new ActiveMQAMQPInternalErrorException(e.getMessage(), e);
- }
- }
- }
- flow(maxCreditAllocation, minCreditRefresh);
- }
-
- /*
- * called when Proton receives a message to be delivered via a Delivery.
- *
- * This may be called more than once per deliver so we have to cache the buffer until we have received it all.
- *
- * */
- @Override
- public void onMessage(Delivery delivery) throws ActiveMQAMQPException {
- Receiver receiver;
- try {
- receiver = ((Receiver) delivery.getLink());
-
- if (!delivery.isReadable()) {
- return;
- }
-
- if (delivery.isPartial()) {
- return;
- }
-
- ByteBuf buffer = PooledByteBufAllocator.DEFAULT.heapBuffer(10 * 1024);
- try {
- synchronized (connection.getLock()) {
- readDelivery(receiver, buffer);
-
- receiver.advance();
-
- Transaction tx = null;
- if (delivery.getRemoteState() instanceof TransactionalState) {
-
- TransactionalState txState = (TransactionalState) delivery.getRemoteState();
- tx = this.sessionSPI.getTransaction(txState.getTxnId());
- }
- sessionSPI.serverSend(tx, receiver, delivery, address, delivery.getMessageFormat(), buffer);
-
- flow(maxCreditAllocation, minCreditRefresh);
- }
- }
- finally {
- buffer.release();
- }
- }
- catch (Exception e) {
- log.warn(e.getMessage(), e);
- Rejected rejected = new Rejected();
- ErrorCondition condition = new ErrorCondition();
- condition.setCondition(Symbol.valueOf("failed"));
- condition.setDescription(e.getMessage());
- rejected.setError(condition);
- delivery.disposition(rejected);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerSenderContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerSenderContext.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerSenderContext.java
deleted file mode 100644
index e9bd123..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerSenderContext.java
+++ /dev/null
@@ -1,452 +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.proton.plug.context.server;
-
-import java.util.Map;
-import java.util.Objects;
-
-import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.server.QueueQueryResult;
-import org.apache.activemq.artemis.core.transaction.Transaction;
-import org.apache.activemq.artemis.jms.client.ActiveMQConnection;
-import org.apache.activemq.artemis.selector.filter.FilterException;
-import org.apache.activemq.artemis.selector.impl.SelectorParser;
-import org.apache.qpid.proton.amqp.DescribedType;
-import org.apache.qpid.proton.amqp.Symbol;
-import org.apache.qpid.proton.amqp.messaging.Accepted;
-import org.apache.qpid.proton.amqp.messaging.Modified;
-import org.apache.qpid.proton.amqp.messaging.Outcome;
-import org.apache.qpid.proton.amqp.messaging.Rejected;
-import org.apache.qpid.proton.amqp.messaging.Released;
-import org.apache.qpid.proton.amqp.messaging.Source;
-import org.apache.qpid.proton.amqp.messaging.TerminusDurability;
-import org.apache.qpid.proton.amqp.messaging.TerminusExpiryPolicy;
-import org.apache.qpid.proton.amqp.transaction.TransactionalState;
-import org.apache.qpid.proton.amqp.transport.AmqpError;
-import org.apache.qpid.proton.amqp.transport.DeliveryState;
-import org.apache.qpid.proton.amqp.transport.ErrorCondition;
-import org.apache.qpid.proton.amqp.transport.SenderSettleMode;
-import org.apache.qpid.proton.engine.Delivery;
-import org.apache.qpid.proton.engine.Sender;
-import org.apache.qpid.proton.message.ProtonJMessage;
-import org.jboss.logging.Logger;
-import org.proton.plug.AMQPSessionCallback;
-import org.proton.plug.AmqpSupport;
-import org.proton.plug.context.AbstractConnectionContext;
-import org.proton.plug.context.AbstractProtonContextSender;
-import org.proton.plug.context.AbstractProtonSessionContext;
-import org.proton.plug.context.ProtonPlugSender;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-import org.proton.plug.exceptions.ActiveMQAMQPIllegalStateException;
-import org.proton.plug.exceptions.ActiveMQAMQPInternalErrorException;
-import org.proton.plug.exceptions.ActiveMQAMQPNotFoundException;
-import org.proton.plug.logger.ActiveMQAMQPProtocolMessageBundle;
-
-import static org.proton.plug.AmqpSupport.JMS_SELECTOR_FILTER_IDS;
-import static org.proton.plug.AmqpSupport.findFilter;
-
-public class ProtonServerSenderContext extends AbstractProtonContextSender implements ProtonPlugSender {
-
- private static final Logger log = Logger.getLogger(ProtonServerSenderContext.class);
-
- private static final Symbol SELECTOR = Symbol.getSymbol("jms-selector");
- private static final Symbol COPY = Symbol.valueOf("copy");
- private static final Symbol TOPIC = Symbol.valueOf("topic");
-
- private Object brokerConsumer;
-
- public ProtonServerSenderContext(AbstractConnectionContext connection,
- Sender sender,
- AbstractProtonSessionContext protonSession,
- AMQPSessionCallback server) {
- super(connection, sender, protonSession, server);
- }
-
- public Object getBrokerConsumer() {
- return brokerConsumer;
- }
-
- @Override
- public void onFlow(int currentCredits, boolean drain) {
- super.onFlow(currentCredits, drain);
- sessionSPI.onFlowConsumer(brokerConsumer, currentCredits, drain);
- }
-
- /*
-* start the session
-* */
- @Override
- public void start() throws ActiveMQAMQPException {
- super.start();
- // protonSession.getServerSession().start();
-
- //todo add flow control
- try {
- // to do whatever you need to make the broker start sending messages to the consumer
- //this could be null if a link reattach has happened
- if (brokerConsumer != null) {
- sessionSPI.startSender(brokerConsumer);
- }
- //protonSession.getServerSession().receiveConsumerCredits(consumerID, -1);
- }
- catch (Exception e) {
- throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorStartingConsumer(e.getMessage());
- }
- }
-
- /**
- * create the actual underlying ActiveMQ Artemis Server Consumer
- */
- @Override
- public void initialise() throws Exception {
- super.initialise();
-
- Source source = (Source) sender.getRemoteSource();
-
- String queue;
-
- String selector = null;
-
- /*
- * even tho the filter is a map it will only return a single filter unless a nolocal is also provided
- * */
- if (source != null) {
- Map.Entry<Symbol, DescribedType> filter = findFilter(source.getFilter(), JMS_SELECTOR_FILTER_IDS);
- if (filter != null) {
- selector = filter.getValue().getDescribed().toString();
- // Validate the Selector.
- try {
- SelectorParser.parse(selector);
- }
- catch (FilterException e) {
- close(new ErrorCondition(AmqpError.INVALID_FIELD, e.getMessage()));
- return;
- }
- }
- }
-
- /*
- * if we have a capability for a topic (qpid-jms) or we are configured on this address to act like a topic then act
- * like a subscription.
- * */
- boolean isPubSub = hasCapabilities(TOPIC, source) || isPubSub(source);
-
- if (isPubSub) {
- if (findFilter(source.getFilter(), AmqpSupport.NO_LOCAL_FILTER_IDS) != null) {
- String remoteContainerId = sender.getSession().getConnection().getRemoteContainer();
- String noLocalFilter = ActiveMQConnection.CONNECTION_ID_PROPERTY_NAME.toString() + "<>'" + remoteContainerId + "'";
- if (selector != null) {
- selector += " AND " + noLocalFilter;
- }
- else {
- selector = noLocalFilter;
- }
- }
- }
-
- if (source == null) {
- // Attempt to recover a previous subscription happens when a link reattach happens on a subscription queue
- String clientId = connection.getRemoteContainer();
- String pubId = sender.getName();
- queue = clientId + ":" + pubId;
- boolean exists = sessionSPI.queueQuery(queue, false).isExists();
-
- /*
- * If it exists then we know it is a subscription so we set the capabilities on the source so we can delete on a
- * link remote close.
- * */
- if (exists) {
- source = new org.apache.qpid.proton.amqp.messaging.Source();
- source.setAddress(queue);
- source.setDurable(TerminusDurability.UNSETTLED_STATE);
- source.setExpiryPolicy(TerminusExpiryPolicy.NEVER);
- source.setDistributionMode(COPY);
- source.setCapabilities(TOPIC);
- sender.setSource(source);
- }
- else {
- throw new ActiveMQAMQPNotFoundException("Unknown subscription link: " + sender.getName());
- }
- }
- else {
- if (source.getDynamic()) {
- //if dynamic we have to create the node (queue) and set the address on the target, the node is temporary and
- // will be deleted on closing of the session
- queue = java.util.UUID.randomUUID().toString();
- try {
- sessionSPI.createTemporaryQueue(queue);
- //protonSession.getServerSession().createQueue(queue, queue, null, true, false);
- }
- catch (Exception e) {
- throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorCreatingTemporaryQueue(e.getMessage());
- }
- source.setAddress(queue);
- }
- else {
- //if not dynamic then we use the targets address as the address to forward the messages to, however there has to
- //be a queue bound to it so we nee to check this.
- if (isPubSub) {
- // if we are a subscription and durable create a durable queue using the container id and link name
- if (TerminusDurability.UNSETTLED_STATE.equals(source.getDurable()) ||
- TerminusDurability.CONFIGURATION.equals(source.getDurable())) {
- String clientId = connection.getRemoteContainer();
- String pubId = sender.getName();
- queue = clientId + ":" + pubId;
- QueueQueryResult result = sessionSPI.queueQuery(queue, false);
-
- if (result.isExists()) {
- // If a client reattaches to a durable subscription with a different no-local filter value, selector
- // or address then we must recreate the queue (JMS semantics).
-
- if (!Objects.equals(result.getFilterString(), SimpleString.toSimpleString(selector)) ||
- (sender.getSource() != null && !sender.getSource().getAddress().equals(result.getAddress().toString()))) {
- if (result.getConsumerCount() == 0) {
- sessionSPI.deleteQueue(queue);
- sessionSPI.createDurableQueue(source.getAddress(), queue, selector);
- }
- else {
- throw new ActiveMQAMQPIllegalStateException("Unable to recreate subscription, consumers already exist");
- }
- }
- }
- else {
- sessionSPI.createDurableQueue(source.getAddress(), queue, selector);
- }
- source.setAddress(queue);
- }
- //otherwise we are a volatile subscription
- else {
- queue = java.util.UUID.randomUUID().toString();
- try {
- sessionSPI.createTemporaryQueue(source.getAddress(), queue, selector);
- }
- catch (Exception e) {
- throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorCreatingTemporaryQueue(e.getMessage());
- }
- source.setAddress(queue);
- }
- }
- else {
- queue = source.getAddress();
- }
- if (queue == null) {
- throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.sourceAddressNotSet();
- }
-
- try {
- if (!sessionSPI.queueQuery(queue, !isPubSub).isExists()) {
- throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.sourceAddressDoesntExist();
- }
- }
- catch (ActiveMQAMQPNotFoundException e) {
- throw e;
- }
- catch (Exception e) {
- throw new ActiveMQAMQPInternalErrorException(e.getMessage(), e);
- }
- }
-
- boolean browseOnly = !isPubSub && source.getDistributionMode() != null && source.getDistributionMode().equals(COPY);
- try {
- brokerConsumer = sessionSPI.createSender(this, queue, isPubSub ? null : selector, browseOnly);
- }
- catch (Exception e) {
- throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorCreatingConsumer(e.getMessage());
- }
- }
- }
-
- private boolean isPubSub(Source source) {
- String pubSubPrefix = sessionSPI.getPubSubPrefix();
- return source != null && pubSubPrefix != null && source.getAddress() != null && source.getAddress().startsWith(pubSubPrefix);
- }
-
- /*
- * close the session
- * */
- @Override
- public void close(ErrorCondition condition) throws ActiveMQAMQPException {
- super.close(condition);
- try {
- sessionSPI.closeSender(brokerConsumer);
- }
- catch (Exception e) {
- log.warn(e.getMessage(), e);
- throw new ActiveMQAMQPInternalErrorException(e.getMessage());
- }
- }
-
- /*
- * close the session
- * */
- @Override
- public void close(boolean remoteLinkClose) throws ActiveMQAMQPException {
- super.close(remoteLinkClose);
- try {
- sessionSPI.closeSender(brokerConsumer);
- //if this is a link close rather than a connection close or detach, we need to delete any durable resources for
- // say pub subs
- if (remoteLinkClose) {
- Source source = (Source) sender.getSource();
- if (source != null && source.getAddress() != null && hasCapabilities(TOPIC, source)) {
- String queueName = source.getAddress();
- QueueQueryResult result = sessionSPI.queueQuery(queueName, false);
- if (result.isExists() && source.getDynamic()) {
- sessionSPI.deleteQueue(queueName);
- }
- else {
- String clientId = connection.getRemoteContainer();
- String pubId = sender.getName();
- String queue = clientId + ":" + pubId;
- result = sessionSPI.queueQuery(queue, false);
- if (result.isExists()) {
- if (result.getConsumerCount() > 0) {
- System.out.println("error");
- }
- sessionSPI.deleteQueue(queue);
- }
- }
- }
- }
- }
- catch (Exception e) {
- log.warn(e.getMessage(), e);
- throw new ActiveMQAMQPInternalErrorException(e.getMessage());
- }
- }
-
- @Override
- public void onMessage(Delivery delivery) throws ActiveMQAMQPException {
- Object message = delivery.getContext();
-
- boolean preSettle = sender.getRemoteSenderSettleMode() == SenderSettleMode.SETTLED;
-
- DeliveryState remoteState = delivery.getRemoteState();
-
- if (remoteState != null) {
- // If we are transactional then we need ack if the msg has been accepted
- if (remoteState instanceof TransactionalState) {
-
- TransactionalState txState = (TransactionalState) remoteState;
- Transaction tx = this.sessionSPI.getTransaction(txState.getTxnId());
- if (txState.getOutcome() != null) {
- Outcome outcome = txState.getOutcome();
- if (outcome instanceof Accepted) {
- if (!delivery.remotelySettled()) {
- TransactionalState txAccepted = new TransactionalState();
- txAccepted.setOutcome(Accepted.getInstance());
- txAccepted.setTxnId(txState.getTxnId());
-
- delivery.disposition(txAccepted);
- }
- //we have to individual ack as we can't guarantee we will get the delivery updates (including acks) in order
- // from dealer, a perf hit but a must
- try {
- sessionSPI.ack(tx, brokerConsumer, message);
- }
- catch (Exception e) {
- throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorAcknowledgingMessage(message.toString(), e.getMessage());
- }
- }
- }
- }
- else if (remoteState instanceof Accepted) {
- //we have to individual ack as we can't guarantee we will get the delivery updates (including acks) in order
- // from dealer, a perf hit but a must
- try {
- sessionSPI.ack(null, brokerConsumer, message);
- }
- catch (Exception e) {
- throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorAcknowledgingMessage(message.toString(), e.getMessage());
- }
- }
- else if (remoteState instanceof Released) {
- try {
- sessionSPI.cancel(brokerConsumer, message, false);
- }
- catch (Exception e) {
- throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorCancellingMessage(message.toString(), e.getMessage());
- }
- }
- else if (remoteState instanceof Rejected || remoteState instanceof Modified) {
- try {
- sessionSPI.cancel(brokerConsumer, message, true);
- }
- catch (Exception e) {
- throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorCancellingMessage(message.toString(), e.getMessage());
- }
- }
- //todo add tag caching
- if (!preSettle) {
- protonSession.replaceTag(delivery.getTag());
- }
-
- synchronized (connection.getLock()) {
- delivery.settle();
- sender.offer(1);
- }
-
- }
- else {
- //todo not sure if we need to do anything here
- }
- }
-
- @Override
- public synchronized void checkState() {
- super.checkState();
- sessionSPI.resumeDelivery(brokerConsumer);
- }
-
- /**
- * handle an out going message from ActiveMQ Artemis, send via the Proton Sender
- */
- @Override
- public int deliverMessage(Object message, int deliveryCount) throws Exception {
- if (closed) {
- System.err.println("Message can't be delivered as it's closed");
- return 0;
- }
-
- //encode the message
- ProtonJMessage serverMessage;
- try {
- // This can be done a lot better here
- serverMessage = sessionSPI.encodeMessage(message, deliveryCount);
- }
- catch (Throwable e) {
- log.warn(e.getMessage(), e);
- throw new ActiveMQAMQPInternalErrorException(e.getMessage(), e);
- }
-
- return performSend(serverMessage, message);
- }
-
- private static boolean hasCapabilities(Symbol symbol, Source source) {
- if (source != null) {
- if (source.getCapabilities() != null) {
- for (Symbol cap : source.getCapabilities()) {
- if (symbol.equals(cap)) {
- return true;
- }
- }
- }
- }
- return false;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerSessionContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerSessionContext.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerSessionContext.java
deleted file mode 100644
index 983fa4e..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/context/server/ProtonServerSessionContext.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.context.server;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.qpid.proton.amqp.Symbol;
-import org.apache.qpid.proton.amqp.transaction.Coordinator;
-import org.apache.qpid.proton.amqp.transport.ErrorCondition;
-import org.apache.qpid.proton.engine.Receiver;
-import org.apache.qpid.proton.engine.Sender;
-import org.apache.qpid.proton.engine.Session;
-import org.proton.plug.AMQPSessionCallback;
-import org.proton.plug.context.AbstractConnectionContext;
-import org.proton.plug.context.AbstractProtonContextSender;
-import org.proton.plug.context.AbstractProtonReceiverContext;
-import org.proton.plug.context.AbstractProtonSessionContext;
-import org.proton.plug.context.ProtonTransactionHandler;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-
-public class ProtonServerSessionContext extends AbstractProtonSessionContext {
-
- public ProtonServerSessionContext(AMQPSessionCallback sessionSPI,
- AbstractConnectionContext connection,
- Session session) {
- super(sessionSPI, connection, session);
- }
-
- protected Map<Object, AbstractProtonContextSender> serverSenders = new HashMap<>();
-
- /**
- * The consumer object from the broker or the key used to store the sender
- *
- * @param message
- * @param consumer
- * @param deliveryCount
- * @return the number of bytes sent
- */
- public int serverDelivery(Object message, Object consumer, int deliveryCount) throws Exception {
- ProtonServerSenderContext protonSender = (ProtonServerSenderContext) serverSenders.get(consumer);
- if (protonSender != null) {
- return protonSender.deliverMessage(message, deliveryCount);
- }
- return 0;
- }
-
- public void addTransactionHandler(Coordinator coordinator, Receiver receiver) {
- ProtonTransactionHandler transactionHandler = new ProtonTransactionHandler(sessionSPI);
-
- coordinator.setCapabilities(Symbol.getSymbol("amqp:local-transactions"),
- Symbol.getSymbol("amqp:multi-txns-per-ssn"),
- Symbol.getSymbol("amqp:multi-ssns-per-txn"));
-
- receiver.setContext(transactionHandler);
- receiver.open();
- receiver.flow(100);
- }
-
- public void addSender(Sender sender) throws Exception {
- ProtonServerSenderContext protonSender = new ProtonServerSenderContext(connection, sender, this, sessionSPI);
-
- try {
- protonSender.initialise();
- senders.put(sender, protonSender);
- serverSenders.put(protonSender.getBrokerConsumer(), protonSender);
- sender.setContext(protonSender);
- sender.open();
- protonSender.start();
- }
- catch (ActiveMQAMQPException e) {
- senders.remove(sender);
- sender.setSource(null);
- sender.setCondition(new ErrorCondition(e.getAmqpError(), e.getMessage()));
- sender.close();
- }
- }
-
- @Override
- public void removeSender(Sender sender) throws ActiveMQAMQPException {
- ProtonServerSenderContext senderRemoved = (ProtonServerSenderContext) senders.remove(sender);
- if (senderRemoved != null) {
- serverSenders.remove(senderRemoved.getBrokerConsumer());
- }
- }
-
- public void addReceiver(Receiver receiver) throws Exception {
- try {
- AbstractProtonReceiverContext protonReceiver = new ProtonServerReceiverContext(sessionSPI, connection, this, receiver);
- protonReceiver.initialise();
- receivers.put(receiver, protonReceiver);
- receiver.setContext(protonReceiver);
- receiver.open();
- }
- catch (ActiveMQAMQPException e) {
- receivers.remove(receiver);
- receiver.setTarget(null);
- receiver.setCondition(new ErrorCondition(e.getAmqpError(), e.getMessage()));
- receiver.close();
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPException.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPException.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPException.java
deleted file mode 100644
index 4838d55..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPException.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.exceptions;
-
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
-import org.apache.qpid.proton.amqp.Symbol;
-
-public class ActiveMQAMQPException extends ActiveMQException {
-
- private static final String ERROR_PREFIX = "amqp:";
-
- public Symbol getAmqpError() {
- return amqpError;
- }
-
- private final Symbol amqpError;
-
- public ActiveMQAMQPException(Symbol amqpError, String message, Throwable e, ActiveMQExceptionType t) {
- super(message, e, t);
- this.amqpError = amqpError;
- }
-
- public ActiveMQAMQPException(Symbol amqpError, String message, ActiveMQExceptionType t) {
- super(message, t);
- this.amqpError = amqpError;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPIllegalStateException.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPIllegalStateException.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPIllegalStateException.java
deleted file mode 100644
index 7818ef9..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPIllegalStateException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.exceptions;
-
-import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
-import org.apache.qpid.proton.amqp.transport.AmqpError;
-
-public class ActiveMQAMQPIllegalStateException extends ActiveMQAMQPException {
-
- public ActiveMQAMQPIllegalStateException(String message) {
- super(AmqpError.ILLEGAL_STATE, message, ActiveMQExceptionType.ILLEGAL_STATE);
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPInternalErrorException.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPInternalErrorException.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPInternalErrorException.java
deleted file mode 100644
index 2c0b0ae..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPInternalErrorException.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.exceptions;
-
-import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
-import org.apache.qpid.proton.amqp.transport.AmqpError;
-
-public class ActiveMQAMQPInternalErrorException extends ActiveMQAMQPException {
-
- public ActiveMQAMQPInternalErrorException(String message, Throwable e) {
- super(AmqpError.INTERNAL_ERROR, message, e, ActiveMQExceptionType.INTERNAL_ERROR);
- }
-
- public ActiveMQAMQPInternalErrorException(String message) {
- super(AmqpError.INTERNAL_ERROR, message, ActiveMQExceptionType.INTERNAL_ERROR);
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPInvalidFieldException.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPInvalidFieldException.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPInvalidFieldException.java
deleted file mode 100644
index f5dd168..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPInvalidFieldException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.exceptions;
-
-import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
-import org.apache.qpid.proton.amqp.transport.AmqpError;
-
-public class ActiveMQAMQPInvalidFieldException extends ActiveMQAMQPException {
-
- public ActiveMQAMQPInvalidFieldException(String message) {
- super(AmqpError.INVALID_FIELD, message, ActiveMQExceptionType.ILLEGAL_STATE);
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPNotFoundException.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPNotFoundException.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPNotFoundException.java
deleted file mode 100644
index 02cc15c..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPNotFoundException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.exceptions;
-
-import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
-import org.apache.qpid.proton.amqp.transport.AmqpError;
-
-public class ActiveMQAMQPNotFoundException extends ActiveMQAMQPException {
-
- public ActiveMQAMQPNotFoundException(String message) {
- super(AmqpError.NOT_FOUND, message, ActiveMQExceptionType.QUEUE_DOES_NOT_EXIST);
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPNotImplementedException.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPNotImplementedException.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPNotImplementedException.java
deleted file mode 100644
index 861e236..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPNotImplementedException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.exceptions;
-
-import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
-import org.apache.qpid.proton.amqp.transport.AmqpError;
-
-public class ActiveMQAMQPNotImplementedException extends ActiveMQAMQPException {
-
- public ActiveMQAMQPNotImplementedException(String message) {
- super(AmqpError.NOT_IMPLEMENTED, message, ActiveMQExceptionType.NOT_IMPLEMTNED_EXCEPTION);
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPResourceLimitExceededException.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPResourceLimitExceededException.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPResourceLimitExceededException.java
deleted file mode 100644
index 2c64a8d..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPResourceLimitExceededException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.exceptions;
-
-import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
-import org.apache.qpid.proton.amqp.transport.AmqpError;
-
-public class ActiveMQAMQPResourceLimitExceededException extends ActiveMQAMQPException {
-
- public ActiveMQAMQPResourceLimitExceededException(String message) {
- super(AmqpError.RESOURCE_LIMIT_EXCEEDED, message, ActiveMQExceptionType.ADDRESS_FULL);
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPTimeoutException.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPTimeoutException.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPTimeoutException.java
deleted file mode 100644
index c86c25d..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/exceptions/ActiveMQAMQPTimeoutException.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.exceptions;
-
-import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
-import org.apache.qpid.proton.amqp.transport.AmqpError;
-
-public class ActiveMQAMQPTimeoutException extends ActiveMQAMQPException {
-
- public ActiveMQAMQPTimeoutException(String message) {
- super(AmqpError.ILLEGAL_STATE, message, ActiveMQExceptionType.CONNECTION_TIMEDOUT);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/EventHandler.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/EventHandler.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/EventHandler.java
deleted file mode 100644
index c020cbb..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/EventHandler.java
+++ /dev/null
@@ -1,78 +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.proton.plug.handler;
-
-import org.apache.qpid.proton.engine.Connection;
-import org.apache.qpid.proton.engine.Delivery;
-import org.apache.qpid.proton.engine.Link;
-import org.apache.qpid.proton.engine.Session;
-import org.apache.qpid.proton.engine.Transport;
-
-/**
- * EventHandler
- */
-public interface EventHandler {
-
- void onAuthInit(ProtonHandler handler, Connection connection, boolean sasl);
-
- void onInit(Connection connection) throws Exception;
-
- void onLocalOpen(Connection connection) throws Exception;
-
- void onRemoteOpen(Connection connection) throws Exception;
-
- void onLocalClose(Connection connection) throws Exception;
-
- void onRemoteClose(Connection connection) throws Exception;
-
- void onFinal(Connection connection) throws Exception;
-
- void onInit(Session session) throws Exception;
-
- void onLocalOpen(Session session) throws Exception;
-
- void onRemoteOpen(Session session) throws Exception;
-
- void onLocalClose(Session session) throws Exception;
-
- void onRemoteClose(Session session) throws Exception;
-
- void onFinal(Session session) throws Exception;
-
- void onInit(Link link) throws Exception;
-
- void onLocalOpen(Link link) throws Exception;
-
- void onRemoteOpen(Link link) throws Exception;
-
- void onLocalClose(Link link) throws Exception;
-
- void onRemoteClose(Link link) throws Exception;
-
- void onFlow(Link link) throws Exception;
-
- void onFinal(Link link) throws Exception;
-
- void onRemoteDetach(Link link) throws Exception;
-
- void onDetach(Link link) throws Exception;
-
- void onDelivery(Delivery delivery) throws Exception;
-
- void onTransport(Transport transport) throws Exception;
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/Events.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/Events.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/Events.java
deleted file mode 100644
index 2f978c7..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/Events.java
+++ /dev/null
@@ -1,105 +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.proton.plug.handler;
-
-import org.apache.qpid.proton.engine.Event;
-import org.apache.qpid.proton.engine.Transport;
-
-/**
- * TODO : this needs a better home
- */
-public final class Events {
-
- public static void dispatchTransport(Transport transport, EventHandler handler) throws Exception {
- handler.onTransport(transport);
- }
-
- public static void dispatch(Event event, EventHandler handler) throws Exception {
- switch (event.getType()) {
- case CONNECTION_INIT:
- handler.onInit(event.getConnection());
- break;
- case CONNECTION_LOCAL_OPEN:
- handler.onLocalOpen(event.getConnection());
- break;
- case CONNECTION_REMOTE_OPEN:
- handler.onRemoteOpen(event.getConnection());
- break;
- case CONNECTION_LOCAL_CLOSE:
- handler.onLocalClose(event.getConnection());
- break;
- case CONNECTION_REMOTE_CLOSE:
- handler.onRemoteClose(event.getConnection());
- break;
- case CONNECTION_FINAL:
- handler.onFinal(event.getConnection());
- break;
- case SESSION_INIT:
- handler.onInit(event.getSession());
- break;
- case SESSION_LOCAL_OPEN:
- handler.onLocalOpen(event.getSession());
- break;
- case SESSION_REMOTE_OPEN:
- handler.onRemoteOpen(event.getSession());
- break;
- case SESSION_LOCAL_CLOSE:
- handler.onLocalClose(event.getSession());
- break;
- case SESSION_REMOTE_CLOSE:
- handler.onRemoteClose(event.getSession());
- break;
- case SESSION_FINAL:
- handler.onFinal(event.getSession());
- break;
- case LINK_INIT:
- handler.onInit(event.getLink());
- break;
- case LINK_LOCAL_OPEN:
- handler.onLocalOpen(event.getLink());
- break;
- case LINK_REMOTE_OPEN:
- handler.onRemoteOpen(event.getLink());
- break;
- case LINK_LOCAL_CLOSE:
- handler.onLocalClose(event.getLink());
- break;
- case LINK_REMOTE_CLOSE:
- handler.onRemoteClose(event.getLink());
- break;
- case LINK_FLOW:
- handler.onFlow(event.getLink());
- break;
- case LINK_FINAL:
- handler.onFinal(event.getLink());
- break;
- case LINK_LOCAL_DETACH:
- handler.onDetach(event.getLink());
- break;
- case LINK_REMOTE_DETACH:
- handler.onRemoteDetach(event.getLink());
- break;
- case TRANSPORT:
- handler.onTransport(event.getTransport());
- break;
- case DELIVERY:
- handler.onDelivery(event.getDelivery());
- break;
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/ExtCapability.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/ExtCapability.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/ExtCapability.java
deleted file mode 100644
index cbb96fd..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/ExtCapability.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.handler;
-
-import org.apache.qpid.proton.amqp.Symbol;
-import org.apache.qpid.proton.engine.Connection;
-
-import static org.proton.plug.AmqpSupport.DELAYED_DELIVERY;
-import static org.proton.plug.AmqpSupport.SOLE_CONNECTION_CAPABILITY;
-
-public class ExtCapability {
-
- public static final Symbol[] capabilities = new Symbol[] {
- SOLE_CONNECTION_CAPABILITY, DELAYED_DELIVERY
- };
-
- public static Symbol[] getCapabilities() {
- return capabilities;
- }
-
- public static boolean needUniqueConnection(Connection connection) {
- Symbol[] extCapabilities = connection.getRemoteDesiredCapabilities();
- if (extCapabilities != null) {
- for (Symbol sym : extCapabilities) {
- if (sym.compareTo(SOLE_CONNECTION_CAPABILITY) == 0) {
- return true;
- }
- }
- }
- return false;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/ProtonHandler.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/ProtonHandler.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/ProtonHandler.java
deleted file mode 100644
index d02546b..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/ProtonHandler.java
+++ /dev/null
@@ -1,133 +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.proton.plug.handler;
-
-import java.util.concurrent.Executor;
-
-import io.netty.buffer.ByteBuf;
-import org.apache.qpid.proton.engine.Connection;
-import org.apache.qpid.proton.engine.Transport;
-import org.proton.plug.ClientSASL;
-import org.proton.plug.ServerSASL;
-import org.proton.plug.SASLResult;
-import org.proton.plug.handler.impl.ProtonHandlerImpl;
-
-/**
- * This is a definition of the public interface for {@link org.proton.plug.handler.impl.ProtonHandlerImpl}
- */
-public interface ProtonHandler {
-
- long tick(boolean firstTick);
-
- final class Factory {
- public static ProtonHandler create(Executor dispatchExecutor) {
- return new ProtonHandlerImpl(dispatchExecutor);
- }
- }
-
- /**
- * It returns true if the transport connection has any capacity available
- *
- * @return
- */
- int capacity();
-
- Transport getTransport();
-
- Connection getConnection();
-
- /**
- * Add an event handler to the chain
- *
- * @param handler
- * @return
- */
- ProtonHandler addEventHandler(EventHandler handler);
-
- void createClientSasl(ClientSASL clientSASL);
-
- /**
- * To be used on server connections. To define SASL integration.
- *
- * @param handlers
- */
- void createServerSASL(ServerSASL[] handlers);
-
- /**
- * To return the SASL Mechanism that was successful with the connection.
- * This should contain any state such as user and password
- *
- * @return
- */
- SASLResult getSASLResult();
-
- /**
- * The input on the Handler.
- * Notice that buffer will be positioned up to where we needed
- *
- * @param buffer
- */
- void inputBuffer(ByteBuf buffer);
-
- /**
- * To be used at your discretion to verify if the client was active since you last checked
- * it can be used to implement server TTL cleanup and verifications
- *
- * @return
- */
- boolean checkDataReceived();
-
- /**
- * Return the creation time of the handler
- *
- * @return
- */
- long getCreationTime();
-
- /**
- * To be called after you used the outputBuffer
- *
- * @param bytes number of bytes you used already on the output
- */
- void outputDone(int bytes);
-
- /**
- * it will return pending bytes you have on the Transport
- * after you are done with it you must call {@link #outputDone(int)}
- *
- * @return
- */
- ByteBuf outputBuffer();
-
- /**
- * It will process the transport and cause events to be called
- */
- void flush();
-
- /**
- * It will close the connection and flush events
- */
- void close();
-
- /**
- * Get the object used to lock transport, connection and events operations
- *
- * @return
- */
- Object getLock();
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/impl/DefaultEventHandler.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/impl/DefaultEventHandler.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/impl/DefaultEventHandler.java
deleted file mode 100644
index 45d5b67..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/impl/DefaultEventHandler.java
+++ /dev/null
@@ -1,144 +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.proton.plug.handler.impl;
-
-import org.apache.qpid.proton.engine.Connection;
-import org.apache.qpid.proton.engine.Delivery;
-import org.apache.qpid.proton.engine.Link;
-import org.apache.qpid.proton.engine.Session;
-import org.apache.qpid.proton.engine.Transport;
-import org.proton.plug.handler.EventHandler;
-
-/**
- * This is useful for cases where you only want to implement a few methods
- */
-public abstract class DefaultEventHandler implements EventHandler {
-
- @Override
- public void onInit(Connection connection) throws Exception {
-
- }
-
- @Override
- public void onLocalOpen(Connection connection) throws Exception {
-
- }
-
- @Override
- public void onRemoteOpen(Connection connection) throws Exception {
-
- }
-
- @Override
- public void onLocalClose(Connection connection) throws Exception {
-
- }
-
- @Override
- public void onRemoteClose(Connection connection) throws Exception {
- }
-
- @Override
- public void onFinal(Connection connection) throws Exception {
-
- }
-
- @Override
- public void onInit(Session session) throws Exception {
-
- }
-
- @Override
- public void onLocalOpen(Session session) throws Exception {
-
- }
-
- @Override
- public void onRemoteOpen(Session session) throws Exception {
-
- }
-
- @Override
- public void onLocalClose(Session session) throws Exception {
-
- }
-
- @Override
- public void onRemoteClose(Session session) throws Exception {
-
- }
-
- @Override
- public void onFinal(Session session) throws Exception {
-
- }
-
- @Override
- public void onInit(Link link) throws Exception {
-
- }
-
- @Override
- public void onLocalOpen(Link link) throws Exception {
-
- }
-
- @Override
- public void onRemoteOpen(Link link) throws Exception {
-
- }
-
- @Override
- public void onLocalClose(Link link) throws Exception {
-
- }
-
- @Override
- public void onRemoteClose(Link link) throws Exception {
-
- }
-
- @Override
- public void onFlow(Link link) throws Exception {
-
- }
-
- @Override
- public void onFinal(Link link) throws Exception {
-
- }
-
- @Override
- public void onRemoteDetach(Link link) throws Exception {
-
- }
-
- @Override
- public void onDetach(Link link) throws Exception {
-
- }
-
- @Override
- public void onDelivery(Delivery delivery) throws Exception {
-
- }
-
- @Override
- public void onTransport(Transport transport) throws Exception {
-
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/impl/ProtonHandlerImpl.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/impl/ProtonHandlerImpl.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/impl/ProtonHandlerImpl.java
deleted file mode 100644
index b2f6406..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/handler/impl/ProtonHandlerImpl.java
+++ /dev/null
@@ -1,389 +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.proton.plug.handler.impl;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.PooledByteBufAllocator;
-import org.apache.qpid.proton.Proton;
-import org.apache.qpid.proton.amqp.transport.ErrorCondition;
-import org.apache.qpid.proton.engine.Collector;
-import org.apache.qpid.proton.engine.Connection;
-import org.apache.qpid.proton.engine.EndpointState;
-import org.apache.qpid.proton.engine.Event;
-import org.apache.qpid.proton.engine.Sasl;
-import org.apache.qpid.proton.engine.Transport;
-import org.jboss.logging.Logger;
-import org.proton.plug.ClientSASL;
-import org.proton.plug.ServerSASL;
-import org.proton.plug.handler.EventHandler;
-import org.proton.plug.handler.Events;
-import org.proton.plug.handler.ProtonHandler;
-import org.proton.plug.context.ProtonInitializable;
-import org.proton.plug.SASLResult;
-import org.proton.plug.util.ByteUtil;
-
-/**
- * Clebert Suconic
- */
-public class ProtonHandlerImpl extends ProtonInitializable implements ProtonHandler {
-
- private static final Logger log = Logger.getLogger(ProtonHandlerImpl.class);
-
- private static final byte SASL = 0x03;
-
- private static final byte BARE = 0x00;
-
- private final Transport transport = Proton.transport();
-
- private final Connection connection = Proton.connection();
-
- private final Collector collector = Proton.collector();
-
- private final Executor dispatchExecutor;
-
- private final Runnable dispatchRunnable = new Runnable() {
- @Override
- public void run() {
- dispatch();
- }
- };
-
- private ArrayList<EventHandler> handlers = new ArrayList<>();
-
- private Sasl serverSasl;
-
- private Sasl clientSasl;
-
- private final Object lock = new Object();
-
- private final long creationTime;
-
- private Map<String, ServerSASL> saslHandlers;
-
- private SASLResult saslResult;
-
- protected volatile boolean dataReceived;
-
- protected boolean receivedFirstPacket = false;
-
- private int offset = 0;
-
- public ProtonHandlerImpl(Executor dispatchExecutor) {
- this.dispatchExecutor = dispatchExecutor;
- this.creationTime = System.currentTimeMillis();
- transport.bind(connection);
- connection.collect(collector);
- }
-
- @Override
- public long tick(boolean firstTick) {
- if (!firstTick) {
- try {
- if (connection.getLocalState() != EndpointState.CLOSED) {
- long rescheduleAt = transport.tick(TimeUnit.NANOSECONDS.toMillis(System.nanoTime()));
- if (transport.isClosed()) {
- throw new IllegalStateException("Channel was inactive for to long");
- }
- return rescheduleAt;
- }
- }
- catch (Exception e) {
- transport.close();
- connection.setCondition(new ErrorCondition());
- }
- return 0;
- }
- return transport.tick(TimeUnit.NANOSECONDS.toMillis(System.nanoTime()));
- }
-
- @Override
- public int capacity() {
- synchronized (lock) {
- return transport.capacity();
- }
- }
-
- @Override
- public Object getLock() {
- return lock;
- }
-
- @Override
- public Transport getTransport() {
- return transport;
- }
-
- @Override
- public Connection getConnection() {
- return connection;
- }
-
- @Override
- public ProtonHandler addEventHandler(EventHandler handler) {
- handlers.add(handler);
- return this;
- }
-
- @Override
- public void createServerSASL(ServerSASL[] handlers) {
- this.serverSasl = transport.sasl();
- saslHandlers = new HashMap<>();
- String[] names = new String[handlers.length];
- int count = 0;
- for (ServerSASL handler : handlers) {
- saslHandlers.put(handler.getName(), handler);
- names[count++] = handler.getName();
- }
- this.serverSasl.server();
- serverSasl.setMechanisms(names);
-
- }
-
- @Override
- public SASLResult getSASLResult() {
- return saslResult;
- }
-
- @Override
- public void inputBuffer(ByteBuf buffer) {
- dataReceived = true;
- synchronized (lock) {
- while (buffer.readableBytes() > 0) {
- int capacity = transport.capacity();
-
- if (!receivedFirstPacket) {
- try {
- byte auth = buffer.getByte(4);
- if (auth == SASL || auth == BARE) {
- dispatchAuth(auth == SASL);
- /*
- * there is a chance that if SASL Handshake has been carried out that the capacity may change.
- * */
- capacity = transport.capacity();
- }
- }
- catch (Throwable e) {
- log.debug(e.getMessage(), e);
- }
-
- receivedFirstPacket = true;
- }
-
- if (capacity > 0) {
- ByteBuffer tail = transport.tail();
- int min = Math.min(capacity, buffer.readableBytes());
- tail.limit(min);
- buffer.readBytes(tail);
-
- flush();
- }
- else {
- if (capacity == 0) {
- log.debugf("abandoning: readableBytes=%d", buffer.readableBytes());
- }
- else {
- log.debugf("transport closed, discarding: readableBytes=%d, capacity=%d", buffer.readableBytes(), transport.capacity());
- }
- break;
- }
- }
- }
- }
-
- @Override
- public boolean checkDataReceived() {
- boolean res = dataReceived;
-
- dataReceived = false;
-
- return res;
- }
-
- @Override
- public long getCreationTime() {
- return creationTime;
- }
-
- @Override
- public void outputDone(int bytes) {
- synchronized (lock) {
- transport.pop(bytes);
- offset -= bytes;
-
- if (offset < 0) {
- throw new IllegalStateException("You called outputDone for more bytes than you actually received. numberOfBytes=" + bytes +
- ", outcome result=" + offset);
- }
- }
-
- flush();
- }
-
- @Override
- public ByteBuf outputBuffer() {
-
- synchronized (lock) {
- int pending = transport.pending();
-
- if (pending < 0) {
- return null;//throw new IllegalStateException("xxx need to close the connection");
- }
-
- int size = pending - offset;
-
- if (size < 0) {
- throw new IllegalStateException("negative size: " + pending);
- }
-
- if (size == 0) {
- return null;
- }
-
- // For returning PooledBytes
- ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(size);
- ByteBuffer head = transport.head();
- head.position(offset);
- head.limit(offset + size);
- buffer.writeBytes(head);
- offset += size; // incrementing offset for future calls
- return buffer;
- }
- }
-
- @Override
- public void createClientSasl(ClientSASL clientSASL) {
- if (clientSASL != null) {
- clientSasl = transport.sasl();
- clientSasl.setMechanisms(clientSASL.getName());
- byte[] initialSasl = clientSASL.getBytes();
- clientSasl.send(initialSasl, 0, initialSasl.length);
- }
- }
-
- @Override
- public void flush() {
- synchronized (lock) {
- transport.process();
-
- checkServerSASL();
-
- }
-
- dispatchExecutor.execute(dispatchRunnable);
- }
-
- @Override
- public void close() {
- synchronized (lock) {
- connection.close();
- }
- flush();
- }
-
- protected void checkServerSASL() {
- if (serverSasl != null && serverSasl.getRemoteMechanisms().length > 0) {
- // TODO: should we look at the first only?
- ServerSASL mechanism = saslHandlers.get(serverSasl.getRemoteMechanisms()[0]);
- if (mechanism != null) {
-
- byte[] dataSASL = new byte[serverSasl.pending()];
- serverSasl.recv(dataSASL, 0, dataSASL.length);
-
- if (log.isTraceEnabled()) {
- log.trace("Working on sasl::" + ByteUtil.bytesToHex(dataSASL, 2));
- }
-
- saslResult = mechanism.processSASL(dataSASL);
-
- if (saslResult != null && saslResult.isSuccess()) {
- serverSasl.done(Sasl.SaslOutcome.PN_SASL_OK);
- serverSasl = null;
- saslHandlers.clear();
- saslHandlers = null;
- }
- else {
- serverSasl.done(Sasl.SaslOutcome.PN_SASL_AUTH);
- }
- serverSasl = null;
- }
- else {
- // no auth available, system error
- serverSasl.done(Sasl.SaslOutcome.PN_SASL_SYS);
- }
- }
- }
-
- private Event popEvent() {
- synchronized (lock) {
- Event ev = collector.peek();
- if (ev != null) {
- // pop will invalidate the event
- // for that reason we make a new one
- // Events are reused inside the collector, so we need to make a new one here
- ev = ev.copy();
- collector.pop();
- }
- return ev;
- }
- }
-
- private void dispatchAuth(boolean sasl) {
- for (EventHandler h : handlers) {
- h.onAuthInit(this, getConnection(), sasl);
- }
- }
-
- private void dispatch() {
- Event ev;
- // We don't hold a lock on the entire event processing
- // because we could have a distributed deadlock
- // while processing events (for instance onTransport)
- // while a client is also trying to write here
- while ((ev = popEvent()) != null) {
- for (EventHandler h : handlers) {
- if (log.isTraceEnabled()) {
- log.trace("Handling " + ev + " towards " + h);
- }
- try {
- Events.dispatch(ev, h);
- }
- catch (Exception e) {
- log.warn(e.getMessage(), e);
- connection.setCondition(new ErrorCondition());
- }
- }
- }
-
- for (EventHandler h : handlers) {
- try {
- h.onTransport(transport);
- }
- catch (Exception e) {
- log.warn(e.getMessage(), e);
- connection.setCondition(new ErrorCondition());
- }
- }
-
- }
-}
[11/15] activemq-artemis git commit: ARTEMIS-751 Simplification of
the AMQP implementation
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/ActiveMQJMSVendor.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/ActiveMQJMSVendor.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/ActiveMQJMSVendor.java
new file mode 100644
index 0000000..7e3ba67
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/ActiveMQJMSVendor.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter;
+
+import javax.jms.BytesMessage;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.MapMessage;
+import javax.jms.Message;
+import javax.jms.ObjectMessage;
+import javax.jms.StreamMessage;
+import javax.jms.TextMessage;
+
+import org.apache.activemq.artemis.core.buffers.impl.ResetLimitWrappedActiveMQBuffer;
+import org.apache.activemq.artemis.protocol.amqp.converter.jms.ServerDestination;
+import org.apache.activemq.artemis.protocol.amqp.converter.jms.ServerJMSMapMessage;
+import org.apache.activemq.artemis.protocol.amqp.converter.message.JMSVendor;
+import org.apache.activemq.artemis.protocol.amqp.converter.jms.ServerJMSBytesMessage;
+import org.apache.activemq.artemis.protocol.amqp.converter.jms.ServerJMSMessage;
+import org.apache.activemq.artemis.protocol.amqp.converter.jms.ServerJMSObjectMessage;
+import org.apache.activemq.artemis.protocol.amqp.converter.jms.ServerJMSStreamMessage;
+import org.apache.activemq.artemis.protocol.amqp.converter.jms.ServerJMSTextMessage;
+import org.apache.activemq.artemis.core.server.ServerMessage;
+import org.apache.activemq.artemis.core.server.impl.ServerMessageImpl;
+import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
+import org.apache.activemq.artemis.utils.IDGenerator;
+
+public class ActiveMQJMSVendor implements JMSVendor {
+
+ private final IDGenerator serverGenerator;
+
+ ActiveMQJMSVendor(IDGenerator idGenerator) {
+ this.serverGenerator = idGenerator;
+ }
+
+ @Override
+ public BytesMessage createBytesMessage() {
+ return new ServerJMSBytesMessage(newMessage(org.apache.activemq.artemis.api.core.Message.BYTES_TYPE), 0);
+ }
+
+ @Override
+ public StreamMessage createStreamMessage() {
+ return new ServerJMSStreamMessage(newMessage(org.apache.activemq.artemis.api.core.Message.STREAM_TYPE), 0);
+ }
+
+ @Override
+ public Message createMessage() {
+ return new ServerJMSMessage(newMessage(org.apache.activemq.artemis.api.core.Message.DEFAULT_TYPE), 0);
+ }
+
+ @Override
+ public TextMessage createTextMessage() {
+ return new ServerJMSTextMessage(newMessage(org.apache.activemq.artemis.api.core.Message.TEXT_TYPE), 0);
+ }
+
+ @Override
+ public ObjectMessage createObjectMessage() {
+ return new ServerJMSObjectMessage(newMessage(org.apache.activemq.artemis.api.core.Message.OBJECT_TYPE), 0);
+ }
+
+ @Override
+ public MapMessage createMapMessage() {
+ return new ServerJMSMapMessage(newMessage(org.apache.activemq.artemis.api.core.Message.MAP_TYPE), 0);
+ }
+
+ @Override
+ public void setJMSXUserID(Message message, String s) {
+ }
+
+ @Override
+ public Destination createDestination(String name) {
+ return new ServerDestination(name);
+ }
+
+ @Override
+ public void setJMSXGroupID(Message message, String s) {
+ try {
+ message.setStringProperty("_AMQ_GROUP_ID", s);
+ }
+ catch (JMSException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void setJMSXGroupSequence(Message message, int i) {
+ try {
+ message.setIntProperty("JMSXGroupSeq", i);
+ }
+ catch (JMSException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void setJMSXDeliveryCount(Message message, long l) {
+ try {
+ message.setLongProperty("JMSXDeliveryCount", l);
+ }
+ catch (JMSException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public ServerJMSMessage wrapMessage(int messageType, ServerMessage wrapped, int deliveryCount) {
+ switch (messageType) {
+ case org.apache.activemq.artemis.api.core.Message.STREAM_TYPE:
+ return new ServerJMSStreamMessage(wrapped, deliveryCount);
+ case org.apache.activemq.artemis.api.core.Message.BYTES_TYPE:
+ return new ServerJMSBytesMessage(wrapped, deliveryCount);
+ case org.apache.activemq.artemis.api.core.Message.MAP_TYPE:
+ return new ServerJMSMapMessage(wrapped, deliveryCount);
+ case org.apache.activemq.artemis.api.core.Message.TEXT_TYPE:
+ return new ServerJMSTextMessage(wrapped, deliveryCount);
+ case org.apache.activemq.artemis.api.core.Message.OBJECT_TYPE:
+ return new ServerJMSObjectMessage(wrapped, deliveryCount);
+ default:
+ return new ServerJMSMessage(wrapped, deliveryCount);
+ }
+ }
+
+ @Override
+ public String toAddress(Destination destination) {
+ if (destination instanceof ActiveMQDestination) {
+ return ((ActiveMQDestination) destination).getAddress();
+ }
+ return null;
+ }
+
+ private ServerMessageImpl newMessage(byte messageType) {
+ ServerMessageImpl message = new ServerMessageImpl(serverGenerator.generateID(), 512);
+ message.setType(messageType);
+ ((ResetLimitWrappedActiveMQBuffer) message.getBodyBuffer()).setMessage(null);
+ return message;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/ProtonMessageConverter.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/ProtonMessageConverter.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/ProtonMessageConverter.java
new file mode 100644
index 0000000..f520387
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/ProtonMessageConverter.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter;
+
+import org.apache.activemq.artemis.core.client.ActiveMQClientLogger;
+import org.apache.activemq.artemis.protocol.amqp.converter.jms.ServerJMSMessage;
+import org.apache.activemq.artemis.protocol.amqp.converter.message.AMQPNativeOutboundTransformer;
+import org.apache.activemq.artemis.protocol.amqp.converter.message.EncodedMessage;
+import org.apache.activemq.artemis.protocol.amqp.converter.message.InboundTransformer;
+import org.apache.activemq.artemis.protocol.amqp.converter.message.JMSMappingInboundTransformer;
+import org.apache.activemq.artemis.protocol.amqp.converter.message.JMSMappingOutboundTransformer;
+import org.apache.activemq.artemis.core.server.ServerMessage;
+import org.apache.activemq.artemis.spi.core.protocol.MessageConverter;
+import org.apache.activemq.artemis.utils.IDGenerator;
+
+import javax.jms.BytesMessage;
+import java.io.IOException;
+
+public class ProtonMessageConverter implements MessageConverter {
+
+ ActiveMQJMSVendor activeMQJMSVendor;
+
+ private final String prefixVendor;
+
+ public ProtonMessageConverter(IDGenerator idGenerator) {
+ activeMQJMSVendor = new ActiveMQJMSVendor(idGenerator);
+ inboundTransformer = new JMSMappingInboundTransformer(activeMQJMSVendor);
+ outboundTransformer = new JMSMappingOutboundTransformer(activeMQJMSVendor);
+ prefixVendor = outboundTransformer.getPrefixVendor();
+ }
+
+ private final InboundTransformer inboundTransformer;
+ private final JMSMappingOutboundTransformer outboundTransformer;
+
+ @Override
+ public ServerMessage inbound(Object messageSource) throws Exception {
+ ServerJMSMessage jmsMessage = inboundJMSType((EncodedMessage) messageSource);
+
+ return (ServerMessage) jmsMessage.getInnerMessage();
+ }
+
+ /**
+ * Just create the JMS Part of the inbound (for testing)
+ *
+ * @param messageSource
+ * @return
+ * @throws Exception https://issues.jboss.org/browse/ENTMQ-1560
+ */
+ public ServerJMSMessage inboundJMSType(EncodedMessage messageSource) throws Exception {
+ EncodedMessage encodedMessageSource = messageSource;
+ ServerJMSMessage transformedMessage = null;
+
+ InboundTransformer transformer = inboundTransformer;
+
+ while (transformer != null) {
+ try {
+ transformedMessage = (ServerJMSMessage) transformer.transform(encodedMessageSource);
+ break;
+ }
+ catch (Exception e) {
+ ActiveMQClientLogger.LOGGER.debug("Transform of message using [{}] transformer, failed" + inboundTransformer.getTransformerName());
+ ActiveMQClientLogger.LOGGER.trace("Transformation error:", e);
+
+ transformer = transformer.getFallbackTransformer();
+ }
+ }
+
+ if (transformedMessage == null) {
+ throw new IOException("Failed to transform incoming delivery, skipping.");
+ }
+
+ transformedMessage.encode();
+
+ return transformedMessage;
+ }
+
+ @Override
+ public Object outbound(ServerMessage messageOutbound, int deliveryCount) throws Exception {
+ ServerJMSMessage jmsMessage = activeMQJMSVendor.wrapMessage(messageOutbound.getType(), messageOutbound, deliveryCount);
+
+ jmsMessage.decode();
+
+ if (jmsMessage.getBooleanProperty(prefixVendor + "NATIVE")) {
+ if (jmsMessage instanceof BytesMessage) {
+ return AMQPNativeOutboundTransformer.transform(outboundTransformer, (BytesMessage) jmsMessage);
+ }
+ else {
+ return null;
+ }
+ }
+ else {
+ return outboundTransformer.convert(jmsMessage);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerDestination.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerDestination.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerDestination.java
new file mode 100644
index 0000000..967ba08
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerDestination.java
@@ -0,0 +1,37 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter.jms;
+
+import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
+
+import javax.jms.JMSException;
+import javax.jms.Queue;
+
+/**
+ * This is just here to avoid all the client checks we need with valid JMS destinations, protocol convertors don't need to
+ * adhere to the jms. semantics.
+ */
+public class ServerDestination extends ActiveMQDestination implements Queue {
+ public ServerDestination(String name) {
+ super(name, name, false, false, null);
+ }
+
+ @Override
+ public String getQueueName() throws JMSException {
+ return getName();
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSBytesMessage.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSBytesMessage.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSBytesMessage.java
new file mode 100644
index 0000000..abdf808
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSBytesMessage.java
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter.jms;
+
+import javax.jms.BytesMessage;
+import javax.jms.JMSException;
+
+import org.apache.activemq.artemis.core.message.impl.MessageImpl;
+import org.apache.activemq.artemis.core.message.impl.MessageInternal;
+
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesMessageReset;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadBoolean;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadByte;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadBytes;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadChar;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadDouble;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadFloat;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadInt;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadLong;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadShort;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadUTF;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadUnsignedByte;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadUnsignedShort;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteBoolean;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteByte;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteBytes;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteChar;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteDouble;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteFloat;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteInt;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteLong;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteObject;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteShort;
+import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteUTF;
+
+public class ServerJMSBytesMessage extends ServerJMSMessage implements BytesMessage {
+
+ public ServerJMSBytesMessage(MessageInternal message, int deliveryCount) {
+ super(message, deliveryCount);
+ }
+
+ @Override
+ public long getBodyLength() throws JMSException {
+ return message.getEndOfBodyPosition() - MessageImpl.BODY_OFFSET;
+ }
+
+ @Override
+ public boolean readBoolean() throws JMSException {
+ return bytesReadBoolean(getReadBodyBuffer());
+ }
+
+ @Override
+ public byte readByte() throws JMSException {
+ return bytesReadByte(getReadBodyBuffer());
+ }
+
+ @Override
+ public int readUnsignedByte() throws JMSException {
+ return bytesReadUnsignedByte(getReadBodyBuffer());
+ }
+
+ @Override
+ public short readShort() throws JMSException {
+ return bytesReadShort(getReadBodyBuffer());
+ }
+
+ @Override
+ public int readUnsignedShort() throws JMSException {
+ return bytesReadUnsignedShort(getReadBodyBuffer());
+ }
+
+ @Override
+ public char readChar() throws JMSException {
+ return bytesReadChar(getReadBodyBuffer());
+ }
+
+ @Override
+ public int readInt() throws JMSException {
+ return bytesReadInt(getReadBodyBuffer());
+ }
+
+ @Override
+ public long readLong() throws JMSException {
+ return bytesReadLong(getReadBodyBuffer());
+ }
+
+ @Override
+ public float readFloat() throws JMSException {
+ return bytesReadFloat(getReadBodyBuffer());
+ }
+
+ @Override
+ public double readDouble() throws JMSException {
+ return bytesReadDouble(getReadBodyBuffer());
+ }
+
+ @Override
+ public String readUTF() throws JMSException {
+ return bytesReadUTF(getReadBodyBuffer());
+ }
+
+ @Override
+ public int readBytes(byte[] value) throws JMSException {
+ return bytesReadBytes(getReadBodyBuffer(), value);
+ }
+
+ @Override
+ public int readBytes(byte[] value, int length) throws JMSException {
+ return bytesReadBytes(getReadBodyBuffer(), value, length);
+ }
+
+ @Override
+ public void writeBoolean(boolean value) throws JMSException {
+ bytesWriteBoolean(getWriteBodyBuffer(), value);
+
+ }
+
+ @Override
+ public void writeByte(byte value) throws JMSException {
+ bytesWriteByte(getWriteBodyBuffer(), value);
+ }
+
+ @Override
+ public void writeShort(short value) throws JMSException {
+ bytesWriteShort(getWriteBodyBuffer(), value);
+ }
+
+ @Override
+ public void writeChar(char value) throws JMSException {
+ bytesWriteChar(getWriteBodyBuffer(), value);
+ }
+
+ @Override
+ public void writeInt(int value) throws JMSException {
+ bytesWriteInt(getWriteBodyBuffer(), value);
+ }
+
+ @Override
+ public void writeLong(long value) throws JMSException {
+ bytesWriteLong(getWriteBodyBuffer(), value);
+ }
+
+ @Override
+ public void writeFloat(float value) throws JMSException {
+ bytesWriteFloat(getWriteBodyBuffer(), value);
+ }
+
+ @Override
+ public void writeDouble(double value) throws JMSException {
+ bytesWriteDouble(getWriteBodyBuffer(), value);
+ }
+
+ @Override
+ public void writeUTF(String value) throws JMSException {
+ bytesWriteUTF(getWriteBodyBuffer(), value);
+ }
+
+ @Override
+ public void writeBytes(byte[] value) throws JMSException {
+ bytesWriteBytes(getWriteBodyBuffer(), value);
+ }
+
+ @Override
+ public void writeBytes(byte[] value, int offset, int length) throws JMSException {
+ bytesWriteBytes(getWriteBodyBuffer(), value, offset, length);
+ }
+
+ @Override
+ public void writeObject(Object value) throws JMSException {
+ if (!bytesWriteObject(getWriteBodyBuffer(), value)) {
+ throw new JMSException("Can't make conversion of " + value + " to any known type");
+ }
+ }
+
+ @Override
+ public void encode() throws Exception {
+ super.encode();
+ // this is to make sure we encode the body-length before it's persisted
+ getBodyLength();
+ }
+
+ @Override
+ public void decode() throws Exception {
+ super.decode();
+
+ }
+
+ @Override
+ public void reset() throws JMSException {
+ bytesMessageReset(getReadBodyBuffer());
+ bytesMessageReset(getWriteBodyBuffer());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSMapMessage.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSMapMessage.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSMapMessage.java
new file mode 100644
index 0000000..548deb3
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSMapMessage.java
@@ -0,0 +1,291 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter.jms;
+
+import javax.jms.JMSException;
+import javax.jms.MapMessage;
+import javax.jms.MessageFormatException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.activemq.artemis.api.core.ActiveMQPropertyConversionException;
+import org.apache.activemq.artemis.api.core.Message;
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.core.message.impl.MessageInternal;
+import org.apache.activemq.artemis.utils.TypedProperties;
+
+import static org.apache.activemq.artemis.reader.MapMessageUtil.readBodyMap;
+import static org.apache.activemq.artemis.reader.MapMessageUtil.writeBodyMap;
+
+/**
+ * ActiveMQ Artemis implementation of a JMS MapMessage.
+ */
+public final class ServerJMSMapMessage extends ServerJMSMessage implements MapMessage {
+ // Constants -----------------------------------------------------
+
+ public static final byte TYPE = Message.MAP_TYPE;
+
+ // Attributes ----------------------------------------------------
+
+ private final TypedProperties map = new TypedProperties();
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ /*
+ * This constructor is used to construct messages prior to sending
+ */
+ public ServerJMSMapMessage(MessageInternal message, int deliveryCount) {
+ super(message, deliveryCount);
+
+ }
+
+ // MapMessage implementation -------------------------------------
+
+ @Override
+ public void setBoolean(final String name, final boolean value) throws JMSException {
+ map.putBooleanProperty(new SimpleString(name), value);
+ }
+
+ @Override
+ public void setByte(final String name, final byte value) throws JMSException {
+ map.putByteProperty(new SimpleString(name), value);
+ }
+
+ @Override
+ public void setShort(final String name, final short value) throws JMSException {
+ map.putShortProperty(new SimpleString(name), value);
+ }
+
+ @Override
+ public void setChar(final String name, final char value) throws JMSException {
+ map.putCharProperty(new SimpleString(name), value);
+ }
+
+ @Override
+ public void setInt(final String name, final int value) throws JMSException {
+ map.putIntProperty(new SimpleString(name), value);
+ }
+
+ @Override
+ public void setLong(final String name, final long value) throws JMSException {
+ map.putLongProperty(new SimpleString(name), value);
+ }
+
+ @Override
+ public void setFloat(final String name, final float value) throws JMSException {
+ map.putFloatProperty(new SimpleString(name), value);
+ }
+
+ @Override
+ public void setDouble(final String name, final double value) throws JMSException {
+ map.putDoubleProperty(new SimpleString(name), value);
+ }
+
+ @Override
+ public void setString(final String name, final String value) throws JMSException {
+ map.putSimpleStringProperty(new SimpleString(name), value == null ? null : new SimpleString(value));
+ }
+
+ @Override
+ public void setBytes(final String name, final byte[] value) throws JMSException {
+ map.putBytesProperty(new SimpleString(name), value);
+ }
+
+ @Override
+ public void setBytes(final String name, final byte[] value, final int offset, final int length) throws JMSException {
+ if (offset + length > value.length) {
+ throw new JMSException("Invalid offset/length");
+ }
+ byte[] newBytes = new byte[length];
+ System.arraycopy(value, offset, newBytes, 0, length);
+ map.putBytesProperty(new SimpleString(name), newBytes);
+ }
+
+ @Override
+ public void setObject(final String name, final Object value) throws JMSException {
+ try {
+ TypedProperties.setObjectProperty(new SimpleString(name), value, map);
+ }
+ catch (ActiveMQPropertyConversionException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ }
+
+ @Override
+ public boolean getBoolean(final String name) throws JMSException {
+ try {
+ return map.getBooleanProperty(new SimpleString(name));
+ }
+ catch (ActiveMQPropertyConversionException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ }
+
+ @Override
+ public byte getByte(final String name) throws JMSException {
+ try {
+ return map.getByteProperty(new SimpleString(name));
+ }
+ catch (ActiveMQPropertyConversionException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ }
+
+ @Override
+ public short getShort(final String name) throws JMSException {
+ try {
+ return map.getShortProperty(new SimpleString(name));
+ }
+ catch (ActiveMQPropertyConversionException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ }
+
+ @Override
+ public char getChar(final String name) throws JMSException {
+ try {
+ return map.getCharProperty(new SimpleString(name));
+ }
+ catch (ActiveMQPropertyConversionException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ }
+
+ @Override
+ public int getInt(final String name) throws JMSException {
+ try {
+ return map.getIntProperty(new SimpleString(name));
+ }
+ catch (ActiveMQPropertyConversionException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ }
+
+ @Override
+ public long getLong(final String name) throws JMSException {
+ try {
+ return map.getLongProperty(new SimpleString(name));
+ }
+ catch (ActiveMQPropertyConversionException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ }
+
+ @Override
+ public float getFloat(final String name) throws JMSException {
+ try {
+ return map.getFloatProperty(new SimpleString(name));
+ }
+ catch (ActiveMQPropertyConversionException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ }
+
+ @Override
+ public double getDouble(final String name) throws JMSException {
+ try {
+ return map.getDoubleProperty(new SimpleString(name));
+ }
+ catch (ActiveMQPropertyConversionException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ }
+
+ @Override
+ public String getString(final String name) throws JMSException {
+ try {
+ SimpleString str = map.getSimpleStringProperty(new SimpleString(name));
+ if (str == null) {
+ return null;
+ }
+ else {
+ return str.toString();
+ }
+ }
+ catch (ActiveMQPropertyConversionException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ }
+
+ @Override
+ public byte[] getBytes(final String name) throws JMSException {
+ try {
+ return map.getBytesProperty(new SimpleString(name));
+ }
+ catch (ActiveMQPropertyConversionException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ }
+
+ @Override
+ public Object getObject(final String name) throws JMSException {
+ Object val = map.getProperty(new SimpleString(name));
+
+ if (val instanceof SimpleString) {
+ val = ((SimpleString) val).toString();
+ }
+
+ return val;
+ }
+
+ @Override
+ public Enumeration getMapNames() throws JMSException {
+ Set<SimpleString> simplePropNames = map.getPropertyNames();
+ Set<String> propNames = new HashSet<>(simplePropNames.size());
+
+ for (SimpleString str : simplePropNames) {
+ propNames.add(str.toString());
+ }
+
+ return Collections.enumeration(propNames);
+ }
+
+ @Override
+ public boolean itemExists(final String name) throws JMSException {
+ return map.containsProperty(new SimpleString(name));
+ }
+
+ @Override
+ public void clearBody() throws JMSException {
+ super.clearBody();
+
+ map.clear();
+ }
+
+ @Override
+ public void encode() throws Exception {
+ super.encode();
+ writeBodyMap(getWriteBodyBuffer(), map);
+ }
+
+ @Override
+ public void decode() throws Exception {
+ super.decode();
+ readBodyMap(getReadBodyBuffer(), map);
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSMessage.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSMessage.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSMessage.java
new file mode 100644
index 0000000..d15d22b
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSMessage.java
@@ -0,0 +1,381 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter.jms;
+
+import javax.jms.DeliveryMode;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import java.util.Collections;
+import java.util.Enumeration;
+
+import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.core.message.impl.MessageInternal;
+import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
+import org.apache.activemq.artemis.reader.MessageUtil;
+
+public class ServerJMSMessage implements Message {
+
+ public static final String NATIVE_MESSAGE_ID = "NATIVE_MESSAGE_ID";
+
+ protected final MessageInternal message;
+
+ protected int deliveryCount;
+
+ public MessageInternal getInnerMessage() {
+ return message;
+ }
+
+ public ServerJMSMessage(MessageInternal message, int deliveryCount) {
+ this.message = message;
+ this.deliveryCount = deliveryCount;
+ }
+
+ private ActiveMQBuffer readBodyBuffer;
+
+ /** When reading we use a protected copy so multi-threads can work fine */
+ protected ActiveMQBuffer getReadBodyBuffer() {
+ if (readBodyBuffer == null) {
+ // to avoid clashes between multiple threads
+ readBodyBuffer = message.getBodyBufferDuplicate();
+ }
+ return readBodyBuffer;
+ }
+
+ /** When writing on the conversion we use the buffer directly */
+ protected ActiveMQBuffer getWriteBodyBuffer() {
+ readBodyBuffer = null; // it invalidates this buffer if anything is written
+ return message.getBodyBuffer();
+ }
+
+
+ @Override
+ public final String getJMSMessageID() throws JMSException {
+ if (message.containsProperty(NATIVE_MESSAGE_ID)) {
+ return getStringProperty(NATIVE_MESSAGE_ID);
+ }
+ return null;
+ }
+
+ @Override
+ public final void setJMSMessageID(String id) throws JMSException {
+ if (id != null) {
+ message.putStringProperty(NATIVE_MESSAGE_ID, id);
+ }
+ }
+
+ @Override
+ public final long getJMSTimestamp() throws JMSException {
+ return message.getTimestamp();
+ }
+
+ @Override
+ public final void setJMSTimestamp(long timestamp) throws JMSException {
+ message.setTimestamp(timestamp);
+ }
+
+ @Override
+ public final byte[] getJMSCorrelationIDAsBytes() throws JMSException {
+ return MessageUtil.getJMSCorrelationIDAsBytes(message);
+ }
+
+ @Override
+ public final void setJMSCorrelationIDAsBytes(byte[] correlationID) throws JMSException {
+ try {
+ MessageUtil.setJMSCorrelationIDAsBytes(message, correlationID);
+ }
+ catch (ActiveMQException e) {
+ throw new JMSException(e.getMessage());
+ }
+ }
+
+ @Override
+ public final void setJMSCorrelationID(String correlationID) throws JMSException {
+ MessageUtil.setJMSCorrelationID(message, correlationID);
+ }
+
+ @Override
+ public final String getJMSCorrelationID() throws JMSException {
+ return MessageUtil.getJMSCorrelationID(message);
+ }
+
+ @Override
+ public final Destination getJMSReplyTo() throws JMSException {
+ SimpleString reply = MessageUtil.getJMSReplyTo(message);
+ if (reply != null) {
+ return new ServerDestination(reply.toString());
+ }
+ else {
+ return null;
+ }
+ }
+
+ @Override
+ public final void setJMSReplyTo(Destination replyTo) throws JMSException {
+ MessageUtil.setJMSReplyTo(message, replyTo == null ? null : ((ActiveMQDestination) replyTo).getSimpleAddress());
+
+ }
+
+ @Override
+ public final Destination getJMSDestination() throws JMSException {
+ SimpleString sdest = message.getAddress();
+
+ if (sdest == null) {
+ return null;
+ }
+ else {
+ return new ServerDestination(sdest.toString());
+ }
+ }
+
+ @Override
+ public final void setJMSDestination(Destination destination) throws JMSException {
+ if (destination == null) {
+ message.setAddress(null);
+ }
+ else {
+ message.setAddress(((ActiveMQDestination) destination).getSimpleAddress());
+ }
+
+ }
+
+ @Override
+ public final int getJMSDeliveryMode() throws JMSException {
+ return message.isDurable() ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT;
+ }
+
+ @Override
+ public final void setJMSDeliveryMode(int deliveryMode) throws JMSException {
+ if (deliveryMode == DeliveryMode.PERSISTENT) {
+ message.setDurable(true);
+ }
+ else if (deliveryMode == DeliveryMode.NON_PERSISTENT) {
+ message.setDurable(false);
+ }
+ else {
+ throw new JMSException("Invalid mode " + deliveryMode);
+ }
+ }
+
+ @Override
+ public final boolean getJMSRedelivered() throws JMSException {
+ return false;
+ }
+
+ @Override
+ public final void setJMSRedelivered(boolean redelivered) throws JMSException {
+ // no op
+ }
+
+ @Override
+ public final String getJMSType() throws JMSException {
+ return MessageUtil.getJMSType(message);
+ }
+
+ @Override
+ public final void setJMSType(String type) throws JMSException {
+ MessageUtil.setJMSType(message, type);
+ }
+
+ @Override
+ public final long getJMSExpiration() throws JMSException {
+ return message.getExpiration();
+ }
+
+ @Override
+ public final void setJMSExpiration(long expiration) throws JMSException {
+ message.setExpiration(expiration);
+ }
+
+ @Override
+ public final long getJMSDeliveryTime() throws JMSException {
+ // no op
+ return 0;
+ }
+
+ @Override
+ public final void setJMSDeliveryTime(long deliveryTime) throws JMSException {
+ // no op
+ }
+
+ @Override
+ public final int getJMSPriority() throws JMSException {
+ return message.getPriority();
+ }
+
+ @Override
+ public final void setJMSPriority(int priority) throws JMSException {
+ message.setPriority((byte) priority);
+ }
+
+ @Override
+ public final void clearProperties() throws JMSException {
+ MessageUtil.clearProperties(message);
+
+ }
+
+ @Override
+ public final boolean propertyExists(String name) throws JMSException {
+ return MessageUtil.propertyExists(message, name);
+ }
+
+ @Override
+ public final boolean getBooleanProperty(String name) throws JMSException {
+ return message.getBooleanProperty(name);
+ }
+
+ @Override
+ public final byte getByteProperty(String name) throws JMSException {
+ return message.getByteProperty(name);
+ }
+
+ @Override
+ public final short getShortProperty(String name) throws JMSException {
+ return message.getShortProperty(name);
+ }
+
+ @Override
+ public final int getIntProperty(String name) throws JMSException {
+ if (MessageUtil.JMSXDELIVERYCOUNT.equals(name)) {
+ return deliveryCount;
+ }
+
+ return message.getIntProperty(name);
+ }
+
+ @Override
+ public final long getLongProperty(String name) throws JMSException {
+ if (MessageUtil.JMSXDELIVERYCOUNT.equals(name)) {
+ return deliveryCount;
+ }
+
+ return message.getLongProperty(name);
+ }
+
+ @Override
+ public final float getFloatProperty(String name) throws JMSException {
+ return message.getFloatProperty(name);
+ }
+
+ @Override
+ public final double getDoubleProperty(String name) throws JMSException {
+ return message.getDoubleProperty(name);
+ }
+
+ @Override
+ public final String getStringProperty(String name) throws JMSException {
+ if (MessageUtil.JMSXDELIVERYCOUNT.equals(name)) {
+ return String.valueOf(deliveryCount);
+ }
+
+ return message.getStringProperty(name);
+ }
+
+ @Override
+ public final Object getObjectProperty(String name) throws JMSException {
+ Object val = message.getObjectProperty(name);
+ if (val instanceof SimpleString) {
+ val = ((SimpleString) val).toString();
+ }
+ return val;
+ }
+
+ @Override
+ public final Enumeration getPropertyNames() throws JMSException {
+ return Collections.enumeration(MessageUtil.getPropertyNames(message));
+ }
+
+ @Override
+ public final void setBooleanProperty(String name, boolean value) throws JMSException {
+ message.putBooleanProperty(name, value);
+ }
+
+ @Override
+ public final void setByteProperty(String name, byte value) throws JMSException {
+ message.putByteProperty(name, value);
+ }
+
+ @Override
+ public final void setShortProperty(String name, short value) throws JMSException {
+ message.putShortProperty(name, value);
+ }
+
+ @Override
+ public final void setIntProperty(String name, int value) throws JMSException {
+ message.putIntProperty(name, value);
+ }
+
+ @Override
+ public final void setLongProperty(String name, long value) throws JMSException {
+ message.putLongProperty(name, value);
+ }
+
+ @Override
+ public final void setFloatProperty(String name, float value) throws JMSException {
+ message.putFloatProperty(name, value);
+ }
+
+ @Override
+ public final void setDoubleProperty(String name, double value) throws JMSException {
+ message.putDoubleProperty(name, value);
+ }
+
+ @Override
+ public final void setStringProperty(String name, String value) throws JMSException {
+ message.putStringProperty(name, value);
+ }
+
+ @Override
+ public final void setObjectProperty(String name, Object value) throws JMSException {
+ message.putObjectProperty(name, value);
+ }
+
+ @Override
+ public final void acknowledge() throws JMSException {
+ // no op
+ }
+
+ @Override
+ public void clearBody() throws JMSException {
+ message.getBodyBuffer().clear();
+ }
+
+ @Override
+ public final <T> T getBody(Class<T> c) throws JMSException {
+ // no op.. jms2 not used on the conversion
+ return null;
+ }
+
+ /**
+ * Encode the body into the internal message
+ */
+ public void encode() throws Exception {
+ message.getBodyBuffer().resetReaderIndex();
+ }
+
+ public void decode() throws Exception {
+ message.getBodyBuffer().resetReaderIndex();
+ }
+
+ @Override
+ public final boolean isBodyAssignableTo(Class c) throws JMSException {
+ // no op.. jms2 not used on the conversion
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSObjectMessage.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSObjectMessage.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSObjectMessage.java
new file mode 100644
index 0000000..39e0df5
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSObjectMessage.java
@@ -0,0 +1,79 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter.jms;
+
+import org.apache.activemq.artemis.api.core.Message;
+import org.apache.activemq.artemis.core.message.impl.MessageInternal;
+import org.apache.activemq.artemis.utils.ObjectInputStreamWithClassLoader;
+
+import javax.jms.JMSException;
+import javax.jms.ObjectMessage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+
+public class ServerJMSObjectMessage extends ServerJMSMessage implements ObjectMessage {
+ private static final String DEFAULT_WHITELIST;
+ private static final String DEFAULT_BLACKLIST;
+
+ static {
+ DEFAULT_WHITELIST = System.getProperty(ObjectInputStreamWithClassLoader.WHITELIST_PROPERTY,
+ "java.lang,java.math,javax.security,java.util,org.apache.activemq,org.apache.qpid.proton.amqp");
+
+ DEFAULT_BLACKLIST = System.getProperty(ObjectInputStreamWithClassLoader.BLACKLIST_PROPERTY, null);
+ }
+ public static final byte TYPE = Message.STREAM_TYPE;
+
+ private Serializable object;
+
+ public ServerJMSObjectMessage(MessageInternal message, int deliveryCount) {
+ super(message, deliveryCount);
+ }
+
+ @Override
+ public void setObject(Serializable object) throws JMSException {
+ this.object = object;
+ }
+
+ @Override
+ public Serializable getObject() throws JMSException {
+ return object;
+ }
+
+ @Override
+ public void encode() throws Exception {
+ super.encode();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ObjectOutputStream ous = new ObjectOutputStream(out);
+ ous.writeObject(object);
+ getInnerMessage().getBodyBuffer().writeBytes(out.toByteArray());
+ }
+
+ @Override
+ public void decode() throws Exception {
+ super.decode();
+ int size = getInnerMessage().getBodyBuffer().readableBytes();
+ byte[] bytes = new byte[size];
+ getInnerMessage().getBodyBuffer().readBytes(bytes);
+ ObjectInputStreamWithClassLoader ois = new ObjectInputStreamWithClassLoader(new ByteArrayInputStream(bytes));
+ ois.setWhiteList(DEFAULT_WHITELIST);
+ ois.setBlackList(DEFAULT_BLACKLIST);
+ object = (Serializable) ois.readObject();
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSStreamMessage.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSStreamMessage.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSStreamMessage.java
new file mode 100644
index 0000000..c63b701
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSStreamMessage.java
@@ -0,0 +1,364 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter.jms;
+
+import javax.jms.JMSException;
+import javax.jms.MessageEOFException;
+import javax.jms.MessageFormatException;
+import javax.jms.StreamMessage;
+
+import org.apache.activemq.artemis.api.core.Message;
+import org.apache.activemq.artemis.api.core.Pair;
+import org.apache.activemq.artemis.core.message.impl.MessageInternal;
+import org.apache.activemq.artemis.utils.DataConstants;
+
+import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadBoolean;
+import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadByte;
+import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadBytes;
+import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadChar;
+import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadDouble;
+import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadFloat;
+import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadInteger;
+import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadLong;
+import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadObject;
+import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadShort;
+import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadString;
+
+public final class ServerJMSStreamMessage extends ServerJMSMessage implements StreamMessage {
+
+ public static final byte TYPE = Message.STREAM_TYPE;
+
+ private int bodyLength = 0;
+
+ public ServerJMSStreamMessage(MessageInternal message, int deliveryCount) {
+ super(message, deliveryCount);
+ }
+
+ // StreamMessage implementation ----------------------------------
+
+ @Override
+ public boolean readBoolean() throws JMSException {
+
+ try {
+ return streamReadBoolean(getReadBodyBuffer());
+ }
+ catch (IllegalStateException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ catch (IndexOutOfBoundsException e) {
+ throw new MessageEOFException("");
+ }
+ }
+
+ @Override
+ public byte readByte() throws JMSException {
+ try {
+ return streamReadByte(getReadBodyBuffer());
+ }
+ catch (IllegalStateException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ catch (IndexOutOfBoundsException e) {
+ throw new MessageEOFException("");
+ }
+ }
+
+ @Override
+ public short readShort() throws JMSException {
+
+ try {
+ return streamReadShort(getReadBodyBuffer());
+ }
+ catch (IllegalStateException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ catch (IndexOutOfBoundsException e) {
+ throw new MessageEOFException("");
+ }
+ }
+
+ @Override
+ public char readChar() throws JMSException {
+
+ try {
+ return streamReadChar(getReadBodyBuffer());
+ }
+ catch (IllegalStateException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ catch (IndexOutOfBoundsException e) {
+ throw new MessageEOFException("");
+ }
+ }
+
+ @Override
+ public int readInt() throws JMSException {
+
+ try {
+ return streamReadInteger(getReadBodyBuffer());
+ }
+ catch (IllegalStateException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ catch (IndexOutOfBoundsException e) {
+ throw new MessageEOFException("");
+ }
+ }
+
+ @Override
+ public long readLong() throws JMSException {
+
+ try {
+ return streamReadLong(getReadBodyBuffer());
+ }
+ catch (IllegalStateException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ catch (IndexOutOfBoundsException e) {
+ throw new MessageEOFException("");
+ }
+ }
+
+ @Override
+ public float readFloat() throws JMSException {
+
+ try {
+ return streamReadFloat(getReadBodyBuffer());
+ }
+ catch (IllegalStateException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ catch (IndexOutOfBoundsException e) {
+ throw new MessageEOFException("");
+ }
+ }
+
+ @Override
+ public double readDouble() throws JMSException {
+
+ try {
+ return streamReadDouble(getReadBodyBuffer());
+ }
+ catch (IllegalStateException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ catch (IndexOutOfBoundsException e) {
+ throw new MessageEOFException("");
+ }
+ }
+
+ @Override
+ public String readString() throws JMSException {
+
+ try {
+ return streamReadString(getReadBodyBuffer());
+ }
+ catch (IllegalStateException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ catch (IndexOutOfBoundsException e) {
+ throw new MessageEOFException("");
+ }
+ }
+
+ /**
+ * len here is used to control how many more bytes to read
+ */
+ private int len = 0;
+
+ @Override
+ public int readBytes(final byte[] value) throws JMSException {
+
+ try {
+ Pair<Integer, Integer> pairRead = streamReadBytes(getReadBodyBuffer(), len, value);
+
+ len = pairRead.getA();
+ return pairRead.getB();
+ }
+ catch (IllegalStateException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ catch (IndexOutOfBoundsException e) {
+ throw new MessageEOFException("");
+ }
+ }
+
+ @Override
+ public Object readObject() throws JMSException {
+
+ if (getReadBodyBuffer().readerIndex() >= message.getEndOfBodyPosition()) {
+ throw new MessageEOFException("");
+ }
+ try {
+ return streamReadObject(getReadBodyBuffer());
+ }
+ catch (IllegalStateException e) {
+ throw new MessageFormatException(e.getMessage());
+ }
+ catch (IndexOutOfBoundsException e) {
+ throw new MessageEOFException("");
+ }
+ }
+
+ @Override
+ public void writeBoolean(final boolean value) throws JMSException {
+
+ getWriteBodyBuffer().writeByte(DataConstants.BOOLEAN);
+ getWriteBodyBuffer().writeBoolean(value);
+ }
+
+ @Override
+ public void writeByte(final byte value) throws JMSException {
+
+ getWriteBodyBuffer().writeByte(DataConstants.BYTE);
+ getWriteBodyBuffer().writeByte(value);
+ }
+
+ @Override
+ public void writeShort(final short value) throws JMSException {
+
+ getWriteBodyBuffer().writeByte(DataConstants.SHORT);
+ getWriteBodyBuffer().writeShort(value);
+ }
+
+ @Override
+ public void writeChar(final char value) throws JMSException {
+
+ getWriteBodyBuffer().writeByte(DataConstants.CHAR);
+ getWriteBodyBuffer().writeShort((short) value);
+ }
+
+ @Override
+ public void writeInt(final int value) throws JMSException {
+
+ getWriteBodyBuffer().writeByte(DataConstants.INT);
+ getWriteBodyBuffer().writeInt(value);
+ }
+
+ @Override
+ public void writeLong(final long value) throws JMSException {
+
+ getWriteBodyBuffer().writeByte(DataConstants.LONG);
+ getWriteBodyBuffer().writeLong(value);
+ }
+
+ @Override
+ public void writeFloat(final float value) throws JMSException {
+
+ getWriteBodyBuffer().writeByte(DataConstants.FLOAT);
+ getWriteBodyBuffer().writeInt(Float.floatToIntBits(value));
+ }
+
+ @Override
+ public void writeDouble(final double value) throws JMSException {
+
+ getWriteBodyBuffer().writeByte(DataConstants.DOUBLE);
+ getWriteBodyBuffer().writeLong(Double.doubleToLongBits(value));
+ }
+
+ @Override
+ public void writeString(final String value) throws JMSException {
+
+ getWriteBodyBuffer().writeByte(DataConstants.STRING);
+ getWriteBodyBuffer().writeNullableString(value);
+ }
+
+ @Override
+ public void writeBytes(final byte[] value) throws JMSException {
+
+ getWriteBodyBuffer().writeByte(DataConstants.BYTES);
+ getWriteBodyBuffer().writeInt(value.length);
+ getWriteBodyBuffer().writeBytes(value);
+ }
+
+ @Override
+ public void writeBytes(final byte[] value, final int offset, final int length) throws JMSException {
+
+ getWriteBodyBuffer().writeByte(DataConstants.BYTES);
+ getWriteBodyBuffer().writeInt(length);
+ getWriteBodyBuffer().writeBytes(value, offset, length);
+ }
+
+ @Override
+ public void writeObject(final Object value) throws JMSException {
+ if (value instanceof String) {
+ writeString((String) value);
+ }
+ else if (value instanceof Boolean) {
+ writeBoolean((Boolean) value);
+ }
+ else if (value instanceof Byte) {
+ writeByte((Byte) value);
+ }
+ else if (value instanceof Short) {
+ writeShort((Short) value);
+ }
+ else if (value instanceof Integer) {
+ writeInt((Integer) value);
+ }
+ else if (value instanceof Long) {
+ writeLong((Long) value);
+ }
+ else if (value instanceof Float) {
+ writeFloat((Float) value);
+ }
+ else if (value instanceof Double) {
+ writeDouble((Double) value);
+ }
+ else if (value instanceof byte[]) {
+ writeBytes((byte[]) value);
+ }
+ else if (value instanceof Character) {
+ writeChar((Character) value);
+ }
+ else if (value == null) {
+ writeString(null);
+ }
+ else {
+ throw new MessageFormatException("Invalid object type: " + value.getClass());
+ }
+ }
+
+ @Override
+ public void reset() throws JMSException {
+ getWriteBodyBuffer().resetReaderIndex();
+ }
+
+ // ActiveMQRAMessage overrides ----------------------------------------
+
+ @Override
+ public void clearBody() throws JMSException {
+ super.clearBody();
+
+ getWriteBodyBuffer().clear();
+ }
+
+ @Override
+ public void decode() throws Exception {
+ super.decode();
+ }
+
+ /**
+ * Encode the body into the internal message
+ */
+ @Override
+ public void encode() throws Exception {
+ super.encode();
+ bodyLength = message.getEndOfBodyPosition();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSTextMessage.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSTextMessage.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSTextMessage.java
new file mode 100644
index 0000000..5178dc2
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/jms/ServerJMSTextMessage.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter.jms;
+
+import javax.jms.JMSException;
+import javax.jms.TextMessage;
+
+import org.apache.activemq.artemis.api.core.Message;
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.core.message.impl.MessageInternal;
+
+import static org.apache.activemq.artemis.reader.TextMessageUtil.readBodyText;
+import static org.apache.activemq.artemis.reader.TextMessageUtil.writeBodyText;
+
+/**
+ * ActiveMQ Artemis implementation of a JMS TextMessage.
+ * <br>
+ * This class was ported from SpyTextMessage in JBossMQ.
+ */
+public class ServerJMSTextMessage extends ServerJMSMessage implements TextMessage {
+ // Constants -----------------------------------------------------
+
+ public static final byte TYPE = Message.TEXT_TYPE;
+
+ // Attributes ----------------------------------------------------
+
+ // We cache it locally - it's more performant to cache as a SimpleString, the AbstractChannelBuffer write
+ // methods are more efficient for a SimpleString
+ private SimpleString text;
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ /*
+ * This constructor is used to construct messages prior to sending
+ */
+ public ServerJMSTextMessage(MessageInternal message, int deliveryCount) {
+ super(message, deliveryCount);
+
+ }
+ // TextMessage implementation ------------------------------------
+
+ @Override
+ public void setText(final String text) throws JMSException {
+ if (text != null) {
+ this.text = new SimpleString(text);
+ }
+ else {
+ this.text = null;
+ }
+
+ writeBodyText(getWriteBodyBuffer(), this.text);
+ }
+
+ @Override
+ public String getText() {
+ if (text != null) {
+ return text.toString();
+ }
+ else {
+ return null;
+ }
+ }
+
+ @Override
+ public void clearBody() throws JMSException {
+ super.clearBody();
+
+ text = null;
+ }
+
+ @Override
+ public void encode() throws Exception {
+ super.encode();
+ writeBodyText(getWriteBodyBuffer(), text);
+ }
+
+ @Override
+ public void decode() throws Exception {
+ super.decode();
+ text = readBodyText(getReadBodyBuffer());
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/AMQPMessageIdHelper.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/AMQPMessageIdHelper.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/AMQPMessageIdHelper.java
new file mode 100644
index 0000000..9e172fa
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/AMQPMessageIdHelper.java
@@ -0,0 +1,257 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter.message;
+
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPIllegalStateException;
+import org.apache.qpid.proton.amqp.Binary;
+import org.apache.qpid.proton.amqp.UnsignedLong;
+
+import java.nio.ByteBuffer;
+import java.util.UUID;
+
+/**
+ * Helper class for identifying and converting message-id and correlation-id values between
+ * the AMQP types and the Strings values used by JMS.
+ * <p>
+ * <p>AMQP messages allow for 4 types of message-id/correlation-id: message-id-string, message-id-binary,
+ * message-id-uuid, or message-id-ulong. In order to accept or return a string representation of these
+ * for interoperability with other AMQP clients, the following encoding can be used after removing or
+ * before adding the "ID:" prefix used for a JMSMessageID value:<br>
+ * <p>
+ * {@literal "AMQP_BINARY:<hex representation of binary content>"}<br>
+ * {@literal "AMQP_UUID:<string representation of uuid>"}<br>
+ * {@literal "AMQP_ULONG:<string representation of ulong>"}<br>
+ * {@literal "AMQP_STRING:<string>"}<br>
+ * <p>
+ * <p>The AMQP_STRING encoding exists only for escaping message-id-string values that happen to begin
+ * with one of the encoding prefixes (including AMQP_STRING itself). It MUST NOT be used otherwise.
+ * <p>
+ * <p>When provided a string for conversion which attempts to identify itself as an encoded binary, uuid, or
+ * ulong but can't be converted into the indicated format, an exception will be thrown.
+ */
+public class AMQPMessageIdHelper {
+
+ public static final AMQPMessageIdHelper INSTANCE = new AMQPMessageIdHelper();
+
+ public static final String AMQP_STRING_PREFIX = "AMQP_STRING:";
+ public static final String AMQP_UUID_PREFIX = "AMQP_UUID:";
+ public static final String AMQP_ULONG_PREFIX = "AMQP_ULONG:";
+ public static final String AMQP_BINARY_PREFIX = "AMQP_BINARY:";
+
+ private static final int AMQP_UUID_PREFIX_LENGTH = AMQP_UUID_PREFIX.length();
+ private static final int AMQP_ULONG_PREFIX_LENGTH = AMQP_ULONG_PREFIX.length();
+ private static final int AMQP_STRING_PREFIX_LENGTH = AMQP_STRING_PREFIX.length();
+ private static final int AMQP_BINARY_PREFIX_LENGTH = AMQP_BINARY_PREFIX.length();
+ private static final char[] HEX_CHARS = "0123456789ABCDEF".toCharArray();
+
+ /**
+ * Takes the provided AMQP messageId style object, and convert it to a base string.
+ * Encodes type information as a prefix where necessary to convey or escape the type
+ * of the provided object.
+ *
+ * @param messageId the raw messageId object to process
+ * @return the base string to be used in creating the actual id.
+ */
+ public String toBaseMessageIdString(Object messageId) {
+ if (messageId == null) {
+ return null;
+ }
+ else if (messageId instanceof String) {
+ String stringId = (String) messageId;
+
+ // If the given string has a type encoding prefix,
+ // we need to escape it as an encoded string (even if
+ // the existing encoding prefix was also for string)
+ if (hasTypeEncodingPrefix(stringId)) {
+ return AMQP_STRING_PREFIX + stringId;
+ }
+ else {
+ return stringId;
+ }
+ }
+ else if (messageId instanceof UUID) {
+ return AMQP_UUID_PREFIX + messageId.toString();
+ }
+ else if (messageId instanceof UnsignedLong) {
+ return AMQP_ULONG_PREFIX + messageId.toString();
+ }
+ else if (messageId instanceof Binary) {
+ ByteBuffer dup = ((Binary) messageId).asByteBuffer();
+
+ byte[] bytes = new byte[dup.remaining()];
+ dup.get(bytes);
+
+ String hex = convertBinaryToHexString(bytes);
+
+ return AMQP_BINARY_PREFIX + hex;
+ }
+ else {
+ throw new IllegalArgumentException("Unsupported type provided: " + messageId.getClass());
+ }
+ }
+
+ /**
+ * Takes the provided base id string and return the appropriate amqp messageId style object.
+ * Converts the type based on any relevant encoding information found as a prefix.
+ *
+ * @param baseId the object to be converted to an AMQP MessageId value.
+ * @return the AMQP messageId style object
+ * @throws ActiveMQAMQPIllegalStateException if the provided baseId String indicates an encoded type but can't be converted to that type.
+ */
+ public Object toIdObject(String baseId) throws ActiveMQAMQPIllegalStateException {
+ if (baseId == null) {
+ return null;
+ }
+
+ try {
+ if (hasAmqpUuidPrefix(baseId)) {
+ String uuidString = strip(baseId, AMQP_UUID_PREFIX_LENGTH);
+ return UUID.fromString(uuidString);
+ }
+ else if (hasAmqpUlongPrefix(baseId)) {
+ String longString = strip(baseId, AMQP_ULONG_PREFIX_LENGTH);
+ return UnsignedLong.valueOf(longString);
+ }
+ else if (hasAmqpStringPrefix(baseId)) {
+ return strip(baseId, AMQP_STRING_PREFIX_LENGTH);
+ }
+ else if (hasAmqpBinaryPrefix(baseId)) {
+ String hexString = strip(baseId, AMQP_BINARY_PREFIX_LENGTH);
+ byte[] bytes = convertHexStringToBinary(hexString);
+ return new Binary(bytes);
+ }
+ else {
+ // We have a string without any type prefix, transmit it as-is.
+ return baseId;
+ }
+ }
+ catch (IllegalArgumentException e) {
+ throw new ActiveMQAMQPIllegalStateException("Unable to convert ID value");
+ }
+ }
+
+ /**
+ * Convert the provided hex-string into a binary representation where each byte represents
+ * two characters of the hex string.
+ * <p>
+ * The hex characters may be upper or lower case.
+ *
+ * @param hexString string to convert to a binary value.
+ * @return a byte array containing the binary representation
+ * @throws IllegalArgumentException if the provided String is a non-even length or contains
+ * non-hex characters
+ */
+ public byte[] convertHexStringToBinary(String hexString) throws IllegalArgumentException {
+ int length = hexString.length();
+
+ // As each byte needs two characters in the hex encoding, the string must be an even length.
+ if (length % 2 != 0) {
+ throw new IllegalArgumentException("The provided hex String must be an even length, but was of length " + length + ": " + hexString);
+ }
+
+ byte[] binary = new byte[length / 2];
+
+ for (int i = 0; i < length; i += 2) {
+ char highBitsChar = hexString.charAt(i);
+ char lowBitsChar = hexString.charAt(i + 1);
+
+ int highBits = hexCharToInt(highBitsChar, hexString) << 4;
+ int lowBits = hexCharToInt(lowBitsChar, hexString);
+
+ binary[i / 2] = (byte) (highBits + lowBits);
+ }
+
+ return binary;
+ }
+
+ /**
+ * Convert the provided binary into a hex-string representation where each character
+ * represents 4 bits of the provided binary, i.e each byte requires two characters.
+ * <p>
+ * The returned hex characters are upper-case.
+ *
+ * @param bytes the binary value to convert to a hex String instance.
+ * @return a String containing a hex representation of the bytes
+ */
+ public String convertBinaryToHexString(byte[] bytes) {
+ // Each byte is represented as 2 chars
+ StringBuilder builder = new StringBuilder(bytes.length * 2);
+
+ for (byte b : bytes) {
+ // The byte will be expanded to int before shifting, replicating the
+ // sign bit, so mask everything beyond the first 4 bits afterwards
+ int highBitsInt = (b >> 4) & 0xF;
+ // We only want the first 4 bits
+ int lowBitsInt = b & 0xF;
+
+ builder.append(HEX_CHARS[highBitsInt]);
+ builder.append(HEX_CHARS[lowBitsInt]);
+ }
+
+ return builder.toString();
+ }
+
+ //----- Internal implementation ------------------------------------------//
+
+ private boolean hasTypeEncodingPrefix(String stringId) {
+ return hasAmqpBinaryPrefix(stringId) || hasAmqpUuidPrefix(stringId) ||
+ hasAmqpUlongPrefix(stringId) || hasAmqpStringPrefix(stringId);
+ }
+
+ private boolean hasAmqpStringPrefix(String stringId) {
+ return stringId.startsWith(AMQP_STRING_PREFIX);
+ }
+
+ private boolean hasAmqpUlongPrefix(String stringId) {
+ return stringId.startsWith(AMQP_ULONG_PREFIX);
+ }
+
+ private boolean hasAmqpUuidPrefix(String stringId) {
+ return stringId.startsWith(AMQP_UUID_PREFIX);
+ }
+
+ private boolean hasAmqpBinaryPrefix(String stringId) {
+ return stringId.startsWith(AMQP_BINARY_PREFIX);
+ }
+
+ private String strip(String id, int numChars) {
+ return id.substring(numChars);
+ }
+
+ private int hexCharToInt(char ch, String orig) throws IllegalArgumentException {
+ if (ch >= '0' && ch <= '9') {
+ // subtract '0' to get difference in position as an int
+ return ch - '0';
+ }
+ else if (ch >= 'A' && ch <= 'F') {
+ // subtract 'A' to get difference in position as an int
+ // and then add 10 for the offset of 'A'
+ return ch - 'A' + 10;
+ }
+ else if (ch >= 'a' && ch <= 'f') {
+ // subtract 'a' to get difference in position as an int
+ // and then add 10 for the offset of 'a'
+ return ch - 'a' + 10;
+ }
+
+ throw new IllegalArgumentException("The provided hex string contains non-hex character '" + ch + "': " + orig);
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/AMQPMessageTypes.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/AMQPMessageTypes.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/AMQPMessageTypes.java
new file mode 100644
index 0000000..613de6d
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/AMQPMessageTypes.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter.message;
+
+public class AMQPMessageTypes {
+ public static final String AMQP_TYPE_KEY = "amqp:type";
+
+ public static final String AMQP_SEQUENCE = "amqp:sequence";
+
+ public static final String AMQP_LIST = "amqp:list";
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/AMQPNativeInboundTransformer.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/AMQPNativeInboundTransformer.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/AMQPNativeInboundTransformer.java
new file mode 100644
index 0000000..8a5d17c
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/AMQPNativeInboundTransformer.java
@@ -0,0 +1,46 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter.message;
+
+import javax.jms.Message;
+
+public class AMQPNativeInboundTransformer extends AMQPRawInboundTransformer {
+
+ public AMQPNativeInboundTransformer(JMSVendor vendor) {
+ super(vendor);
+ }
+
+ @Override
+ public String getTransformerName() {
+ return TRANSFORMER_NATIVE;
+ }
+
+ @Override
+ public InboundTransformer getFallbackTransformer() {
+ return new AMQPRawInboundTransformer(getVendor());
+ }
+
+ @Override
+ public Message transform(EncodedMessage amqpMessage) throws Exception {
+ org.apache.qpid.proton.message.Message amqp = amqpMessage.decode();
+
+ Message rc = super.transform(amqpMessage);
+
+ populateMessage(rc, amqp);
+ return rc;
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/AMQPNativeOutboundTransformer.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/AMQPNativeOutboundTransformer.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/AMQPNativeOutboundTransformer.java
new file mode 100644
index 0000000..67175ab
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/AMQPNativeOutboundTransformer.java
@@ -0,0 +1,60 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter.message;
+
+import org.apache.qpid.proton.amqp.UnsignedInteger;
+import org.apache.qpid.proton.amqp.messaging.Header;
+import org.apache.qpid.proton.message.ProtonJMessage;
+
+import javax.jms.BytesMessage;
+import javax.jms.JMSException;
+
+public class AMQPNativeOutboundTransformer extends OutboundTransformer {
+
+ public AMQPNativeOutboundTransformer(JMSVendor vendor) {
+ super(vendor);
+ }
+
+ public static ProtonJMessage transform(OutboundTransformer options, BytesMessage msg) throws JMSException {
+ byte[] data = new byte[(int) msg.getBodyLength()];
+ msg.readBytes(data);
+ msg.reset();
+ int count = msg.getIntProperty("JMSXDeliveryCount");
+
+ // decode...
+ ProtonJMessage amqp = (ProtonJMessage) org.apache.qpid.proton.message.Message.Factory.create();
+ int offset = 0;
+ int len = data.length;
+ while (len > 0) {
+ final int decoded = amqp.decode(data, offset, len);
+ assert decoded > 0 : "Make progress decoding the message";
+ offset += decoded;
+ len -= decoded;
+ }
+
+ // Update the DeliveryCount header...
+ // The AMQP delivery-count field only includes prior failed delivery attempts,
+ // whereas JMSXDeliveryCount includes the first/current delivery attempt. Subtract 1.
+ if (amqp.getHeader() == null) {
+ amqp.setHeader(new Header());
+ }
+
+ amqp.getHeader().setDeliveryCount(new UnsignedInteger(count - 1));
+
+ return amqp;
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/AMQPRawInboundTransformer.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/AMQPRawInboundTransformer.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/AMQPRawInboundTransformer.java
new file mode 100644
index 0000000..e6bf171
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/AMQPRawInboundTransformer.java
@@ -0,0 +1,60 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter.message;
+
+import javax.jms.BytesMessage;
+import javax.jms.DeliveryMode;
+import javax.jms.Message;
+
+public class AMQPRawInboundTransformer extends InboundTransformer {
+
+ public AMQPRawInboundTransformer(JMSVendor vendor) {
+ super(vendor);
+ }
+
+ @Override
+ public String getTransformerName() {
+ return TRANSFORMER_RAW;
+ }
+
+ @Override
+ public InboundTransformer getFallbackTransformer() {
+ return null; // No fallback from full raw transform
+ }
+
+ @Override
+ public Message transform(EncodedMessage amqpMessage) throws Exception {
+ BytesMessage rc = vendor.createBytesMessage();
+ rc.writeBytes(amqpMessage.getArray(), amqpMessage.getArrayOffset(), amqpMessage.getLength());
+
+ // We cannot decode the message headers to check so err on the side of caution
+ // and mark all messages as persistent.
+ rc.setJMSDeliveryMode(DeliveryMode.PERSISTENT);
+ rc.setJMSPriority(defaultPriority);
+
+ final long now = System.currentTimeMillis();
+ rc.setJMSTimestamp(now);
+ if (defaultTtl > 0) {
+ rc.setJMSExpiration(now + defaultTtl);
+ }
+
+ rc.setLongProperty(prefixVendor + "MESSAGE_FORMAT", amqpMessage.getMessageFormat());
+ rc.setBooleanProperty(prefixVendor + "NATIVE", true);
+
+ return rc;
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/EncodedMessage.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/EncodedMessage.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/EncodedMessage.java
new file mode 100644
index 0000000..4a80ea6
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/EncodedMessage.java
@@ -0,0 +1,67 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter.message;
+
+import org.apache.qpid.proton.amqp.Binary;
+import org.apache.qpid.proton.message.Message;
+
+public class EncodedMessage {
+
+ private final Binary data;
+ final long messageFormat;
+
+ public EncodedMessage(long messageFormat, byte[] data, int offset, int length) {
+ this.data = new Binary(data, offset, length);
+ this.messageFormat = messageFormat;
+ }
+
+ public long getMessageFormat() {
+ return messageFormat;
+ }
+
+ public Message decode() throws Exception {
+ Message amqp = Message.Factory.create();
+
+ int offset = getArrayOffset();
+ int len = getLength();
+ while (len > 0) {
+ final int decoded = amqp.decode(getArray(), offset, len);
+ assert decoded > 0 : "Make progress decoding the message";
+ offset += decoded;
+ len -= decoded;
+ }
+
+ return amqp;
+ }
+
+ public int getLength() {
+ return data.getLength();
+ }
+
+ public int getArrayOffset() {
+ return data.getArrayOffset();
+ }
+
+ public byte[] getArray() {
+ return data.getArray();
+ }
+
+ @Override
+ public String toString() {
+ return data.toString();
+ }
+}
[10/15] activemq-artemis git commit: ARTEMIS-751 Simplification of
the AMQP implementation
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/InboundTransformer.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/InboundTransformer.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/InboundTransformer.java
new file mode 100644
index 0000000..55195eb
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/InboundTransformer.java
@@ -0,0 +1,318 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter.message;
+
+import org.apache.qpid.proton.amqp.Binary;
+import org.apache.qpid.proton.amqp.Decimal128;
+import org.apache.qpid.proton.amqp.Decimal32;
+import org.apache.qpid.proton.amqp.Decimal64;
+import org.apache.qpid.proton.amqp.Symbol;
+import org.apache.qpid.proton.amqp.UnsignedByte;
+import org.apache.qpid.proton.amqp.UnsignedInteger;
+import org.apache.qpid.proton.amqp.UnsignedLong;
+import org.apache.qpid.proton.amqp.UnsignedShort;
+import org.apache.qpid.proton.amqp.messaging.ApplicationProperties;
+import org.apache.qpid.proton.amqp.messaging.Footer;
+import org.apache.qpid.proton.amqp.messaging.Header;
+import org.apache.qpid.proton.amqp.messaging.MessageAnnotations;
+import org.apache.qpid.proton.amqp.messaging.Properties;
+
+import javax.jms.DeliveryMode;
+import javax.jms.JMSException;
+import javax.jms.Message;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Set;
+
+import static org.apache.activemq.artemis.api.core.Message.HDR_SCHEDULED_DELIVERY_TIME;
+
+public abstract class InboundTransformer {
+
+ JMSVendor vendor;
+
+ public static final String TRANSFORMER_NATIVE = "native";
+ public static final String TRANSFORMER_RAW = "raw";
+ public static final String TRANSFORMER_JMS = "jms";
+
+ String prefixVendor = "JMS_AMQP_";
+ String prefixDeliveryAnnotations = "DA_";
+ String prefixMessageAnnotations = "MA_";
+ String prefixFooter = "FT_";
+
+ int defaultDeliveryMode = DeliveryMode.NON_PERSISTENT;
+ int defaultPriority = Message.DEFAULT_PRIORITY;
+ long defaultTtl = Message.DEFAULT_TIME_TO_LIVE;
+
+ public InboundTransformer(JMSVendor vendor) {
+ this.vendor = vendor;
+ }
+
+ public abstract Message transform(EncodedMessage amqpMessage) throws Exception;
+
+ public abstract String getTransformerName();
+
+ public abstract InboundTransformer getFallbackTransformer();
+
+ public int getDefaultDeliveryMode() {
+ return defaultDeliveryMode;
+ }
+
+ public void setDefaultDeliveryMode(int defaultDeliveryMode) {
+ this.defaultDeliveryMode = defaultDeliveryMode;
+ }
+
+ public int getDefaultPriority() {
+ return defaultPriority;
+ }
+
+ public void setDefaultPriority(int defaultPriority) {
+ this.defaultPriority = defaultPriority;
+ }
+
+ public long getDefaultTtl() {
+ return defaultTtl;
+ }
+
+ public void setDefaultTtl(long defaultTtl) {
+ this.defaultTtl = defaultTtl;
+ }
+
+ public String getPrefixVendor() {
+ return prefixVendor;
+ }
+
+ public void setPrefixVendor(String prefixVendor) {
+ this.prefixVendor = prefixVendor;
+ }
+
+ public JMSVendor getVendor() {
+ return vendor;
+ }
+
+ public void setVendor(JMSVendor vendor) {
+ this.vendor = vendor;
+ }
+
+ protected void populateMessage(Message jms, org.apache.qpid.proton.message.Message amqp) throws Exception {
+ Header header = amqp.getHeader();
+ if (header == null) {
+ header = new Header();
+ }
+
+ if (header.getDurable() != null) {
+ jms.setJMSDeliveryMode(header.getDurable().booleanValue() ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+ }
+ else {
+ jms.setJMSDeliveryMode(defaultDeliveryMode);
+ }
+
+ if (header.getPriority() != null) {
+ jms.setJMSPriority(header.getPriority().intValue());
+ }
+ else {
+ jms.setJMSPriority(defaultPriority);
+ }
+
+ if (header.getFirstAcquirer() != null) {
+ jms.setBooleanProperty(prefixVendor + "FirstAcquirer", header.getFirstAcquirer());
+ }
+
+ if (header.getDeliveryCount() != null) {
+ vendor.setJMSXDeliveryCount(jms, header.getDeliveryCount().longValue());
+ }
+
+ final MessageAnnotations ma = amqp.getMessageAnnotations();
+ if (ma != null) {
+ for (Map.Entry<?, ?> entry : ma.getValue().entrySet()) {
+ String key = entry.getKey().toString();
+ if ("x-opt-jms-type".equals(key) && entry.getValue() != null) {
+ // Legacy annotation, JMSType value will be replaced by Subject further down if also present.
+ jms.setJMSType(entry.getValue().toString());
+ }
+ else if ("x-opt-delivery-time".equals(key) && entry.getValue() != null) {
+ long deliveryTime = ((Number) entry.getValue()).longValue();
+ jms.setLongProperty(HDR_SCHEDULED_DELIVERY_TIME.toString(), deliveryTime);
+ }
+ else if ("x-opt-delivery-delay".equals(key) && entry.getValue() != null) {
+ long delay = ((Number) entry.getValue()).longValue();
+ if (delay > 0) {
+ jms.setLongProperty(HDR_SCHEDULED_DELIVERY_TIME.toString(), System.currentTimeMillis() + delay);
+ }
+ }
+ //todo
+ /*else if ("x-opt-delivery-repeat".equals(key) && entry.getValue() != null) {
+ int repeat = ((Number) entry.getValue()).intValue();
+ if (repeat > 0) {
+ jms.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, repeat);
+ }
+ } else if ("x-opt-delivery-period".equals(key) && entry.getValue() != null) {
+ long period = ((Number) entry.getValue()).longValue();
+ if (period > 0) {
+ jms.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, period);
+ }
+ } else if ("x-opt-delivery-cron".equals(key) && entry.getValue() != null) {
+ String cronEntry = (String) entry.getValue();
+ if (cronEntry != null) {
+ jms.setStringProperty(ScheduledMessage.AMQ_SCHEDULED_CRON, cronEntry);
+ }
+ }*/
+
+ setProperty(jms, prefixVendor + prefixMessageAnnotations + key, entry.getValue());
+ }
+ }
+
+ final ApplicationProperties ap = amqp.getApplicationProperties();
+ if (ap != null) {
+ for (Map.Entry<Object, Object> entry : (Set<Map.Entry<Object, Object>>) ap.getValue().entrySet()) {
+ String key = entry.getKey().toString();
+ if ("JMSXGroupID".equals(key)) {
+ vendor.setJMSXGroupID(jms, entry.getValue().toString());
+ }
+ else if ("JMSXGroupSequence".equals(key)) {
+ vendor.setJMSXGroupSequence(jms, ((Number) entry.getValue()).intValue());
+ }
+ else if ("JMSXUserID".equals(key)) {
+ vendor.setJMSXUserID(jms, entry.getValue().toString());
+ }
+ else {
+ setProperty(jms, key, entry.getValue());
+ }
+ }
+ }
+
+ final Properties properties = amqp.getProperties();
+ if (properties != null) {
+ if (properties.getMessageId() != null) {
+ jms.setJMSMessageID(AMQPMessageIdHelper.INSTANCE.toBaseMessageIdString(properties.getMessageId()));
+ }
+ Binary userId = properties.getUserId();
+ if (userId != null) {
+ vendor.setJMSXUserID(jms, new String(userId.getArray(), userId.getArrayOffset(), userId.getLength(), StandardCharsets.UTF_8));
+ }
+ if (properties.getTo() != null) {
+ jms.setJMSDestination(vendor.createDestination(properties.getTo()));
+ }
+ if (properties.getSubject() != null) {
+ jms.setJMSType(properties.getSubject());
+ }
+ if (properties.getReplyTo() != null) {
+ jms.setJMSReplyTo(vendor.createDestination(properties.getReplyTo()));
+ }
+ if (properties.getCorrelationId() != null) {
+ jms.setJMSCorrelationID(AMQPMessageIdHelper.INSTANCE.toBaseMessageIdString(properties.getCorrelationId()));
+ }
+ if (properties.getContentType() != null) {
+ jms.setStringProperty(prefixVendor + "ContentType", properties.getContentType().toString());
+ }
+ if (properties.getContentEncoding() != null) {
+ jms.setStringProperty(prefixVendor + "ContentEncoding", properties.getContentEncoding().toString());
+ }
+ if (properties.getCreationTime() != null) {
+ jms.setJMSTimestamp(properties.getCreationTime().getTime());
+ }
+ if (properties.getGroupId() != null) {
+ vendor.setJMSXGroupID(jms, properties.getGroupId());
+ }
+ if (properties.getGroupSequence() != null) {
+ vendor.setJMSXGroupSequence(jms, properties.getGroupSequence().intValue());
+ }
+ if (properties.getReplyToGroupId() != null) {
+ jms.setStringProperty(prefixVendor + "ReplyToGroupID", properties.getReplyToGroupId());
+ }
+ if (properties.getAbsoluteExpiryTime() != null) {
+ jms.setJMSExpiration(properties.getAbsoluteExpiryTime().getTime());
+ }
+ }
+
+ // If the jms expiration has not yet been set...
+ if (jms.getJMSExpiration() == 0) {
+ // Then lets try to set it based on the message ttl.
+ long ttl = defaultTtl;
+ if (header.getTtl() != null) {
+ ttl = header.getTtl().longValue();
+ }
+
+ if (ttl == 0) {
+ jms.setJMSExpiration(0);
+ }
+ else {
+ jms.setJMSExpiration(System.currentTimeMillis() + ttl);
+ }
+ }
+
+ final Footer fp = amqp.getFooter();
+ if (fp != null) {
+ for (Map.Entry<Object, Object> entry : (Set<Map.Entry<Object, Object>>) fp.getValue().entrySet()) {
+ String key = entry.getKey().toString();
+ setProperty(jms, prefixVendor + prefixFooter + key, entry.getValue());
+ }
+ }
+ }
+
+ private void setProperty(Message msg, String key, Object value) throws JMSException {
+ if (value instanceof UnsignedLong) {
+ long v = ((UnsignedLong) value).longValue();
+ msg.setLongProperty(key, v);
+ }
+ else if (value instanceof UnsignedInteger) {
+ long v = ((UnsignedInteger) value).longValue();
+ if (Integer.MIN_VALUE <= v && v <= Integer.MAX_VALUE) {
+ msg.setIntProperty(key, (int) v);
+ }
+ else {
+ msg.setLongProperty(key, v);
+ }
+ }
+ else if (value instanceof UnsignedShort) {
+ int v = ((UnsignedShort) value).intValue();
+ if (Short.MIN_VALUE <= v && v <= Short.MAX_VALUE) {
+ msg.setShortProperty(key, (short) v);
+ }
+ else {
+ msg.setIntProperty(key, v);
+ }
+ }
+ else if (value instanceof UnsignedByte) {
+ short v = ((UnsignedByte) value).shortValue();
+ if (Byte.MIN_VALUE <= v && v <= Byte.MAX_VALUE) {
+ msg.setByteProperty(key, (byte) v);
+ }
+ else {
+ msg.setShortProperty(key, v);
+ }
+ }
+ else if (value instanceof Symbol) {
+ msg.setStringProperty(key, value.toString());
+ }
+ else if (value instanceof Decimal128) {
+ msg.setDoubleProperty(key, ((Decimal128) value).doubleValue());
+ }
+ else if (value instanceof Decimal64) {
+ msg.setDoubleProperty(key, ((Decimal64) value).doubleValue());
+ }
+ else if (value instanceof Decimal32) {
+ msg.setFloatProperty(key, ((Decimal32) value).floatValue());
+ }
+ else if (value instanceof Binary) {
+ msg.setStringProperty(key, value.toString());
+ }
+ else {
+ msg.setObjectProperty(key, value);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/JMSMappingInboundTransformer.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/JMSMappingInboundTransformer.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/JMSMappingInboundTransformer.java
new file mode 100644
index 0000000..2bcbfe2
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/JMSMappingInboundTransformer.java
@@ -0,0 +1,128 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter.message;
+
+import org.apache.qpid.proton.amqp.Binary;
+import org.apache.qpid.proton.amqp.messaging.AmqpSequence;
+import org.apache.qpid.proton.amqp.messaging.AmqpValue;
+import org.apache.qpid.proton.amqp.messaging.Data;
+import org.apache.qpid.proton.amqp.messaging.Section;
+
+import javax.jms.BytesMessage;
+import javax.jms.MapMessage;
+import javax.jms.Message;
+import javax.jms.ObjectMessage;
+import javax.jms.StreamMessage;
+import javax.jms.TextMessage;
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class JMSMappingInboundTransformer extends InboundTransformer {
+
+ public JMSMappingInboundTransformer(JMSVendor vendor) {
+ super(vendor);
+ }
+
+ @Override
+ public String getTransformerName() {
+ return TRANSFORMER_JMS;
+ }
+
+ @Override
+ public InboundTransformer getFallbackTransformer() {
+ return new AMQPNativeInboundTransformer(getVendor());
+ }
+
+ @SuppressWarnings({"unchecked"})
+ @Override
+ public Message transform(EncodedMessage amqpMessage) throws Exception {
+ org.apache.qpid.proton.message.Message amqp = amqpMessage.decode();
+
+ Message rc;
+ final Section body = amqp.getBody();
+ if (body == null) {
+ rc = vendor.createMessage();
+ }
+ else if (body instanceof Data) {
+ Binary d = ((Data) body).getValue();
+ BytesMessage m = vendor.createBytesMessage();
+ m.writeBytes(d.getArray(), d.getArrayOffset(), d.getLength());
+ rc = m;
+ }
+ else if (body instanceof AmqpSequence) {
+ AmqpSequence sequence = (AmqpSequence) body;
+ StreamMessage m = vendor.createStreamMessage();
+ for (Object item : sequence.getValue()) {
+ m.writeObject(item);
+ }
+ rc = m;
+ m.setStringProperty(AMQPMessageTypes.AMQP_TYPE_KEY, AMQPMessageTypes.AMQP_SEQUENCE);
+ }
+ else if (body instanceof AmqpValue) {
+ Object value = ((AmqpValue) body).getValue();
+ if (value == null) {
+ rc = vendor.createObjectMessage();
+ }
+ if (value instanceof String) {
+ TextMessage m = vendor.createTextMessage();
+ m.setText((String) value);
+ rc = m;
+ }
+ else if (value instanceof Binary) {
+ Binary d = (Binary) value;
+ BytesMessage m = vendor.createBytesMessage();
+ m.writeBytes(d.getArray(), d.getArrayOffset(), d.getLength());
+ rc = m;
+ }
+ else if (value instanceof List) {
+ StreamMessage m = vendor.createStreamMessage();
+ for (Object item : (List<Object>) value) {
+ m.writeObject(item);
+ }
+ rc = m;
+ m.setStringProperty(AMQPMessageTypes.AMQP_TYPE_KEY, AMQPMessageTypes.AMQP_LIST);
+ }
+ else if (value instanceof Map) {
+ MapMessage m = vendor.createMapMessage();
+ final Set<Map.Entry<String, Object>> set = ((Map<String, Object>) value).entrySet();
+ for (Map.Entry<String, Object> entry : set) {
+ m.setObject(entry.getKey(), entry.getValue());
+ }
+ rc = m;
+ }
+ else {
+ ObjectMessage m = vendor.createObjectMessage();
+ m.setObject((Serializable) value);
+ rc = m;
+ }
+ }
+ else {
+ throw new RuntimeException("Unexpected body type: " + body.getClass());
+ }
+ rc.setJMSDeliveryMode(defaultDeliveryMode);
+ rc.setJMSPriority(defaultPriority);
+ rc.setJMSExpiration(defaultTtl);
+
+ populateMessage(rc, amqp);
+
+ rc.setLongProperty(prefixVendor + "MESSAGE_FORMAT", amqpMessage.getMessageFormat());
+ rc.setBooleanProperty(prefixVendor + "NATIVE", false);
+ return rc;
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/JMSMappingOutboundTransformer.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/JMSMappingOutboundTransformer.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/JMSMappingOutboundTransformer.java
new file mode 100644
index 0000000..7de9408
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/JMSMappingOutboundTransformer.java
@@ -0,0 +1,365 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter.message;
+
+import org.apache.activemq.artemis.core.message.impl.MessageInternal;
+import org.apache.activemq.artemis.protocol.amqp.converter.jms.ServerJMSMessage;
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPIllegalStateException;
+import org.apache.qpid.proton.amqp.Binary;
+import org.apache.qpid.proton.amqp.Symbol;
+import org.apache.qpid.proton.amqp.UnsignedByte;
+import org.apache.qpid.proton.amqp.UnsignedInteger;
+import org.apache.qpid.proton.amqp.messaging.AmqpSequence;
+import org.apache.qpid.proton.amqp.messaging.AmqpValue;
+import org.apache.qpid.proton.amqp.messaging.ApplicationProperties;
+import org.apache.qpid.proton.amqp.messaging.Data;
+import org.apache.qpid.proton.amqp.messaging.DeliveryAnnotations;
+import org.apache.qpid.proton.amqp.messaging.Footer;
+import org.apache.qpid.proton.amqp.messaging.Header;
+import org.apache.qpid.proton.amqp.messaging.MessageAnnotations;
+import org.apache.qpid.proton.amqp.messaging.Properties;
+import org.apache.qpid.proton.amqp.messaging.Section;
+import org.apache.qpid.proton.message.ProtonJMessage;
+import org.jboss.logging.Logger;
+
+import javax.jms.BytesMessage;
+import javax.jms.DeliveryMode;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.MapMessage;
+import javax.jms.Message;
+import javax.jms.MessageEOFException;
+import javax.jms.ObjectMessage;
+import javax.jms.Queue;
+import javax.jms.StreamMessage;
+import javax.jms.TemporaryQueue;
+import javax.jms.TemporaryTopic;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+
+public class JMSMappingOutboundTransformer extends OutboundTransformer {
+ private static final Logger logger = Logger.getLogger(JMSMappingOutboundTransformer.class);
+ public static final Symbol JMS_DEST_TYPE_MSG_ANNOTATION = Symbol.valueOf("x-opt-jms-dest");
+ public static final Symbol JMS_REPLY_TO_TYPE_MSG_ANNOTATION = Symbol.valueOf("x-opt-jms-reply-to");
+
+ public static final byte QUEUE_TYPE = 0x00;
+ public static final byte TOPIC_TYPE = 0x01;
+ public static final byte TEMP_QUEUE_TYPE = 0x02;
+ public static final byte TEMP_TOPIC_TYPE = 0x03;
+
+ // Deprecated legacy values used by old QPid AMQP 1.0 JMS client.
+
+ public static final Symbol LEGACY_JMS_DEST_TYPE_MSG_ANNOTATION = Symbol.valueOf("x-opt-to-type");
+ public static final Symbol LEGACY_JMS_REPLY_TO_TYPE_MSG_ANNOTATION = Symbol.valueOf("x-opt-reply-type");
+
+ public static final String LEGACY_QUEUE_TYPE = "queue";
+ public static final String LEGACY_TOPIC_TYPE = "topic";
+ public static final String LEGACY_TEMP_QUEUE_TYPE = "temporary,queue";
+ public static final String LEGACY_TEMP_TOPIC_TYPE = "temporary,topic";
+
+ public JMSMappingOutboundTransformer(JMSVendor vendor) {
+ super(vendor);
+ }
+
+ /**
+ * Perform the conversion between JMS Message and Proton Message without
+ * re-encoding it to array. This is needed because some frameworks may elect
+ * to do this on their own way (Netty for instance using Nettybuffers)
+ *
+ * @param msg
+ * @return
+ * @throws Exception
+ */
+ public ProtonJMessage convert(Message msg) throws JMSException, UnsupportedEncodingException {
+ Header header = new Header();
+ Properties props = new Properties();
+ HashMap<Symbol, Object> daMap = null;
+ HashMap<Symbol, Object> maMap = null;
+ HashMap apMap = null;
+ Section body = null;
+ HashMap footerMap = null;
+ if (msg instanceof BytesMessage) {
+ BytesMessage m = (BytesMessage) msg;
+ byte[] data = new byte[(int) m.getBodyLength()];
+ m.readBytes(data);
+ m.reset(); // Need to reset after readBytes or future readBytes
+ // calls (ex: redeliveries) will fail and return -1
+ body = new Data(new Binary(data));
+ }
+ if (msg instanceof TextMessage) {
+ body = new AmqpValue(((TextMessage) msg).getText());
+ }
+ if (msg instanceof MapMessage) {
+ final HashMap<String, Object> map = new HashMap<>();
+ final MapMessage m = (MapMessage) msg;
+ final Enumeration<String> names = m.getMapNames();
+ while (names.hasMoreElements()) {
+ String key = names.nextElement();
+ map.put(key, m.getObject(key));
+ }
+ body = new AmqpValue(map);
+ }
+ if (msg instanceof StreamMessage) {
+ ArrayList<Object> list = new ArrayList<>();
+ final StreamMessage m = (StreamMessage) msg;
+ try {
+ while (true) {
+ list.add(m.readObject());
+ }
+ }
+ catch (MessageEOFException e) {
+ }
+
+ String amqpType = msg.getStringProperty(AMQPMessageTypes.AMQP_TYPE_KEY);
+ if (amqpType.equals(AMQPMessageTypes.AMQP_LIST)) {
+ body = new AmqpValue(list);
+ }
+ else {
+ body = new AmqpSequence(list);
+ }
+ }
+ if (msg instanceof ObjectMessage) {
+ body = new AmqpValue(((ObjectMessage) msg).getObject());
+ }
+
+ if (body == null && msg instanceof ServerJMSMessage) {
+
+ MessageInternal internalMessage = ((ServerJMSMessage) msg).getInnerMessage();
+ if (!internalMessage.containsProperty("AMQP_MESSAGE_FORMAT")) {
+ int readerIndex = internalMessage.getBodyBuffer().readerIndex();
+ try {
+ Object s = internalMessage.getBodyBuffer().readNullableSimpleString();
+ if (s != null) {
+ body = new AmqpValue(s.toString());
+ }
+ }
+ catch (Throwable ignored) {
+ logger.debug("Exception ignored during conversion, should be ok!", ignored.getMessage(), ignored);
+ }
+ finally {
+ internalMessage.getBodyBuffer().readerIndex(readerIndex);
+ }
+ }
+ }
+
+ header.setDurable(msg.getJMSDeliveryMode() == DeliveryMode.PERSISTENT ? true : false);
+ header.setPriority(new UnsignedByte((byte) msg.getJMSPriority()));
+ if (msg.getJMSType() != null) {
+ props.setSubject(msg.getJMSType());
+ }
+ if (msg.getJMSMessageID() != null) {
+
+ String msgId = msg.getJMSMessageID();
+
+ try {
+ props.setMessageId(AMQPMessageIdHelper.INSTANCE.toIdObject(msgId));
+ }
+ catch (ActiveMQAMQPIllegalStateException e) {
+ props.setMessageId(msgId);
+ }
+ }
+ if (msg.getJMSDestination() != null) {
+ props.setTo(vendor.toAddress(msg.getJMSDestination()));
+ if (maMap == null) {
+ maMap = new HashMap<>();
+ }
+ maMap.put(JMS_DEST_TYPE_MSG_ANNOTATION, destinationType(msg.getJMSDestination()));
+
+ // Deprecated: used by legacy QPid AMQP 1.0 JMS client
+ maMap.put(LEGACY_JMS_DEST_TYPE_MSG_ANNOTATION, destinationAttributes(msg.getJMSDestination()));
+ }
+ if (msg.getJMSReplyTo() != null) {
+ props.setReplyTo(vendor.toAddress(msg.getJMSReplyTo()));
+ if (maMap == null) {
+ maMap = new HashMap<>();
+ }
+ maMap.put(JMS_REPLY_TO_TYPE_MSG_ANNOTATION, destinationType(msg.getJMSReplyTo()));
+
+ // Deprecated: used by legacy QPid AMQP 1.0 JMS client
+ maMap.put(LEGACY_JMS_REPLY_TO_TYPE_MSG_ANNOTATION, destinationAttributes(msg.getJMSReplyTo()));
+ }
+ if (msg.getJMSCorrelationID() != null) {
+ String correlationId = msg.getJMSCorrelationID();
+
+ try {
+ props.setCorrelationId(AMQPMessageIdHelper.INSTANCE.toIdObject(correlationId));
+ }
+ catch (ActiveMQAMQPIllegalStateException e) {
+ props.setCorrelationId(correlationId);
+ }
+ }
+ if (msg.getJMSExpiration() != 0) {
+ long ttl = msg.getJMSExpiration() - System.currentTimeMillis();
+ if (ttl < 0) {
+ ttl = 1;
+ }
+ header.setTtl(new UnsignedInteger((int) ttl));
+
+ props.setAbsoluteExpiryTime(new Date(msg.getJMSExpiration()));
+ }
+ if (msg.getJMSTimestamp() != 0) {
+ props.setCreationTime(new Date(msg.getJMSTimestamp()));
+ }
+
+ final Enumeration<String> keys = msg.getPropertyNames();
+ while (keys.hasMoreElements()) {
+ String key = keys.nextElement();
+ if (key.equals(messageFormatKey) || key.equals(nativeKey) || key.equals(ServerJMSMessage.NATIVE_MESSAGE_ID)) {
+ // skip..
+ }
+ else if (key.equals(firstAcquirerKey)) {
+ header.setFirstAcquirer(msg.getBooleanProperty(key));
+ }
+ else if (key.startsWith("JMSXDeliveryCount")) {
+ // The AMQP delivery-count field only includes prior failed delivery attempts,
+ // whereas JMSXDeliveryCount includes the first/current delivery attempt.
+ int amqpDeliveryCount = msg.getIntProperty(key) - 1;
+ if (amqpDeliveryCount > 0) {
+ header.setDeliveryCount(new UnsignedInteger(amqpDeliveryCount));
+ }
+ }
+ else if (key.startsWith("JMSXUserID")) {
+ String value = msg.getStringProperty(key);
+ props.setUserId(new Binary(value.getBytes(StandardCharsets.UTF_8)));
+ }
+ else if (key.startsWith("JMSXGroupID") || key.startsWith("_AMQ_GROUP_ID")) {
+ String value = msg.getStringProperty(key);
+ props.setGroupId(value);
+ if (apMap == null) {
+ apMap = new HashMap();
+ }
+ apMap.put(key, value);
+ }
+ else if (key.startsWith("JMSXGroupSeq")) {
+ UnsignedInteger value = new UnsignedInteger(msg.getIntProperty(key));
+ props.setGroupSequence(value);
+ if (apMap == null) {
+ apMap = new HashMap();
+ }
+ apMap.put(key, value);
+ }
+ else if (key.startsWith(prefixDeliveryAnnotationsKey)) {
+ if (daMap == null) {
+ daMap = new HashMap<>();
+ }
+ String name = key.substring(prefixDeliveryAnnotationsKey.length());
+ daMap.put(Symbol.valueOf(name), msg.getObjectProperty(key));
+ }
+ else if (key.startsWith(prefixMessageAnnotationsKey)) {
+ if (maMap == null) {
+ maMap = new HashMap<>();
+ }
+ String name = key.substring(prefixMessageAnnotationsKey.length());
+ maMap.put(Symbol.valueOf(name), msg.getObjectProperty(key));
+ }
+ else if (key.equals(contentTypeKey)) {
+ props.setContentType(Symbol.getSymbol(msg.getStringProperty(key)));
+ }
+ else if (key.equals(contentEncodingKey)) {
+ props.setContentEncoding(Symbol.getSymbol(msg.getStringProperty(key)));
+ }
+ else if (key.equals(replyToGroupIDKey)) {
+ props.setReplyToGroupId(msg.getStringProperty(key));
+ }
+ else if (key.startsWith(prefixFooterKey)) {
+ if (footerMap == null) {
+ footerMap = new HashMap();
+ }
+ String name = key.substring(prefixFooterKey.length());
+ footerMap.put(name, msg.getObjectProperty(key));
+ }
+ else if (key.equals(AMQPMessageTypes.AMQP_TYPE_KEY)) {
+ // skip
+ }
+ else {
+ if (apMap == null) {
+ apMap = new HashMap();
+ }
+ apMap.put(key, msg.getObjectProperty(key));
+ }
+ }
+
+ MessageAnnotations ma = null;
+ if (maMap != null) {
+ ma = new MessageAnnotations(maMap);
+ }
+ DeliveryAnnotations da = null;
+ if (daMap != null) {
+ da = new DeliveryAnnotations(daMap);
+ }
+ ApplicationProperties ap = null;
+ if (apMap != null) {
+ ap = new ApplicationProperties(apMap);
+ }
+ Footer footer = null;
+ if (footerMap != null) {
+ footer = new Footer(footerMap);
+ }
+
+ return (ProtonJMessage) org.apache.qpid.proton.message.Message.Factory.create(header, da, ma, props, ap, body, footer);
+ }
+
+ private static byte destinationType(Destination destination) {
+ if (destination instanceof Queue) {
+ if (destination instanceof TemporaryQueue) {
+ return TEMP_QUEUE_TYPE;
+ }
+ else {
+ return QUEUE_TYPE;
+ }
+ }
+ else if (destination instanceof Topic) {
+ if (destination instanceof TemporaryTopic) {
+ return TEMP_TOPIC_TYPE;
+ }
+ else {
+ return TOPIC_TYPE;
+ }
+ }
+
+ throw new IllegalArgumentException("Unknown Destination Type passed to JMS Transformer.");
+ }
+
+ // Used by legacy QPid AMQP 1.0 JMS client.
+ @Deprecated
+ private static String destinationAttributes(Destination destination) {
+ if (destination instanceof Queue) {
+ if (destination instanceof TemporaryQueue) {
+ return LEGACY_TEMP_QUEUE_TYPE;
+ }
+ else {
+ return LEGACY_QUEUE_TYPE;
+ }
+ }
+ else if (destination instanceof Topic) {
+ if (destination instanceof TemporaryTopic) {
+ return LEGACY_TEMP_TOPIC_TYPE;
+ }
+ else {
+ return LEGACY_TOPIC_TYPE;
+ }
+ }
+
+ throw new IllegalArgumentException("Unknown Destination Type passed to JMS Transformer.");
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/JMSVendor.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/JMSVendor.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/JMSVendor.java
new file mode 100644
index 0000000..9a0ed63
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/JMSVendor.java
@@ -0,0 +1,53 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter.message;
+
+import javax.jms.BytesMessage;
+import javax.jms.Destination;
+import javax.jms.MapMessage;
+import javax.jms.Message;
+import javax.jms.ObjectMessage;
+import javax.jms.StreamMessage;
+import javax.jms.TextMessage;
+
+public interface JMSVendor {
+
+ BytesMessage createBytesMessage();
+
+ StreamMessage createStreamMessage();
+
+ Message createMessage();
+
+ TextMessage createTextMessage();
+
+ ObjectMessage createObjectMessage();
+
+ MapMessage createMapMessage();
+
+ void setJMSXUserID(Message message, String value);
+
+ Destination createDestination(String name);
+
+ void setJMSXGroupID(Message message, String groupId);
+
+ void setJMSXGroupSequence(Message message, int value);
+
+ void setJMSXDeliveryCount(Message message, long value);
+
+ String toAddress(Destination destination);
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/OutboundTransformer.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/OutboundTransformer.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/OutboundTransformer.java
new file mode 100644
index 0000000..310d4ba
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/message/OutboundTransformer.java
@@ -0,0 +1,69 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter.message;
+
+public abstract class OutboundTransformer {
+
+ JMSVendor vendor;
+ String prefixVendor;
+
+ String prefixDeliveryAnnotations = "DA_";
+ String prefixMessageAnnotations = "MA_";
+ String prefixFooter = "FT_";
+
+ String messageFormatKey;
+ String nativeKey;
+ String firstAcquirerKey;
+ String prefixDeliveryAnnotationsKey;
+ String prefixMessageAnnotationsKey;
+ String contentTypeKey;
+ String contentEncodingKey;
+ String replyToGroupIDKey;
+ String prefixFooterKey;
+
+ public OutboundTransformer(JMSVendor vendor) {
+ this.vendor = vendor;
+ this.setPrefixVendor("JMS_AMQP_");
+ }
+
+ public String getPrefixVendor() {
+ return prefixVendor;
+ }
+
+ public void setPrefixVendor(String prefixVendor) {
+ this.prefixVendor = prefixVendor;
+
+ messageFormatKey = prefixVendor + "MESSAGE_FORMAT";
+ nativeKey = prefixVendor + "NATIVE";
+ firstAcquirerKey = prefixVendor + "FirstAcquirer";
+ prefixDeliveryAnnotationsKey = prefixVendor + prefixDeliveryAnnotations;
+ prefixMessageAnnotationsKey = prefixVendor + prefixMessageAnnotations;
+ contentTypeKey = prefixVendor + "ContentType";
+ contentEncodingKey = prefixVendor + "ContentEncoding";
+ replyToGroupIDKey = prefixVendor + "ReplyToGroupID";
+ prefixFooterKey = prefixVendor + prefixFooter;
+
+ }
+
+ public JMSVendor getVendor() {
+ return vendor;
+ }
+
+ public void setVendor(JMSVendor vendor) {
+ this.vendor = vendor;
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/package-info.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/package-info.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/package-info.java
new file mode 100644
index 0000000..a2d7889
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/converter/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * This package will include classes used to make convertions between Artemis and AMQP.
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPException.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPException.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPException.java
new file mode 100644
index 0000000..1634c89
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPException.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.exceptions;
+
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
+import org.apache.qpid.proton.amqp.Symbol;
+
+public class ActiveMQAMQPException extends ActiveMQException {
+
+ private static final String ERROR_PREFIX = "amqp:";
+
+ public Symbol getAmqpError() {
+ return amqpError;
+ }
+
+ private final Symbol amqpError;
+
+ public ActiveMQAMQPException(Symbol amqpError, String message, Throwable e, ActiveMQExceptionType t) {
+ super(message, e, t);
+ this.amqpError = amqpError;
+ }
+
+ public ActiveMQAMQPException(Symbol amqpError, String message, ActiveMQExceptionType t) {
+ super(message, t);
+ this.amqpError = amqpError;
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPIllegalStateException.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPIllegalStateException.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPIllegalStateException.java
new file mode 100644
index 0000000..7f0fc52
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPIllegalStateException.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.exceptions;
+
+import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
+import org.apache.qpid.proton.amqp.transport.AmqpError;
+
+public class ActiveMQAMQPIllegalStateException extends ActiveMQAMQPException {
+
+ public ActiveMQAMQPIllegalStateException(String message) {
+ super(AmqpError.ILLEGAL_STATE, message, ActiveMQExceptionType.ILLEGAL_STATE);
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPInternalErrorException.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPInternalErrorException.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPInternalErrorException.java
new file mode 100644
index 0000000..0af0bbb
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPInternalErrorException.java
@@ -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.apache.activemq.artemis.protocol.amqp.exceptions;
+
+import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
+import org.apache.qpid.proton.amqp.transport.AmqpError;
+
+public class ActiveMQAMQPInternalErrorException extends ActiveMQAMQPException {
+
+ public ActiveMQAMQPInternalErrorException(String message, Throwable e) {
+ super(AmqpError.INTERNAL_ERROR, message, e, ActiveMQExceptionType.INTERNAL_ERROR);
+ }
+
+ public ActiveMQAMQPInternalErrorException(String message) {
+ super(AmqpError.INTERNAL_ERROR, message, ActiveMQExceptionType.INTERNAL_ERROR);
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPInvalidFieldException.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPInvalidFieldException.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPInvalidFieldException.java
new file mode 100644
index 0000000..a73811c
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPInvalidFieldException.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.exceptions;
+
+import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
+import org.apache.qpid.proton.amqp.transport.AmqpError;
+
+public class ActiveMQAMQPInvalidFieldException extends ActiveMQAMQPException {
+
+ public ActiveMQAMQPInvalidFieldException(String message) {
+ super(AmqpError.INVALID_FIELD, message, ActiveMQExceptionType.ILLEGAL_STATE);
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPNotFoundException.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPNotFoundException.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPNotFoundException.java
new file mode 100644
index 0000000..f9acae3
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPNotFoundException.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.exceptions;
+
+import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
+import org.apache.qpid.proton.amqp.transport.AmqpError;
+
+public class ActiveMQAMQPNotFoundException extends ActiveMQAMQPException {
+
+ public ActiveMQAMQPNotFoundException(String message) {
+ super(AmqpError.NOT_FOUND, message, ActiveMQExceptionType.QUEUE_DOES_NOT_EXIST);
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPNotImplementedException.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPNotImplementedException.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPNotImplementedException.java
new file mode 100644
index 0000000..d2b09c7
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPNotImplementedException.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.exceptions;
+
+import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
+import org.apache.qpid.proton.amqp.transport.AmqpError;
+
+public class ActiveMQAMQPNotImplementedException extends ActiveMQAMQPException {
+
+ public ActiveMQAMQPNotImplementedException(String message) {
+ super(AmqpError.NOT_IMPLEMENTED, message, ActiveMQExceptionType.NOT_IMPLEMTNED_EXCEPTION);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPResourceLimitExceededException.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPResourceLimitExceededException.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPResourceLimitExceededException.java
new file mode 100644
index 0000000..978ffb4
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPResourceLimitExceededException.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.exceptions;
+
+import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
+import org.apache.qpid.proton.amqp.transport.AmqpError;
+
+public class ActiveMQAMQPResourceLimitExceededException extends ActiveMQAMQPException {
+
+ public ActiveMQAMQPResourceLimitExceededException(String message) {
+ super(AmqpError.RESOURCE_LIMIT_EXCEEDED, message, ActiveMQExceptionType.ADDRESS_FULL);
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPTimeoutException.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPTimeoutException.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPTimeoutException.java
new file mode 100644
index 0000000..992f34b
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/exceptions/ActiveMQAMQPTimeoutException.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.exceptions;
+
+import org.apache.activemq.artemis.api.core.ActiveMQExceptionType;
+import org.apache.qpid.proton.amqp.transport.AmqpError;
+
+public class ActiveMQAMQPTimeoutException extends ActiveMQAMQPException {
+
+ public ActiveMQAMQPTimeoutException(String message) {
+ super(AmqpError.ILLEGAL_STATE, message, ActiveMQExceptionType.CONNECTION_TIMEDOUT);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/logger/ActiveMQAMQPProtocolMessageBundle.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/logger/ActiveMQAMQPProtocolMessageBundle.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/logger/ActiveMQAMQPProtocolMessageBundle.java
new file mode 100644
index 0000000..2bfe5fc
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/logger/ActiveMQAMQPProtocolMessageBundle.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.logger;
+
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPInternalErrorException;
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPInvalidFieldException;
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPNotFoundException;
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPIllegalStateException;
+import org.jboss.logging.annotations.Message;
+import org.jboss.logging.annotations.MessageBundle;
+import org.jboss.logging.Messages;
+
+/**
+ * Logger Code 11
+ * <p>
+ * Each message id must be 6 digits long starting with 10, the 3rd digit should be 9. So the range
+ * is from 219000 to 119999.
+ * <p>
+ * Once released, methods should not be deleted as they may be referenced by knowledge base
+ * articles. Unused methods should be marked as deprecated.
+ */
+@MessageBundle(projectCode = "AMQ")
+public interface ActiveMQAMQPProtocolMessageBundle {
+
+ ActiveMQAMQPProtocolMessageBundle BUNDLE = Messages.getBundle(ActiveMQAMQPProtocolMessageBundle.class);
+
+ @Message(id = 219000, value = "target address not set")
+ ActiveMQAMQPInvalidFieldException targetAddressNotSet();
+
+ @Message(id = 219001, value = "error creating temporary queue, {0}", format = Message.Format.MESSAGE_FORMAT)
+ ActiveMQAMQPInternalErrorException errorCreatingTemporaryQueue(String message);
+
+ @Message(id = 219002, value = "target address does not exist")
+ ActiveMQAMQPNotFoundException addressDoesntExist();
+
+ @Message(id = 219003, value = "error finding temporary queue, {0}", format = Message.Format.MESSAGE_FORMAT)
+ ActiveMQAMQPNotFoundException errorFindingTemporaryQueue(String message);
+
+ @Message(id = 219005, value = "error creating consumer, {0}", format = Message.Format.MESSAGE_FORMAT)
+ ActiveMQAMQPInternalErrorException errorCreatingConsumer(String message);
+
+ @Message(id = 219006, value = "error starting consumer, {0}", format = Message.Format.MESSAGE_FORMAT)
+ ActiveMQAMQPIllegalStateException errorStartingConsumer(String message);
+
+ @Message(id = 219007, value = "error acknowledging message {0}, {1}", format = Message.Format.MESSAGE_FORMAT)
+ ActiveMQAMQPIllegalStateException errorAcknowledgingMessage(String messageID, String message);
+
+ @Message(id = 219008, value = "error cancelling message {0}, {1}", format = Message.Format.MESSAGE_FORMAT)
+ ActiveMQAMQPIllegalStateException errorCancellingMessage(String messageID, String message);
+
+ @Message(id = 219010, value = "source address does not exist")
+ ActiveMQAMQPNotFoundException sourceAddressDoesntExist();
+
+ @Message(id = 219011, value = "source address not set")
+ ActiveMQAMQPInvalidFieldException sourceAddressNotSet();
+
+ @Message(id = 219012, value = "error rolling back coordinator: {0}", format = Message.Format.MESSAGE_FORMAT)
+ ActiveMQAMQPIllegalStateException errorRollingbackCoordinator(String message);
+
+ @Message(id = 219013, value = "error committing coordinator: {0}", format = Message.Format.MESSAGE_FORMAT)
+ ActiveMQAMQPIllegalStateException errorCommittingCoordinator(String message);
+
+ @Message(id = 219014, value = "Transaction not found: xid={0}", format = Message.Format.MESSAGE_FORMAT)
+ ActiveMQAMQPIllegalStateException txNotFound(String xidToString);
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/AMQPConnectionContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/AMQPConnectionContext.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/AMQPConnectionContext.java
new file mode 100644
index 0000000..8b14e67
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/AMQPConnectionContext.java
@@ -0,0 +1,424 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.proton;
+
+import io.netty.buffer.ByteBuf;
+import org.apache.activemq.artemis.protocol.amqp.broker.AMQPConnectionCallback;
+import org.apache.activemq.artemis.protocol.amqp.broker.AMQPSessionCallback;
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPException;
+import org.apache.activemq.artemis.protocol.amqp.proton.handler.EventHandler;
+import org.apache.activemq.artemis.protocol.amqp.sasl.SASLResult;
+import org.apache.activemq.artemis.protocol.amqp.proton.handler.ProtonHandler;
+import org.apache.activemq.artemis.utils.ByteUtil;
+import org.apache.activemq.artemis.utils.VersionLoader;
+import org.apache.qpid.proton.amqp.Symbol;
+import org.apache.qpid.proton.amqp.transaction.Coordinator;
+import org.apache.qpid.proton.engine.Connection;
+import org.apache.qpid.proton.engine.Delivery;
+import org.apache.qpid.proton.engine.Link;
+import org.apache.qpid.proton.engine.Receiver;
+import org.apache.qpid.proton.engine.Sender;
+import org.apache.qpid.proton.engine.Session;
+import org.apache.qpid.proton.engine.Transport;
+import org.jboss.logging.Logger;
+import org.apache.activemq.artemis.protocol.amqp.proton.handler.ExtCapability;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+public class AMQPConnectionContext extends ProtonInitializable {
+
+ private static final Logger log = Logger.getLogger(AMQPConnectionContext.class);
+
+ public static final Symbol CONNECTION_OPEN_FAILED = Symbol.valueOf("amqp:connection-establishment-failed");
+ public static final String AMQP_CONTAINER_ID = "amqp-container-id";
+
+ protected final ProtonHandler handler;
+
+ protected AMQPConnectionCallback connectionCallback;
+ private final String containerId;
+ private final Map<Symbol, Object> connectionProperties = new HashMap<>();
+ private final ScheduledExecutorService scheduledPool;
+
+ private final Map<Session, AMQPSessionContext> sessions = new ConcurrentHashMap<>();
+
+ protected LocalListener listener = new LocalListener();
+
+
+
+ public AMQPConnectionContext(AMQPConnectionCallback connectionSP,
+ String containerId,
+ int idleTimeout,
+ int maxFrameSize,
+ int channelMax,
+ Executor dispatchExecutor,
+ ScheduledExecutorService scheduledPool) {
+ this.connectionCallback = connectionSP;
+ this.containerId = (containerId != null) ? containerId : UUID.randomUUID().toString();
+
+ connectionProperties.put(AmqpSupport.PRODUCT, "apache-activemq-artemis");
+ connectionProperties.put(AmqpSupport.VERSION, VersionLoader.getVersion().getFullVersion());
+
+ this.scheduledPool = scheduledPool;
+ connectionCallback.setConnection(this);
+ this.handler = new ProtonHandler(dispatchExecutor);
+ Transport transport = handler.getTransport();
+ transport.setEmitFlowEventOnSend(false);
+ if (idleTimeout > 0) {
+ transport.setIdleTimeout(idleTimeout);
+ }
+ transport.setChannelMax(channelMax);
+ transport.setMaxFrameSize(maxFrameSize);
+ handler.addEventHandler(listener);
+ }
+
+ protected AMQPSessionContext newSessionExtension(Session realSession) throws ActiveMQAMQPException {
+ AMQPSessionCallback sessionSPI = connectionCallback.createSessionCallback(this);
+ AMQPSessionContext protonSession = new AMQPSessionContext(sessionSPI, this, realSession);
+
+ return protonSession;
+ }
+
+ public SASLResult getSASLResult() {
+ return handler.getSASLResult();
+ }
+
+ public void inputBuffer(ByteBuf buffer) {
+ if (log.isTraceEnabled()) {
+ ByteUtil.debugFrame(log, "Buffer Received ", buffer);
+ }
+
+ handler.inputBuffer(buffer);
+ }
+
+ public void destroy() {
+ connectionCallback.close();
+ }
+
+ public boolean isSyncOnFlush() {
+ return false;
+ }
+
+ public Object getLock() {
+ return handler.getLock();
+ }
+
+ public int capacity() {
+ return handler.capacity();
+ }
+
+ public void outputDone(int bytes) {
+ handler.outputDone(bytes);
+ }
+
+ public void flush() {
+ handler.flush();
+ }
+
+ public void close() {
+ handler.close();
+ }
+
+
+ protected AMQPSessionContext getSessionExtension(Session realSession) throws ActiveMQAMQPException {
+ AMQPSessionContext sessionExtension = sessions.get(realSession);
+ if (sessionExtension == null) {
+ // how this is possible? Log a warn here
+ sessionExtension = newSessionExtension(realSession);
+ realSession.setContext(sessionExtension);
+ sessions.put(realSession, sessionExtension);
+ }
+ return sessionExtension;
+ }
+
+
+
+ protected boolean validateConnection(Connection connection) {
+ return connectionCallback.validateConnection(connection, handler.getSASLResult());
+ }
+
+ public boolean checkDataReceived() {
+ return handler.checkDataReceived();
+ }
+
+ public long getCreationTime() {
+ return handler.getCreationTime();
+ }
+
+ protected void flushBytes() {
+ ByteBuf bytes;
+ // handler.outputBuffer has the lock
+ while ((bytes = handler.outputBuffer()) != null) {
+ connectionCallback.onTransport(bytes, this);
+ }
+ }
+
+ public String getRemoteContainer() {
+ return handler.getConnection().getRemoteContainer();
+ }
+
+ public String getPubSubPrefix() {
+ return null;
+ }
+
+ protected void initInternal() throws Exception {
+ }
+
+ protected void remoteLinkOpened(Link link) throws Exception {
+
+ AMQPSessionContext protonSession = (AMQPSessionContext) getSessionExtension(link.getSession());
+
+ link.setSource(link.getRemoteSource());
+ link.setTarget(link.getRemoteTarget());
+ if (link instanceof Receiver) {
+ Receiver receiver = (Receiver) link;
+ if (link.getRemoteTarget() instanceof Coordinator) {
+ Coordinator coordinator = (Coordinator) link.getRemoteTarget();
+ protonSession.addTransactionHandler(coordinator, receiver);
+ }
+ else {
+ protonSession.addReceiver(receiver);
+ }
+ }
+ else {
+ Sender sender = (Sender) link;
+ protonSession.addSender(sender);
+ sender.offer(1);
+ }
+ }
+
+ public Symbol[] getConnectionCapabilitiesOffered() {
+ return ExtCapability.getCapabilities();
+ }
+
+
+
+ // This listener will perform a bunch of things here
+ class LocalListener implements EventHandler {
+
+ @Override
+ public void onInit(Connection connection) throws Exception {
+
+ }
+
+ @Override
+ public void onLocalOpen(Connection connection) throws Exception {
+
+ }
+
+ @Override
+ public void onLocalClose(Connection connection) throws Exception {
+
+ }
+
+ @Override
+ public void onFinal(Connection connection) throws Exception {
+
+ }
+
+ @Override
+ public void onInit(Session session) throws Exception {
+
+ }
+
+ @Override
+ public void onFinal(Session session) throws Exception {
+
+ }
+
+ @Override
+ public void onInit(Link link) throws Exception {
+
+ }
+
+ @Override
+ public void onLocalOpen(Link link) throws Exception {
+
+ }
+
+ @Override
+ public void onLocalClose(Link link) throws Exception {
+
+ }
+
+ @Override
+ public void onFinal(Link link) throws Exception {
+
+ }
+
+ @Override
+ public void onAuthInit(ProtonHandler handler, Connection connection, boolean sasl) {
+ if (sasl) {
+ handler.createServerSASL(connectionCallback.getSASLMechnisms());
+ }
+ else {
+ if (!connectionCallback.isSupportsAnonymous()) {
+ connectionCallback.sendSASLSupported();
+ connectionCallback.close();
+ handler.close();
+ }
+ }
+ }
+
+ @Override
+ public void onTransport(Transport transport) {
+ flushBytes();
+ }
+
+ @Override
+ public void onRemoteOpen(Connection connection) throws Exception {
+ synchronized (getLock()) {
+ try {
+ initInternal();
+ }
+ catch (Exception e) {
+ log.error("Error init connection", e);
+ }
+ if (!validateConnection(connection)) {
+ connection.close();
+ }
+ else {
+ connection.setContext(AMQPConnectionContext.this);
+ connection.setContainer(containerId);
+ connection.setProperties(connectionProperties);
+ connection.setOfferedCapabilities(getConnectionCapabilitiesOffered());
+ connection.open();
+ }
+ }
+ initialise();
+
+ /*
+ * This can be null which is in effect an empty map, also we really dont need to check this for in bound connections
+ * but its here in case we add support for outbound connections.
+ * */
+ if (connection.getRemoteProperties() == null || !connection.getRemoteProperties().containsKey(CONNECTION_OPEN_FAILED)) {
+ long nextKeepAliveTime = handler.tick(true);
+ flushBytes();
+ if (nextKeepAliveTime > 0 && scheduledPool != null) {
+ scheduledPool.schedule(new Runnable() {
+ @Override
+ public void run() {
+ long rescheduleAt = (handler.tick(false) - TimeUnit.NANOSECONDS.toMillis(System.nanoTime()));
+ flushBytes();
+ if (rescheduleAt > 0) {
+ scheduledPool.schedule(this, rescheduleAt, TimeUnit.MILLISECONDS);
+ }
+ }
+ }, (nextKeepAliveTime - TimeUnit.NANOSECONDS.toMillis(System.nanoTime())), TimeUnit.MILLISECONDS);
+ }
+ }
+ }
+
+ @Override
+ public void onRemoteClose(Connection connection) {
+ synchronized (getLock()) {
+ connection.close();
+ for (AMQPSessionContext protonSession : sessions.values()) {
+ protonSession.close();
+ }
+ sessions.clear();
+ }
+ // We must force write the channel before we actually destroy the connection
+ onTransport(handler.getTransport());
+ destroy();
+ }
+
+ @Override
+ public void onLocalOpen(Session session) throws Exception {
+ getSessionExtension(session);
+ }
+
+ @Override
+ public void onRemoteOpen(Session session) throws Exception {
+ getSessionExtension(session).initialise();
+ synchronized (getLock()) {
+ session.open();
+ }
+ }
+
+ @Override
+ public void onLocalClose(Session session) throws Exception {
+ }
+
+ @Override
+ public void onRemoteClose(Session session) throws Exception {
+ synchronized (getLock()) {
+ session.close();
+ }
+
+ AMQPSessionContext sessionContext = (AMQPSessionContext)session.getContext();
+ if (sessionContext != null) {
+ sessionContext.close();
+ sessions.remove(session);
+ session.setContext(null);
+ }
+ }
+
+ @Override
+ public void onRemoteOpen(Link link) throws Exception {
+ remoteLinkOpened(link);
+ }
+
+ @Override
+ public void onFlow(Link link) throws Exception {
+ ((ProtonDeliveryHandler) link.getContext()).onFlow(link.getCredit(), link.getDrain());
+ }
+
+ @Override
+ public void onRemoteClose(Link link) throws Exception {
+ link.close();
+ ProtonDeliveryHandler linkContext = (ProtonDeliveryHandler) link.getContext();
+ if (linkContext != null) {
+ linkContext.close(true);
+ }
+ }
+
+ @Override
+ public void onRemoteDetach(Link link) throws Exception {
+ link.detach();
+ }
+
+ @Override
+ public void onDetach(Link link) throws Exception {
+ Object context = link.getContext();
+ if (context instanceof ProtonServerSenderContext) {
+ ProtonServerSenderContext senderContext = (ProtonServerSenderContext) context;
+ senderContext.close(false);
+ }
+ }
+
+ @Override
+ public void onDelivery(Delivery delivery) throws Exception {
+ ProtonDeliveryHandler handler = (ProtonDeliveryHandler) delivery.getLink().getContext();
+ if (handler != null) {
+ handler.onMessage(delivery);
+ }
+ else {
+ // TODO: logs
+
+ System.err.println("Handler is null, can't delivery " + delivery);
+ }
+ }
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/AMQPConstants.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/AMQPConstants.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/AMQPConstants.java
new file mode 100644
index 0000000..728a87b
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/AMQPConstants.java
@@ -0,0 +1,36 @@
+/**
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.proton;
+
+/**
+ * Constants derived from the AMQP spec
+ */
+public class AMQPConstants {
+
+ /*
+ * Connection Properties
+ * http://docs.oasis-open.org/amqp/core/v1.0/amqp-core-complete-v1.0.pdf#subsection.2.7.1
+ * */
+ public static class Connection {
+
+ public static final int DEFAULT_IDLE_TIMEOUT = -1;
+
+ public static final int DEFAULT_MAX_FRAME_SIZE = -1;//it should be according to the spec 4294967295l;
+
+ public static final int DEFAULT_CHANNEL_MAX = 65535;
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/AMQPSessionContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/AMQPSessionContext.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/AMQPSessionContext.java
new file mode 100644
index 0000000..9003d3b
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/AMQPSessionContext.java
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.proton;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.activemq.artemis.protocol.amqp.broker.AMQPSessionCallback;
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPInternalErrorException;
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPException;
+import org.apache.qpid.proton.amqp.Symbol;
+import org.apache.qpid.proton.amqp.transaction.Coordinator;
+import org.apache.qpid.proton.amqp.transport.ErrorCondition;
+import org.apache.qpid.proton.engine.Receiver;
+import org.apache.qpid.proton.engine.Sender;
+import org.apache.qpid.proton.engine.Session;
+import org.jboss.logging.Logger;
+
+public class AMQPSessionContext extends ProtonInitializable {
+
+ private static final Logger log = Logger.getLogger(AMQPSessionContext.class);
+ protected final AMQPConnectionContext connection;
+
+ protected final AMQPSessionCallback sessionSPI;
+
+ protected final Session session;
+
+ private long currentTag = 0;
+
+ protected Map<Receiver, ProtonServerReceiverContext> receivers = new HashMap<>();
+
+ protected Map<Sender, ProtonServerSenderContext> senders = new HashMap<>();
+
+ protected boolean closed = false;
+
+ public AMQPSessionContext(AMQPSessionCallback sessionSPI,
+ AMQPConnectionContext connection,
+ Session session) {
+ this.connection = connection;
+ this.sessionSPI = sessionSPI;
+ this.session = session;
+ }
+
+ protected Map<Object, ProtonServerSenderContext> serverSenders = new HashMap<>();
+
+ @Override
+ public void initialise() throws Exception {
+ if (!isInitialized()) {
+ super.initialise();
+
+ if (sessionSPI != null) {
+ try {
+ sessionSPI.init(this, connection.getSASLResult());
+ }
+ catch (Exception e) {
+ throw new ActiveMQAMQPInternalErrorException(e.getMessage(), e);
+ }
+ }
+ }
+ }
+
+ /**
+ * @param consumer
+ * @param queueName
+ */
+ public void disconnect(Object consumer, String queueName) {
+ ProtonServerSenderContext protonConsumer = senders.remove(consumer);
+ if (protonConsumer != null) {
+ try {
+ protonConsumer.close(false);
+ }
+ catch (ActiveMQAMQPException e) {
+ protonConsumer.getSender().setTarget(null);
+ protonConsumer.getSender().setCondition(new ErrorCondition(e.getAmqpError(), e.getMessage()));
+ }
+ }
+ }
+
+
+ /**
+ * The consumer object from the broker or the key used to store the sender
+ *
+ * @param message
+ * @param consumer
+ * @param deliveryCount
+ * @return the number of bytes sent
+ */
+ public int serverDelivery(Object message, Object consumer, int deliveryCount) throws Exception {
+ ProtonServerSenderContext protonSender = serverSenders.get(consumer);
+ if (protonSender != null) {
+ return protonSender.deliverMessage(message, deliveryCount);
+ }
+ return 0;
+ }
+
+ public byte[] getTag() {
+ return Long.toHexString(currentTag++).getBytes();
+ }
+
+ public void replaceTag(byte[] tag) {
+ // TODO: do we need to reuse this?
+ }
+
+ public void close() {
+ if (closed) {
+ return;
+ }
+
+ // Making a copy to avoid ConcurrentModificationException during the iteration
+ Set<ProtonServerReceiverContext> receiversCopy = new HashSet<>();
+ receiversCopy.addAll(receivers.values());
+
+ for (ProtonServerReceiverContext protonProducer : receiversCopy) {
+ try {
+ protonProducer.close(false);
+ }
+ catch (Exception e) {
+ log.warn(e.getMessage(), e);
+ }
+ }
+ receivers.clear();
+
+ Set<ProtonServerSenderContext> protonSendersClone = new HashSet<>();
+ protonSendersClone.addAll(senders.values());
+
+ for (ProtonServerSenderContext protonConsumer : protonSendersClone) {
+ try {
+ protonConsumer.close(false);
+ }
+ catch (Exception e) {
+ log.warn(e.getMessage(), e);
+ }
+ }
+ senders.clear();
+ try {
+ if (sessionSPI != null) {
+ sessionSPI.close();
+ }
+ }
+ catch (Exception e) {
+ log.warn(e.getMessage(), e);
+ }
+ closed = true;
+ }
+
+ public void removeReceiver(Receiver receiver) {
+ receivers.remove(receiver);
+ }
+
+ public void addTransactionHandler(Coordinator coordinator, Receiver receiver) {
+ ProtonTransactionHandler transactionHandler = new ProtonTransactionHandler(sessionSPI);
+
+ coordinator.setCapabilities(Symbol.getSymbol("amqp:local-transactions"),
+ Symbol.getSymbol("amqp:multi-txns-per-ssn"),
+ Symbol.getSymbol("amqp:multi-ssns-per-txn"));
+
+ receiver.setContext(transactionHandler);
+ receiver.open();
+ receiver.flow(100);
+ }
+
+ public void addSender(Sender sender) throws Exception {
+ ProtonServerSenderContext protonSender = new ProtonServerSenderContext(connection, sender, this, sessionSPI);
+
+ try {
+ protonSender.initialise();
+ senders.put(sender, protonSender);
+ serverSenders.put(protonSender.getBrokerConsumer(), protonSender);
+ sender.setContext(protonSender);
+ sender.open();
+ protonSender.start();
+ }
+ catch (ActiveMQAMQPException e) {
+ senders.remove(sender);
+ sender.setSource(null);
+ sender.setCondition(new ErrorCondition(e.getAmqpError(), e.getMessage()));
+ sender.close();
+ }
+ }
+
+ public void removeSender(Sender sender) throws ActiveMQAMQPException {
+ senders.remove(sender);
+ ProtonServerSenderContext senderRemoved = senders.remove(sender);
+ if (senderRemoved != null) {
+ serverSenders.remove(senderRemoved.getBrokerConsumer());
+ }
+ }
+
+ public void addReceiver(Receiver receiver) throws Exception {
+ try {
+ ProtonServerReceiverContext protonReceiver = new ProtonServerReceiverContext(sessionSPI, connection, this, receiver);
+ protonReceiver.initialise();
+ receivers.put(receiver, protonReceiver);
+ receiver.setContext(protonReceiver);
+ receiver.open();
+ }
+ catch (ActiveMQAMQPException e) {
+ receivers.remove(receiver);
+ receiver.setTarget(null);
+ receiver.setCondition(new ErrorCondition(e.getAmqpError(), e.getMessage()));
+ receiver.close();
+ }
+ }
+
+}
[12/15] activemq-artemis git commit: ARTEMIS-751 Simplification of
the AMQP implementation
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ActiveMQProtonConnectionCallback.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ActiveMQProtonConnectionCallback.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ActiveMQProtonConnectionCallback.java
deleted file mode 100644
index d5b2ff7..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ActiveMQProtonConnectionCallback.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.plug;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelFutureListener;
-import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.core.buffers.impl.ChannelBufferWrapper;
-import org.apache.activemq.artemis.core.protocol.proton.ActiveMQProtonRemotingConnection;
-import org.apache.activemq.artemis.core.protocol.proton.ProtonProtocolManager;
-import org.apache.activemq.artemis.core.protocol.proton.sasl.ActiveMQPlainSASL;
-import org.apache.activemq.artemis.core.remoting.CloseListener;
-import org.apache.activemq.artemis.core.remoting.FailureListener;
-import org.apache.activemq.artemis.core.server.ActiveMQServer;
-import org.apache.activemq.artemis.core.transaction.Transaction;
-import org.apache.activemq.artemis.core.transaction.impl.TransactionImpl;
-import org.apache.activemq.artemis.core.transaction.impl.XidImpl;
-import org.apache.activemq.artemis.spi.core.remoting.Connection;
-import org.apache.activemq.artemis.utils.ReusableLatch;
-import org.apache.activemq.artemis.utils.UUIDGenerator;
-import org.apache.qpid.proton.amqp.Binary;
-import org.apache.qpid.proton.amqp.Symbol;
-import org.apache.qpid.proton.amqp.transport.AmqpError;
-import org.jboss.logging.Logger;
-import org.proton.plug.AMQPConnectionCallback;
-import org.proton.plug.AMQPConnectionContext;
-import org.proton.plug.AMQPSessionCallback;
-import org.proton.plug.SASLResult;
-import org.proton.plug.ServerSASL;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-import org.proton.plug.handler.ExtCapability;
-import org.proton.plug.logger.ActiveMQAMQPProtocolMessageBundle;
-import org.proton.plug.sasl.AnonymousServerSASL;
-
-import static org.proton.plug.AmqpSupport.CONTAINER_ID;
-import static org.proton.plug.AmqpSupport.INVALID_FIELD;
-import static org.proton.plug.context.AbstractConnectionContext.CONNECTION_OPEN_FAILED;
-
-public class ActiveMQProtonConnectionCallback implements AMQPConnectionCallback, FailureListener, CloseListener {
- private static final Logger logger = Logger.getLogger(ActiveMQProtonConnectionCallback.class);
- private static final List<String> connectedContainers = Collections.synchronizedList(new ArrayList());
-
- private ConcurrentMap<XidImpl, Transaction> transactions = new ConcurrentHashMap<>();
-
- private static final Logger log = Logger.getLogger(ActiveMQProtonConnectionCallback.class);
-
- private final ProtonProtocolManager manager;
-
- private final Connection connection;
-
- protected ActiveMQProtonRemotingConnection protonConnectionDelegate;
-
- protected AMQPConnectionContext amqpConnection;
-
- private final ReusableLatch latch = new ReusableLatch(0);
-
- private final Executor closeExecutor;
-
- private String remoteContainerId;
-
- private AtomicBoolean registeredConnectionId = new AtomicBoolean(false);
-
- private ActiveMQServer server;
-
- public ActiveMQProtonConnectionCallback(ProtonProtocolManager manager,
- Connection connection,
- Executor closeExecutor,
- ActiveMQServer server) {
- this.manager = manager;
- this.connection = connection;
- this.closeExecutor = closeExecutor;
- this.server = server;
- }
-
- @Override
- public ServerSASL[] getSASLMechnisms() {
-
- ServerSASL[] result;
-
- if (isSupportsAnonymous()) {
- result = new ServerSASL[]{new ActiveMQPlainSASL(manager.getServer().getSecurityStore()), new AnonymousServerSASL()};
- }
- else {
- result = new ServerSASL[]{new ActiveMQPlainSASL(manager.getServer().getSecurityStore())};
- }
-
- return result;
- }
-
- @Override
- public boolean isSupportsAnonymous() {
- boolean supportsAnonymous = false;
- try {
- manager.getServer().getSecurityStore().authenticate(null, null, null);
- supportsAnonymous = true;
- }
- catch (Exception e) {
- // authentication failed so no anonymous support
- }
- return supportsAnonymous;
- }
-
- @Override
- public void close() {
- try {
- if (registeredConnectionId.getAndSet(false)) {
- server.removeClientConnection(remoteContainerId);
- }
- connection.close();
- amqpConnection.close();
- }
- finally {
- for (Transaction tx : transactions.values()) {
- try {
- tx.rollback();
- }
- catch (Exception e) {
- logger.warn(e.getMessage(), e);
- }
- }
- }
- }
-
- public Executor getExeuctor() {
- if (protonConnectionDelegate != null) {
- return protonConnectionDelegate.getExecutor();
- }
- else {
- return null;
- }
- }
-
- @Override
- public void setConnection(AMQPConnectionContext connection) {
- this.amqpConnection = connection;
- }
-
- @Override
- public AMQPConnectionContext getConnection() {
- return amqpConnection;
- }
-
- public ActiveMQProtonRemotingConnection getProtonConnectionDelegate() {
- return protonConnectionDelegate;
- }
-
- public void setProtonConnectionDelegate(ActiveMQProtonRemotingConnection protonConnectionDelegate) {
-
- this.protonConnectionDelegate = protonConnectionDelegate;
- }
-
- @Override
- public void onTransport(ByteBuf byteBuf, AMQPConnectionContext amqpConnection) {
- final int size = byteBuf.writerIndex();
-
- latch.countUp();
- connection.write(new ChannelBufferWrapper(byteBuf, true), false, false, new ChannelFutureListener() {
- @Override
- public void operationComplete(ChannelFuture future) throws Exception {
- latch.countDown();
- }
- });
-
- if (amqpConnection.isSyncOnFlush()) {
- try {
- latch.await(5, TimeUnit.SECONDS);
- }
- catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- amqpConnection.outputDone(size);
- }
-
- @Override
- public AMQPSessionCallback createSessionCallback(AMQPConnectionContext connection) {
- return new ProtonSessionIntegrationCallback(this, manager, connection, this.connection, closeExecutor);
- }
-
- @Override
- public void sendSASLSupported() {
- connection.write(ActiveMQBuffers.wrappedBuffer(new byte[]{'A', 'M', 'Q', 'P', 3, 1, 0, 0}));
- }
-
- @Override
- public boolean validateConnection(org.apache.qpid.proton.engine.Connection connection, SASLResult saslResult) {
- remoteContainerId = connection.getRemoteContainer();
- boolean idOK = server.addClientConnection(remoteContainerId, ExtCapability.needUniqueConnection(connection));
- if (!idOK) {
- //https://issues.apache.org/jira/browse/ARTEMIS-728
- Map<Symbol, Object> connProp = new HashMap<>();
- connProp.put(CONNECTION_OPEN_FAILED, "true");
- connection.setProperties(connProp);
- connection.getCondition().setCondition(AmqpError.INVALID_FIELD);
- Map<Symbol, Symbol> info = new HashMap<>();
- info.put(INVALID_FIELD, CONTAINER_ID);
- connection.getCondition().setInfo(info);
- return false;
- }
- registeredConnectionId.set(true);
- return true;
- }
-
- @Override
- public void connectionClosed() {
- close();
- }
-
- @Override
- public void connectionFailed(ActiveMQException exception, boolean failedOver) {
- close();
- }
-
- @Override
- public void connectionFailed(ActiveMQException exception, boolean failedOver, String scaleDownTargetNodeID) {
- close();
- }
-
- @Override
- public Binary newTransaction() {
- XidImpl xid = newXID();
- Transaction transaction = new TransactionImpl(xid, server.getStorageManager(), -1);
- transactions.put(xid, transaction);
- return new Binary(xid.getGlobalTransactionId());
- }
-
- @Override
- public Transaction getTransaction(Binary txid) throws ActiveMQAMQPException {
- XidImpl xid = newXID(txid.getArray());
- Transaction tx = transactions.get(xid);
-
- if (tx == null) {
- throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.txNotFound(xid.toString());
- }
-
- return tx;
- }
-
- @Override
- public void removeTransaction(Binary txid) {
- XidImpl xid = newXID(txid.getArray());
- transactions.remove(xid);
- }
-
-
- protected XidImpl newXID() {
- return newXID(UUIDGenerator.getInstance().generateStringUUID().getBytes());
- }
-
- protected XidImpl newXID(byte[] bytes) {
- return new XidImpl("amqp".getBytes(), 1, bytes);
- }
-
-
-
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ProtonSessionIntegrationCallback.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ProtonSessionIntegrationCallback.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ProtonSessionIntegrationCallback.java
deleted file mode 100644
index da9dd9c..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/plug/ProtonSessionIntegrationCallback.java
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.plug;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import io.netty.buffer.ByteBuf;
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.api.core.ActiveMQQueueExistsException;
-import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
-import org.apache.activemq.artemis.core.io.IOCallback;
-import org.apache.activemq.artemis.core.paging.PagingStore;
-import org.apache.activemq.artemis.core.protocol.proton.ProtonProtocolManager;
-import org.apache.activemq.artemis.core.protocol.proton.converter.message.EncodedMessage;
-import org.apache.activemq.artemis.core.server.BindingQueryResult;
-import org.apache.activemq.artemis.core.server.MessageReference;
-import org.apache.activemq.artemis.core.server.QueueQueryResult;
-import org.apache.activemq.artemis.core.server.ServerConsumer;
-import org.apache.activemq.artemis.core.server.ServerMessage;
-import org.apache.activemq.artemis.core.server.ServerSession;
-import org.apache.activemq.artemis.core.server.impl.ServerConsumerImpl;
-import org.apache.activemq.artemis.core.transaction.Transaction;
-import org.apache.activemq.artemis.jms.client.ActiveMQConnection;
-import org.apache.activemq.artemis.spi.core.protocol.SessionCallback;
-import org.apache.activemq.artemis.spi.core.remoting.Connection;
-import org.apache.activemq.artemis.spi.core.remoting.ReadyListener;
-import org.apache.activemq.artemis.utils.IDGenerator;
-import org.apache.activemq.artemis.utils.SelectorTranslator;
-import org.apache.activemq.artemis.utils.SimpleIDGenerator;
-import org.apache.activemq.artemis.utils.UUIDGenerator;
-import org.apache.qpid.proton.amqp.Binary;
-import org.apache.qpid.proton.amqp.messaging.Accepted;
-import org.apache.qpid.proton.amqp.messaging.Rejected;
-import org.apache.qpid.proton.amqp.transport.AmqpError;
-import org.apache.qpid.proton.amqp.transport.ErrorCondition;
-import org.apache.qpid.proton.engine.Delivery;
-import org.apache.qpid.proton.engine.Link;
-import org.apache.qpid.proton.engine.Receiver;
-import org.apache.qpid.proton.message.ProtonJMessage;
-import org.proton.plug.AMQPConnectionContext;
-import org.proton.plug.AMQPSessionCallback;
-import org.proton.plug.AMQPSessionContext;
-import org.proton.plug.SASLResult;
-import org.proton.plug.context.ProtonPlugSender;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-import org.proton.plug.exceptions.ActiveMQAMQPInternalErrorException;
-import org.proton.plug.exceptions.ActiveMQAMQPResourceLimitExceededException;
-import org.proton.plug.sasl.PlainSASLResult;
-
-public class ProtonSessionIntegrationCallback implements AMQPSessionCallback, SessionCallback {
-
- protected final IDGenerator consumerIDGenerator = new SimpleIDGenerator(0);
-
- private final ActiveMQProtonConnectionCallback protonSPI;
-
- private final ProtonProtocolManager manager;
-
- private final AMQPConnectionContext connection;
-
- private final Connection transportConnection;
-
- private ServerSession serverSession;
-
- private AMQPSessionContext protonSession;
-
- private final Executor closeExecutor;
-
- private final AtomicBoolean draining = new AtomicBoolean(false);
-
- public ProtonSessionIntegrationCallback(ActiveMQProtonConnectionCallback protonSPI,
- ProtonProtocolManager manager,
- AMQPConnectionContext connection,
- Connection transportConnection,
- Executor executor) {
- this.protonSPI = protonSPI;
- this.manager = manager;
- this.connection = connection;
- this.transportConnection = transportConnection;
- this.closeExecutor = executor;
- }
-
- @Override
- public boolean isWritable(ReadyListener callback) {
- return transportConnection.isWritable(callback);
- }
-
- @Override
- public void onFlowConsumer(Object consumer, int credits, final boolean drain) {
- ServerConsumerImpl serverConsumer = (ServerConsumerImpl) consumer;
- if (drain) {
- // If the draining is already running, then don't do anything
- if (draining.compareAndSet(false, true)) {
- final ProtonPlugSender plugSender = (ProtonPlugSender) serverConsumer.getProtocolContext();
- serverConsumer.forceDelivery(1, new Runnable() {
- @Override
- public void run() {
- try {
- plugSender.getSender().drained();
- }
- finally {
- draining.set(false);
- }
- }
- });
- }
- }
- else {
- serverConsumer.receiveCredits(-1);
- }
- }
-
- @Override
- public void browserFinished(ServerConsumer consumer) {
-
- }
-
- @Override
- public void init(AMQPSessionContext protonSession, SASLResult saslResult) throws Exception {
-
- this.protonSession = protonSession;
-
- String name = UUIDGenerator.getInstance().generateStringUUID();
-
- String user = null;
- String passcode = null;
- if (saslResult != null) {
- user = saslResult.getUser();
- if (saslResult instanceof PlainSASLResult) {
- passcode = ((PlainSASLResult) saslResult).getPassword();
- }
- }
-
- serverSession = manager.getServer().createSession(name, user, passcode, ActiveMQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE, protonSPI.getProtonConnectionDelegate(), // RemotingConnection remotingConnection,
- false, // boolean autoCommitSends
- false, // boolean autoCommitAcks,
- false, // boolean preAcknowledge,
- true, //boolean xa,
- (String) null, this, true);
- }
-
- @Override
- public void afterDelivery() throws Exception {
-
- }
-
- @Override
- public void start() {
-
- }
-
- @Override
- public Object createSender(ProtonPlugSender protonSender,
- String queue,
- String filter,
- boolean browserOnly) throws Exception {
- long consumerID = consumerIDGenerator.generateID();
-
- filter = SelectorTranslator.convertToActiveMQFilterString(filter);
-
- ServerConsumer consumer = serverSession.createConsumer(consumerID, SimpleString.toSimpleString(queue), SimpleString.toSimpleString(filter), browserOnly);
-
- // AMQP handles its own flow control for when it's started
- consumer.setStarted(true);
-
- consumer.setProtocolContext(protonSender);
-
- return consumer;
- }
-
- @Override
- public void startSender(Object brokerConsumer) throws Exception {
- ServerConsumer serverConsumer = (ServerConsumer) brokerConsumer;
- // flow control is done at proton
- serverConsumer.receiveCredits(-1);
- }
-
- @Override
- public void createTemporaryQueue(String queueName) throws Exception {
- serverSession.createQueue(SimpleString.toSimpleString(queueName), SimpleString.toSimpleString(queueName), null, true, false);
- }
-
- @Override
- public void createTemporaryQueue(String address, String queueName, String filter) throws Exception {
- serverSession.createQueue(SimpleString.toSimpleString(address), SimpleString.toSimpleString(queueName), SimpleString.toSimpleString(filter), true, false);
- }
-
- @Override
- public void createDurableQueue(String address, String queueName, String filter) throws Exception {
- serverSession.createQueue(SimpleString.toSimpleString(address), SimpleString.toSimpleString(queueName), SimpleString.toSimpleString(filter), false, true);
- }
-
- @Override
- public QueueQueryResult queueQuery(String queueName, boolean autoCreate) throws Exception {
- QueueQueryResult queueQueryResult = serverSession.executeQueueQuery(SimpleString.toSimpleString(queueName));
-
- if (!queueQueryResult.isExists() && queueQueryResult.isAutoCreateJmsQueues() && autoCreate) {
- try {
- serverSession.createQueue(new SimpleString(queueName), new SimpleString(queueName), null, false, true);
- }
- catch (ActiveMQQueueExistsException e) {
- // The queue may have been created by another thread in the mean time. Catch and do nothing.
- }
- queueQueryResult = new QueueQueryResult(queueQueryResult.getName(), queueQueryResult.getAddress(), queueQueryResult.isDurable(), queueQueryResult.isTemporary(), queueQueryResult.getFilterString(), queueQueryResult.getConsumerCount(), queueQueryResult.getMessageCount(), queueQueryResult.isAutoCreateJmsQueues(), true);
- }
- return queueQueryResult;
- }
-
- @Override
- public boolean bindingQuery(String address) throws Exception {
- BindingQueryResult bindingQueryResult = serverSession.executeBindingQuery(SimpleString.toSimpleString(address));
- if (!bindingQueryResult.isExists() && bindingQueryResult.isAutoCreateJmsQueues()) {
- try {
- serverSession.createQueue(new SimpleString(address), new SimpleString(address), null, false, true);
- }
- catch (ActiveMQQueueExistsException e) {
- // The queue may have been created by another thread in the mean time. Catch and do nothing.
- }
- bindingQueryResult = serverSession.executeBindingQuery(SimpleString.toSimpleString(address));
- }
- return bindingQueryResult.isExists();
- }
-
- @Override
- public void closeSender(final Object brokerConsumer) throws Exception {
-
- final ServerConsumer consumer = ((ServerConsumer) brokerConsumer);
- final CountDownLatch latch = new CountDownLatch(1);
-
- Runnable runnable = new Runnable() {
- @Override
- public void run() {
- try {
- consumer.close(false);
- latch.countDown();
- }
- catch (Exception e) {
- }
- }
- };
-
- // Due to the nature of proton this could be happening within flushes from the queue-delivery (depending on how it happened on the protocol)
- // to avoid deadlocks the close has to be done outside of the main thread on an executor
- // otherwise you could get a deadlock
- Executor executor = protonSPI.getExeuctor();
-
- if (executor != null) {
- executor.execute(runnable);
- }
- else {
- runnable.run();
- }
-
- try {
- latch.await(10, TimeUnit.SECONDS);
- }
- catch (InterruptedException e) {
- throw new ActiveMQAMQPInternalErrorException("Unable to close consumers for queue: " + consumer.getQueue());
- }
- }
-
- @Override
- public ProtonJMessage encodeMessage(Object message, int deliveryCount) throws Exception {
- return (ProtonJMessage) manager.getConverter().outbound((ServerMessage) message, deliveryCount);
- }
-
- @Override
- public String tempQueueName() {
- return UUIDGenerator.getInstance().generateStringUUID();
- }
-
- @Override
- public void close() throws Exception {
- //need to check here as this can be called if init fails
- if (serverSession != null) {
- recoverContext();
- try {
- serverSession.close(false);
- }
- finally {
- resetContext();
- }
- }
- }
-
- @Override
- public void ack(Transaction transaction, Object brokerConsumer, Object message) throws Exception {
- if (transaction == null) {
- transaction = serverSession.getCurrentTransaction();
- }
- recoverContext();
- try {
- ((ServerConsumer) brokerConsumer).individualAcknowledge(transaction, ((ServerMessage) message).getMessageID());
- }
- finally {
- resetContext();
- }
- }
-
- @Override
- public void cancel(Object brokerConsumer, Object message, boolean updateCounts) throws Exception {
- recoverContext();
- try {
- ((ServerConsumer) brokerConsumer).individualCancel(((ServerMessage) message).getMessageID(), updateCounts);
- }
- finally {
- resetContext();
- }
- }
-
- @Override
- public void resumeDelivery(Object consumer) {
- ((ServerConsumer) consumer).receiveCredits(-1);
- }
-
- @Override
- public void serverSend(final Transaction transaction,
- final Receiver receiver,
- final Delivery delivery,
- String address,
- int messageFormat,
- ByteBuf messageEncoded) throws Exception {
- EncodedMessage encodedMessage = new EncodedMessage(messageFormat, messageEncoded.array(), messageEncoded.arrayOffset(), messageEncoded.writerIndex());
-
- ServerMessage message = manager.getConverter().inbound(encodedMessage);
- //use the address on the receiver if not null, if null let's hope it was set correctly on the message
- if (address != null) {
- message.setAddress(new SimpleString(address));
- }
-
- recoverContext();
-
- PagingStore store = manager.getServer().getPagingManager().getPageStore(message.getAddress());
- if (store.isRejectingMessages()) {
- // We drop pre-settled messages (and abort any associated Tx)
- if (delivery.remotelySettled()) {
- if (transaction != null) {
- String amqpAddress = delivery.getLink().getTarget().getAddress();
- ActiveMQException e = new ActiveMQAMQPResourceLimitExceededException("Address is full: " + amqpAddress);
- transaction.markAsRollbackOnly(e);
- }
- }
- else {
- rejectMessage(delivery);
- }
- }
- else {
- serverSend(transaction, message, delivery, receiver);
- }
- }
-
- private void rejectMessage(Delivery delivery) {
- String address = delivery.getLink().getTarget().getAddress();
- ErrorCondition ec = new ErrorCondition(AmqpError.RESOURCE_LIMIT_EXCEEDED, "Address is full: " + address);
- Rejected rejected = new Rejected();
- rejected.setError(ec);
- delivery.disposition(rejected);
- connection.flush();
- }
-
- private void serverSend(final Transaction transaction, final ServerMessage message, final Delivery delivery, final Receiver receiver) throws Exception {
- try {
-
- message.putStringProperty(ActiveMQConnection.CONNECTION_ID_PROPERTY_NAME.toString(), receiver.getSession().getConnection().getRemoteContainer());
- serverSession.send(transaction, message, false, false);
-
- // FIXME Potential race here...
- manager.getServer().getStorageManager().afterCompleteOperations(new IOCallback() {
- @Override
- public void done() {
- synchronized (connection.getLock()) {
- delivery.disposition(Accepted.getInstance());
- delivery.settle();
- connection.flush();
- }
- }
-
- @Override
- public void onError(int errorCode, String errorMessage) {
- synchronized (connection.getLock()) {
- receiver.setCondition(new ErrorCondition(AmqpError.ILLEGAL_STATE, errorCode + ":" + errorMessage));
- connection.flush();
- }
- }
- });
- }
- finally {
- resetContext();
- }
- }
-
- @Override
- public String getPubSubPrefix() {
- return manager.getPubSubPrefix();
- }
-
- @Override
- public void offerProducerCredit(final String address, final int credits, final int threshold, final Receiver receiver) {
- try {
- final PagingStore store = manager.getServer().getPagingManager().getPageStore(new SimpleString(address));
- store.checkMemory(new Runnable() {
- @Override
- public void run() {
- if (receiver.getRemoteCredit() < threshold) {
- receiver.flow(credits);
- connection.flush();
- }
- }
- });
- }
- catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void deleteQueue(String queueName) throws Exception {
- manager.getServer().destroyQueue(new SimpleString(queueName));
- }
-
- private void resetContext() {
- manager.getServer().getStorageManager().setContext(null);
- }
-
- private void recoverContext() {
- manager.getServer().getStorageManager().setContext(serverSession.getSessionContext());
- }
-
- @Override
- public void sendProducerCreditsMessage(int credits, SimpleString address) {
- }
-
- @Override
- public boolean updateDeliveryCountAfterCancel(ServerConsumer consumer, MessageReference ref, boolean failed) {
- return false;
- }
-
- @Override
- public void sendProducerCreditsFailMessage(int credits, SimpleString address) {
- }
-
- @Override
- public int sendMessage(MessageReference ref, ServerMessage message, ServerConsumer consumer, int deliveryCount) {
-
- message.removeProperty(ActiveMQConnection.CONNECTION_ID_PROPERTY_NAME.toString());
-
- ProtonPlugSender plugSender = (ProtonPlugSender) consumer.getProtocolContext();
-
- try {
- return plugSender.deliverMessage(message, deliveryCount);
- }
- catch (Exception e) {
- synchronized (connection.getLock()) {
- plugSender.getSender().setCondition(new ErrorCondition(AmqpError.INTERNAL_ERROR, e.getMessage()));
- connection.flush();
- }
- throw new IllegalStateException("Can't deliver message " + e, e);
- }
-
- }
-
- @Override
- public int sendLargeMessage(MessageReference ref, ServerMessage message, ServerConsumer consumer, long bodySize, int deliveryCount) {
- return 0;
- }
-
- @Override
- public int sendLargeMessageContinuation(ServerConsumer consumer,
- byte[] body,
- boolean continues,
- boolean requiresResponse) {
- return 0;
- }
-
- @Override
- public void closed() {
- }
-
- @Override
- public void disconnect(ServerConsumer consumer, String queueName) {
- synchronized (connection.getLock()) {
- ((Link) consumer.getProtocolContext()).close();
- connection.flush();
- }
- }
-
- @Override
- public boolean hasCredits(ServerConsumer consumer) {
- ProtonPlugSender plugSender = (ProtonPlugSender) consumer.getProtocolContext();
-
- if (plugSender != null && plugSender.getSender().getCredit() > 0) {
- return true;
- }
- else {
- return false;
- }
- }
-
- @Override
- public Transaction getTransaction(Binary txid) throws ActiveMQAMQPException {
- return protonSPI.getTransaction(txid);
- }
-
- @Override
- public Binary newTransaction() {
- return protonSPI.newTransaction();
- }
-
-
- @Override
- public void commitTX(Binary txid) throws Exception {
- Transaction tx = protonSPI.getTransaction(txid);
- tx.commit(true);
- protonSPI.removeTransaction(txid);
- }
-
- @Override
- public void rollbackTX(Binary txid, boolean lastMessageReceived) throws Exception {
- Transaction tx = protonSPI.getTransaction(txid);
- tx.rollback();
- protonSPI.removeTransaction(txid);
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/sasl/ActiveMQPlainSASL.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/sasl/ActiveMQPlainSASL.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/sasl/ActiveMQPlainSASL.java
deleted file mode 100644
index bf4f043..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/sasl/ActiveMQPlainSASL.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.sasl;
-
-import org.apache.activemq.artemis.core.security.SecurityStore;
-import org.proton.plug.sasl.ServerSASLPlain;
-
-public class ActiveMQPlainSASL extends ServerSASLPlain {
-
- private final SecurityStore securityStore;
-
- public ActiveMQPlainSASL(SecurityStore securityStore) {
- this.securityStore = securityStore;
- }
-
- @Override
- protected boolean authenticate(String user, String password) {
- if (securityStore.isSecurityEnabled()) {
- try {
- securityStore.authenticate(user, password, null);
- return true;
- }
- catch (Exception e) {
- return false;
- }
- }
- else {
- return true;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPConnectionCallback.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPConnectionCallback.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPConnectionCallback.java
new file mode 100644
index 0000000..fd79547
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPConnectionCallback.java
@@ -0,0 +1,260 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.broker;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.core.buffers.impl.ChannelBufferWrapper;
+import org.apache.activemq.artemis.protocol.amqp.sasl.AnonymousServerSASL;
+import org.apache.activemq.artemis.protocol.amqp.sasl.PlainSASL;
+import org.apache.activemq.artemis.core.remoting.CloseListener;
+import org.apache.activemq.artemis.core.remoting.FailureListener;
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.core.transaction.Transaction;
+import org.apache.activemq.artemis.core.transaction.impl.TransactionImpl;
+import org.apache.activemq.artemis.core.transaction.impl.XidImpl;
+import org.apache.activemq.artemis.protocol.amqp.proton.AmqpSupport;
+import org.apache.activemq.artemis.spi.core.remoting.Connection;
+import org.apache.activemq.artemis.utils.ReusableLatch;
+import org.apache.activemq.artemis.utils.UUIDGenerator;
+import org.apache.qpid.proton.amqp.Binary;
+import org.apache.qpid.proton.amqp.Symbol;
+import org.apache.qpid.proton.amqp.transport.AmqpError;
+import org.jboss.logging.Logger;
+import org.apache.activemq.artemis.protocol.amqp.sasl.SASLResult;
+import org.apache.activemq.artemis.protocol.amqp.sasl.ServerSASL;
+import org.apache.activemq.artemis.protocol.amqp.proton.AMQPConnectionContext;
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPException;
+import org.apache.activemq.artemis.protocol.amqp.proton.handler.ExtCapability;
+import org.apache.activemq.artemis.protocol.amqp.logger.ActiveMQAMQPProtocolMessageBundle;
+
+public class AMQPConnectionCallback implements FailureListener, CloseListener {
+ private static final Logger logger = Logger.getLogger(AMQPConnectionCallback.class);
+
+ private ConcurrentMap<XidImpl, Transaction> transactions = new ConcurrentHashMap<>();
+
+ private final ProtonProtocolManager manager;
+
+ private final Connection connection;
+
+ protected ActiveMQProtonRemotingConnection protonConnectionDelegate;
+
+ protected AMQPConnectionContext amqpConnection;
+
+ private final ReusableLatch latch = new ReusableLatch(0);
+
+ private final Executor closeExecutor;
+
+ private String remoteContainerId;
+
+ private AtomicBoolean registeredConnectionId = new AtomicBoolean(false);
+
+ private ActiveMQServer server;
+
+ public AMQPConnectionCallback(ProtonProtocolManager manager,
+ Connection connection,
+ Executor closeExecutor,
+ ActiveMQServer server) {
+ this.manager = manager;
+ this.connection = connection;
+ this.closeExecutor = closeExecutor;
+ this.server = server;
+ }
+
+ public ServerSASL[] getSASLMechnisms() {
+
+ ServerSASL[] result;
+
+ if (isSupportsAnonymous()) {
+ result = new ServerSASL[]{new PlainSASL(manager.getServer().getSecurityStore()), new AnonymousServerSASL()};
+ }
+ else {
+ result = new ServerSASL[]{new PlainSASL(manager.getServer().getSecurityStore())};
+ }
+
+ return result;
+ }
+
+ public boolean isSupportsAnonymous() {
+ boolean supportsAnonymous = false;
+ try {
+ manager.getServer().getSecurityStore().authenticate(null, null, null);
+ supportsAnonymous = true;
+ }
+ catch (Exception e) {
+ // authentication failed so no anonymous support
+ }
+ return supportsAnonymous;
+ }
+
+ public void close() {
+ try {
+ if (registeredConnectionId.getAndSet(false)) {
+ server.removeClientConnection(remoteContainerId);
+ }
+ connection.close();
+ amqpConnection.close();
+ }
+ finally {
+ for (Transaction tx : transactions.values()) {
+ try {
+ tx.rollback();
+ }
+ catch (Exception e) {
+ logger.warn(e.getMessage(), e);
+ }
+ }
+ }
+ }
+
+ public Executor getExeuctor() {
+ if (protonConnectionDelegate != null) {
+ return protonConnectionDelegate.getExecutor();
+ }
+ else {
+ return null;
+ }
+ }
+
+ public void setConnection(AMQPConnectionContext connection) {
+ this.amqpConnection = connection;
+ }
+
+ public AMQPConnectionContext getConnection() {
+ return amqpConnection;
+ }
+
+ public ActiveMQProtonRemotingConnection getProtonConnectionDelegate() {
+ return protonConnectionDelegate;
+ }
+
+ public void setProtonConnectionDelegate(ActiveMQProtonRemotingConnection protonConnectionDelegate) {
+
+ this.protonConnectionDelegate = protonConnectionDelegate;
+ }
+
+ public void onTransport(ByteBuf byteBuf, AMQPConnectionContext amqpConnection) {
+ final int size = byteBuf.writerIndex();
+
+ latch.countUp();
+ connection.write(new ChannelBufferWrapper(byteBuf, true), false, false, new ChannelFutureListener() {
+ @Override
+ public void operationComplete(ChannelFuture future) throws Exception {
+ latch.countDown();
+ }
+ });
+
+ if (amqpConnection.isSyncOnFlush()) {
+ try {
+ latch.await(5, TimeUnit.SECONDS);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ amqpConnection.outputDone(size);
+ }
+
+ public AMQPSessionCallback createSessionCallback(AMQPConnectionContext connection) {
+ return new AMQPSessionCallback(this, manager, connection, this.connection, closeExecutor);
+ }
+
+ public void sendSASLSupported() {
+ connection.write(ActiveMQBuffers.wrappedBuffer(new byte[]{'A', 'M', 'Q', 'P', 3, 1, 0, 0}));
+ }
+
+ public boolean validateConnection(org.apache.qpid.proton.engine.Connection connection, SASLResult saslResult) {
+ remoteContainerId = connection.getRemoteContainer();
+ boolean idOK = server.addClientConnection(remoteContainerId, ExtCapability.needUniqueConnection(connection));
+ if (!idOK) {
+ //https://issues.apache.org/jira/browse/ARTEMIS-728
+ Map<Symbol, Object> connProp = new HashMap<>();
+ connProp.put(AmqpSupport.CONNECTION_OPEN_FAILED, "true");
+ connection.setProperties(connProp);
+ connection.getCondition().setCondition(AmqpError.INVALID_FIELD);
+ Map<Symbol, Symbol> info = new HashMap<>();
+ info.put(AmqpSupport.INVALID_FIELD, AmqpSupport.CONTAINER_ID);
+ connection.getCondition().setInfo(info);
+ return false;
+ }
+ registeredConnectionId.set(true);
+ return true;
+ }
+
+ @Override
+ public void connectionClosed() {
+ close();
+ }
+
+ @Override
+ public void connectionFailed(ActiveMQException exception, boolean failedOver) {
+ close();
+ }
+
+ @Override
+ public void connectionFailed(ActiveMQException exception, boolean failedOver, String scaleDownTargetNodeID) {
+ close();
+ }
+
+ public Binary newTransaction() {
+ XidImpl xid = newXID();
+ Transaction transaction = new TransactionImpl(xid, server.getStorageManager(), -1);
+ transactions.put(xid, transaction);
+ return new Binary(xid.getGlobalTransactionId());
+ }
+
+ public Transaction getTransaction(Binary txid) throws ActiveMQAMQPException {
+ XidImpl xid = newXID(txid.getArray());
+ Transaction tx = transactions.get(xid);
+
+ if (tx == null) {
+ throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.txNotFound(xid.toString());
+ }
+
+ return tx;
+ }
+
+ public void removeTransaction(Binary txid) {
+ XidImpl xid = newXID(txid.getArray());
+ transactions.remove(xid);
+ }
+
+
+ protected XidImpl newXID() {
+ return newXID(UUIDGenerator.getInstance().generateStringUUID().getBytes());
+ }
+
+ protected XidImpl newXID(byte[] bytes) {
+ return new XidImpl("amqp".getBytes(), 1, bytes);
+ }
+
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPSessionCallback.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPSessionCallback.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPSessionCallback.java
new file mode 100644
index 0000000..9bdf4e1
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPSessionCallback.java
@@ -0,0 +1,515 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.broker;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import io.netty.buffer.ByteBuf;
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.api.core.ActiveMQQueueExistsException;
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
+import org.apache.activemq.artemis.core.io.IOCallback;
+import org.apache.activemq.artemis.core.paging.PagingStore;
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPInternalErrorException;
+import org.apache.activemq.artemis.protocol.amqp.converter.message.EncodedMessage;
+import org.apache.activemq.artemis.core.server.BindingQueryResult;
+import org.apache.activemq.artemis.core.server.MessageReference;
+import org.apache.activemq.artemis.core.server.QueueQueryResult;
+import org.apache.activemq.artemis.core.server.ServerConsumer;
+import org.apache.activemq.artemis.core.server.ServerMessage;
+import org.apache.activemq.artemis.core.server.ServerSession;
+import org.apache.activemq.artemis.core.server.impl.ServerConsumerImpl;
+import org.apache.activemq.artemis.core.transaction.Transaction;
+import org.apache.activemq.artemis.jms.client.ActiveMQConnection;
+import org.apache.activemq.artemis.protocol.amqp.sasl.PlainSASLResult;
+import org.apache.activemq.artemis.spi.core.protocol.SessionCallback;
+import org.apache.activemq.artemis.spi.core.remoting.Connection;
+import org.apache.activemq.artemis.spi.core.remoting.ReadyListener;
+import org.apache.activemq.artemis.utils.IDGenerator;
+import org.apache.activemq.artemis.utils.SelectorTranslator;
+import org.apache.activemq.artemis.utils.SimpleIDGenerator;
+import org.apache.activemq.artemis.utils.UUIDGenerator;
+import org.apache.qpid.proton.amqp.Binary;
+import org.apache.qpid.proton.amqp.messaging.Accepted;
+import org.apache.qpid.proton.amqp.messaging.Rejected;
+import org.apache.qpid.proton.amqp.transport.AmqpError;
+import org.apache.qpid.proton.amqp.transport.ErrorCondition;
+import org.apache.qpid.proton.engine.Delivery;
+import org.apache.qpid.proton.engine.Link;
+import org.apache.qpid.proton.engine.Receiver;
+import org.apache.qpid.proton.message.ProtonJMessage;
+import org.apache.activemq.artemis.protocol.amqp.proton.AMQPSessionContext;
+import org.apache.activemq.artemis.protocol.amqp.sasl.SASLResult;
+import org.apache.activemq.artemis.protocol.amqp.proton.AMQPConnectionContext;
+import org.apache.activemq.artemis.protocol.amqp.proton.ProtonServerSenderContext;
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPException;
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPResourceLimitExceededException;
+
+public class AMQPSessionCallback implements SessionCallback {
+
+ protected final IDGenerator consumerIDGenerator = new SimpleIDGenerator(0);
+
+ private final AMQPConnectionCallback protonSPI;
+
+ private final ProtonProtocolManager manager;
+
+ private final AMQPConnectionContext connection;
+
+ private final Connection transportConnection;
+
+ private ServerSession serverSession;
+
+ private AMQPSessionContext protonSession;
+
+ private final Executor closeExecutor;
+
+ private final AtomicBoolean draining = new AtomicBoolean(false);
+
+ public AMQPSessionCallback(AMQPConnectionCallback protonSPI,
+ ProtonProtocolManager manager,
+ AMQPConnectionContext connection,
+ Connection transportConnection,
+ Executor executor) {
+ this.protonSPI = protonSPI;
+ this.manager = manager;
+ this.connection = connection;
+ this.transportConnection = transportConnection;
+ this.closeExecutor = executor;
+ }
+
+ @Override
+ public boolean isWritable(ReadyListener callback) {
+ return transportConnection.isWritable(callback);
+ }
+
+ public void onFlowConsumer(Object consumer, int credits, final boolean drain) {
+ ServerConsumerImpl serverConsumer = (ServerConsumerImpl) consumer;
+ if (drain) {
+ // If the draining is already running, then don't do anything
+ if (draining.compareAndSet(false, true)) {
+ final ProtonServerSenderContext plugSender = (ProtonServerSenderContext) serverConsumer.getProtocolContext();
+ serverConsumer.forceDelivery(1, new Runnable() {
+ @Override
+ public void run() {
+ try {
+ plugSender.getSender().drained();
+ }
+ finally {
+ draining.set(false);
+ }
+ }
+ });
+ }
+ }
+ else {
+ serverConsumer.receiveCredits(-1);
+ }
+ }
+
+ @Override
+ public void browserFinished(ServerConsumer consumer) {
+
+ }
+
+ public void init(AMQPSessionContext protonSession, SASLResult saslResult) throws Exception {
+
+ this.protonSession = protonSession;
+
+ String name = UUIDGenerator.getInstance().generateStringUUID();
+
+ String user = null;
+ String passcode = null;
+ if (saslResult != null) {
+ user = saslResult.getUser();
+ if (saslResult instanceof PlainSASLResult) {
+ passcode = ((PlainSASLResult) saslResult).getPassword();
+ }
+ }
+
+ serverSession = manager.getServer().createSession(name, user, passcode, ActiveMQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE, protonSPI.getProtonConnectionDelegate(), // RemotingConnection remotingConnection,
+ false, // boolean autoCommitSends
+ false, // boolean autoCommitAcks,
+ false, // boolean preAcknowledge,
+ true, //boolean xa,
+ (String) null, this, true);
+ }
+
+ @Override
+ public void afterDelivery() throws Exception {
+
+ }
+
+ public void start() {
+
+ }
+
+ public Object createSender(ProtonServerSenderContext protonSender,
+ String queue,
+ String filter,
+ boolean browserOnly) throws Exception {
+ long consumerID = consumerIDGenerator.generateID();
+
+ filter = SelectorTranslator.convertToActiveMQFilterString(filter);
+
+ ServerConsumer consumer = serverSession.createConsumer(consumerID, SimpleString.toSimpleString(queue), SimpleString.toSimpleString(filter), browserOnly);
+
+ // AMQP handles its own flow control for when it's started
+ consumer.setStarted(true);
+
+ consumer.setProtocolContext(protonSender);
+
+ return consumer;
+ }
+
+ public void startSender(Object brokerConsumer) throws Exception {
+ ServerConsumer serverConsumer = (ServerConsumer) brokerConsumer;
+ // flow control is done at proton
+ serverConsumer.receiveCredits(-1);
+ }
+
+ public void createTemporaryQueue(String queueName) throws Exception {
+ serverSession.createQueue(SimpleString.toSimpleString(queueName), SimpleString.toSimpleString(queueName), null, true, false);
+ }
+
+ public void createTemporaryQueue(String address, String queueName, String filter) throws Exception {
+ serverSession.createQueue(SimpleString.toSimpleString(address), SimpleString.toSimpleString(queueName), SimpleString.toSimpleString(filter), true, false);
+ }
+
+ public void createDurableQueue(String address, String queueName, String filter) throws Exception {
+ serverSession.createQueue(SimpleString.toSimpleString(address), SimpleString.toSimpleString(queueName), SimpleString.toSimpleString(filter), false, true);
+ }
+
+ public QueueQueryResult queueQuery(String queueName, boolean autoCreate) throws Exception {
+ QueueQueryResult queueQueryResult = serverSession.executeQueueQuery(SimpleString.toSimpleString(queueName));
+
+ if (!queueQueryResult.isExists() && queueQueryResult.isAutoCreateJmsQueues() && autoCreate) {
+ try {
+ serverSession.createQueue(new SimpleString(queueName), new SimpleString(queueName), null, false, true);
+ }
+ catch (ActiveMQQueueExistsException e) {
+ // The queue may have been created by another thread in the mean time. Catch and do nothing.
+ }
+ queueQueryResult = new QueueQueryResult(queueQueryResult.getName(), queueQueryResult.getAddress(), queueQueryResult.isDurable(), queueQueryResult.isTemporary(), queueQueryResult.getFilterString(), queueQueryResult.getConsumerCount(), queueQueryResult.getMessageCount(), queueQueryResult.isAutoCreateJmsQueues(), true);
+ }
+ return queueQueryResult;
+ }
+
+ public boolean bindingQuery(String address) throws Exception {
+ BindingQueryResult bindingQueryResult = serverSession.executeBindingQuery(SimpleString.toSimpleString(address));
+ if (!bindingQueryResult.isExists() && bindingQueryResult.isAutoCreateJmsQueues()) {
+ try {
+ serverSession.createQueue(new SimpleString(address), new SimpleString(address), null, false, true);
+ }
+ catch (ActiveMQQueueExistsException e) {
+ // The queue may have been created by another thread in the mean time. Catch and do nothing.
+ }
+ bindingQueryResult = serverSession.executeBindingQuery(SimpleString.toSimpleString(address));
+ }
+ return bindingQueryResult.isExists();
+ }
+
+ public void closeSender(final Object brokerConsumer) throws Exception {
+
+ final ServerConsumer consumer = ((ServerConsumer) brokerConsumer);
+ final CountDownLatch latch = new CountDownLatch(1);
+
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ consumer.close(false);
+ latch.countDown();
+ }
+ catch (Exception e) {
+ }
+ }
+ };
+
+ // Due to the nature of proton this could be happening within flushes from the queue-delivery (depending on how it happened on the protocol)
+ // to avoid deadlocks the close has to be done outside of the main thread on an executor
+ // otherwise you could get a deadlock
+ Executor executor = protonSPI.getExeuctor();
+
+ if (executor != null) {
+ executor.execute(runnable);
+ }
+ else {
+ runnable.run();
+ }
+
+ try {
+ latch.await(10, TimeUnit.SECONDS);
+ }
+ catch (InterruptedException e) {
+ throw new ActiveMQAMQPInternalErrorException("Unable to close consumers for queue: " + consumer.getQueue());
+ }
+ }
+
+ public ProtonJMessage encodeMessage(Object message, int deliveryCount) throws Exception {
+ return (ProtonJMessage) manager.getConverter().outbound((ServerMessage) message, deliveryCount);
+ }
+
+ public String tempQueueName() {
+ return UUIDGenerator.getInstance().generateStringUUID();
+ }
+
+ public void close() throws Exception {
+ //need to check here as this can be called if init fails
+ if (serverSession != null) {
+ recoverContext();
+ try {
+ serverSession.close(false);
+ }
+ finally {
+ resetContext();
+ }
+ }
+ }
+
+ public void ack(Transaction transaction, Object brokerConsumer, Object message) throws Exception {
+ if (transaction == null) {
+ transaction = serverSession.getCurrentTransaction();
+ }
+ recoverContext();
+ try {
+ ((ServerConsumer) brokerConsumer).individualAcknowledge(transaction, ((ServerMessage) message).getMessageID());
+ }
+ finally {
+ resetContext();
+ }
+ }
+
+ public void cancel(Object brokerConsumer, Object message, boolean updateCounts) throws Exception {
+ recoverContext();
+ try {
+ ((ServerConsumer) brokerConsumer).individualCancel(((ServerMessage) message).getMessageID(), updateCounts);
+ }
+ finally {
+ resetContext();
+ }
+ }
+
+ public void resumeDelivery(Object consumer) {
+ ((ServerConsumer) consumer).receiveCredits(-1);
+ }
+
+ public void serverSend(final Transaction transaction,
+ final Receiver receiver,
+ final Delivery delivery,
+ String address,
+ int messageFormat,
+ ByteBuf messageEncoded) throws Exception {
+ EncodedMessage encodedMessage = new EncodedMessage(messageFormat, messageEncoded.array(), messageEncoded.arrayOffset(), messageEncoded.writerIndex());
+
+ ServerMessage message = manager.getConverter().inbound(encodedMessage);
+ //use the address on the receiver if not null, if null let's hope it was set correctly on the message
+ if (address != null) {
+ message.setAddress(new SimpleString(address));
+ }
+
+ recoverContext();
+
+ PagingStore store = manager.getServer().getPagingManager().getPageStore(message.getAddress());
+ if (store.isRejectingMessages()) {
+ // We drop pre-settled messages (and abort any associated Tx)
+ if (delivery.remotelySettled()) {
+ if (transaction != null) {
+ String amqpAddress = delivery.getLink().getTarget().getAddress();
+ ActiveMQException e = new ActiveMQAMQPResourceLimitExceededException("Address is full: " + amqpAddress);
+ transaction.markAsRollbackOnly(e);
+ }
+ }
+ else {
+ rejectMessage(delivery);
+ }
+ }
+ else {
+ serverSend(transaction, message, delivery, receiver);
+ }
+ }
+
+ private void rejectMessage(Delivery delivery) {
+ String address = delivery.getLink().getTarget().getAddress();
+ ErrorCondition ec = new ErrorCondition(AmqpError.RESOURCE_LIMIT_EXCEEDED, "Address is full: " + address);
+ Rejected rejected = new Rejected();
+ rejected.setError(ec);
+ delivery.disposition(rejected);
+ connection.flush();
+ }
+
+ private void serverSend(final Transaction transaction, final ServerMessage message, final Delivery delivery, final Receiver receiver) throws Exception {
+ try {
+
+ message.putStringProperty(ActiveMQConnection.CONNECTION_ID_PROPERTY_NAME.toString(), receiver.getSession().getConnection().getRemoteContainer());
+ serverSession.send(transaction, message, false, false);
+
+ // FIXME Potential race here...
+ manager.getServer().getStorageManager().afterCompleteOperations(new IOCallback() {
+ @Override
+ public void done() {
+ synchronized (connection.getLock()) {
+ delivery.disposition(Accepted.getInstance());
+ delivery.settle();
+ connection.flush();
+ }
+ }
+
+ @Override
+ public void onError(int errorCode, String errorMessage) {
+ synchronized (connection.getLock()) {
+ receiver.setCondition(new ErrorCondition(AmqpError.ILLEGAL_STATE, errorCode + ":" + errorMessage));
+ connection.flush();
+ }
+ }
+ });
+ }
+ finally {
+ resetContext();
+ }
+ }
+
+ public String getPubSubPrefix() {
+ return manager.getPubSubPrefix();
+ }
+
+ public void offerProducerCredit(final String address, final int credits, final int threshold, final Receiver receiver) {
+ try {
+ final PagingStore store = manager.getServer().getPagingManager().getPageStore(new SimpleString(address));
+ store.checkMemory(new Runnable() {
+ @Override
+ public void run() {
+ if (receiver.getRemoteCredit() < threshold) {
+ receiver.flow(credits);
+ connection.flush();
+ }
+ }
+ });
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void deleteQueue(String queueName) throws Exception {
+ manager.getServer().destroyQueue(new SimpleString(queueName));
+ }
+
+ private void resetContext() {
+ manager.getServer().getStorageManager().setContext(null);
+ }
+
+ private void recoverContext() {
+ manager.getServer().getStorageManager().setContext(serverSession.getSessionContext());
+ }
+
+ @Override
+ public void sendProducerCreditsMessage(int credits, SimpleString address) {
+ }
+
+ @Override
+ public boolean updateDeliveryCountAfterCancel(ServerConsumer consumer, MessageReference ref, boolean failed) {
+ return false;
+ }
+
+ @Override
+ public void sendProducerCreditsFailMessage(int credits, SimpleString address) {
+ }
+
+ @Override
+ public int sendMessage(MessageReference ref, ServerMessage message, ServerConsumer consumer, int deliveryCount) {
+
+ message.removeProperty(ActiveMQConnection.CONNECTION_ID_PROPERTY_NAME.toString());
+
+ ProtonServerSenderContext plugSender = (ProtonServerSenderContext) consumer.getProtocolContext();
+
+ try {
+ return plugSender.deliverMessage(message, deliveryCount);
+ }
+ catch (Exception e) {
+ synchronized (connection.getLock()) {
+ plugSender.getSender().setCondition(new ErrorCondition(AmqpError.INTERNAL_ERROR, e.getMessage()));
+ connection.flush();
+ }
+ throw new IllegalStateException("Can't deliver message " + e, e);
+ }
+
+ }
+
+ @Override
+ public int sendLargeMessage(MessageReference ref, ServerMessage message, ServerConsumer consumer, long bodySize, int deliveryCount) {
+ return 0;
+ }
+
+ @Override
+ public int sendLargeMessageContinuation(ServerConsumer consumer,
+ byte[] body,
+ boolean continues,
+ boolean requiresResponse) {
+ return 0;
+ }
+
+ @Override
+ public void closed() {
+ }
+
+ @Override
+ public void disconnect(ServerConsumer consumer, String queueName) {
+ synchronized (connection.getLock()) {
+ ((Link) consumer.getProtocolContext()).close();
+ connection.flush();
+ }
+ }
+
+ @Override
+ public boolean hasCredits(ServerConsumer consumer) {
+ ProtonServerSenderContext plugSender = (ProtonServerSenderContext) consumer.getProtocolContext();
+
+ if (plugSender != null && plugSender.getSender().getCredit() > 0) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ public Transaction getTransaction(Binary txid) throws ActiveMQAMQPException {
+ return protonSPI.getTransaction(txid);
+ }
+
+ public Binary newTransaction() {
+ return protonSPI.newTransaction();
+ }
+
+
+ public void commitTX(Binary txid) throws Exception {
+ Transaction tx = protonSPI.getTransaction(txid);
+ tx.commit(true);
+ protonSPI.removeTransaction(txid);
+ }
+
+ public void rollbackTX(Binary txid, boolean lastMessageReceived) throws Exception {
+ Transaction tx = protonSPI.getTransaction(txid);
+ tx.rollback();
+ protonSPI.removeTransaction(txid);
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/ActiveMQProtonRemotingConnection.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/ActiveMQProtonRemotingConnection.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/ActiveMQProtonRemotingConnection.java
new file mode 100644
index 0000000..8fd3169
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/ActiveMQProtonRemotingConnection.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.broker;
+
+import java.util.concurrent.Executor;
+
+import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
+import org.apache.activemq.artemis.api.core.ActiveMQException;
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.core.client.ActiveMQClientLogger;
+import org.apache.activemq.artemis.spi.core.protocol.AbstractRemotingConnection;
+import org.apache.activemq.artemis.spi.core.remoting.Connection;
+import org.apache.activemq.artemis.protocol.amqp.proton.AMQPConnectionContext;
+
+/**
+ * This is a Server's Connection representation used by ActiveMQ Artemis.
+ */
+public class ActiveMQProtonRemotingConnection extends AbstractRemotingConnection {
+
+ private final AMQPConnectionContext amqpConnection;
+
+ private boolean destroyed = false;
+
+ private final ProtonProtocolManager manager;
+
+ public ActiveMQProtonRemotingConnection(ProtonProtocolManager manager,
+ AMQPConnectionContext amqpConnection,
+ Connection transportConnection,
+ Executor executor) {
+ super(transportConnection, executor);
+ this.manager = manager;
+ this.amqpConnection = amqpConnection;
+ }
+
+ public Executor getExecutor() {
+ return this.executor;
+ }
+
+ public ProtonProtocolManager getManager() {
+ return manager;
+ }
+
+ /*
+ * This can be called concurrently by more than one thread so needs to be locked
+ */
+ @Override
+ public void fail(final ActiveMQException me, String scaleDownTargetNodeID) {
+ if (destroyed) {
+ return;
+ }
+
+ destroyed = true;
+
+ ActiveMQClientLogger.LOGGER.connectionFailureDetected(me.getMessage(), me.getType());
+
+ // Then call the listeners
+ callFailureListeners(me, scaleDownTargetNodeID);
+
+ callClosingListeners();
+
+ internalClose();
+ }
+
+ @Override
+ public void destroy() {
+ synchronized (this) {
+ if (destroyed) {
+ return;
+ }
+
+ destroyed = true;
+ }
+
+ callClosingListeners();
+
+ internalClose();
+
+ }
+
+ @Override
+ public boolean isClient() {
+ return false;
+ }
+
+ @Override
+ public boolean isDestroyed() {
+ return destroyed;
+ }
+
+ @Override
+ public void disconnect(boolean criticalError) {
+ getTransportConnection().close();
+ }
+
+ /**
+ * Disconnect the connection, closing all channels
+ */
+ @Override
+ public void disconnect(String scaleDownNodeID, boolean criticalError) {
+ getTransportConnection().close();
+ }
+
+ @Override
+ public boolean checkDataReceived() {
+ return amqpConnection.checkDataReceived();
+ }
+
+ @Override
+ public void flush() {
+ amqpConnection.flush();
+ }
+
+ @Override
+ public void bufferReceived(Object connectionID, ActiveMQBuffer buffer) {
+ amqpConnection.inputBuffer(buffer.byteBuf());
+ super.bufferReceived(connectionID, buffer);
+ }
+
+ private void internalClose() {
+ // We close the underlying transport connection
+ getTransportConnection().close();
+ }
+
+ @Override
+ public void killMessage(SimpleString nodeID) {
+ //unsupported
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/ProtonProtocolManager.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/ProtonProtocolManager.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/ProtonProtocolManager.java
new file mode 100644
index 0000000..fe7b976
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/ProtonProtocolManager.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.broker;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+import io.netty.channel.ChannelPipeline;
+import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
+import org.apache.activemq.artemis.api.core.BaseInterceptor;
+import org.apache.activemq.artemis.api.core.Interceptor;
+import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
+import org.apache.activemq.artemis.protocol.amqp.proton.AMQPConstants;
+import org.apache.activemq.artemis.protocol.amqp.converter.ProtonMessageConverter;
+import org.apache.activemq.artemis.core.remoting.impl.netty.NettyServerConnection;
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.core.server.management.Notification;
+import org.apache.activemq.artemis.core.server.management.NotificationListener;
+import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
+import org.apache.activemq.artemis.spi.core.protocol.ConnectionEntry;
+import org.apache.activemq.artemis.spi.core.protocol.MessageConverter;
+import org.apache.activemq.artemis.spi.core.protocol.ProtocolManager;
+import org.apache.activemq.artemis.spi.core.protocol.ProtocolManagerFactory;
+import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
+import org.apache.activemq.artemis.spi.core.remoting.Acceptor;
+import org.apache.activemq.artemis.spi.core.remoting.Connection;
+import org.apache.activemq.artemis.protocol.amqp.proton.AMQPConnectionContext;
+
+/**
+ * A proton protocol manager, basically reads the Proton Input and maps proton resources to ActiveMQ Artemis resources
+ */
+public class ProtonProtocolManager implements ProtocolManager<Interceptor>, NotificationListener {
+
+ private static final List<String> websocketRegistryNames = Arrays.asList("amqp");
+
+ private final ActiveMQServer server;
+
+ private MessageConverter protonConverter;
+
+ private final ProtonProtocolManagerFactory factory;
+
+ /*
+ * used when you want to treat senders as a subscription on an address rather than consuming from the actual queue for
+ * the address. This can be changed on the acceptor.
+ * */
+ private String pubSubPrefix = ActiveMQDestination.JMS_TOPIC_ADDRESS_PREFIX;
+
+ private int maxFrameSize = AMQPConstants.Connection.DEFAULT_MAX_FRAME_SIZE;
+
+ public ProtonProtocolManager(ProtonProtocolManagerFactory factory, ActiveMQServer server) {
+ this.factory = factory;
+ this.server = server;
+ this.protonConverter = new ProtonMessageConverter(server.getStorageManager());
+ }
+
+ public ActiveMQServer getServer() {
+ return server;
+ }
+
+ @Override
+ public MessageConverter getConverter() {
+ return protonConverter;
+ }
+
+ @Override
+ public void onNotification(Notification notification) {
+
+ }
+
+ @Override
+ public ProtocolManagerFactory<Interceptor> getFactory() {
+ return factory;
+ }
+
+ @Override
+ public void updateInterceptors(List<BaseInterceptor> incomingInterceptors,
+ List<BaseInterceptor> outgoingInterceptors) {
+ // no op
+ }
+
+ @Override
+ public boolean acceptsNoHandshake() {
+ return false;
+ }
+
+ @Override
+ public ConnectionEntry createConnectionEntry(Acceptor acceptorUsed, Connection remotingConnection) {
+ AMQPConnectionCallback connectionCallback = new AMQPConnectionCallback(this, remotingConnection, server.getExecutorFactory().getExecutor(), server);
+ long ttl = ActiveMQClient.DEFAULT_CONNECTION_TTL;
+
+ if (server.getConfiguration().getConnectionTTLOverride() != -1) {
+ ttl = server.getConfiguration().getConnectionTTLOverride();
+ }
+
+ String id = server.getConfiguration().getName();
+ AMQPConnectionContext amqpConnection =
+ new AMQPConnectionContext(connectionCallback, id, (int) ttl, getMaxFrameSize(), AMQPConstants.Connection.DEFAULT_CHANNEL_MAX, server.getExecutorFactory().getExecutor(), server.getScheduledPool());
+
+ Executor executor = server.getExecutorFactory().getExecutor();
+
+ ActiveMQProtonRemotingConnection delegate = new ActiveMQProtonRemotingConnection(this, amqpConnection, remotingConnection, executor);
+
+ connectionCallback.setProtonConnectionDelegate(delegate);
+
+ ConnectionEntry entry = new ConnectionEntry(delegate, executor, System.currentTimeMillis(), ttl);
+
+ return entry;
+ }
+
+ @Override
+ public void removeHandler(String name) {
+
+ }
+
+ @Override
+ public void handleBuffer(RemotingConnection connection, ActiveMQBuffer buffer) {
+ ActiveMQProtonRemotingConnection protonConnection = (ActiveMQProtonRemotingConnection) connection;
+
+ protonConnection.bufferReceived(protonConnection.getID(), buffer);
+ }
+
+ @Override
+ public void addChannelHandlers(ChannelPipeline pipeline) {
+
+ }
+
+ @Override
+ public boolean isProtocol(byte[] array) {
+ return array.length >= 4 && array[0] == (byte) 'A' && array[1] == (byte) 'M' && array[2] == (byte) 'Q' && array[3] == (byte) 'P';
+ }
+
+ @Override
+ public void handshake(NettyServerConnection connection, ActiveMQBuffer buffer) {
+ }
+
+ @Override
+ public List<String> websocketSubprotocolIdentifiers() {
+ return websocketRegistryNames;
+ }
+
+ public String getPubSubPrefix() {
+ return pubSubPrefix;
+ }
+
+ public void setPubSubPrefix(String pubSubPrefix) {
+ this.pubSubPrefix = pubSubPrefix;
+ }
+
+
+ public int getMaxFrameSize() {
+ return maxFrameSize;
+ }
+
+ public void setMaxFrameSize(int maxFrameSize) {
+ this.maxFrameSize = maxFrameSize;
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/ProtonProtocolManagerFactory.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/ProtonProtocolManagerFactory.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/ProtonProtocolManagerFactory.java
new file mode 100644
index 0000000..7255ca0
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/ProtonProtocolManagerFactory.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.broker;
+
+import org.apache.activemq.artemis.api.core.BaseInterceptor;
+import org.apache.activemq.artemis.api.core.Interceptor;
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.spi.core.protocol.AbstractProtocolManagerFactory;
+import org.apache.activemq.artemis.spi.core.protocol.ProtocolManager;
+import org.apache.activemq.artemis.spi.core.protocol.ProtocolManagerFactory;
+import org.apache.activemq.artemis.utils.uri.BeanSupport;
+import org.osgi.service.component.annotations.Component;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+@Component(service = ProtocolManagerFactory.class)
+public class ProtonProtocolManagerFactory extends AbstractProtocolManagerFactory<Interceptor> {
+
+ private static final String AMQP_PROTOCOL_NAME = "AMQP";
+
+ private static final String MODULE_NAME = "artemis-amqp-protocol";
+
+ private static String[] SUPPORTED_PROTOCOLS = {AMQP_PROTOCOL_NAME};
+
+ @Override
+ public ProtocolManager createProtocolManager(ActiveMQServer server,
+ final Map<String, Object> parameters,
+ List<BaseInterceptor> incomingInterceptors,
+ List<BaseInterceptor> outgoingInterceptors) throws Exception {
+ return BeanSupport.setData(new ProtonProtocolManager(this, server), parameters);
+ }
+
+ @Override
+ public List<Interceptor> filterInterceptors(List<BaseInterceptor> interceptors) {
+ // no interceptors on Proton
+ return Collections.emptyList();
+ }
+
+ @Override
+ public String[] getProtocols() {
+ return SUPPORTED_PROTOCOLS;
+ }
+
+ @Override
+ public String getModuleName() {
+ return MODULE_NAME;
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/package-info.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/package-info.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/package-info.java
new file mode 100644
index 0000000..c8a3c6a
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+/**
+ * This package includes classes used to interact with the broker.
+ * The ProtocolManager will be here, and some classes that will interact with the PostOffice
+ * and other internal components directly.
+ */
+package org.apache.activemq.artemis.protocol.amqp.broker;
\ No newline at end of file
[04/15] activemq-artemis git commit: ARTEMIS-751 Simplification of
the AMQP implementation
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalclient/SimpleAMQPConnector.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalclient/SimpleAMQPConnector.java b/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalclient/SimpleAMQPConnector.java
deleted file mode 100644
index 59772f0..0000000
--- a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalclient/SimpleAMQPConnector.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.test.minimalclient;
-
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.concurrent.Executors;
-
-import io.netty.bootstrap.Bootstrap;
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelDuplexHandler;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.nio.NioSocketChannel;
-import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
-import org.proton.plug.AMQPClientConnectionContext;
-import org.proton.plug.context.client.ProtonClientConnectionContextFactory;
-
-public class SimpleAMQPConnector implements Connector {
-
- private Bootstrap bootstrap;
-
- @Override
- public void start() {
-
- bootstrap = new Bootstrap();
- bootstrap.channel(NioSocketChannel.class);
- bootstrap.group(new NioEventLoopGroup(10));
-
- bootstrap.handler(new ChannelInitializer<Channel>() {
- @Override
- public void initChannel(Channel channel) throws Exception {
- }
- });
- }
-
- @Override
- public AMQPClientConnectionContext connect(String host, int port) throws Exception {
- SocketAddress remoteDestination = new InetSocketAddress(host, port);
-
- ChannelFuture future = bootstrap.connect(remoteDestination);
-
- future.awaitUninterruptibly();
-
- AMQPClientSPI clientConnectionSPI = new AMQPClientSPI(future.channel());
-
- final AMQPClientConnectionContext connection = (AMQPClientConnectionContext) ProtonClientConnectionContextFactory.getFactory().createConnection(clientConnectionSPI, Executors.newSingleThreadExecutor(ActiveMQThreadFactory.defaultThreadFactory()), null);
-
- future.channel().pipeline().addLast(new ChannelDuplexHandler() {
- @Override
- public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
- ByteBuf buffer = (ByteBuf) msg;
- connection.inputBuffer(buffer);
- }
- });
-
- return connection;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalserver/DumbServer.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalserver/DumbServer.java b/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalserver/DumbServer.java
deleted file mode 100644
index 10499ef..0000000
--- a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalserver/DumbServer.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.test.minimalserver;
-
-import java.util.concurrent.BlockingDeque;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.LinkedBlockingDeque;
-
-public class DumbServer {
-
- static ConcurrentMap<String, BlockingDeque<Object>> maps = new ConcurrentHashMap<>();
-
- public static BlockingDeque<Object> getQueue(String name) {
- BlockingDeque<Object> q = maps.get(name);
- if (q == null) {
- q = new LinkedBlockingDeque<>();
- BlockingDeque<Object> oldValue = maps.putIfAbsent(name, q);
- if (oldValue != null) {
- q = oldValue;
- }
- }
- return q;
- }
-
- public static void clear() {
- for (BlockingDeque<Object> queue : maps.values()) {
- // We clear the queues just in case there is a component holding it
- queue.clear();
- }
- maps.clear();
- }
-
- public static void put(String queue, Object message) {
- getQueue(queue).add(message);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalserver/MinimalConnectionSPI.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalserver/MinimalConnectionSPI.java b/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalserver/MinimalConnectionSPI.java
deleted file mode 100644
index 6325ad7..0000000
--- a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalserver/MinimalConnectionSPI.java
+++ /dev/null
@@ -1,171 +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.proton.plug.test.minimalserver;
-
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelFutureListener;
-import org.apache.activemq.artemis.core.transaction.Transaction;
-import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
-import org.apache.qpid.proton.amqp.Binary;
-import org.apache.qpid.proton.engine.Connection;
-import org.jboss.logging.Logger;
-import org.proton.plug.AMQPConnectionContext;
-import org.proton.plug.AMQPConnectionCallback;
-import org.proton.plug.AMQPSessionCallback;
-import org.proton.plug.SASLResult;
-import org.proton.plug.ServerSASL;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-import org.proton.plug.sasl.AnonymousServerSASL;
-import org.proton.plug.sasl.ServerSASLPlain;
-import org.proton.plug.util.ByteUtil;
-import org.proton.plug.util.ReusableLatch;
-
-public class MinimalConnectionSPI implements AMQPConnectionCallback {
-
- private static final Logger logger = Logger.getLogger(MinimalConnectionSPI.class);
- Channel channel;
-
- private AMQPConnectionContext connection;
-
- public MinimalConnectionSPI(Channel channel) {
- this.channel = channel;
- }
-
- ExecutorService executorService = Executors.newSingleThreadExecutor(ActiveMQThreadFactory.defaultThreadFactory());
-
- @Override
- public void close() {
- executorService.shutdown();
- }
-
- @Override
- public void setConnection(AMQPConnectionContext connection) {
- this.connection = connection;
- }
-
- @Override
- public AMQPConnectionContext getConnection() {
- return connection;
- }
-
- final ReusableLatch latch = new ReusableLatch(0);
-
- @Override
- public ServerSASL[] getSASLMechnisms() {
- return new ServerSASL[]{new AnonymousServerSASL(), new ServerSASLPlain()};
- }
-
- @Override
- public boolean isSupportsAnonymous() {
- return true;
- }
-
- @Override
- public void sendSASLSupported() {
-
- }
-
- @Override
- public boolean validateConnection(Connection connection, SASLResult saslResult) {
- return true;
- }
-
- @Override
- public Binary newTransaction() {
- return null;
- }
-
- @Override
- public Transaction getTransaction(Binary txid) throws ActiveMQAMQPException {
- return null;
- }
-
- @Override
- public void removeTransaction(Binary txid) {
-
- }
-
- @Override
- public void onTransport(final ByteBuf bytes, final AMQPConnectionContext connection) {
- final int bufferSize = bytes.writerIndex();
-
- if (logger.isTraceEnabled()) {
- // some debug
- byte[] frame = new byte[bytes.writerIndex()];
- int readerOriginalPos = bytes.readerIndex();
-
- bytes.getBytes(0, frame);
-
- try {
- System.err.println("Buffer Outgoing: " + "\n" + ByteUtil.formatGroup(ByteUtil.bytesToHex(frame), 4, 16));
- }
- catch (Exception e) {
- e.printStackTrace();
- }
-
- bytes.readerIndex(readerOriginalPos);
- }
-
- latch.countUp();
- // ^^ debug
-
- channel.writeAndFlush(bytes).addListener(new ChannelFutureListener() {
- @Override
- public void operationComplete(ChannelFuture future) throws Exception {
- latch.countDown();
-
- // https://issues.apache.org/jira/browse/PROTON-645
- // connection.outputDone(bufferSize);
- // if (connection.capacity() > 0)
- // {
- // channel.read();
- // }
- }
- });
-
- channel.flush();
-
- if (connection.isSyncOnFlush()) {
- try {
- if (!latch.await(5, TimeUnit.SECONDS)) {
- // TODO logs
- System.err.println("Flush took longer than 5 seconds!!!");
- }
- }
- catch (Throwable e) {
- e.printStackTrace();
- }
- }
- connection.outputDone(bufferSize);
-
- // if (connection.capacity() > 0)
- // {
- // channel.read();
- // }
- }
-
- @Override
- public AMQPSessionCallback createSessionCallback(AMQPConnectionContext connection) {
- return new MinimalSessionSPI();
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalserver/MinimalServer.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalserver/MinimalServer.java b/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalserver/MinimalServer.java
deleted file mode 100644
index 8729cb4..0000000
--- a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalserver/MinimalServer.java
+++ /dev/null
@@ -1,167 +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.proton.plug.test.minimalserver;
-
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.List;
-import java.util.concurrent.Executors;
-
-import io.netty.bootstrap.ServerBootstrap;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.PooledByteBufAllocator;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.ChannelOption;
-import io.netty.channel.ChannelPipeline;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.ServerChannel;
-import io.netty.channel.group.ChannelGroup;
-import io.netty.channel.group.ChannelGroupFuture;
-import io.netty.channel.group.DefaultChannelGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.nio.NioServerSocketChannel;
-import io.netty.handler.codec.ByteToMessageDecoder;
-import io.netty.util.ResourceLeakDetector;
-import io.netty.util.concurrent.GlobalEventExecutor;
-
-import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
-import org.proton.plug.AMQPServerConnectionContext;
-import org.proton.plug.context.server.ProtonServerConnectionContextFactory;
-import org.proton.plug.test.Constants;
-
-/**
- * A Netty TCP Acceptor that supports SSL
- */
-public class MinimalServer {
-
- static {
- // Disable resource leak detection for performance reasons by default
- ResourceLeakDetector.setEnabled(false);
- }
-
- private Class<? extends ServerChannel> channelClazz;
-
- private EventLoopGroup eventLoopGroup;
-
- private volatile ChannelGroup serverChannelGroup;
-
- private volatile ChannelGroup channelGroup;
-
- private ServerBootstrap bootstrap;
-
- private String host;
-
- private boolean sasl;
-
- // Constants.PORT is the default here
- private int port;
-
- public synchronized void start(String host, int port, final boolean sasl) throws Exception {
- this.host = host;
- this.port = port;
- this.sasl = sasl;
-
- if (channelClazz != null) {
- // Already started
- return;
- }
-
- int threadsToUse = Runtime.getRuntime().availableProcessors() * 3;
- channelClazz = NioServerSocketChannel.class;
- eventLoopGroup = new NioEventLoopGroup(threadsToUse, new SimpleServerThreadFactory("simple-server", true, Thread.currentThread().getContextClassLoader()));
-
- bootstrap = new ServerBootstrap();
- bootstrap.group(eventLoopGroup);
- bootstrap.channel(channelClazz);
-
- ChannelInitializer<Channel> factory = new ChannelInitializer<Channel>() {
- @Override
- public void initChannel(Channel channel) throws Exception {
- ChannelPipeline pipeline = channel.pipeline();
- pipeline.addLast("amqp-handler", new ProtocolDecoder());
- }
- };
- bootstrap.childHandler(factory);
-
- bootstrap.option(ChannelOption.SO_REUSEADDR, true).
- childOption(ChannelOption.SO_REUSEADDR, true).
- childOption(ChannelOption.SO_KEEPALIVE, true).
- // childOption(ChannelOption.AUTO_READ, false).
- childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
-
- channelGroup = new DefaultChannelGroup("activemq-accepted-channels", GlobalEventExecutor.INSTANCE);
-
- serverChannelGroup = new DefaultChannelGroup("activemq-acceptor-channels", GlobalEventExecutor.INSTANCE);
-
- SocketAddress address;
- address = new InetSocketAddress(host, port);
- Channel serverChannel = bootstrap.bind(address).syncUninterruptibly().channel();
- serverChannelGroup.add(serverChannel);
-
- }
-
- class ProtocolDecoder extends ByteToMessageDecoder {
-
- AMQPServerConnectionContext connection;
-
- ProtocolDecoder() {
- }
-
- @Override
- public void channelActive(ChannelHandlerContext ctx) throws Exception {
- super.channelActive(ctx);
- connection = ProtonServerConnectionContextFactory.getFactory().createConnection(new MinimalConnectionSPI(ctx.channel()), Executors.newSingleThreadExecutor(ActiveMQThreadFactory.defaultThreadFactory()), null);
- //ctx.read();
- }
-
- @Override
- protected void decode(final ChannelHandlerContext ctx, ByteBuf byteIn, List<Object> out) throws Exception {
- connection.inputBuffer(byteIn);
- ctx.flush();
- // if (connection.capacity() > 0)
- // {
- // ctx.read();
- // }
- }
- }
-
- public synchronized void stop() {
- if (serverChannelGroup != null) {
- serverChannelGroup.close().awaitUninterruptibly();
- }
-
- if (channelGroup != null) {
- ChannelGroupFuture future = channelGroup.close().awaitUninterruptibly();
- }
- }
-
- public static void main(String[] arg) {
- MinimalServer server = new MinimalServer();
- try {
- server.start("127.0.0.1", Constants.PORT, true);
-
- while (true) {
- Thread.sleep(360000000);
- }
- }
- catch (Throwable e) {
- e.printStackTrace();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalserver/MinimalSessionSPI.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalserver/MinimalSessionSPI.java b/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalserver/MinimalSessionSPI.java
deleted file mode 100644
index d366c5b..0000000
--- a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalserver/MinimalSessionSPI.java
+++ /dev/null
@@ -1,229 +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.proton.plug.test.minimalserver;
-
-import java.util.concurrent.BlockingDeque;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import io.netty.buffer.ByteBuf;
-import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.persistence.impl.nullpm.NullStorageManager;
-import org.apache.activemq.artemis.core.server.QueueQueryResult;
-import org.apache.activemq.artemis.core.transaction.Transaction;
-import org.apache.activemq.artemis.core.transaction.impl.TransactionImpl;
-import org.apache.qpid.proton.amqp.Binary;
-import org.apache.qpid.proton.engine.Delivery;
-import org.apache.qpid.proton.engine.Receiver;
-import org.apache.qpid.proton.message.ProtonJMessage;
-import org.proton.plug.AMQPSessionCallback;
-import org.proton.plug.AMQPSessionContext;
-import org.proton.plug.SASLResult;
-import org.proton.plug.context.ProtonPlugSender;
-import org.proton.plug.context.server.ProtonServerSessionContext;
-import org.proton.plug.util.ProtonServerMessage;
-
-public class MinimalSessionSPI implements AMQPSessionCallback {
-
- private SASLResult result;
- ProtonServerSessionContext session;
-
- @Override
- public void init(AMQPSessionContext session, SASLResult result) {
- this.session = (ProtonServerSessionContext) session;
- this.result = result;
- }
-
- @Override
- public void start() {
- }
-
- static AtomicInteger tempQueueGenerator = new AtomicInteger(0);
-
- @Override
- public String tempQueueName() {
- return "TempQueueName" + tempQueueGenerator.incrementAndGet();
- }
-
- @Override
- public Object createSender(ProtonPlugSender plugSender, String queue, String filer, boolean browserOnly) {
- Consumer consumer = new Consumer(DumbServer.getQueue(queue));
- return consumer;
- }
-
- @Override
- public void startSender(Object brokerConsumer) {
- ((Consumer) brokerConsumer).start();
- }
-
- @Override
- public void createTemporaryQueue(String queueName) {
-
- }
-
- @Override
- public void createDurableQueue(String address, String queueName, String filter) throws Exception {
-
- }
-
- @Override
- public void offerProducerCredit(String address, int credits, int threshold, Receiver receiver) {
-
- }
-
- @Override
- public void createTemporaryQueue(String address, String queueName, String filter) throws Exception {
-
- }
-
- @Override
- public void deleteQueue(String address) throws Exception {
-
- }
-
- @Override
- public String getPubSubPrefix() {
- return null;
- }
-
- @Override
- public void onFlowConsumer(Object consumer, int credits, boolean drain) {
- }
-
- @Override
- public QueueQueryResult queueQuery(String queueName, boolean autoCreate) {
- return new QueueQueryResult(SimpleString.toSimpleString(queueName), SimpleString.toSimpleString(queueName), false, false, null, 0, 0, false);
- }
-
- @Override
- public boolean bindingQuery(String address) throws Exception {
- return true;
- }
-
- @Override
- public void closeSender(Object brokerConsumer) {
- ((Consumer) brokerConsumer).close();
- }
-
- @Override
- public ProtonJMessage encodeMessage(Object message, int deliveryCount) {
- // We are storing internally as EncodedMessage on this minimalserver server
- return (ProtonServerMessage) message;
- }
-
- @Override
- public Transaction getTransaction(Binary txid) {
- return new TransactionImpl(new NullStorageManager());
- }
-
- @Override
- public Binary newTransaction() {
- return null;
- }
-
- @Override
- public void commitTX(Binary txid) throws Exception {
-
- }
-
- @Override
- public void rollbackTX(Binary txid, boolean lastMessageReceived) throws Exception {
-
- }
-
- @Override
- public void close() {
-
- }
-
- @Override
- public void ack(Transaction tx, Object brokerConsumer, Object message) {
-
- }
-
- @Override
- public void cancel(Object brokerConsumer, Object message, boolean updateCounts) {
-
- }
-
- @Override
- public void resumeDelivery(Object consumer) {
- System.out.println("Resume delivery!!!");
- ((Consumer) consumer).start();
- }
-
- @Override
- public void serverSend(Transaction tx, Receiver receiver, Delivery delivery, String address, int messageFormat, ByteBuf buffer) {
- ProtonServerMessage serverMessage = new ProtonServerMessage();
- serverMessage.decode(buffer.nioBuffer());
-
- BlockingDeque<Object> queue = DumbServer.getQueue(address);
- queue.add(serverMessage);
- }
-
- class Consumer {
-
- final BlockingDeque<Object> queue;
-
- Consumer(BlockingDeque<Object> queue) {
- this.queue = queue;
- }
-
- boolean running = false;
- volatile Thread thread;
-
- public void close() {
- System.out.println("Closing!!!");
- running = false;
- if (thread != null && Thread.currentThread() != thread) {
- try {
- thread.join(1000);
- }
- catch (Throwable ignored) {
- }
- }
-
- thread = null;
- }
-
- public synchronized void start() {
- running = true;
- if (thread == null) {
- System.out.println("Start!!!");
- thread = new Thread() {
- @Override
- public void run() {
- try {
- while (running) {
- Object msg = queue.poll(1, TimeUnit.SECONDS);
-
- if (msg != null) {
- session.serverDelivery(msg, Consumer.this, 1);
- }
- }
- }
- catch (Exception e) {
- e.printStackTrace();
- }
- }
- };
- thread.start();
- }
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalserver/SimpleServerThreadFactory.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalserver/SimpleServerThreadFactory.java b/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalserver/SimpleServerThreadFactory.java
deleted file mode 100644
index ac1d28f..0000000
--- a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalserver/SimpleServerThreadFactory.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.test.minimalserver;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.atomic.AtomicInteger;
-
-public final class SimpleServerThreadFactory implements ThreadFactory {
-
- private final ThreadGroup group;
-
- private final AtomicInteger threadCount = new AtomicInteger(0);
-
- private final int threadPriority;
-
- private final boolean daemon;
-
- private final ClassLoader tccl;
-
- public SimpleServerThreadFactory(final String groupName, final boolean daemon, final ClassLoader tccl) {
- group = new ThreadGroup(groupName + "-" + System.identityHashCode(this));
-
- this.threadPriority = Thread.NORM_PRIORITY;
-
- this.tccl = tccl;
-
- this.daemon = daemon;
- }
-
- @Override
- public Thread newThread(final Runnable command) {
- final Thread t;
- // attach the thread to a group only if there is no security manager:
- // when sandboxed, the code does not have the RuntimePermission modifyThreadGroup
- if (System.getSecurityManager() == null) {
- t = new Thread(group, command, "Thread-" + threadCount.getAndIncrement() + " (" + group.getName() + ")");
- }
- else {
- t = new Thread(command, "Thread-" + threadCount.getAndIncrement());
- }
-
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- @Override
- public Object run() {
- t.setDaemon(daemon);
- t.setPriority(threadPriority);
- return null;
- }
- });
-
- try {
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- @Override
- public Object run() {
- t.setContextClassLoader(tccl);
- return null;
- }
- });
- }
- catch (java.security.AccessControlException e) {
- e.printStackTrace();
- }
-
- return t;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/sasl/PlainSASLTest.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/sasl/PlainSASLTest.java b/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/sasl/PlainSASLTest.java
deleted file mode 100644
index a085eab..0000000
--- a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/sasl/PlainSASLTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.test.sasl;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.proton.plug.sasl.ClientSASLPlain;
-import org.proton.plug.sasl.PlainSASLResult;
-import org.proton.plug.sasl.ServerSASLPlain;
-
-public class PlainSASLTest {
-
- @Test
- public void testPlain() {
- ClientSASLPlain plainSASL = new ClientSASLPlain("user-me", "password-secret");
- byte[] bytesResult = plainSASL.getBytes();
-
- ServerSASLPlain serverSASLPlain = new ServerSASLPlain();
- PlainSASLResult result = (PlainSASLResult) serverSASLPlain.processSASL(bytesResult);
- Assert.assertEquals("user-me", result.getUser());
- Assert.assertEquals("password-secret", result.getPassword());
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/util/CreditsSemaphoreTest.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/util/CreditsSemaphoreTest.java b/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/util/CreditsSemaphoreTest.java
deleted file mode 100644
index b7ae38b..0000000
--- a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/util/CreditsSemaphoreTest.java
+++ /dev/null
@@ -1,135 +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.proton.plug.test.util;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.proton.plug.util.CreditsSemaphore;
-
-public class CreditsSemaphoreTest {
-
- final CreditsSemaphore semaphore = new CreditsSemaphore(10);
-
- final AtomicInteger errors = new AtomicInteger(0);
-
- final AtomicInteger acquired = new AtomicInteger(0);
-
- final CountDownLatch waiting = new CountDownLatch(1);
-
- Thread thread = new Thread() {
- @Override
- public void run() {
- try {
- for (int i = 0; i < 12; i++) {
- if (!semaphore.tryAcquire()) {
- waiting.countDown();
- semaphore.acquire();
- }
- acquired.incrementAndGet();
- }
- }
- catch (Throwable e) {
- e.printStackTrace();
- errors.incrementAndGet();
- }
- }
- };
-
- @Test
- public void testSetAndRelease() throws Exception {
- thread.start();
-
- // 5 seconds would be an eternity here
- Assert.assertTrue(waiting.await(5, TimeUnit.SECONDS));
-
- Assert.assertEquals(0, semaphore.getCredits());
-
- long timeout = System.currentTimeMillis() + 1000;
- while (!semaphore.hasQueuedThreads() && System.currentTimeMillis() < timeout) {
- Thread.sleep(10);
- }
-
- Assert.assertTrue(semaphore.hasQueuedThreads());
-
- semaphore.setCredits(2);
-
- thread.join();
-
- Assert.assertEquals(12, acquired.get());
-
- Assert.assertFalse(semaphore.hasQueuedThreads());
- }
-
- @Test
- public void testDownAndUp() throws Exception {
- thread.start();
-
- // 5 seconds would be an eternity here
- Assert.assertTrue(waiting.await(5, TimeUnit.SECONDS));
-
- Assert.assertEquals(0, semaphore.getCredits());
-
- long timeout = System.currentTimeMillis() + 1000;
- while (!semaphore.hasQueuedThreads() && System.currentTimeMillis() < timeout) {
- Thread.sleep(10);
- }
-
- Assert.assertTrue(semaphore.hasQueuedThreads());
-
- semaphore.release(2);
-
- thread.join();
-
- Assert.assertEquals(12, acquired.get());
-
- Assert.assertFalse(semaphore.hasQueuedThreads());
- }
-
- @Test
- public void testStartedZeroedSetLater() throws Exception {
- semaphore.setCredits(0);
-
- thread.start();
-
- // 5 seconds would be an eternity here
- Assert.assertTrue(waiting.await(5, TimeUnit.SECONDS));
-
- Assert.assertEquals(0, semaphore.getCredits());
-
- long timeout = System.currentTimeMillis() + 1000;
- while (!semaphore.hasQueuedThreads() && System.currentTimeMillis() < timeout) {
- Thread.sleep(10);
- }
-
- Assert.assertTrue(semaphore.hasQueuedThreads());
-
- Assert.assertEquals(0, acquired.get());
-
- semaphore.setCredits(12);
-
- thread.join();
-
- Assert.assertEquals(12, acquired.get());
-
- Assert.assertFalse(semaphore.hasQueuedThreads());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/util/ReusableLatchTest.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/util/ReusableLatchTest.java b/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/util/ReusableLatchTest.java
deleted file mode 100644
index 8909b5e..0000000
--- a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/util/ReusableLatchTest.java
+++ /dev/null
@@ -1,300 +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.proton.plug.test.util;
-
-import java.util.concurrent.CountDownLatch;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.proton.plug.util.ReusableLatch;
-
-public class ReusableLatchTest {
-
- @Test
- public void testLatchWithParameterizedDown() throws Exception {
- ReusableLatch latch = new ReusableLatch(1000);
-
- latch.countDown(5000);
-
- Assert.assertTrue(latch.await(1000));
-
- Assert.assertEquals(0, latch.getCount());
- }
-
- @Test
- public void testLatchOnSingleThread() throws Exception {
- ReusableLatch latch = new ReusableLatch();
-
- for (int i = 1; i <= 100; i++) {
- latch.countUp();
- Assert.assertEquals(i, latch.getCount());
- }
-
- for (int i = 100; i > 0; i--) {
- Assert.assertEquals(i, latch.getCount());
- latch.countDown();
- Assert.assertEquals(i - 1, latch.getCount());
- }
-
- latch.await();
- }
-
- /**
- * This test will open numberOfThreads threads, and add numberOfAdds on the
- * VariableLatch After those addthreads are finished, the latch count should
- * be numberOfThreads * numberOfAdds Then it will open numberOfThreads
- * threads again releasing numberOfAdds on the VariableLatch After those
- * releaseThreads are finished, the latch count should be 0 And all the
- * waiting threads should be finished also
- *
- * @throws Exception
- */
- @Test
- public void testLatchOnMultiThread() throws Exception {
- final ReusableLatch latch = new ReusableLatch();
-
- latch.countUp(); // We hold at least one, so ThreadWaits won't go away
-
- final int numberOfThreads = 100;
- final int numberOfAdds = 100;
-
- class ThreadWait extends Thread {
-
- private volatile boolean waiting = true;
-
- @Override
- public void run() {
- try {
- if (!latch.await(5000)) {
- System.err.println("Latch timed out");
- }
- }
- catch (Exception e) {
- e.printStackTrace();
- }
- waiting = false;
- }
- }
-
- class ThreadAdd extends Thread {
-
- private final CountDownLatch latchReady;
-
- private final CountDownLatch latchStart;
-
- ThreadAdd(final CountDownLatch latchReady, final CountDownLatch latchStart) {
- this.latchReady = latchReady;
- this.latchStart = latchStart;
- }
-
- @Override
- public void run() {
- try {
- latchReady.countDown();
- // Everybody should start at the same time, to worse concurrency
- // effects
- latchStart.await();
- for (int i = 0; i < numberOfAdds; i++) {
- latch.countUp();
- }
- }
- catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
-
- CountDownLatch latchReady = new CountDownLatch(numberOfThreads);
- CountDownLatch latchStart = new CountDownLatch(1);
-
- ThreadAdd[] threadAdds = new ThreadAdd[numberOfThreads];
- ThreadWait[] waits = new ThreadWait[numberOfThreads];
-
- for (int i = 0; i < numberOfThreads; i++) {
- threadAdds[i] = new ThreadAdd(latchReady, latchStart);
- threadAdds[i].start();
- waits[i] = new ThreadWait();
- waits[i].start();
- }
-
- latchReady.await();
- latchStart.countDown();
-
- for (int i = 0; i < numberOfThreads; i++) {
- threadAdds[i].join();
- }
-
- for (int i = 0; i < numberOfThreads; i++) {
- Assert.assertTrue(waits[i].waiting);
- }
-
- Assert.assertEquals(numberOfThreads * numberOfAdds + 1, latch.getCount());
-
- class ThreadDown extends Thread {
-
- private final CountDownLatch latchReady;
-
- private final CountDownLatch latchStart;
-
- ThreadDown(final CountDownLatch latchReady, final CountDownLatch latchStart) {
- this.latchReady = latchReady;
- this.latchStart = latchStart;
- }
-
- @Override
- public void run() {
- try {
- latchReady.countDown();
- // Everybody should start at the same time, to worse concurrency
- // effects
- latchStart.await();
- for (int i = 0; i < numberOfAdds; i++) {
- latch.countDown();
- }
- }
- catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
-
- latchReady = new CountDownLatch(numberOfThreads);
- latchStart = new CountDownLatch(1);
-
- ThreadDown[] down = new ThreadDown[numberOfThreads];
-
- for (int i = 0; i < numberOfThreads; i++) {
- down[i] = new ThreadDown(latchReady, latchStart);
- down[i].start();
- }
-
- latchReady.await();
- latchStart.countDown();
-
- for (int i = 0; i < numberOfThreads; i++) {
- down[i].join();
- }
-
- Assert.assertEquals(1, latch.getCount());
-
- for (int i = 0; i < numberOfThreads; i++) {
- Assert.assertTrue(waits[i].waiting);
- }
-
- latch.countDown();
-
- for (int i = 0; i < numberOfThreads; i++) {
- waits[i].join();
- }
-
- Assert.assertEquals(0, latch.getCount());
-
- for (int i = 0; i < numberOfThreads; i++) {
- Assert.assertFalse(waits[i].waiting);
- }
- }
-
- @Test
- public void testReuseLatch() throws Exception {
- final ReusableLatch latch = new ReusableLatch(5);
- for (int i = 0; i < 5; i++) {
- latch.countDown();
- }
-
- latch.countUp();
-
- class ThreadWait extends Thread {
-
- private volatile boolean waiting = false;
-
- private volatile Exception e;
-
- private final CountDownLatch readyLatch = new CountDownLatch(1);
-
- @Override
- public void run() {
- waiting = true;
- readyLatch.countDown();
- try {
- if (!latch.await(1000)) {
- System.err.println("Latch timed out!");
- }
- }
- catch (Exception e) {
- e.printStackTrace();
- this.e = e;
- }
- waiting = false;
- }
- }
-
- ThreadWait t = new ThreadWait();
- t.start();
-
- t.readyLatch.await();
-
- Assert.assertEquals(true, t.waiting);
-
- latch.countDown();
-
- t.join();
-
- Assert.assertEquals(false, t.waiting);
-
- Assert.assertNull(t.e);
-
- latch.countUp();
-
- t = new ThreadWait();
- t.start();
-
- t.readyLatch.await();
-
- Assert.assertEquals(true, t.waiting);
-
- latch.countDown();
-
- t.join();
-
- Assert.assertEquals(false, t.waiting);
-
- Assert.assertNull(t.e);
-
- Assert.assertTrue(latch.await(1000));
-
- Assert.assertEquals(0, latch.getCount());
-
- latch.countDown();
-
- Assert.assertEquals(0, latch.getCount());
-
- }
-
- @Test
- public void testTimeout() throws Exception {
- ReusableLatch latch = new ReusableLatch();
-
- latch.countUp();
-
- long start = System.currentTimeMillis();
- Assert.assertFalse(latch.await(1000));
- long end = System.currentTimeMillis();
-
- Assert.assertTrue("Timeout didn't work correctly", end - start >= 1000 && end - start < 2000);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/util/SimpleServerAbstractTest.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/util/SimpleServerAbstractTest.java b/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/util/SimpleServerAbstractTest.java
deleted file mode 100644
index 1bfa0b4..0000000
--- a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/util/SimpleServerAbstractTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.test.util;
-
-import org.proton.plug.test.AbstractJMSTest;
-import org.proton.plug.test.Constants;
-import org.proton.plug.test.invm.InVMTestConnector;
-import org.proton.plug.test.minimalclient.Connector;
-import org.proton.plug.test.minimalclient.SimpleAMQPConnector;
-import org.proton.plug.test.minimalserver.DumbServer;
-import org.proton.plug.test.minimalserver.MinimalServer;
-import org.junit.After;
-import org.junit.Before;
-
-public class SimpleServerAbstractTest {
-
- protected final boolean useSASL;
- protected final boolean useInVM;
- protected MinimalServer server = new MinimalServer();
-
- public SimpleServerAbstractTest(boolean useSASL, boolean useInVM) {
- this.useSASL = useSASL;
- this.useInVM = useInVM;
- }
-
- @Before
- public void setUp() throws Exception {
- DumbServer.clear();
- AbstractJMSTest.forceGC();
- if (!useInVM) {
- server.start("127.0.0.1", Constants.PORT, useSASL);
- }
-
- }
-
- @After
- public void tearDown() throws Exception {
- if (!useInVM) {
- server.stop();
- }
- DumbServer.clear();
- }
-
- protected Connector newConnector() {
- if (useInVM) {
- return new InVMTestConnector();
- }
- else {
- return new SimpleAMQPConnector();
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/pom.xml
----------------------------------------------------------------------
diff --git a/artemis-protocols/pom.xml b/artemis-protocols/pom.xml
index 3eb9ade..29289ac 100644
--- a/artemis-protocols/pom.xml
+++ b/artemis-protocols/pom.xml
@@ -36,7 +36,6 @@
<module>artemis-amqp-protocol</module>
<module>artemis-stomp-protocol</module>
<module>artemis-openwire-protocol</module>
- <module>artemis-proton-plug</module>
<module>artemis-hornetq-protocol</module>
<module>artemis-hqclient-protocol</module>
<module>artemis-mqtt-protocol</module>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/tests/integration-tests/pom.xml
----------------------------------------------------------------------
diff --git a/tests/integration-tests/pom.xml b/tests/integration-tests/pom.xml
index 4f56ca8..9ac3a72 100644
--- a/tests/integration-tests/pom.xml
+++ b/tests/integration-tests/pom.xml
@@ -153,18 +153,6 @@
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
- <artifactId>artemis-proton-plug</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.activemq</groupId>
- <artifactId>artemis-proton-plug</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- <type>test-jar</type>
- </dependency>
- <dependency>
- <groupId>org.apache.activemq</groupId>
<artifactId>artemis-hornetq-protocol</artifactId>
<version>${project.version}</version>
</dependency>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonMaxFrameSizeTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonMaxFrameSizeTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonMaxFrameSizeTest.java
new file mode 100644
index 0000000..9f22362
--- /dev/null
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonMaxFrameSizeTest.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.tests.integration.amqp;
+
+import org.apache.activemq.transport.amqp.client.AmqpClient;
+import org.apache.activemq.transport.amqp.client.AmqpConnection;
+import org.apache.activemq.transport.amqp.client.AmqpMessage;
+import org.apache.activemq.transport.amqp.client.AmqpReceiver;
+import org.apache.activemq.transport.amqp.client.AmqpSender;
+import org.apache.activemq.transport.amqp.client.AmqpSession;
+import org.apache.qpid.proton.amqp.messaging.Data;
+import org.apache.qpid.proton.message.impl.MessageImpl;
+import org.junit.Test;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+public class ProtonMaxFrameSizeTest extends ProtonTestBase {
+
+ private static final int FRAME_SIZE = 512;
+
+ @Override
+ protected void configureAmqp(Map<String, Object> params) {
+ params.put("maxFrameSize", FRAME_SIZE);
+ }
+
+ @Test
+ public void testMultipleTransfers() throws Exception {
+
+ String testQueueName = "ConnectionFrameSize";
+ int nMsgs = 200;
+
+ AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
+
+
+ AmqpConnection amqpConnection = client.createConnection();
+
+ try {
+ amqpConnection.connect();
+
+ AmqpSession session = amqpConnection.createSession();
+ AmqpSender sender = session.createSender("jms.queue." + testQueueName);
+
+ final int payload = FRAME_SIZE * 16;
+
+ for (int i = 0; i < nMsgs; ++i) {
+ AmqpMessage message = createAmqpMessage((byte) 'A', payload);
+ sender.send(message);
+ }
+
+ int count = getMessageCount(server.getPostOffice(), "jms.queue." + testQueueName);
+ assertEquals(nMsgs, count);
+
+ AmqpReceiver receiver = session.createReceiver("jms.queue." + testQueueName);
+ receiver.flow(nMsgs);
+
+ for (int i = 0; i < nMsgs; ++i) {
+ AmqpMessage message = receiver.receive(5, TimeUnit.SECONDS);
+ assertNotNull("failed at " + i, message);
+ MessageImpl wrapped = (MessageImpl) message.getWrappedMessage();
+ Data data = (Data) wrapped.getBody();
+ System.out.println("received : message: " + data.getValue().getLength());
+ assertEquals(payload, data.getValue().getLength());
+ message.accept();
+ }
+
+ }
+ finally {
+ amqpConnection.close();
+ }
+ }
+
+ private AmqpMessage createAmqpMessage(byte value, int payloadSize) {
+ AmqpMessage message = new AmqpMessage();
+ byte[] payload = new byte[payloadSize];
+ for (int i = 0; i < payload.length; i++) {
+ payload[i] = value;
+ }
+ message.setBytes(payload);
+ return message;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonPubSubTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonPubSubTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonPubSubTest.java
new file mode 100644
index 0000000..c8fc454
--- /dev/null
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/ProtonPubSubTest.java
@@ -0,0 +1,257 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.tests.integration.amqp;
+
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.qpid.jms.JmsConnectionFactory;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.jms.Connection;
+import javax.jms.ExceptionListener;
+import javax.jms.JMSException;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+import javax.jms.TopicConnection;
+import javax.jms.TopicSession;
+import javax.jms.TopicSubscriber;
+import java.util.Map;
+
+
+public class ProtonPubSubTest extends ProtonTestBase {
+ private final String prefix = "foo.bar.";
+ private final String pubAddress = "pubAddress";
+ private final String prefixedPubAddress = prefix + "pubAddress";
+ private final SimpleString ssPubAddress = new SimpleString(pubAddress);
+ private final SimpleString ssprefixedPubAddress = new SimpleString(prefixedPubAddress);
+ private Connection connection;
+ private JmsConnectionFactory factory;
+
+ @Override
+ protected void configureAmqp(Map<String, Object> params) {
+ params.put("pubSubPrefix", prefix);
+ }
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ server.createQueue(ssPubAddress, ssPubAddress, new SimpleString("foo=bar"), false, true);
+ server.createQueue(ssprefixedPubAddress, ssprefixedPubAddress, new SimpleString("foo=bar"), false, true);
+ factory = new JmsConnectionFactory("amqp://localhost:5672");
+ factory.setClientID("myClientID");
+ connection = factory.createConnection();
+ connection.setExceptionListener(new ExceptionListener() {
+ @Override
+ public void onException(JMSException exception) {
+ exception.printStackTrace();
+ }
+ });
+
+ }
+
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ try {
+ Thread.sleep(250);
+ if (connection != null) {
+ connection.close();
+ }
+ }
+ finally {
+ super.tearDown();
+ }
+ }
+
+ @Test
+ public void testNonDurablePubSub() throws Exception {
+ int numMessages = 100;
+ Topic topic = createTopic(pubAddress);
+ TopicSession session = ((TopicConnection) connection).createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageConsumer sub = session.createSubscriber(topic);
+
+ Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageProducer producer = sendSession.createProducer(topic);
+ connection.start();
+ for (int i = 0; i < numMessages; i++) {
+ producer.send(sendSession.createTextMessage("message:" + i));
+ }
+ for (int i = 0; i < numMessages; i++) {
+ TextMessage receive = (TextMessage) sub.receive(5000);
+ Assert.assertNotNull(receive);
+ Assert.assertEquals(receive.getText(), "message:" + i);
+ }
+ }
+
+ @Test
+ public void testNonDurableMultiplePubSub() throws Exception {
+ int numMessages = 100;
+ Topic topic = createTopic(pubAddress);
+ TopicSession session = ((TopicConnection) connection).createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageConsumer sub = session.createSubscriber(topic);
+ MessageConsumer sub2 = session.createSubscriber(topic);
+ MessageConsumer sub3 = session.createSubscriber(topic);
+
+ Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageProducer producer = sendSession.createProducer(topic);
+ connection.start();
+ for (int i = 0; i < numMessages; i++) {
+ producer.send(sendSession.createTextMessage("message:" + i));
+ }
+ for (int i = 0; i < numMessages; i++) {
+ TextMessage receive = (TextMessage) sub.receive(5000);
+ Assert.assertNotNull(receive);
+ Assert.assertEquals(receive.getText(), "message:" + i);
+ receive = (TextMessage) sub2.receive(5000);
+ Assert.assertNotNull(receive);
+ Assert.assertEquals(receive.getText(), "message:" + i);
+ receive = (TextMessage) sub3.receive(5000);
+ Assert.assertNotNull(receive);
+ Assert.assertEquals(receive.getText(), "message:" + i);
+ }
+ }
+
+
+ @Test
+ public void testDurablePubSub() throws Exception {
+ int numMessages = 100;
+ Topic topic = createTopic(pubAddress);
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ TopicSubscriber sub = session.createDurableSubscriber(topic, "myPubId");
+
+ Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageProducer producer = sendSession.createProducer(topic);
+ connection.start();
+ for (int i = 0; i < numMessages; i++) {
+ producer.send(sendSession.createTextMessage("message:" + i));
+ }
+ for (int i = 0; i < numMessages; i++) {
+ TextMessage receive = (TextMessage) sub.receive(5000);
+ Assert.assertNotNull(receive);
+ Assert.assertEquals(receive.getText(), "message:" + i);
+ }
+ }
+
+ @Test
+ public void testDurableMultiplePubSub() throws Exception {
+ int numMessages = 100;
+ Topic topic = createTopic(pubAddress);
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ TopicSubscriber sub = session.createDurableSubscriber(topic, "myPubId");
+ TopicSubscriber sub2 = session.createDurableSubscriber(topic, "myPubId2");
+ TopicSubscriber sub3 = session.createDurableSubscriber(topic, "myPubId3");
+
+ Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageProducer producer = sendSession.createProducer(topic);
+ connection.start();
+ for (int i = 0; i < numMessages; i++) {
+ producer.send(sendSession.createTextMessage("message:" + i));
+ }
+ for (int i = 0; i < numMessages; i++) {
+ TextMessage receive = (TextMessage) sub.receive(5000);
+ Assert.assertNotNull(receive);
+ Assert.assertEquals(receive.getText(), "message:" + i);
+ receive = (TextMessage) sub2.receive(5000);
+ Assert.assertNotNull(receive);
+ Assert.assertEquals(receive.getText(), "message:" + i);
+ receive = (TextMessage) sub3.receive(5000);
+ Assert.assertNotNull(receive);
+ Assert.assertEquals(receive.getText(), "message:" + i);
+ }
+ }
+
+ @Test
+ public void testDurablePubSubReconnect() throws Exception {
+ int numMessages = 100;
+ Topic topic = createTopic(pubAddress);
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ TopicSubscriber sub = session.createDurableSubscriber(topic, "myPubId");
+
+ Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageProducer producer = sendSession.createProducer(topic);
+ connection.start();
+ for (int i = 0; i < numMessages; i++) {
+ producer.send(sendSession.createTextMessage("message:" + i));
+ }
+ for (int i = 0; i < numMessages; i++) {
+ TextMessage receive = (TextMessage) sub.receive(5000);
+ Assert.assertNotNull(receive);
+ Assert.assertEquals(receive.getText(), "message:" + i);
+ }
+ connection.close();
+ connection = factory.createConnection();
+ connection.setExceptionListener(new ExceptionListener() {
+ @Override
+ public void onException(JMSException exception) {
+ exception.printStackTrace();
+ }
+ });
+ session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ sub = session.createDurableSubscriber(topic, "myPubId");
+
+ sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ producer = sendSession.createProducer(topic);
+ connection.start();
+ for (int i = 0; i < numMessages; i++) {
+ producer.send(sendSession.createTextMessage("message:" + i));
+ }
+ for (int i = 0; i < numMessages; i++) {
+ TextMessage receive = (TextMessage) sub.receive(5000);
+ Assert.assertNotNull(receive);
+ Assert.assertEquals(receive.getText(), "message:" + i);
+ }
+ }
+
+ @Test
+ public void testDurablePubSubUnsubscribe() throws Exception {
+ int numMessages = 100;
+ Topic topic = createTopic(pubAddress);
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ TopicSubscriber sub = session.createDurableSubscriber(topic, "myPubId");
+
+ Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageProducer producer = sendSession.createProducer(topic);
+ connection.start();
+ for (int i = 0; i < numMessages; i++) {
+ producer.send(sendSession.createTextMessage("message:" + i));
+ }
+ for (int i = 0; i < numMessages; i++) {
+ TextMessage receive = (TextMessage) sub.receive(5000);
+ Assert.assertNotNull(receive);
+ Assert.assertEquals(receive.getText(), "message:" + i);
+ }
+ sub.close();
+ session.unsubscribe("myPubId");
+ }
+
+
+ private javax.jms.Topic createTopic(String address) throws Exception {
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ try {
+ return session.createTopic(address);
+ }
+ finally {
+ session.close();
+ }
+ }
+}
[09/15] activemq-artemis git commit: ARTEMIS-751 Simplification of
the AMQP implementation
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/AmqpSupport.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/AmqpSupport.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/AmqpSupport.java
new file mode 100644
index 0000000..848f0d2
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/AmqpSupport.java
@@ -0,0 +1,131 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.proton;
+
+import org.apache.qpid.proton.amqp.DescribedType;
+import org.apache.qpid.proton.amqp.Symbol;
+import org.apache.qpid.proton.amqp.UnsignedLong;
+
+import java.util.AbstractMap;
+import java.util.Map;
+
+/**
+ * Set of useful methods and definitions used in the AMQP protocol handling
+ */
+public class AmqpSupport {
+
+ // Identification values used to locating JMS selector types.
+ public static final UnsignedLong JMS_SELECTOR_CODE = UnsignedLong.valueOf(0x0000468C00000004L);
+ public static final Symbol JMS_SELECTOR_NAME = Symbol.valueOf("apache.org:selector-filter:string");
+ public static final Object[] JMS_SELECTOR_FILTER_IDS = new Object[]{JMS_SELECTOR_CODE, JMS_SELECTOR_NAME};
+ public static final UnsignedLong NO_LOCAL_CODE = UnsignedLong.valueOf(0x0000468C00000003L);
+ public static final Symbol NO_LOCAL_NAME = Symbol.valueOf("apache.org:no-local-filter:list");
+ public static final Object[] NO_LOCAL_FILTER_IDS = new Object[]{NO_LOCAL_CODE, NO_LOCAL_NAME};
+
+ // Capabilities used to identify destination type in some requests.
+ public static final Symbol TEMP_QUEUE_CAPABILITY = Symbol.valueOf("temporary-queue");
+ public static final Symbol TEMP_TOPIC_CAPABILITY = Symbol.valueOf("temporary-topic");
+
+ // Symbols used to announce connection information to remote peer.
+ public static final Symbol INVALID_FIELD = Symbol.valueOf("invalid-field");
+ public static final Symbol CONTAINER_ID = Symbol.valueOf("container-id");
+
+ // Symbols used to announce connection information to remote peer.
+ public static final Symbol ANONYMOUS_RELAY = Symbol.valueOf("ANONYMOUS-RELAY");
+ public static final Symbol DELAYED_DELIVERY = Symbol.valueOf("DELAYED_DELIVERY");
+ public static final Symbol QUEUE_PREFIX = Symbol.valueOf("queue-prefix");
+ public static final Symbol TOPIC_PREFIX = Symbol.valueOf("topic-prefix");
+ public static final Symbol CONNECTION_OPEN_FAILED = Symbol.valueOf("amqp:connection-establishment-failed");
+ public static final Symbol PRODUCT = Symbol.valueOf("product");
+ public static final Symbol VERSION = Symbol.valueOf("version");
+ public static final Symbol PLATFORM = Symbol.valueOf("platform");
+
+ // Symbols used in configuration of newly opened links.
+ public static final Symbol COPY = Symbol.getSymbol("copy");
+
+ // Lifetime policy symbols
+ public static final Symbol LIFETIME_POLICY = Symbol.valueOf("lifetime-policy");
+
+ public static final Symbol SOLE_CONNECTION_CAPABILITY = Symbol.valueOf("sole-connection-for-container");
+ /**
+ * Search for a given Symbol in a given array of Symbol object.
+ *
+ * @param symbols
+ * the set of Symbols to search.
+ * @param key
+ * the value to try and find in the Symbol array.
+ *
+ * @return true if the key is found in the given Symbol array.
+ */
+ public static boolean contains(Symbol[] symbols, Symbol key) {
+ if (symbols == null || symbols.length == 0) {
+ return false;
+ }
+
+ for (Symbol symbol : symbols) {
+ if (symbol.equals(key)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Search for a particular filter using a set of known indentification values
+ * in the Map of filters.
+ *
+ * @param filters
+ * The filters map that should be searched.
+ * @param filterIds
+ * The aliases for the target filter to be located.
+ *
+ * @return the filter if found in the mapping or null if not found.
+ */
+ public static Map.Entry<Symbol, DescribedType> findFilter(Map<Symbol, Object> filters, Object[] filterIds) {
+
+ if (filterIds == null || filterIds.length == 0) {
+ StringBuilder ids = new StringBuilder();
+ if (filterIds != null) {
+ for (Object filterId : filterIds) {
+ ids.append(filterId).append(" ");
+ }
+ }
+ throw new IllegalArgumentException("Invalid Filter Ids array passed: " + ids);
+ }
+
+ if (filters == null || filters.isEmpty()) {
+ return null;
+ }
+
+ for (Map.Entry<Symbol, Object> filter : filters.entrySet()) {
+ if (filter.getValue() instanceof DescribedType) {
+ DescribedType describedType = ((DescribedType) filter.getValue());
+ Object descriptor = describedType.getDescriptor();
+
+ for (Object filterId : filterIds) {
+ if (descriptor.equals(filterId)) {
+ return new AbstractMap.SimpleImmutableEntry<>(filter.getKey(), describedType);
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonDeliveryHandler.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonDeliveryHandler.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonDeliveryHandler.java
new file mode 100644
index 0000000..43f1913
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonDeliveryHandler.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.proton;
+
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPException;
+import org.apache.qpid.proton.amqp.transport.ErrorCondition;
+import org.apache.qpid.proton.engine.Delivery;
+
+/**
+ * An interface to handle deliveries, either messages, acks or transaction calls
+ */
+public interface ProtonDeliveryHandler {
+
+ void onFlow(int currentCredits, boolean drain);
+
+ void onMessage(Delivery delivery) throws ActiveMQAMQPException;
+
+ /*
+ * we have to distinguish between a remote close on the link and a close via a connection or session as the latter mean
+ * that a link reattach can happen and we need to keep the underlying resource (queue/subscription) around for pub subs
+ * */
+ void close(boolean remoteLinkClose) throws ActiveMQAMQPException;
+
+ void close(ErrorCondition condition) throws ActiveMQAMQPException;
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonInitializable.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonInitializable.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonInitializable.java
new file mode 100644
index 0000000..3870810
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonInitializable.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.proton;
+
+public class ProtonInitializable {
+
+ private boolean initialized = false;
+
+ public boolean isInitialized() {
+ return initialized;
+ }
+
+ public void initialise() throws Exception {
+ if (!initialized) {
+ initialized = true;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonServerReceiverContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonServerReceiverContext.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonServerReceiverContext.java
new file mode 100644
index 0000000..4b97831
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonServerReceiverContext.java
@@ -0,0 +1,211 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.proton;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.PooledByteBufAllocator;
+import org.apache.activemq.artemis.protocol.amqp.broker.AMQPSessionCallback;
+import org.apache.activemq.artemis.protocol.amqp.logger.ActiveMQAMQPProtocolMessageBundle;
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPException;
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPInternalErrorException;
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPNotFoundException;
+import org.apache.activemq.artemis.protocol.amqp.util.DeliveryUtil;
+import org.apache.activemq.artemis.core.transaction.Transaction;
+import org.apache.qpid.proton.amqp.Symbol;
+import org.apache.qpid.proton.amqp.messaging.Rejected;
+import org.apache.qpid.proton.amqp.transaction.TransactionalState;
+import org.apache.qpid.proton.amqp.transport.ErrorCondition;
+import org.apache.qpid.proton.engine.Delivery;
+import org.apache.qpid.proton.engine.Receiver;
+import org.jboss.logging.Logger;
+
+public class ProtonServerReceiverContext extends ProtonInitializable implements ProtonDeliveryHandler {
+
+ private static final Logger log = Logger.getLogger(ProtonServerReceiverContext.class);
+
+ protected final AMQPConnectionContext connection;
+
+ protected final AMQPSessionContext protonSession;
+
+ protected final Receiver receiver;
+
+ protected String address;
+
+ protected final AMQPSessionCallback sessionSPI;
+
+
+ /*
+ The maximum number of credits we will allocate to clients.
+ This number is also used by the broker when refresh client credits.
+ */
+ private static int maxCreditAllocation = 100;
+
+ // Used by the broker to decide when to refresh clients credit. This is not used when client requests credit.
+ private static int minCreditRefresh = 30;
+
+ public ProtonServerReceiverContext(AMQPSessionCallback sessionSPI,
+ AMQPConnectionContext connection,
+ AMQPSessionContext protonSession,
+ Receiver receiver) {
+ this.connection = connection;
+ this.protonSession = protonSession;
+ this.receiver = receiver;
+ this.sessionSPI = sessionSPI;
+ }
+
+ @Override
+ public void onFlow(int credits, boolean drain) {
+ flow(Math.min(credits, maxCreditAllocation), maxCreditAllocation);
+ }
+
+ @Override
+ public void initialise() throws Exception {
+ super.initialise();
+ org.apache.qpid.proton.amqp.messaging.Target target = (org.apache.qpid.proton.amqp.messaging.Target) receiver.getRemoteTarget();
+
+ if (target != null) {
+ if (target.getDynamic()) {
+ //if dynamic we have to create the node (queue) and set the address on the target, the node is temporary and
+ // will be deleted on closing of the session
+ address = sessionSPI.tempQueueName();
+
+ try {
+ sessionSPI.createTemporaryQueue(address);
+ }
+ catch (Exception e) {
+ throw new ActiveMQAMQPInternalErrorException(e.getMessage(), e);
+ }
+ target.setAddress(address);
+ }
+ else {
+ //if not dynamic then we use the targets address as the address to forward the messages to, however there has to
+ //be a queue bound to it so we nee to check this.
+ address = target.getAddress();
+ if (address == null) {
+ throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.targetAddressNotSet();
+ }
+
+ try {
+ if (!sessionSPI.bindingQuery(address)) {
+ throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.addressDoesntExist();
+ }
+ }
+ catch (ActiveMQAMQPNotFoundException e) {
+ throw e;
+ }
+ catch (Exception e) {
+ throw new ActiveMQAMQPInternalErrorException(e.getMessage(), e);
+ }
+ }
+ }
+ flow(maxCreditAllocation, minCreditRefresh);
+ }
+
+ /*
+ * called when Proton receives a message to be delivered via a Delivery.
+ *
+ * This may be called more than once per deliver so we have to cache the buffer until we have received it all.
+ *
+ * */
+ @Override
+ public void onMessage(Delivery delivery) throws ActiveMQAMQPException {
+ Receiver receiver;
+ try {
+ receiver = ((Receiver) delivery.getLink());
+
+ if (!delivery.isReadable()) {
+ return;
+ }
+
+ if (delivery.isPartial()) {
+ return;
+ }
+
+ ByteBuf buffer = PooledByteBufAllocator.DEFAULT.heapBuffer(10 * 1024);
+ try {
+ synchronized (connection.getLock()) {
+ DeliveryUtil.readDelivery(receiver, buffer);
+
+ receiver.advance();
+
+ Transaction tx = null;
+ if (delivery.getRemoteState() instanceof TransactionalState) {
+
+ TransactionalState txState = (TransactionalState) delivery.getRemoteState();
+ tx = this.sessionSPI.getTransaction(txState.getTxnId());
+ }
+ sessionSPI.serverSend(tx, receiver, delivery, address, delivery.getMessageFormat(), buffer);
+
+ flow(maxCreditAllocation, minCreditRefresh);
+ }
+ }
+ finally {
+ buffer.release();
+ }
+ }
+ catch (Exception e) {
+ log.warn(e.getMessage(), e);
+ Rejected rejected = new Rejected();
+ ErrorCondition condition = new ErrorCondition();
+ condition.setCondition(Symbol.valueOf("failed"));
+ condition.setDescription(e.getMessage());
+ rejected.setError(condition);
+ delivery.disposition(rejected);
+ }
+ }
+
+ @Override
+ public void close(boolean remoteLinkClose) throws ActiveMQAMQPException {
+ protonSession.removeReceiver(receiver);
+ }
+
+ @Override
+ public void close(ErrorCondition condition) throws ActiveMQAMQPException {
+ receiver.setCondition(condition);
+ close(false);
+ }
+
+ public void flow(int credits, int threshold) {
+ // Use the SessionSPI to allocate producer credits, or default, always allocate credit.
+ if (sessionSPI != null) {
+ sessionSPI.offerProducerCredit(address, credits, threshold, receiver);
+ }
+ else {
+ synchronized (connection.getLock()) {
+ receiver.flow(credits);
+ connection.flush();
+ }
+ }
+
+ }
+
+ public void drain(int credits) {
+ synchronized (connection.getLock()) {
+ receiver.drain(credits);
+ }
+ connection.flush();
+ }
+
+ public int drained() {
+ return receiver.drained();
+ }
+
+ public boolean isDraining() {
+ return receiver.draining();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonServerSenderContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonServerSenderContext.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonServerSenderContext.java
new file mode 100644
index 0000000..0a071fd
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonServerSenderContext.java
@@ -0,0 +1,513 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.proton;
+
+import java.util.Map;
+import java.util.Objects;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.PooledByteBufAllocator;
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.protocol.amqp.broker.AMQPSessionCallback;
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPInternalErrorException;
+import org.apache.activemq.artemis.protocol.amqp.util.CreditsSemaphore;
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPNotFoundException;
+import org.apache.activemq.artemis.core.server.QueueQueryResult;
+import org.apache.activemq.artemis.core.transaction.Transaction;
+import org.apache.activemq.artemis.jms.client.ActiveMQConnection;
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPException;
+import org.apache.activemq.artemis.protocol.amqp.logger.ActiveMQAMQPProtocolMessageBundle;
+import org.apache.activemq.artemis.selector.filter.FilterException;
+import org.apache.activemq.artemis.selector.impl.SelectorParser;
+import org.apache.qpid.proton.amqp.DescribedType;
+import org.apache.qpid.proton.amqp.Symbol;
+import org.apache.qpid.proton.amqp.messaging.Accepted;
+import org.apache.qpid.proton.amqp.messaging.Modified;
+import org.apache.qpid.proton.amqp.messaging.Outcome;
+import org.apache.qpid.proton.amqp.messaging.Rejected;
+import org.apache.qpid.proton.amqp.messaging.Released;
+import org.apache.qpid.proton.amqp.messaging.Source;
+import org.apache.qpid.proton.amqp.messaging.TerminusDurability;
+import org.apache.qpid.proton.amqp.messaging.TerminusExpiryPolicy;
+import org.apache.qpid.proton.amqp.transaction.TransactionalState;
+import org.apache.qpid.proton.amqp.transport.AmqpError;
+import org.apache.qpid.proton.amqp.transport.DeliveryState;
+import org.apache.qpid.proton.amqp.transport.ErrorCondition;
+import org.apache.qpid.proton.amqp.transport.SenderSettleMode;
+import org.apache.qpid.proton.engine.Delivery;
+import org.apache.qpid.proton.engine.Sender;
+import org.apache.qpid.proton.message.ProtonJMessage;
+import org.jboss.logging.Logger;
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPIllegalStateException;
+import org.apache.activemq.artemis.protocol.amqp.util.NettyWritable;
+
+public class ProtonServerSenderContext extends ProtonInitializable implements ProtonDeliveryHandler {
+
+ private static final Logger log = Logger.getLogger(ProtonServerSenderContext.class);
+
+ private static final Symbol SELECTOR = Symbol.getSymbol("jms-selector");
+ private static final Symbol COPY = Symbol.valueOf("copy");
+ private static final Symbol TOPIC = Symbol.valueOf("topic");
+
+ private Object brokerConsumer;
+
+ protected final AMQPSessionContext protonSession;
+ protected final Sender sender;
+ protected final AMQPConnectionContext connection;
+ protected boolean closed = false;
+ protected final AMQPSessionCallback sessionSPI;
+ protected CreditsSemaphore creditsSemaphore = new CreditsSemaphore(0);
+
+
+ public ProtonServerSenderContext(AMQPConnectionContext connection,
+ Sender sender,
+ AMQPSessionContext protonSession,
+ AMQPSessionCallback server) {
+ super();
+ this.connection = connection;
+ this.sender = sender;
+ this.protonSession = protonSession;
+ this.sessionSPI = server;
+ }
+
+ public Object getBrokerConsumer() {
+ return brokerConsumer;
+ }
+
+ @Override
+ public void onFlow(int currentCredits, boolean drain) {
+ this.creditsSemaphore.setCredits(currentCredits);
+ sessionSPI.onFlowConsumer(brokerConsumer, currentCredits, drain);
+ }
+
+ public Sender getSender() {
+ return sender;
+ }
+
+ /*
+* start the session
+* */
+ public void start() throws ActiveMQAMQPException {
+ sessionSPI.start();
+ // protonSession.getServerSession().start();
+
+ //todo add flow control
+ try {
+ // to do whatever you need to make the broker start sending messages to the consumer
+ //this could be null if a link reattach has happened
+ if (brokerConsumer != null) {
+ sessionSPI.startSender(brokerConsumer);
+ }
+ //protonSession.getServerSession().receiveConsumerCredits(consumerID, -1);
+ }
+ catch (Exception e) {
+ throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorStartingConsumer(e.getMessage());
+ }
+ }
+
+ /**
+ * create the actual underlying ActiveMQ Artemis Server Consumer
+ */
+ @Override
+ public void initialise() throws Exception {
+ super.initialise();
+
+ Source source = (Source) sender.getRemoteSource();
+
+ String queue;
+
+ String selector = null;
+
+ /*
+ * even tho the filter is a map it will only return a single filter unless a nolocal is also provided
+ * */
+ if (source != null) {
+ Map.Entry<Symbol, DescribedType> filter = AmqpSupport.findFilter(source.getFilter(), AmqpSupport.JMS_SELECTOR_FILTER_IDS);
+ if (filter != null) {
+ selector = filter.getValue().getDescribed().toString();
+ // Validate the Selector.
+ try {
+ SelectorParser.parse(selector);
+ }
+ catch (FilterException e) {
+ close(new ErrorCondition(AmqpError.INVALID_FIELD, e.getMessage()));
+ return;
+ }
+ }
+ }
+
+ /*
+ * if we have a capability for a topic (qpid-jms) or we are configured on this address to act like a topic then act
+ * like a subscription.
+ * */
+ boolean isPubSub = hasCapabilities(TOPIC, source) || isPubSub(source);
+
+ if (isPubSub) {
+ if (AmqpSupport.findFilter(source.getFilter(), AmqpSupport.NO_LOCAL_FILTER_IDS) != null) {
+ String remoteContainerId = sender.getSession().getConnection().getRemoteContainer();
+ String noLocalFilter = ActiveMQConnection.CONNECTION_ID_PROPERTY_NAME.toString() + "<>'" + remoteContainerId + "'";
+ if (selector != null) {
+ selector += " AND " + noLocalFilter;
+ }
+ else {
+ selector = noLocalFilter;
+ }
+ }
+ }
+
+ if (source == null) {
+ // Attempt to recover a previous subscription happens when a link reattach happens on a subscription queue
+ String clientId = connection.getRemoteContainer();
+ String pubId = sender.getName();
+ queue = clientId + ":" + pubId;
+ boolean exists = sessionSPI.queueQuery(queue, false).isExists();
+
+ /*
+ * If it exists then we know it is a subscription so we set the capabilities on the source so we can delete on a
+ * link remote close.
+ * */
+ if (exists) {
+ source = new org.apache.qpid.proton.amqp.messaging.Source();
+ source.setAddress(queue);
+ source.setDurable(TerminusDurability.UNSETTLED_STATE);
+ source.setExpiryPolicy(TerminusExpiryPolicy.NEVER);
+ source.setDistributionMode(COPY);
+ source.setCapabilities(TOPIC);
+ sender.setSource(source);
+ }
+ else {
+ throw new ActiveMQAMQPNotFoundException("Unknown subscription link: " + sender.getName());
+ }
+ }
+ else {
+ if (source.getDynamic()) {
+ //if dynamic we have to create the node (queue) and set the address on the target, the node is temporary and
+ // will be deleted on closing of the session
+ queue = java.util.UUID.randomUUID().toString();
+ try {
+ sessionSPI.createTemporaryQueue(queue);
+ //protonSession.getServerSession().createQueue(queue, queue, null, true, false);
+ }
+ catch (Exception e) {
+ throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorCreatingTemporaryQueue(e.getMessage());
+ }
+ source.setAddress(queue);
+ }
+ else {
+ //if not dynamic then we use the targets address as the address to forward the messages to, however there has to
+ //be a queue bound to it so we nee to check this.
+ if (isPubSub) {
+ // if we are a subscription and durable create a durable queue using the container id and link name
+ if (TerminusDurability.UNSETTLED_STATE.equals(source.getDurable()) ||
+ TerminusDurability.CONFIGURATION.equals(source.getDurable())) {
+ String clientId = connection.getRemoteContainer();
+ String pubId = sender.getName();
+ queue = clientId + ":" + pubId;
+ QueueQueryResult result = sessionSPI.queueQuery(queue, false);
+
+ if (result.isExists()) {
+ // If a client reattaches to a durable subscription with a different no-local filter value, selector
+ // or address then we must recreate the queue (JMS semantics).
+
+ if (!Objects.equals(result.getFilterString(), SimpleString.toSimpleString(selector)) ||
+ (sender.getSource() != null && !sender.getSource().getAddress().equals(result.getAddress().toString()))) {
+ if (result.getConsumerCount() == 0) {
+ sessionSPI.deleteQueue(queue);
+ sessionSPI.createDurableQueue(source.getAddress(), queue, selector);
+ }
+ else {
+ throw new ActiveMQAMQPIllegalStateException("Unable to recreate subscription, consumers already exist");
+ }
+ }
+ }
+ else {
+ sessionSPI.createDurableQueue(source.getAddress(), queue, selector);
+ }
+ source.setAddress(queue);
+ }
+ //otherwise we are a volatile subscription
+ else {
+ queue = java.util.UUID.randomUUID().toString();
+ try {
+ sessionSPI.createTemporaryQueue(source.getAddress(), queue, selector);
+ }
+ catch (Exception e) {
+ throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorCreatingTemporaryQueue(e.getMessage());
+ }
+ source.setAddress(queue);
+ }
+ }
+ else {
+ queue = source.getAddress();
+ }
+ if (queue == null) {
+ throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.sourceAddressNotSet();
+ }
+
+ try {
+ if (!sessionSPI.queueQuery(queue, !isPubSub).isExists()) {
+ throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.sourceAddressDoesntExist();
+ }
+ }
+ catch (ActiveMQAMQPNotFoundException e) {
+ throw e;
+ }
+ catch (Exception e) {
+ throw new ActiveMQAMQPInternalErrorException(e.getMessage(), e);
+ }
+ }
+
+ boolean browseOnly = !isPubSub && source.getDistributionMode() != null && source.getDistributionMode().equals(COPY);
+ try {
+ brokerConsumer = sessionSPI.createSender(this, queue, isPubSub ? null : selector, browseOnly);
+ }
+ catch (Exception e) {
+ throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorCreatingConsumer(e.getMessage());
+ }
+ }
+ }
+
+ private boolean isPubSub(Source source) {
+ String pubSubPrefix = sessionSPI.getPubSubPrefix();
+ return source != null && pubSubPrefix != null && source.getAddress() != null && source.getAddress().startsWith(pubSubPrefix);
+ }
+
+ /*
+ * close the session
+ * */
+ @Override
+ public void close(ErrorCondition condition) throws ActiveMQAMQPException {
+ closed = true;
+ protonSession.removeSender(sender);
+ synchronized (connection.getLock()) {
+ sender.close();
+ }
+ connection.flush();
+
+ try {
+ sessionSPI.closeSender(brokerConsumer);
+ }
+ catch (Exception e) {
+ log.warn(e.getMessage(), e);
+ throw new ActiveMQAMQPInternalErrorException(e.getMessage());
+ }
+ }
+
+ /*
+ * close the session
+ * */
+ @Override
+ public void close(boolean remoteLinkClose) throws ActiveMQAMQPException {
+ try {
+ sessionSPI.closeSender(brokerConsumer);
+ //if this is a link close rather than a connection close or detach, we need to delete any durable resources for
+ // say pub subs
+ if (remoteLinkClose) {
+ Source source = (Source) sender.getSource();
+ if (source != null && source.getAddress() != null && hasCapabilities(TOPIC, source)) {
+ String queueName = source.getAddress();
+ QueueQueryResult result = sessionSPI.queueQuery(queueName, false);
+ if (result.isExists() && source.getDynamic()) {
+ sessionSPI.deleteQueue(queueName);
+ }
+ else {
+ String clientId = connection.getRemoteContainer();
+ String pubId = sender.getName();
+ String queue = clientId + ":" + pubId;
+ result = sessionSPI.queueQuery(queue, false);
+ if (result.isExists()) {
+ if (result.getConsumerCount() > 0) {
+ System.out.println("error");
+ }
+ sessionSPI.deleteQueue(queue);
+ }
+ }
+ }
+ }
+ }
+ catch (Exception e) {
+ log.warn(e.getMessage(), e);
+ throw new ActiveMQAMQPInternalErrorException(e.getMessage());
+ }
+ }
+
+ @Override
+ public void onMessage(Delivery delivery) throws ActiveMQAMQPException {
+ Object message = delivery.getContext();
+
+ boolean preSettle = sender.getRemoteSenderSettleMode() == SenderSettleMode.SETTLED;
+
+ DeliveryState remoteState = delivery.getRemoteState();
+
+ if (remoteState != null) {
+ // If we are transactional then we need ack if the msg has been accepted
+ if (remoteState instanceof TransactionalState) {
+
+ TransactionalState txState = (TransactionalState) remoteState;
+ Transaction tx = this.sessionSPI.getTransaction(txState.getTxnId());
+ if (txState.getOutcome() != null) {
+ Outcome outcome = txState.getOutcome();
+ if (outcome instanceof Accepted) {
+ if (!delivery.remotelySettled()) {
+ TransactionalState txAccepted = new TransactionalState();
+ txAccepted.setOutcome(Accepted.getInstance());
+ txAccepted.setTxnId(txState.getTxnId());
+
+ delivery.disposition(txAccepted);
+ }
+ //we have to individual ack as we can't guarantee we will get the delivery updates (including acks) in order
+ // from dealer, a perf hit but a must
+ try {
+ sessionSPI.ack(tx, brokerConsumer, message);
+ }
+ catch (Exception e) {
+ throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorAcknowledgingMessage(message.toString(), e.getMessage());
+ }
+ }
+ }
+ }
+ else if (remoteState instanceof Accepted) {
+ //we have to individual ack as we can't guarantee we will get the delivery updates (including acks) in order
+ // from dealer, a perf hit but a must
+ try {
+ sessionSPI.ack(null, brokerConsumer, message);
+ }
+ catch (Exception e) {
+ throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorAcknowledgingMessage(message.toString(), e.getMessage());
+ }
+ }
+ else if (remoteState instanceof Released) {
+ try {
+ sessionSPI.cancel(brokerConsumer, message, false);
+ }
+ catch (Exception e) {
+ throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorCancellingMessage(message.toString(), e.getMessage());
+ }
+ }
+ else if (remoteState instanceof Rejected || remoteState instanceof Modified) {
+ try {
+ sessionSPI.cancel(brokerConsumer, message, true);
+ }
+ catch (Exception e) {
+ throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorCancellingMessage(message.toString(), e.getMessage());
+ }
+ }
+ //todo add tag caching
+ if (!preSettle) {
+ protonSession.replaceTag(delivery.getTag());
+ }
+
+ synchronized (connection.getLock()) {
+ delivery.settle();
+ sender.offer(1);
+ }
+
+ }
+ else {
+ //todo not sure if we need to do anything here
+ }
+ }
+
+ public synchronized void checkState() {
+ sessionSPI.resumeDelivery(brokerConsumer);
+ }
+
+ /**
+ * handle an out going message from ActiveMQ Artemis, send via the Proton Sender
+ */
+ public int deliverMessage(Object message, int deliveryCount) throws Exception {
+ if (closed) {
+ System.err.println("Message can't be delivered as it's closed");
+ return 0;
+ }
+
+ //encode the message
+ ProtonJMessage serverMessage;
+ try {
+ // This can be done a lot better here
+ serverMessage = sessionSPI.encodeMessage(message, deliveryCount);
+ }
+ catch (Throwable e) {
+ log.warn(e.getMessage(), e);
+ throw new ActiveMQAMQPInternalErrorException(e.getMessage(), e);
+ }
+
+ return performSend(serverMessage, message);
+ }
+
+ private static boolean hasCapabilities(Symbol symbol, Source source) {
+ if (source != null) {
+ if (source.getCapabilities() != null) {
+ for (Symbol cap : source.getCapabilities()) {
+ if (symbol.equals(cap)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+ protected int performSend(ProtonJMessage serverMessage, Object context) {
+ if (!creditsSemaphore.tryAcquire()) {
+ try {
+ creditsSemaphore.acquire();
+ }
+ catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ // nothing to be done here.. we just keep going
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ }
+
+ //presettle means we can ack the message on the dealer side before we send it, i.e. for browsers
+ boolean preSettle = sender.getRemoteSenderSettleMode() == SenderSettleMode.SETTLED;
+
+ //we only need a tag if we are going to ack later
+ byte[] tag = preSettle ? new byte[0] : protonSession.getTag();
+
+ ByteBuf nettyBuffer = PooledByteBufAllocator.DEFAULT.heapBuffer(1024);
+ try {
+ serverMessage.encode(new NettyWritable(nettyBuffer));
+
+ int size = nettyBuffer.writerIndex();
+
+ synchronized (connection.getLock()) {
+ final Delivery delivery;
+ delivery = sender.delivery(tag, 0, tag.length);
+ delivery.setContext(context);
+
+ // this will avoid a copy.. patch provided by Norman using buffer.array()
+ sender.send(nettyBuffer.array(), nettyBuffer.arrayOffset() + nettyBuffer.readerIndex(), nettyBuffer.readableBytes());
+
+ if (preSettle) {
+ delivery.settle();
+ }
+ else {
+ sender.advance();
+ }
+ }
+
+ connection.flush();
+
+ return size;
+ }
+ finally {
+ nettyBuffer.release();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonTransactionHandler.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonTransactionHandler.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonTransactionHandler.java
new file mode 100644
index 0000000..6d4e73a
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonTransactionHandler.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.proton;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.PooledByteBufAllocator;
+import org.apache.activemq.artemis.protocol.amqp.broker.AMQPSessionCallback;
+import org.apache.activemq.artemis.protocol.amqp.logger.ActiveMQAMQPProtocolMessageBundle;
+import org.apache.activemq.artemis.protocol.amqp.util.DeliveryUtil;
+import org.apache.qpid.proton.amqp.Binary;
+import org.apache.qpid.proton.amqp.Symbol;
+import org.apache.qpid.proton.amqp.messaging.Accepted;
+import org.apache.qpid.proton.amqp.messaging.AmqpValue;
+import org.apache.qpid.proton.amqp.messaging.Rejected;
+import org.apache.qpid.proton.amqp.transaction.Declare;
+import org.apache.qpid.proton.amqp.transaction.Declared;
+import org.apache.qpid.proton.amqp.transaction.Discharge;
+import org.apache.qpid.proton.amqp.transport.ErrorCondition;
+import org.apache.qpid.proton.engine.Delivery;
+import org.apache.qpid.proton.engine.Receiver;
+import org.apache.qpid.proton.message.impl.MessageImpl;
+import org.jboss.logging.Logger;
+import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPException;
+
+/**
+ * handles an amqp Coordinator to deal with transaction boundaries etc
+ */
+public class ProtonTransactionHandler implements ProtonDeliveryHandler {
+
+ private static final Logger log = Logger.getLogger(ProtonTransactionHandler.class);
+
+ final AMQPSessionCallback sessionSPI;
+
+ public ProtonTransactionHandler(AMQPSessionCallback sessionSPI) {
+ this.sessionSPI = sessionSPI;
+ }
+
+ @Override
+ public void onMessage(Delivery delivery) throws ActiveMQAMQPException {
+ ByteBuf buffer = PooledByteBufAllocator.DEFAULT.heapBuffer(1024);
+
+ final Receiver receiver;
+ try {
+ receiver = ((Receiver) delivery.getLink());
+
+ if (!delivery.isReadable()) {
+ return;
+ }
+
+ DeliveryUtil.readDelivery(receiver, buffer);
+
+ receiver.advance();
+
+ MessageImpl msg = DeliveryUtil.decodeMessageImpl(buffer);
+
+ Object action = ((AmqpValue) msg.getBody()).getValue();
+
+ if (action instanceof Declare) {
+ Binary txID = sessionSPI.newTransaction();
+ Declared declared = new Declared();
+ declared.setTxnId(txID);
+ delivery.disposition(declared);
+ delivery.settle();
+ }
+ else if (action instanceof Discharge) {
+ Discharge discharge = (Discharge) action;
+
+ Binary txID = discharge.getTxnId();
+ if (discharge.getFail()) {
+ try {
+ sessionSPI.rollbackTX(txID, true);
+ delivery.disposition(new Accepted());
+ }
+ catch (Exception e) {
+ throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorRollingbackCoordinator(e.getMessage());
+ }
+ }
+ else {
+ try {
+ sessionSPI.commitTX(txID);
+ delivery.disposition(new Accepted());
+ }
+ catch (ActiveMQAMQPException amqpE) {
+ throw amqpE;
+ }
+ catch (Exception e) {
+ throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorCommittingCoordinator(e.getMessage());
+ }
+ }
+ }
+ }
+ catch (ActiveMQAMQPException amqpE) {
+ delivery.disposition(createRejected(amqpE.getAmqpError(), amqpE.getMessage()));
+ }
+ catch (Exception e) {
+ log.warn(e.getMessage(), e);
+ delivery.disposition(createRejected(Symbol.getSymbol("failed"), e.getMessage()));
+ }
+ finally {
+ delivery.settle();
+ buffer.release();
+ }
+ }
+
+ private Rejected createRejected(Symbol amqpError, String message) {
+ Rejected rejected = new Rejected();
+ ErrorCondition condition = new ErrorCondition();
+ condition.setCondition(amqpError);
+ condition.setDescription(message);
+ rejected.setError(condition);
+ return rejected;
+ }
+
+ @Override
+ public void onFlow(int credits, boolean drain) {
+ }
+
+ @Override
+ public void close(boolean linkRemoteClose) throws ActiveMQAMQPException {
+ // no op
+ }
+
+ @Override
+ public void close(ErrorCondition condition) throws ActiveMQAMQPException {
+ // no op
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/handler/EventHandler.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/handler/EventHandler.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/handler/EventHandler.java
new file mode 100644
index 0000000..91c9a67
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/handler/EventHandler.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.proton.handler;
+
+import org.apache.qpid.proton.engine.Connection;
+import org.apache.qpid.proton.engine.Delivery;
+import org.apache.qpid.proton.engine.Link;
+import org.apache.qpid.proton.engine.Session;
+import org.apache.qpid.proton.engine.Transport;
+
+/**
+ * EventHandler
+ */
+public interface EventHandler {
+
+ void onAuthInit(ProtonHandler handler, Connection connection, boolean sasl);
+
+ void onInit(Connection connection) throws Exception;
+
+ void onLocalOpen(Connection connection) throws Exception;
+
+ void onRemoteOpen(Connection connection) throws Exception;
+
+ void onLocalClose(Connection connection) throws Exception;
+
+ void onRemoteClose(Connection connection) throws Exception;
+
+ void onFinal(Connection connection) throws Exception;
+
+ void onInit(Session session) throws Exception;
+
+ void onLocalOpen(Session session) throws Exception;
+
+ void onRemoteOpen(Session session) throws Exception;
+
+ void onLocalClose(Session session) throws Exception;
+
+ void onRemoteClose(Session session) throws Exception;
+
+ void onFinal(Session session) throws Exception;
+
+ void onInit(Link link) throws Exception;
+
+ void onLocalOpen(Link link) throws Exception;
+
+ void onRemoteOpen(Link link) throws Exception;
+
+ void onLocalClose(Link link) throws Exception;
+
+ void onRemoteClose(Link link) throws Exception;
+
+ void onFlow(Link link) throws Exception;
+
+ void onFinal(Link link) throws Exception;
+
+ void onRemoteDetach(Link link) throws Exception;
+
+ void onDetach(Link link) throws Exception;
+
+ void onDelivery(Delivery delivery) throws Exception;
+
+ void onTransport(Transport transport) throws Exception;
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/handler/Events.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/handler/Events.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/handler/Events.java
new file mode 100644
index 0000000..6552f64
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/handler/Events.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.proton.handler;
+
+import org.apache.qpid.proton.engine.Event;
+import org.apache.qpid.proton.engine.Transport;
+
+public final class Events {
+
+ public static void dispatchTransport(Transport transport, EventHandler handler) throws Exception {
+ handler.onTransport(transport);
+ }
+
+ public static void dispatch(Event event, EventHandler handler) throws Exception {
+ switch (event.getType()) {
+ case CONNECTION_INIT:
+ handler.onInit(event.getConnection());
+ break;
+ case CONNECTION_LOCAL_OPEN:
+ handler.onLocalOpen(event.getConnection());
+ break;
+ case CONNECTION_REMOTE_OPEN:
+ handler.onRemoteOpen(event.getConnection());
+ break;
+ case CONNECTION_LOCAL_CLOSE:
+ handler.onLocalClose(event.getConnection());
+ break;
+ case CONNECTION_REMOTE_CLOSE:
+ handler.onRemoteClose(event.getConnection());
+ break;
+ case CONNECTION_FINAL:
+ handler.onFinal(event.getConnection());
+ break;
+ case SESSION_INIT:
+ handler.onInit(event.getSession());
+ break;
+ case SESSION_LOCAL_OPEN:
+ handler.onLocalOpen(event.getSession());
+ break;
+ case SESSION_REMOTE_OPEN:
+ handler.onRemoteOpen(event.getSession());
+ break;
+ case SESSION_LOCAL_CLOSE:
+ handler.onLocalClose(event.getSession());
+ break;
+ case SESSION_REMOTE_CLOSE:
+ handler.onRemoteClose(event.getSession());
+ break;
+ case SESSION_FINAL:
+ handler.onFinal(event.getSession());
+ break;
+ case LINK_INIT:
+ handler.onInit(event.getLink());
+ break;
+ case LINK_LOCAL_OPEN:
+ handler.onLocalOpen(event.getLink());
+ break;
+ case LINK_REMOTE_OPEN:
+ handler.onRemoteOpen(event.getLink());
+ break;
+ case LINK_LOCAL_CLOSE:
+ handler.onLocalClose(event.getLink());
+ break;
+ case LINK_REMOTE_CLOSE:
+ handler.onRemoteClose(event.getLink());
+ break;
+ case LINK_FLOW:
+ handler.onFlow(event.getLink());
+ break;
+ case LINK_FINAL:
+ handler.onFinal(event.getLink());
+ break;
+ case LINK_LOCAL_DETACH:
+ handler.onDetach(event.getLink());
+ break;
+ case LINK_REMOTE_DETACH:
+ handler.onRemoteDetach(event.getLink());
+ break;
+ case TRANSPORT:
+ handler.onTransport(event.getTransport());
+ break;
+ case DELIVERY:
+ handler.onDelivery(event.getDelivery());
+ break;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/handler/ExtCapability.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/handler/ExtCapability.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/handler/ExtCapability.java
new file mode 100644
index 0000000..b2a6230
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/handler/ExtCapability.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.proton.handler;
+
+import org.apache.activemq.artemis.protocol.amqp.proton.AmqpSupport;
+import org.apache.qpid.proton.amqp.Symbol;
+import org.apache.qpid.proton.engine.Connection;
+
+public class ExtCapability {
+
+ public static final Symbol[] capabilities = new Symbol[] {
+ AmqpSupport.SOLE_CONNECTION_CAPABILITY, AmqpSupport.DELAYED_DELIVERY
+ };
+
+ public static Symbol[] getCapabilities() {
+ return capabilities;
+ }
+
+ public static boolean needUniqueConnection(Connection connection) {
+ Symbol[] extCapabilities = connection.getRemoteDesiredCapabilities();
+ if (extCapabilities != null) {
+ for (Symbol sym : extCapabilities) {
+ if (sym.compareTo(AmqpSupport.SOLE_CONNECTION_CAPABILITY) == 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/handler/ProtonHandler.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/handler/ProtonHandler.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/handler/ProtonHandler.java
new file mode 100644
index 0000000..2efaa1b
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/handler/ProtonHandler.java
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.proton.handler;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.PooledByteBufAllocator;
+import org.apache.activemq.artemis.protocol.amqp.proton.ProtonInitializable;
+import org.apache.activemq.artemis.protocol.amqp.sasl.SASLResult;
+import org.apache.activemq.artemis.protocol.amqp.sasl.ServerSASL;
+import org.apache.activemq.artemis.utils.ByteUtil;
+import org.apache.qpid.proton.Proton;
+import org.apache.qpid.proton.amqp.transport.ErrorCondition;
+import org.apache.qpid.proton.engine.Collector;
+import org.apache.qpid.proton.engine.Connection;
+import org.apache.qpid.proton.engine.EndpointState;
+import org.apache.qpid.proton.engine.Event;
+import org.apache.qpid.proton.engine.Sasl;
+import org.apache.qpid.proton.engine.Transport;
+import org.jboss.logging.Logger;
+
+public class ProtonHandler extends ProtonInitializable {
+
+ private static final Logger log = Logger.getLogger(ProtonHandler.class);
+
+ private static final byte SASL = 0x03;
+
+ private static final byte BARE = 0x00;
+
+ private final Transport transport = Proton.transport();
+
+ private final Connection connection = Proton.connection();
+
+ private final Collector collector = Proton.collector();
+
+ private final Executor dispatchExecutor;
+
+ private final Runnable dispatchRunnable = new Runnable() {
+ @Override
+ public void run() {
+ dispatch();
+ }
+ };
+
+ private ArrayList<EventHandler> handlers = new ArrayList<>();
+
+ private Sasl serverSasl;
+
+ private Sasl clientSasl;
+
+ private final Object lock = new Object();
+
+ private final long creationTime;
+
+ private Map<String, ServerSASL> saslHandlers;
+
+ private SASLResult saslResult;
+
+ protected volatile boolean dataReceived;
+
+ protected boolean receivedFirstPacket = false;
+
+ private int offset = 0;
+
+ public ProtonHandler(Executor dispatchExecutor) {
+ this.dispatchExecutor = dispatchExecutor;
+ this.creationTime = System.currentTimeMillis();
+ transport.bind(connection);
+ connection.collect(collector);
+ }
+
+ public long tick(boolean firstTick) {
+ if (!firstTick) {
+ try {
+ if (connection.getLocalState() != EndpointState.CLOSED) {
+ long rescheduleAt = transport.tick(TimeUnit.NANOSECONDS.toMillis(System.nanoTime()));
+ if (transport.isClosed()) {
+ throw new IllegalStateException("Channel was inactive for to long");
+ }
+ return rescheduleAt;
+ }
+ }
+ catch (Exception e) {
+ transport.close();
+ connection.setCondition(new ErrorCondition());
+ }
+ return 0;
+ }
+ return transport.tick(TimeUnit.NANOSECONDS.toMillis(System.nanoTime()));
+ }
+
+ public int capacity() {
+ synchronized (lock) {
+ return transport.capacity();
+ }
+ }
+
+ public Object getLock() {
+ return lock;
+ }
+
+ public Transport getTransport() {
+ return transport;
+ }
+
+ public Connection getConnection() {
+ return connection;
+ }
+
+ public ProtonHandler addEventHandler(EventHandler handler) {
+ handlers.add(handler);
+ return this;
+ }
+
+ public void createServerSASL(ServerSASL[] handlers) {
+ this.serverSasl = transport.sasl();
+ saslHandlers = new HashMap<>();
+ String[] names = new String[handlers.length];
+ int count = 0;
+ for (ServerSASL handler : handlers) {
+ saslHandlers.put(handler.getName(), handler);
+ names[count++] = handler.getName();
+ }
+ this.serverSasl.server();
+ serverSasl.setMechanisms(names);
+
+ }
+
+ public SASLResult getSASLResult() {
+ return saslResult;
+ }
+
+ public void inputBuffer(ByteBuf buffer) {
+ dataReceived = true;
+ synchronized (lock) {
+ while (buffer.readableBytes() > 0) {
+ int capacity = transport.capacity();
+
+ if (!receivedFirstPacket) {
+ try {
+ byte auth = buffer.getByte(4);
+ if (auth == SASL || auth == BARE) {
+ dispatchAuth(auth == SASL);
+ /*
+ * there is a chance that if SASL Handshake has been carried out that the capacity may change.
+ * */
+ capacity = transport.capacity();
+ }
+ }
+ catch (Throwable e) {
+ log.debug(e.getMessage(), e);
+ }
+
+ receivedFirstPacket = true;
+ }
+
+ if (capacity > 0) {
+ ByteBuffer tail = transport.tail();
+ int min = Math.min(capacity, buffer.readableBytes());
+ tail.limit(min);
+ buffer.readBytes(tail);
+
+ flush();
+ }
+ else {
+ if (capacity == 0) {
+ log.debugf("abandoning: readableBytes=%d", buffer.readableBytes());
+ }
+ else {
+ log.debugf("transport closed, discarding: readableBytes=%d, capacity=%d", buffer.readableBytes(), transport.capacity());
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ public boolean checkDataReceived() {
+ boolean res = dataReceived;
+
+ dataReceived = false;
+
+ return res;
+ }
+
+ public long getCreationTime() {
+ return creationTime;
+ }
+
+ public void outputDone(int bytes) {
+ synchronized (lock) {
+ transport.pop(bytes);
+ offset -= bytes;
+
+ if (offset < 0) {
+ throw new IllegalStateException("You called outputDone for more bytes than you actually received. numberOfBytes=" + bytes +
+ ", outcome result=" + offset);
+ }
+ }
+
+ flush();
+ }
+
+ public ByteBuf outputBuffer() {
+
+ synchronized (lock) {
+ int pending = transport.pending();
+
+ if (pending < 0) {
+ return null;//throw new IllegalStateException("xxx need to close the connection");
+ }
+
+ int size = pending - offset;
+
+ if (size < 0) {
+ throw new IllegalStateException("negative size: " + pending);
+ }
+
+ if (size == 0) {
+ return null;
+ }
+
+ // For returning PooledBytes
+ ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(size);
+ ByteBuffer head = transport.head();
+ head.position(offset);
+ head.limit(offset + size);
+ buffer.writeBytes(head);
+ offset += size; // incrementing offset for future calls
+ return buffer;
+ }
+ }
+
+ public void flush() {
+ synchronized (lock) {
+ transport.process();
+
+ checkServerSASL();
+
+ }
+
+ dispatchExecutor.execute(dispatchRunnable);
+ }
+
+ public void close() {
+ synchronized (lock) {
+ connection.close();
+ }
+ flush();
+ }
+
+ protected void checkServerSASL() {
+ if (serverSasl != null && serverSasl.getRemoteMechanisms().length > 0) {
+ // TODO: should we look at the first only?
+ ServerSASL mechanism = saslHandlers.get(serverSasl.getRemoteMechanisms()[0]);
+ if (mechanism != null) {
+
+ byte[] dataSASL = new byte[serverSasl.pending()];
+ serverSasl.recv(dataSASL, 0, dataSASL.length);
+
+ if (log.isTraceEnabled()) {
+ log.trace("Working on sasl::" + ByteUtil.bytesToHex(dataSASL, 2));
+ }
+
+ saslResult = mechanism.processSASL(dataSASL);
+
+ if (saslResult != null && saslResult.isSuccess()) {
+ serverSasl.done(Sasl.SaslOutcome.PN_SASL_OK);
+ serverSasl = null;
+ saslHandlers.clear();
+ saslHandlers = null;
+ }
+ else {
+ serverSasl.done(Sasl.SaslOutcome.PN_SASL_AUTH);
+ }
+ serverSasl = null;
+ }
+ else {
+ // no auth available, system error
+ serverSasl.done(Sasl.SaslOutcome.PN_SASL_SYS);
+ }
+ }
+ }
+
+ private Event popEvent() {
+ synchronized (lock) {
+ Event ev = collector.peek();
+ if (ev != null) {
+ // pop will invalidate the event
+ // for that reason we make a new one
+ // Events are reused inside the collector, so we need to make a new one here
+ ev = ev.copy();
+ collector.pop();
+ }
+ return ev;
+ }
+ }
+
+ private void dispatchAuth(boolean sasl) {
+ for (EventHandler h : handlers) {
+ h.onAuthInit(this, getConnection(), sasl);
+ }
+ }
+
+ private void dispatch() {
+ Event ev;
+ // We don't hold a lock on the entire event processing
+ // because we could have a distributed deadlock
+ // while processing events (for instance onTransport)
+ // while a client is also trying to write here
+ while ((ev = popEvent()) != null) {
+ for ( EventHandler h : handlers) {
+ if (log.isTraceEnabled()) {
+ log.trace("Handling " + ev + " towards " + h);
+ }
+ try {
+ Events.dispatch(ev, h);
+ }
+ catch (Exception e) {
+ log.warn(e.getMessage(), e);
+ connection.setCondition(new ErrorCondition());
+ }
+ }
+ }
+
+ for (EventHandler h : handlers) {
+ try {
+ h.onTransport(transport);
+ }
+ catch (Exception e) {
+ log.warn(e.getMessage(), e);
+ connection.setCondition(new ErrorCondition());
+ }
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/package-info.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/package-info.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/package-info.java
new file mode 100644
index 0000000..8476f5b
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+/**
+ * This package includes classes used on the interaction with Proton, including Context classes that will be translated
+ * through the model event.
+ */
+package org.apache.activemq.artemis.protocol.amqp.proton;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/AnonymousServerSASL.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/AnonymousServerSASL.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/AnonymousServerSASL.java
new file mode 100644
index 0000000..013b73b
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/AnonymousServerSASL.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.sasl;
+
+public class AnonymousServerSASL implements ServerSASL {
+
+ public AnonymousServerSASL() {
+ }
+
+ @Override
+ public String getName() {
+ return "ANONYMOUS";
+ }
+
+ @Override
+ public SASLResult processSASL(byte[] bytes) {
+ return new PlainSASLResult(true, null, null);
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/PlainSASL.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/PlainSASL.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/PlainSASL.java
new file mode 100644
index 0000000..cb82eba
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/PlainSASL.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.sasl;
+
+import org.apache.activemq.artemis.core.security.SecurityStore;
+
+public class PlainSASL extends ServerSASLPlain {
+
+ private final SecurityStore securityStore;
+
+ public PlainSASL(SecurityStore securityStore) {
+ this.securityStore = securityStore;
+ }
+
+ @Override
+ protected boolean authenticate(String user, String password) {
+ if (securityStore.isSecurityEnabled()) {
+ try {
+ securityStore.authenticate(user, password, null);
+ return true;
+ }
+ catch (Exception e) {
+ return false;
+ }
+ }
+ else {
+ return true;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/PlainSASLResult.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/PlainSASLResult.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/PlainSASLResult.java
new file mode 100644
index 0000000..f138ae3
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/PlainSASLResult.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.sasl;
+
+public class PlainSASLResult implements SASLResult {
+
+ private boolean success;
+ private String user;
+ private String password;
+
+ public PlainSASLResult(boolean success, String user, String password) {
+ this.success = success;
+ this.user = user;
+ this.password = password;
+ }
+
+ @Override
+ public String getUser() {
+ return user;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ @Override
+ public boolean isSuccess() {
+ return success;
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/SASLResult.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/SASLResult.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/SASLResult.java
new file mode 100644
index 0000000..f8c4297
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/SASLResult.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.sasl;
+
+public interface SASLResult {
+
+ String getUser();
+
+ boolean isSuccess();
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/ServerSASL.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/ServerSASL.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/ServerSASL.java
new file mode 100644
index 0000000..43d57d0
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/ServerSASL.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.sasl;
+
+public interface ServerSASL {
+
+ String getName();
+
+ SASLResult processSASL(byte[] bytes);
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/ServerSASLPlain.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/ServerSASLPlain.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/ServerSASLPlain.java
new file mode 100644
index 0000000..da26d2e
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/ServerSASLPlain.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.sasl;
+
+public class ServerSASLPlain implements ServerSASL {
+
+ public static final String NAME = "PLAIN";
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ @Override
+ public SASLResult processSASL(byte[] data) {
+
+ String username = null;
+ String password = null;
+ String bytes = new String(data);
+ String[] credentials = bytes.split(Character.toString((char) 0));
+ int offSet = 0;
+ if (credentials.length > 0) {
+ if (credentials[0].length() == 0) {
+ offSet = 1;
+ }
+
+ if (credentials.length >= offSet) {
+ username = credentials[offSet];
+ }
+ if (credentials.length >= (offSet + 1)) {
+ password = credentials[offSet + 1];
+ }
+ }
+
+ boolean success = authenticate(username, password);
+
+ return new PlainSASLResult(success, username, password);
+ }
+
+ /**
+ * Hook for subclasses to perform the authentication here
+ *
+ * @param user
+ * @param password
+ */
+ protected boolean authenticate(String user, String password) {
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/util/CodecCache.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/util/CodecCache.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/util/CodecCache.java
new file mode 100644
index 0000000..53d0bc1
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/util/CodecCache.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.util;
+
+import org.apache.qpid.proton.codec.AMQPDefinedTypes;
+import org.apache.qpid.proton.codec.DecoderImpl;
+import org.apache.qpid.proton.codec.EncoderImpl;
+
+public class CodecCache {
+
+ private static class EncoderDecoderPair {
+
+ DecoderImpl decoder = new DecoderImpl();
+ EncoderImpl encoder = new EncoderImpl(decoder);
+
+ {
+ AMQPDefinedTypes.registerAllTypes(decoder, encoder);
+ }
+ }
+
+ private static final ThreadLocal<EncoderDecoderPair> tlsCodec = new ThreadLocal<EncoderDecoderPair>() {
+ @Override
+ protected EncoderDecoderPair initialValue() {
+ return new EncoderDecoderPair();
+ }
+ };
+
+ public static DecoderImpl getDecoder() {
+ return tlsCodec.get().decoder;
+ }
+
+ public static EncoderImpl getEncoder() {
+ return tlsCodec.get().encoder;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/util/CreditsSemaphore.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/util/CreditsSemaphore.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/util/CreditsSemaphore.java
new file mode 100644
index 0000000..3eda199
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/util/CreditsSemaphore.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.util;
+
+import java.util.concurrent.locks.AbstractQueuedSynchronizer;
+
+public class CreditsSemaphore {
+
+ @SuppressWarnings("serial")
+ private static class Sync extends AbstractQueuedSynchronizer {
+
+ private Sync(int initial) {
+ setState(initial);
+ }
+
+ public int getCredits() {
+ return getState();
+ }
+
+ @Override
+ public int tryAcquireShared(final int numberOfAqcquires) {
+ for (;;) {
+ int actualSize = getState();
+ int newValue = actualSize - numberOfAqcquires;
+
+ if (newValue < 0) {
+ if (actualSize == getState()) {
+ return -1;
+ }
+ }
+ else if (compareAndSetState(actualSize, newValue)) {
+ return newValue;
+ }
+ }
+ }
+
+ @Override
+ public boolean tryReleaseShared(final int numberOfReleases) {
+ for (;;) {
+ int actualSize = getState();
+ int newValue = actualSize + numberOfReleases;
+
+ if (compareAndSetState(actualSize, newValue)) {
+ return true;
+ }
+
+ }
+ }
+
+ public void setCredits(final int credits) {
+ for (;;) {
+ int actualState = getState();
+ if (compareAndSetState(actualState, credits)) {
+ // This is to wake up any pending threads that could be waiting on queued
+ releaseShared(0);
+ return;
+ }
+ }
+ }
+ }
+
+ private final Sync sync;
+
+ public CreditsSemaphore(int initialCredits) {
+ sync = new Sync(initialCredits);
+ }
+
+ public void acquire() throws InterruptedException {
+ sync.acquireSharedInterruptibly(1);
+ }
+
+ public boolean tryAcquire() {
+ return sync.tryAcquireShared(1) >= 0;
+ }
+
+ public void release() throws InterruptedException {
+ sync.releaseShared(1);
+ }
+
+ public void release(int credits) throws InterruptedException {
+ sync.releaseShared(credits);
+ }
+
+ public void setCredits(int credits) {
+ sync.setCredits(credits);
+ }
+
+ public int getCredits() {
+ return sync.getCredits();
+ }
+
+ public boolean hasQueuedThreads() {
+ return sync.hasQueuedThreads();
+ }
+
+}
\ No newline at end of file
[02/15] activemq-artemis git commit: ARTEMIS-751 Simplification of
the AMQP implementation
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonPubSubTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonPubSubTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonPubSubTest.java
deleted file mode 100644
index 35700ac..0000000
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonPubSubTest.java
+++ /dev/null
@@ -1,337 +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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.tests.integration.proton;
-
-import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.qpid.jms.JmsConnectionFactory;
-import org.apache.qpid.proton.amqp.messaging.AmqpValue;
-import org.apache.qpid.proton.message.ProtonJMessage;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.proton.plug.AMQPClientConnectionContext;
-import org.proton.plug.AMQPClientReceiverContext;
-import org.proton.plug.AMQPClientSessionContext;
-import org.proton.plug.test.Constants;
-import org.proton.plug.test.minimalclient.SimpleAMQPConnector;
-
-import javax.jms.Connection;
-import javax.jms.ExceptionListener;
-import javax.jms.JMSException;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageProducer;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-import javax.jms.Topic;
-import javax.jms.TopicConnection;
-import javax.jms.TopicSession;
-import javax.jms.TopicSubscriber;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-
-public class ProtonPubSubTest extends ProtonTestBase {
- private final String prefix = "foo.bar.";
- private final String pubAddress = "pubAddress";
- private final String prefixedPubAddress = prefix + "pubAddress";
- private final SimpleString ssPubAddress = new SimpleString(pubAddress);
- private final SimpleString ssprefixedPubAddress = new SimpleString(prefixedPubAddress);
- private Connection connection;
- private JmsConnectionFactory factory;
-
- @Override
- protected void configureAmqp(Map<String, Object> params) {
- params.put("pubSubPrefix", prefix);
- }
-
- @Override
- @Before
- public void setUp() throws Exception {
- super.setUp();
- server.createQueue(ssPubAddress, ssPubAddress, new SimpleString("foo=bar"), false, true);
- server.createQueue(ssprefixedPubAddress, ssprefixedPubAddress, new SimpleString("foo=bar"), false, true);
- factory = new JmsConnectionFactory("amqp://localhost:5672");
- factory.setClientID("myClientID");
- connection = factory.createConnection();
- connection.setExceptionListener(new ExceptionListener() {
- @Override
- public void onException(JMSException exception) {
- exception.printStackTrace();
- }
- });
-
- }
-
- @Override
- @After
- public void tearDown() throws Exception {
- try {
- Thread.sleep(250);
- if (connection != null) {
- connection.close();
- }
- }
- finally {
- super.tearDown();
- }
- }
-
- @Test
- public void testNonDurablePubSub() throws Exception {
- int numMessages = 100;
- Topic topic = createTopic(pubAddress);
- TopicSession session = ((TopicConnection) connection).createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageConsumer sub = session.createSubscriber(topic);
-
- Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer producer = sendSession.createProducer(topic);
- connection.start();
- for (int i = 0; i < numMessages; i++) {
- producer.send(sendSession.createTextMessage("message:" + i));
- }
- for (int i = 0; i < numMessages; i++) {
- TextMessage receive = (TextMessage) sub.receive(5000);
- Assert.assertNotNull(receive);
- Assert.assertEquals(receive.getText(), "message:" + i);
- }
- }
-
- @Test
- public void testNonDurableMultiplePubSub() throws Exception {
- int numMessages = 100;
- Topic topic = createTopic(pubAddress);
- TopicSession session = ((TopicConnection) connection).createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageConsumer sub = session.createSubscriber(topic);
- MessageConsumer sub2 = session.createSubscriber(topic);
- MessageConsumer sub3 = session.createSubscriber(topic);
-
- Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer producer = sendSession.createProducer(topic);
- connection.start();
- for (int i = 0; i < numMessages; i++) {
- producer.send(sendSession.createTextMessage("message:" + i));
- }
- for (int i = 0; i < numMessages; i++) {
- TextMessage receive = (TextMessage) sub.receive(5000);
- Assert.assertNotNull(receive);
- Assert.assertEquals(receive.getText(), "message:" + i);
- receive = (TextMessage) sub2.receive(5000);
- Assert.assertNotNull(receive);
- Assert.assertEquals(receive.getText(), "message:" + i);
- receive = (TextMessage) sub3.receive(5000);
- Assert.assertNotNull(receive);
- Assert.assertEquals(receive.getText(), "message:" + i);
- }
- }
-
-
- @Test
- public void testDurablePubSub() throws Exception {
- int numMessages = 100;
- Topic topic = createTopic(pubAddress);
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- TopicSubscriber sub = session.createDurableSubscriber(topic, "myPubId");
-
- Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer producer = sendSession.createProducer(topic);
- connection.start();
- for (int i = 0; i < numMessages; i++) {
- producer.send(sendSession.createTextMessage("message:" + i));
- }
- for (int i = 0; i < numMessages; i++) {
- TextMessage receive = (TextMessage) sub.receive(5000);
- Assert.assertNotNull(receive);
- Assert.assertEquals(receive.getText(), "message:" + i);
- }
- }
-
- @Test
- public void testDurableMultiplePubSub() throws Exception {
- int numMessages = 100;
- Topic topic = createTopic(pubAddress);
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- TopicSubscriber sub = session.createDurableSubscriber(topic, "myPubId");
- TopicSubscriber sub2 = session.createDurableSubscriber(topic, "myPubId2");
- TopicSubscriber sub3 = session.createDurableSubscriber(topic, "myPubId3");
-
- Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer producer = sendSession.createProducer(topic);
- connection.start();
- for (int i = 0; i < numMessages; i++) {
- producer.send(sendSession.createTextMessage("message:" + i));
- }
- for (int i = 0; i < numMessages; i++) {
- TextMessage receive = (TextMessage) sub.receive(5000);
- Assert.assertNotNull(receive);
- Assert.assertEquals(receive.getText(), "message:" + i);
- receive = (TextMessage) sub2.receive(5000);
- Assert.assertNotNull(receive);
- Assert.assertEquals(receive.getText(), "message:" + i);
- receive = (TextMessage) sub3.receive(5000);
- Assert.assertNotNull(receive);
- Assert.assertEquals(receive.getText(), "message:" + i);
- }
- }
-
- @Test
- public void testDurablePubSubReconnect() throws Exception {
- int numMessages = 100;
- Topic topic = createTopic(pubAddress);
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- TopicSubscriber sub = session.createDurableSubscriber(topic, "myPubId");
-
- Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer producer = sendSession.createProducer(topic);
- connection.start();
- for (int i = 0; i < numMessages; i++) {
- producer.send(sendSession.createTextMessage("message:" + i));
- }
- for (int i = 0; i < numMessages; i++) {
- TextMessage receive = (TextMessage) sub.receive(5000);
- Assert.assertNotNull(receive);
- Assert.assertEquals(receive.getText(), "message:" + i);
- }
- connection.close();
- connection = factory.createConnection();
- connection.setExceptionListener(new ExceptionListener() {
- @Override
- public void onException(JMSException exception) {
- exception.printStackTrace();
- }
- });
- session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- sub = session.createDurableSubscriber(topic, "myPubId");
-
- sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- producer = sendSession.createProducer(topic);
- connection.start();
- for (int i = 0; i < numMessages; i++) {
- producer.send(sendSession.createTextMessage("message:" + i));
- }
- for (int i = 0; i < numMessages; i++) {
- TextMessage receive = (TextMessage) sub.receive(5000);
- Assert.assertNotNull(receive);
- Assert.assertEquals(receive.getText(), "message:" + i);
- }
- }
-
- @Test
- public void testDurablePubSubUnsubscribe() throws Exception {
- int numMessages = 100;
- Topic topic = createTopic(pubAddress);
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- TopicSubscriber sub = session.createDurableSubscriber(topic, "myPubId");
-
- Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer producer = sendSession.createProducer(topic);
- connection.start();
- for (int i = 0; i < numMessages; i++) {
- producer.send(sendSession.createTextMessage("message:" + i));
- }
- for (int i = 0; i < numMessages; i++) {
- TextMessage receive = (TextMessage) sub.receive(5000);
- Assert.assertNotNull(receive);
- Assert.assertEquals(receive.getText(), "message:" + i);
- }
- sub.close();
- session.unsubscribe("myPubId");
- }
-
-
- @Test
- public void testPubSubWithSimpleClient() throws Exception {
- SimpleAMQPConnector connector = new SimpleAMQPConnector();
- connector.start();
- AMQPClientConnectionContext clientConnection = connector.connect("127.0.0.1", Constants.PORT);
-
- clientConnection.setContainer("myContainerID");
-
- clientConnection.clientOpen(null);
-
- AMQPClientSessionContext clientSession = clientConnection.createClientSession();
- AMQPClientReceiverContext receiver = clientSession.createReceiver(prefixedPubAddress);
- int numMessages = 100;
- Topic topic = createTopic(prefixedPubAddress);
- Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer producer = sendSession.createProducer(topic);
- connection.start();
- for (int i = 0; i < numMessages; i++) {
- producer.send(sendSession.createTextMessage("message:" + i));
- }
-
- receiver.flow(100);
- for (int i = 0; i < numMessages; i++) {
- ProtonJMessage protonJMessage = receiver.receiveMessage(5000, TimeUnit.MILLISECONDS);
- assertNotNull(protonJMessage);
- assertEquals(((AmqpValue) protonJMessage.getBody()).getValue(), "message:" + i);
- }
-
- }
-
-
- @Test
- public void testMultiplePubSubWithSimpleClient() throws Exception {
- SimpleAMQPConnector connector = new SimpleAMQPConnector();
- connector.start();
- AMQPClientConnectionContext clientConnection = connector.connect("127.0.0.1", Constants.PORT);
-
- clientConnection.setContainer("myContainerID");
-
- clientConnection.clientOpen(null);
-
- AMQPClientSessionContext clientSession = clientConnection.createClientSession();
- AMQPClientReceiverContext receiver = clientSession.createReceiver("sub1", prefixedPubAddress);
- AMQPClientReceiverContext receiver2 = clientSession.createReceiver("sub2", prefixedPubAddress);
- AMQPClientReceiverContext receiver3 = clientSession.createReceiver("sub3", prefixedPubAddress);
- int numMessages = 100;
- Topic topic = createTopic(prefixedPubAddress);
- Session sendSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer producer = sendSession.createProducer(topic);
- receiver.flow(100);
- receiver2.flow(100);
- receiver3.flow(100);
- connection.start();
- for (int i = 0; i < numMessages; i++) {
- producer.send(sendSession.createTextMessage("message:" + i));
- }
-
- for (int i = 0; i < numMessages; i++) {
- ProtonJMessage protonJMessage = receiver.receiveMessage(5000, TimeUnit.MILLISECONDS);
- assertNotNull("did not get message " + i, protonJMessage);
- assertEquals(((AmqpValue) protonJMessage.getBody()).getValue(), "message:" + i);
- protonJMessage = receiver2.receiveMessage(5000, TimeUnit.MILLISECONDS);
- assertNotNull("did not get message " + i, protonJMessage);
- assertEquals(((AmqpValue) protonJMessage.getBody()).getValue(), "message:" + i);
- protonJMessage = receiver3.receiveMessage(5000, TimeUnit.MILLISECONDS);
- assertNotNull("did not get message " + i, protonJMessage);
- assertEquals(((AmqpValue) protonJMessage.getBody()).getValue(), "message:" + i);
- }
-
- }
-
-
- private javax.jms.Topic createTopic(String address) throws Exception {
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- try {
- return session.createTopic(address);
- }
- finally {
- session.close();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonTest.java
deleted file mode 100644
index 984459e..0000000
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonTest.java
+++ /dev/null
@@ -1,1700 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.tests.integration.proton;
-
-import static org.proton.plug.AmqpSupport.contains;
-import static org.proton.plug.AmqpSupport.DELAYED_DELIVERY;
-import static org.proton.plug.AmqpSupport.PRODUCT;
-import static org.proton.plug.AmqpSupport.VERSION;
-
-import javax.jms.BytesMessage;
-import javax.jms.Connection;
-import javax.jms.ConnectionFactory;
-import javax.jms.DeliveryMode;
-import javax.jms.Destination;
-import javax.jms.ExceptionListener;
-import javax.jms.InvalidClientIDException;
-import javax.jms.JMSException;
-import javax.jms.MapMessage;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageProducer;
-import javax.jms.ObjectMessage;
-import javax.jms.QueueBrowser;
-import javax.jms.ResourceAllocationException;
-import javax.jms.Session;
-import javax.jms.StreamMessage;
-import javax.jms.TemporaryQueue;
-import javax.jms.TextMessage;
-import javax.jms.Topic;
-import javax.jms.TopicSession;
-import javax.jms.TopicSubscriber;
-import java.io.IOException;
-import java.io.Serializable;
-import java.lang.reflect.Field;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Random;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.api.core.TransportConfiguration;
-import org.apache.activemq.artemis.core.postoffice.Bindings;
-import org.apache.activemq.artemis.core.remoting.CloseListener;
-import org.apache.activemq.artemis.core.server.Queue;
-import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy;
-import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
-import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
-import org.apache.activemq.artemis.utils.ByteUtil;
-import org.apache.activemq.artemis.utils.VersionLoader;
-import org.apache.activemq.transport.amqp.client.AmqpClient;
-import org.apache.activemq.transport.amqp.client.AmqpConnection;
-import org.apache.activemq.transport.amqp.client.AmqpMessage;
-import org.apache.activemq.transport.amqp.client.AmqpReceiver;
-import org.apache.activemq.transport.amqp.client.AmqpSender;
-import org.apache.activemq.transport.amqp.client.AmqpSession;
-import org.apache.activemq.transport.amqp.client.AmqpValidator;
-import org.apache.qpid.jms.JmsConnectionFactory;
-import org.apache.qpid.proton.amqp.Symbol;
-import org.apache.qpid.proton.amqp.messaging.AmqpValue;
-import org.apache.qpid.proton.amqp.messaging.Properties;
-import org.apache.qpid.proton.message.ProtonJMessage;
-import org.apache.qpid.proton.message.impl.MessageImpl;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import static org.junit.Assume.assumeTrue;
-import org.proton.plug.AMQPClientConnectionContext;
-import org.proton.plug.AMQPClientReceiverContext;
-import org.proton.plug.AMQPClientSenderContext;
-import org.proton.plug.AMQPClientSessionContext;
-import org.proton.plug.context.server.ProtonServerReceiverContext;
-import org.proton.plug.test.Constants;
-import org.proton.plug.test.minimalclient.SimpleAMQPConnector;
-
-@RunWith(Parameterized.class)
-public class ProtonTest extends ProtonTestBase {
-
- private static final String amqpConnectionUri = "amqp://localhost:5672";
-
- private static final String tcpAmqpConnectionUri = "tcp://localhost:5672";
-
- private static final String userName = "guest";
-
- private static final String password = "guest";
-
-
- private static final String brokerName = "my-broker";
-
- private static final long maxSizeBytes = 1 * 1024 * 1024;
-
- private static final long maxSizeBytesRejectThreshold = 2 * 1024 * 1024;
-
- private int messagesSent = 0;
-
- // this will ensure that all tests in this class are run twice,
- // once with "true" passed to the class' constructor and once with "false"
- @Parameterized.Parameters(name = "{0}")
- public static Collection getParameters() {
-
- // these 3 are for comparison
- return Arrays.asList(new Object[][]{{"AMQP", 0}, {"ActiveMQ (InVM)", 1}, {"ActiveMQ (Netty)", 2}, {"AMQP_ANONYMOUS", 3}});
- }
-
- ConnectionFactory factory;
-
- private final int protocol;
-
- public ProtonTest(String name, int protocol) {
- this.coreAddress = "jms.queue.exampleQueue";
- this.protocol = protocol;
- if (protocol == 0 || protocol == 3) {
- this.address = coreAddress;
- }
- else {
- this.address = "exampleQueue";
- }
- }
-
- private final String coreAddress;
- private final String address;
- private Connection connection;
-
- @Override
- @Before
- public void setUp() throws Exception {
- super.setUp();
-
- server.createQueue(new SimpleString(coreAddress), new SimpleString(coreAddress), null, true, false);
- server.createQueue(new SimpleString(coreAddress + "1"), new SimpleString(coreAddress + "1"), null, true, false);
- server.createQueue(new SimpleString(coreAddress + "2"), new SimpleString(coreAddress + "2"), null, true, false);
- server.createQueue(new SimpleString(coreAddress + "3"), new SimpleString(coreAddress + "3"), null, true, false);
- server.createQueue(new SimpleString(coreAddress + "4"), new SimpleString(coreAddress + "4"), null, true, false);
- server.createQueue(new SimpleString(coreAddress + "5"), new SimpleString(coreAddress + "5"), null, true, false);
- server.createQueue(new SimpleString(coreAddress + "6"), new SimpleString(coreAddress + "6"), null, true, false);
- server.createQueue(new SimpleString(coreAddress + "7"), new SimpleString(coreAddress + "7"), null, true, false);
- server.createQueue(new SimpleString(coreAddress + "8"), new SimpleString(coreAddress + "8"), null, true, false);
- server.createQueue(new SimpleString(coreAddress + "9"), new SimpleString(coreAddress + "9"), null, true, false);
- server.createQueue(new SimpleString(coreAddress + "10"), new SimpleString(coreAddress + "10"), null, true, false);
- server.createQueue(new SimpleString("amqp_testtopic"), new SimpleString("amqp_testtopic"), null, true, false);
- server.createQueue(new SimpleString("amqp_testtopic" + "1"), new SimpleString("amqp_testtopic" + "1"), null, true, false);
- server.createQueue(new SimpleString("amqp_testtopic" + "2"), new SimpleString("amqp_testtopic" + "2"), null, true, false);
- server.createQueue(new SimpleString("amqp_testtopic" + "3"), new SimpleString("amqp_testtopic" + "3"), null, true, false);
- server.createQueue(new SimpleString("amqp_testtopic" + "4"), new SimpleString("amqp_testtopic" + "4"), null, true, false);
- server.createQueue(new SimpleString("amqp_testtopic" + "5"), new SimpleString("amqp_testtopic" + "5"), null, true, false);
- server.createQueue(new SimpleString("amqp_testtopic" + "6"), new SimpleString("amqp_testtopic" + "6"), null, true, false);
- server.createQueue(new SimpleString("amqp_testtopic" + "7"), new SimpleString("amqp_testtopic" + "7"), null, true, false);
- server.createQueue(new SimpleString("amqp_testtopic" + "8"), new SimpleString("amqp_testtopic" + "8"), null, true, false);
- server.createQueue(new SimpleString("amqp_testtopic" + "9"), new SimpleString("amqp_testtopic" + "9"), null, true, false);
- server.createQueue(new SimpleString("amqp_testtopic" + "10"), new SimpleString("amqp_testtopic" + "10"), null, true, false);
- connection = createConnection();
-
- }
-
- @Override
- @After
- public void tearDown() throws Exception {
- try {
- Thread.sleep(250);
- if (connection != null) {
- connection.close();
- }
- }
- finally {
- super.tearDown();
- }
- }
-
- @Test
- public void testDurableSubscriptionUnsubscribe() throws Exception {
- if (protocol != 0 && protocol != 3) return; // Only run this test for AMQP protocol
- Connection connection = createConnection("myClientId");
- try {
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Topic topic = session.createTopic("amqp_testtopic");
- TopicSubscriber myDurSub = session.createDurableSubscriber(topic, "myDurSub");
- session.close();
- connection.close();
- connection = createConnection("myClientId");
- session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- myDurSub = session.createDurableSubscriber(topic, "myDurSub");
- myDurSub.close();
- Assert.assertNotNull(server.getPostOffice().getBinding(new SimpleString("myClientId:myDurSub")));
- session.unsubscribe("myDurSub");
- Assert.assertNull(server.getPostOffice().getBinding(new SimpleString("myClientId:myDurSub")));
- session.close();
- connection.close();
- }
- finally {
- if (connection != null) {
- connection.close();
- }
- }
- }
-
- @Test
- public void testTemporarySubscriptionDeleted() throws Exception {
- if (protocol != 0 && protocol != 3) return; // Only run this test for AMQP protocol
- try {
- TopicSession session = (TopicSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Topic topic = session.createTopic("amqp_testtopic");
- TopicSubscriber myDurSub = session.createSubscriber(topic);
- Bindings bindingsForAddress = server.getPostOffice().getBindingsForAddress(new SimpleString("amqp_testtopic"));
- Assert.assertEquals(2, bindingsForAddress.getBindings().size());
- session.close();
- final CountDownLatch latch = new CountDownLatch(1);
- server.getRemotingService().getConnections().iterator().next().addCloseListener(new CloseListener() {
- @Override
- public void connectionClosed() {
- latch.countDown();
- }
- });
- connection.close();
- latch.await(5, TimeUnit.SECONDS);
- bindingsForAddress = server.getPostOffice().getBindingsForAddress(new SimpleString("amqp_testtopic"));
- Assert.assertEquals(1, bindingsForAddress.getBindings().size());
- }
- finally {
- if (connection != null) {
- connection.close();
- }
- }
- }
-
- @Test
- public void testBrokerContainerId() throws Exception {
- if (protocol != 0 && protocol != 3) return; // Only run this test for AMQP protocol
-
- AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
- AmqpConnection amqpConnection = client.connect();
- try {
- assertTrue(brokerName.equals(amqpConnection.getEndpoint().getRemoteContainer()));
- }
- finally {
- amqpConnection.close();
- }
- }
-
- @Test
- public void testBrokerConnectionProperties() throws Exception {
- if (protocol != 0 && protocol != 3) return; // Only run this test for AMQP protocol
-
- AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
- AmqpConnection amqpConnection = client.connect();
- try {
- Map<Symbol, Object> properties = amqpConnection.getEndpoint().getRemoteProperties();
- assertTrue(properties != null);
- if (properties != null) {
- assertTrue("apache-activemq-artemis".equals(properties.get(Symbol.valueOf("product"))));
- assertTrue(VersionLoader.getVersion().getFullVersion().equals(properties.get(Symbol.valueOf("version"))));
- }
- }
- finally {
- amqpConnection.close();
- }
- }
-
- @Test(timeout = 60000)
- public void testConnectionCarriesExpectedCapabilities() throws Exception {
- if (protocol != 0 && protocol != 3) return; // Only run this test for AMQP protocol
-
- AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
- assertNotNull(client);
-
- client.setValidator(new AmqpValidator() {
-
- @Override
- public void inspectOpenedResource(org.apache.qpid.proton.engine.Connection connection) {
-
- Symbol[] offered = connection.getRemoteOfferedCapabilities();
-
- if (!contains(offered, DELAYED_DELIVERY)) {
- markAsInvalid("Broker did not indicate it support delayed message delivery");
- return;
- }
-
- Map<Symbol, Object> properties = connection.getRemoteProperties();
- if (!properties.containsKey(PRODUCT)) {
- markAsInvalid("Broker did not send a queue product name value");
- return;
- }
-
- if (!properties.containsKey(VERSION)) {
- markAsInvalid("Broker did not send a queue version value");
- return;
- }
- }
- });
-
- AmqpConnection connection = client.connect();
- try {
- assertNotNull(connection);
- connection.getStateInspector().assertValid();
- }
- finally {
- connection.close();
- }
- }
-
- @Test(timeout = 60000)
- public void testSendWithDeliveryTimeHoldsMessage() throws Exception {
- if (protocol != 0 && protocol != 3) return; // Only run this test for AMQP protocol
-
- AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
- assertNotNull(client);
-
- AmqpConnection connection = client.connect();
- try {
- AmqpSession session = connection.createSession();
-
- AmqpSender sender = session.createSender(address);
- AmqpReceiver receiver = session.createReceiver(address);
-
- AmqpMessage message = new AmqpMessage();
- long deliveryTime = System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5);
- message.setMessageAnnotation("x-opt-delivery-time", deliveryTime);
- message.setText("Test-Message");
- sender.send(message);
-
- // Now try and get the message
- receiver.flow(1);
-
- // Shouldn't get this since we delayed the message.
- assertNull(receiver.receive(5, TimeUnit.SECONDS));
- }
- finally {
- connection.close();
- }
- }
-
- @Test(timeout = 60000)
- public void testSendWithDeliveryTimeDeliversMessageAfterDelay() throws Exception {
- if (protocol != 0 && protocol != 3) return; // Only run this test for AMQP protocol
-
- AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
- assertNotNull(client);
-
- AmqpConnection connection = client.connect();
- try {
- AmqpSession session = connection.createSession();
-
- AmqpSender sender = session.createSender(address);
- AmqpReceiver receiver = session.createReceiver(address);
-
- AmqpMessage message = new AmqpMessage();
- long deliveryTime = System.currentTimeMillis() + 2000;
- message.setMessageAnnotation("x-opt-delivery-time", deliveryTime);
- message.setText("Test-Message");
- sender.send(message);
-
- // Now try and get the message
- receiver.flow(1);
-
- AmqpMessage received = receiver.receive(10, TimeUnit.SECONDS);
- assertNotNull(received);
- received.accept();
- Long msgDeliveryTime = (Long) received.getMessageAnnotation("x-opt-delivery-time");
- assertNotNull(msgDeliveryTime);
- assertEquals(deliveryTime, msgDeliveryTime.longValue());
- }
- finally {
- connection.close();
- }
- }
-
- @Test
- public void testCreditsAreAllocatedOnlyOnceOnLinkCreate() throws Exception {
- if (protocol != 0 && protocol != 3) return; // Only run this test for AMQP protocol
-
- // Only allow 1 credit to be submitted at a time.
- Field maxCreditAllocation = ProtonServerReceiverContext.class.getDeclaredField("maxCreditAllocation");
- maxCreditAllocation.setAccessible(true);
- int originalMaxCreditAllocation = maxCreditAllocation.getInt(null);
- maxCreditAllocation.setInt(null, 1);
-
- String destinationAddress = address + 1;
- AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
- AmqpConnection amqpConnection = client.connect();
- try {
- AmqpSession session = amqpConnection.createSession();
- AmqpSender sender = session.createSender(destinationAddress);
- assertTrue(sender.getSender().getCredit() == 1);
- }
- finally {
- amqpConnection.close();
- maxCreditAllocation.setInt(null, originalMaxCreditAllocation);
- }
- }
-
- @Test
- public void testTemporaryQueue() throws Throwable {
-
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- TemporaryQueue queue = session.createTemporaryQueue();
- System.out.println("queue:" + queue.getQueueName());
- MessageProducer p = session.createProducer(queue);
-
- TextMessage message = session.createTextMessage();
- message.setText("Message temporary");
- p.send(message);
-
- MessageConsumer cons = session.createConsumer(queue);
- connection.start();
-
- message = (TextMessage) cons.receive(5000);
- Assert.assertNotNull(message);
- }
-
- @Test
- public void testCommitProducer() throws Throwable {
-
- Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
- javax.jms.Queue queue = createQueue(address);
- System.out.println("queue:" + queue.getQueueName());
- MessageProducer p = session.createProducer(queue);
- for (int i = 0; i < 10; i++) {
- TextMessage message = session.createTextMessage();
- message.setText("Message:" + i);
- p.send(message);
- }
- session.commit();
- session.close();
- Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable();
- Assert.assertEquals(q.getMessageCount(), 10);
- }
-
- @Test
- public void testRollbackProducer() throws Throwable {
-
- Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
- javax.jms.Queue queue = createQueue(address);
- System.out.println("queue:" + queue.getQueueName());
- MessageProducer p = session.createProducer(queue);
- for (int i = 0; i < 10; i++) {
- TextMessage message = session.createTextMessage();
- message.setText("Message:" + i);
- p.send(message);
- }
- session.rollback();
- session.close();
- Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable();
- Assert.assertEquals(q.getMessageCount(), 0);
- }
-
- @Test
- public void testCommitConsumer() throws Throwable {
-
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- javax.jms.Queue queue = createQueue(address);
- System.out.println("queue:" + queue.getQueueName());
- MessageProducer p = session.createProducer(queue);
- for (int i = 0; i < 10; i++) {
- TextMessage message = session.createTextMessage();
- message.setText("Message:" + i);
- p.send(message);
- }
- session.close();
-
- session = connection.createSession(true, Session.SESSION_TRANSACTED);
- MessageConsumer cons = session.createConsumer(queue);
- connection.start();
-
- for (int i = 0; i < 10; i++) {
- TextMessage message = (TextMessage) cons.receive(5000);
- Assert.assertNotNull(message);
- Assert.assertEquals("Message:" + i, message.getText());
- }
- session.commit();
- Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable();
- Assert.assertEquals(q.getMessageCount(), 0);
- }
-
-
- @Test
- public void testRollbackConsumer() throws Throwable {
-
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- javax.jms.Queue queue = createQueue(address);
- System.out.println("queue:" + queue.getQueueName());
- MessageProducer p = session.createProducer(queue);
- for (int i = 0; i < 10; i++) {
- TextMessage message = session.createTextMessage();
- message.setText("Message:" + i);
- p.send(message);
- }
- session.close();
-
- session = connection.createSession(true, Session.SESSION_TRANSACTED);
- MessageConsumer cons = session.createConsumer(queue);
- connection.start();
-
- for (int i = 0; i < 10; i++) {
- TextMessage message = (TextMessage) cons.receive(5000);
- Assert.assertNotNull(message);
- Assert.assertEquals("Message:" + i, message.getText());
- }
- session.rollback();
- Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable();
- Assert.assertEquals(q.getMessageCount(), 10);
- }
-
- @Test
- public void testResourceLimitExceptionOnAddressFull() throws Exception {
- if (protocol != 0 && protocol != 3) return; // Only run this test for AMQP protocol
- setAddressFullBlockPolicy();
- String destinationAddress = address + 1;
- fillAddress(destinationAddress);
-
- long addressSize = server.getPagingManager().getPageStore(new SimpleString(destinationAddress)).getAddressSize();
- assertTrue(addressSize >= maxSizeBytesRejectThreshold);
- }
-
- @Test
- public void testAddressIsBlockedForOtherProdudersWhenFull() throws Exception {
- if (protocol != 0 && protocol != 3) return; // Only run this test for AMQP protocol
- setAddressFullBlockPolicy();
-
- String destinationAddress = address + 1;
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Destination d = session.createQueue(destinationAddress);
- MessageProducer p = session.createProducer(d);
-
- fillAddress(destinationAddress);
-
- Exception e = null;
- try {
- p.send(session.createBytesMessage());
- }
- catch (ResourceAllocationException rae) {
- e = rae;
- }
- assertTrue(e instanceof ResourceAllocationException);
- assertTrue(e.getMessage().contains("resource-limit-exceeded"));
-
- long addressSize = server.getPagingManager().getPageStore(new SimpleString(destinationAddress)).getAddressSize();
- assertTrue(addressSize >= maxSizeBytesRejectThreshold);
- }
-
- @Test
- public void testCreditsAreNotAllocatedWhenAddressIsFull() throws Exception {
- if (protocol != 0 && protocol != 3) return; // Only run this test for AMQP protocol
- setAddressFullBlockPolicy();
-
- // Only allow 1 credit to be submitted at a time.
- Field maxCreditAllocation = ProtonServerReceiverContext.class.getDeclaredField("maxCreditAllocation");
- maxCreditAllocation.setAccessible(true);
- int originalMaxCreditAllocation = maxCreditAllocation.getInt(null);
- maxCreditAllocation.setInt(null, 1);
-
- String destinationAddress = address + 1;
- AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
- AmqpConnection amqpConnection = client.connect();
- try {
- AmqpSession session = amqpConnection.createSession();
- AmqpSender sender = session.createSender(destinationAddress);
-
- // Use blocking send to ensure buffered messages do not interfere with credit.
- sender.setSendTimeout(-1);
- sendUntilFull(sender);
-
- // This should be -1. A single message is buffered in the client, and 0 credit has been allocated.
- assertTrue(sender.getSender().getCredit() == -1);
-
- long addressSize = server.getPagingManager().getPageStore(new SimpleString(destinationAddress)).getAddressSize();
- assertTrue(addressSize >= maxSizeBytes && addressSize <= maxSizeBytesRejectThreshold);
- }
- finally {
- amqpConnection.close();
- maxCreditAllocation.setInt(null, originalMaxCreditAllocation);
- }
- }
-
- @Test
- public void testCreditsAreRefreshedWhenAddressIsUnblocked() throws Exception {
- if (protocol != 0 && protocol != 3) return; // Only run this test for AMQP protocol
- setAddressFullBlockPolicy();
-
- String destinationAddress = address + 1;
- fillAddress(destinationAddress);
-
- AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
- AmqpConnection amqpConnection = amqpConnection = client.connect();
- try {
- AmqpSession session = amqpConnection.createSession();
- AmqpSender sender = session.createSender(destinationAddress);
-
- // Wait for a potential flow frame.
- Thread.sleep(500);
- assertEquals(0, sender.getSender().getCredit());
-
- // Empty Address except for 1 message used later.
- AmqpReceiver receiver = session.createReceiver(destinationAddress);
- receiver.flow(100);
-
- AmqpMessage m;
- for (int i = 0; i < messagesSent - 1; i++) {
- m = receiver.receive();
- m.accept();
- }
-
- // Wait for address to unblock and flow frame to arrive
- Thread.sleep(500);
-
- assertTrue(sender.getSender().getCredit() >= 0);
- }
- finally {
- amqpConnection.close();
- }
- }
-
- @Test
- public void testNewLinkAttachAreNotAllocatedCreditsWhenAddressIsBlocked() throws Exception {
- if (protocol != 0 && protocol != 3) return; // Only run this test for AMQP protocol
- setAddressFullBlockPolicy();
-
- fillAddress(address + 1);
- AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
- AmqpConnection amqpConnection = client.connect();
- try {
- AmqpSession session = amqpConnection.createSession();
- AmqpSender sender = session.createSender(address + 1);
- // Wait for a potential flow frame.
- Thread.sleep(1000);
- assertEquals(0, sender.getSender().getCredit());
- }
- finally {
- amqpConnection.close();
- }
- }
-
- @Test
- public void testTxIsRolledBackOnRejectedPreSettledMessage() throws Throwable {
- if (protocol != 0 && protocol != 3) return; // Only run this test for AMQP protocol
- setAddressFullBlockPolicy();
-
- // Create the link attach before filling the address to ensure the link is allocated credit.
- AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
- AmqpConnection amqpConnection = client.connect();
-
- AmqpSession session = amqpConnection.createSession();
- AmqpSender sender = session.createSender(address);
- sender.setPresettle(true);
-
- fillAddress(address);
-
- final AmqpMessage message = new AmqpMessage();
- byte[] payload = new byte[50 * 1024];
- message.setBytes(payload);
-
- Exception expectedException = null;
- try {
- session.begin();
- sender.send(message);
- session.commit();
- }
- catch (Exception e) {
- expectedException = e;
- }
- finally {
- amqpConnection.close();
- }
-
- assertNotNull(expectedException);
- assertTrue(expectedException.getMessage().contains("resource-limit-exceeded"));
- assertTrue(expectedException.getMessage().contains("Address is full: " + address));
- }
-
- /**
- * Fills an address. Careful when using this method. Only use when rejected messages are switched on.
- * @param address
- * @return
- * @throws Exception
- */
- private void fillAddress(String address) throws Exception {
- AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
- AmqpConnection amqpConnection = client.connect();
- Exception exception = null;
- try {
- AmqpSession session = amqpConnection.createSession();
- AmqpSender sender = session.createSender(address);
- sendUntilFull(sender);
- }
- catch (Exception e) {
- exception = e;
- }
- finally {
- amqpConnection.close();
- }
-
- // Should receive a rejected error
- assertNotNull(exception);
- assertTrue(exception.getMessage().contains("amqp:resource-limit-exceeded"));
- }
-
- private void sendUntilFull(final AmqpSender sender) throws Exception {
- final AmqpMessage message = new AmqpMessage();
- byte[] payload = new byte[50 * 1024];
- message.setBytes(payload);
-
- final int maxMessages = 50;
- final AtomicInteger sentMessages = new AtomicInteger(0);
- final Exception[] errors = new Exception[1];
- final CountDownLatch timeout = new CountDownLatch(1);
-
- Runnable sendMessages = new Runnable() {
- @Override
- public void run() {
- try {
- for (int i = 0; i < maxMessages; i++) {
- sender.send(message);
- sentMessages.getAndIncrement();
- }
- timeout.countDown();
- }
- catch (IOException e) {
- errors[0] = e;
- }
- }
- };
-
- Thread t = new Thread(sendMessages);
- t.start();
-
- timeout.await(5, TimeUnit.SECONDS);
-
- messagesSent = sentMessages.get();
- if (errors[0] != null) {
- throw errors[0];
- }
- }
-
- @Test
- public void testLinkDetatchErrorIsCorrectWhenQueueDoesNotExists() throws Exception {
- AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
- AmqpConnection amqpConnection = client.connect();
- AmqpSession session = amqpConnection.createSession();
-
- Exception expectedException = null;
- try {
- session.createSender("AnAddressThatDoesNotExist");
- }
- catch (Exception e) {
- expectedException = e;
- }
-
- assertNotNull(expectedException);
- assertTrue(expectedException.getMessage().contains("amqp:not-found"));
- assertTrue(expectedException.getMessage().contains("target address does not exist"));
- }
-
- @Test
- public void testSendingAndReceivingToQueueWithDifferentAddressAndQueueName() throws Exception {
-
- String queueName = "TestQueueName";
- String address = "TestAddress";
-
- server.createQueue(new SimpleString(address), new SimpleString(queueName), null, true, false);
-
- AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
- AmqpConnection amqpConnection = client.connect();
- AmqpSession session = amqpConnection.createSession();
- AmqpSender sender = session.createSender(address);
- AmqpReceiver receiver = session.createReceiver(queueName);
- receiver.flow(1);
-
- AmqpMessage message = new AmqpMessage();
- message.setText("TestPayload");
- sender.send(message);
-
- AmqpMessage receivedMessage = receiver.receive();
- assertNotNull(receivedMessage);
- }
-
- @Test
- public void testManagementQueryOverAMQP() throws Throwable {
- assumeTrue(protocol == 0 || protocol == 3); // Only run this test for AMQP protocol
-
- AmqpClient client = new AmqpClient(new URI(tcpAmqpConnectionUri), userName, password);
- AmqpConnection amqpConnection = client.connect();
- try {
- String destinationAddress = address + 1;
- AmqpSession session = amqpConnection.createSession();
- AmqpSender sender = session.createSender("jms.queue.activemq.management");
- AmqpReceiver receiver = session.createReceiver(destinationAddress);
- receiver.flow(10);
-
- //create request message for getQueueNames query
- AmqpMessage request = new AmqpMessage();
- request.setApplicationProperty("_AMQ_ResourceName", "core.server");
- request.setApplicationProperty("_AMQ_OperationName", "getQueueNames");
- request.setApplicationProperty("JMSReplyTo", destinationAddress);
- request.setText("[]");
-
- sender.send(request);
- AmqpMessage response = receiver.receive(50, TimeUnit.SECONDS);
- Assert.assertNotNull(response);
- assertNotNull(response);
- Object section = response.getWrappedMessage().getBody();
- assertTrue(section instanceof AmqpValue);
- Object value = ((AmqpValue) section).getValue();
- assertTrue(value instanceof String);
- assertTrue(((String) value).length() > 0);
- assertTrue(((String) value).contains(destinationAddress));
- response.accept();
- }
- finally {
- amqpConnection.close();
- }
- }
-
- @Test
- public void testReplyTo() throws Throwable {
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- TemporaryQueue queue = session.createTemporaryQueue();
- MessageProducer p = session.createProducer(queue);
-
- TextMessage message = session.createTextMessage();
- message.setText("Message temporary");
- message.setJMSReplyTo(createQueue(address));
- p.send(message);
-
- MessageConsumer cons = session.createConsumer(queue);
- connection.start();
-
- message = (TextMessage) cons.receive(5000);
- Destination jmsReplyTo = message.getJMSReplyTo();
- Assert.assertNotNull(jmsReplyTo);
- Assert.assertNotNull(message);
- }
-
- @Test
- public void testReplyToNonJMS() throws Throwable {
-
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- TemporaryQueue queue = session.createTemporaryQueue();
- System.out.println("queue:" + queue.getQueueName());
- MessageProducer p = session.createProducer(queue);
-
- TextMessage message = session.createTextMessage();
- message.setText("Message temporary");
- message.setJMSReplyTo(createQueue("someaddress"));
- p.send(message);
-
- MessageConsumer cons = session.createConsumer(queue);
- connection.start();
-
- message = (TextMessage) cons.receive(5000);
- Destination jmsReplyTo = message.getJMSReplyTo();
- Assert.assertNotNull(jmsReplyTo);
- Assert.assertNotNull(message);
-
- }
-
- /*
- // Uncomment testLoopBrowser to validate the hunging on the test
- @Test
- public void testLoopBrowser() throws Throwable {
- for (int i = 0 ; i < 1000; i++) {
- System.out.println("#test " + i);
- testBrowser();
- tearDown();
- setUp();
- }
- } */
-
- /**
- * This test eventually fails because of: https://issues.apache.org/jira/browse/QPID-4901
- *
- * @throws Throwable
- */
- //@Test // TODO: re-enable this when we can get a version free of QPID-4901 bug
- public void testBrowser() throws Throwable {
-
- boolean success = false;
-
- for (int i = 0; i < 10; i++) {
- // As this test was hunging, we added a protection here to fail it instead.
- // it seems something on the qpid client, so this failure belongs to them and we can ignore it on
- // our side (ActiveMQ)
- success = runWithTimeout(new RunnerWithEX() {
- @Override
- public void run() throws Throwable {
- int numMessages = 50;
- javax.jms.Queue queue = createQueue(address);
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer p = session.createProducer(queue);
- for (int i = 0; i < numMessages; i++) {
- TextMessage message = session.createTextMessage();
- message.setText("msg:" + i);
- p.send(message);
- }
-
- connection.close();
- Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable();
-
- connection = createConnection();
- session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- QueueBrowser browser = session.createBrowser(queue);
- Enumeration enumeration = browser.getEnumeration();
- int count = 0;
- while (enumeration.hasMoreElements()) {
- Message msg = (Message) enumeration.nextElement();
- Assert.assertNotNull("" + count, msg);
- Assert.assertTrue("" + msg, msg instanceof TextMessage);
- String text = ((TextMessage) msg).getText();
- Assert.assertEquals(text, "msg:" + count++);
- }
- Assert.assertEquals(count, numMessages);
- connection.close();
- Assert.assertEquals(getMessageCount(q), numMessages);
- }
- }, 5000);
-
- if (success) {
- break;
- }
- else {
- System.err.println("Had to make it fail!!!");
- tearDown();
- setUp();
- }
- }
-
- // There is a bug on the qpid client library currently, we can expect having to interrupt the thread on browsers.
- // but we can't have it on 10 iterations... something must be broken if that's the case
- Assert.assertTrue("Test had to interrupt on all occasions.. this is beyond the expected for the test", success);
- }
-
- @Test
- public void testReceiveImmediate() throws Exception {
- testReceiveImmediate(1000, 1000);
- }
-
- @Test
- public void testReceiveImmediateMoreCredits() throws Exception {
- testReceiveImmediate(1000, 100);
- }
-
- @Test
- public void testReceiveImmediateMoreMessages() throws Exception {
- testReceiveImmediate(100, 1000);
- }
-
- public void testReceiveImmediate(int noCredits, int noMessages) throws Exception {
-
- if (protocol != 0 && protocol != 3) return; // Only run this test for AMQP protocol
-
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- javax.jms.Queue queue = createQueue(address);
- MessageProducer p = session.createProducer(queue);
-
- TextMessage message = session.createTextMessage();
- message.setText("Message temporary");
- for (int i = 0; i < noMessages; i++) {
- message.setText("msg:" + i);
- p.send(message);
- }
-
- SimpleAMQPConnector connector = new SimpleAMQPConnector();
- connector.start();
- AMQPClientConnectionContext clientConnection = connector.connect("127.0.0.1", Constants.PORT);
-
- clientConnection.clientOpen(null);
-
- AMQPClientSessionContext csession = clientConnection.createClientSession();
- AMQPClientReceiverContext receiver = csession.createReceiver(address);
- receiver.drain(noCredits);
-
- int expectedNumberMessages = noCredits > noMessages ? noMessages : noCredits;
- for (int i = 0; i < expectedNumberMessages; i++) {
- ProtonJMessage protonJMessage = receiver.receiveMessage(500, TimeUnit.SECONDS);
- Assert.assertNotNull(protonJMessage);
- }
- ProtonJMessage protonJMessage = receiver.receiveMessage(500, TimeUnit.MILLISECONDS);
- Assert.assertNull(protonJMessage);
-
- assertFalse(receiver.isDraining());
- if (noCredits >= noMessages) {
- assertEquals(noCredits - noMessages, receiver.drained());
- }
- else {
- assertEquals(0, receiver.drained());
- }
- }
-
- @Test
- public void testDynamicSenderLink() throws Exception {
-
- if (protocol != 0 && protocol != 3) return; // Only run this test for AMQP protocol
-
- SimpleAMQPConnector connector = new SimpleAMQPConnector();
- connector.start();
- AMQPClientConnectionContext clientConnection = connector.connect("127.0.0.1", Constants.PORT);
-
- clientConnection.clientOpen(null);
-
- AMQPClientSessionContext csession = clientConnection.createClientSession();
- AMQPClientSenderContext sender = csession.createDynamicSender(false);
-
- String address = sender.getAddress();
-
- AMQPClientReceiverContext receiver = csession.createReceiver(address);
- receiver.flow(1);
-
- // Send one on the dynamic address
- MessageImpl message = (MessageImpl) org.apache.qpid.proton.message.Message.Factory.create();
-
- Properties props = new Properties();
- Map<Object, Object> map = new HashMap<>();
-
- map.put("some-property", 1);
- AmqpValue value = new AmqpValue(map);
- message.setBody(value);
- message.setProperties(props);
- sender.send(message);
-
- ProtonJMessage protonJMessage = receiver.receiveMessage(500, TimeUnit.MILLISECONDS);
- Assert.assertNotNull(protonJMessage);
- }
-
- @Test
- public void testConnection() throws Exception {
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- MessageConsumer cons = session.createConsumer(createQueue(address));
-
- org.apache.activemq.artemis.core.server.Queue serverQueue = server.locateQueue(SimpleString.toSimpleString(coreAddress));
-
- assertEquals(1, serverQueue.getConsumerCount());
-
- cons.close();
-
- for (int i = 0; i < 100 && serverQueue.getConsumerCount() != 0; i++) {
- Thread.sleep(500);
- }
-
- assertEquals(0, serverQueue.getConsumerCount());
-
- session.close();
-
- }
-
- @Test
- public void testMessagesSentTransactional() throws Exception {
- int numMessages = 1000;
- javax.jms.Queue queue = createQueue(address);
- Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
- MessageProducer p = session.createProducer(queue);
- byte[] bytes = new byte[2048];
- new Random().nextBytes(bytes);
- for (int i = 0; i < numMessages; i++) {
- TextMessage message = session.createTextMessage();
- message.setText("msg:" + i);
- p.send(message);
- }
- session.commit();
- connection.close();
- Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable();
- for (long timeout = System.currentTimeMillis() + 5000; timeout > System.currentTimeMillis() && getMessageCount(q) != numMessages; ) {
- Thread.sleep(1);
- }
- Assert.assertEquals(numMessages, getMessageCount(q));
- }
-
- @Test
- public void testMessagesSentTransactionalRolledBack() throws Exception {
- int numMessages = 1;
- javax.jms.Queue queue = createQueue(address);
- Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
- MessageProducer p = session.createProducer(queue);
- byte[] bytes = new byte[2048];
- new Random().nextBytes(bytes);
- for (int i = 0; i < numMessages; i++) {
- TextMessage message = session.createTextMessage();
- message.setText("msg:" + i);
- p.send(message);
- }
- session.close();
- connection.close();
- Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable();
- Assert.assertEquals(getMessageCount(q), 0);
- }
-
- @Test
- public void testCancelMessages() throws Exception {
- int numMessages = 10;
- long time = System.currentTimeMillis();
- javax.jms.Queue queue = createQueue(address);
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer p = session.createProducer(queue);
- byte[] bytes = new byte[2048];
- new Random().nextBytes(bytes);
- for (int i = 0; i < numMessages; i++) {
- TextMessage message = session.createTextMessage();
- message.setText("msg:" + i);
- p.send(message);
- }
- connection.close();
- Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable();
-
- for (long timeout = System.currentTimeMillis() + 5000; timeout > System.currentTimeMillis() && getMessageCount(q) != numMessages; ) {
- Thread.sleep(1);
- }
-
- Assert.assertEquals(numMessages, getMessageCount(q));
- //now create a new connection and receive
- connection = createConnection();
- session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageConsumer consumer = session.createConsumer(queue);
- Thread.sleep(100);
- consumer.close();
- connection.close();
- Assert.assertEquals(numMessages, getMessageCount(q));
- long taken = (System.currentTimeMillis() - time) / 1000;
- System.out.println("taken = " + taken);
- }
-
- @Test
- public void testClientAckMessages() throws Exception {
- int numMessages = 10;
- long time = System.currentTimeMillis();
- javax.jms.Queue queue = createQueue(address);
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer p = session.createProducer(queue);
- byte[] bytes = new byte[2048];
- new Random().nextBytes(bytes);
- for (int i = 0; i < numMessages; i++) {
- TextMessage message = session.createTextMessage();
- message.setText("msg:" + i);
- p.send(message);
- }
- connection.close();
- Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable();
-
- for (long timeout = System.currentTimeMillis() + 5000; timeout > System.currentTimeMillis() && getMessageCount(q) != numMessages; ) {
- Thread.sleep(1);
- }
- Assert.assertEquals(numMessages, getMessageCount(q));
- //now create a new connection and receive
- connection = createConnection();
- session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
- MessageConsumer consumer = session.createConsumer(queue);
- for (int i = 0; i < numMessages; i++) {
- Message msg = consumer.receive(5000);
- if (msg == null) {
- System.out.println("ProtonTest.testManyMessages");
- }
- Assert.assertNotNull("" + i, msg);
- Assert.assertTrue("" + msg, msg instanceof TextMessage);
- String text = ((TextMessage) msg).getText();
- //System.out.println("text = " + text);
- Assert.assertEquals(text, "msg:" + i);
- msg.acknowledge();
- }
-
- consumer.close();
- connection.close();
-
- // Wait for Acks to be processed and message removed from queue.
- Thread.sleep(500);
-
- Assert.assertEquals(0, getMessageCount(q));
- long taken = (System.currentTimeMillis() - time) / 1000;
- System.out.println("taken = " + taken);
- }
-
- @Test
- public void testMessagesReceivedInParallel() throws Throwable {
- final int numMessages = 50000;
- long time = System.currentTimeMillis();
- final javax.jms.Queue queue = createQueue(address);
-
- final ArrayList<Throwable> exceptions = new ArrayList<>();
-
- Thread t = new Thread(new Runnable() {
- @Override
- public void run() {
- Connection connectionConsumer = null;
- try {
- // TODO the test may starve if using the same connection (dead lock maybe?)
- connectionConsumer = createConnection();
- // connectionConsumer = connection;
- connectionConsumer.start();
- Session sessionConsumer = connectionConsumer.createSession(false, Session.AUTO_ACKNOWLEDGE);
- final MessageConsumer consumer = sessionConsumer.createConsumer(queue);
-
- long n = 0;
- int count = numMessages;
- while (count > 0) {
- try {
- if (++n % 1000 == 0) {
- System.out.println("received " + n + " messages");
- }
-
- Message m = consumer.receive(5000);
- Assert.assertNotNull("Could not receive message count=" + count + " on consumer", m);
- count--;
- }
- catch (JMSException e) {
- e.printStackTrace();
- break;
- }
- }
- }
- catch (Throwable e) {
- exceptions.add(e);
- e.printStackTrace();
- }
- finally {
- try {
- // if the createconnecion wasn't commented out
- if (connectionConsumer != connection) {
- connectionConsumer.close();
- }
- }
- catch (Throwable ignored) {
- // NO OP
- }
- }
- }
- });
-
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- t.start();
-
- MessageProducer p = session.createProducer(queue);
- p.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
- for (int i = 0; i < numMessages; i++) {
- BytesMessage message = session.createBytesMessage();
- message.writeUTF("Hello world!!!!" + i);
- message.setIntProperty("count", i);
- p.send(message);
- }
- t.join();
-
- for (Throwable e : exceptions) {
- throw e;
- }
- Queue q = (Queue) server.getPostOffice().getBinding(new SimpleString(coreAddress)).getBindable();
-
- connection.close();
- Assert.assertEquals(0, getMessageCount(q));
-
- long taken = (System.currentTimeMillis() - time);
- System.out.println("Microbenchamrk ran in " + taken + " milliseconds, sending/receiving " + numMessages);
-
- double messagesPerSecond = ((double) numMessages / (double) taken) * 1000;
-
- System.out.println(((int) messagesPerSecond) + " messages per second");
-
- }
-
- @Test
- public void testSimpleBinary() throws Throwable {
- final int numMessages = 500;
- long time = System.currentTimeMillis();
- final javax.jms.Queue queue = createQueue(address);
-
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- byte[] bytes = new byte[0xf + 1];
- for (int i = 0; i <= 0xf; i++) {
- bytes[i] = (byte) i;
- }
-
- MessageProducer p = session.createProducer(queue);
- for (int i = 0; i < numMessages; i++) {
- System.out.println("Sending " + i);
- BytesMessage message = session.createBytesMessage();
-
- message.writeBytes(bytes);
- message.setIntProperty("count", i);
- p.send(message);
- }
-
- Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- final MessageConsumer consumer = sessionConsumer.createConsumer(queue);
-
- for (int i = 0; i < numMessages; i++) {
- BytesMessage m = (BytesMessage) consumer.receive(5000);
- Assert.assertNotNull("Could not receive message count=" + i + " on consumer", m);
-
- m.reset();
-
- long size = m.getBodyLength();
- byte[] bytesReceived = new byte[(int) size];
- m.readBytes(bytesReceived);
-
- System.out.println("Received " + ByteUtil.bytesToHex(bytesReceived, 1) + " count - " + m.getIntProperty("count"));
-
- Assert.assertArrayEquals(bytes, bytesReceived);
- }
-
- // assertEquals(0, q.getMessageCount());
- long taken = (System.currentTimeMillis() - time) / 1000;
- System.out.println("taken = " + taken);
- }
-
- @Test
- public void testSimpleDefault() throws Throwable {
- final int numMessages = 500;
- long time = System.currentTimeMillis();
- final javax.jms.Queue queue = createQueue(address);
-
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- byte[] bytes = new byte[0xf + 1];
- for (int i = 0; i <= 0xf; i++) {
- bytes[i] = (byte) i;
- }
-
- MessageProducer p = session.createProducer(queue);
- for (int i = 0; i < numMessages; i++) {
- System.out.println("Sending " + i);
- Message message = session.createMessage();
-
- message.setIntProperty("count", i);
- p.send(message);
- }
-
- Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- final MessageConsumer consumer = sessionConsumer.createConsumer(queue);
-
- for (int i = 0; i < numMessages; i++) {
- Message m = consumer.receive(5000);
- Assert.assertNotNull("Could not receive message count=" + i + " on consumer", m);
- }
-
- // assertEquals(0, q.getMessageCount());
- long taken = (System.currentTimeMillis() - time) / 1000;
- System.out.println("taken = " + taken);
- }
-
- @Test
- public void testSimpleMap() throws Throwable {
- final int numMessages = 100;
- long time = System.currentTimeMillis();
- final javax.jms.Queue queue = createQueue(address);
-
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- MessageProducer p = session.createProducer(queue);
- for (int i = 0; i < numMessages; i++) {
- System.out.println("Sending " + i);
- MapMessage message = session.createMapMessage();
-
- message.setInt("i", i);
- message.setIntProperty("count", i);
- p.send(message);
- }
-
- Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- final MessageConsumer consumer = sessionConsumer.createConsumer(queue);
-
- for (int i = 0; i < numMessages; i++) {
- MapMessage m = (MapMessage) consumer.receive(5000);
- Assert.assertNotNull("Could not receive message count=" + i + " on consumer", m);
-
- Assert.assertEquals(i, m.getInt("i"));
- Assert.assertEquals(i, m.getIntProperty("count"));
- }
-
- // assertEquals(0, q.getMessageCount());
- long taken = (System.currentTimeMillis() - time) / 1000;
- System.out.println("taken = " + taken);
- }
-
- @Test
- public void testSimpleStream() throws Throwable {
- final int numMessages = 100;
- final javax.jms.Queue queue = createQueue(address);
-
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- MessageProducer p = session.createProducer(queue);
- for (int i = 0; i < numMessages; i++) {
- StreamMessage message = session.createStreamMessage();
- message.writeInt(i);
- message.writeBoolean(true);
- message.writeString("test");
- p.send(message);
- }
-
- Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- final MessageConsumer consumer = sessionConsumer.createConsumer(queue);
-
- for (int i = 0; i < numMessages; i++) {
- StreamMessage m = (StreamMessage) consumer.receive(5000);
- Assert.assertNotNull("Could not receive message count=" + i + " on consumer", m);
-
- Assert.assertEquals(i, m.readInt());
- Assert.assertEquals(true, m.readBoolean());
- Assert.assertEquals("test", m.readString());
- }
-
- }
-
- @Test
- public void testSimpleText() throws Throwable {
- final int numMessages = 100;
- long time = System.currentTimeMillis();
- final javax.jms.Queue queue = createQueue(address);
-
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- MessageProducer p = session.createProducer(queue);
- for (int i = 0; i < numMessages; i++) {
- System.out.println("Sending " + i);
- TextMessage message = session.createTextMessage("text" + i);
- message.setStringProperty("text", "text" + i);
- p.send(message);
- }
-
- Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- final MessageConsumer consumer = sessionConsumer.createConsumer(queue);
-
- for (int i = 0; i < numMessages; i++) {
- TextMessage m = (TextMessage) consumer.receive(5000);
- Assert.assertNotNull("Could not receive message count=" + i + " on consumer", m);
- Assert.assertEquals("text" + i, m.getText());
- }
-
- // assertEquals(0, q.getMessageCount());
- long taken = (System.currentTimeMillis() - time) / 1000;
- System.out.println("taken = " + taken);
- }
-
- @Test
- public void testSimpleObject() throws Throwable {
- final int numMessages = 1;
- long time = System.currentTimeMillis();
- final javax.jms.Queue queue = createQueue(address);
-
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- MessageProducer p = session.createProducer(queue);
- for (int i = 0; i < numMessages; i++) {
- System.out.println("Sending " + i);
- ObjectMessage message = session.createObjectMessage(new AnythingSerializable(i));
- p.send(message);
- }
-
- Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- final MessageConsumer consumer = sessionConsumer.createConsumer(queue);
-
- for (int i = 0; i < numMessages; i++) {
- ObjectMessage msg = (ObjectMessage) consumer.receive(5000);
- Assert.assertNotNull("Could not receive message count=" + i + " on consumer", msg);
-
- AnythingSerializable someSerialThing = (AnythingSerializable) msg.getObject();
- Assert.assertEquals(i, someSerialThing.getCount());
- }
-
- // assertEquals(0, q.getMessageCount());
- long taken = (System.currentTimeMillis() - time) / 1000;
- System.out.println("taken = " + taken);
- }
-
- @Test
- public void testSelector() throws Exception {
- javax.jms.Queue queue = createQueue(address);
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer p = session.createProducer(queue);
- TextMessage message = session.createTextMessage();
- message.setText("msg:0");
- p.send(message);
- message = session.createTextMessage();
- message.setText("msg:1");
- message.setStringProperty("color", "RED");
- p.send(message);
- connection.start();
- MessageConsumer messageConsumer = session.createConsumer(queue, "color = 'RED'");
- TextMessage m = (TextMessage) messageConsumer.receive(5000);
- Assert.assertNotNull(m);
- Assert.assertEquals("msg:1", m.getText());
- Assert.assertEquals(m.getStringProperty("color"), "RED");
- connection.close();
- }
-
- @Test
- public void testProperties() throws Exception {
- javax.jms.Queue queue = createQueue(address);
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer p = session.createProducer(queue);
- TextMessage message = session.createTextMessage();
- message.setText("msg:0");
- message.setBooleanProperty("true", true);
- message.setBooleanProperty("false", false);
- message.setStringProperty("foo", "bar");
- message.setDoubleProperty("double", 66.6);
- message.setFloatProperty("float", 56.789f);
- message.setIntProperty("int", 8);
- message.setByteProperty("byte", (byte) 10);
- p.send(message);
- p.send(message);
- connection.start();
- MessageConsumer messageConsumer = session.createConsumer(queue);
- TextMessage m = (TextMessage) messageConsumer.receive(5000);
- Assert.assertNotNull(m);
- Assert.assertEquals("msg:0", m.getText());
- Assert.assertEquals(m.getBooleanProperty("true"), true);
- Assert.assertEquals(m.getBooleanProperty("false"), false);
- Assert.assertEquals(m.getStringProperty("foo"), "bar");
- Assert.assertEquals(m.getDoubleProperty("double"), 66.6, 0.0001);
- Assert.assertEquals(m.getFloatProperty("float"), 56.789f, 0.0001);
- Assert.assertEquals(m.getIntProperty("int"), 8);
- Assert.assertEquals(m.getByteProperty("byte"), (byte) 10);
- m = (TextMessage) messageConsumer.receive(5000);
- Assert.assertNotNull(m);
- connection.close();
- }
-
- @Test
- public void testClientID() throws Exception {
- Connection testConn1 = createConnection(false);
- Connection testConn2 = createConnection(false);
- try {
- testConn1.setClientID("client-id1");
- try {
- testConn1.setClientID("client-id2");
- fail("didn't get expected exception");
- }
- catch (javax.jms.IllegalStateException e) {
- //expected
- }
-
- try {
- testConn2.setClientID("client-id1");
- fail("didn't get expected exception");
- }
- catch (InvalidClientIDException e) {
- //expected
- }
- }
- finally {
- testConn1.close();
- testConn2.close();
- }
-
- try {
- testConn1 = createConnection(false);
- testConn2 = createConnection(false);
- testConn1.setClientID("client-id1");
- testConn2.setClientID("client-id2");
- }
- finally {
- testConn1.close();
- testConn2.close();
- }
- }
-
- private javax.jms.Queue createQueue(String address) throws Exception {
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- try {
- return session.createQueue(address);
- }
- finally {
- session.close();
- }
- }
-
- private Connection createConnection() throws JMSException {
- return this.createConnection(true);
- }
-
- private javax.jms.Connection createConnection(boolean isStart) throws JMSException {
- Connection connection;
- if (protocol == 3) {
- factory = new JmsConnectionFactory(amqpConnectionUri);
- connection = factory.createConnection();
- }
- else if (protocol == 0) {
- factory = new JmsConnectionFactory(userName, password, amqpConnectionUri);
- connection = factory.createConnection();
- }
- else {
- TransportConfiguration transport;
-
- if (protocol == 1) {
- transport = new TransportConfiguration(INVM_CONNECTOR_FACTORY);
- factory = new ActiveMQConnectionFactory("vm:/0");
- }
- else {
- factory = new ActiveMQConnectionFactory();
- }
-
- connection = factory.createConnection(userName, password);
- }
- if (isStart) {
- connection.setExceptionListener(new ExceptionListener() {
- @Override
- public void onException(JMSException exception) {
- exception.printStackTrace();
- }
- });
- connection.start();
- }
-
- return connection;
- }
-
- private javax.jms.Connection createConnection(String clientId) throws JMSException {
- Connection connection;
- if (protocol == 3) {
- factory = new JmsConnectionFactory(amqpConnectionUri);
- connection = factory.createConnection();
- connection.setExceptionListener(new ExceptionListener() {
- @Override
- public void onException(JMSException exception) {
- exception.printStackTrace();
- }
- });
- connection.setClientID(clientId);
- connection.start();
- }
- else if (protocol == 0) {
- factory = new JmsConnectionFactory(userName, password, amqpConnectionUri);
- connection = factory.createConnection();
- connection.setExceptionListener(new ExceptionListener() {
- @Override
- public void onException(JMSException exception) {
- exception.printStackTrace();
- }
- });
- connection.setClientID(clientId);
- connection.start();
- }
- else {
- TransportConfiguration transport;
-
- if (protocol == 1) {
- transport = new TransportConfiguration(INVM_CONNECTOR_FACTORY);
- factory = new ActiveMQConnectionFactory("vm:/0");
- }
- else {
- factory = new ActiveMQConnectionFactory();
- }
-
- connection = factory.createConnection(userName, password);
- connection.setClientID(clientId);
- connection.setExceptionListener(new ExceptionListener() {
- @Override
- public void onException(JMSException exception) {
- exception.printStackTrace();
- }
- });
- connection.start();
- }
-
- return connection;
- }
-
-
- private void setAddressFullBlockPolicy() {
- // For BLOCK tests
- AddressSettings addressSettings = server.getAddressSettingsRepository().getMatch("#");
- addressSettings.setAddressFullMessagePolicy(AddressFullMessagePolicy.BLOCK);
- addressSettings.setMaxSizeBytes(maxSizeBytes);
- addressSettings.setMaxSizeBytesRejectThreshold(maxSizeBytesRejectThreshold);
- server.getAddressSettingsRepository().addMatch("#", addressSettings);
- }
-
- public static class AnythingSerializable implements Serializable {
-
- private int count;
-
- public AnythingSerializable(int count) {
- this.count = count;
- }
-
- public int getCount() {
- return count;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonTestBase.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonTestBase.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonTestBase.java
deleted file mode 100644
index cec59da..0000000
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/proton/ProtonTestBase.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.tests.integration.proton;
-
-import org.apache.activemq.artemis.api.core.TransportConfiguration;
-import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
-import org.apache.activemq.artemis.core.server.ActiveMQServer;
-import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy;
-import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
-import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
-import org.junit.After;
-import org.junit.Before;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class ProtonTestBase extends ActiveMQTestBase {
-
- protected String brokerName = "my-broker";
- protected ActiveMQServer server;
-
- protected String tcpAmqpConnectionUri = "tcp://localhost:5672";
- protected String userName = "guest";
- protected String password = "guest";
-
- @Override
- @Before
- public void setUp() throws Exception {
- super.setUp();
-
- server = this.createServer(true, true);
- HashMap<String, Object> params = new HashMap<>();
- params.put(TransportConstants.PORT_PROP_NAME, "5672");
- params.put(TransportConstants.PROTOCOLS_PROP_NAME, "AMQP");
- HashMap<String, Object> amqpParams = new HashMap<>();
- configureAmqp(amqpParams);
- TransportConfiguration transportConfiguration = new TransportConfiguration(NETTY_ACCEPTOR_FACTORY, params, "amqp-acceptor", amqpParams);
-
- server.getConfiguration().getAcceptorConfigurations().add(transportConfiguration);
- server.getConfiguration().setName(brokerName);
-
- // Default Page
- AddressSettings addressSettings = new AddressSettings();
- addressSettings.setAddressFullMessagePolicy(AddressFullMessagePolicy.PAGE);
- server.getConfiguration().getAddressesSettings().put("#", addressSettings);
-
- server.start();
- }
-
- protected void configureAmqp(Map<String, Object> params) {
- }
-
- @Override
- @After
- public void tearDown() throws Exception {
- try {
- server.stop();
- }
- finally {
- super.tearDown();
- }
- }
-}
[05/15] activemq-artemis git commit: ARTEMIS-751 Simplification of
the AMQP implementation
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/logger/ActiveMQAMQPProtocolMessageBundle.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/logger/ActiveMQAMQPProtocolMessageBundle.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/logger/ActiveMQAMQPProtocolMessageBundle.java
deleted file mode 100644
index 576e61a..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/logger/ActiveMQAMQPProtocolMessageBundle.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.logger;
-
-import org.proton.plug.exceptions.ActiveMQAMQPIllegalStateException;
-import org.proton.plug.exceptions.ActiveMQAMQPInternalErrorException;
-import org.proton.plug.exceptions.ActiveMQAMQPInvalidFieldException;
-import org.jboss.logging.annotations.Message;
-import org.jboss.logging.annotations.MessageBundle;
-import org.jboss.logging.Messages;
-import org.proton.plug.exceptions.ActiveMQAMQPNotFoundException;
-
-/**
- * Logger Code 11
- * <p>
- * Each message id must be 6 digits long starting with 10, the 3rd digit should be 9. So the range
- * is from 219000 to 119999.
- * <p>
- * Once released, methods should not be deleted as they may be referenced by knowledge base
- * articles. Unused methods should be marked as deprecated.
- */
-@MessageBundle(projectCode = "AMQ")
-public interface ActiveMQAMQPProtocolMessageBundle {
-
- ActiveMQAMQPProtocolMessageBundle BUNDLE = Messages.getBundle(ActiveMQAMQPProtocolMessageBundle.class);
-
- @Message(id = 219000, value = "target address not set")
- ActiveMQAMQPInvalidFieldException targetAddressNotSet();
-
- @Message(id = 219001, value = "error creating temporary queue, {0}", format = Message.Format.MESSAGE_FORMAT)
- ActiveMQAMQPInternalErrorException errorCreatingTemporaryQueue(String message);
-
- @Message(id = 219002, value = "target address does not exist")
- ActiveMQAMQPNotFoundException addressDoesntExist();
-
- @Message(id = 219003, value = "error finding temporary queue, {0}", format = Message.Format.MESSAGE_FORMAT)
- ActiveMQAMQPNotFoundException errorFindingTemporaryQueue(String message);
-
- @Message(id = 219005, value = "error creating consumer, {0}", format = Message.Format.MESSAGE_FORMAT)
- ActiveMQAMQPInternalErrorException errorCreatingConsumer(String message);
-
- @Message(id = 219006, value = "error starting consumer, {0}", format = Message.Format.MESSAGE_FORMAT)
- ActiveMQAMQPIllegalStateException errorStartingConsumer(String message);
-
- @Message(id = 219007, value = "error acknowledging message {0}, {1}", format = Message.Format.MESSAGE_FORMAT)
- ActiveMQAMQPIllegalStateException errorAcknowledgingMessage(String messageID, String message);
-
- @Message(id = 219008, value = "error cancelling message {0}, {1}", format = Message.Format.MESSAGE_FORMAT)
- ActiveMQAMQPIllegalStateException errorCancellingMessage(String messageID, String message);
-
- @Message(id = 219010, value = "source address does not exist")
- ActiveMQAMQPNotFoundException sourceAddressDoesntExist();
-
- @Message(id = 219011, value = "source address not set")
- ActiveMQAMQPInvalidFieldException sourceAddressNotSet();
-
- @Message(id = 219012, value = "error rolling back coordinator: {0}", format = Message.Format.MESSAGE_FORMAT)
- ActiveMQAMQPIllegalStateException errorRollingbackCoordinator(String message);
-
- @Message(id = 219013, value = "error committing coordinator: {0}", format = Message.Format.MESSAGE_FORMAT)
- ActiveMQAMQPIllegalStateException errorCommittingCoordinator(String message);
-
- @Message(id = 219014, value = "Transaction not found: xid={0}", format = Message.Format.MESSAGE_FORMAT)
- ActiveMQAMQPIllegalStateException txNotFound(String xidToString);
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/sasl/AnonymousServerSASL.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/sasl/AnonymousServerSASL.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/sasl/AnonymousServerSASL.java
deleted file mode 100644
index d52df40..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/sasl/AnonymousServerSASL.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.sasl;
-
-import org.proton.plug.SASLResult;
-import org.proton.plug.ServerSASL;
-
-public class AnonymousServerSASL implements ServerSASL {
-
- public AnonymousServerSASL() {
- }
-
- @Override
- public String getName() {
- return "ANONYMOUS";
- }
-
- @Override
- public SASLResult processSASL(byte[] bytes) {
- return new PlainSASLResult(true, null, null);
- }
-}
-
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/sasl/ClientSASLPlain.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/sasl/ClientSASLPlain.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/sasl/ClientSASLPlain.java
deleted file mode 100644
index 59685ad..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/sasl/ClientSASLPlain.java
+++ /dev/null
@@ -1,59 +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.proton.plug.sasl;
-
-import org.proton.plug.ClientSASL;
-
-/**
- * This is a simple implementation provided with just user/password
- * TODO: this interface will probaby change as we are challenged with more SASL cases where there is a communication between client and server to determine the authentication
- */
-public class ClientSASLPlain implements ClientSASL {
-
- private String username;
- private String password;
-
- public ClientSASLPlain(String user, String password) {
- this.username = user;
- this.password = password;
- }
-
- @Override
- public String getName() {
- return "PLAIN";
- }
-
- @Override
- public byte[] getBytes() {
-
- if (username == null) {
- username = "";
- }
-
- if (password == null) {
- password = "";
- }
-
- byte[] usernameBytes = username.getBytes();
- byte[] passwordBytes = password.getBytes();
- byte[] data = new byte[usernameBytes.length + passwordBytes.length + 2];
- System.arraycopy(usernameBytes, 0, data, 1, usernameBytes.length);
- System.arraycopy(passwordBytes, 0, data, 2 + usernameBytes.length, passwordBytes.length);
- return data;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/sasl/PlainSASLResult.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/sasl/PlainSASLResult.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/sasl/PlainSASLResult.java
deleted file mode 100644
index fe33886..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/sasl/PlainSASLResult.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.sasl;
-
-import org.proton.plug.SASLResult;
-
-public class PlainSASLResult implements SASLResult {
-
- private boolean success;
- private String user;
- private String password;
-
- public PlainSASLResult(boolean success, String user, String password) {
- this.success = success;
- this.user = user;
- this.password = password;
- }
-
- @Override
- public String getUser() {
- return user;
- }
-
- public String getPassword() {
- return password;
- }
-
- @Override
- public boolean isSuccess() {
- return success;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/sasl/ServerSASLPlain.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/sasl/ServerSASLPlain.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/sasl/ServerSASLPlain.java
deleted file mode 100644
index 37c8dd3..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/sasl/ServerSASLPlain.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.sasl;
-
-import org.proton.plug.SASLResult;
-import org.proton.plug.ServerSASL;
-
-public class ServerSASLPlain implements ServerSASL {
-
- public static final String NAME = "PLAIN";
-
- @Override
- public String getName() {
- return NAME;
- }
-
- @Override
- public SASLResult processSASL(byte[] data) {
-
- String username = null;
- String password = null;
- String bytes = new String(data);
- String[] credentials = bytes.split(Character.toString((char) 0));
- int offSet = 0;
- if (credentials.length > 0) {
- if (credentials[0].length() == 0) {
- offSet = 1;
- }
-
- if (credentials.length >= offSet) {
- username = credentials[offSet];
- }
- if (credentials.length >= (offSet + 1)) {
- password = credentials[offSet + 1];
- }
- }
-
- boolean success = authenticate(username, password);
-
- return new PlainSASLResult(success, username, password);
- }
-
- /**
- * Hook for subclasses to perform the authentication here
- *
- * @param user
- * @param password
- */
- protected boolean authenticate(String user, String password) {
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/ByteUtil.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/ByteUtil.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/ByteUtil.java
deleted file mode 100644
index e1e6944..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/ByteUtil.java
+++ /dev/null
@@ -1,130 +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.proton.plug.util;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.UnpooledByteBufAllocator;
-import org.jboss.logging.Logger;
-
-public class ByteUtil {
-
- public static void debugFrame(Logger logger, String message, ByteBuf byteIn) {
- if (logger.isTraceEnabled()) {
- int location = byteIn.readerIndex();
- // debugging
- byte[] frame = new byte[byteIn.writerIndex()];
- byteIn.readBytes(frame);
-
- try {
- logger.trace(message + "\n" + ByteUtil.formatGroup(ByteUtil.bytesToHex(frame), 8, 16));
- }
- catch (Exception e) {
- logger.warn(e.getMessage(), e);
- }
-
- byteIn.readerIndex(location);
- }
- }
-
- public static String formatGroup(String str, int groupSize, int lineBreak) {
- StringBuffer buffer = new StringBuffer();
-
- int line = 1;
- buffer.append("/* 1 */ \"");
- for (int i = 0; i < str.length(); i += groupSize) {
- buffer.append(str.substring(i, i + Math.min(str.length() - i, groupSize)));
-
- if ((i + groupSize) % lineBreak == 0) {
- buffer.append("\" +\n/* ");
- line++;
- if (line < 10) {
- buffer.append(" ");
- }
- buffer.append(Integer.toString(line) + " */ \"");
- }
- else if ((i + groupSize) % groupSize == 0 && str.length() - i > groupSize) {
- buffer.append("\" + \"");
- }
- }
-
- buffer.append("\";");
-
- return buffer.toString();
-
- }
-
- protected static final char[] hexArray = "0123456789ABCDEF".toCharArray();
-
- public static String bytesToHex(byte[] bytes) {
- char[] hexChars = new char[bytes.length * 2];
- for (int j = 0; j < bytes.length; j++) {
- int v = bytes[j] & 0xFF;
- hexChars[j * 2] = hexArray[v >>> 4];
- hexChars[j * 2 + 1] = hexArray[v & 0x0F];
- }
- return new String(hexChars);
- }
-
- public static byte[] hexStringToByteArray(String s) {
- int len = s.length();
- byte[] data = new byte[len / 2];
- for (int i = 0; i < len; i += 2) {
- data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
- }
- return data;
- }
-
- public static byte[] longToBytes(long x) {
- ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.heapBuffer(8, 8);
- buffer.writeLong(x);
- return buffer.array();
- }
-
- public static String maxString(String value, int size) {
- if (value.length() < size) {
- return value;
- }
- else {
- return value.substring(0, size / 2) + " ... " + value.substring(value.length() - size / 2);
- }
- }
-
- public static String bytesToHex(byte[] bytes, int groupSize) {
- char[] hexChars = new char[bytes.length * 2 + numberOfGroups(bytes, groupSize)];
- int outPos = 0;
- for (int j = 0; j < bytes.length; j++) {
- if (j > 0 && j % groupSize == 0) {
- hexChars[outPos++] = ' ';
- }
- int v = bytes[j] & 0xFF;
- hexChars[outPos++] = hexArray[v >>> 4];
- hexChars[outPos++] = hexArray[v & 0x0F];
- }
- return new String(hexChars);
- }
-
- private static int numberOfGroups(byte[] bytes, int groupSize) {
- int groups = bytes.length / groupSize;
-
- if (bytes.length % groupSize == 0) {
- groups--;
- }
-
- return groups;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/CodecCache.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/CodecCache.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/CodecCache.java
deleted file mode 100644
index 014efb0..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/CodecCache.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.util;
-
-import org.apache.qpid.proton.codec.AMQPDefinedTypes;
-import org.apache.qpid.proton.codec.DecoderImpl;
-import org.apache.qpid.proton.codec.EncoderImpl;
-
-public class CodecCache {
-
- private static class EncoderDecoderPair {
-
- DecoderImpl decoder = new DecoderImpl();
- EncoderImpl encoder = new EncoderImpl(decoder);
-
- {
- AMQPDefinedTypes.registerAllTypes(decoder, encoder);
- }
- }
-
- private static final ThreadLocal<EncoderDecoderPair> tlsCodec = new ThreadLocal<EncoderDecoderPair>() {
- @Override
- protected EncoderDecoderPair initialValue() {
- return new EncoderDecoderPair();
- }
- };
-
- public static DecoderImpl getDecoder() {
- return tlsCodec.get().decoder;
- }
-
- public static EncoderImpl getEncoder() {
- return tlsCodec.get().encoder;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/CreditsSemaphore.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/CreditsSemaphore.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/CreditsSemaphore.java
deleted file mode 100644
index a175805..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/CreditsSemaphore.java
+++ /dev/null
@@ -1,110 +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.proton.plug.util;
-
-import java.util.concurrent.locks.AbstractQueuedSynchronizer;
-
-public class CreditsSemaphore {
-
- @SuppressWarnings("serial")
- private static class Sync extends AbstractQueuedSynchronizer {
-
- private Sync(int initial) {
- setState(initial);
- }
-
- public int getCredits() {
- return getState();
- }
-
- @Override
- public int tryAcquireShared(final int numberOfAqcquires) {
- for (;;) {
- int actualSize = getState();
- int newValue = actualSize - numberOfAqcquires;
-
- if (newValue < 0) {
- if (actualSize == getState()) {
- return -1;
- }
- }
- else if (compareAndSetState(actualSize, newValue)) {
- return newValue;
- }
- }
- }
-
- @Override
- public boolean tryReleaseShared(final int numberOfReleases) {
- for (;;) {
- int actualSize = getState();
- int newValue = actualSize + numberOfReleases;
-
- if (compareAndSetState(actualSize, newValue)) {
- return true;
- }
-
- }
- }
-
- public void setCredits(final int credits) {
- for (;;) {
- int actualState = getState();
- if (compareAndSetState(actualState, credits)) {
- // This is to wake up any pending threads that could be waiting on queued
- releaseShared(0);
- return;
- }
- }
- }
- }
-
- private final Sync sync;
-
- public CreditsSemaphore(int initialCredits) {
- sync = new Sync(initialCredits);
- }
-
- public void acquire() throws InterruptedException {
- sync.acquireSharedInterruptibly(1);
- }
-
- public boolean tryAcquire() {
- return sync.tryAcquireShared(1) >= 0;
- }
-
- public void release() throws InterruptedException {
- sync.releaseShared(1);
- }
-
- public void release(int credits) throws InterruptedException {
- sync.releaseShared(credits);
- }
-
- public void setCredits(int credits) {
- sync.setCredits(credits);
- }
-
- public int getCredits() {
- return sync.getCredits();
- }
-
- public boolean hasQueuedThreads() {
- return sync.hasQueuedThreads();
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/DeliveryUtil.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/DeliveryUtil.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/DeliveryUtil.java
deleted file mode 100644
index ae98891..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/DeliveryUtil.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.util;
-
-import io.netty.buffer.ByteBuf;
-import org.apache.qpid.proton.engine.Receiver;
-import org.apache.qpid.proton.message.Message;
-import org.apache.qpid.proton.message.impl.MessageImpl;
-
-public class DeliveryUtil {
-
- public static int readDelivery(Receiver receiver, ByteBuf buffer) {
- int initial = buffer.writerIndex();
- // optimization by norman
- int count;
- while ((count = receiver.recv(buffer.array(), buffer.arrayOffset() + buffer.writerIndex(), buffer.writableBytes())) > 0) {
- // Increment the writer index by the number of bytes written into it while calling recv.
- buffer.writerIndex(buffer.writerIndex() + count);
- buffer.ensureWritable(count);
- }
- return buffer.writerIndex() - initial;
- }
-
- public static MessageImpl decodeMessageImpl(ByteBuf buffer) {
- MessageImpl message = (MessageImpl) Message.Factory.create();
- message.decode(buffer.array(), buffer.arrayOffset() + buffer.readerIndex(), buffer.readableBytes());
- return message;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/FutureRunnable.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/FutureRunnable.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/FutureRunnable.java
deleted file mode 100644
index 20095ff..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/FutureRunnable.java
+++ /dev/null
@@ -1,61 +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.proton.plug.util;
-
-import java.util.concurrent.TimeUnit;
-
-public class FutureRunnable implements Runnable {
-
- private final ReusableLatch latch;
-
- public FutureRunnable(final int initialIterations) {
- latch = new ReusableLatch(initialIterations);
- }
-
- public FutureRunnable() {
- this(0);
- }
-
- @Override
- public void run() {
- latch.countDown();
- }
-
- public void countUp() {
- latch.countUp();
- }
-
- public void countDown() {
- latch.countDown();
- }
-
- public int getCount() {
- return latch.getCount();
- }
-
- public void await() throws InterruptedException {
- latch.await();
- }
-
- public boolean await(long timeWait, TimeUnit timeUnit) throws InterruptedException {
- return latch.await(timeWait, timeUnit);
- }
-
- public boolean await(long milliseconds) throws InterruptedException {
- return latch.await(milliseconds);
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/NettyWritable.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/NettyWritable.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/NettyWritable.java
deleted file mode 100644
index 98afd30..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/NettyWritable.java
+++ /dev/null
@@ -1,100 +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.proton.plug.util;
-
-import java.nio.ByteBuffer;
-
-import io.netty.buffer.ByteBuf;
-import org.apache.qpid.proton.codec.WritableBuffer;
-
-/**
- * This is to use NettyBuffer within Proton
- */
-
-public class NettyWritable implements WritableBuffer {
-
- final ByteBuf nettyBuffer;
-
- public NettyWritable(ByteBuf nettyBuffer) {
- this.nettyBuffer = nettyBuffer;
- }
-
- @Override
- public void put(byte b) {
- nettyBuffer.writeByte(b);
- }
-
- @Override
- public void putFloat(float f) {
- nettyBuffer.writeFloat(f);
- }
-
- @Override
- public void putDouble(double d) {
- nettyBuffer.writeDouble(d);
- }
-
- @Override
- public void put(byte[] src, int offset, int length) {
- nettyBuffer.writeBytes(src, offset, length);
- }
-
- @Override
- public void putShort(short s) {
- nettyBuffer.writeShort(s);
- }
-
- @Override
- public void putInt(int i) {
- nettyBuffer.writeInt(i);
- }
-
- @Override
- public void putLong(long l) {
- nettyBuffer.writeLong(l);
- }
-
- @Override
- public boolean hasRemaining() {
- return nettyBuffer.writerIndex() < nettyBuffer.capacity();
- }
-
- @Override
- public int remaining() {
- return nettyBuffer.capacity() - nettyBuffer.writerIndex();
- }
-
- @Override
- public int position() {
- return nettyBuffer.writerIndex();
- }
-
- @Override
- public void position(int position) {
- nettyBuffer.writerIndex(position);
- }
-
- @Override
- public void put(ByteBuffer payload) {
- nettyBuffer.writeBytes(payload);
- }
-
- @Override
- public int limit() {
- return nettyBuffer.capacity();
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/ProtonServerMessage.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/ProtonServerMessage.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/ProtonServerMessage.java
deleted file mode 100644
index c3fab5d..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/ProtonServerMessage.java
+++ /dev/null
@@ -1,470 +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.proton.plug.util;
-
-import java.nio.ByteBuffer;
-
-import org.apache.qpid.proton.amqp.messaging.ApplicationProperties;
-import org.apache.qpid.proton.amqp.messaging.DeliveryAnnotations;
-import org.apache.qpid.proton.amqp.messaging.Footer;
-import org.apache.qpid.proton.amqp.messaging.Header;
-import org.apache.qpid.proton.amqp.messaging.MessageAnnotations;
-import org.apache.qpid.proton.amqp.messaging.Properties;
-import org.apache.qpid.proton.amqp.messaging.Section;
-import org.apache.qpid.proton.codec.DecoderImpl;
-import org.apache.qpid.proton.codec.EncoderImpl;
-import org.apache.qpid.proton.codec.WritableBuffer;
-import org.apache.qpid.proton.message.MessageError;
-import org.apache.qpid.proton.message.ProtonJMessage;
-
-/**
- * This is a serverMessage that won't deal with the body
- */
-public class ProtonServerMessage implements ProtonJMessage {
-
- private Header header;
- private DeliveryAnnotations deliveryAnnotations;
- private MessageAnnotations messageAnnotations;
- private Properties properties;
- private ApplicationProperties applicationProperties;
-
- // This should include a raw body of both footer and body
- private byte[] rawBody;
-
- private Section parsedBody;
- private Footer parsedFooter;
-
- private final int EOF = 0;
-
- // TODO: Enumerations maybe?
- private static final int HEADER_TYPE = 0x070;
- private static final int DELIVERY_ANNOTATIONS = 0x071;
- private static final int MESSAGE_ANNOTATIONS = 0x072;
- private static final int PROPERTIES = 0x073;
- private static final int APPLICATION_PROPERTIES = 0x074;
-
- /**
- * This will decode a ByteBuffer tha represents the entire message.
- * Set the limits around the parameter.
- *
- * @param buffer a limited buffer for the message
- */
- public void decode(ByteBuffer buffer) {
-
- DecoderImpl decoder = CodecCache.getDecoder();
-
- header = null;
- deliveryAnnotations = null;
- messageAnnotations = null;
- properties = null;
- applicationProperties = null;
- rawBody = null;
-
- decoder.setByteBuffer(buffer);
- try {
- int type = readType(buffer, decoder);
- if (type == HEADER_TYPE) {
- header = (Header) readSection(buffer, decoder);
- type = readType(buffer, decoder);
-
- }
-
- if (type == DELIVERY_ANNOTATIONS) {
- deliveryAnnotations = (DeliveryAnnotations) readSection(buffer, decoder);
- type = readType(buffer, decoder);
-
- }
-
- if (type == MESSAGE_ANNOTATIONS) {
- messageAnnotations = (MessageAnnotations) readSection(buffer, decoder);
- type = readType(buffer, decoder);
- }
-
- if (type == PROPERTIES) {
- properties = (Properties) readSection(buffer, decoder);
- type = readType(buffer, decoder);
-
- }
-
- if (type == APPLICATION_PROPERTIES) {
- applicationProperties = (ApplicationProperties) readSection(buffer, decoder);
- type = readType(buffer, decoder);
- }
-
- if (type != EOF) {
- rawBody = new byte[buffer.limit() - buffer.position()];
- buffer.get(rawBody);
- }
- }
- finally {
- decoder.setByteBuffer(null);
- }
-
- }
-
- public void encode(ByteBuffer buffer) {
- WritableBuffer writableBuffer = new WritableBuffer.ByteBufferWrapper(buffer);
- encode(writableBuffer);
- }
-
- @Override
- public int encode(WritableBuffer writableBuffer) {
- final int firstPosition = writableBuffer.position();
-
- EncoderImpl encoder = CodecCache.getEncoder();
- encoder.setByteBuffer(writableBuffer);
-
- try {
- if (header != null) {
- encoder.writeObject(header);
- }
- if (deliveryAnnotations != null) {
- encoder.writeObject(deliveryAnnotations);
- }
- if (messageAnnotations != null) {
- encoder.writeObject(messageAnnotations);
- }
- if (properties != null) {
- encoder.writeObject(properties);
- }
- if (applicationProperties != null) {
- encoder.writeObject(applicationProperties);
- }
-
- // It should write either the parsed one or the rawBody
- if (parsedBody != null) {
- encoder.writeObject(parsedBody);
- if (parsedFooter != null) {
- encoder.writeObject(parsedFooter);
- }
- }
- else if (rawBody != null) {
- writableBuffer.put(rawBody, 0, rawBody.length);
- }
-
- return writableBuffer.position() - firstPosition;
- }
- finally {
- encoder.setByteBuffer((WritableBuffer) null);
- }
- }
-
- private int readType(ByteBuffer buffer, DecoderImpl decoder) {
-
- int pos = buffer.position();
-
- if (!buffer.hasRemaining()) {
- return EOF;
- }
- try {
- if (buffer.get() != 0) {
- return EOF;
- }
- else {
- return ((Number) decoder.readObject()).intValue();
- }
- }
- finally {
- buffer.position(pos);
- }
- }
-
- private Section readSection(ByteBuffer buffer, DecoderImpl decoder) {
- if (buffer.hasRemaining()) {
- return (Section) decoder.readObject();
- }
- else {
- return null;
- }
- }
-
- // At the moment we only need encode implemented!!!
- @Override
- public boolean isDurable() {
- return false;
- }
-
- @Override
- public long getDeliveryCount() {
- return 0;
- }
-
- @Override
- public short getPriority() {
- return 0;
- }
-
- @Override
- public boolean isFirstAcquirer() {
- return false;
- }
-
- @Override
- public long getTtl() {
- return 0;
- }
-
- @Override
- public void setDurable(boolean durable) {
-
- }
-
- @Override
- public void setTtl(long ttl) {
-
- }
-
- @Override
- public void setDeliveryCount(long deliveryCount) {
-
- }
-
- @Override
- public void setFirstAcquirer(boolean firstAcquirer) {
-
- }
-
- @Override
- public void setPriority(short priority) {
-
- }
-
- @Override
- public Object getMessageId() {
- return null;
- }
-
- @Override
- public long getGroupSequence() {
- return 0;
- }
-
- @Override
- public String getReplyToGroupId() {
- return null;
- }
-
- @Override
- public long getCreationTime() {
- return 0;
- }
-
- @Override
- public String getAddress() {
- return null;
- }
-
- @Override
- public byte[] getUserId() {
- return new byte[0];
- }
-
- @Override
- public String getReplyTo() {
- return null;
- }
-
- @Override
- public String getGroupId() {
- return null;
- }
-
- @Override
- public String getContentType() {
- return null;
- }
-
- @Override
- public long getExpiryTime() {
- return 0;
- }
-
- @Override
- public Object getCorrelationId() {
- return null;
- }
-
- @Override
- public String getContentEncoding() {
- return null;
- }
-
- @Override
- public String getSubject() {
- return null;
- }
-
- @Override
- public void setGroupSequence(long groupSequence) {
-
- }
-
- @Override
- public void setUserId(byte[] userId) {
-
- }
-
- @Override
- public void setCreationTime(long creationTime) {
-
- }
-
- @Override
- public void setSubject(String subject) {
-
- }
-
- @Override
- public void setGroupId(String groupId) {
-
- }
-
- @Override
- public void setAddress(String to) {
-
- }
-
- @Override
- public void setExpiryTime(long absoluteExpiryTime) {
-
- }
-
- @Override
- public void setReplyToGroupId(String replyToGroupId) {
-
- }
-
- @Override
- public void setContentEncoding(String contentEncoding) {
-
- }
-
- @Override
- public void setContentType(String contentType) {
-
- }
-
- @Override
- public void setReplyTo(String replyTo) {
-
- }
-
- @Override
- public void setCorrelationId(Object correlationId) {
-
- }
-
- @Override
- public void setMessageId(Object messageId) {
-
- }
-
- @Override
- public Header getHeader() {
- return null;
- }
-
- @Override
- public DeliveryAnnotations getDeliveryAnnotations() {
- return null;
- }
-
- @Override
- public MessageAnnotations getMessageAnnotations() {
- return null;
- }
-
- @Override
- public Properties getProperties() {
- return null;
- }
-
- @Override
- public ApplicationProperties getApplicationProperties() {
- return null;
- }
-
- @Override
- public Section getBody() {
- return null;
- }
-
- @Override
- public Footer getFooter() {
- return null;
- }
-
- @Override
- public void setHeader(Header header) {
-
- }
-
- @Override
- public void setDeliveryAnnotations(DeliveryAnnotations deliveryAnnotations) {
-
- }
-
- @Override
- public void setMessageAnnotations(MessageAnnotations messageAnnotations) {
-
- }
-
- @Override
- public void setProperties(Properties properties) {
-
- }
-
- @Override
- public void setApplicationProperties(ApplicationProperties applicationProperties) {
-
- }
-
- @Override
- public void setBody(Section body) {
-
- }
-
- @Override
- public void setFooter(Footer footer) {
-
- }
-
- @Override
- public int decode(byte[] data, int offset, int length) {
- return 0;
- }
-
- @Override
- public int encode(byte[] data, int offset, int length) {
- return 0;
- }
-
- @Override
- public void clear() {
-
- }
-
- @Override
- public MessageError getError() {
- return null;
- }
-
- @Override
- public int encode2(byte[] data, int offset, int length) {
- return 0;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/ReusableLatch.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/ReusableLatch.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/ReusableLatch.java
deleted file mode 100644
index beccc03..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/util/ReusableLatch.java
+++ /dev/null
@@ -1,130 +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.proton.plug.util;
-
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.AbstractQueuedSynchronizer;
-
-/**
- * <p>This class will use the framework provided to by AbstractQueuedSynchronizer.</p>
- * <p>AbstractQueuedSynchronizer is the framework for any sort of concurrent synchronization, such as Semaphores, events, etc, based on AtomicIntegers.</p>
- * <p>This class works just like CountDownLatch, with the difference you can also increase the counter</p>
- * <p>It could be used for sync points when one process is feeding the latch while another will wait when everything is done. (e.g. waiting IO completions to finish)</p>
- * <p>On ActiveMQ Artemis we have the requirement of increment and decrement a counter until the user fires a ready handler (commit). At that point we just act as a regular countDown.</p>
- * <p>Note: This latch is reusable. Once it reaches zero, you can call up again, and reuse it on further waits.</p>
- * <p>For example: prepareTransaction will wait for the current completions, and further adds will be called on the latch. Later on when commit is called you can reuse the same latch.</p>
- */
-public class ReusableLatch {
-
- /**
- * Look at the doc and examples provided by AbstractQueuedSynchronizer for more information
- *
- * @see AbstractQueuedSynchronizer
- */
- @SuppressWarnings("serial")
- private static class CountSync extends AbstractQueuedSynchronizer {
-
- private CountSync(int count) {
- setState(count);
- }
-
- public int getCount() {
- return getState();
- }
-
- public void setCount(final int count) {
- setState(count);
- }
-
- @Override
- public int tryAcquireShared(final int numberOfAqcquires) {
- return getState() == 0 ? 1 : -1;
- }
-
- public void add() {
- for (;;) {
- int actualState = getState();
- int newState = actualState + 1;
- if (compareAndSetState(actualState, newState)) {
- return;
- }
- }
- }
-
- @Override
- public boolean tryReleaseShared(final int numberOfReleases) {
- for (;;) {
- int actualState = getState();
- if (actualState == 0) {
- return true;
- }
-
- int newState = actualState - numberOfReleases;
-
- if (newState < 0) {
- newState = 0;
- }
-
- if (compareAndSetState(actualState, newState)) {
- return newState == 0;
- }
- }
- }
- }
-
- private final CountSync control;
-
- public ReusableLatch() {
- this(0);
- }
-
- public ReusableLatch(final int count) {
- control = new CountSync(count);
- }
-
- public int getCount() {
- return control.getCount();
- }
-
- public void setCount(final int count) {
- control.setCount(count);
- }
-
- public void countUp() {
- control.add();
- }
-
- public void countDown() {
- control.releaseShared(1);
- }
-
- public void countDown(final int count) {
- control.releaseShared(count);
- }
-
- public void await() throws InterruptedException {
- control.acquireSharedInterruptibly(1);
- }
-
- public boolean await(final long milliseconds) throws InterruptedException {
- return control.tryAcquireSharedNanos(1, TimeUnit.MILLISECONDS.toNanos(milliseconds));
- }
-
- public boolean await(final long timeWait, TimeUnit timeUnit) throws InterruptedException {
- return control.tryAcquireSharedNanos(1, timeUnit.toNanos(timeWait));
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/context/AbstractConnectionContextTest.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/context/AbstractConnectionContextTest.java b/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/context/AbstractConnectionContextTest.java
deleted file mode 100644
index 825b987..0000000
--- a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/context/AbstractConnectionContextTest.java
+++ /dev/null
@@ -1,137 +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.proton.plug.context;
-
-import java.util.concurrent.Executors;
-
-import io.netty.buffer.ByteBuf;
-
-import org.apache.activemq.artemis.core.transaction.Transaction;
-import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
-import org.apache.qpid.proton.amqp.Binary;
-import org.apache.qpid.proton.engine.Connection;
-import org.apache.qpid.proton.engine.Link;
-import org.apache.qpid.proton.engine.Session;
-import org.junit.Test;
-import org.proton.plug.AMQPConnectionCallback;
-import org.proton.plug.AMQPConnectionContext;
-import org.proton.plug.AMQPSessionCallback;
-import org.proton.plug.SASLResult;
-import org.proton.plug.ServerSASL;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-import org.proton.plug.handler.EventHandler;
-
-public class AbstractConnectionContextTest {
-
- @Test
- public void testListenerDoesntThrowNPEWhenClosingLinkWithNullContext() throws Exception {
- TestConnectionContext connectionContext = new TestConnectionContext(new TestConnectionCallback());
- EventHandler listener = connectionContext.getListener();
-
- Connection protonConnection = Connection.Factory.create();
- Session protonSession = protonConnection.session();
- Link link = protonSession.receiver("link");
-
- link.setContext(null);
-
- listener.onRemoteClose(link);
- }
-
- private class TestConnectionContext extends AbstractConnectionContext {
-
- private TestConnectionContext(AMQPConnectionCallback connectionCallback) {
- super(connectionCallback, Executors.newSingleThreadExecutor(ActiveMQThreadFactory.defaultThreadFactory()), null);
- }
-
- @Override
- protected void remoteLinkOpened(Link link) throws Exception {
-
- }
-
- @Override
- protected AbstractProtonSessionContext newSessionExtension(Session realSession) throws ActiveMQAMQPException {
- return null;
- }
-
- public EventHandler getListener() {
- return listener;
- }
- }
-
- private class TestConnectionCallback implements AMQPConnectionCallback {
-
- @Override
- public void close() {
-
- }
-
- @Override
- public Binary newTransaction() {
- return null;
- }
-
- @Override
- public Transaction getTransaction(Binary txid) throws ActiveMQAMQPException {
- return null;
- }
-
- @Override
- public void removeTransaction(Binary txid) {
-
- }
-
- @Override
- public void onTransport(ByteBuf bytes, AMQPConnectionContext connection) {
-
- }
-
- @Override
- public AMQPSessionCallback createSessionCallback(AMQPConnectionContext connection) {
- return null;
- }
-
- @Override
- public void setConnection(AMQPConnectionContext connection) {
-
- }
-
- @Override
- public AMQPConnectionContext getConnection() {
- return null;
- }
-
- @Override
- public ServerSASL[] getSASLMechnisms() {
- return null;
- }
-
- @Override
- public boolean isSupportsAnonymous() {
- return true;
- }
-
- @Override
- public void sendSASLSupported() {
-
- }
-
- @Override
- public boolean validateConnection(Connection connection, SASLResult saslResult) {
- return true;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/AbstractJMSTest.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/AbstractJMSTest.java b/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/AbstractJMSTest.java
deleted file mode 100644
index 0046dd6..0000000
--- a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/AbstractJMSTest.java
+++ /dev/null
@@ -1,93 +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.proton.plug.test;
-
-import javax.jms.Connection;
-import javax.jms.ConnectionFactory;
-import javax.jms.ExceptionListener;
-import javax.jms.JMSException;
-import javax.jms.Queue;
-import javax.jms.Session;
-
-import java.lang.ref.WeakReference;
-
-import org.apache.qpid.jms.JmsConnectionFactory;
-import org.jboss.logging.Logger;
-import org.proton.plug.test.minimalserver.DumbServer;
-import org.proton.plug.test.minimalserver.MinimalServer;
-
-public class AbstractJMSTest {
-
- private static final Logger log = Logger.getLogger(AbstractJMSTest.class);
-
- protected final boolean useSASL;
-
- protected String address = "exampleQueue";
- protected MinimalServer server = new MinimalServer();
-
- public AbstractJMSTest(boolean useSASL) {
- this.useSASL = useSASL;
- }
-
- public void tearDown() throws Exception {
- server.stop();
- DumbServer.clear();
- }
-
- public static void forceGC() {
- System.out.println("#test forceGC");
- WeakReference<Object> dumbReference = new WeakReference<>(new Object());
- // A loop that will wait GC, using the minimalserver time as possible
- while (dumbReference.get() != null) {
- System.gc();
- try {
- Thread.sleep(100);
- }
- catch (InterruptedException e) {
- }
- }
- System.out.println("#test forceGC Done");
- }
-
- protected Connection createConnection() throws JMSException {
- final ConnectionFactory factory = createConnectionFactory();
- final Connection connection = factory.createConnection();
- connection.setExceptionListener(new ExceptionListener() {
- @Override
- public void onException(JMSException exception) {
- log.warn(exception.getMessage(), exception);
- }
- });
- connection.start();
- return connection;
- }
-
- protected ConnectionFactory createConnectionFactory() {
- if (useSASL) {
- return new JmsConnectionFactory("aaaaaaaa", "aaaaaaa", "amqp://localhost:5672");
- }
- else {
- return new JmsConnectionFactory( "amqp://localhost:5672");
-
- }
- }
-
- protected Queue createQueue(Session session) throws Exception {
- return session.createQueue(address);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/Constants.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/Constants.java b/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/Constants.java
deleted file mode 100644
index bacfd7b..0000000
--- a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/Constants.java
+++ /dev/null
@@ -1,22 +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.proton.plug.test;
-
-public class Constants {
-
- public static final int PORT = 5672;
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/ProtonTest.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/ProtonTest.java b/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/ProtonTest.java
deleted file mode 100644
index 4c3aaf4..0000000
--- a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/ProtonTest.java
+++ /dev/null
@@ -1,335 +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.proton.plug.test;
-
-import javax.jms.BytesMessage;
-import javax.jms.Connection;
-import javax.jms.DeliveryMode;
-import javax.jms.JMSException;
-import javax.jms.MapMessage;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageProducer;
-import javax.jms.Queue;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-
-import org.apache.qpid.proton.amqp.messaging.AmqpValue;
-import org.apache.qpid.proton.amqp.messaging.Properties;
-import org.apache.qpid.proton.message.Message;
-import org.apache.qpid.proton.message.impl.MessageImpl;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.proton.plug.AMQPClientConnectionContext;
-import org.proton.plug.AMQPClientSenderContext;
-import org.proton.plug.AMQPClientSessionContext;
-import org.proton.plug.sasl.ClientSASLPlain;
-import org.proton.plug.test.minimalclient.SimpleAMQPConnector;
-import org.proton.plug.test.minimalserver.DumbServer;
-import org.proton.plug.util.ByteUtil;
-
-/**
- * This is simulating a JMS client against a simple server
- * This is being effectively tested by {@link org.apache.activemq.artemis.tests.integration.proton.ProtonTest} with a proper framework in place.
- * This test eventually hungs on the testsuite.
- * While it is still valid for debugging, for that reason the test will be ignored.
- * and will be kept here for debug purposes.
- */
-@Ignore // remove this to debug it
-@RunWith(Parameterized.class)
-public class ProtonTest extends AbstractJMSTest {
-
- protected Connection connection;
-
- @Parameterized.Parameters(name = "sasl={0}")
- public static Collection<Object[]> data() {
- List<Object[]> list = Arrays.asList(new Object[][]{{Boolean.TRUE}, {Boolean.FALSE}});
- System.out.println("Size = " + list.size());
- return list;
- }
-
- public ProtonTest(boolean useSASL) {
- super(useSASL);
- }
-
- @Before
- public void setUp() throws Exception {
- DumbServer.clear();
- AbstractJMSTest.forceGC();
- server.start("127.0.0.1", Constants.PORT, true);
- connection = createConnection();
- }
-
- @Override
- @After
- public void tearDown() throws Exception {
- if (connection != null) {
- connection.close();
- }
-
- super.tearDown();
- }
-
- @Test
- public void testMessagesReceivedInParallel() throws Throwable {
- final int numMessages = getNumberOfMessages();
- long time = System.currentTimeMillis();
-
- final ArrayList<Throwable> exceptions = new ArrayList<>();
-
- Thread t = new Thread(new Runnable() {
- @Override
- public void run() {
- Connection connectionConsumer = null;
- try {
- connectionConsumer = createConnection();
- // connectionConsumer = connection;
- connectionConsumer.start();
- Session sessionConsumer = connectionConsumer.createSession(false, Session.AUTO_ACKNOWLEDGE);
- final Queue queue = createQueue(sessionConsumer);
- final MessageConsumer consumer = sessionConsumer.createConsumer(queue);
-
- int count = numMessages;
- while (count > 0) {
- try {
- BytesMessage m = (BytesMessage) consumer.receive(1000);
- if (count % 1000 == 0) {
- System.out.println("Count = " + count + ", property=" + m.getStringProperty("XX"));
- }
- Assert.assertNotNull("Could not receive message count=" + count + " on consumer", m);
- count--;
- }
- catch (JMSException e) {
- break;
- }
- }
- }
- catch (Throwable e) {
- exceptions.add(e);
- e.printStackTrace();
- }
- finally {
- try {
- // if the createconnecion wasn't commented out
- if (connectionConsumer != connection) {
- connectionConsumer.close();
- }
- }
- catch (Throwable ignored) {
- // NO OP
- }
- }
- }
- });
-
- Session session = connection.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
-
- t.start();
- final Queue queue = createQueue(session);
-
- MessageProducer p = session.createProducer(queue);
- p.setDeliveryMode(DeliveryMode.PERSISTENT);
- for (int i = 0; i < numMessages; i++) {
- BytesMessage message = session.createBytesMessage();
- // TODO: this will break stuff if I use a large number
- message.writeBytes(new byte[5]);
- message.setIntProperty("count", i);
- message.setStringProperty("XX", "count" + i);
- p.send(message);
- }
-
- long taken = (System.currentTimeMillis() - time);
- System.out.println("taken on send = " + taken + " sasl = " + useSASL);
- t.join();
-
- for (Throwable e : exceptions) {
- throw e;
- }
- taken = (System.currentTimeMillis() - time);
- System.out.println("taken = " + taken + " sasl = " + useSASL);
-
- connection.close();
- // assertEquals(0, q.getMessageCount());
- }
-
- @Test
- public void testSimpleCreateSessionAndClose() throws Throwable {
-
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Queue queue = session.createQueue(address);
- Thread.sleep(1000);
- session.close();
- connection.close();
- }
-
- @Test
- public void testSimpleBinary() throws Throwable {
- final int numMessages = 5;
- long time = System.currentTimeMillis();
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- Queue queue = createQueue(session);
-
- byte[] bytes = new byte[0xf + 1];
- for (int i = 0; i <= 0xf; i++) {
- bytes[i] = (byte) i;
- }
-
- MessageProducer p = session.createProducer(queue);
- for (int i = 0; i < numMessages; i++) {
- BytesMessage message = session.createBytesMessage();
-
- message.writeBytes(bytes);
- message.setIntProperty("count", i);
- p.send(message);
- }
-
- session.close();
-
- Session sessionConsumer = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- final MessageConsumer consumer = sessionConsumer.createConsumer(queue);
-
- for (int i = 0; i < numMessages; i++) {
- BytesMessage m = (BytesMessage) consumer.receive(5000);
-
- System.out.println("length " + m.getBodyLength());
- Assert.assertNotNull("Could not receive message count=" + i + " on consumer", m);
-
- m.reset();
-
- long size = m.getBodyLength();
- byte[] bytesReceived = new byte[(int) size];
- m.readBytes(bytesReceived);
-
- System.out.println("Received " + ByteUtil.bytesToHex(bytesReceived, 1));
-
- Assert.assertArrayEquals(bytes, bytesReceived);
- }
-
- // assertEquals(0, q.getMessageCount());
- long taken = (System.currentTimeMillis() - time) / 1000;
- System.out.println("taken = " + taken);
- }
-
- @Test
- public void testMapMessage() throws Exception {
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Queue queue = createQueue(session);
- MessageProducer p = session.createProducer(queue);
- for (int i = 0; i < 10; i++) {
- MapMessage message = session.createMapMessage();
- message.setInt("x", i);
- message.setString("str", "str" + i);
- p.send(message);
- }
- MessageConsumer messageConsumer = session.createConsumer(queue);
- for (int i = 0; i < 10; i++) {
- MapMessage m = (MapMessage) messageConsumer.receive(5000);
- Assert.assertNotNull(m);
- Assert.assertEquals(i, m.getInt("x"));
- Assert.assertEquals("str" + i, m.getString("str"));
- }
-
- Assert.assertNull(messageConsumer.receiveNoWait());
- }
-
- @Test
- public void testProperties() throws Exception {
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Queue queue = createQueue(session);
- MessageProducer p = session.createProducer(queue);
- TextMessage message = session.createTextMessage();
- message.setText("msg:0");
- message.setBooleanProperty("true", true);
- message.setBooleanProperty("false", false);
- message.setStringProperty("foo", "bar");
- message.setDoubleProperty("double", 66.6);
- message.setFloatProperty("float", 56.789f);
- message.setIntProperty("int", 8);
- message.setByteProperty("byte", (byte) 10);
- p.send(message);
- p.send(message);
- connection.start();
- MessageConsumer messageConsumer = session.createConsumer(queue);
- TextMessage m = (TextMessage) messageConsumer.receive(5000);
- Assert.assertNotNull(m);
- Assert.assertEquals("msg:0", m.getText());
- Assert.assertEquals(m.getBooleanProperty("true"), true);
- Assert.assertEquals(m.getBooleanProperty("false"), false);
- Assert.assertEquals(m.getStringProperty("foo"), "bar");
- Assert.assertEquals(m.getDoubleProperty("double"), 66.6, 0.0001);
- Assert.assertEquals(m.getFloatProperty("float"), 56.789f, 0.0001);
- Assert.assertEquals(m.getIntProperty("int"), 8);
- Assert.assertEquals(m.getByteProperty("byte"), (byte) 10);
- m = (TextMessage) messageConsumer.receive(5000);
- Assert.assertNotNull(m);
- connection.close();
- }
-
- // @Test
- public void testSendWithSimpleClient() throws Exception {
- SimpleAMQPConnector connector = new SimpleAMQPConnector();
- connector.start();
- AMQPClientConnectionContext clientConnection = connector.connect("127.0.0.1", Constants.PORT);
-
- clientConnection.clientOpen(new ClientSASLPlain("aa", "aa"));
-
- AMQPClientSessionContext session = clientConnection.createClientSession();
- AMQPClientSenderContext clientSender = session.createSender(address, true);
-
- Properties props = new Properties();
- for (int i = 0; i < 1; i++) {
- MessageImpl message = (MessageImpl) Message.Factory.create();
-
- HashMap map = new HashMap();
-
- map.put("i", i);
- AmqpValue value = new AmqpValue(map);
- message.setBody(value);
- message.setProperties(props);
- clientSender.send(message);
- }
-
- Session clientSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- connection.start();
-
- MessageConsumer consumer = clientSession.createConsumer(createQueue(clientSession));
- for (int i = 0; i < 1; i++) {
- MapMessage msg = (MapMessage) consumer.receive(5000);
- System.out.println("Msg " + msg);
- Assert.assertNotNull(msg);
-
- System.out.println("Receive message " + i);
-
- Assert.assertEquals(0, msg.getInt("i"));
- }
- }
-
- protected int getNumberOfMessages() {
- return 10000;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/invm/InVMTestConnector.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/invm/InVMTestConnector.java b/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/invm/InVMTestConnector.java
deleted file mode 100644
index 197c39e..0000000
--- a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/invm/InVMTestConnector.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.test.invm;
-
-import java.util.concurrent.Executors;
-
-import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
-import org.proton.plug.AMQPClientConnectionContext;
-import org.proton.plug.context.client.ProtonClientConnectionContext;
-import org.proton.plug.test.minimalclient.Connector;
-
-/**
- * This is used for testing, where we bypass Netty or any networking for test conditions only
- */
-public class InVMTestConnector implements Connector {
-
- @Override
- public void start() {
-
- }
-
- @Override
- public AMQPClientConnectionContext connect(String host, int port) throws Exception {
- return new ProtonClientConnectionContext(new ProtonINVMSPI(), Executors.newSingleThreadExecutor(ActiveMQThreadFactory.defaultThreadFactory()), null);
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/invm/ProtonINVMSPI.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/invm/ProtonINVMSPI.java b/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/invm/ProtonINVMSPI.java
deleted file mode 100644
index a35e8ac..0000000
--- a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/invm/ProtonINVMSPI.java
+++ /dev/null
@@ -1,240 +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.proton.plug.test.invm;
-
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import io.netty.buffer.ByteBuf;
-import org.apache.activemq.artemis.core.transaction.Transaction;
-import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
-import org.apache.qpid.proton.amqp.Binary;
-import org.apache.qpid.proton.engine.Connection;
-import org.jboss.logging.Logger;
-import org.proton.plug.AMQPConnectionContext;
-import org.proton.plug.AMQPConnectionCallback;
-import org.proton.plug.AMQPSessionCallback;
-import org.proton.plug.SASLResult;
-import org.proton.plug.ServerSASL;
-import org.proton.plug.context.server.ProtonServerConnectionContext;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-import org.proton.plug.sasl.AnonymousServerSASL;
-import org.proton.plug.sasl.ServerSASLPlain;
-import org.proton.plug.test.minimalserver.MinimalSessionSPI;
-import org.proton.plug.util.ByteUtil;
-
-public class ProtonINVMSPI implements AMQPConnectionCallback {
-
- private static final Logger log = Logger.getLogger(ProtonINVMSPI.class);
-
-
- AMQPConnectionContext returningConnection;
-
- ProtonServerConnectionContext serverConnection = new ProtonServerConnectionContext(new ReturnSPI(), Executors.newSingleThreadExecutor(ActiveMQThreadFactory.defaultThreadFactory()), null);
-
- final ExecutorService mainExecutor = Executors.newSingleThreadExecutor(ActiveMQThreadFactory.defaultThreadFactory());
-
- final ExecutorService returningExecutor = Executors.newSingleThreadExecutor(ActiveMQThreadFactory.defaultThreadFactory());
-
- public ProtonINVMSPI() {
- mainExecutor.execute(new Runnable() {
- @Override
- public void run() {
- Thread.currentThread().setName("MainExecutor-INVM");
- }
- });
- returningExecutor.execute(new Runnable() {
- @Override
- public void run() {
- Thread.currentThread().setName("ReturningExecutor-INVM");
- }
- });
- }
-
- @Override
- public void close() {
- mainExecutor.shutdown();
- }
-
- @Override
- public ServerSASL[] getSASLMechnisms() {
- return new ServerSASL[]{new AnonymousServerSASL(), new ServerSASLPlain()};
- }
-
- @Override
- public boolean isSupportsAnonymous() {
- return true;
- }
-
- @Override
- public void sendSASLSupported() {
-
- }
-
- @Override
- public boolean validateConnection(Connection connection, SASLResult saslResult) {
- return true;
- }
-
- @Override
- public void onTransport(final ByteBuf bytes, final AMQPConnectionContext connection) {
- if (log.isTraceEnabled()) {
- ByteUtil.debugFrame(log, "InVM->", bytes);
- }
- final int size = bytes.writerIndex();
-
- bytes.retain();
- mainExecutor.execute(new Runnable() {
- @Override
- public void run() {
- try {
- if (log.isTraceEnabled()) {
- ByteUtil.debugFrame(log, "InVMDone->", bytes);
- }
- serverConnection.inputBuffer(bytes);
- try {
- connection.outputDone(size);
- }
- catch (Exception e) {
- log.warn(e.getMessage(), e);
- }
- }
- finally {
- bytes.release();
- }
- }
- });
- }
-
- @Override
- public void setConnection(AMQPConnectionContext connection) {
- returningConnection = connection;
- }
-
- @Override
- public AMQPConnectionContext getConnection() {
- return returningConnection;
- }
-
- @Override
- public AMQPSessionCallback createSessionCallback(AMQPConnectionContext connection) {
- return null;
- }
-
- @Override
- public Binary newTransaction() {
- return null;
- }
-
- @Override
- public Transaction getTransaction(Binary txid) throws ActiveMQAMQPException {
- return null;
- }
-
- @Override
- public void removeTransaction(Binary txid) {
-
- }
-
- class ReturnSPI implements AMQPConnectionCallback {
-
- @Override
- public void close() {
-
- }
-
- @Override
- public Binary newTransaction() {
- return null;
- }
-
- @Override
- public Transaction getTransaction(Binary txid) throws ActiveMQAMQPException {
- return null;
- }
-
- @Override
- public void removeTransaction(Binary txid) {
-
- }
-
- @Override
- public ServerSASL[] getSASLMechnisms() {
- return new ServerSASL[]{new AnonymousServerSASL(), new ServerSASLPlain()};
- }
-
- @Override
- public boolean isSupportsAnonymous() {
- return false;
- }
-
- @Override
- public void sendSASLSupported() {
-
- }
-
- @Override
- public boolean validateConnection(Connection connection, SASLResult saslResult) {
- return true;
- }
-
- @Override
- public void onTransport(final ByteBuf bytes, final AMQPConnectionContext connection) {
-
- final int size = bytes.writerIndex();
- ByteUtil.debugFrame(log, "InVM<-", bytes);
-
- bytes.retain();
- returningExecutor.execute(new Runnable() {
- @Override
- public void run() {
- try {
-
- ByteUtil.debugFrame(log, "InVM done<-", bytes);
-
- returningConnection.inputBuffer(bytes);
- try {
- connection.outputDone(size);
- }
- catch (Exception e) {
- log.warn(e.getMessage(), e);
- }
-
- }
- finally {
- bytes.release();
- }
- }
- });
- }
-
- @Override
- public AMQPSessionCallback createSessionCallback(AMQPConnectionContext connection) {
- return new MinimalSessionSPI();
- }
-
- @Override
- public void setConnection(AMQPConnectionContext connection) {
-
- }
-
- @Override
- public AMQPConnectionContext getConnection() {
- return null;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalclient/AMQPClientSPI.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalclient/AMQPClientSPI.java b/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalclient/AMQPClientSPI.java
deleted file mode 100644
index 85e4c02..0000000
--- a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalclient/AMQPClientSPI.java
+++ /dev/null
@@ -1,140 +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.proton.plug.test.minimalclient;
-
-import java.util.concurrent.TimeUnit;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelFutureListener;
-import org.apache.activemq.artemis.core.transaction.Transaction;
-import org.apache.qpid.proton.amqp.Binary;
-import org.apache.qpid.proton.engine.Connection;
-import org.jboss.logging.Logger;
-import org.proton.plug.AMQPConnectionContext;
-import org.proton.plug.AMQPConnectionCallback;
-import org.proton.plug.AMQPSessionCallback;
-import org.proton.plug.SASLResult;
-import org.proton.plug.ServerSASL;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-import org.proton.plug.sasl.AnonymousServerSASL;
-import org.proton.plug.sasl.ServerSASLPlain;
-import org.proton.plug.util.ByteUtil;
-import org.proton.plug.util.ReusableLatch;
-
-public class AMQPClientSPI implements AMQPConnectionCallback {
-
- private static final Logger log = Logger.getLogger(AMQPClientSPI.class);
- final Channel channel;
- protected AMQPConnectionContext connection;
-
- public AMQPClientSPI(Channel channel) {
- this.channel = channel;
- }
-
- @Override
- public void setConnection(AMQPConnectionContext connection) {
- this.connection = connection;
- }
-
- @Override
- public AMQPConnectionContext getConnection() {
- return connection;
- }
-
- @Override
- public void close() {
-
- }
-
- @Override
- public ServerSASL[] getSASLMechnisms() {
- return new ServerSASL[]{new AnonymousServerSASL(), new ServerSASLPlain()};
- }
-
- @Override
- public boolean isSupportsAnonymous() {
- return true;
- }
-
- @Override
- public void sendSASLSupported() {
-
- }
-
- @Override
- public Binary newTransaction() {
- return null;
- }
-
- @Override
- public Transaction getTransaction(Binary txid) throws ActiveMQAMQPException {
- return null;
- }
-
- @Override
- public void removeTransaction(Binary txid) {
-
- }
-
- @Override
- public boolean validateConnection(Connection connection, SASLResult saslResult) {
- return true;
- }
-
- final ReusableLatch latch = new ReusableLatch(0);
-
- @Override
- public void onTransport(final ByteBuf bytes, final AMQPConnectionContext connection) {
- if (log.isTraceEnabled()) {
- ByteUtil.debugFrame(log, "Bytes leaving client", bytes);
- }
-
- final int bufferSize = bytes.writerIndex();
-
- latch.countUp();
-
- channel.writeAndFlush(bytes).addListener(new ChannelFutureListener() {
- @Override
- public void operationComplete(ChannelFuture future) throws Exception {
- //
- // connection.outputDone(bufferSize);
- latch.countDown();
- }
- });
-
- if (connection.isSyncOnFlush()) {
- try {
- if (!latch.await(5, TimeUnit.SECONDS)) {
- log.debug("Flush took longer than 5 seconds!!!");
- }
- }
- catch (Throwable e) {
- log.warn(e.getMessage(), e);
- }
- }
-
- connection.outputDone(bufferSize);
-
- }
-
- @Override
- public AMQPSessionCallback createSessionCallback(AMQPConnectionContext connection) {
- return null;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalclient/Connector.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalclient/Connector.java b/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalclient/Connector.java
deleted file mode 100644
index e6b67c2..0000000
--- a/artemis-protocols/artemis-proton-plug/src/test/java/org/proton/plug/test/minimalclient/Connector.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug.test.minimalclient;
-
-import org.proton.plug.AMQPClientConnectionContext;
-
-public interface Connector {
-
- void start();
-
- AMQPClientConnectionContext connect(String host, int port) throws Exception;
-}
[15/15] activemq-artemis git commit: This closes #794
Posted by ma...@apache.org.
This closes #794
Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/0ac9dbd5
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/0ac9dbd5
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/0ac9dbd5
Branch: refs/heads/master
Commit: 0ac9dbd573e85b585b554be6c88b75ea7b0a8da8
Parents: 4e34969 a838bf0
Author: Martyn Taylor <mt...@redhat.com>
Authored: Tue Sep 27 14:54:13 2016 +0100
Committer: Martyn Taylor <mt...@redhat.com>
Committed: Tue Sep 27 14:54:13 2016 +0100
----------------------------------------------------------------------
.../apache/activemq/artemis/utils/ByteUtil.java | 57 +
artemis-distribution/src/main/assembly/dep.xml | 1 -
.../src/main/resources/features.xml | 1 -
artemis-protocols/artemis-amqp-protocol/pom.xml | 5 -
.../ActiveMQProtonRemotingConnection.java | 142 --
.../protocol/proton/ProtonProtocolManager.java | 176 --
.../proton/ProtonProtocolManagerFactory.java | 64 -
.../proton/converter/ActiveMQJMSVendor.java | 151 --
.../converter/ProtonMessageConverter.java | 109 --
.../proton/converter/jms/ServerDestination.java | 37 -
.../converter/jms/ServerJMSBytesMessage.java | 208 ---
.../converter/jms/ServerJMSMapMessage.java | 291 ---
.../proton/converter/jms/ServerJMSMessage.java | 381 ----
.../converter/jms/ServerJMSObjectMessage.java | 79 -
.../converter/jms/ServerJMSStreamMessage.java | 364 ----
.../converter/jms/ServerJMSTextMessage.java | 99 -
.../converter/message/AMQPMessageIdHelper.java | 257 ---
.../converter/message/AMQPMessageTypes.java | 25 -
.../message/AMQPNativeInboundTransformer.java | 46 -
.../message/AMQPNativeOutboundTransformer.java | 60 -
.../message/AMQPRawInboundTransformer.java | 60 -
.../converter/message/EncodedMessage.java | 67 -
.../converter/message/InboundTransformer.java | 318 ----
.../message/JMSMappingInboundTransformer.java | 128 --
.../message/JMSMappingOutboundTransformer.java | 365 ----
.../proton/converter/message/JMSVendor.java | 53 -
.../converter/message/OutboundTransformer.java | 69 -
.../plug/ActiveMQProtonConnectionCallback.java | 285 ---
.../plug/ProtonSessionIntegrationCallback.java | 542 ------
.../protocol/proton/sasl/ActiveMQPlainSASL.java | 45 -
.../amqp/broker/AMQPConnectionCallback.java | 260 +++
.../amqp/broker/AMQPSessionCallback.java | 515 ++++++
.../ActiveMQProtonRemotingConnection.java | 142 ++
.../amqp/broker/ProtonProtocolManager.java | 172 ++
.../broker/ProtonProtocolManagerFactory.java | 64 +
.../protocol/amqp/broker/package-info.java | 23 +
.../amqp/converter/ActiveMQJMSVendor.java | 151 ++
.../amqp/converter/ProtonMessageConverter.java | 109 ++
.../amqp/converter/jms/ServerDestination.java | 37 +
.../converter/jms/ServerJMSBytesMessage.java | 208 +++
.../amqp/converter/jms/ServerJMSMapMessage.java | 291 +++
.../amqp/converter/jms/ServerJMSMessage.java | 381 ++++
.../converter/jms/ServerJMSObjectMessage.java | 79 +
.../converter/jms/ServerJMSStreamMessage.java | 364 ++++
.../converter/jms/ServerJMSTextMessage.java | 99 +
.../converter/message/AMQPMessageIdHelper.java | 257 +++
.../converter/message/AMQPMessageTypes.java | 25 +
.../message/AMQPNativeInboundTransformer.java | 46 +
.../message/AMQPNativeOutboundTransformer.java | 60 +
.../message/AMQPRawInboundTransformer.java | 60 +
.../amqp/converter/message/EncodedMessage.java | 67 +
.../converter/message/InboundTransformer.java | 318 ++++
.../message/JMSMappingInboundTransformer.java | 128 ++
.../message/JMSMappingOutboundTransformer.java | 365 ++++
.../amqp/converter/message/JMSVendor.java | 53 +
.../converter/message/OutboundTransformer.java | 69 +
.../protocol/amqp/converter/package-info.java | 21 +
.../amqp/exceptions/ActiveMQAMQPException.java | 42 +
.../ActiveMQAMQPIllegalStateException.java | 27 +
.../ActiveMQAMQPInternalErrorException.java | 31 +
.../ActiveMQAMQPInvalidFieldException.java | 27 +
.../ActiveMQAMQPNotFoundException.java | 27 +
.../ActiveMQAMQPNotImplementedException.java | 27 +
...iveMQAMQPResourceLimitExceededException.java | 27 +
.../ActiveMQAMQPTimeoutException.java | 28 +
.../ActiveMQAMQPProtocolMessageBundle.java | 80 +
.../amqp/proton/AMQPConnectionContext.java | 424 +++++
.../protocol/amqp/proton/AMQPConstants.java | 36 +
.../amqp/proton/AMQPSessionContext.java | 221 +++
.../protocol/amqp/proton/AmqpSupport.java | 131 ++
.../amqp/proton/ProtonDeliveryHandler.java | 39 +
.../amqp/proton/ProtonInitializable.java | 32 +
.../proton/ProtonServerReceiverContext.java | 211 +++
.../amqp/proton/ProtonServerSenderContext.java | 513 ++++++
.../amqp/proton/ProtonTransactionHandler.java | 141 ++
.../amqp/proton/handler/EventHandler.java | 78 +
.../protocol/amqp/proton/handler/Events.java | 102 ++
.../amqp/proton/handler/ExtCapability.java | 44 +
.../amqp/proton/handler/ProtonHandler.java | 357 ++++
.../protocol/amqp/proton/package-info.java | 22 +
.../protocol/amqp/sasl/AnonymousServerSASL.java | 34 +
.../artemis/protocol/amqp/sasl/PlainSASL.java | 44 +
.../protocol/amqp/sasl/PlainSASLResult.java | 44 +
.../artemis/protocol/amqp/sasl/SASLResult.java | 24 +
.../artemis/protocol/amqp/sasl/ServerSASL.java | 24 +
.../protocol/amqp/sasl/ServerSASLPlain.java | 63 +
.../artemis/protocol/amqp/util/CodecCache.java | 50 +
.../protocol/amqp/util/CreditsSemaphore.java | 110 ++
.../protocol/amqp/util/DeliveryUtil.java | 44 +
.../protocol/amqp/util/NettyWritable.java | 100 ++
.../protocol/amqp/util/ProtonServerMessage.java | 470 +++++
...mis.spi.core.protocol.ProtocolManagerFactory | 2 +-
.../core/protocol/proton/TestConversions.java | 793 --------
.../amqp/converter/TestConversions.java | 792 ++++++++
.../protocol/amqp/sasl/ClientSASLPlain.java | 54 +
.../protocol/amqp/sasl/PlainSASLTest.java | 34 +
.../amqp/util/CreditsSemaphoreTest.java | 134 ++
artemis-protocols/artemis-proton-plug/pom.xml | 137 --
.../plug/AMQPClientConnectionContext.java | 36 -
.../proton/plug/AMQPClientReceiverContext.java | 34 -
.../proton/plug/AMQPClientSenderContext.java | 27 -
.../proton/plug/AMQPClientSessionContext.java | 30 -
.../org/proton/plug/AMQPConnectionCallback.java | 58 -
.../org/proton/plug/AMQPConnectionContext.java | 71 -
.../plug/AMQPConnectionContextFactory.java | 39 -
.../plug/AMQPServerConnectionContext.java | 21 -
.../org/proton/plug/AMQPSessionCallback.java | 112 --
.../org/proton/plug/AMQPSessionContext.java | 34 -
.../main/java/org/proton/plug/AmqpSupport.java | 131 --
.../main/java/org/proton/plug/ClientSASL.java | 24 -
.../main/java/org/proton/plug/SASLResult.java | 24 -
.../main/java/org/proton/plug/ServerSASL.java | 24 -
.../org/proton/plug/context/AMQPConstants.java | 36 -
.../plug/context/AbstractConnectionContext.java | 360 ----
.../context/AbstractProtonContextSender.java | 153 --
.../context/AbstractProtonReceiverContext.java | 88 -
.../context/AbstractProtonSessionContext.java | 161 --
.../plug/context/ProtonDeliveryHandler.java | 39 -
.../plug/context/ProtonInitializable.java | 67 -
.../proton/plug/context/ProtonPlugSender.java | 26 -
.../plug/context/ProtonTransactionHandler.java | 143 --
.../client/ProtonClientConnectionContext.java | 107 --
.../ProtonClientConnectionContextFactory.java | 50 -
.../context/client/ProtonClientContext.java | 76 -
.../client/ProtonClientReceiverContext.java | 92 -
.../client/ProtonClientSessionContext.java | 145 --
.../server/ProtonServerConnectionContext.java | 94 -
.../ProtonServerConnectionContextFactory.java | 53 -
.../server/ProtonServerReceiverContext.java | 161 --
.../server/ProtonServerSenderContext.java | 452 -----
.../server/ProtonServerSessionContext.java | 117 --
.../plug/exceptions/ActiveMQAMQPException.java | 42 -
.../ActiveMQAMQPIllegalStateException.java | 27 -
.../ActiveMQAMQPInternalErrorException.java | 31 -
.../ActiveMQAMQPInvalidFieldException.java | 27 -
.../ActiveMQAMQPNotFoundException.java | 27 -
.../ActiveMQAMQPNotImplementedException.java | 27 -
...iveMQAMQPResourceLimitExceededException.java | 27 -
.../ActiveMQAMQPTimeoutException.java | 28 -
.../org/proton/plug/handler/EventHandler.java | 78 -
.../java/org/proton/plug/handler/Events.java | 105 --
.../org/proton/plug/handler/ExtCapability.java | 46 -
.../org/proton/plug/handler/ProtonHandler.java | 133 --
.../plug/handler/impl/DefaultEventHandler.java | 144 --
.../plug/handler/impl/ProtonHandlerImpl.java | 389 ----
.../ActiveMQAMQPProtocolMessageBundle.java | 80 -
.../proton/plug/sasl/AnonymousServerSASL.java | 37 -
.../org/proton/plug/sasl/ClientSASLPlain.java | 59 -
.../org/proton/plug/sasl/PlainSASLResult.java | 46 -
.../org/proton/plug/sasl/ServerSASLPlain.java | 66 -
.../java/org/proton/plug/util/ByteUtil.java | 130 --
.../java/org/proton/plug/util/CodecCache.java | 50 -
.../org/proton/plug/util/CreditsSemaphore.java | 110 --
.../java/org/proton/plug/util/DeliveryUtil.java | 44 -
.../org/proton/plug/util/FutureRunnable.java | 61 -
.../org/proton/plug/util/NettyWritable.java | 100 --
.../proton/plug/util/ProtonServerMessage.java | 470 -----
.../org/proton/plug/util/ReusableLatch.java | 130 --
.../context/AbstractConnectionContextTest.java | 137 --
.../org/proton/plug/test/AbstractJMSTest.java | 93 -
.../java/org/proton/plug/test/Constants.java | 22 -
.../java/org/proton/plug/test/ProtonTest.java | 335 ----
.../plug/test/invm/InVMTestConnector.java | 40 -
.../proton/plug/test/invm/ProtonINVMSPI.java | 240 ---
.../plug/test/minimalclient/AMQPClientSPI.java | 140 --
.../plug/test/minimalclient/Connector.java | 26 -
.../test/minimalclient/SimpleAMQPConnector.java | 76 -
.../plug/test/minimalserver/DumbServer.java | 52 -
.../minimalserver/MinimalConnectionSPI.java | 171 --
.../plug/test/minimalserver/MinimalServer.java | 167 --
.../test/minimalserver/MinimalSessionSPI.java | 229 ---
.../SimpleServerThreadFactory.java | 82 -
.../proton/plug/test/sasl/PlainSASLTest.java | 37 -
.../plug/test/util/CreditsSemaphoreTest.java | 135 --
.../plug/test/util/ReusableLatchTest.java | 300 ----
.../test/util/SimpleServerAbstractTest.java | 67 -
artemis-protocols/pom.xml | 1 -
tests/integration-tests/pom.xml | 12 -
.../amqp/ProtonMaxFrameSizeTest.java | 98 +
.../integration/amqp/ProtonPubSubTest.java | 257 +++
.../tests/integration/amqp/ProtonTest.java | 1548 ++++++++++++++++
.../tests/integration/amqp/ProtonTestBase.java | 77 +
.../integration/amqp/ProtonTestForHeader.java | 219 +++
.../amqp/SendingAndReceivingTest.java | 100 ++
.../amqp/jms/SendingAndReceivingTest.java | 100 --
.../proton/ProtonMaxFrameSizeTest.java | 98 -
.../integration/proton/ProtonPubSubTest.java | 337 ----
.../tests/integration/proton/ProtonTest.java | 1700 ------------------
.../integration/proton/ProtonTestBase.java | 77 -
.../integration/proton/ProtonTestForHeader.java | 219 ---
190 files changed, 11409 insertions(+), 15851 deletions(-)
----------------------------------------------------------------------
[14/15] activemq-artemis git commit: ARTEMIS-751 Simplification of
the AMQP implementation
Posted by ma...@apache.org.
ARTEMIS-751 Simplification of the AMQP implementation
Since we don't need client implementations any longer, given the maturity level of
qpid jms, these classes can go, as a result a lot of the interfaces can be removed.
As part of this I am removing proton-plug, and reorganizing the packages in a way I think it
makes more sense and easier to other developers to understand and maintain it.
https://issues.apache.org/jira/browse/ARTEMIS-751
Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/a838bf04
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/a838bf04
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/a838bf04
Branch: refs/heads/master
Commit: a838bf047951e264d40ae1e59fbfe88aae854bf5
Parents: 4e34969
Author: Clebert Suconic <cl...@apache.org>
Authored: Fri Sep 23 17:25:36 2016 -0400
Committer: Clebert Suconic <cl...@apache.org>
Committed: Tue Sep 27 09:29:40 2016 -0400
----------------------------------------------------------------------
.../apache/activemq/artemis/utils/ByteUtil.java | 57 +
artemis-distribution/src/main/assembly/dep.xml | 1 -
.../src/main/resources/features.xml | 1 -
artemis-protocols/artemis-amqp-protocol/pom.xml | 5 -
.../ActiveMQProtonRemotingConnection.java | 142 --
.../protocol/proton/ProtonProtocolManager.java | 176 --
.../proton/ProtonProtocolManagerFactory.java | 64 -
.../proton/converter/ActiveMQJMSVendor.java | 151 --
.../converter/ProtonMessageConverter.java | 109 --
.../proton/converter/jms/ServerDestination.java | 37 -
.../converter/jms/ServerJMSBytesMessage.java | 208 ---
.../converter/jms/ServerJMSMapMessage.java | 291 ---
.../proton/converter/jms/ServerJMSMessage.java | 381 ----
.../converter/jms/ServerJMSObjectMessage.java | 79 -
.../converter/jms/ServerJMSStreamMessage.java | 364 ----
.../converter/jms/ServerJMSTextMessage.java | 99 -
.../converter/message/AMQPMessageIdHelper.java | 257 ---
.../converter/message/AMQPMessageTypes.java | 25 -
.../message/AMQPNativeInboundTransformer.java | 46 -
.../message/AMQPNativeOutboundTransformer.java | 60 -
.../message/AMQPRawInboundTransformer.java | 60 -
.../converter/message/EncodedMessage.java | 67 -
.../converter/message/InboundTransformer.java | 318 ----
.../message/JMSMappingInboundTransformer.java | 128 --
.../message/JMSMappingOutboundTransformer.java | 365 ----
.../proton/converter/message/JMSVendor.java | 53 -
.../converter/message/OutboundTransformer.java | 69 -
.../plug/ActiveMQProtonConnectionCallback.java | 285 ---
.../plug/ProtonSessionIntegrationCallback.java | 542 ------
.../protocol/proton/sasl/ActiveMQPlainSASL.java | 45 -
.../amqp/broker/AMQPConnectionCallback.java | 260 +++
.../amqp/broker/AMQPSessionCallback.java | 515 ++++++
.../ActiveMQProtonRemotingConnection.java | 142 ++
.../amqp/broker/ProtonProtocolManager.java | 172 ++
.../broker/ProtonProtocolManagerFactory.java | 64 +
.../protocol/amqp/broker/package-info.java | 23 +
.../amqp/converter/ActiveMQJMSVendor.java | 151 ++
.../amqp/converter/ProtonMessageConverter.java | 109 ++
.../amqp/converter/jms/ServerDestination.java | 37 +
.../converter/jms/ServerJMSBytesMessage.java | 208 +++
.../amqp/converter/jms/ServerJMSMapMessage.java | 291 +++
.../amqp/converter/jms/ServerJMSMessage.java | 381 ++++
.../converter/jms/ServerJMSObjectMessage.java | 79 +
.../converter/jms/ServerJMSStreamMessage.java | 364 ++++
.../converter/jms/ServerJMSTextMessage.java | 99 +
.../converter/message/AMQPMessageIdHelper.java | 257 +++
.../converter/message/AMQPMessageTypes.java | 25 +
.../message/AMQPNativeInboundTransformer.java | 46 +
.../message/AMQPNativeOutboundTransformer.java | 60 +
.../message/AMQPRawInboundTransformer.java | 60 +
.../amqp/converter/message/EncodedMessage.java | 67 +
.../converter/message/InboundTransformer.java | 318 ++++
.../message/JMSMappingInboundTransformer.java | 128 ++
.../message/JMSMappingOutboundTransformer.java | 365 ++++
.../amqp/converter/message/JMSVendor.java | 53 +
.../converter/message/OutboundTransformer.java | 69 +
.../protocol/amqp/converter/package-info.java | 21 +
.../amqp/exceptions/ActiveMQAMQPException.java | 42 +
.../ActiveMQAMQPIllegalStateException.java | 27 +
.../ActiveMQAMQPInternalErrorException.java | 31 +
.../ActiveMQAMQPInvalidFieldException.java | 27 +
.../ActiveMQAMQPNotFoundException.java | 27 +
.../ActiveMQAMQPNotImplementedException.java | 27 +
...iveMQAMQPResourceLimitExceededException.java | 27 +
.../ActiveMQAMQPTimeoutException.java | 28 +
.../ActiveMQAMQPProtocolMessageBundle.java | 80 +
.../amqp/proton/AMQPConnectionContext.java | 424 +++++
.../protocol/amqp/proton/AMQPConstants.java | 36 +
.../amqp/proton/AMQPSessionContext.java | 221 +++
.../protocol/amqp/proton/AmqpSupport.java | 131 ++
.../amqp/proton/ProtonDeliveryHandler.java | 39 +
.../amqp/proton/ProtonInitializable.java | 32 +
.../proton/ProtonServerReceiverContext.java | 211 +++
.../amqp/proton/ProtonServerSenderContext.java | 513 ++++++
.../amqp/proton/ProtonTransactionHandler.java | 141 ++
.../amqp/proton/handler/EventHandler.java | 78 +
.../protocol/amqp/proton/handler/Events.java | 102 ++
.../amqp/proton/handler/ExtCapability.java | 44 +
.../amqp/proton/handler/ProtonHandler.java | 357 ++++
.../protocol/amqp/proton/package-info.java | 22 +
.../protocol/amqp/sasl/AnonymousServerSASL.java | 34 +
.../artemis/protocol/amqp/sasl/PlainSASL.java | 44 +
.../protocol/amqp/sasl/PlainSASLResult.java | 44 +
.../artemis/protocol/amqp/sasl/SASLResult.java | 24 +
.../artemis/protocol/amqp/sasl/ServerSASL.java | 24 +
.../protocol/amqp/sasl/ServerSASLPlain.java | 63 +
.../artemis/protocol/amqp/util/CodecCache.java | 50 +
.../protocol/amqp/util/CreditsSemaphore.java | 110 ++
.../protocol/amqp/util/DeliveryUtil.java | 44 +
.../protocol/amqp/util/NettyWritable.java | 100 ++
.../protocol/amqp/util/ProtonServerMessage.java | 470 +++++
...mis.spi.core.protocol.ProtocolManagerFactory | 2 +-
.../core/protocol/proton/TestConversions.java | 793 --------
.../amqp/converter/TestConversions.java | 792 ++++++++
.../protocol/amqp/sasl/ClientSASLPlain.java | 54 +
.../protocol/amqp/sasl/PlainSASLTest.java | 34 +
.../amqp/util/CreditsSemaphoreTest.java | 134 ++
artemis-protocols/artemis-proton-plug/pom.xml | 137 --
.../plug/AMQPClientConnectionContext.java | 36 -
.../proton/plug/AMQPClientReceiverContext.java | 34 -
.../proton/plug/AMQPClientSenderContext.java | 27 -
.../proton/plug/AMQPClientSessionContext.java | 30 -
.../org/proton/plug/AMQPConnectionCallback.java | 58 -
.../org/proton/plug/AMQPConnectionContext.java | 71 -
.../plug/AMQPConnectionContextFactory.java | 39 -
.../plug/AMQPServerConnectionContext.java | 21 -
.../org/proton/plug/AMQPSessionCallback.java | 112 --
.../org/proton/plug/AMQPSessionContext.java | 34 -
.../main/java/org/proton/plug/AmqpSupport.java | 131 --
.../main/java/org/proton/plug/ClientSASL.java | 24 -
.../main/java/org/proton/plug/SASLResult.java | 24 -
.../main/java/org/proton/plug/ServerSASL.java | 24 -
.../org/proton/plug/context/AMQPConstants.java | 36 -
.../plug/context/AbstractConnectionContext.java | 360 ----
.../context/AbstractProtonContextSender.java | 153 --
.../context/AbstractProtonReceiverContext.java | 88 -
.../context/AbstractProtonSessionContext.java | 161 --
.../plug/context/ProtonDeliveryHandler.java | 39 -
.../plug/context/ProtonInitializable.java | 67 -
.../proton/plug/context/ProtonPlugSender.java | 26 -
.../plug/context/ProtonTransactionHandler.java | 143 --
.../client/ProtonClientConnectionContext.java | 107 --
.../ProtonClientConnectionContextFactory.java | 50 -
.../context/client/ProtonClientContext.java | 76 -
.../client/ProtonClientReceiverContext.java | 92 -
.../client/ProtonClientSessionContext.java | 145 --
.../server/ProtonServerConnectionContext.java | 94 -
.../ProtonServerConnectionContextFactory.java | 53 -
.../server/ProtonServerReceiverContext.java | 161 --
.../server/ProtonServerSenderContext.java | 452 -----
.../server/ProtonServerSessionContext.java | 117 --
.../plug/exceptions/ActiveMQAMQPException.java | 42 -
.../ActiveMQAMQPIllegalStateException.java | 27 -
.../ActiveMQAMQPInternalErrorException.java | 31 -
.../ActiveMQAMQPInvalidFieldException.java | 27 -
.../ActiveMQAMQPNotFoundException.java | 27 -
.../ActiveMQAMQPNotImplementedException.java | 27 -
...iveMQAMQPResourceLimitExceededException.java | 27 -
.../ActiveMQAMQPTimeoutException.java | 28 -
.../org/proton/plug/handler/EventHandler.java | 78 -
.../java/org/proton/plug/handler/Events.java | 105 --
.../org/proton/plug/handler/ExtCapability.java | 46 -
.../org/proton/plug/handler/ProtonHandler.java | 133 --
.../plug/handler/impl/DefaultEventHandler.java | 144 --
.../plug/handler/impl/ProtonHandlerImpl.java | 389 ----
.../ActiveMQAMQPProtocolMessageBundle.java | 80 -
.../proton/plug/sasl/AnonymousServerSASL.java | 37 -
.../org/proton/plug/sasl/ClientSASLPlain.java | 59 -
.../org/proton/plug/sasl/PlainSASLResult.java | 46 -
.../org/proton/plug/sasl/ServerSASLPlain.java | 66 -
.../java/org/proton/plug/util/ByteUtil.java | 130 --
.../java/org/proton/plug/util/CodecCache.java | 50 -
.../org/proton/plug/util/CreditsSemaphore.java | 110 --
.../java/org/proton/plug/util/DeliveryUtil.java | 44 -
.../org/proton/plug/util/FutureRunnable.java | 61 -
.../org/proton/plug/util/NettyWritable.java | 100 --
.../proton/plug/util/ProtonServerMessage.java | 470 -----
.../org/proton/plug/util/ReusableLatch.java | 130 --
.../context/AbstractConnectionContextTest.java | 137 --
.../org/proton/plug/test/AbstractJMSTest.java | 93 -
.../java/org/proton/plug/test/Constants.java | 22 -
.../java/org/proton/plug/test/ProtonTest.java | 335 ----
.../plug/test/invm/InVMTestConnector.java | 40 -
.../proton/plug/test/invm/ProtonINVMSPI.java | 240 ---
.../plug/test/minimalclient/AMQPClientSPI.java | 140 --
.../plug/test/minimalclient/Connector.java | 26 -
.../test/minimalclient/SimpleAMQPConnector.java | 76 -
.../plug/test/minimalserver/DumbServer.java | 52 -
.../minimalserver/MinimalConnectionSPI.java | 171 --
.../plug/test/minimalserver/MinimalServer.java | 167 --
.../test/minimalserver/MinimalSessionSPI.java | 229 ---
.../SimpleServerThreadFactory.java | 82 -
.../proton/plug/test/sasl/PlainSASLTest.java | 37 -
.../plug/test/util/CreditsSemaphoreTest.java | 135 --
.../plug/test/util/ReusableLatchTest.java | 300 ----
.../test/util/SimpleServerAbstractTest.java | 67 -
artemis-protocols/pom.xml | 1 -
tests/integration-tests/pom.xml | 12 -
.../amqp/ProtonMaxFrameSizeTest.java | 98 +
.../integration/amqp/ProtonPubSubTest.java | 257 +++
.../tests/integration/amqp/ProtonTest.java | 1548 ++++++++++++++++
.../tests/integration/amqp/ProtonTestBase.java | 77 +
.../integration/amqp/ProtonTestForHeader.java | 219 +++
.../amqp/SendingAndReceivingTest.java | 100 ++
.../amqp/jms/SendingAndReceivingTest.java | 100 --
.../proton/ProtonMaxFrameSizeTest.java | 98 -
.../integration/proton/ProtonPubSubTest.java | 337 ----
.../tests/integration/proton/ProtonTest.java | 1700 ------------------
.../integration/proton/ProtonTestBase.java | 77 -
.../integration/proton/ProtonTestForHeader.java | 219 ---
190 files changed, 11409 insertions(+), 15851 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/ByteUtil.java
----------------------------------------------------------------------
diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/ByteUtil.java b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/ByteUtil.java
index 7921072..c678941 100644
--- a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/ByteUtil.java
+++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/ByteUtil.java
@@ -22,6 +22,7 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.UnpooledByteBufAllocator;
import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
import org.apache.activemq.artemis.api.core.SimpleString;
+import org.jboss.logging.Logger;
public class ByteUtil {
@@ -29,6 +30,52 @@ public class ByteUtil {
private static final char[] hexArray = "0123456789ABCDEF".toCharArray();
+ public static void debugFrame(Logger logger, String message, ByteBuf byteIn) {
+ if (logger.isTraceEnabled()) {
+ int location = byteIn.readerIndex();
+ // debugging
+ byte[] frame = new byte[byteIn.writerIndex()];
+ byteIn.readBytes(frame);
+
+ try {
+ logger.trace(message + "\n" + ByteUtil.formatGroup(ByteUtil.bytesToHex(frame), 8, 16));
+ }
+ catch (Exception e) {
+ logger.warn(e.getMessage(), e);
+ }
+
+ byteIn.readerIndex(location);
+ }
+ }
+
+
+ public static String formatGroup(String str, int groupSize, int lineBreak) {
+ StringBuffer buffer = new StringBuffer();
+
+ int line = 1;
+ buffer.append("/* 1 */ \"");
+ for (int i = 0; i < str.length(); i += groupSize) {
+ buffer.append(str.substring(i, i + Math.min(str.length() - i, groupSize)));
+
+ if ((i + groupSize) % lineBreak == 0) {
+ buffer.append("\" +\n/* ");
+ line++;
+ if (line < 10) {
+ buffer.append(" ");
+ }
+ buffer.append(Integer.toString(line) + " */ \"");
+ }
+ else if ((i + groupSize) % groupSize == 0 && str.length() - i > groupSize) {
+ buffer.append("\" + \"");
+ }
+ }
+
+ buffer.append("\";");
+
+ return buffer.toString();
+
+ }
+
public static String maxString(String value, int size) {
if (value.length() < size) {
return value;
@@ -38,6 +85,16 @@ public class ByteUtil {
}
}
+ public static String bytesToHex(byte[] bytes) {
+ char[] hexChars = new char[bytes.length * 2];
+ for (int j = 0; j < bytes.length; j++) {
+ int v = bytes[j] & 0xFF;
+ hexChars[j * 2] = hexArray[v >>> 4];
+ hexChars[j * 2 + 1] = hexArray[v & 0x0F];
+ }
+ return new String(hexChars);
+ }
+
public static String bytesToHex(byte[] bytes, int groupSize) {
char[] hexChars = new char[bytes.length * 2 + numberOfGroups(bytes, groupSize)];
int outPos = 0;
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-distribution/src/main/assembly/dep.xml
----------------------------------------------------------------------
diff --git a/artemis-distribution/src/main/assembly/dep.xml b/artemis-distribution/src/main/assembly/dep.xml
index a62ef25..a50fe79 100644
--- a/artemis-distribution/src/main/assembly/dep.xml
+++ b/artemis-distribution/src/main/assembly/dep.xml
@@ -58,7 +58,6 @@
<include>org.apache.activemq:artemis-native</include>
<include>org.apache.activemq:artemis-amqp-protocol</include>
<include>org.apache.activemq:artemis-openwire-protocol</include>
- <include>org.apache.activemq:artemis-proton-plug</include>
<include>org.apache.activemq:artemis-hornetq-protocol</include>
<include>org.apache.activemq:artemis-hqclient-protocol</include>
<include>org.apache.activemq:artemis-stomp-protocol</include>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-features/src/main/resources/features.xml
----------------------------------------------------------------------
diff --git a/artemis-features/src/main/resources/features.xml b/artemis-features/src/main/resources/features.xml
index 2677626..7e477aa 100644
--- a/artemis-features/src/main/resources/features.xml
+++ b/artemis-features/src/main/resources/features.xml
@@ -63,7 +63,6 @@
<feature>artemis-core</feature>
<bundle>wrap:mvn:org.apache.qpid/proton-j/${proton.version}</bundle>
<bundle>wrap:mvn:org.apache.qpid/qpid-jms-client/${qpid.jms.version}</bundle>
- <bundle>mvn:org.apache.activemq/artemis-proton-plug/${pom.version}</bundle>
<bundle>mvn:org.apache.activemq/artemis-amqp-protocol/${pom.version}</bundle>
</feature>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/pom.xml
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/pom.xml b/artemis-protocols/artemis-amqp-protocol/pom.xml
index e623ef8..aac507e 100644
--- a/artemis-protocols/artemis-amqp-protocol/pom.xml
+++ b/artemis-protocols/artemis-amqp-protocol/pom.xml
@@ -75,11 +75,6 @@
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.apache.activemq</groupId>
- <artifactId>artemis-proton-plug</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
<groupId>org.apache.qpid</groupId>
<artifactId>proton-j</artifactId>
</dependency>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/ActiveMQProtonRemotingConnection.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/ActiveMQProtonRemotingConnection.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/ActiveMQProtonRemotingConnection.java
deleted file mode 100644
index 670ca5b..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/ActiveMQProtonRemotingConnection.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton;
-
-import java.util.concurrent.Executor;
-
-import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.client.ActiveMQClientLogger;
-import org.apache.activemq.artemis.spi.core.protocol.AbstractRemotingConnection;
-import org.apache.activemq.artemis.spi.core.remoting.Connection;
-import org.proton.plug.AMQPConnectionContext;
-
-/**
- * This is a Server's Connection representation used by ActiveMQ Artemis.
- */
-public class ActiveMQProtonRemotingConnection extends AbstractRemotingConnection {
-
- private final AMQPConnectionContext amqpConnection;
-
- private boolean destroyed = false;
-
- private final ProtonProtocolManager manager;
-
- public ActiveMQProtonRemotingConnection(ProtonProtocolManager manager,
- AMQPConnectionContext amqpConnection,
- Connection transportConnection,
- Executor executor) {
- super(transportConnection, executor);
- this.manager = manager;
- this.amqpConnection = amqpConnection;
- }
-
- public Executor getExecutor() {
- return this.executor;
- }
-
- public ProtonProtocolManager getManager() {
- return manager;
- }
-
- /*
- * This can be called concurrently by more than one thread so needs to be locked
- */
- @Override
- public void fail(final ActiveMQException me, String scaleDownTargetNodeID) {
- if (destroyed) {
- return;
- }
-
- destroyed = true;
-
- ActiveMQClientLogger.LOGGER.connectionFailureDetected(me.getMessage(), me.getType());
-
- // Then call the listeners
- callFailureListeners(me, scaleDownTargetNodeID);
-
- callClosingListeners();
-
- internalClose();
- }
-
- @Override
- public void destroy() {
- synchronized (this) {
- if (destroyed) {
- return;
- }
-
- destroyed = true;
- }
-
- callClosingListeners();
-
- internalClose();
-
- }
-
- @Override
- public boolean isClient() {
- return false;
- }
-
- @Override
- public boolean isDestroyed() {
- return destroyed;
- }
-
- @Override
- public void disconnect(boolean criticalError) {
- getTransportConnection().close();
- }
-
- /**
- * Disconnect the connection, closing all channels
- */
- @Override
- public void disconnect(String scaleDownNodeID, boolean criticalError) {
- getTransportConnection().close();
- }
-
- @Override
- public boolean checkDataReceived() {
- return amqpConnection.checkDataReceived();
- }
-
- @Override
- public void flush() {
- amqpConnection.flush();
- }
-
- @Override
- public void bufferReceived(Object connectionID, ActiveMQBuffer buffer) {
- amqpConnection.inputBuffer(buffer.byteBuf());
- super.bufferReceived(connectionID, buffer);
- }
-
- private void internalClose() {
- // We close the underlying transport connection
- getTransportConnection().close();
- }
-
- @Override
- public void killMessage(SimpleString nodeID) {
- //unsupported
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/ProtonProtocolManager.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/ProtonProtocolManager.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/ProtonProtocolManager.java
deleted file mode 100644
index a2563a1..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/ProtonProtocolManager.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-import io.netty.channel.ChannelPipeline;
-import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
-import org.apache.activemq.artemis.api.core.BaseInterceptor;
-import org.apache.activemq.artemis.api.core.Interceptor;
-import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
-import org.apache.activemq.artemis.core.protocol.proton.converter.ProtonMessageConverter;
-import org.apache.activemq.artemis.core.protocol.proton.plug.ActiveMQProtonConnectionCallback;
-import org.apache.activemq.artemis.core.remoting.impl.netty.NettyServerConnection;
-import org.apache.activemq.artemis.core.server.ActiveMQServer;
-import org.apache.activemq.artemis.core.server.management.Notification;
-import org.apache.activemq.artemis.core.server.management.NotificationListener;
-import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
-import org.apache.activemq.artemis.spi.core.protocol.ConnectionEntry;
-import org.apache.activemq.artemis.spi.core.protocol.MessageConverter;
-import org.apache.activemq.artemis.spi.core.protocol.ProtocolManager;
-import org.apache.activemq.artemis.spi.core.protocol.ProtocolManagerFactory;
-import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
-import org.apache.activemq.artemis.spi.core.remoting.Acceptor;
-import org.apache.activemq.artemis.spi.core.remoting.Connection;
-import org.proton.plug.AMQPServerConnectionContext;
-import org.proton.plug.context.server.ProtonServerConnectionContextFactory;
-
-import static org.proton.plug.context.AMQPConstants.Connection.DEFAULT_CHANNEL_MAX;
-import static org.proton.plug.context.AMQPConstants.Connection.DEFAULT_MAX_FRAME_SIZE;
-
-/**
- * A proton protocol manager, basically reads the Proton Input and maps proton resources to ActiveMQ Artemis resources
- */
-public class ProtonProtocolManager implements ProtocolManager<Interceptor>, NotificationListener {
-
- private static final List<String> websocketRegistryNames = Arrays.asList("amqp");
-
- private final ActiveMQServer server;
-
- private MessageConverter protonConverter;
-
- private final ProtonProtocolManagerFactory factory;
-
- /*
- * used when you want to treat senders as a subscription on an address rather than consuming from the actual queue for
- * the address. This can be changed on the acceptor.
- * */
- private String pubSubPrefix = ActiveMQDestination.JMS_TOPIC_ADDRESS_PREFIX;
-
- private int maxFrameSize = DEFAULT_MAX_FRAME_SIZE;
-
- public ProtonProtocolManager(ProtonProtocolManagerFactory factory, ActiveMQServer server) {
- this.factory = factory;
- this.server = server;
- this.protonConverter = new ProtonMessageConverter(server.getStorageManager());
- }
-
- public ActiveMQServer getServer() {
- return server;
- }
-
- @Override
- public MessageConverter getConverter() {
- return protonConverter;
- }
-
- @Override
- public void onNotification(Notification notification) {
-
- }
-
- @Override
- public ProtocolManagerFactory<Interceptor> getFactory() {
- return factory;
- }
-
- @Override
- public void updateInterceptors(List<BaseInterceptor> incomingInterceptors,
- List<BaseInterceptor> outgoingInterceptors) {
- // no op
- }
-
- @Override
- public boolean acceptsNoHandshake() {
- return false;
- }
-
- @Override
- public ConnectionEntry createConnectionEntry(Acceptor acceptorUsed, Connection remotingConnection) {
- ActiveMQProtonConnectionCallback connectionCallback = new ActiveMQProtonConnectionCallback(this, remotingConnection, server.getExecutorFactory().getExecutor(), server);
- long ttl = ActiveMQClient.DEFAULT_CONNECTION_TTL;
-
- if (server.getConfiguration().getConnectionTTLOverride() != -1) {
- ttl = server.getConfiguration().getConnectionTTLOverride();
- }
-
- String id = server.getConfiguration().getName();
- AMQPServerConnectionContext amqpConnection = ProtonServerConnectionContextFactory.getFactory().
- createConnection(connectionCallback, id, (int) ttl, getMaxFrameSize(), DEFAULT_CHANNEL_MAX, server.getExecutorFactory().getExecutor(), server.getScheduledPool());
-
- Executor executor = server.getExecutorFactory().getExecutor();
-
- ActiveMQProtonRemotingConnection delegate = new ActiveMQProtonRemotingConnection(this, amqpConnection, remotingConnection, executor);
-
- connectionCallback.setProtonConnectionDelegate(delegate);
-
- ConnectionEntry entry = new ConnectionEntry(delegate, executor, System.currentTimeMillis(), ttl);
-
- return entry;
- }
-
- @Override
- public void removeHandler(String name) {
-
- }
-
- @Override
- public void handleBuffer(RemotingConnection connection, ActiveMQBuffer buffer) {
- ActiveMQProtonRemotingConnection protonConnection = (ActiveMQProtonRemotingConnection) connection;
-
- protonConnection.bufferReceived(protonConnection.getID(), buffer);
- }
-
- @Override
- public void addChannelHandlers(ChannelPipeline pipeline) {
-
- }
-
- @Override
- public boolean isProtocol(byte[] array) {
- return array.length >= 4 && array[0] == (byte) 'A' && array[1] == (byte) 'M' && array[2] == (byte) 'Q' && array[3] == (byte) 'P';
- }
-
- @Override
- public void handshake(NettyServerConnection connection, ActiveMQBuffer buffer) {
- }
-
- @Override
- public List<String> websocketSubprotocolIdentifiers() {
- return websocketRegistryNames;
- }
-
- public String getPubSubPrefix() {
- return pubSubPrefix;
- }
-
- public void setPubSubPrefix(String pubSubPrefix) {
- this.pubSubPrefix = pubSubPrefix;
- }
-
-
- public int getMaxFrameSize() {
- return maxFrameSize;
- }
-
- public void setMaxFrameSize(int maxFrameSize) {
- this.maxFrameSize = maxFrameSize;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/ProtonProtocolManagerFactory.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/ProtonProtocolManagerFactory.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/ProtonProtocolManagerFactory.java
deleted file mode 100644
index e677563..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/ProtonProtocolManagerFactory.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton;
-
-import org.apache.activemq.artemis.api.core.BaseInterceptor;
-import org.apache.activemq.artemis.api.core.Interceptor;
-import org.apache.activemq.artemis.core.server.ActiveMQServer;
-import org.apache.activemq.artemis.spi.core.protocol.AbstractProtocolManagerFactory;
-import org.apache.activemq.artemis.spi.core.protocol.ProtocolManager;
-import org.apache.activemq.artemis.spi.core.protocol.ProtocolManagerFactory;
-import org.apache.activemq.artemis.utils.uri.BeanSupport;
-import org.osgi.service.component.annotations.Component;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-@Component(service = ProtocolManagerFactory.class)
-public class ProtonProtocolManagerFactory extends AbstractProtocolManagerFactory<Interceptor> {
-
- private static final String AMQP_PROTOCOL_NAME = "AMQP";
-
- private static final String MODULE_NAME = "artemis-amqp-protocol";
-
- private static String[] SUPPORTED_PROTOCOLS = {AMQP_PROTOCOL_NAME};
-
- @Override
- public ProtocolManager createProtocolManager(ActiveMQServer server,
- final Map<String, Object> parameters,
- List<BaseInterceptor> incomingInterceptors,
- List<BaseInterceptor> outgoingInterceptors) throws Exception {
- return BeanSupport.setData(new ProtonProtocolManager(this, server), parameters);
- }
-
- @Override
- public List<Interceptor> filterInterceptors(List<BaseInterceptor> interceptors) {
- // no interceptors on Proton
- return Collections.emptyList();
- }
-
- @Override
- public String[] getProtocols() {
- return SUPPORTED_PROTOCOLS;
- }
-
- @Override
- public String getModuleName() {
- return MODULE_NAME;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/ActiveMQJMSVendor.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/ActiveMQJMSVendor.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/ActiveMQJMSVendor.java
deleted file mode 100644
index 7ed95d4..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/ActiveMQJMSVendor.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.converter;
-
-import javax.jms.BytesMessage;
-import javax.jms.Destination;
-import javax.jms.JMSException;
-import javax.jms.MapMessage;
-import javax.jms.Message;
-import javax.jms.ObjectMessage;
-import javax.jms.StreamMessage;
-import javax.jms.TextMessage;
-
-import org.apache.activemq.artemis.core.buffers.impl.ResetLimitWrappedActiveMQBuffer;
-import org.apache.activemq.artemis.core.protocol.proton.converter.jms.ServerDestination;
-import org.apache.activemq.artemis.core.protocol.proton.converter.jms.ServerJMSBytesMessage;
-import org.apache.activemq.artemis.core.protocol.proton.converter.jms.ServerJMSMapMessage;
-import org.apache.activemq.artemis.core.protocol.proton.converter.jms.ServerJMSMessage;
-import org.apache.activemq.artemis.core.protocol.proton.converter.jms.ServerJMSObjectMessage;
-import org.apache.activemq.artemis.core.protocol.proton.converter.jms.ServerJMSStreamMessage;
-import org.apache.activemq.artemis.core.protocol.proton.converter.jms.ServerJMSTextMessage;
-import org.apache.activemq.artemis.core.protocol.proton.converter.message.JMSVendor;
-import org.apache.activemq.artemis.core.server.ServerMessage;
-import org.apache.activemq.artemis.core.server.impl.ServerMessageImpl;
-import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
-import org.apache.activemq.artemis.utils.IDGenerator;
-
-public class ActiveMQJMSVendor implements JMSVendor {
-
- private final IDGenerator serverGenerator;
-
- ActiveMQJMSVendor(IDGenerator idGenerator) {
- this.serverGenerator = idGenerator;
- }
-
- @Override
- public BytesMessage createBytesMessage() {
- return new ServerJMSBytesMessage(newMessage(org.apache.activemq.artemis.api.core.Message.BYTES_TYPE), 0);
- }
-
- @Override
- public StreamMessage createStreamMessage() {
- return new ServerJMSStreamMessage(newMessage(org.apache.activemq.artemis.api.core.Message.STREAM_TYPE), 0);
- }
-
- @Override
- public Message createMessage() {
- return new ServerJMSMessage(newMessage(org.apache.activemq.artemis.api.core.Message.DEFAULT_TYPE), 0);
- }
-
- @Override
- public TextMessage createTextMessage() {
- return new ServerJMSTextMessage(newMessage(org.apache.activemq.artemis.api.core.Message.TEXT_TYPE), 0);
- }
-
- @Override
- public ObjectMessage createObjectMessage() {
- return new ServerJMSObjectMessage(newMessage(org.apache.activemq.artemis.api.core.Message.OBJECT_TYPE), 0);
- }
-
- @Override
- public MapMessage createMapMessage() {
- return new ServerJMSMapMessage(newMessage(org.apache.activemq.artemis.api.core.Message.MAP_TYPE), 0);
- }
-
- @Override
- public void setJMSXUserID(Message message, String s) {
- }
-
- @Override
- public Destination createDestination(String name) {
- return new ServerDestination(name);
- }
-
- @Override
- public void setJMSXGroupID(Message message, String s) {
- try {
- message.setStringProperty("_AMQ_GROUP_ID", s);
- }
- catch (JMSException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void setJMSXGroupSequence(Message message, int i) {
- try {
- message.setIntProperty("JMSXGroupSeq", i);
- }
- catch (JMSException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void setJMSXDeliveryCount(Message message, long l) {
- try {
- message.setLongProperty("JMSXDeliveryCount", l);
- }
- catch (JMSException e) {
- throw new RuntimeException(e);
- }
- }
-
- public ServerJMSMessage wrapMessage(int messageType, ServerMessage wrapped, int deliveryCount) {
- switch (messageType) {
- case org.apache.activemq.artemis.api.core.Message.STREAM_TYPE:
- return new ServerJMSStreamMessage(wrapped, deliveryCount);
- case org.apache.activemq.artemis.api.core.Message.BYTES_TYPE:
- return new ServerJMSBytesMessage(wrapped, deliveryCount);
- case org.apache.activemq.artemis.api.core.Message.MAP_TYPE:
- return new ServerJMSMapMessage(wrapped, deliveryCount);
- case org.apache.activemq.artemis.api.core.Message.TEXT_TYPE:
- return new ServerJMSTextMessage(wrapped, deliveryCount);
- case org.apache.activemq.artemis.api.core.Message.OBJECT_TYPE:
- return new ServerJMSObjectMessage(wrapped, deliveryCount);
- default:
- return new ServerJMSMessage(wrapped, deliveryCount);
- }
- }
-
- @Override
- public String toAddress(Destination destination) {
- if (destination instanceof ActiveMQDestination) {
- return ((ActiveMQDestination) destination).getAddress();
- }
- return null;
- }
-
- private ServerMessageImpl newMessage(byte messageType) {
- ServerMessageImpl message = new ServerMessageImpl(serverGenerator.generateID(), 512);
- message.setType(messageType);
- ((ResetLimitWrappedActiveMQBuffer) message.getBodyBuffer()).setMessage(null);
- return message;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/ProtonMessageConverter.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/ProtonMessageConverter.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/ProtonMessageConverter.java
deleted file mode 100644
index 6b4e99b..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/ProtonMessageConverter.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.converter;
-
-import org.apache.activemq.artemis.core.client.ActiveMQClientLogger;
-import org.apache.activemq.artemis.core.protocol.proton.converter.message.AMQPNativeOutboundTransformer;
-import org.apache.activemq.artemis.core.protocol.proton.converter.message.EncodedMessage;
-import org.apache.activemq.artemis.core.protocol.proton.converter.message.InboundTransformer;
-import org.apache.activemq.artemis.core.protocol.proton.converter.message.JMSMappingInboundTransformer;
-import org.apache.activemq.artemis.core.protocol.proton.converter.jms.ServerJMSMessage;
-import org.apache.activemq.artemis.core.protocol.proton.converter.message.JMSMappingOutboundTransformer;
-import org.apache.activemq.artemis.core.server.ServerMessage;
-import org.apache.activemq.artemis.spi.core.protocol.MessageConverter;
-import org.apache.activemq.artemis.utils.IDGenerator;
-
-import javax.jms.BytesMessage;
-import java.io.IOException;
-
-public class ProtonMessageConverter implements MessageConverter {
-
- ActiveMQJMSVendor activeMQJMSVendor;
-
- private final String prefixVendor;
-
- public ProtonMessageConverter(IDGenerator idGenerator) {
- activeMQJMSVendor = new ActiveMQJMSVendor(idGenerator);
- inboundTransformer = new JMSMappingInboundTransformer(activeMQJMSVendor);
- outboundTransformer = new JMSMappingOutboundTransformer(activeMQJMSVendor);
- prefixVendor = outboundTransformer.getPrefixVendor();
- }
-
- private final InboundTransformer inboundTransformer;
- private final JMSMappingOutboundTransformer outboundTransformer;
-
- @Override
- public ServerMessage inbound(Object messageSource) throws Exception {
- ServerJMSMessage jmsMessage = inboundJMSType((EncodedMessage) messageSource);
-
- return (ServerMessage) jmsMessage.getInnerMessage();
- }
-
- /**
- * Just create the JMS Part of the inbound (for testing)
- *
- * @param messageSource
- * @return
- * @throws Exception https://issues.jboss.org/browse/ENTMQ-1560
- */
- public ServerJMSMessage inboundJMSType(EncodedMessage messageSource) throws Exception {
- EncodedMessage encodedMessageSource = messageSource;
- ServerJMSMessage transformedMessage = null;
-
- InboundTransformer transformer = inboundTransformer;
-
- while (transformer != null) {
- try {
- transformedMessage = (ServerJMSMessage) transformer.transform(encodedMessageSource);
- break;
- }
- catch (Exception e) {
- ActiveMQClientLogger.LOGGER.debug("Transform of message using [{}] transformer, failed" + inboundTransformer.getTransformerName());
- ActiveMQClientLogger.LOGGER.trace("Transformation error:", e);
-
- transformer = transformer.getFallbackTransformer();
- }
- }
-
- if (transformedMessage == null) {
- throw new IOException("Failed to transform incoming delivery, skipping.");
- }
-
- transformedMessage.encode();
-
- return transformedMessage;
- }
-
- @Override
- public Object outbound(ServerMessage messageOutbound, int deliveryCount) throws Exception {
- ServerJMSMessage jmsMessage = activeMQJMSVendor.wrapMessage(messageOutbound.getType(), messageOutbound, deliveryCount);
-
- jmsMessage.decode();
-
- if (jmsMessage.getBooleanProperty(prefixVendor + "NATIVE")) {
- if (jmsMessage instanceof BytesMessage) {
- return AMQPNativeOutboundTransformer.transform(outboundTransformer, (BytesMessage) jmsMessage);
- }
- else {
- return null;
- }
- }
- else {
- return outboundTransformer.convert(jmsMessage);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerDestination.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerDestination.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerDestination.java
deleted file mode 100644
index 0a8bb29..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerDestination.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.converter.jms;
-
-import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
-
-import javax.jms.JMSException;
-import javax.jms.Queue;
-
-/**
- * This is just here to avoid all the client checks we need with valid JMS destinations, protocol convertors don't need to
- * adhere to the jms. semantics.
- */
-public class ServerDestination extends ActiveMQDestination implements Queue {
- public ServerDestination(String name) {
- super(name, name, false, false, null);
- }
-
- @Override
- public String getQueueName() throws JMSException {
- return getName();
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSBytesMessage.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSBytesMessage.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSBytesMessage.java
deleted file mode 100644
index 990c7d7..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSBytesMessage.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.converter.jms;
-
-import javax.jms.BytesMessage;
-import javax.jms.JMSException;
-
-import org.apache.activemq.artemis.core.message.impl.MessageImpl;
-import org.apache.activemq.artemis.core.message.impl.MessageInternal;
-
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesMessageReset;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadBoolean;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadByte;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadBytes;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadChar;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadDouble;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadFloat;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadInt;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadLong;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadShort;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadUTF;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadUnsignedByte;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesReadUnsignedShort;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteBoolean;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteByte;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteBytes;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteChar;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteDouble;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteFloat;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteInt;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteLong;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteObject;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteShort;
-import static org.apache.activemq.artemis.reader.BytesMessageUtil.bytesWriteUTF;
-
-public class ServerJMSBytesMessage extends ServerJMSMessage implements BytesMessage {
-
- public ServerJMSBytesMessage(MessageInternal message, int deliveryCount) {
- super(message, deliveryCount);
- }
-
- @Override
- public long getBodyLength() throws JMSException {
- return message.getEndOfBodyPosition() - MessageImpl.BODY_OFFSET;
- }
-
- @Override
- public boolean readBoolean() throws JMSException {
- return bytesReadBoolean(getReadBodyBuffer());
- }
-
- @Override
- public byte readByte() throws JMSException {
- return bytesReadByte(getReadBodyBuffer());
- }
-
- @Override
- public int readUnsignedByte() throws JMSException {
- return bytesReadUnsignedByte(getReadBodyBuffer());
- }
-
- @Override
- public short readShort() throws JMSException {
- return bytesReadShort(getReadBodyBuffer());
- }
-
- @Override
- public int readUnsignedShort() throws JMSException {
- return bytesReadUnsignedShort(getReadBodyBuffer());
- }
-
- @Override
- public char readChar() throws JMSException {
- return bytesReadChar(getReadBodyBuffer());
- }
-
- @Override
- public int readInt() throws JMSException {
- return bytesReadInt(getReadBodyBuffer());
- }
-
- @Override
- public long readLong() throws JMSException {
- return bytesReadLong(getReadBodyBuffer());
- }
-
- @Override
- public float readFloat() throws JMSException {
- return bytesReadFloat(getReadBodyBuffer());
- }
-
- @Override
- public double readDouble() throws JMSException {
- return bytesReadDouble(getReadBodyBuffer());
- }
-
- @Override
- public String readUTF() throws JMSException {
- return bytesReadUTF(getReadBodyBuffer());
- }
-
- @Override
- public int readBytes(byte[] value) throws JMSException {
- return bytesReadBytes(getReadBodyBuffer(), value);
- }
-
- @Override
- public int readBytes(byte[] value, int length) throws JMSException {
- return bytesReadBytes(getReadBodyBuffer(), value, length);
- }
-
- @Override
- public void writeBoolean(boolean value) throws JMSException {
- bytesWriteBoolean(getWriteBodyBuffer(), value);
-
- }
-
- @Override
- public void writeByte(byte value) throws JMSException {
- bytesWriteByte(getWriteBodyBuffer(), value);
- }
-
- @Override
- public void writeShort(short value) throws JMSException {
- bytesWriteShort(getWriteBodyBuffer(), value);
- }
-
- @Override
- public void writeChar(char value) throws JMSException {
- bytesWriteChar(getWriteBodyBuffer(), value);
- }
-
- @Override
- public void writeInt(int value) throws JMSException {
- bytesWriteInt(getWriteBodyBuffer(), value);
- }
-
- @Override
- public void writeLong(long value) throws JMSException {
- bytesWriteLong(getWriteBodyBuffer(), value);
- }
-
- @Override
- public void writeFloat(float value) throws JMSException {
- bytesWriteFloat(getWriteBodyBuffer(), value);
- }
-
- @Override
- public void writeDouble(double value) throws JMSException {
- bytesWriteDouble(getWriteBodyBuffer(), value);
- }
-
- @Override
- public void writeUTF(String value) throws JMSException {
- bytesWriteUTF(getWriteBodyBuffer(), value);
- }
-
- @Override
- public void writeBytes(byte[] value) throws JMSException {
- bytesWriteBytes(getWriteBodyBuffer(), value);
- }
-
- @Override
- public void writeBytes(byte[] value, int offset, int length) throws JMSException {
- bytesWriteBytes(getWriteBodyBuffer(), value, offset, length);
- }
-
- @Override
- public void writeObject(Object value) throws JMSException {
- if (!bytesWriteObject(getWriteBodyBuffer(), value)) {
- throw new JMSException("Can't make conversion of " + value + " to any known type");
- }
- }
-
- @Override
- public void encode() throws Exception {
- super.encode();
- // this is to make sure we encode the body-length before it's persisted
- getBodyLength();
- }
-
- @Override
- public void decode() throws Exception {
- super.decode();
-
- }
-
- @Override
- public void reset() throws JMSException {
- bytesMessageReset(getReadBodyBuffer());
- bytesMessageReset(getWriteBodyBuffer());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSMapMessage.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSMapMessage.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSMapMessage.java
deleted file mode 100644
index 2083b84..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSMapMessage.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.converter.jms;
-
-import javax.jms.JMSException;
-import javax.jms.MapMessage;
-import javax.jms.MessageFormatException;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.activemq.artemis.api.core.ActiveMQPropertyConversionException;
-import org.apache.activemq.artemis.api.core.Message;
-import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.message.impl.MessageInternal;
-import org.apache.activemq.artemis.utils.TypedProperties;
-
-import static org.apache.activemq.artemis.reader.MapMessageUtil.readBodyMap;
-import static org.apache.activemq.artemis.reader.MapMessageUtil.writeBodyMap;
-
-/**
- * ActiveMQ Artemis implementation of a JMS MapMessage.
- */
-public final class ServerJMSMapMessage extends ServerJMSMessage implements MapMessage {
- // Constants -----------------------------------------------------
-
- public static final byte TYPE = Message.MAP_TYPE;
-
- // Attributes ----------------------------------------------------
-
- private final TypedProperties map = new TypedProperties();
-
- // Static --------------------------------------------------------
-
- // Constructors --------------------------------------------------
-
- /*
- * This constructor is used to construct messages prior to sending
- */
- public ServerJMSMapMessage(MessageInternal message, int deliveryCount) {
- super(message, deliveryCount);
-
- }
-
- // MapMessage implementation -------------------------------------
-
- @Override
- public void setBoolean(final String name, final boolean value) throws JMSException {
- map.putBooleanProperty(new SimpleString(name), value);
- }
-
- @Override
- public void setByte(final String name, final byte value) throws JMSException {
- map.putByteProperty(new SimpleString(name), value);
- }
-
- @Override
- public void setShort(final String name, final short value) throws JMSException {
- map.putShortProperty(new SimpleString(name), value);
- }
-
- @Override
- public void setChar(final String name, final char value) throws JMSException {
- map.putCharProperty(new SimpleString(name), value);
- }
-
- @Override
- public void setInt(final String name, final int value) throws JMSException {
- map.putIntProperty(new SimpleString(name), value);
- }
-
- @Override
- public void setLong(final String name, final long value) throws JMSException {
- map.putLongProperty(new SimpleString(name), value);
- }
-
- @Override
- public void setFloat(final String name, final float value) throws JMSException {
- map.putFloatProperty(new SimpleString(name), value);
- }
-
- @Override
- public void setDouble(final String name, final double value) throws JMSException {
- map.putDoubleProperty(new SimpleString(name), value);
- }
-
- @Override
- public void setString(final String name, final String value) throws JMSException {
- map.putSimpleStringProperty(new SimpleString(name), value == null ? null : new SimpleString(value));
- }
-
- @Override
- public void setBytes(final String name, final byte[] value) throws JMSException {
- map.putBytesProperty(new SimpleString(name), value);
- }
-
- @Override
- public void setBytes(final String name, final byte[] value, final int offset, final int length) throws JMSException {
- if (offset + length > value.length) {
- throw new JMSException("Invalid offset/length");
- }
- byte[] newBytes = new byte[length];
- System.arraycopy(value, offset, newBytes, 0, length);
- map.putBytesProperty(new SimpleString(name), newBytes);
- }
-
- @Override
- public void setObject(final String name, final Object value) throws JMSException {
- try {
- TypedProperties.setObjectProperty(new SimpleString(name), value, map);
- }
- catch (ActiveMQPropertyConversionException e) {
- throw new MessageFormatException(e.getMessage());
- }
- }
-
- @Override
- public boolean getBoolean(final String name) throws JMSException {
- try {
- return map.getBooleanProperty(new SimpleString(name));
- }
- catch (ActiveMQPropertyConversionException e) {
- throw new MessageFormatException(e.getMessage());
- }
- }
-
- @Override
- public byte getByte(final String name) throws JMSException {
- try {
- return map.getByteProperty(new SimpleString(name));
- }
- catch (ActiveMQPropertyConversionException e) {
- throw new MessageFormatException(e.getMessage());
- }
- }
-
- @Override
- public short getShort(final String name) throws JMSException {
- try {
- return map.getShortProperty(new SimpleString(name));
- }
- catch (ActiveMQPropertyConversionException e) {
- throw new MessageFormatException(e.getMessage());
- }
- }
-
- @Override
- public char getChar(final String name) throws JMSException {
- try {
- return map.getCharProperty(new SimpleString(name));
- }
- catch (ActiveMQPropertyConversionException e) {
- throw new MessageFormatException(e.getMessage());
- }
- }
-
- @Override
- public int getInt(final String name) throws JMSException {
- try {
- return map.getIntProperty(new SimpleString(name));
- }
- catch (ActiveMQPropertyConversionException e) {
- throw new MessageFormatException(e.getMessage());
- }
- }
-
- @Override
- public long getLong(final String name) throws JMSException {
- try {
- return map.getLongProperty(new SimpleString(name));
- }
- catch (ActiveMQPropertyConversionException e) {
- throw new MessageFormatException(e.getMessage());
- }
- }
-
- @Override
- public float getFloat(final String name) throws JMSException {
- try {
- return map.getFloatProperty(new SimpleString(name));
- }
- catch (ActiveMQPropertyConversionException e) {
- throw new MessageFormatException(e.getMessage());
- }
- }
-
- @Override
- public double getDouble(final String name) throws JMSException {
- try {
- return map.getDoubleProperty(new SimpleString(name));
- }
- catch (ActiveMQPropertyConversionException e) {
- throw new MessageFormatException(e.getMessage());
- }
- }
-
- @Override
- public String getString(final String name) throws JMSException {
- try {
- SimpleString str = map.getSimpleStringProperty(new SimpleString(name));
- if (str == null) {
- return null;
- }
- else {
- return str.toString();
- }
- }
- catch (ActiveMQPropertyConversionException e) {
- throw new MessageFormatException(e.getMessage());
- }
- }
-
- @Override
- public byte[] getBytes(final String name) throws JMSException {
- try {
- return map.getBytesProperty(new SimpleString(name));
- }
- catch (ActiveMQPropertyConversionException e) {
- throw new MessageFormatException(e.getMessage());
- }
- }
-
- @Override
- public Object getObject(final String name) throws JMSException {
- Object val = map.getProperty(new SimpleString(name));
-
- if (val instanceof SimpleString) {
- val = ((SimpleString) val).toString();
- }
-
- return val;
- }
-
- @Override
- public Enumeration getMapNames() throws JMSException {
- Set<SimpleString> simplePropNames = map.getPropertyNames();
- Set<String> propNames = new HashSet<>(simplePropNames.size());
-
- for (SimpleString str : simplePropNames) {
- propNames.add(str.toString());
- }
-
- return Collections.enumeration(propNames);
- }
-
- @Override
- public boolean itemExists(final String name) throws JMSException {
- return map.containsProperty(new SimpleString(name));
- }
-
- @Override
- public void clearBody() throws JMSException {
- super.clearBody();
-
- map.clear();
- }
-
- @Override
- public void encode() throws Exception {
- super.encode();
- writeBodyMap(getWriteBodyBuffer(), map);
- }
-
- @Override
- public void decode() throws Exception {
- super.decode();
- readBodyMap(getReadBodyBuffer(), map);
- }
-
- // Package protected ---------------------------------------------
-
- // Protected -----------------------------------------------------
-
- // Private -------------------------------------------------------
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSMessage.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSMessage.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSMessage.java
deleted file mode 100644
index 465539b..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSMessage.java
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.converter.jms;
-
-import javax.jms.DeliveryMode;
-import javax.jms.Destination;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import java.util.Collections;
-import java.util.Enumeration;
-
-import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
-import org.apache.activemq.artemis.api.core.ActiveMQException;
-import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.message.impl.MessageInternal;
-import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
-import org.apache.activemq.artemis.reader.MessageUtil;
-
-public class ServerJMSMessage implements Message {
-
- public static final String NATIVE_MESSAGE_ID = "NATIVE_MESSAGE_ID";
-
- protected final MessageInternal message;
-
- protected int deliveryCount;
-
- public MessageInternal getInnerMessage() {
- return message;
- }
-
- public ServerJMSMessage(MessageInternal message, int deliveryCount) {
- this.message = message;
- this.deliveryCount = deliveryCount;
- }
-
- private ActiveMQBuffer readBodyBuffer;
-
- /** When reading we use a protected copy so multi-threads can work fine */
- protected ActiveMQBuffer getReadBodyBuffer() {
- if (readBodyBuffer == null) {
- // to avoid clashes between multiple threads
- readBodyBuffer = message.getBodyBufferDuplicate();
- }
- return readBodyBuffer;
- }
-
- /** When writing on the conversion we use the buffer directly */
- protected ActiveMQBuffer getWriteBodyBuffer() {
- readBodyBuffer = null; // it invalidates this buffer if anything is written
- return message.getBodyBuffer();
- }
-
-
- @Override
- public final String getJMSMessageID() throws JMSException {
- if (message.containsProperty(NATIVE_MESSAGE_ID)) {
- return getStringProperty(NATIVE_MESSAGE_ID);
- }
- return null;
- }
-
- @Override
- public final void setJMSMessageID(String id) throws JMSException {
- if (id != null) {
- message.putStringProperty(NATIVE_MESSAGE_ID, id);
- }
- }
-
- @Override
- public final long getJMSTimestamp() throws JMSException {
- return message.getTimestamp();
- }
-
- @Override
- public final void setJMSTimestamp(long timestamp) throws JMSException {
- message.setTimestamp(timestamp);
- }
-
- @Override
- public final byte[] getJMSCorrelationIDAsBytes() throws JMSException {
- return MessageUtil.getJMSCorrelationIDAsBytes(message);
- }
-
- @Override
- public final void setJMSCorrelationIDAsBytes(byte[] correlationID) throws JMSException {
- try {
- MessageUtil.setJMSCorrelationIDAsBytes(message, correlationID);
- }
- catch (ActiveMQException e) {
- throw new JMSException(e.getMessage());
- }
- }
-
- @Override
- public final void setJMSCorrelationID(String correlationID) throws JMSException {
- MessageUtil.setJMSCorrelationID(message, correlationID);
- }
-
- @Override
- public final String getJMSCorrelationID() throws JMSException {
- return MessageUtil.getJMSCorrelationID(message);
- }
-
- @Override
- public final Destination getJMSReplyTo() throws JMSException {
- SimpleString reply = MessageUtil.getJMSReplyTo(message);
- if (reply != null) {
- return new ServerDestination(reply.toString());
- }
- else {
- return null;
- }
- }
-
- @Override
- public final void setJMSReplyTo(Destination replyTo) throws JMSException {
- MessageUtil.setJMSReplyTo(message, replyTo == null ? null : ((ActiveMQDestination) replyTo).getSimpleAddress());
-
- }
-
- @Override
- public final Destination getJMSDestination() throws JMSException {
- SimpleString sdest = message.getAddress();
-
- if (sdest == null) {
- return null;
- }
- else {
- return new ServerDestination(sdest.toString());
- }
- }
-
- @Override
- public final void setJMSDestination(Destination destination) throws JMSException {
- if (destination == null) {
- message.setAddress(null);
- }
- else {
- message.setAddress(((ActiveMQDestination) destination).getSimpleAddress());
- }
-
- }
-
- @Override
- public final int getJMSDeliveryMode() throws JMSException {
- return message.isDurable() ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT;
- }
-
- @Override
- public final void setJMSDeliveryMode(int deliveryMode) throws JMSException {
- if (deliveryMode == DeliveryMode.PERSISTENT) {
- message.setDurable(true);
- }
- else if (deliveryMode == DeliveryMode.NON_PERSISTENT) {
- message.setDurable(false);
- }
- else {
- throw new JMSException("Invalid mode " + deliveryMode);
- }
- }
-
- @Override
- public final boolean getJMSRedelivered() throws JMSException {
- return false;
- }
-
- @Override
- public final void setJMSRedelivered(boolean redelivered) throws JMSException {
- // no op
- }
-
- @Override
- public final String getJMSType() throws JMSException {
- return MessageUtil.getJMSType(message);
- }
-
- @Override
- public final void setJMSType(String type) throws JMSException {
- MessageUtil.setJMSType(message, type);
- }
-
- @Override
- public final long getJMSExpiration() throws JMSException {
- return message.getExpiration();
- }
-
- @Override
- public final void setJMSExpiration(long expiration) throws JMSException {
- message.setExpiration(expiration);
- }
-
- @Override
- public final long getJMSDeliveryTime() throws JMSException {
- // no op
- return 0;
- }
-
- @Override
- public final void setJMSDeliveryTime(long deliveryTime) throws JMSException {
- // no op
- }
-
- @Override
- public final int getJMSPriority() throws JMSException {
- return message.getPriority();
- }
-
- @Override
- public final void setJMSPriority(int priority) throws JMSException {
- message.setPriority((byte) priority);
- }
-
- @Override
- public final void clearProperties() throws JMSException {
- MessageUtil.clearProperties(message);
-
- }
-
- @Override
- public final boolean propertyExists(String name) throws JMSException {
- return MessageUtil.propertyExists(message, name);
- }
-
- @Override
- public final boolean getBooleanProperty(String name) throws JMSException {
- return message.getBooleanProperty(name);
- }
-
- @Override
- public final byte getByteProperty(String name) throws JMSException {
- return message.getByteProperty(name);
- }
-
- @Override
- public final short getShortProperty(String name) throws JMSException {
- return message.getShortProperty(name);
- }
-
- @Override
- public final int getIntProperty(String name) throws JMSException {
- if (MessageUtil.JMSXDELIVERYCOUNT.equals(name)) {
- return deliveryCount;
- }
-
- return message.getIntProperty(name);
- }
-
- @Override
- public final long getLongProperty(String name) throws JMSException {
- if (MessageUtil.JMSXDELIVERYCOUNT.equals(name)) {
- return deliveryCount;
- }
-
- return message.getLongProperty(name);
- }
-
- @Override
- public final float getFloatProperty(String name) throws JMSException {
- return message.getFloatProperty(name);
- }
-
- @Override
- public final double getDoubleProperty(String name) throws JMSException {
- return message.getDoubleProperty(name);
- }
-
- @Override
- public final String getStringProperty(String name) throws JMSException {
- if (MessageUtil.JMSXDELIVERYCOUNT.equals(name)) {
- return String.valueOf(deliveryCount);
- }
-
- return message.getStringProperty(name);
- }
-
- @Override
- public final Object getObjectProperty(String name) throws JMSException {
- Object val = message.getObjectProperty(name);
- if (val instanceof SimpleString) {
- val = ((SimpleString) val).toString();
- }
- return val;
- }
-
- @Override
- public final Enumeration getPropertyNames() throws JMSException {
- return Collections.enumeration(MessageUtil.getPropertyNames(message));
- }
-
- @Override
- public final void setBooleanProperty(String name, boolean value) throws JMSException {
- message.putBooleanProperty(name, value);
- }
-
- @Override
- public final void setByteProperty(String name, byte value) throws JMSException {
- message.putByteProperty(name, value);
- }
-
- @Override
- public final void setShortProperty(String name, short value) throws JMSException {
- message.putShortProperty(name, value);
- }
-
- @Override
- public final void setIntProperty(String name, int value) throws JMSException {
- message.putIntProperty(name, value);
- }
-
- @Override
- public final void setLongProperty(String name, long value) throws JMSException {
- message.putLongProperty(name, value);
- }
-
- @Override
- public final void setFloatProperty(String name, float value) throws JMSException {
- message.putFloatProperty(name, value);
- }
-
- @Override
- public final void setDoubleProperty(String name, double value) throws JMSException {
- message.putDoubleProperty(name, value);
- }
-
- @Override
- public final void setStringProperty(String name, String value) throws JMSException {
- message.putStringProperty(name, value);
- }
-
- @Override
- public final void setObjectProperty(String name, Object value) throws JMSException {
- message.putObjectProperty(name, value);
- }
-
- @Override
- public final void acknowledge() throws JMSException {
- // no op
- }
-
- @Override
- public void clearBody() throws JMSException {
- message.getBodyBuffer().clear();
- }
-
- @Override
- public final <T> T getBody(Class<T> c) throws JMSException {
- // no op.. jms2 not used on the conversion
- return null;
- }
-
- /**
- * Encode the body into the internal message
- */
- public void encode() throws Exception {
- message.getBodyBuffer().resetReaderIndex();
- }
-
- public void decode() throws Exception {
- message.getBodyBuffer().resetReaderIndex();
- }
-
- @Override
- public final boolean isBodyAssignableTo(Class c) throws JMSException {
- // no op.. jms2 not used on the conversion
- return false;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSObjectMessage.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSObjectMessage.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSObjectMessage.java
deleted file mode 100644
index fb42993..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSObjectMessage.java
+++ /dev/null
@@ -1,79 +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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.converter.jms;
-
-import org.apache.activemq.artemis.api.core.Message;
-import org.apache.activemq.artemis.core.message.impl.MessageInternal;
-import org.apache.activemq.artemis.utils.ObjectInputStreamWithClassLoader;
-
-import javax.jms.JMSException;
-import javax.jms.ObjectMessage;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-
-
-public class ServerJMSObjectMessage extends ServerJMSMessage implements ObjectMessage {
- private static final String DEFAULT_WHITELIST;
- private static final String DEFAULT_BLACKLIST;
-
- static {
- DEFAULT_WHITELIST = System.getProperty(ObjectInputStreamWithClassLoader.WHITELIST_PROPERTY,
- "java.lang,java.math,javax.security,java.util,org.apache.activemq,org.apache.qpid.proton.amqp");
-
- DEFAULT_BLACKLIST = System.getProperty(ObjectInputStreamWithClassLoader.BLACKLIST_PROPERTY, null);
- }
- public static final byte TYPE = Message.STREAM_TYPE;
-
- private Serializable object;
-
- public ServerJMSObjectMessage(MessageInternal message, int deliveryCount) {
- super(message, deliveryCount);
- }
-
- @Override
- public void setObject(Serializable object) throws JMSException {
- this.object = object;
- }
-
- @Override
- public Serializable getObject() throws JMSException {
- return object;
- }
-
- @Override
- public void encode() throws Exception {
- super.encode();
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- ObjectOutputStream ous = new ObjectOutputStream(out);
- ous.writeObject(object);
- getInnerMessage().getBodyBuffer().writeBytes(out.toByteArray());
- }
-
- @Override
- public void decode() throws Exception {
- super.decode();
- int size = getInnerMessage().getBodyBuffer().readableBytes();
- byte[] bytes = new byte[size];
- getInnerMessage().getBodyBuffer().readBytes(bytes);
- ObjectInputStreamWithClassLoader ois = new ObjectInputStreamWithClassLoader(new ByteArrayInputStream(bytes));
- ois.setWhiteList(DEFAULT_WHITELIST);
- ois.setBlackList(DEFAULT_BLACKLIST);
- object = (Serializable) ois.readObject();
- }
-}
[13/15] activemq-artemis git commit: ARTEMIS-751 Simplification of
the AMQP implementation
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSStreamMessage.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSStreamMessage.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSStreamMessage.java
deleted file mode 100644
index 492ae0a..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSStreamMessage.java
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.converter.jms;
-
-import javax.jms.JMSException;
-import javax.jms.MessageEOFException;
-import javax.jms.MessageFormatException;
-import javax.jms.StreamMessage;
-
-import org.apache.activemq.artemis.api.core.Message;
-import org.apache.activemq.artemis.api.core.Pair;
-import org.apache.activemq.artemis.core.message.impl.MessageInternal;
-import org.apache.activemq.artemis.utils.DataConstants;
-
-import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadBoolean;
-import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadByte;
-import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadBytes;
-import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadChar;
-import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadDouble;
-import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadFloat;
-import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadInteger;
-import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadLong;
-import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadObject;
-import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadShort;
-import static org.apache.activemq.artemis.reader.StreamMessageUtil.streamReadString;
-
-public final class ServerJMSStreamMessage extends ServerJMSMessage implements StreamMessage {
-
- public static final byte TYPE = Message.STREAM_TYPE;
-
- private int bodyLength = 0;
-
- public ServerJMSStreamMessage(MessageInternal message, int deliveryCount) {
- super(message, deliveryCount);
- }
-
- // StreamMessage implementation ----------------------------------
-
- @Override
- public boolean readBoolean() throws JMSException {
-
- try {
- return streamReadBoolean(getReadBodyBuffer());
- }
- catch (IllegalStateException e) {
- throw new MessageFormatException(e.getMessage());
- }
- catch (IndexOutOfBoundsException e) {
- throw new MessageEOFException("");
- }
- }
-
- @Override
- public byte readByte() throws JMSException {
- try {
- return streamReadByte(getReadBodyBuffer());
- }
- catch (IllegalStateException e) {
- throw new MessageFormatException(e.getMessage());
- }
- catch (IndexOutOfBoundsException e) {
- throw new MessageEOFException("");
- }
- }
-
- @Override
- public short readShort() throws JMSException {
-
- try {
- return streamReadShort(getReadBodyBuffer());
- }
- catch (IllegalStateException e) {
- throw new MessageFormatException(e.getMessage());
- }
- catch (IndexOutOfBoundsException e) {
- throw new MessageEOFException("");
- }
- }
-
- @Override
- public char readChar() throws JMSException {
-
- try {
- return streamReadChar(getReadBodyBuffer());
- }
- catch (IllegalStateException e) {
- throw new MessageFormatException(e.getMessage());
- }
- catch (IndexOutOfBoundsException e) {
- throw new MessageEOFException("");
- }
- }
-
- @Override
- public int readInt() throws JMSException {
-
- try {
- return streamReadInteger(getReadBodyBuffer());
- }
- catch (IllegalStateException e) {
- throw new MessageFormatException(e.getMessage());
- }
- catch (IndexOutOfBoundsException e) {
- throw new MessageEOFException("");
- }
- }
-
- @Override
- public long readLong() throws JMSException {
-
- try {
- return streamReadLong(getReadBodyBuffer());
- }
- catch (IllegalStateException e) {
- throw new MessageFormatException(e.getMessage());
- }
- catch (IndexOutOfBoundsException e) {
- throw new MessageEOFException("");
- }
- }
-
- @Override
- public float readFloat() throws JMSException {
-
- try {
- return streamReadFloat(getReadBodyBuffer());
- }
- catch (IllegalStateException e) {
- throw new MessageFormatException(e.getMessage());
- }
- catch (IndexOutOfBoundsException e) {
- throw new MessageEOFException("");
- }
- }
-
- @Override
- public double readDouble() throws JMSException {
-
- try {
- return streamReadDouble(getReadBodyBuffer());
- }
- catch (IllegalStateException e) {
- throw new MessageFormatException(e.getMessage());
- }
- catch (IndexOutOfBoundsException e) {
- throw new MessageEOFException("");
- }
- }
-
- @Override
- public String readString() throws JMSException {
-
- try {
- return streamReadString(getReadBodyBuffer());
- }
- catch (IllegalStateException e) {
- throw new MessageFormatException(e.getMessage());
- }
- catch (IndexOutOfBoundsException e) {
- throw new MessageEOFException("");
- }
- }
-
- /**
- * len here is used to control how many more bytes to read
- */
- private int len = 0;
-
- @Override
- public int readBytes(final byte[] value) throws JMSException {
-
- try {
- Pair<Integer, Integer> pairRead = streamReadBytes(getReadBodyBuffer(), len, value);
-
- len = pairRead.getA();
- return pairRead.getB();
- }
- catch (IllegalStateException e) {
- throw new MessageFormatException(e.getMessage());
- }
- catch (IndexOutOfBoundsException e) {
- throw new MessageEOFException("");
- }
- }
-
- @Override
- public Object readObject() throws JMSException {
-
- if (getReadBodyBuffer().readerIndex() >= message.getEndOfBodyPosition()) {
- throw new MessageEOFException("");
- }
- try {
- return streamReadObject(getReadBodyBuffer());
- }
- catch (IllegalStateException e) {
- throw new MessageFormatException(e.getMessage());
- }
- catch (IndexOutOfBoundsException e) {
- throw new MessageEOFException("");
- }
- }
-
- @Override
- public void writeBoolean(final boolean value) throws JMSException {
-
- getWriteBodyBuffer().writeByte(DataConstants.BOOLEAN);
- getWriteBodyBuffer().writeBoolean(value);
- }
-
- @Override
- public void writeByte(final byte value) throws JMSException {
-
- getWriteBodyBuffer().writeByte(DataConstants.BYTE);
- getWriteBodyBuffer().writeByte(value);
- }
-
- @Override
- public void writeShort(final short value) throws JMSException {
-
- getWriteBodyBuffer().writeByte(DataConstants.SHORT);
- getWriteBodyBuffer().writeShort(value);
- }
-
- @Override
- public void writeChar(final char value) throws JMSException {
-
- getWriteBodyBuffer().writeByte(DataConstants.CHAR);
- getWriteBodyBuffer().writeShort((short) value);
- }
-
- @Override
- public void writeInt(final int value) throws JMSException {
-
- getWriteBodyBuffer().writeByte(DataConstants.INT);
- getWriteBodyBuffer().writeInt(value);
- }
-
- @Override
- public void writeLong(final long value) throws JMSException {
-
- getWriteBodyBuffer().writeByte(DataConstants.LONG);
- getWriteBodyBuffer().writeLong(value);
- }
-
- @Override
- public void writeFloat(final float value) throws JMSException {
-
- getWriteBodyBuffer().writeByte(DataConstants.FLOAT);
- getWriteBodyBuffer().writeInt(Float.floatToIntBits(value));
- }
-
- @Override
- public void writeDouble(final double value) throws JMSException {
-
- getWriteBodyBuffer().writeByte(DataConstants.DOUBLE);
- getWriteBodyBuffer().writeLong(Double.doubleToLongBits(value));
- }
-
- @Override
- public void writeString(final String value) throws JMSException {
-
- getWriteBodyBuffer().writeByte(DataConstants.STRING);
- getWriteBodyBuffer().writeNullableString(value);
- }
-
- @Override
- public void writeBytes(final byte[] value) throws JMSException {
-
- getWriteBodyBuffer().writeByte(DataConstants.BYTES);
- getWriteBodyBuffer().writeInt(value.length);
- getWriteBodyBuffer().writeBytes(value);
- }
-
- @Override
- public void writeBytes(final byte[] value, final int offset, final int length) throws JMSException {
-
- getWriteBodyBuffer().writeByte(DataConstants.BYTES);
- getWriteBodyBuffer().writeInt(length);
- getWriteBodyBuffer().writeBytes(value, offset, length);
- }
-
- @Override
- public void writeObject(final Object value) throws JMSException {
- if (value instanceof String) {
- writeString((String) value);
- }
- else if (value instanceof Boolean) {
- writeBoolean((Boolean) value);
- }
- else if (value instanceof Byte) {
- writeByte((Byte) value);
- }
- else if (value instanceof Short) {
- writeShort((Short) value);
- }
- else if (value instanceof Integer) {
- writeInt((Integer) value);
- }
- else if (value instanceof Long) {
- writeLong((Long) value);
- }
- else if (value instanceof Float) {
- writeFloat((Float) value);
- }
- else if (value instanceof Double) {
- writeDouble((Double) value);
- }
- else if (value instanceof byte[]) {
- writeBytes((byte[]) value);
- }
- else if (value instanceof Character) {
- writeChar((Character) value);
- }
- else if (value == null) {
- writeString(null);
- }
- else {
- throw new MessageFormatException("Invalid object type: " + value.getClass());
- }
- }
-
- @Override
- public void reset() throws JMSException {
- getWriteBodyBuffer().resetReaderIndex();
- }
-
- // ActiveMQRAMessage overrides ----------------------------------------
-
- @Override
- public void clearBody() throws JMSException {
- super.clearBody();
-
- getWriteBodyBuffer().clear();
- }
-
- @Override
- public void decode() throws Exception {
- super.decode();
- }
-
- /**
- * Encode the body into the internal message
- */
- @Override
- public void encode() throws Exception {
- super.encode();
- bodyLength = message.getEndOfBodyPosition();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSTextMessage.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSTextMessage.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSTextMessage.java
deleted file mode 100644
index a055c8e..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/jms/ServerJMSTextMessage.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.converter.jms;
-
-import javax.jms.JMSException;
-import javax.jms.TextMessage;
-
-import org.apache.activemq.artemis.api.core.Message;
-import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.message.impl.MessageInternal;
-
-import static org.apache.activemq.artemis.reader.TextMessageUtil.readBodyText;
-import static org.apache.activemq.artemis.reader.TextMessageUtil.writeBodyText;
-
-/**
- * ActiveMQ Artemis implementation of a JMS TextMessage.
- * <br>
- * This class was ported from SpyTextMessage in JBossMQ.
- */
-public class ServerJMSTextMessage extends ServerJMSMessage implements TextMessage {
- // Constants -----------------------------------------------------
-
- public static final byte TYPE = Message.TEXT_TYPE;
-
- // Attributes ----------------------------------------------------
-
- // We cache it locally - it's more performant to cache as a SimpleString, the AbstractChannelBuffer write
- // methods are more efficient for a SimpleString
- private SimpleString text;
-
- // Static --------------------------------------------------------
-
- // Constructors --------------------------------------------------
-
- /*
- * This constructor is used to construct messages prior to sending
- */
- public ServerJMSTextMessage(MessageInternal message, int deliveryCount) {
- super(message, deliveryCount);
-
- }
- // TextMessage implementation ------------------------------------
-
- @Override
- public void setText(final String text) throws JMSException {
- if (text != null) {
- this.text = new SimpleString(text);
- }
- else {
- this.text = null;
- }
-
- writeBodyText(getWriteBodyBuffer(), this.text);
- }
-
- @Override
- public String getText() {
- if (text != null) {
- return text.toString();
- }
- else {
- return null;
- }
- }
-
- @Override
- public void clearBody() throws JMSException {
- super.clearBody();
-
- text = null;
- }
-
- @Override
- public void encode() throws Exception {
- super.encode();
- writeBodyText(getWriteBodyBuffer(), text);
- }
-
- @Override
- public void decode() throws Exception {
- super.decode();
- text = readBodyText(getReadBodyBuffer());
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/AMQPMessageIdHelper.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/AMQPMessageIdHelper.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/AMQPMessageIdHelper.java
deleted file mode 100644
index 479c1f7..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/AMQPMessageIdHelper.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.activemq.artemis.core.protocol.proton.converter.message;
-
-import org.apache.qpid.proton.amqp.Binary;
-import org.apache.qpid.proton.amqp.UnsignedLong;
-import org.proton.plug.exceptions.ActiveMQAMQPIllegalStateException;
-
-import java.nio.ByteBuffer;
-import java.util.UUID;
-
-/**
- * Helper class for identifying and converting message-id and correlation-id values between
- * the AMQP types and the Strings values used by JMS.
- * <p>
- * <p>AMQP messages allow for 4 types of message-id/correlation-id: message-id-string, message-id-binary,
- * message-id-uuid, or message-id-ulong. In order to accept or return a string representation of these
- * for interoperability with other AMQP clients, the following encoding can be used after removing or
- * before adding the "ID:" prefix used for a JMSMessageID value:<br>
- * <p>
- * {@literal "AMQP_BINARY:<hex representation of binary content>"}<br>
- * {@literal "AMQP_UUID:<string representation of uuid>"}<br>
- * {@literal "AMQP_ULONG:<string representation of ulong>"}<br>
- * {@literal "AMQP_STRING:<string>"}<br>
- * <p>
- * <p>The AMQP_STRING encoding exists only for escaping message-id-string values that happen to begin
- * with one of the encoding prefixes (including AMQP_STRING itself). It MUST NOT be used otherwise.
- * <p>
- * <p>When provided a string for conversion which attempts to identify itself as an encoded binary, uuid, or
- * ulong but can't be converted into the indicated format, an exception will be thrown.
- */
-public class AMQPMessageIdHelper {
-
- public static final AMQPMessageIdHelper INSTANCE = new AMQPMessageIdHelper();
-
- public static final String AMQP_STRING_PREFIX = "AMQP_STRING:";
- public static final String AMQP_UUID_PREFIX = "AMQP_UUID:";
- public static final String AMQP_ULONG_PREFIX = "AMQP_ULONG:";
- public static final String AMQP_BINARY_PREFIX = "AMQP_BINARY:";
-
- private static final int AMQP_UUID_PREFIX_LENGTH = AMQP_UUID_PREFIX.length();
- private static final int AMQP_ULONG_PREFIX_LENGTH = AMQP_ULONG_PREFIX.length();
- private static final int AMQP_STRING_PREFIX_LENGTH = AMQP_STRING_PREFIX.length();
- private static final int AMQP_BINARY_PREFIX_LENGTH = AMQP_BINARY_PREFIX.length();
- private static final char[] HEX_CHARS = "0123456789ABCDEF".toCharArray();
-
- /**
- * Takes the provided AMQP messageId style object, and convert it to a base string.
- * Encodes type information as a prefix where necessary to convey or escape the type
- * of the provided object.
- *
- * @param messageId the raw messageId object to process
- * @return the base string to be used in creating the actual id.
- */
- public String toBaseMessageIdString(Object messageId) {
- if (messageId == null) {
- return null;
- }
- else if (messageId instanceof String) {
- String stringId = (String) messageId;
-
- // If the given string has a type encoding prefix,
- // we need to escape it as an encoded string (even if
- // the existing encoding prefix was also for string)
- if (hasTypeEncodingPrefix(stringId)) {
- return AMQP_STRING_PREFIX + stringId;
- }
- else {
- return stringId;
- }
- }
- else if (messageId instanceof UUID) {
- return AMQP_UUID_PREFIX + messageId.toString();
- }
- else if (messageId instanceof UnsignedLong) {
- return AMQP_ULONG_PREFIX + messageId.toString();
- }
- else if (messageId instanceof Binary) {
- ByteBuffer dup = ((Binary) messageId).asByteBuffer();
-
- byte[] bytes = new byte[dup.remaining()];
- dup.get(bytes);
-
- String hex = convertBinaryToHexString(bytes);
-
- return AMQP_BINARY_PREFIX + hex;
- }
- else {
- throw new IllegalArgumentException("Unsupported type provided: " + messageId.getClass());
- }
- }
-
- /**
- * Takes the provided base id string and return the appropriate amqp messageId style object.
- * Converts the type based on any relevant encoding information found as a prefix.
- *
- * @param baseId the object to be converted to an AMQP MessageId value.
- * @return the AMQP messageId style object
- * @throws ActiveMQAMQPIllegalStateException if the provided baseId String indicates an encoded type but can't be converted to that type.
- */
- public Object toIdObject(String baseId) throws ActiveMQAMQPIllegalStateException {
- if (baseId == null) {
- return null;
- }
-
- try {
- if (hasAmqpUuidPrefix(baseId)) {
- String uuidString = strip(baseId, AMQP_UUID_PREFIX_LENGTH);
- return UUID.fromString(uuidString);
- }
- else if (hasAmqpUlongPrefix(baseId)) {
- String longString = strip(baseId, AMQP_ULONG_PREFIX_LENGTH);
- return UnsignedLong.valueOf(longString);
- }
- else if (hasAmqpStringPrefix(baseId)) {
- return strip(baseId, AMQP_STRING_PREFIX_LENGTH);
- }
- else if (hasAmqpBinaryPrefix(baseId)) {
- String hexString = strip(baseId, AMQP_BINARY_PREFIX_LENGTH);
- byte[] bytes = convertHexStringToBinary(hexString);
- return new Binary(bytes);
- }
- else {
- // We have a string without any type prefix, transmit it as-is.
- return baseId;
- }
- }
- catch (IllegalArgumentException e) {
- throw new ActiveMQAMQPIllegalStateException("Unable to convert ID value");
- }
- }
-
- /**
- * Convert the provided hex-string into a binary representation where each byte represents
- * two characters of the hex string.
- * <p>
- * The hex characters may be upper or lower case.
- *
- * @param hexString string to convert to a binary value.
- * @return a byte array containing the binary representation
- * @throws IllegalArgumentException if the provided String is a non-even length or contains
- * non-hex characters
- */
- public byte[] convertHexStringToBinary(String hexString) throws IllegalArgumentException {
- int length = hexString.length();
-
- // As each byte needs two characters in the hex encoding, the string must be an even length.
- if (length % 2 != 0) {
- throw new IllegalArgumentException("The provided hex String must be an even length, but was of length " + length + ": " + hexString);
- }
-
- byte[] binary = new byte[length / 2];
-
- for (int i = 0; i < length; i += 2) {
- char highBitsChar = hexString.charAt(i);
- char lowBitsChar = hexString.charAt(i + 1);
-
- int highBits = hexCharToInt(highBitsChar, hexString) << 4;
- int lowBits = hexCharToInt(lowBitsChar, hexString);
-
- binary[i / 2] = (byte) (highBits + lowBits);
- }
-
- return binary;
- }
-
- /**
- * Convert the provided binary into a hex-string representation where each character
- * represents 4 bits of the provided binary, i.e each byte requires two characters.
- * <p>
- * The returned hex characters are upper-case.
- *
- * @param bytes the binary value to convert to a hex String instance.
- * @return a String containing a hex representation of the bytes
- */
- public String convertBinaryToHexString(byte[] bytes) {
- // Each byte is represented as 2 chars
- StringBuilder builder = new StringBuilder(bytes.length * 2);
-
- for (byte b : bytes) {
- // The byte will be expanded to int before shifting, replicating the
- // sign bit, so mask everything beyond the first 4 bits afterwards
- int highBitsInt = (b >> 4) & 0xF;
- // We only want the first 4 bits
- int lowBitsInt = b & 0xF;
-
- builder.append(HEX_CHARS[highBitsInt]);
- builder.append(HEX_CHARS[lowBitsInt]);
- }
-
- return builder.toString();
- }
-
- //----- Internal implementation ------------------------------------------//
-
- private boolean hasTypeEncodingPrefix(String stringId) {
- return hasAmqpBinaryPrefix(stringId) || hasAmqpUuidPrefix(stringId) ||
- hasAmqpUlongPrefix(stringId) || hasAmqpStringPrefix(stringId);
- }
-
- private boolean hasAmqpStringPrefix(String stringId) {
- return stringId.startsWith(AMQP_STRING_PREFIX);
- }
-
- private boolean hasAmqpUlongPrefix(String stringId) {
- return stringId.startsWith(AMQP_ULONG_PREFIX);
- }
-
- private boolean hasAmqpUuidPrefix(String stringId) {
- return stringId.startsWith(AMQP_UUID_PREFIX);
- }
-
- private boolean hasAmqpBinaryPrefix(String stringId) {
- return stringId.startsWith(AMQP_BINARY_PREFIX);
- }
-
- private String strip(String id, int numChars) {
- return id.substring(numChars);
- }
-
- private int hexCharToInt(char ch, String orig) throws IllegalArgumentException {
- if (ch >= '0' && ch <= '9') {
- // subtract '0' to get difference in position as an int
- return ch - '0';
- }
- else if (ch >= 'A' && ch <= 'F') {
- // subtract 'A' to get difference in position as an int
- // and then add 10 for the offset of 'A'
- return ch - 'A' + 10;
- }
- else if (ch >= 'a' && ch <= 'f') {
- // subtract 'a' to get difference in position as an int
- // and then add 10 for the offset of 'a'
- return ch - 'a' + 10;
- }
-
- throw new IllegalArgumentException("The provided hex string contains non-hex character '" + ch + "': " + orig);
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/AMQPMessageTypes.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/AMQPMessageTypes.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/AMQPMessageTypes.java
deleted file mode 100644
index 2e67c4d..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/AMQPMessageTypes.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.converter.message;
-
-public class AMQPMessageTypes {
- public static final String AMQP_TYPE_KEY = "amqp:type";
-
- public static final String AMQP_SEQUENCE = "amqp:sequence";
-
- public static final String AMQP_LIST = "amqp:list";
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/AMQPNativeInboundTransformer.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/AMQPNativeInboundTransformer.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/AMQPNativeInboundTransformer.java
deleted file mode 100644
index e194e6b..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/AMQPNativeInboundTransformer.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.converter.message;
-
-import javax.jms.Message;
-
-public class AMQPNativeInboundTransformer extends AMQPRawInboundTransformer {
-
- public AMQPNativeInboundTransformer(JMSVendor vendor) {
- super(vendor);
- }
-
- @Override
- public String getTransformerName() {
- return TRANSFORMER_NATIVE;
- }
-
- @Override
- public InboundTransformer getFallbackTransformer() {
- return new AMQPRawInboundTransformer(getVendor());
- }
-
- @Override
- public Message transform(EncodedMessage amqpMessage) throws Exception {
- org.apache.qpid.proton.message.Message amqp = amqpMessage.decode();
-
- Message rc = super.transform(amqpMessage);
-
- populateMessage(rc, amqp);
- return rc;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/AMQPNativeOutboundTransformer.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/AMQPNativeOutboundTransformer.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/AMQPNativeOutboundTransformer.java
deleted file mode 100644
index fa7f206..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/AMQPNativeOutboundTransformer.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.converter.message;
-
-import org.apache.qpid.proton.amqp.UnsignedInteger;
-import org.apache.qpid.proton.amqp.messaging.Header;
-import org.apache.qpid.proton.message.ProtonJMessage;
-
-import javax.jms.BytesMessage;
-import javax.jms.JMSException;
-
-public class AMQPNativeOutboundTransformer extends OutboundTransformer {
-
- public AMQPNativeOutboundTransformer(JMSVendor vendor) {
- super(vendor);
- }
-
- public static ProtonJMessage transform(OutboundTransformer options, BytesMessage msg) throws JMSException {
- byte[] data = new byte[(int) msg.getBodyLength()];
- msg.readBytes(data);
- msg.reset();
- int count = msg.getIntProperty("JMSXDeliveryCount");
-
- // decode...
- ProtonJMessage amqp = (ProtonJMessage) org.apache.qpid.proton.message.Message.Factory.create();
- int offset = 0;
- int len = data.length;
- while (len > 0) {
- final int decoded = amqp.decode(data, offset, len);
- assert decoded > 0 : "Make progress decoding the message";
- offset += decoded;
- len -= decoded;
- }
-
- // Update the DeliveryCount header...
- // The AMQP delivery-count field only includes prior failed delivery attempts,
- // whereas JMSXDeliveryCount includes the first/current delivery attempt. Subtract 1.
- if (amqp.getHeader() == null) {
- amqp.setHeader(new Header());
- }
-
- amqp.getHeader().setDeliveryCount(new UnsignedInteger(count - 1));
-
- return amqp;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/AMQPRawInboundTransformer.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/AMQPRawInboundTransformer.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/AMQPRawInboundTransformer.java
deleted file mode 100644
index fd9540d..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/AMQPRawInboundTransformer.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.converter.message;
-
-import javax.jms.BytesMessage;
-import javax.jms.DeliveryMode;
-import javax.jms.Message;
-
-public class AMQPRawInboundTransformer extends InboundTransformer {
-
- public AMQPRawInboundTransformer(JMSVendor vendor) {
- super(vendor);
- }
-
- @Override
- public String getTransformerName() {
- return TRANSFORMER_RAW;
- }
-
- @Override
- public InboundTransformer getFallbackTransformer() {
- return null; // No fallback from full raw transform
- }
-
- @Override
- public Message transform(EncodedMessage amqpMessage) throws Exception {
- BytesMessage rc = vendor.createBytesMessage();
- rc.writeBytes(amqpMessage.getArray(), amqpMessage.getArrayOffset(), amqpMessage.getLength());
-
- // We cannot decode the message headers to check so err on the side of caution
- // and mark all messages as persistent.
- rc.setJMSDeliveryMode(DeliveryMode.PERSISTENT);
- rc.setJMSPriority(defaultPriority);
-
- final long now = System.currentTimeMillis();
- rc.setJMSTimestamp(now);
- if (defaultTtl > 0) {
- rc.setJMSExpiration(now + defaultTtl);
- }
-
- rc.setLongProperty(prefixVendor + "MESSAGE_FORMAT", amqpMessage.getMessageFormat());
- rc.setBooleanProperty(prefixVendor + "NATIVE", true);
-
- return rc;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/EncodedMessage.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/EncodedMessage.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/EncodedMessage.java
deleted file mode 100644
index 2857c17..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/EncodedMessage.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.converter.message;
-
-import org.apache.qpid.proton.amqp.Binary;
-import org.apache.qpid.proton.message.Message;
-
-public class EncodedMessage {
-
- private final Binary data;
- final long messageFormat;
-
- public EncodedMessage(long messageFormat, byte[] data, int offset, int length) {
- this.data = new Binary(data, offset, length);
- this.messageFormat = messageFormat;
- }
-
- public long getMessageFormat() {
- return messageFormat;
- }
-
- public Message decode() throws Exception {
- Message amqp = Message.Factory.create();
-
- int offset = getArrayOffset();
- int len = getLength();
- while (len > 0) {
- final int decoded = amqp.decode(getArray(), offset, len);
- assert decoded > 0 : "Make progress decoding the message";
- offset += decoded;
- len -= decoded;
- }
-
- return amqp;
- }
-
- public int getLength() {
- return data.getLength();
- }
-
- public int getArrayOffset() {
- return data.getArrayOffset();
- }
-
- public byte[] getArray() {
- return data.getArray();
- }
-
- @Override
- public String toString() {
- return data.toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/InboundTransformer.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/InboundTransformer.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/InboundTransformer.java
deleted file mode 100644
index a437e68..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/InboundTransformer.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.converter.message;
-
-import org.apache.qpid.proton.amqp.Binary;
-import org.apache.qpid.proton.amqp.Decimal128;
-import org.apache.qpid.proton.amqp.Decimal32;
-import org.apache.qpid.proton.amqp.Decimal64;
-import org.apache.qpid.proton.amqp.Symbol;
-import org.apache.qpid.proton.amqp.UnsignedByte;
-import org.apache.qpid.proton.amqp.UnsignedInteger;
-import org.apache.qpid.proton.amqp.UnsignedLong;
-import org.apache.qpid.proton.amqp.UnsignedShort;
-import org.apache.qpid.proton.amqp.messaging.ApplicationProperties;
-import org.apache.qpid.proton.amqp.messaging.Footer;
-import org.apache.qpid.proton.amqp.messaging.Header;
-import org.apache.qpid.proton.amqp.messaging.MessageAnnotations;
-import org.apache.qpid.proton.amqp.messaging.Properties;
-
-import javax.jms.DeliveryMode;
-import javax.jms.JMSException;
-import javax.jms.Message;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Map;
-import java.util.Set;
-
-import static org.apache.activemq.artemis.api.core.Message.HDR_SCHEDULED_DELIVERY_TIME;
-
-public abstract class InboundTransformer {
-
- JMSVendor vendor;
-
- public static final String TRANSFORMER_NATIVE = "native";
- public static final String TRANSFORMER_RAW = "raw";
- public static final String TRANSFORMER_JMS = "jms";
-
- String prefixVendor = "JMS_AMQP_";
- String prefixDeliveryAnnotations = "DA_";
- String prefixMessageAnnotations = "MA_";
- String prefixFooter = "FT_";
-
- int defaultDeliveryMode = DeliveryMode.NON_PERSISTENT;
- int defaultPriority = Message.DEFAULT_PRIORITY;
- long defaultTtl = Message.DEFAULT_TIME_TO_LIVE;
-
- public InboundTransformer(JMSVendor vendor) {
- this.vendor = vendor;
- }
-
- public abstract Message transform(EncodedMessage amqpMessage) throws Exception;
-
- public abstract String getTransformerName();
-
- public abstract InboundTransformer getFallbackTransformer();
-
- public int getDefaultDeliveryMode() {
- return defaultDeliveryMode;
- }
-
- public void setDefaultDeliveryMode(int defaultDeliveryMode) {
- this.defaultDeliveryMode = defaultDeliveryMode;
- }
-
- public int getDefaultPriority() {
- return defaultPriority;
- }
-
- public void setDefaultPriority(int defaultPriority) {
- this.defaultPriority = defaultPriority;
- }
-
- public long getDefaultTtl() {
- return defaultTtl;
- }
-
- public void setDefaultTtl(long defaultTtl) {
- this.defaultTtl = defaultTtl;
- }
-
- public String getPrefixVendor() {
- return prefixVendor;
- }
-
- public void setPrefixVendor(String prefixVendor) {
- this.prefixVendor = prefixVendor;
- }
-
- public JMSVendor getVendor() {
- return vendor;
- }
-
- public void setVendor(JMSVendor vendor) {
- this.vendor = vendor;
- }
-
- protected void populateMessage(Message jms, org.apache.qpid.proton.message.Message amqp) throws Exception {
- Header header = amqp.getHeader();
- if (header == null) {
- header = new Header();
- }
-
- if (header.getDurable() != null) {
- jms.setJMSDeliveryMode(header.getDurable().booleanValue() ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
- }
- else {
- jms.setJMSDeliveryMode(defaultDeliveryMode);
- }
-
- if (header.getPriority() != null) {
- jms.setJMSPriority(header.getPriority().intValue());
- }
- else {
- jms.setJMSPriority(defaultPriority);
- }
-
- if (header.getFirstAcquirer() != null) {
- jms.setBooleanProperty(prefixVendor + "FirstAcquirer", header.getFirstAcquirer());
- }
-
- if (header.getDeliveryCount() != null) {
- vendor.setJMSXDeliveryCount(jms, header.getDeliveryCount().longValue());
- }
-
- final MessageAnnotations ma = amqp.getMessageAnnotations();
- if (ma != null) {
- for (Map.Entry<?, ?> entry : ma.getValue().entrySet()) {
- String key = entry.getKey().toString();
- if ("x-opt-jms-type".equals(key) && entry.getValue() != null) {
- // Legacy annotation, JMSType value will be replaced by Subject further down if also present.
- jms.setJMSType(entry.getValue().toString());
- }
- else if ("x-opt-delivery-time".equals(key) && entry.getValue() != null) {
- long deliveryTime = ((Number) entry.getValue()).longValue();
- jms.setLongProperty(HDR_SCHEDULED_DELIVERY_TIME.toString(), deliveryTime);
- }
- else if ("x-opt-delivery-delay".equals(key) && entry.getValue() != null) {
- long delay = ((Number) entry.getValue()).longValue();
- if (delay > 0) {
- jms.setLongProperty(HDR_SCHEDULED_DELIVERY_TIME.toString(), System.currentTimeMillis() + delay);
- }
- }
- //todo
- /*else if ("x-opt-delivery-repeat".equals(key) && entry.getValue() != null) {
- int repeat = ((Number) entry.getValue()).intValue();
- if (repeat > 0) {
- jms.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, repeat);
- }
- } else if ("x-opt-delivery-period".equals(key) && entry.getValue() != null) {
- long period = ((Number) entry.getValue()).longValue();
- if (period > 0) {
- jms.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, period);
- }
- } else if ("x-opt-delivery-cron".equals(key) && entry.getValue() != null) {
- String cronEntry = (String) entry.getValue();
- if (cronEntry != null) {
- jms.setStringProperty(ScheduledMessage.AMQ_SCHEDULED_CRON, cronEntry);
- }
- }*/
-
- setProperty(jms, prefixVendor + prefixMessageAnnotations + key, entry.getValue());
- }
- }
-
- final ApplicationProperties ap = amqp.getApplicationProperties();
- if (ap != null) {
- for (Map.Entry<Object, Object> entry : (Set<Map.Entry<Object, Object>>) ap.getValue().entrySet()) {
- String key = entry.getKey().toString();
- if ("JMSXGroupID".equals(key)) {
- vendor.setJMSXGroupID(jms, entry.getValue().toString());
- }
- else if ("JMSXGroupSequence".equals(key)) {
- vendor.setJMSXGroupSequence(jms, ((Number) entry.getValue()).intValue());
- }
- else if ("JMSXUserID".equals(key)) {
- vendor.setJMSXUserID(jms, entry.getValue().toString());
- }
- else {
- setProperty(jms, key, entry.getValue());
- }
- }
- }
-
- final Properties properties = amqp.getProperties();
- if (properties != null) {
- if (properties.getMessageId() != null) {
- jms.setJMSMessageID(AMQPMessageIdHelper.INSTANCE.toBaseMessageIdString(properties.getMessageId()));
- }
- Binary userId = properties.getUserId();
- if (userId != null) {
- vendor.setJMSXUserID(jms, new String(userId.getArray(), userId.getArrayOffset(), userId.getLength(), StandardCharsets.UTF_8));
- }
- if (properties.getTo() != null) {
- jms.setJMSDestination(vendor.createDestination(properties.getTo()));
- }
- if (properties.getSubject() != null) {
- jms.setJMSType(properties.getSubject());
- }
- if (properties.getReplyTo() != null) {
- jms.setJMSReplyTo(vendor.createDestination(properties.getReplyTo()));
- }
- if (properties.getCorrelationId() != null) {
- jms.setJMSCorrelationID(AMQPMessageIdHelper.INSTANCE.toBaseMessageIdString(properties.getCorrelationId()));
- }
- if (properties.getContentType() != null) {
- jms.setStringProperty(prefixVendor + "ContentType", properties.getContentType().toString());
- }
- if (properties.getContentEncoding() != null) {
- jms.setStringProperty(prefixVendor + "ContentEncoding", properties.getContentEncoding().toString());
- }
- if (properties.getCreationTime() != null) {
- jms.setJMSTimestamp(properties.getCreationTime().getTime());
- }
- if (properties.getGroupId() != null) {
- vendor.setJMSXGroupID(jms, properties.getGroupId());
- }
- if (properties.getGroupSequence() != null) {
- vendor.setJMSXGroupSequence(jms, properties.getGroupSequence().intValue());
- }
- if (properties.getReplyToGroupId() != null) {
- jms.setStringProperty(prefixVendor + "ReplyToGroupID", properties.getReplyToGroupId());
- }
- if (properties.getAbsoluteExpiryTime() != null) {
- jms.setJMSExpiration(properties.getAbsoluteExpiryTime().getTime());
- }
- }
-
- // If the jms expiration has not yet been set...
- if (jms.getJMSExpiration() == 0) {
- // Then lets try to set it based on the message ttl.
- long ttl = defaultTtl;
- if (header.getTtl() != null) {
- ttl = header.getTtl().longValue();
- }
-
- if (ttl == 0) {
- jms.setJMSExpiration(0);
- }
- else {
- jms.setJMSExpiration(System.currentTimeMillis() + ttl);
- }
- }
-
- final Footer fp = amqp.getFooter();
- if (fp != null) {
- for (Map.Entry<Object, Object> entry : (Set<Map.Entry<Object, Object>>) fp.getValue().entrySet()) {
- String key = entry.getKey().toString();
- setProperty(jms, prefixVendor + prefixFooter + key, entry.getValue());
- }
- }
- }
-
- private void setProperty(Message msg, String key, Object value) throws JMSException {
- if (value instanceof UnsignedLong) {
- long v = ((UnsignedLong) value).longValue();
- msg.setLongProperty(key, v);
- }
- else if (value instanceof UnsignedInteger) {
- long v = ((UnsignedInteger) value).longValue();
- if (Integer.MIN_VALUE <= v && v <= Integer.MAX_VALUE) {
- msg.setIntProperty(key, (int) v);
- }
- else {
- msg.setLongProperty(key, v);
- }
- }
- else if (value instanceof UnsignedShort) {
- int v = ((UnsignedShort) value).intValue();
- if (Short.MIN_VALUE <= v && v <= Short.MAX_VALUE) {
- msg.setShortProperty(key, (short) v);
- }
- else {
- msg.setIntProperty(key, v);
- }
- }
- else if (value instanceof UnsignedByte) {
- short v = ((UnsignedByte) value).shortValue();
- if (Byte.MIN_VALUE <= v && v <= Byte.MAX_VALUE) {
- msg.setByteProperty(key, (byte) v);
- }
- else {
- msg.setShortProperty(key, v);
- }
- }
- else if (value instanceof Symbol) {
- msg.setStringProperty(key, value.toString());
- }
- else if (value instanceof Decimal128) {
- msg.setDoubleProperty(key, ((Decimal128) value).doubleValue());
- }
- else if (value instanceof Decimal64) {
- msg.setDoubleProperty(key, ((Decimal64) value).doubleValue());
- }
- else if (value instanceof Decimal32) {
- msg.setFloatProperty(key, ((Decimal32) value).floatValue());
- }
- else if (value instanceof Binary) {
- msg.setStringProperty(key, value.toString());
- }
- else {
- msg.setObjectProperty(key, value);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/JMSMappingInboundTransformer.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/JMSMappingInboundTransformer.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/JMSMappingInboundTransformer.java
deleted file mode 100644
index 62eca7c..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/JMSMappingInboundTransformer.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.converter.message;
-
-import org.apache.qpid.proton.amqp.Binary;
-import org.apache.qpid.proton.amqp.messaging.AmqpSequence;
-import org.apache.qpid.proton.amqp.messaging.AmqpValue;
-import org.apache.qpid.proton.amqp.messaging.Data;
-import org.apache.qpid.proton.amqp.messaging.Section;
-
-import javax.jms.BytesMessage;
-import javax.jms.MapMessage;
-import javax.jms.Message;
-import javax.jms.ObjectMessage;
-import javax.jms.StreamMessage;
-import javax.jms.TextMessage;
-import java.io.Serializable;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-public class JMSMappingInboundTransformer extends InboundTransformer {
-
- public JMSMappingInboundTransformer(JMSVendor vendor) {
- super(vendor);
- }
-
- @Override
- public String getTransformerName() {
- return TRANSFORMER_JMS;
- }
-
- @Override
- public InboundTransformer getFallbackTransformer() {
- return new AMQPNativeInboundTransformer(getVendor());
- }
-
- @SuppressWarnings({"unchecked"})
- @Override
- public Message transform(EncodedMessage amqpMessage) throws Exception {
- org.apache.qpid.proton.message.Message amqp = amqpMessage.decode();
-
- Message rc;
- final Section body = amqp.getBody();
- if (body == null) {
- rc = vendor.createMessage();
- }
- else if (body instanceof Data) {
- Binary d = ((Data) body).getValue();
- BytesMessage m = vendor.createBytesMessage();
- m.writeBytes(d.getArray(), d.getArrayOffset(), d.getLength());
- rc = m;
- }
- else if (body instanceof AmqpSequence) {
- AmqpSequence sequence = (AmqpSequence) body;
- StreamMessage m = vendor.createStreamMessage();
- for (Object item : sequence.getValue()) {
- m.writeObject(item);
- }
- rc = m;
- m.setStringProperty(AMQPMessageTypes.AMQP_TYPE_KEY, AMQPMessageTypes.AMQP_SEQUENCE);
- }
- else if (body instanceof AmqpValue) {
- Object value = ((AmqpValue) body).getValue();
- if (value == null) {
- rc = vendor.createObjectMessage();
- }
- if (value instanceof String) {
- TextMessage m = vendor.createTextMessage();
- m.setText((String) value);
- rc = m;
- }
- else if (value instanceof Binary) {
- Binary d = (Binary) value;
- BytesMessage m = vendor.createBytesMessage();
- m.writeBytes(d.getArray(), d.getArrayOffset(), d.getLength());
- rc = m;
- }
- else if (value instanceof List) {
- StreamMessage m = vendor.createStreamMessage();
- for (Object item : (List<Object>) value) {
- m.writeObject(item);
- }
- rc = m;
- m.setStringProperty(AMQPMessageTypes.AMQP_TYPE_KEY, AMQPMessageTypes.AMQP_LIST);
- }
- else if (value instanceof Map) {
- MapMessage m = vendor.createMapMessage();
- final Set<Map.Entry<String, Object>> set = ((Map<String, Object>) value).entrySet();
- for (Map.Entry<String, Object> entry : set) {
- m.setObject(entry.getKey(), entry.getValue());
- }
- rc = m;
- }
- else {
- ObjectMessage m = vendor.createObjectMessage();
- m.setObject((Serializable) value);
- rc = m;
- }
- }
- else {
- throw new RuntimeException("Unexpected body type: " + body.getClass());
- }
- rc.setJMSDeliveryMode(defaultDeliveryMode);
- rc.setJMSPriority(defaultPriority);
- rc.setJMSExpiration(defaultTtl);
-
- populateMessage(rc, amqp);
-
- rc.setLongProperty(prefixVendor + "MESSAGE_FORMAT", amqpMessage.getMessageFormat());
- rc.setBooleanProperty(prefixVendor + "NATIVE", false);
- return rc;
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/JMSMappingOutboundTransformer.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/JMSMappingOutboundTransformer.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/JMSMappingOutboundTransformer.java
deleted file mode 100644
index 1f202f6..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/JMSMappingOutboundTransformer.java
+++ /dev/null
@@ -1,365 +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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.converter.message;
-
-import org.apache.activemq.artemis.core.message.impl.MessageInternal;
-import org.apache.activemq.artemis.core.protocol.proton.converter.jms.ServerJMSMessage;
-import org.apache.qpid.proton.amqp.Binary;
-import org.apache.qpid.proton.amqp.Symbol;
-import org.apache.qpid.proton.amqp.UnsignedByte;
-import org.apache.qpid.proton.amqp.UnsignedInteger;
-import org.apache.qpid.proton.amqp.messaging.AmqpSequence;
-import org.apache.qpid.proton.amqp.messaging.AmqpValue;
-import org.apache.qpid.proton.amqp.messaging.ApplicationProperties;
-import org.apache.qpid.proton.amqp.messaging.Data;
-import org.apache.qpid.proton.amqp.messaging.DeliveryAnnotations;
-import org.apache.qpid.proton.amqp.messaging.Footer;
-import org.apache.qpid.proton.amqp.messaging.Header;
-import org.apache.qpid.proton.amqp.messaging.MessageAnnotations;
-import org.apache.qpid.proton.amqp.messaging.Properties;
-import org.apache.qpid.proton.amqp.messaging.Section;
-import org.apache.qpid.proton.message.ProtonJMessage;
-import org.jboss.logging.Logger;
-import org.proton.plug.exceptions.ActiveMQAMQPIllegalStateException;
-
-import javax.jms.BytesMessage;
-import javax.jms.DeliveryMode;
-import javax.jms.Destination;
-import javax.jms.JMSException;
-import javax.jms.MapMessage;
-import javax.jms.Message;
-import javax.jms.MessageEOFException;
-import javax.jms.ObjectMessage;
-import javax.jms.Queue;
-import javax.jms.StreamMessage;
-import javax.jms.TemporaryQueue;
-import javax.jms.TemporaryTopic;
-import javax.jms.TextMessage;
-import javax.jms.Topic;
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.HashMap;
-
-public class JMSMappingOutboundTransformer extends OutboundTransformer {
- private static final Logger logger = Logger.getLogger(JMSMappingOutboundTransformer.class);
- public static final Symbol JMS_DEST_TYPE_MSG_ANNOTATION = Symbol.valueOf("x-opt-jms-dest");
- public static final Symbol JMS_REPLY_TO_TYPE_MSG_ANNOTATION = Symbol.valueOf("x-opt-jms-reply-to");
-
- public static final byte QUEUE_TYPE = 0x00;
- public static final byte TOPIC_TYPE = 0x01;
- public static final byte TEMP_QUEUE_TYPE = 0x02;
- public static final byte TEMP_TOPIC_TYPE = 0x03;
-
- // Deprecated legacy values used by old QPid AMQP 1.0 JMS client.
-
- public static final Symbol LEGACY_JMS_DEST_TYPE_MSG_ANNOTATION = Symbol.valueOf("x-opt-to-type");
- public static final Symbol LEGACY_JMS_REPLY_TO_TYPE_MSG_ANNOTATION = Symbol.valueOf("x-opt-reply-type");
-
- public static final String LEGACY_QUEUE_TYPE = "queue";
- public static final String LEGACY_TOPIC_TYPE = "topic";
- public static final String LEGACY_TEMP_QUEUE_TYPE = "temporary,queue";
- public static final String LEGACY_TEMP_TOPIC_TYPE = "temporary,topic";
-
- public JMSMappingOutboundTransformer(JMSVendor vendor) {
- super(vendor);
- }
-
- /**
- * Perform the conversion between JMS Message and Proton Message without
- * re-encoding it to array. This is needed because some frameworks may elect
- * to do this on their own way (Netty for instance using Nettybuffers)
- *
- * @param msg
- * @return
- * @throws Exception
- */
- public ProtonJMessage convert(Message msg) throws JMSException, UnsupportedEncodingException {
- Header header = new Header();
- Properties props = new Properties();
- HashMap<Symbol, Object> daMap = null;
- HashMap<Symbol, Object> maMap = null;
- HashMap apMap = null;
- Section body = null;
- HashMap footerMap = null;
- if (msg instanceof BytesMessage) {
- BytesMessage m = (BytesMessage) msg;
- byte[] data = new byte[(int) m.getBodyLength()];
- m.readBytes(data);
- m.reset(); // Need to reset after readBytes or future readBytes
- // calls (ex: redeliveries) will fail and return -1
- body = new Data(new Binary(data));
- }
- if (msg instanceof TextMessage) {
- body = new AmqpValue(((TextMessage) msg).getText());
- }
- if (msg instanceof MapMessage) {
- final HashMap<String, Object> map = new HashMap<>();
- final MapMessage m = (MapMessage) msg;
- final Enumeration<String> names = m.getMapNames();
- while (names.hasMoreElements()) {
- String key = names.nextElement();
- map.put(key, m.getObject(key));
- }
- body = new AmqpValue(map);
- }
- if (msg instanceof StreamMessage) {
- ArrayList<Object> list = new ArrayList<>();
- final StreamMessage m = (StreamMessage) msg;
- try {
- while (true) {
- list.add(m.readObject());
- }
- }
- catch (MessageEOFException e) {
- }
-
- String amqpType = msg.getStringProperty(AMQPMessageTypes.AMQP_TYPE_KEY);
- if (amqpType.equals(AMQPMessageTypes.AMQP_LIST)) {
- body = new AmqpValue(list);
- }
- else {
- body = new AmqpSequence(list);
- }
- }
- if (msg instanceof ObjectMessage) {
- body = new AmqpValue(((ObjectMessage) msg).getObject());
- }
-
- if (body == null && msg instanceof org.apache.activemq.artemis.core.protocol.proton.converter.jms.ServerJMSMessage) {
-
- MessageInternal internalMessage = ((org.apache.activemq.artemis.core.protocol.proton.converter.jms.ServerJMSMessage) msg).getInnerMessage();
- if (!internalMessage.containsProperty("AMQP_MESSAGE_FORMAT")) {
- int readerIndex = internalMessage.getBodyBuffer().readerIndex();
- try {
- Object s = internalMessage.getBodyBuffer().readNullableSimpleString();
- if (s != null) {
- body = new AmqpValue(s.toString());
- }
- }
- catch (Throwable ignored) {
- logger.debug("Exception ignored during conversion, should be ok!", ignored.getMessage(), ignored);
- }
- finally {
- internalMessage.getBodyBuffer().readerIndex(readerIndex);
- }
- }
- }
-
- header.setDurable(msg.getJMSDeliveryMode() == DeliveryMode.PERSISTENT ? true : false);
- header.setPriority(new UnsignedByte((byte) msg.getJMSPriority()));
- if (msg.getJMSType() != null) {
- props.setSubject(msg.getJMSType());
- }
- if (msg.getJMSMessageID() != null) {
-
- String msgId = msg.getJMSMessageID();
-
- try {
- props.setMessageId(AMQPMessageIdHelper.INSTANCE.toIdObject(msgId));
- }
- catch (ActiveMQAMQPIllegalStateException e) {
- props.setMessageId(msgId);
- }
- }
- if (msg.getJMSDestination() != null) {
- props.setTo(vendor.toAddress(msg.getJMSDestination()));
- if (maMap == null) {
- maMap = new HashMap<>();
- }
- maMap.put(JMS_DEST_TYPE_MSG_ANNOTATION, destinationType(msg.getJMSDestination()));
-
- // Deprecated: used by legacy QPid AMQP 1.0 JMS client
- maMap.put(LEGACY_JMS_DEST_TYPE_MSG_ANNOTATION, destinationAttributes(msg.getJMSDestination()));
- }
- if (msg.getJMSReplyTo() != null) {
- props.setReplyTo(vendor.toAddress(msg.getJMSReplyTo()));
- if (maMap == null) {
- maMap = new HashMap<>();
- }
- maMap.put(JMS_REPLY_TO_TYPE_MSG_ANNOTATION, destinationType(msg.getJMSReplyTo()));
-
- // Deprecated: used by legacy QPid AMQP 1.0 JMS client
- maMap.put(LEGACY_JMS_REPLY_TO_TYPE_MSG_ANNOTATION, destinationAttributes(msg.getJMSReplyTo()));
- }
- if (msg.getJMSCorrelationID() != null) {
- String correlationId = msg.getJMSCorrelationID();
-
- try {
- props.setCorrelationId(AMQPMessageIdHelper.INSTANCE.toIdObject(correlationId));
- }
- catch (ActiveMQAMQPIllegalStateException e) {
- props.setCorrelationId(correlationId);
- }
- }
- if (msg.getJMSExpiration() != 0) {
- long ttl = msg.getJMSExpiration() - System.currentTimeMillis();
- if (ttl < 0) {
- ttl = 1;
- }
- header.setTtl(new UnsignedInteger((int) ttl));
-
- props.setAbsoluteExpiryTime(new Date(msg.getJMSExpiration()));
- }
- if (msg.getJMSTimestamp() != 0) {
- props.setCreationTime(new Date(msg.getJMSTimestamp()));
- }
-
- final Enumeration<String> keys = msg.getPropertyNames();
- while (keys.hasMoreElements()) {
- String key = keys.nextElement();
- if (key.equals(messageFormatKey) || key.equals(nativeKey) || key.equals(ServerJMSMessage.NATIVE_MESSAGE_ID)) {
- // skip..
- }
- else if (key.equals(firstAcquirerKey)) {
- header.setFirstAcquirer(msg.getBooleanProperty(key));
- }
- else if (key.startsWith("JMSXDeliveryCount")) {
- // The AMQP delivery-count field only includes prior failed delivery attempts,
- // whereas JMSXDeliveryCount includes the first/current delivery attempt.
- int amqpDeliveryCount = msg.getIntProperty(key) - 1;
- if (amqpDeliveryCount > 0) {
- header.setDeliveryCount(new UnsignedInteger(amqpDeliveryCount));
- }
- }
- else if (key.startsWith("JMSXUserID")) {
- String value = msg.getStringProperty(key);
- props.setUserId(new Binary(value.getBytes(StandardCharsets.UTF_8)));
- }
- else if (key.startsWith("JMSXGroupID") || key.startsWith("_AMQ_GROUP_ID")) {
- String value = msg.getStringProperty(key);
- props.setGroupId(value);
- if (apMap == null) {
- apMap = new HashMap();
- }
- apMap.put(key, value);
- }
- else if (key.startsWith("JMSXGroupSeq")) {
- UnsignedInteger value = new UnsignedInteger(msg.getIntProperty(key));
- props.setGroupSequence(value);
- if (apMap == null) {
- apMap = new HashMap();
- }
- apMap.put(key, value);
- }
- else if (key.startsWith(prefixDeliveryAnnotationsKey)) {
- if (daMap == null) {
- daMap = new HashMap<>();
- }
- String name = key.substring(prefixDeliveryAnnotationsKey.length());
- daMap.put(Symbol.valueOf(name), msg.getObjectProperty(key));
- }
- else if (key.startsWith(prefixMessageAnnotationsKey)) {
- if (maMap == null) {
- maMap = new HashMap<>();
- }
- String name = key.substring(prefixMessageAnnotationsKey.length());
- maMap.put(Symbol.valueOf(name), msg.getObjectProperty(key));
- }
- else if (key.equals(contentTypeKey)) {
- props.setContentType(Symbol.getSymbol(msg.getStringProperty(key)));
- }
- else if (key.equals(contentEncodingKey)) {
- props.setContentEncoding(Symbol.getSymbol(msg.getStringProperty(key)));
- }
- else if (key.equals(replyToGroupIDKey)) {
- props.setReplyToGroupId(msg.getStringProperty(key));
- }
- else if (key.startsWith(prefixFooterKey)) {
- if (footerMap == null) {
- footerMap = new HashMap();
- }
- String name = key.substring(prefixFooterKey.length());
- footerMap.put(name, msg.getObjectProperty(key));
- }
- else if (key.equals(AMQPMessageTypes.AMQP_TYPE_KEY)) {
- // skip
- }
- else {
- if (apMap == null) {
- apMap = new HashMap();
- }
- apMap.put(key, msg.getObjectProperty(key));
- }
- }
-
- MessageAnnotations ma = null;
- if (maMap != null) {
- ma = new MessageAnnotations(maMap);
- }
- DeliveryAnnotations da = null;
- if (daMap != null) {
- da = new DeliveryAnnotations(daMap);
- }
- ApplicationProperties ap = null;
- if (apMap != null) {
- ap = new ApplicationProperties(apMap);
- }
- Footer footer = null;
- if (footerMap != null) {
- footer = new Footer(footerMap);
- }
-
- return (ProtonJMessage) org.apache.qpid.proton.message.Message.Factory.create(header, da, ma, props, ap, body, footer);
- }
-
- private static byte destinationType(Destination destination) {
- if (destination instanceof Queue) {
- if (destination instanceof TemporaryQueue) {
- return TEMP_QUEUE_TYPE;
- }
- else {
- return QUEUE_TYPE;
- }
- }
- else if (destination instanceof Topic) {
- if (destination instanceof TemporaryTopic) {
- return TEMP_TOPIC_TYPE;
- }
- else {
- return TOPIC_TYPE;
- }
- }
-
- throw new IllegalArgumentException("Unknown Destination Type passed to JMS Transformer.");
- }
-
- // Used by legacy QPid AMQP 1.0 JMS client.
- @Deprecated
- private static String destinationAttributes(Destination destination) {
- if (destination instanceof Queue) {
- if (destination instanceof TemporaryQueue) {
- return LEGACY_TEMP_QUEUE_TYPE;
- }
- else {
- return LEGACY_QUEUE_TYPE;
- }
- }
- else if (destination instanceof Topic) {
- if (destination instanceof TemporaryTopic) {
- return LEGACY_TEMP_TOPIC_TYPE;
- }
- else {
- return LEGACY_TOPIC_TYPE;
- }
- }
-
- throw new IllegalArgumentException("Unknown Destination Type passed to JMS Transformer.");
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/JMSVendor.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/JMSVendor.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/JMSVendor.java
deleted file mode 100644
index 7255295..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/JMSVendor.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.converter.message;
-
-import javax.jms.BytesMessage;
-import javax.jms.Destination;
-import javax.jms.MapMessage;
-import javax.jms.Message;
-import javax.jms.ObjectMessage;
-import javax.jms.StreamMessage;
-import javax.jms.TextMessage;
-
-public interface JMSVendor {
-
- BytesMessage createBytesMessage();
-
- StreamMessage createStreamMessage();
-
- Message createMessage();
-
- TextMessage createTextMessage();
-
- ObjectMessage createObjectMessage();
-
- MapMessage createMapMessage();
-
- void setJMSXUserID(Message message, String value);
-
- Destination createDestination(String name);
-
- void setJMSXGroupID(Message message, String groupId);
-
- void setJMSXGroupSequence(Message message, int value);
-
- void setJMSXDeliveryCount(Message message, long value);
-
- String toAddress(Destination destination);
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/OutboundTransformer.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/OutboundTransformer.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/OutboundTransformer.java
deleted file mode 100644
index bd20eee..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/proton/converter/message/OutboundTransformer.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton.converter.message;
-
-public abstract class OutboundTransformer {
-
- JMSVendor vendor;
- String prefixVendor;
-
- String prefixDeliveryAnnotations = "DA_";
- String prefixMessageAnnotations = "MA_";
- String prefixFooter = "FT_";
-
- String messageFormatKey;
- String nativeKey;
- String firstAcquirerKey;
- String prefixDeliveryAnnotationsKey;
- String prefixMessageAnnotationsKey;
- String contentTypeKey;
- String contentEncodingKey;
- String replyToGroupIDKey;
- String prefixFooterKey;
-
- public OutboundTransformer(JMSVendor vendor) {
- this.vendor = vendor;
- this.setPrefixVendor("JMS_AMQP_");
- }
-
- public String getPrefixVendor() {
- return prefixVendor;
- }
-
- public void setPrefixVendor(String prefixVendor) {
- this.prefixVendor = prefixVendor;
-
- messageFormatKey = prefixVendor + "MESSAGE_FORMAT";
- nativeKey = prefixVendor + "NATIVE";
- firstAcquirerKey = prefixVendor + "FirstAcquirer";
- prefixDeliveryAnnotationsKey = prefixVendor + prefixDeliveryAnnotations;
- prefixMessageAnnotationsKey = prefixVendor + prefixMessageAnnotations;
- contentTypeKey = prefixVendor + "ContentType";
- contentEncodingKey = prefixVendor + "ContentEncoding";
- replyToGroupIDKey = prefixVendor + "ReplyToGroupID";
- prefixFooterKey = prefixVendor + prefixFooter;
-
- }
-
- public JMSVendor getVendor() {
- return vendor;
- }
-
- public void setVendor(JMSVendor vendor) {
- this.vendor = vendor;
- }
-}
[08/15] activemq-artemis git commit: ARTEMIS-751 Simplification of
the AMQP implementation
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/util/DeliveryUtil.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/util/DeliveryUtil.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/util/DeliveryUtil.java
new file mode 100644
index 0000000..9257c6b
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/util/DeliveryUtil.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.util;
+
+import io.netty.buffer.ByteBuf;
+import org.apache.qpid.proton.engine.Receiver;
+import org.apache.qpid.proton.message.Message;
+import org.apache.qpid.proton.message.impl.MessageImpl;
+
+public class DeliveryUtil {
+
+ public static int readDelivery(Receiver receiver, ByteBuf buffer) {
+ int initial = buffer.writerIndex();
+ // optimization by norman
+ int count;
+ while ((count = receiver.recv(buffer.array(), buffer.arrayOffset() + buffer.writerIndex(), buffer.writableBytes())) > 0) {
+ // Increment the writer index by the number of bytes written into it while calling recv.
+ buffer.writerIndex(buffer.writerIndex() + count);
+ buffer.ensureWritable(count);
+ }
+ return buffer.writerIndex() - initial;
+ }
+
+ public static MessageImpl decodeMessageImpl(ByteBuf buffer) {
+ MessageImpl message = (MessageImpl) Message.Factory.create();
+ message.decode(buffer.array(), buffer.arrayOffset() + buffer.readerIndex(), buffer.readableBytes());
+ return message;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/util/NettyWritable.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/util/NettyWritable.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/util/NettyWritable.java
new file mode 100644
index 0000000..75d39b6
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/util/NettyWritable.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.util;
+
+import java.nio.ByteBuffer;
+
+import io.netty.buffer.ByteBuf;
+import org.apache.qpid.proton.codec.WritableBuffer;
+
+/**
+ * This is to use NettyBuffer within Proton
+ */
+
+public class NettyWritable implements WritableBuffer {
+
+ final ByteBuf nettyBuffer;
+
+ public NettyWritable(ByteBuf nettyBuffer) {
+ this.nettyBuffer = nettyBuffer;
+ }
+
+ @Override
+ public void put(byte b) {
+ nettyBuffer.writeByte(b);
+ }
+
+ @Override
+ public void putFloat(float f) {
+ nettyBuffer.writeFloat(f);
+ }
+
+ @Override
+ public void putDouble(double d) {
+ nettyBuffer.writeDouble(d);
+ }
+
+ @Override
+ public void put(byte[] src, int offset, int length) {
+ nettyBuffer.writeBytes(src, offset, length);
+ }
+
+ @Override
+ public void putShort(short s) {
+ nettyBuffer.writeShort(s);
+ }
+
+ @Override
+ public void putInt(int i) {
+ nettyBuffer.writeInt(i);
+ }
+
+ @Override
+ public void putLong(long l) {
+ nettyBuffer.writeLong(l);
+ }
+
+ @Override
+ public boolean hasRemaining() {
+ return nettyBuffer.writerIndex() < nettyBuffer.capacity();
+ }
+
+ @Override
+ public int remaining() {
+ return nettyBuffer.capacity() - nettyBuffer.writerIndex();
+ }
+
+ @Override
+ public int position() {
+ return nettyBuffer.writerIndex();
+ }
+
+ @Override
+ public void position(int position) {
+ nettyBuffer.writerIndex(position);
+ }
+
+ @Override
+ public void put(ByteBuffer payload) {
+ nettyBuffer.writeBytes(payload);
+ }
+
+ @Override
+ public int limit() {
+ return nettyBuffer.capacity();
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/util/ProtonServerMessage.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/util/ProtonServerMessage.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/util/ProtonServerMessage.java
new file mode 100644
index 0000000..c15741e
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/util/ProtonServerMessage.java
@@ -0,0 +1,470 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.util;
+
+import java.nio.ByteBuffer;
+
+import org.apache.qpid.proton.amqp.messaging.ApplicationProperties;
+import org.apache.qpid.proton.amqp.messaging.DeliveryAnnotations;
+import org.apache.qpid.proton.amqp.messaging.Footer;
+import org.apache.qpid.proton.amqp.messaging.Header;
+import org.apache.qpid.proton.amqp.messaging.MessageAnnotations;
+import org.apache.qpid.proton.amqp.messaging.Properties;
+import org.apache.qpid.proton.amqp.messaging.Section;
+import org.apache.qpid.proton.codec.DecoderImpl;
+import org.apache.qpid.proton.codec.EncoderImpl;
+import org.apache.qpid.proton.codec.WritableBuffer;
+import org.apache.qpid.proton.message.MessageError;
+import org.apache.qpid.proton.message.ProtonJMessage;
+
+/**
+ * This is a serverMessage that won't deal with the body
+ */
+public class ProtonServerMessage implements ProtonJMessage {
+
+ private Header header;
+ private DeliveryAnnotations deliveryAnnotations;
+ private MessageAnnotations messageAnnotations;
+ private Properties properties;
+ private ApplicationProperties applicationProperties;
+
+ // This should include a raw body of both footer and body
+ private byte[] rawBody;
+
+ private Section parsedBody;
+ private Footer parsedFooter;
+
+ private final int EOF = 0;
+
+ // TODO: Enumerations maybe?
+ private static final int HEADER_TYPE = 0x070;
+ private static final int DELIVERY_ANNOTATIONS = 0x071;
+ private static final int MESSAGE_ANNOTATIONS = 0x072;
+ private static final int PROPERTIES = 0x073;
+ private static final int APPLICATION_PROPERTIES = 0x074;
+
+ /**
+ * This will decode a ByteBuffer tha represents the entire message.
+ * Set the limits around the parameter.
+ *
+ * @param buffer a limited buffer for the message
+ */
+ public void decode(ByteBuffer buffer) {
+
+ DecoderImpl decoder = CodecCache.getDecoder();
+
+ header = null;
+ deliveryAnnotations = null;
+ messageAnnotations = null;
+ properties = null;
+ applicationProperties = null;
+ rawBody = null;
+
+ decoder.setByteBuffer(buffer);
+ try {
+ int type = readType(buffer, decoder);
+ if (type == HEADER_TYPE) {
+ header = (Header) readSection(buffer, decoder);
+ type = readType(buffer, decoder);
+
+ }
+
+ if (type == DELIVERY_ANNOTATIONS) {
+ deliveryAnnotations = (DeliveryAnnotations) readSection(buffer, decoder);
+ type = readType(buffer, decoder);
+
+ }
+
+ if (type == MESSAGE_ANNOTATIONS) {
+ messageAnnotations = (MessageAnnotations) readSection(buffer, decoder);
+ type = readType(buffer, decoder);
+ }
+
+ if (type == PROPERTIES) {
+ properties = (Properties) readSection(buffer, decoder);
+ type = readType(buffer, decoder);
+
+ }
+
+ if (type == APPLICATION_PROPERTIES) {
+ applicationProperties = (ApplicationProperties) readSection(buffer, decoder);
+ type = readType(buffer, decoder);
+ }
+
+ if (type != EOF) {
+ rawBody = new byte[buffer.limit() - buffer.position()];
+ buffer.get(rawBody);
+ }
+ }
+ finally {
+ decoder.setByteBuffer(null);
+ }
+
+ }
+
+ public void encode(ByteBuffer buffer) {
+ WritableBuffer writableBuffer = new WritableBuffer.ByteBufferWrapper(buffer);
+ encode(writableBuffer);
+ }
+
+ @Override
+ public int encode(WritableBuffer writableBuffer) {
+ final int firstPosition = writableBuffer.position();
+
+ EncoderImpl encoder = CodecCache.getEncoder();
+ encoder.setByteBuffer(writableBuffer);
+
+ try {
+ if (header != null) {
+ encoder.writeObject(header);
+ }
+ if (deliveryAnnotations != null) {
+ encoder.writeObject(deliveryAnnotations);
+ }
+ if (messageAnnotations != null) {
+ encoder.writeObject(messageAnnotations);
+ }
+ if (properties != null) {
+ encoder.writeObject(properties);
+ }
+ if (applicationProperties != null) {
+ encoder.writeObject(applicationProperties);
+ }
+
+ // It should write either the parsed one or the rawBody
+ if (parsedBody != null) {
+ encoder.writeObject(parsedBody);
+ if (parsedFooter != null) {
+ encoder.writeObject(parsedFooter);
+ }
+ }
+ else if (rawBody != null) {
+ writableBuffer.put(rawBody, 0, rawBody.length);
+ }
+
+ return writableBuffer.position() - firstPosition;
+ }
+ finally {
+ encoder.setByteBuffer((WritableBuffer) null);
+ }
+ }
+
+ private int readType(ByteBuffer buffer, DecoderImpl decoder) {
+
+ int pos = buffer.position();
+
+ if (!buffer.hasRemaining()) {
+ return EOF;
+ }
+ try {
+ if (buffer.get() != 0) {
+ return EOF;
+ }
+ else {
+ return ((Number) decoder.readObject()).intValue();
+ }
+ }
+ finally {
+ buffer.position(pos);
+ }
+ }
+
+ private Section readSection(ByteBuffer buffer, DecoderImpl decoder) {
+ if (buffer.hasRemaining()) {
+ return (Section) decoder.readObject();
+ }
+ else {
+ return null;
+ }
+ }
+
+ // At the moment we only need encode implemented!!!
+ @Override
+ public boolean isDurable() {
+ return false;
+ }
+
+ @Override
+ public long getDeliveryCount() {
+ return 0;
+ }
+
+ @Override
+ public short getPriority() {
+ return 0;
+ }
+
+ @Override
+ public boolean isFirstAcquirer() {
+ return false;
+ }
+
+ @Override
+ public long getTtl() {
+ return 0;
+ }
+
+ @Override
+ public void setDurable(boolean durable) {
+
+ }
+
+ @Override
+ public void setTtl(long ttl) {
+
+ }
+
+ @Override
+ public void setDeliveryCount(long deliveryCount) {
+
+ }
+
+ @Override
+ public void setFirstAcquirer(boolean firstAcquirer) {
+
+ }
+
+ @Override
+ public void setPriority(short priority) {
+
+ }
+
+ @Override
+ public Object getMessageId() {
+ return null;
+ }
+
+ @Override
+ public long getGroupSequence() {
+ return 0;
+ }
+
+ @Override
+ public String getReplyToGroupId() {
+ return null;
+ }
+
+ @Override
+ public long getCreationTime() {
+ return 0;
+ }
+
+ @Override
+ public String getAddress() {
+ return null;
+ }
+
+ @Override
+ public byte[] getUserId() {
+ return new byte[0];
+ }
+
+ @Override
+ public String getReplyTo() {
+ return null;
+ }
+
+ @Override
+ public String getGroupId() {
+ return null;
+ }
+
+ @Override
+ public String getContentType() {
+ return null;
+ }
+
+ @Override
+ public long getExpiryTime() {
+ return 0;
+ }
+
+ @Override
+ public Object getCorrelationId() {
+ return null;
+ }
+
+ @Override
+ public String getContentEncoding() {
+ return null;
+ }
+
+ @Override
+ public String getSubject() {
+ return null;
+ }
+
+ @Override
+ public void setGroupSequence(long groupSequence) {
+
+ }
+
+ @Override
+ public void setUserId(byte[] userId) {
+
+ }
+
+ @Override
+ public void setCreationTime(long creationTime) {
+
+ }
+
+ @Override
+ public void setSubject(String subject) {
+
+ }
+
+ @Override
+ public void setGroupId(String groupId) {
+
+ }
+
+ @Override
+ public void setAddress(String to) {
+
+ }
+
+ @Override
+ public void setExpiryTime(long absoluteExpiryTime) {
+
+ }
+
+ @Override
+ public void setReplyToGroupId(String replyToGroupId) {
+
+ }
+
+ @Override
+ public void setContentEncoding(String contentEncoding) {
+
+ }
+
+ @Override
+ public void setContentType(String contentType) {
+
+ }
+
+ @Override
+ public void setReplyTo(String replyTo) {
+
+ }
+
+ @Override
+ public void setCorrelationId(Object correlationId) {
+
+ }
+
+ @Override
+ public void setMessageId(Object messageId) {
+
+ }
+
+ @Override
+ public Header getHeader() {
+ return null;
+ }
+
+ @Override
+ public DeliveryAnnotations getDeliveryAnnotations() {
+ return null;
+ }
+
+ @Override
+ public MessageAnnotations getMessageAnnotations() {
+ return null;
+ }
+
+ @Override
+ public Properties getProperties() {
+ return null;
+ }
+
+ @Override
+ public ApplicationProperties getApplicationProperties() {
+ return null;
+ }
+
+ @Override
+ public Section getBody() {
+ return null;
+ }
+
+ @Override
+ public Footer getFooter() {
+ return null;
+ }
+
+ @Override
+ public void setHeader(Header header) {
+
+ }
+
+ @Override
+ public void setDeliveryAnnotations(DeliveryAnnotations deliveryAnnotations) {
+
+ }
+
+ @Override
+ public void setMessageAnnotations(MessageAnnotations messageAnnotations) {
+
+ }
+
+ @Override
+ public void setProperties(Properties properties) {
+
+ }
+
+ @Override
+ public void setApplicationProperties(ApplicationProperties applicationProperties) {
+
+ }
+
+ @Override
+ public void setBody(Section body) {
+
+ }
+
+ @Override
+ public void setFooter(Footer footer) {
+
+ }
+
+ @Override
+ public int decode(byte[] data, int offset, int length) {
+ return 0;
+ }
+
+ @Override
+ public int encode(byte[] data, int offset, int length) {
+ return 0;
+ }
+
+ @Override
+ public void clear() {
+
+ }
+
+ @Override
+ public MessageError getError() {
+ return null;
+ }
+
+ @Override
+ public int encode2(byte[] data, int offset, int length) {
+ return 0;
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/main/resources/META-INF/services/org.apache.activemq.artemis.spi.core.protocol.ProtocolManagerFactory
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/resources/META-INF/services/org.apache.activemq.artemis.spi.core.protocol.ProtocolManagerFactory b/artemis-protocols/artemis-amqp-protocol/src/main/resources/META-INF/services/org.apache.activemq.artemis.spi.core.protocol.ProtocolManagerFactory
index 2cd27f4..93b9dfa 100644
--- a/artemis-protocols/artemis-amqp-protocol/src/main/resources/META-INF/services/org.apache.activemq.artemis.spi.core.protocol.ProtocolManagerFactory
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/resources/META-INF/services/org.apache.activemq.artemis.spi.core.protocol.ProtocolManagerFactory
@@ -1 +1 @@
-org.apache.activemq.artemis.core.protocol.proton.ProtonProtocolManagerFactory
\ No newline at end of file
+org.apache.activemq.artemis.protocol.amqp.broker.ProtonProtocolManagerFactory
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/test/java/org/apache/activemq/artemis/core/protocol/proton/TestConversions.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/test/java/org/apache/activemq/artemis/core/protocol/proton/TestConversions.java b/artemis-protocols/artemis-amqp-protocol/src/test/java/org/apache/activemq/artemis/core/protocol/proton/TestConversions.java
deleted file mode 100644
index fc77c7d..0000000
--- a/artemis-protocols/artemis-amqp-protocol/src/test/java/org/apache/activemq/artemis/core/protocol/proton/TestConversions.java
+++ /dev/null
@@ -1,793 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.core.protocol.proton;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
-import java.nio.ByteBuffer;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.PooledByteBufAllocator;
-import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
-import org.apache.activemq.artemis.core.protocol.proton.converter.jms.ServerJMSObjectMessage;
-import org.apache.activemq.artemis.core.protocol.proton.converter.message.EncodedMessage;
-import org.apache.activemq.artemis.core.server.impl.ServerMessageImpl;
-import org.apache.blacklist.ABadClass;
-import org.apache.qpid.proton.amqp.Binary;
-import org.apache.qpid.proton.amqp.messaging.AmqpSequence;
-import org.apache.qpid.proton.amqp.messaging.AmqpValue;
-import org.apache.qpid.proton.amqp.messaging.ApplicationProperties;
-import org.apache.qpid.proton.amqp.messaging.Data;
-import org.apache.qpid.proton.message.Message;
-import org.apache.qpid.proton.message.ProtonJMessage;
-import org.apache.qpid.proton.message.impl.MessageImpl;
-import org.apache.activemq.artemis.api.core.SimpleString;
-import org.apache.activemq.artemis.core.journal.EncodingSupport;
-import org.apache.activemq.artemis.core.protocol.proton.converter.ProtonMessageConverter;
-import org.apache.activemq.artemis.core.protocol.proton.converter.jms.ServerJMSBytesMessage;
-import org.apache.activemq.artemis.core.protocol.proton.converter.jms.ServerJMSMapMessage;
-import org.apache.activemq.artemis.core.protocol.proton.converter.jms.ServerJMSMessage;
-import org.apache.activemq.artemis.core.protocol.proton.converter.jms.ServerJMSStreamMessage;
-import org.apache.activemq.artemis.core.protocol.proton.converter.jms.ServerJMSTextMessage;
-import org.apache.activemq.artemis.core.server.ServerMessage;
-import org.apache.activemq.artemis.utils.SimpleIDGenerator;
-import org.junit.Assert;
-import org.junit.Test;
-import org.proton.plug.util.NettyWritable;
-
-public class TestConversions extends Assert {
-
- @Test
- public void testObjectMessageWhiteList() throws Exception {
- Map<String, Object> mapprop = createPropertiesMap();
- ApplicationProperties properties = new ApplicationProperties(mapprop);
- MessageImpl message = (MessageImpl) Message.Factory.create();
- message.setApplicationProperties(properties);
-
- byte[] bodyBytes = new byte[4];
-
- for (int i = 0; i < bodyBytes.length; i++) {
- bodyBytes[i] = (byte) 0xff;
- }
-
- message.setBody(new AmqpValue(new Boolean(true)));
-
- EncodedMessage encodedMessage = encodeMessage(message);
-
- ProtonMessageConverter converter = new ProtonMessageConverter(new SimpleIDGenerator(0));
- ServerJMSObjectMessage serverMessage = (ServerJMSObjectMessage) converter.inboundJMSType(encodedMessage);
-
- verifyProperties(serverMessage);
-
- assertEquals(true, serverMessage.getObject());
-
- Object obj = converter.outbound((ServerMessage) serverMessage.getInnerMessage(), 0);
-
- AmqpValue value = (AmqpValue) ((Message)obj).getBody();
- assertEquals(value.getValue(), true);
-
- }
-
- @Test
- public void testObjectMessageNotOnWhiteList() throws Exception {
-
-
- ProtonMessageConverter converter = new ProtonMessageConverter(new SimpleIDGenerator(0));
- ServerMessageImpl message = new ServerMessageImpl(1, 1024);
- message.setType((byte) 2);
- ServerJMSObjectMessage serverMessage = new ServerJMSObjectMessage(message, 1024);
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- ObjectOutputStream ois = new ObjectOutputStream(out);
- ois.writeObject(new ABadClass());
- serverMessage.getInnerMessage().getBodyBuffer().writeBytes(out.toByteArray());
-
- try {
- converter.outbound((ServerMessage) serverMessage.getInnerMessage(), 0);
- fail("should throw ClassNotFoundException");
- }
- catch (ClassNotFoundException e) {
- //ignore
- }
- }
-
-
- @Test
- public void testSimpleConversionBytes() throws Exception {
- Map<String, Object> mapprop = createPropertiesMap();
- ApplicationProperties properties = new ApplicationProperties(mapprop);
- MessageImpl message = (MessageImpl) Message.Factory.create();
- message.setApplicationProperties(properties);
-
- byte[] bodyBytes = new byte[4];
-
- for (int i = 0; i < bodyBytes.length; i++) {
- bodyBytes[i] = (byte) 0xff;
- }
-
- message.setBody(new Data(new Binary(bodyBytes)));
-
- EncodedMessage encodedMessage = encodeMessage(message);
-
- ProtonMessageConverter converter = new ProtonMessageConverter(new SimpleIDGenerator(0));
- ServerJMSBytesMessage serverMessage = (ServerJMSBytesMessage) converter.inboundJMSType(encodedMessage);
-
- verifyProperties(serverMessage);
-
- assertEquals(bodyBytes.length, serverMessage.getBodyLength());
-
- byte[] newBodyBytes = new byte[4];
-
- serverMessage.readBytes(newBodyBytes);
-
- Assert.assertArrayEquals(bodyBytes, newBodyBytes);
-
- Object obj = converter.outbound((ServerMessage) serverMessage.getInnerMessage(), 0);
-
- System.out.println("output = " + obj);
-
- }
-
- private void verifyProperties(javax.jms.Message message) throws Exception {
- assertEquals(true, message.getBooleanProperty("true"));
- assertEquals(false, message.getBooleanProperty("false"));
- assertEquals("bar", message.getStringProperty("foo"));
- }
-
- private Map<String, Object> createPropertiesMap() {
- Map<String, Object> mapprop = new HashMap<>();
-
- mapprop.put("true", Boolean.TRUE);
- mapprop.put("false", Boolean.FALSE);
- mapprop.put("foo", "bar");
- return mapprop;
- }
-
- @Test
- public void testSimpleConversionMap() throws Exception {
- Map<String, Object> mapprop = createPropertiesMap();
- ApplicationProperties properties = new ApplicationProperties(mapprop);
- MessageImpl message = (MessageImpl) Message.Factory.create();
- message.setApplicationProperties(properties);
-
- Map<String, Object> mapValues = new HashMap<>();
- mapValues.put("somestr", "value");
- mapValues.put("someint", Integer.valueOf(1));
-
- message.setBody(new AmqpValue(mapValues));
-
- EncodedMessage encodedMessage = encodeMessage(message);
-
- ProtonMessageConverter converter = new ProtonMessageConverter(new SimpleIDGenerator(0));
- ServerJMSMapMessage serverMessage = (ServerJMSMapMessage) converter.inboundJMSType(encodedMessage);
-
- verifyProperties(serverMessage);
-
- Assert.assertEquals(1, serverMessage.getInt("someint"));
- Assert.assertEquals("value", serverMessage.getString("somestr"));
-
- Object obj = converter.outbound((ServerMessage) serverMessage.getInnerMessage(), 0);
-
- reEncodeMsg(obj);
-
- MessageImpl outMessage = (MessageImpl) obj;
- AmqpValue value = (AmqpValue) outMessage.getBody();
- Map mapoutput = (Map) value.getValue();
-
- assertEquals(Integer.valueOf(1), mapoutput.get("someint"));
-
- System.out.println("output = " + obj);
-
- }
-
- @Test
- public void testSimpleConversionStream() throws Exception {
- Map<String, Object> mapprop = createPropertiesMap();
- ApplicationProperties properties = new ApplicationProperties(mapprop);
- MessageImpl message = (MessageImpl) Message.Factory.create();
- message.setApplicationProperties(properties);
-
- List<Object> objects = new LinkedList<>();
- objects.add(new Integer(10));
- objects.add("10");
-
- message.setBody(new AmqpSequence(objects));
-
- EncodedMessage encodedMessage = encodeMessage(message);
-
- ProtonMessageConverter converter = new ProtonMessageConverter(new SimpleIDGenerator(0));
- ServerJMSStreamMessage serverMessage = (ServerJMSStreamMessage) converter.inboundJMSType(encodedMessage);
-
- simulatePersistence(serverMessage);
-
- verifyProperties(serverMessage);
-
- serverMessage.reset();
-
- assertEquals(10, serverMessage.readInt());
- assertEquals("10", serverMessage.readString());
-
- Object obj = converter.outbound((ServerMessage) serverMessage.getInnerMessage(), 0);
-
- reEncodeMsg(obj);
-
- MessageImpl outMessage = (MessageImpl) obj;
- List list = ((AmqpSequence) outMessage.getBody()).getValue();
- Assert.assertEquals(Integer.valueOf(10), list.get(0));
- Assert.assertEquals("10", list.get(1));
-
- }
-
- @Test
- public void testSimpleConversionText() throws Exception {
- Map<String, Object> mapprop = createPropertiesMap();
- ApplicationProperties properties = new ApplicationProperties(mapprop);
- MessageImpl message = (MessageImpl) Message.Factory.create();
- message.setApplicationProperties(properties);
-
- String text = "someText";
- message.setBody(new AmqpValue(text));
-
- EncodedMessage encodedMessage = encodeMessage(message);
-
- ProtonMessageConverter converter = new ProtonMessageConverter(new SimpleIDGenerator(0));
- ServerJMSTextMessage serverMessage = (ServerJMSTextMessage) converter.inboundJMSType(encodedMessage);
-
- simulatePersistence(serverMessage);
-
- verifyProperties(serverMessage);
-
- Assert.assertEquals(text, serverMessage.getText());
-
- Object obj = converter.outbound((ServerMessage) serverMessage.getInnerMessage(), 0);
-
- reEncodeMsg(obj);
-
- MessageImpl outMessage = (MessageImpl) obj;
- AmqpValue value = (AmqpValue) outMessage.getBody();
- String textValue = (String) value.getValue();
-
- Assert.assertEquals(text, textValue);
-
- System.out.println("output = " + obj);
-
- }
-
- private void simulatePersistence(ServerJMSMessage serverMessage) {
- serverMessage.getInnerMessage().setAddress(new SimpleString("jms.queue.SomeAddress"));
- // This is just to simulate what would happen during the persistence of the message
- // We need to still be able to recover the message when we read it back
- ((EncodingSupport) serverMessage.getInnerMessage()).encode(new EmptyBuffer());
- }
-
- private ProtonJMessage reEncodeMsg(Object obj) {
- ProtonJMessage objOut = (ProtonJMessage) obj;
-
- ByteBuf nettyBuffer = PooledByteBufAllocator.DEFAULT.heapBuffer(1024);
-
- objOut.encode(new NettyWritable(nettyBuffer));
- return objOut;
- }
-
- private EncodedMessage encodeMessage(MessageImpl message) {
- ByteBuf buf = PooledByteBufAllocator.DEFAULT.heapBuffer(1024 * 1024);
- message.encode(new NettyWritable(buf));
- byte[] bytesConvert = new byte[buf.writerIndex()];
- buf.readBytes(bytesConvert);
- return new EncodedMessage(0, bytesConvert, 0, bytesConvert.length);
- }
-
- class EmptyBuffer implements ActiveMQBuffer {
-
- @Override
- public ByteBuf byteBuf() {
- return null;
- }
-
- @Override
- public int capacity() {
- return 0;
- }
-
- @Override
- public int readerIndex() {
- return 0;
- }
-
- @Override
- public void readerIndex(int readerIndex) {
-
- }
-
- @Override
- public int writerIndex() {
- return 0;
- }
-
- @Override
- public void writerIndex(int writerIndex) {
-
- }
-
- @Override
- public void setIndex(int readerIndex, int writerIndex) {
-
- }
-
- @Override
- public int readableBytes() {
- return 0;
- }
-
- @Override
- public int writableBytes() {
- return 0;
- }
-
- @Override
- public boolean readable() {
- return false;
- }
-
- @Override
- public boolean writable() {
- return false;
- }
-
- @Override
- public void clear() {
-
- }
-
- @Override
- public void markReaderIndex() {
-
- }
-
- @Override
- public void resetReaderIndex() {
-
- }
-
- @Override
- public void markWriterIndex() {
-
- }
-
- @Override
- public void resetWriterIndex() {
-
- }
-
- @Override
- public void discardReadBytes() {
-
- }
-
- @Override
- public byte getByte(int index) {
- return 0;
- }
-
- @Override
- public short getUnsignedByte(int index) {
- return 0;
- }
-
- @Override
- public short getShort(int index) {
- return 0;
- }
-
- @Override
- public int getUnsignedShort(int index) {
- return 0;
- }
-
- @Override
- public int getInt(int index) {
- return 0;
- }
-
- @Override
- public long getUnsignedInt(int index) {
- return 0;
- }
-
- @Override
- public long getLong(int index) {
- return 0;
- }
-
- @Override
- public void getBytes(int index, ActiveMQBuffer dst) {
-
- }
-
- @Override
- public void getBytes(int index, ActiveMQBuffer dst, int length) {
-
- }
-
- @Override
- public void getBytes(int index, ActiveMQBuffer dst, int dstIndex, int length) {
-
- }
-
- @Override
- public void getBytes(int index, byte[] dst) {
-
- }
-
- @Override
- public void getBytes(int index, byte[] dst, int dstIndex, int length) {
-
- }
-
- @Override
- public void getBytes(int index, ByteBuffer dst) {
-
- }
-
- @Override
- public char getChar(int index) {
- return 0;
- }
-
- @Override
- public float getFloat(int index) {
- return 0;
- }
-
- @Override
- public double getDouble(int index) {
- return 0;
- }
-
- @Override
- public void setByte(int index, byte value) {
-
- }
-
- @Override
- public void setShort(int index, short value) {
-
- }
-
- @Override
- public void setInt(int index, int value) {
-
- }
-
- @Override
- public void setLong(int index, long value) {
-
- }
-
- @Override
- public void setBytes(int index, ActiveMQBuffer src) {
-
- }
-
- @Override
- public void setBytes(int index, ActiveMQBuffer src, int length) {
-
- }
-
- @Override
- public void setBytes(int index, ActiveMQBuffer src, int srcIndex, int length) {
-
- }
-
- @Override
- public void setBytes(int index, byte[] src) {
-
- }
-
- @Override
- public void setBytes(int index, byte[] src, int srcIndex, int length) {
-
- }
-
- @Override
- public void setBytes(int index, ByteBuffer src) {
-
- }
-
- @Override
- public void setChar(int index, char value) {
-
- }
-
- @Override
- public void setFloat(int index, float value) {
-
- }
-
- @Override
- public void setDouble(int index, double value) {
-
- }
-
- @Override
- public byte readByte() {
- return 0;
- }
-
- @Override
- public int readUnsignedByte() {
- return 0;
- }
-
- @Override
- public short readShort() {
- return 0;
- }
-
- @Override
- public int readUnsignedShort() {
- return 0;
- }
-
- @Override
- public int readInt() {
- return 0;
- }
-
- @Override
- public long readUnsignedInt() {
- return 0;
- }
-
- @Override
- public long readLong() {
- return 0;
- }
-
- @Override
- public char readChar() {
- return 0;
- }
-
- @Override
- public float readFloat() {
- return 0;
- }
-
- @Override
- public double readDouble() {
- return 0;
- }
-
- @Override
- public boolean readBoolean() {
- return false;
- }
-
- @Override
- public SimpleString readNullableSimpleString() {
- return null;
- }
-
- @Override
- public String readNullableString() {
- return null;
- }
-
- @Override
- public SimpleString readSimpleString() {
- return null;
- }
-
- @Override
- public String readString() {
- return null;
- }
-
- @Override
- public String readUTF() {
- return null;
- }
-
- @Override
- public ActiveMQBuffer readBytes(int length) {
- return null;
- }
-
- @Override
- public ActiveMQBuffer readSlice(int length) {
- return null;
- }
-
- @Override
- public void readBytes(ActiveMQBuffer dst) {
-
- }
-
- @Override
- public void readBytes(ActiveMQBuffer dst, int length) {
-
- }
-
- @Override
- public void readBytes(ActiveMQBuffer dst, int dstIndex, int length) {
-
- }
-
- @Override
- public void readBytes(byte[] dst) {
-
- }
-
- @Override
- public void readBytes(byte[] dst, int dstIndex, int length) {
-
- }
-
- @Override
- public void readBytes(ByteBuffer dst) {
-
- }
-
- @Override
- public int skipBytes(int length) {
- return length;
- }
-
- @Override
- public void writeByte(byte value) {
-
- }
-
- @Override
- public void writeShort(short value) {
-
- }
-
- @Override
- public void writeInt(int value) {
-
- }
-
- @Override
- public void writeLong(long value) {
-
- }
-
- @Override
- public void writeChar(char chr) {
-
- }
-
- @Override
- public void writeFloat(float value) {
-
- }
-
- @Override
- public void writeDouble(double value) {
-
- }
-
- @Override
- public void writeBoolean(boolean val) {
-
- }
-
- @Override
- public void writeNullableSimpleString(SimpleString val) {
-
- }
-
- @Override
- public void writeNullableString(String val) {
-
- }
-
- @Override
- public void writeSimpleString(SimpleString val) {
-
- }
-
- @Override
- public void writeString(String val) {
-
- }
-
- @Override
- public void writeUTF(String utf) {
-
- }
-
- @Override
- public void writeBytes(ActiveMQBuffer src, int length) {
-
- }
-
- @Override
- public void writeBytes(ActiveMQBuffer src, int srcIndex, int length) {
-
- }
-
- @Override
- public void writeBytes(byte[] src) {
-
- }
-
- @Override
- public void writeBytes(byte[] src, int srcIndex, int length) {
-
- }
-
- @Override
- public void writeBytes(ByteBuffer src) {
-
- }
-
- @Override
- public void readFully(byte[] b) throws IOException {
- }
-
- @Override
- public void readFully(byte[] b, int off, int len) throws IOException {
- }
-
- @Override
- public String readLine() throws IOException {
- return null;
- }
-
- @Override
- public ActiveMQBuffer copy() {
- return null;
- }
-
- @Override
- public ActiveMQBuffer copy(int index, int length) {
- return null;
- }
-
- @Override
- public ActiveMQBuffer slice() {
- return null;
- }
-
- @Override
- public ActiveMQBuffer slice(int index, int length) {
- return null;
- }
-
- @Override
- public ActiveMQBuffer duplicate() {
- return null;
- }
-
- @Override
- public ByteBuffer toByteBuffer() {
- return null;
- }
-
- @Override
- public ByteBuffer toByteBuffer(int index, int length) {
- return null;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/test/java/org/apache/activemq/artemis/protocol/amqp/converter/TestConversions.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/test/java/org/apache/activemq/artemis/protocol/amqp/converter/TestConversions.java b/artemis-protocols/artemis-amqp-protocol/src/test/java/org/apache/activemq/artemis/protocol/amqp/converter/TestConversions.java
new file mode 100644
index 0000000..19524b0
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/test/java/org/apache/activemq/artemis/protocol/amqp/converter/TestConversions.java
@@ -0,0 +1,792 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.converter;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.PooledByteBufAllocator;
+import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
+import org.apache.activemq.artemis.protocol.amqp.converter.jms.ServerJMSMapMessage;
+import org.apache.activemq.artemis.protocol.amqp.converter.jms.ServerJMSObjectMessage;
+import org.apache.activemq.artemis.protocol.amqp.converter.message.EncodedMessage;
+import org.apache.activemq.artemis.core.server.impl.ServerMessageImpl;
+import org.apache.activemq.artemis.protocol.amqp.converter.jms.ServerJMSBytesMessage;
+import org.apache.activemq.artemis.protocol.amqp.converter.jms.ServerJMSStreamMessage;
+import org.apache.activemq.artemis.protocol.amqp.converter.jms.ServerJMSTextMessage;
+import org.apache.blacklist.ABadClass;
+import org.apache.qpid.proton.amqp.Binary;
+import org.apache.qpid.proton.amqp.messaging.AmqpSequence;
+import org.apache.qpid.proton.amqp.messaging.AmqpValue;
+import org.apache.qpid.proton.amqp.messaging.ApplicationProperties;
+import org.apache.qpid.proton.amqp.messaging.Data;
+import org.apache.qpid.proton.message.Message;
+import org.apache.qpid.proton.message.ProtonJMessage;
+import org.apache.qpid.proton.message.impl.MessageImpl;
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.core.journal.EncodingSupport;
+import org.apache.activemq.artemis.protocol.amqp.converter.jms.ServerJMSMessage;
+import org.apache.activemq.artemis.core.server.ServerMessage;
+import org.apache.activemq.artemis.utils.SimpleIDGenerator;
+import org.junit.Assert;
+import org.junit.Test;
+import org.apache.activemq.artemis.protocol.amqp.util.NettyWritable;
+
+public class TestConversions extends Assert {
+
+ @Test
+ public void testObjectMessageWhiteList() throws Exception {
+ Map<String, Object> mapprop = createPropertiesMap();
+ ApplicationProperties properties = new ApplicationProperties(mapprop);
+ MessageImpl message = (MessageImpl) Message.Factory.create();
+ message.setApplicationProperties(properties);
+
+ byte[] bodyBytes = new byte[4];
+
+ for (int i = 0; i < bodyBytes.length; i++) {
+ bodyBytes[i] = (byte) 0xff;
+ }
+
+ message.setBody(new AmqpValue(new Boolean(true)));
+
+ EncodedMessage encodedMessage = encodeMessage(message);
+
+ ProtonMessageConverter converter = new ProtonMessageConverter(new SimpleIDGenerator(0));
+ ServerJMSObjectMessage serverMessage = (ServerJMSObjectMessage) converter.inboundJMSType(encodedMessage);
+
+ verifyProperties(serverMessage);
+
+ assertEquals(true, serverMessage.getObject());
+
+ Object obj = converter.outbound((ServerMessage) serverMessage.getInnerMessage(), 0);
+
+ AmqpValue value = (AmqpValue) ((Message)obj).getBody();
+ assertEquals(value.getValue(), true);
+
+ }
+
+ @Test
+ public void testObjectMessageNotOnWhiteList() throws Exception {
+
+
+ ProtonMessageConverter converter = new ProtonMessageConverter(new SimpleIDGenerator(0));
+ ServerMessageImpl message = new ServerMessageImpl(1, 1024);
+ message.setType((byte) 2);
+ ServerJMSObjectMessage serverMessage = new ServerJMSObjectMessage(message, 1024);
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ObjectOutputStream ois = new ObjectOutputStream(out);
+ ois.writeObject(new ABadClass());
+ serverMessage.getInnerMessage().getBodyBuffer().writeBytes(out.toByteArray());
+
+ try {
+ converter.outbound((ServerMessage) serverMessage.getInnerMessage(), 0);
+ fail("should throw ClassNotFoundException");
+ }
+ catch (ClassNotFoundException e) {
+ //ignore
+ }
+ }
+
+
+ @Test
+ public void testSimpleConversionBytes() throws Exception {
+ Map<String, Object> mapprop = createPropertiesMap();
+ ApplicationProperties properties = new ApplicationProperties(mapprop);
+ MessageImpl message = (MessageImpl) Message.Factory.create();
+ message.setApplicationProperties(properties);
+
+ byte[] bodyBytes = new byte[4];
+
+ for (int i = 0; i < bodyBytes.length; i++) {
+ bodyBytes[i] = (byte) 0xff;
+ }
+
+ message.setBody(new Data(new Binary(bodyBytes)));
+
+ EncodedMessage encodedMessage = encodeMessage(message);
+
+ ProtonMessageConverter converter = new ProtonMessageConverter(new SimpleIDGenerator(0));
+ ServerJMSBytesMessage serverMessage = (ServerJMSBytesMessage) converter.inboundJMSType(encodedMessage);
+
+ verifyProperties(serverMessage);
+
+ assertEquals(bodyBytes.length, serverMessage.getBodyLength());
+
+ byte[] newBodyBytes = new byte[4];
+
+ serverMessage.readBytes(newBodyBytes);
+
+ Assert.assertArrayEquals(bodyBytes, newBodyBytes);
+
+ Object obj = converter.outbound((ServerMessage) serverMessage.getInnerMessage(), 0);
+
+ System.out.println("output = " + obj);
+
+ }
+
+ private void verifyProperties(javax.jms.Message message) throws Exception {
+ assertEquals(true, message.getBooleanProperty("true"));
+ assertEquals(false, message.getBooleanProperty("false"));
+ assertEquals("bar", message.getStringProperty("foo"));
+ }
+
+ private Map<String, Object> createPropertiesMap() {
+ Map<String, Object> mapprop = new HashMap<>();
+
+ mapprop.put("true", Boolean.TRUE);
+ mapprop.put("false", Boolean.FALSE);
+ mapprop.put("foo", "bar");
+ return mapprop;
+ }
+
+ @Test
+ public void testSimpleConversionMap() throws Exception {
+ Map<String, Object> mapprop = createPropertiesMap();
+ ApplicationProperties properties = new ApplicationProperties(mapprop);
+ MessageImpl message = (MessageImpl) Message.Factory.create();
+ message.setApplicationProperties(properties);
+
+ Map<String, Object> mapValues = new HashMap<>();
+ mapValues.put("somestr", "value");
+ mapValues.put("someint", Integer.valueOf(1));
+
+ message.setBody(new AmqpValue(mapValues));
+
+ EncodedMessage encodedMessage = encodeMessage(message);
+
+ ProtonMessageConverter converter = new ProtonMessageConverter(new SimpleIDGenerator(0));
+ ServerJMSMapMessage serverMessage = (ServerJMSMapMessage) converter.inboundJMSType(encodedMessage);
+
+ verifyProperties(serverMessage);
+
+ Assert.assertEquals(1, serverMessage.getInt("someint"));
+ Assert.assertEquals("value", serverMessage.getString("somestr"));
+
+ Object obj = converter.outbound((ServerMessage) serverMessage.getInnerMessage(), 0);
+
+ reEncodeMsg(obj);
+
+ MessageImpl outMessage = (MessageImpl) obj;
+ AmqpValue value = (AmqpValue) outMessage.getBody();
+ Map mapoutput = (Map) value.getValue();
+
+ assertEquals(Integer.valueOf(1), mapoutput.get("someint"));
+
+ System.out.println("output = " + obj);
+
+ }
+
+ @Test
+ public void testSimpleConversionStream() throws Exception {
+ Map<String, Object> mapprop = createPropertiesMap();
+ ApplicationProperties properties = new ApplicationProperties(mapprop);
+ MessageImpl message = (MessageImpl) Message.Factory.create();
+ message.setApplicationProperties(properties);
+
+ List<Object> objects = new LinkedList<>();
+ objects.add(new Integer(10));
+ objects.add("10");
+
+ message.setBody(new AmqpSequence(objects));
+
+ EncodedMessage encodedMessage = encodeMessage(message);
+
+ ProtonMessageConverter converter = new ProtonMessageConverter(new SimpleIDGenerator(0));
+ ServerJMSStreamMessage serverMessage = (ServerJMSStreamMessage) converter.inboundJMSType(encodedMessage);
+
+ simulatePersistence(serverMessage);
+
+ verifyProperties(serverMessage);
+
+ serverMessage.reset();
+
+ assertEquals(10, serverMessage.readInt());
+ assertEquals("10", serverMessage.readString());
+
+ Object obj = converter.outbound((ServerMessage) serverMessage.getInnerMessage(), 0);
+
+ reEncodeMsg(obj);
+
+ MessageImpl outMessage = (MessageImpl) obj;
+ List list = ((AmqpSequence) outMessage.getBody()).getValue();
+ Assert.assertEquals(Integer.valueOf(10), list.get(0));
+ Assert.assertEquals("10", list.get(1));
+
+ }
+
+ @Test
+ public void testSimpleConversionText() throws Exception {
+ Map<String, Object> mapprop = createPropertiesMap();
+ ApplicationProperties properties = new ApplicationProperties(mapprop);
+ MessageImpl message = (MessageImpl) Message.Factory.create();
+ message.setApplicationProperties(properties);
+
+ String text = "someText";
+ message.setBody(new AmqpValue(text));
+
+ EncodedMessage encodedMessage = encodeMessage(message);
+
+ ProtonMessageConverter converter = new ProtonMessageConverter(new SimpleIDGenerator(0));
+ ServerJMSTextMessage serverMessage = (ServerJMSTextMessage) converter.inboundJMSType(encodedMessage);
+
+ simulatePersistence(serverMessage);
+
+ verifyProperties(serverMessage);
+
+ Assert.assertEquals(text, serverMessage.getText());
+
+ Object obj = converter.outbound((ServerMessage) serverMessage.getInnerMessage(), 0);
+
+ reEncodeMsg(obj);
+
+ MessageImpl outMessage = (MessageImpl) obj;
+ AmqpValue value = (AmqpValue) outMessage.getBody();
+ String textValue = (String) value.getValue();
+
+ Assert.assertEquals(text, textValue);
+
+ System.out.println("output = " + obj);
+
+ }
+
+ private void simulatePersistence(ServerJMSMessage serverMessage) {
+ serverMessage.getInnerMessage().setAddress(new SimpleString("jms.queue.SomeAddress"));
+ // This is just to simulate what would happen during the persistence of the message
+ // We need to still be able to recover the message when we read it back
+ ((EncodingSupport) serverMessage.getInnerMessage()).encode(new EmptyBuffer());
+ }
+
+ private ProtonJMessage reEncodeMsg(Object obj) {
+ ProtonJMessage objOut = (ProtonJMessage) obj;
+
+ ByteBuf nettyBuffer = PooledByteBufAllocator.DEFAULT.heapBuffer(1024);
+
+ objOut.encode(new NettyWritable(nettyBuffer));
+ return objOut;
+ }
+
+ private EncodedMessage encodeMessage(MessageImpl message) {
+ ByteBuf buf = PooledByteBufAllocator.DEFAULT.heapBuffer(1024 * 1024);
+ message.encode(new NettyWritable(buf));
+ byte[] bytesConvert = new byte[buf.writerIndex()];
+ buf.readBytes(bytesConvert);
+ return new EncodedMessage(0, bytesConvert, 0, bytesConvert.length);
+ }
+
+ class EmptyBuffer implements ActiveMQBuffer {
+
+ @Override
+ public ByteBuf byteBuf() {
+ return null;
+ }
+
+ @Override
+ public int capacity() {
+ return 0;
+ }
+
+ @Override
+ public int readerIndex() {
+ return 0;
+ }
+
+ @Override
+ public void readerIndex(int readerIndex) {
+
+ }
+
+ @Override
+ public int writerIndex() {
+ return 0;
+ }
+
+ @Override
+ public void writerIndex(int writerIndex) {
+
+ }
+
+ @Override
+ public void setIndex(int readerIndex, int writerIndex) {
+
+ }
+
+ @Override
+ public int readableBytes() {
+ return 0;
+ }
+
+ @Override
+ public int writableBytes() {
+ return 0;
+ }
+
+ @Override
+ public boolean readable() {
+ return false;
+ }
+
+ @Override
+ public boolean writable() {
+ return false;
+ }
+
+ @Override
+ public void clear() {
+
+ }
+
+ @Override
+ public void markReaderIndex() {
+
+ }
+
+ @Override
+ public void resetReaderIndex() {
+
+ }
+
+ @Override
+ public void markWriterIndex() {
+
+ }
+
+ @Override
+ public void resetWriterIndex() {
+
+ }
+
+ @Override
+ public void discardReadBytes() {
+
+ }
+
+ @Override
+ public byte getByte(int index) {
+ return 0;
+ }
+
+ @Override
+ public short getUnsignedByte(int index) {
+ return 0;
+ }
+
+ @Override
+ public short getShort(int index) {
+ return 0;
+ }
+
+ @Override
+ public int getUnsignedShort(int index) {
+ return 0;
+ }
+
+ @Override
+ public int getInt(int index) {
+ return 0;
+ }
+
+ @Override
+ public long getUnsignedInt(int index) {
+ return 0;
+ }
+
+ @Override
+ public long getLong(int index) {
+ return 0;
+ }
+
+ @Override
+ public void getBytes(int index, ActiveMQBuffer dst) {
+
+ }
+
+ @Override
+ public void getBytes(int index, ActiveMQBuffer dst, int length) {
+
+ }
+
+ @Override
+ public void getBytes(int index, ActiveMQBuffer dst, int dstIndex, int length) {
+
+ }
+
+ @Override
+ public void getBytes(int index, byte[] dst) {
+
+ }
+
+ @Override
+ public void getBytes(int index, byte[] dst, int dstIndex, int length) {
+
+ }
+
+ @Override
+ public void getBytes(int index, ByteBuffer dst) {
+
+ }
+
+ @Override
+ public char getChar(int index) {
+ return 0;
+ }
+
+ @Override
+ public float getFloat(int index) {
+ return 0;
+ }
+
+ @Override
+ public double getDouble(int index) {
+ return 0;
+ }
+
+ @Override
+ public void setByte(int index, byte value) {
+
+ }
+
+ @Override
+ public void setShort(int index, short value) {
+
+ }
+
+ @Override
+ public void setInt(int index, int value) {
+
+ }
+
+ @Override
+ public void setLong(int index, long value) {
+
+ }
+
+ @Override
+ public void setBytes(int index, ActiveMQBuffer src) {
+
+ }
+
+ @Override
+ public void setBytes(int index, ActiveMQBuffer src, int length) {
+
+ }
+
+ @Override
+ public void setBytes(int index, ActiveMQBuffer src, int srcIndex, int length) {
+
+ }
+
+ @Override
+ public void setBytes(int index, byte[] src) {
+
+ }
+
+ @Override
+ public void setBytes(int index, byte[] src, int srcIndex, int length) {
+
+ }
+
+ @Override
+ public void setBytes(int index, ByteBuffer src) {
+
+ }
+
+ @Override
+ public void setChar(int index, char value) {
+
+ }
+
+ @Override
+ public void setFloat(int index, float value) {
+
+ }
+
+ @Override
+ public void setDouble(int index, double value) {
+
+ }
+
+ @Override
+ public byte readByte() {
+ return 0;
+ }
+
+ @Override
+ public int readUnsignedByte() {
+ return 0;
+ }
+
+ @Override
+ public short readShort() {
+ return 0;
+ }
+
+ @Override
+ public int readUnsignedShort() {
+ return 0;
+ }
+
+ @Override
+ public int readInt() {
+ return 0;
+ }
+
+ @Override
+ public long readUnsignedInt() {
+ return 0;
+ }
+
+ @Override
+ public long readLong() {
+ return 0;
+ }
+
+ @Override
+ public char readChar() {
+ return 0;
+ }
+
+ @Override
+ public float readFloat() {
+ return 0;
+ }
+
+ @Override
+ public double readDouble() {
+ return 0;
+ }
+
+ @Override
+ public boolean readBoolean() {
+ return false;
+ }
+
+ @Override
+ public SimpleString readNullableSimpleString() {
+ return null;
+ }
+
+ @Override
+ public String readNullableString() {
+ return null;
+ }
+
+ @Override
+ public SimpleString readSimpleString() {
+ return null;
+ }
+
+ @Override
+ public String readString() {
+ return null;
+ }
+
+ @Override
+ public String readUTF() {
+ return null;
+ }
+
+ @Override
+ public ActiveMQBuffer readBytes(int length) {
+ return null;
+ }
+
+ @Override
+ public ActiveMQBuffer readSlice(int length) {
+ return null;
+ }
+
+ @Override
+ public void readBytes(ActiveMQBuffer dst) {
+
+ }
+
+ @Override
+ public void readBytes(ActiveMQBuffer dst, int length) {
+
+ }
+
+ @Override
+ public void readBytes(ActiveMQBuffer dst, int dstIndex, int length) {
+
+ }
+
+ @Override
+ public void readBytes(byte[] dst) {
+
+ }
+
+ @Override
+ public void readBytes(byte[] dst, int dstIndex, int length) {
+
+ }
+
+ @Override
+ public void readBytes(ByteBuffer dst) {
+
+ }
+
+ @Override
+ public int skipBytes(int length) {
+ return length;
+ }
+
+ @Override
+ public void writeByte(byte value) {
+
+ }
+
+ @Override
+ public void writeShort(short value) {
+
+ }
+
+ @Override
+ public void writeInt(int value) {
+
+ }
+
+ @Override
+ public void writeLong(long value) {
+
+ }
+
+ @Override
+ public void writeChar(char chr) {
+
+ }
+
+ @Override
+ public void writeFloat(float value) {
+
+ }
+
+ @Override
+ public void writeDouble(double value) {
+
+ }
+
+ @Override
+ public void writeBoolean(boolean val) {
+
+ }
+
+ @Override
+ public void writeNullableSimpleString(SimpleString val) {
+
+ }
+
+ @Override
+ public void writeNullableString(String val) {
+
+ }
+
+ @Override
+ public void writeSimpleString(SimpleString val) {
+
+ }
+
+ @Override
+ public void writeString(String val) {
+
+ }
+
+ @Override
+ public void writeUTF(String utf) {
+
+ }
+
+ @Override
+ public void writeBytes(ActiveMQBuffer src, int length) {
+
+ }
+
+ @Override
+ public void writeBytes(ActiveMQBuffer src, int srcIndex, int length) {
+
+ }
+
+ @Override
+ public void writeBytes(byte[] src) {
+
+ }
+
+ @Override
+ public void writeBytes(byte[] src, int srcIndex, int length) {
+
+ }
+
+ @Override
+ public void writeBytes(ByteBuffer src) {
+
+ }
+
+ @Override
+ public void readFully(byte[] b) throws IOException {
+ }
+
+ @Override
+ public void readFully(byte[] b, int off, int len) throws IOException {
+ }
+
+ @Override
+ public String readLine() throws IOException {
+ return null;
+ }
+
+ @Override
+ public ActiveMQBuffer copy() {
+ return null;
+ }
+
+ @Override
+ public ActiveMQBuffer copy(int index, int length) {
+ return null;
+ }
+
+ @Override
+ public ActiveMQBuffer slice() {
+ return null;
+ }
+
+ @Override
+ public ActiveMQBuffer slice(int index, int length) {
+ return null;
+ }
+
+ @Override
+ public ActiveMQBuffer duplicate() {
+ return null;
+ }
+
+ @Override
+ public ByteBuffer toByteBuffer() {
+ return null;
+ }
+
+ @Override
+ public ByteBuffer toByteBuffer(int index, int length) {
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/test/java/org/apache/activemq/artemis/protocol/amqp/sasl/ClientSASLPlain.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/test/java/org/apache/activemq/artemis/protocol/amqp/sasl/ClientSASLPlain.java b/artemis-protocols/artemis-amqp-protocol/src/test/java/org/apache/activemq/artemis/protocol/amqp/sasl/ClientSASLPlain.java
new file mode 100644
index 0000000..0e9d0d4
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/test/java/org/apache/activemq/artemis/protocol/amqp/sasl/ClientSASLPlain.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.sasl;
+
+/**
+ * This will generate what a client would generate for bytes on Plain sasl. Used on test
+ */
+public class ClientSASLPlain {
+
+ private String username;
+ private String password;
+
+ public ClientSASLPlain(String user, String password) {
+ this.username = user;
+ this.password = password;
+ }
+
+ public String getName() {
+ return "PLAIN";
+ }
+
+ public byte[] getBytes() {
+
+ if (username == null) {
+ username = "";
+ }
+
+ if (password == null) {
+ password = "";
+ }
+
+ byte[] usernameBytes = username.getBytes();
+ byte[] passwordBytes = password.getBytes();
+ byte[] data = new byte[usernameBytes.length + passwordBytes.length + 2];
+ System.arraycopy(usernameBytes, 0, data, 1, usernameBytes.length);
+ System.arraycopy(passwordBytes, 0, data, 2 + usernameBytes.length, passwordBytes.length);
+ return data;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/test/java/org/apache/activemq/artemis/protocol/amqp/sasl/PlainSASLTest.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/test/java/org/apache/activemq/artemis/protocol/amqp/sasl/PlainSASLTest.java b/artemis-protocols/artemis-amqp-protocol/src/test/java/org/apache/activemq/artemis/protocol/amqp/sasl/PlainSASLTest.java
new file mode 100644
index 0000000..d259de2
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/test/java/org/apache/activemq/artemis/protocol/amqp/sasl/PlainSASLTest.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.sasl;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class PlainSASLTest {
+
+ @Test
+ public void testPlain() {
+ ClientSASLPlain plainSASL = new ClientSASLPlain("user-me", "password-secret");
+ byte[] bytesResult = plainSASL.getBytes();
+
+ ServerSASLPlain serverSASLPlain = new ServerSASLPlain();
+ PlainSASLResult result = (PlainSASLResult) serverSASLPlain.processSASL(bytesResult);
+ Assert.assertEquals("user-me", result.getUser());
+ Assert.assertEquals("password-secret", result.getPassword());
+ }
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-amqp-protocol/src/test/java/org/apache/activemq/artemis/protocol/amqp/util/CreditsSemaphoreTest.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-amqp-protocol/src/test/java/org/apache/activemq/artemis/protocol/amqp/util/CreditsSemaphoreTest.java b/artemis-protocols/artemis-amqp-protocol/src/test/java/org/apache/activemq/artemis/protocol/amqp/util/CreditsSemaphoreTest.java
new file mode 100644
index 0000000..c608b85
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/test/java/org/apache/activemq/artemis/protocol/amqp/util/CreditsSemaphoreTest.java
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.protocol.amqp.util;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class CreditsSemaphoreTest {
+
+ final CreditsSemaphore semaphore = new CreditsSemaphore(10);
+
+ final AtomicInteger errors = new AtomicInteger(0);
+
+ final AtomicInteger acquired = new AtomicInteger(0);
+
+ final CountDownLatch waiting = new CountDownLatch(1);
+
+ Thread thread = new Thread() {
+ @Override
+ public void run() {
+ try {
+ for (int i = 0; i < 12; i++) {
+ if (!semaphore.tryAcquire()) {
+ waiting.countDown();
+ semaphore.acquire();
+ }
+ acquired.incrementAndGet();
+ }
+ }
+ catch (Throwable e) {
+ e.printStackTrace();
+ errors.incrementAndGet();
+ }
+ }
+ };
+
+ @Test
+ public void testSetAndRelease() throws Exception {
+ thread.start();
+
+ // 5 seconds would be an eternity here
+ Assert.assertTrue(waiting.await(5, TimeUnit.SECONDS));
+
+ Assert.assertEquals(0, semaphore.getCredits());
+
+ long timeout = System.currentTimeMillis() + 1000;
+ while (!semaphore.hasQueuedThreads() && System.currentTimeMillis() < timeout) {
+ Thread.sleep(10);
+ }
+
+ Assert.assertTrue(semaphore.hasQueuedThreads());
+
+ semaphore.setCredits(2);
+
+ thread.join();
+
+ Assert.assertEquals(12, acquired.get());
+
+ Assert.assertFalse(semaphore.hasQueuedThreads());
+ }
+
+ @Test
+ public void testDownAndUp() throws Exception {
+ thread.start();
+
+ // 5 seconds would be an eternity here
+ Assert.assertTrue(waiting.await(5, TimeUnit.SECONDS));
+
+ Assert.assertEquals(0, semaphore.getCredits());
+
+ long timeout = System.currentTimeMillis() + 1000;
+ while (!semaphore.hasQueuedThreads() && System.currentTimeMillis() < timeout) {
+ Thread.sleep(10);
+ }
+
+ Assert.assertTrue(semaphore.hasQueuedThreads());
+
+ semaphore.release(2);
+
+ thread.join();
+
+ Assert.assertEquals(12, acquired.get());
+
+ Assert.assertFalse(semaphore.hasQueuedThreads());
+ }
+
+ @Test
+ public void testStartedZeroedSetLater() throws Exception {
+ semaphore.setCredits(0);
+
+ thread.start();
+
+ // 5 seconds would be an eternity here
+ Assert.assertTrue(waiting.await(5, TimeUnit.SECONDS));
+
+ Assert.assertEquals(0, semaphore.getCredits());
+
+ long timeout = System.currentTimeMillis() + 1000;
+ while (!semaphore.hasQueuedThreads() && System.currentTimeMillis() < timeout) {
+ Thread.sleep(10);
+ }
+
+ Assert.assertTrue(semaphore.hasQueuedThreads());
+
+ Assert.assertEquals(0, acquired.get());
+
+ semaphore.setCredits(12);
+
+ thread.join();
+
+ Assert.assertEquals(12, acquired.get());
+
+ Assert.assertFalse(semaphore.hasQueuedThreads());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/pom.xml
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/pom.xml b/artemis-protocols/artemis-proton-plug/pom.xml
deleted file mode 100644
index 2412a43..0000000
--- a/artemis-protocols/artemis-proton-plug/pom.xml
+++ /dev/null
@@ -1,137 +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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <artifactId>artemis-protocols</artifactId>
- <groupId>org.apache.activemq</groupId>
- <version>1.5.0-SNAPSHOT</version>
- </parent>
- <modelVersion>4.0.0</modelVersion>
-
- <artifactId>artemis-proton-plug</artifactId>
- <name>ActiveMQ Artemis Proton Protocol</name>
-
- <properties>
- <activemq.basedir>${project.basedir}/../..</activemq.basedir>
- </properties>
-
- <dependencies>
- <!-- JMS Client because of some conversions that are done -->
- <dependency>
- <groupId>org.apache.activemq</groupId>
- <artifactId>artemis-jms-client</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.activemq</groupId>
- <artifactId>artemis-core-client</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.jboss.logging</groupId>
- <artifactId>jboss-logging-processor</artifactId>
- <scope>provided</scope>
- <optional>true</optional>
- </dependency>
-
- <!--
- JBoss Logging
- -->
-
-
- <dependency>
- <groupId>org.jboss.logmanager</groupId>
- <artifactId>jboss-logmanager</artifactId>
- <scope>test</scope>
- </dependency>
-
- <!-- this is for the log assertion -->
- <dependency>
- <groupId>org.apache.activemq</groupId>
- <artifactId>artemis-commons</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.logging</groupId>
- <artifactId>jboss-logging</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.activemq</groupId>
- <artifactId>artemis-server</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.activemq</groupId>
- <artifactId>artemis-commons</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.qpid</groupId>
- <artifactId>proton-j</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.apache.qpid</groupId>
- <artifactId>qpid-client</artifactId>
- <version>0.24</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.qpid</groupId>
- <artifactId>qpid-jms-client</artifactId>
- <version>0.5.0</version>
- <scope>test</scope>
- </dependency>
-
-
-
- <dependency>
- <groupId>org.apache.geronimo.specs</groupId>
- <artifactId>geronimo-jms_2.0_spec</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
-
-
- </dependencies>
-
- <!-- We use the proton plug test classes in some of the Artemis Integration tests -->
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <version>2.6</version>
- <executions>
- <execution>
- <goals>
- <goal>test-jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
- <packaging>bundle</packaging>
-</project>
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPClientConnectionContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPClientConnectionContext.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPClientConnectionContext.java
deleted file mode 100644
index 1abd96f..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPClientConnectionContext.java
+++ /dev/null
@@ -1,36 +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.proton.plug;
-
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-
-/**
- * This is valid only on a client connection.
- */
-public interface AMQPClientConnectionContext extends AMQPConnectionContext {
-
- /**
- * This will send an open and block for its return on AMQP protocol.
- *
- * @throws Exception
- */
- void clientOpen(ClientSASL sasl) throws Exception;
-
- AMQPClientSessionContext createClientSession() throws ActiveMQAMQPException;
-
- void setContainer(String containerID);
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPClientReceiverContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPClientReceiverContext.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPClientReceiverContext.java
deleted file mode 100644
index 514ee19..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPClientReceiverContext.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug;
-
-import java.util.concurrent.TimeUnit;
-
-import org.apache.qpid.proton.message.ProtonJMessage;
-
-public interface AMQPClientReceiverContext {
-
- ProtonJMessage receiveMessage(int time, TimeUnit unit) throws Exception;
-
- void flow(int credits);
-
- void drain(int i);
-
- int drained();
-
- boolean isDraining();
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPClientSenderContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPClientSenderContext.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPClientSenderContext.java
deleted file mode 100644
index 44d1056..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPClientSenderContext.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug;
-
-import org.apache.qpid.proton.message.ProtonJMessage;
-
-public interface AMQPClientSenderContext {
-
- void send(ProtonJMessage message);
-
- String getAddress();
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPClientSessionContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPClientSessionContext.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPClientSessionContext.java
deleted file mode 100644
index 44cec7c..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPClientSessionContext.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug;
-
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-
-public interface AMQPClientSessionContext extends AMQPSessionContext {
-
- AMQPClientSenderContext createSender(String address, boolean preSettled) throws ActiveMQAMQPException;
-
- AMQPClientSenderContext createDynamicSender(boolean preSettled) throws ActiveMQAMQPException;
-
- AMQPClientReceiverContext createReceiver(String address) throws ActiveMQAMQPException;
-
- AMQPClientReceiverContext createReceiver(String name, String address) throws ActiveMQAMQPException;
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPConnectionCallback.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPConnectionCallback.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPConnectionCallback.java
deleted file mode 100644
index f4ed64c..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPConnectionCallback.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug;
-
-import io.netty.buffer.ByteBuf;
-import org.apache.activemq.artemis.core.transaction.Transaction;
-import org.apache.qpid.proton.amqp.Binary;
-import org.apache.qpid.proton.engine.Connection;
-import org.proton.plug.exceptions.ActiveMQAMQPException;
-
-public interface AMQPConnectionCallback {
-
- void close();
-
- /**
- * this is called when bytes are available to be sent to the client.
- * you have to callback {@link org.proton.plug.AMQPConnectionContext#outputDone(int)} after you're done with this buffer
- *
- * @param bytes
- */
- void onTransport(ByteBuf bytes, AMQPConnectionContext connection);
-
- AMQPSessionCallback createSessionCallback(AMQPConnectionContext connection);
-
- void setConnection(AMQPConnectionContext connection);
-
- AMQPConnectionContext getConnection();
-
- ServerSASL[] getSASLMechnisms();
-
- boolean isSupportsAnonymous();
-
- void sendSASLSupported();
-
- boolean validateConnection(Connection connection, SASLResult saslResult);
-
- Binary newTransaction();
-
- Transaction getTransaction(Binary txid) throws ActiveMQAMQPException;
-
- void removeTransaction(Binary txid);
-
-
-}
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a838bf04/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPConnectionContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPConnectionContext.java b/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPConnectionContext.java
deleted file mode 100644
index 9123006..0000000
--- a/artemis-protocols/artemis-proton-plug/src/main/java/org/proton/plug/AMQPConnectionContext.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.proton.plug;
-
-import org.apache.qpid.proton.amqp.Symbol;
-
-import io.netty.buffer.ByteBuf;
-
-public interface AMQPConnectionContext {
-
- void close();
-
- Object getLock();
-
- boolean checkDataReceived();
-
- long getCreationTime();
-
- SASLResult getSASLResult();
-
- /**
- * Load and return a <code>[]Symbol</code> that contains the connection capabilities
- * offered to new connections
- *
- * @return the capabilities that are offered to new remote peers on connect.
- */
- Symbol[] getConnectionCapabilitiesOffered();
-
- /**
- * Even though we are currently always sending packets asynchronsouly
- * we have a possibility to start trusting on the network flow control
- * and always sync on the send of the packet
- *
- * This is for future use and should be kept returning false.
- *
- * We will have to do some testing before we make this return true
- */
- boolean isSyncOnFlush();
-
- int capacity();
-
- /**
- * This is for the Remoting layer to push bytes on the AMQP Connection
- * The buffer readerIndex should be at the latest read byte after this method is called
- */
- void inputBuffer(ByteBuf buffer);
-
- void flush();
-
- /**
- * To be called when the bytes were sent down the stream (flushed on the socket for example)
- *
- * @param numberOfBytes
- */
- void outputDone(int numberOfBytes);
-
-}