[1/5] activemq-artemis git commit: This closes #1832

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[1/5] activemq-artemis git commit: This closes #1832

michaelpearce
Repository: activemq-artemis
Updated Branches:
  refs/heads/master 56e1df3c3 -> 4883b0360


This closes #1832


Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/4883b036
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/4883b036
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/4883b036

Branch: refs/heads/master
Commit: 4883b0360ed54e950d4cda9fcfd8c5be3cf88cc6
Parents: 56e1df3 38c45c9
Author: Michael Andre Pearce <[hidden email]>
Authored: Wed Feb 7 15:27:29 2018 +0000
Committer: Michael Andre Pearce <[hidden email]>
Committed: Wed Feb 7 15:27:29 2018 +0000

----------------------------------------------------------------------
 .../artemis/api/core/ParameterisedAddress.java  |  98 ++++++
 .../artemis/api/core/QueueAttributes.java       |  79 +++++
 .../activemq/artemis/utils/uri/URISupport.java  |  32 +-
 .../config/ActiveMQDefaultConfiguration.java    |  12 +
 .../artemis/api/core/client/ClientSession.java  |  77 +++++
 .../core/management/ActiveMQServerControl.java  |  16 +
 .../api/core/management/QueueControl.java       |  12 +
 .../core/client/impl/AddressQueryImpl.java      |  20 +-
 .../core/client/impl/ClientSessionImpl.java     |  96 +++++-
 .../core/client/impl/QueueQueryImpl.java        |  33 ++
 .../core/impl/ActiveMQSessionContext.java       |  45 ++-
 .../impl/wireformat/CreateQueueMessage_V2.java  |  41 ++-
 .../wireformat/CreateSharedQueueMessage_V2.java |  75 ++++-
 .../SessionBindingQueryResponseMessage_V4.java  |  35 +-
 .../SessionQueueQueryResponseMessage_V3.java    |  49 ++-
 .../artemis/core/server/QueueQueryResult.java   |  20 +-
 .../spi/core/remoting/SessionContext.java       |  25 ++
 .../artemis/jms/client/ActiveMQDestination.java |  28 +-
 .../jms/client/ActiveMQMessageProducer.java     |  26 +-
 .../artemis/jms/client/ActiveMQSession.java     |  88 ++++-
 .../jms/client/ActiveMQParameterTest.java       |  63 ++++
 .../client/HornetQClientSessionContext.java     |   2 +-
 .../core/config/CoreQueueConfiguration.java     |  36 +++
 .../deployers/impl/FileConfigurationParser.java |  19 +-
 .../impl/ActiveMQServerControlImpl.java         |  15 +-
 .../core/management/impl/QueueControlImpl.java  |  24 ++
 .../core/management/impl/view/QueueView.java    |   8 +-
 .../view/predicate/QueueFilterPredicate.java    |   6 +-
 .../core/persistence/QueueBindingInfo.java      |   4 +
 .../journal/AbstractJournalStorageManager.java  |   2 +-
 .../codec/PersistentQueueBindingEncoding.java   |  26 +-
 .../artemis/core/postoffice/PostOffice.java     |   3 +-
 .../core/postoffice/impl/PostOfficeImpl.java    |   7 +-
 .../core/ServerSessionPacketHandler.java        |   8 +-
 .../artemis/core/server/ActiveMQServer.java     |  17 +
 .../artemis/core/server/BindingQueryResult.java |  20 +-
 .../activemq/artemis/core/server/Queue.java     |   6 +
 .../artemis/core/server/QueueConfig.java        |  39 ++-
 .../artemis/core/server/ServerSession.java      |  31 ++
 .../core/server/impl/ActiveMQServerImpl.java    |  78 ++++-
 .../core/server/impl/LastValueQueue.java        |   8 +-
 .../server/impl/PostOfficeJournalLoader.java    |   1 +
 .../core/server/impl/QueueFactoryImpl.java      |  11 +-
 .../artemis/core/server/impl/QueueImpl.java     |  50 ++-
 .../core/server/impl/ServerSessionImpl.java     |  71 ++++-
 .../core/settings/impl/AddressSettings.java     |  60 +++-
 .../resources/schema/artemis-configuration.xsd  |  22 +-
 .../impl/ScheduledDeliveryHandlerTest.java      |  15 +
 .../test/resources/artemis-configuration.xsd    |  23 +-
 .../tests/integration/amqp/JMSLVQTest.java      |   2 +-
 .../client/MultipleProducersTest.java           |   2 +-
 .../client/SessionCreateAndDeleteQueueTest.java |   2 +-
 .../integration/client/UpdateQueueTest.java     |   2 +-
 .../integration/jms/client/ExclusiveTest.java   | 319 +++++++++++++++++++
 .../tests/integration/jms/client/LVQTest.java   | 145 +++++++++
 .../ActiveMQServerControlUsingCoreTest.java     |  10 +
 .../management/QueueControlUsingCoreTest.java   |  10 +
 .../integration/server/LVQRecoveryTest.java     |   4 +-
 .../tests/integration/server/LVQTest.java       |   2 +-
 .../jms/tests/message/MessageHeaderTest.java    |  27 ++
 .../unit/core/postoffice/impl/FakeQueue.java    |  17 +
 .../core/server/impl/fakes/FakePostOffice.java  |   3 +-
 62 files changed, 1988 insertions(+), 139 deletions(-)
----------------------------------------------------------------------


Reply | Threaded
Open this post in threaded view
|

[2/5] activemq-artemis git commit: ARTEMIS-853 Support for exclusive consumers

michaelpearce
ARTEMIS-853 Support for exclusive consumers

Rationalise and re-use URISupport.

Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/38c45c92
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/38c45c92
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/38c45c92

Branch: refs/heads/master
Commit: 38c45c92142cd6a3b9f49f2d436d7a0665309c00
Parents: dc41f3c
Author: Michael André Pearce <[hidden email]>
Authored: Fri Feb 2 18:19:40 2018 +0000
Committer: Michael Andre Pearce <[hidden email]>
Committed: Wed Feb 7 15:27:29 2018 +0000

----------------------------------------------------------------------
 .../artemis/api/core/ParameterisedAddress.java  | 55 +++++++-------------
 .../activemq/artemis/utils/uri/URISupport.java  | 32 ++++++++----
 .../jms/client/ActiveMQParameterTest.java       | 17 ++++++
 3 files changed, 58 insertions(+), 46 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/38c45c92/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/ParameterisedAddress.java
----------------------------------------------------------------------
diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/ParameterisedAddress.java b/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/ParameterisedAddress.java
index bbc3c4d..6a6d45c 100644
--- a/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/ParameterisedAddress.java
+++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/ParameterisedAddress.java
@@ -16,46 +16,32 @@
  */
 package org.apache.activemq.artemis.api.core;
 
+import static org.apache.activemq.artemis.utils.uri.URISupport.appendParameters;
+import static org.apache.activemq.artemis.utils.uri.URISupport.parseQuery;
+
+import java.net.URISyntaxException;
 import java.util.Map;
 
+import org.apache.activemq.artemis.utils.uri.URISupport;
+
 public class ParameterisedAddress {
 
-   public static SimpleString toParameterisedAddress(SimpleString address, Map<String, String> parameters) {
-      if (parameters != null && parameters.size() > 0) {
+   public static SimpleString toParameterisedAddress(SimpleString address, Map<String, String> parameters) throws URISyntaxException {
+      if (parameters != null && !parameters.isEmpty()) {
          return SimpleString.toSimpleString(toParameterisedAddress(address.toString(), parameters));
       } else {
          return address;
       }
    }
 
-   public static String toParameterisedAddress(String address, Map<String, String> parameters) {
-      if (parameters != null && parameters.size() > 0) {
-         StringBuilder stringBuilder = new StringBuilder(address).append(PARAMETER_MARKER);
-         return toParameterString(stringBuilder, parameters).toString();
+   public static String toParameterisedAddress(String address, Map<String, String> parameters) throws URISyntaxException {
+      if (parameters != null && !parameters.isEmpty()) {
+         return appendParameters(new StringBuilder(address), parameters).toString();
       } else {
          return address;
       }
    }
 
-   private static StringBuilder toParameterString(StringBuilder stringBuilder, Map<String, String> parameters) {
-      boolean first = true;
-      for (Map.Entry<String, String> entry : parameters.entrySet()) {
-         if (first) {
-            first = false;
-         } else {
-            stringBuilder.append(PARAMETER_SEPERATOR);
-         }
-         stringBuilder.append(entry.getKey()).append(PARAMETER_KEY_VALUE_SEPERATOR).append(entry.getValue());
-      }
-      return stringBuilder;
-   }
-
-   public static char PARAMETER_SEPERATOR = '&';
-   public static char PARAMETER_KEY_VALUE_SEPERATOR = '=';
-   public static char PARAMETER_MARKER = '?';
-   public static String PARAMETER_SEPERATOR_STRING = Character.toString(PARAMETER_SEPERATOR);
-   public static String PARAMETER_KEY_VALUE_SEPERATOR_STRING = Character.toString(PARAMETER_KEY_VALUE_SEPERATOR);
-   public static String PARAMETER_MARKER_STRING = Character.toString(PARAMETER_MARKER);
    private final SimpleString address;
    private final QueueAttributes queueAttributes;
 
@@ -81,22 +67,17 @@ public class ParameterisedAddress {
    }
 
    public ParameterisedAddress(String address) {
-      int index = address.indexOf(PARAMETER_MARKER);
+      int index = address.indexOf('?');
       if (index == -1) {
          this.address = SimpleString.toSimpleString(address);
          this.queueAttributes = null;
       } else {
          this.address = SimpleString.toSimpleString(address.substring(0, index));
-         String parametersString = address.substring(index + 1, address.length());
-         String[] parameterPairs = parametersString.split(PARAMETER_SEPERATOR_STRING);
          QueueAttributes queueAttributes = new QueueAttributes();
-         for (String param : parameterPairs) {
-            String[] keyValue = param.split(PARAMETER_KEY_VALUE_SEPERATOR_STRING);
-            if (keyValue.length != 2) {
-               throw new IllegalArgumentException("Malformed parameter section " + param);
-            } else {
-               queueAttributes.set(keyValue[0], keyValue[1]);
-            }
+         try {
+            parseQuery(address).forEach(queueAttributes::set);
+         } catch (URISyntaxException use) {
+            throw new IllegalArgumentException("Malformed parameters in address " + address);
          }
          this.queueAttributes = queueAttributes;
       }
@@ -107,11 +88,11 @@ public class ParameterisedAddress {
    }
 
    public static boolean isParameterised(String address) {
-      return address.contains(PARAMETER_MARKER_STRING);
+      return URISupport.containsQuery(address);
    }
 
    public static boolean isParameterised(SimpleString address) {
-      return address.contains(PARAMETER_MARKER);
+      return URISupport.containsQuery(address);
    }
 
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/38c45c92/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/URISupport.java
----------------------------------------------------------------------
diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/URISupport.java b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/URISupport.java
index e26993d..7530759 100644
--- a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/URISupport.java
+++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/URISupport.java
@@ -27,6 +27,8 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.activemq.artemis.api.core.SimpleString;
+
 /**
  * Utility class that provides methods for parsing URI's
  *
@@ -75,7 +77,7 @@ public class URISupport {
       }
 
       public URI toURI() throws URISyntaxException {
-         StringBuffer sb = new StringBuffer();
+         StringBuilder sb = new StringBuilder();
          if (scheme != null) {
             sb.append(scheme);
             sb.append(':');
@@ -98,18 +100,23 @@ public class URISupport {
             sb.append('/');
             sb.append(path);
          }
-         if (!parameters.isEmpty()) {
-            sb.append("?");
-            sb.append(createQueryString(parameters));
-         }
+         appendParameters(sb, parameters);
          if (fragment != null) {
-            sb.append("#");
+            sb.append('#');
             sb.append(fragment);
          }
          return new URI(sb.toString());
       }
    }
 
+   public static StringBuilder appendParameters(StringBuilder sb, Map<String, String> parameters) throws URISyntaxException {
+      if (!parameters.isEmpty()) {
+         sb.append('?');
+         sb.append(createQueryString(parameters));
+      }
+      return sb;
+   }
+
    /**
     * Give a URI break off any URI options and store them in a Key / Value Mapping.
     *
@@ -122,8 +129,7 @@ public class URISupport {
          uri = uri.substring(uri.lastIndexOf("?") + 1); // get only the relevant part of the query
          Map<String, String> rc = new HashMap<>();
          if (uri != null && !uri.isEmpty()) {
-            parseParameters(rc, uri.split("&"));
-            parseParameters(rc, uri.split(";"));
+            parseParameters(rc, uri.split("[&;]"));
          }
          return rc;
       } catch (UnsupportedEncodingException e) {
@@ -131,6 +137,14 @@ public class URISupport {
       }
    }
 
+   public static boolean containsQuery(String uri) {
+      return uri.contains("?");
+   }
+
+   public static boolean containsQuery(SimpleString uri) {
+      return uri.contains('?');
+   }
+
    private static void parseParameters(Map<String, String> rc,
                                        String[] parameters) throws UnsupportedEncodingException {
       for (String parameter : parameters) {
@@ -198,7 +212,7 @@ public class URISupport {
                                      Map<String, String> queryParameters,
                                      String optionPrefix) throws URISyntaxException {
       if (queryParameters != null && !queryParameters.isEmpty()) {
-         StringBuffer newQuery = uri.getRawQuery() != null ? new StringBuffer(uri.getRawQuery()) : new StringBuffer();
+         StringBuilder newQuery = uri.getRawQuery() != null ? new StringBuilder(uri.getRawQuery()) : new StringBuilder();
          for (Map.Entry<String, String> param : queryParameters.entrySet()) {
             if (param.getKey().startsWith(optionPrefix)) {
                if (newQuery.length() != 0) {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/38c45c92/artemis-jms-client/src/test/java/org/apache/activemq/artemis/jms/client/ActiveMQParameterTest.java
----------------------------------------------------------------------
diff --git a/artemis-jms-client/src/test/java/org/apache/activemq/artemis/jms/client/ActiveMQParameterTest.java b/artemis-jms-client/src/test/java/org/apache/activemq/artemis/jms/client/ActiveMQParameterTest.java
index cf42fe3..1cb179d 100644
--- a/artemis-jms-client/src/test/java/org/apache/activemq/artemis/jms/client/ActiveMQParameterTest.java
+++ b/artemis-jms-client/src/test/java/org/apache/activemq/artemis/jms/client/ActiveMQParameterTest.java
@@ -18,6 +18,7 @@ package org.apache.activemq.artemis.jms.client;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import org.junit.Test;
@@ -42,5 +43,21 @@ public class ActiveMQParameterTest {
 
       activeMQDestination = new ActiveMQQueue("jms.queue.foo?last-value=false");
       assertFalse(activeMQDestination.getQueueAttributes().getLastValue());
+
+   }
+
+   @Test
+   public void testMultipleQueueParameters() {
+      ActiveMQDestination activeMQDestination = new ActiveMQQueue("jms.queue.foo?last-value=true&exclusive=true");
+      assertEquals("jms.queue.foo", activeMQDestination.getAddress());
+      assertTrue(activeMQDestination.getQueueAttributes().getLastValue());
+      assertTrue(activeMQDestination.getQueueAttributes().getExclusive());
+   }
+
+   @Test
+   public void testNoQueueParameters() {
+      ActiveMQDestination activeMQDestination = new ActiveMQQueue("jms.queue.foo");
+      assertEquals("jms.queue.foo", activeMQDestination.getAddress());
+      assertNull(activeMQDestination.getQueueAttributes());
    }
 }

Reply | Threaded
Open this post in threaded view
|

[3/5] activemq-artemis git commit: ARTEMIS-853 Support for exclusive consumers

michaelpearce
In reply to this post by michaelpearce
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
index a3e817b..55125bd 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
@@ -559,7 +559,7 @@ public class ServerSessionImpl implements ServerSession, FailureListener {
    @Override
    public Queue createQueue(AddressInfo addressInfo, SimpleString name, SimpleString filterString, boolean temporary, boolean durable) throws Exception {
       AddressSettings as = server.getAddressSettingsRepository().getMatch(addressInfo.getName().toString());
-      return createQueue(addressInfo, name, filterString, temporary, durable, as.getDefaultMaxConsumers(), as.isDefaultPurgeOnNoConsumers(), false);
+      return createQueue(addressInfo, name, filterString, temporary, durable, as.getDefaultMaxConsumers(), as.isDefaultPurgeOnNoConsumers(), as.isDefaultExclusiveQueue(), as.isDefaultLastValueQueue(), false);
    }
 
    public Queue createQueue(final AddressInfo addressInfo,
@@ -569,6 +569,8 @@ public class ServerSessionImpl implements ServerSession, FailureListener {
                             final boolean durable,
                             final int maxConsumers,
                             final boolean purgeOnNoConsumers,
+                            final boolean exclusive,
+                            final boolean lastValue,
                             final boolean autoCreated) throws Exception {
       final SimpleString unPrefixedName = removePrefix(name);
 
@@ -583,7 +585,7 @@ public class ServerSessionImpl implements ServerSession, FailureListener {
 
       server.checkQueueCreationLimit(getUsername());
 
-      Queue queue = server.createQueue(art, unPrefixedName, filterString, SimpleString.toSimpleString(getUsername()), durable, temporary, autoCreated, maxConsumers, purgeOnNoConsumers, server.getAddressSettingsRepository().getMatch(art.getName().toString()).isAutoCreateAddresses());
+      Queue queue = server.createQueue(art, unPrefixedName, filterString, SimpleString.toSimpleString(getUsername()), durable, temporary, autoCreated, maxConsumers, purgeOnNoConsumers, exclusive, lastValue, server.getAddressSettingsRepository().getMatch(art.getName().toString()).isAutoCreateAddresses());
 
       if (temporary) {
          // Temporary queue in core simply means the queue will be deleted if
@@ -622,7 +624,30 @@ public class ServerSessionImpl implements ServerSession, FailureListener {
                             final int maxConsumers,
                             final boolean purgeOnNoConsumers,
                             final boolean autoCreated) throws Exception {
-      return createQueue(new AddressInfo(address, routingType), name, filterString, temporary, durable, maxConsumers, purgeOnNoConsumers, autoCreated);
+      AddressSettings as = server.getAddressSettingsRepository().getMatch(address.toString());
+      return createQueue(new AddressInfo(address, routingType), name, filterString, temporary, durable, maxConsumers, purgeOnNoConsumers, as.isDefaultExclusiveQueue(), as.isDefaultLastValueQueue(), autoCreated);
+   }
+
+   @Override
+   public Queue createQueue(final SimpleString address,
+                            final SimpleString name,
+                            final RoutingType routingType,
+                            final SimpleString filterString,
+                            final boolean temporary,
+                            final boolean durable,
+                            final int maxConsumers,
+                            final boolean purgeOnNoConsumers,
+                            final Boolean exclusive,
+                            final Boolean lastValue,
+                            final boolean autoCreated) throws Exception {
+      if (exclusive == null || lastValue == null) {
+         AddressSettings as = server.getAddressSettingsRepository().getMatch(address.toString());
+         return createQueue(new AddressInfo(address, routingType), name, filterString, temporary, durable, maxConsumers, purgeOnNoConsumers,
+                            exclusive == null ? as.isDefaultExclusiveQueue() : exclusive, lastValue == null ? as.isDefaultLastValueQueue() : lastValue, autoCreated);
+      } else {
+         return createQueue(new AddressInfo(address, routingType), name, filterString, temporary, durable, maxConsumers, purgeOnNoConsumers,
+                            exclusive, lastValue, autoCreated);
+      }
    }
 
    @Override
@@ -640,7 +665,14 @@ public class ServerSessionImpl implements ServerSession, FailureListener {
    @Override
    public Queue createQueue(AddressInfo addressInfo, SimpleString name, SimpleString filterString, boolean temporary, boolean durable, boolean autoCreated) throws Exception {
       AddressSettings as = server.getAddressSettingsRepository().getMatch(addressInfo.getName().toString());
-      return createQueue(addressInfo, name, filterString, temporary, durable, as.getDefaultMaxConsumers(), as.isDefaultPurgeOnNoConsumers(), autoCreated);
+      return createQueue(addressInfo, name, filterString, temporary, durable, as.getDefaultMaxConsumers(), as.isDefaultPurgeOnNoConsumers(), as.isDefaultExclusiveQueue(), as.isDefaultLastValueQueue(), autoCreated);
+   }
+
+   @Override
+   public Queue createQueue(AddressInfo addressInfo, SimpleString name, SimpleString filterString, boolean temporary, boolean durable, Boolean exclusive, Boolean lastValue, boolean autoCreated) throws Exception {
+      AddressSettings as = server.getAddressSettingsRepository().getMatch(addressInfo.getName().toString());
+      return createQueue(addressInfo, name, filterString, temporary, durable, as.getDefaultMaxConsumers(), as.isDefaultPurgeOnNoConsumers(),
+                         exclusive == null ? as.isDefaultExclusiveQueue() : exclusive, lastValue == null ? as.isDefaultLastValueQueue() : lastValue, autoCreated);
    }
 
    @Override
@@ -670,18 +702,37 @@ public class ServerSessionImpl implements ServerSession, FailureListener {
 
    @Override
    public void createSharedQueue(SimpleString address,
-                                 final SimpleString name,
-                                 final RoutingType routingType,
+                                 SimpleString name,
+                                 RoutingType routingType,
+                                 SimpleString filterString,
                                  boolean durable,
-                                 final SimpleString filterString) throws Exception {
-
+                                 Integer maxConsumers,
+                                 Boolean purgeOnNoConsumers,
+                                 Boolean exclusive,
+                                 Boolean lastValue) throws Exception {
       address = removePrefix(address);
 
-      securityCheck(address, name, CheckType.CREATE_NON_DURABLE_QUEUE, this);
+      securityCheck(address, name, durable ? CheckType.CREATE_DURABLE_QUEUE : CheckType.CREATE_NON_DURABLE_QUEUE, this);
 
       server.checkQueueCreationLimit(getUsername());
 
-      server.createSharedQueue(address, routingType, name, filterString, SimpleString.toSimpleString(getUsername()), durable);
+      AddressSettings as = server.getAddressSettingsRepository().getMatch(address.toString());
+
+      server.createSharedQueue(address, routingType, name, filterString, SimpleString.toSimpleString(getUsername()), durable,
+                               maxConsumers == null ? as.getDefaultMaxConsumers() : maxConsumers,
+                               purgeOnNoConsumers == null ? as.isDefaultPurgeOnNoConsumers() : purgeOnNoConsumers,
+                               exclusive == null ? as.isDefaultExclusiveQueue() : exclusive,
+                               lastValue == null ? as.isDefaultLastValueQueue() : lastValue);
+   }
+
+   @Override
+   public void createSharedQueue(SimpleString address,
+                                 final SimpleString name,
+                                 final RoutingType routingType,
+                                 boolean durable,
+                                 final SimpleString filterString) throws Exception {
+
+      createSharedQueue(address, name, routingType, filterString, durable, null, null, null, null);
    }
 
    @Override

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/AddressSettings.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/AddressSettings.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/AddressSettings.java
index ca9c550..c7021fd 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/AddressSettings.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/AddressSettings.java
@@ -124,7 +124,9 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
 
    private Long expiryDelay = AddressSettings.DEFAULT_EXPIRY_DELAY;
 
-   private Boolean lastValueQueue = null;
+   private Boolean defaultLastValueQueue = null;
+
+   private Boolean defaultExclusiveQueue = null;
 
    private Long redistributionDelay = null;
 
@@ -190,7 +192,8 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
       this.deadLetterAddress = other.deadLetterAddress;
       this.expiryAddress = other.expiryAddress;
       this.expiryDelay = other.expiryDelay;
-      this.lastValueQueue = other.lastValueQueue;
+      this.defaultLastValueQueue = other.defaultLastValueQueue;
+      this.defaultExclusiveQueue = other.defaultExclusiveQueue;
       this.redistributionDelay = other.redistributionDelay;
       this.sendToDLAOnNoRoute = other.sendToDLAOnNoRoute;
       this.slowConsumerThreshold = other.slowConsumerThreshold;
@@ -352,12 +355,21 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
       return this;
    }
 
-   public boolean isLastValueQueue() {
-      return lastValueQueue != null ? lastValueQueue : AddressSettings.DEFAULT_LAST_VALUE_QUEUE;
+   public boolean isDefaultLastValueQueue() {
+      return defaultLastValueQueue != null ? defaultLastValueQueue : AddressSettings.DEFAULT_LAST_VALUE_QUEUE;
    }
 
-   public AddressSettings setLastValueQueue(final boolean lastValueQueue) {
-      this.lastValueQueue = lastValueQueue;
+   public AddressSettings setDefaultLastValueQueue(final boolean defaultLastValueQueue) {
+      this.defaultLastValueQueue = defaultLastValueQueue;
+      return this;
+   }
+
+   public boolean isDefaultExclusiveQueue() {
+      return defaultExclusiveQueue != null ? defaultExclusiveQueue : ActiveMQDefaultConfiguration.getDefaultExclusive();
+   }
+
+   public AddressSettings setDefaultExclusiveQueue(Boolean defaultExclusiveQueue) {
+      this.defaultExclusiveQueue = defaultExclusiveQueue;
       return this;
    }
 
@@ -691,7 +703,7 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
 
       expiryDelay = BufferHelper.readNullableLong(buffer);
 
-      lastValueQueue = BufferHelper.readNullableBoolean(buffer);
+      defaultLastValueQueue = BufferHelper.readNullableBoolean(buffer);
 
       redistributionDelay = BufferHelper.readNullableLong(buffer);
 
@@ -751,6 +763,10 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
       defaultQueueRoutingType = RoutingType.getType(buffer.readByte());
 
       defaultAddressRoutingType = RoutingType.getType(buffer.readByte());
+
+      if (buffer.readableBytes() > 0) {
+         defaultExclusiveQueue = BufferHelper.readNullableBoolean(buffer);
+      }
    }
 
    @Override
@@ -769,7 +785,7 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
          SimpleString.sizeofNullableString(deadLetterAddress) +
          SimpleString.sizeofNullableString(expiryAddress) +
          BufferHelper.sizeOfNullableLong(expiryDelay) +
-         BufferHelper.sizeOfNullableBoolean(lastValueQueue) +
+         BufferHelper.sizeOfNullableBoolean(defaultLastValueQueue) +
          BufferHelper.sizeOfNullableLong(redistributionDelay) +
          BufferHelper.sizeOfNullableBoolean(sendToDLAOnNoRoute) +
          BufferHelper.sizeOfNullableLong(slowConsumerCheckPeriod) +
@@ -788,7 +804,8 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
          BufferHelper.sizeOfNullableInteger(defaultMaxConsumers) +
          BufferHelper.sizeOfNullableBoolean(defaultPurgeOnNoConsumers) +
          DataConstants.SIZE_BYTE +
-         DataConstants.SIZE_BYTE;
+         DataConstants.SIZE_BYTE +
+         BufferHelper.sizeOfNullableBoolean(defaultExclusiveQueue);
    }
 
    @Override
@@ -819,7 +836,7 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
 
       BufferHelper.writeNullableLong(buffer, expiryDelay);
 
-      BufferHelper.writeNullableBoolean(buffer, lastValueQueue);
+      BufferHelper.writeNullableBoolean(buffer, defaultLastValueQueue);
 
       BufferHelper.writeNullableLong(buffer, redistributionDelay);
 
@@ -862,6 +879,9 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
       buffer.writeByte(defaultQueueRoutingType == null ? -1 : defaultQueueRoutingType.getType());
 
       buffer.writeByte(defaultAddressRoutingType == null ? -1 : defaultAddressRoutingType.getType());
+
+      BufferHelper.writeNullableBoolean(buffer, defaultExclusiveQueue);
+
    }
 
    /* (non-Javadoc)
@@ -876,7 +896,8 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
       result = prime * result + ((dropMessagesWhenFull == null) ? 0 : dropMessagesWhenFull.hashCode());
       result = prime * result + ((expiryAddress == null) ? 0 : expiryAddress.hashCode());
       result = prime * result + ((expiryDelay == null) ? 0 : expiryDelay.hashCode());
-      result = prime * result + ((lastValueQueue == null) ? 0 : lastValueQueue.hashCode());
+      result = prime * result + ((defaultLastValueQueue == null) ? 0 : defaultLastValueQueue.hashCode());
+      result = prime * result + ((defaultExclusiveQueue == null) ? 0 : defaultExclusiveQueue.hashCode());
       result = prime * result + ((maxDeliveryAttempts == null) ? 0 : maxDeliveryAttempts.hashCode());
       result = prime * result + ((maxSizeBytes == null) ? 0 : maxSizeBytes.hashCode());
       result = prime * result + ((messageCounterHistoryDayLimit == null) ? 0 : messageCounterHistoryDayLimit.hashCode());
@@ -947,10 +968,15 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
             return false;
       } else if (!expiryDelay.equals(other.expiryDelay))
          return false;
-      if (lastValueQueue == null) {
-         if (other.lastValueQueue != null)
+      if (defaultLastValueQueue == null) {
+         if (other.defaultLastValueQueue != null)
+            return false;
+      } else if (!defaultLastValueQueue.equals(other.defaultLastValueQueue))
+         return false;
+      if (defaultExclusiveQueue == null) {
+         if (other.defaultExclusiveQueue != null)
             return false;
-      } else if (!lastValueQueue.equals(other.lastValueQueue))
+      } else if (!defaultExclusiveQueue.equals(other.defaultExclusiveQueue))
          return false;
       if (maxDeliveryAttempts == null) {
          if (other.maxDeliveryAttempts != null)
@@ -1124,8 +1150,10 @@ public class AddressSettings implements Mergeable<AddressSettings>, Serializable
          expiryAddress +
          ", expiryDelay=" +
          expiryDelay +
-         ", lastValueQueue=" +
-         lastValueQueue +
+         ", defaultLastValueQueue=" +
+         defaultLastValueQueue +
+         ", defaultExclusiveQueue=" +
+         defaultExclusiveQueue +
          ", maxDeliveryAttempts=" +
          maxDeliveryAttempts +
          ", maxSizeBytes=" +

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/resources/schema/artemis-configuration.xsd
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/resources/schema/artemis-configuration.xsd b/artemis-server/src/main/resources/schema/artemis-configuration.xsd
index 58abd67..f67cd48 100644
--- a/artemis-server/src/main/resources/schema/artemis-configuration.xsd
+++ b/artemis-server/src/main/resources/schema/artemis-configuration.xsd
@@ -502,6 +502,8 @@
                         </xsd:attribute>
                         <xsd:attribute name="max-consumers" type="xsd:integer" use="optional"/>
                         <xsd:attribute name="purge-on-no-consumers" type="xsd:boolean" use="optional"/>
+                        <xsd:attribute name="exclusive" type="xsd:boolean" use="optional"/>
+                        <xsd:attribute name="last-value" type="xsd:boolean" use="optional"/>
                      </xsd:complexType>
                   </xsd:element>
                </xsd:sequence>
@@ -2693,7 +2695,23 @@
             <xsd:element name="last-value-queue" type="xsd:boolean" default="false" maxOccurs="1" minOccurs="0">
                <xsd:annotation>
                   <xsd:documentation>
-                     whether to treat the queue as a last value queue
+                     This is deprecated please use default-last-value-queue instead.
+                  </xsd:documentation>
+               </xsd:annotation>
+            </xsd:element>
+
+            <xsd:element name="default-last-value-queue" type="xsd:boolean" default="false" maxOccurs="1" minOccurs="0">
+               <xsd:annotation>
+                  <xsd:documentation>
+                     whether to treat the queues under the address as a last value queues by default
+                  </xsd:documentation>
+               </xsd:annotation>
+            </xsd:element>
+
+            <xsd:element name="default-exclusive-queue" type="xsd:boolean" default="false" maxOccurs="1" minOccurs="0">
+               <xsd:annotation>
+                  <xsd:documentation>
+                     whether to treat the queues under the address as exclusive queues by default
                   </xsd:documentation>
                </xsd:annotation>
             </xsd:element>
@@ -3009,6 +3027,8 @@
       <xsd:attribute name="name" type="xsd:string" use="required"/>
       <xsd:attribute name="max-consumers" type="xsd:integer" use="optional"/>
       <xsd:attribute name="purge-on-no-consumers" type="xsd:boolean" use="optional"/>
+      <xsd:attribute name="exclusive" type="xsd:boolean" use="optional"/>
+      <xsd:attribute name="last-value" type="xsd:boolean" use="optional"/>
    </xsd:complexType>
 
    <xsd:complexType name="addressType">

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/ScheduledDeliveryHandlerTest.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/ScheduledDeliveryHandlerTest.java b/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/ScheduledDeliveryHandlerTest.java
index 256a670..4fda8b3 100644
--- a/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/ScheduledDeliveryHandlerTest.java
+++ b/artemis-server/src/test/java/org/apache/activemq/artemis/core/server/impl/ScheduledDeliveryHandlerTest.java
@@ -1312,6 +1312,21 @@ public class ScheduledDeliveryHandlerTest extends Assert {
       }
 
       @Override
+      public boolean isLastValue() {
+         return false;
+      }
+
+      @Override
+      public boolean isExclusive() {
+         return false;
+      }
+
+      @Override
+      public void setExclusive(boolean exclusive) {
+
+      }
+
+      @Override
       public void decDelivering(int size) {
 
       }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-tools/src/test/resources/artemis-configuration.xsd
----------------------------------------------------------------------
diff --git a/artemis-tools/src/test/resources/artemis-configuration.xsd b/artemis-tools/src/test/resources/artemis-configuration.xsd
index c0b88f9..cb579a8 100644
--- a/artemis-tools/src/test/resources/artemis-configuration.xsd
+++ b/artemis-tools/src/test/resources/artemis-configuration.xsd
@@ -484,6 +484,8 @@
                         </xsd:attribute>
                         <xsd:attribute name="max-consumers" type="xsd:integer" use="optional"/>
                         <xsd:attribute name="purge-on-no-consumers" type="xsd:boolean" use="optional"/>
+                        <xsd:attribute name="exclusive" type="xsd:boolean" use="optional"/>
+                        <xsd:attribute name="last-value" type="xsd:boolean" use="optional"/>
                      </xsd:complexType>
                   </xsd:element>
                </xsd:sequence>
@@ -2422,7 +2424,23 @@
             <xsd:element name="last-value-queue" type="xsd:boolean" default="false" maxOccurs="1" minOccurs="0">
                <xsd:annotation>
                   <xsd:documentation>
-                     whether to treat the queue as a last value queue
+                     This is deprecated please use default-last-value-queue instead.
+                  </xsd:documentation>
+               </xsd:annotation>
+            </xsd:element>
+
+            <xsd:element name="default-last-value-queue" type="xsd:boolean" default="false" maxOccurs="1" minOccurs="0">
+               <xsd:annotation>
+                  <xsd:documentation>
+                     whether to treat the queues under the address as a last value queues by default
+                  </xsd:documentation>
+               </xsd:annotation>
+            </xsd:element>
+
+            <xsd:element name="default-exclusive-queue" type="xsd:boolean" default="false" maxOccurs="1" minOccurs="0">
+               <xsd:annotation>
+                  <xsd:documentation>
+                     whether to treat the queues under the address as exclusive queues by default
                   </xsd:documentation>
                </xsd:annotation>
             </xsd:element>
@@ -2679,6 +2697,7 @@
       </xsd:simpleContent>
    </xsd:complexType>
 
+  
 
    <!-- 2.0 Addressing configuration -->
 
@@ -2691,6 +2710,8 @@
       <xsd:attribute name="name" type="xsd:string" use="required"/>
       <xsd:attribute name="max-consumers" type="xsd:integer" use="optional"/>
       <xsd:attribute name="purge-on-no-consumers" type="xsd:boolean" use="optional"/>
+      <xsd:attribute name="exclusive" type="xsd:boolean" use="optional"/>
+      <xsd:attribute name="last-value" type="xsd:boolean" use="optional"/>
    </xsd:complexType>
 
    <xsd:complexType name="addressType">

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSLVQTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSLVQTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSLVQTest.java
index 0ffa9c5..1c50412 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSLVQTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSLVQTest.java
@@ -43,7 +43,7 @@ public class JMSLVQTest extends JMSClientTestSupport {
 
    @Override
    protected void addConfiguration(ActiveMQServer server) {
-      server.getAddressSettingsRepository().addMatch(LVQ_QUEUE_NAME, new AddressSettings().setLastValueQueue(true));
+      server.getAddressSettingsRepository().addMatch(LVQ_QUEUE_NAME, new AddressSettings().setDefaultLastValueQueue(true));
    }
    @Override
    protected void createAddressAndQueues(ActiveMQServer server) throws Exception {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/MultipleProducersTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/MultipleProducersTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/MultipleProducersTest.java
index f412426..0c9c566 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/MultipleProducersTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/MultipleProducersTest.java
@@ -74,7 +74,7 @@ public class MultipleProducersTest extends JMSTestBase {
       addressSettings.setDeadLetterAddress(expiryQueue);
       addressSettings.setRedeliveryDelay(0);
       addressSettings.setMessageCounterHistoryDayLimit(2);
-      addressSettings.setLastValueQueue(false);
+      addressSettings.setDefaultLastValueQueue(false);
       addressSettings.setMaxDeliveryAttempts(10);
       addressSettings.setMaxSizeBytes(1048576);
       addressSettings.setPageCacheMaxSize(5);

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/SessionCreateAndDeleteQueueTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/SessionCreateAndDeleteQueueTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/SessionCreateAndDeleteQueueTest.java
index 4d6dde3..af4ab8d 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/SessionCreateAndDeleteQueueTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/SessionCreateAndDeleteQueueTest.java
@@ -99,7 +99,7 @@ public class SessionCreateAndDeleteQueueTest extends ActiveMQTestBase {
 
    @Test
    public void testAddressSettingUSed() throws Exception {
-      server.getAddressSettingsRepository().addMatch(address.toString(), new AddressSettings().setLastValueQueue(true));
+      server.getAddressSettingsRepository().addMatch(address.toString(), new AddressSettings().setDefaultLastValueQueue(true));
       ClientSession session = createSessionFactory(locator).createSession(false, true, true);
       SimpleString filterString = new SimpleString("x=y");
       session.createQueue(address, queueName, filterString, false);

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/UpdateQueueTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/UpdateQueueTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/UpdateQueueTest.java
index 5d1763f..f5b6a00 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/UpdateQueueTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/UpdateQueueTest.java
@@ -59,7 +59,7 @@ public class UpdateQueueTest extends ActiveMQTestBase {
          prod.send(session.createTextMessage("message " + i));
       }
 
-      server.updateQueue(ADDRESS.toString(), RoutingType.ANYCAST, 1, false);
+      server.updateQueue(ADDRESS.toString(), RoutingType.ANYCAST, 1, false, false);
 
       conn.close();
       factory.close();

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/client/ExclusiveTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/client/ExclusiveTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/client/ExclusiveTest.java
new file mode 100644
index 0000000..1331615
--- /dev/null
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/client/ExclusiveTest.java
@@ -0,0 +1,319 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.jms.client;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.Destination;
+import javax.jms.JMSConsumer;
+import javax.jms.JMSContext;
+import javax.jms.JMSProducer;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+
+import org.apache.activemq.artemis.api.core.RoutingType;
+import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
+import org.apache.activemq.artemis.tests.util.JMSTestBase;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Exclusive Test
+ */
+public class ExclusiveTest extends JMSTestBase {
+
+   private SimpleString queueName = SimpleString.toSimpleString("jms.exclusive.queue");
+
+   @Override
+   @Before
+   public void setUp() throws Exception {
+      super.setUp();
+      server.createQueue(queueName, RoutingType.ANYCAST, queueName, null, null, true, false, false, false, false, -1, false, true, false,true);
+   }
+
+
+   protected ConnectionFactory getCF() throws Exception {
+      return cf;
+   }
+
+   @Test
+   public void testExclusiveQueueConsumer() throws Exception {
+      ConnectionFactory fact = getCF();
+      Connection connection = fact.createConnection();
+
+      try {
+
+         Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+
+         Destination queue = session.createQueue(queueName.toString());
+         MessageProducer producer = session.createProducer(queue);
+
+         MessageConsumer consumer1 = session.createConsumer(queue);
+         MessageConsumer consumer2 = session.createConsumer(queue);
+         MessageConsumer consumer3 = session.createConsumer(queue);
+
+         connection.start();
+
+         for (int j = 0; j < 100; j++) {
+            TextMessage message = session.createTextMessage();
+
+            message.setText("Message" + j);
+
+            producer.send(message);
+         }
+
+
+         //All msgs should go to the first consumer
+         for (int j = 0; j < 100; j++) {
+            TextMessage tm = (TextMessage) consumer1.receive(10000);
+
+            assertNotNull(tm);
+
+            assertEquals("Message" + j, tm.getText());
+
+            tm = (TextMessage) consumer2.receiveNoWait();
+            assertNull(tm);
+            tm = (TextMessage) consumer3.receiveNoWait();
+            assertNull(tm);
+         }
+      } finally {
+         connection.close();
+      }
+   }
+
+   @Test
+   public void testExclusiveWithJMS2Producer() throws Exception {
+      ConnectionFactory fact = getCF();
+      JMSContext ctx = addContext(getCF().createContext(JMSContext.SESSION_TRANSACTED));
+
+      try {
+         JMSProducer producer = ctx.createProducer();
+         Destination queue = ctx.createQueue(queueName.toString());
+
+         JMSConsumer consumer1 = ctx.createConsumer(queue);
+         JMSConsumer consumer2 = ctx.createConsumer(queue);
+         JMSConsumer consumer3 = ctx.createConsumer(queue);
+
+         ctx.start();
+
+         for (int j = 0; j < 100; j++) {
+            TextMessage message = ctx.createTextMessage("Message" + j);
+
+            producer.send(queue, message);
+         }
+
+         ctx.commit();
+
+         //All msgs should go to the first consumer
+         for (int j = 0; j < 100; j++) {
+            TextMessage tm = (TextMessage) consumer1.receive(10000);
+
+            assertNotNull(tm);
+
+            tm.acknowledge();
+
+            assertEquals("Message" + j, tm.getText());
+
+            tm = (TextMessage) consumer2.receiveNoWait();
+            assertNull(tm);
+            tm = (TextMessage) consumer3.receiveNoWait();
+            assertNull(tm);
+         }
+
+         ctx.commit();
+      } finally {
+         ctx.close();
+      }
+   }
+
+   @Test
+   public void testExclusiveQueueConsumerSettingUsingAddressQueueParameters() throws Exception {
+      ConnectionFactory fact = getCF();
+      Connection connection = fact.createConnection();
+
+      try {
+
+         Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+
+         Queue queue = session.createQueue("random?exclusive=true");
+         assertEquals("random", queue.getQueueName());
+
+         ActiveMQDestination a = (ActiveMQDestination) queue;
+         assertTrue(a.getQueueAttributes().getExclusive());
+
+         MessageProducer producer = session.createProducer(queue);
+
+         MessageConsumer consumer1 = session.createConsumer(queue);
+         MessageConsumer consumer2 = session.createConsumer(queue);
+         MessageConsumer consumer3 = session.createConsumer(queue);
+
+         connection.start();
+
+         for (int j = 0; j < 100; j++) {
+            TextMessage message = session.createTextMessage();
+
+            message.setText("Message" + j);
+
+            producer.send(message);
+         }
+
+
+         //All msgs should go to the first consumer
+         for (int j = 0; j < 100; j++) {
+            TextMessage tm = (TextMessage) consumer1.receive(10000);
+
+            assertNotNull(tm);
+
+            assertEquals("Message" + j, tm.getText());
+
+            tm = (TextMessage) consumer2.receiveNoWait();
+            assertNull(tm);
+            tm = (TextMessage) consumer3.receiveNoWait();
+            assertNull(tm);
+         }
+      } finally {
+         connection.close();
+      }
+   }
+
+   @Test
+   public void testExclusiveQueueConsumerFailover() throws Exception {
+      ConnectionFactory fact = getCF();
+      Connection connection = fact.createConnection();
+
+      try {
+
+         Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+
+         Destination queue = session.createQueue(queueName.toString());
+         MessageProducer producer = session.createProducer(queue);
+
+         MessageConsumer consumer1 = session.createConsumer(queue);
+         MessageConsumer consumer2 = session.createConsumer(queue);
+         MessageConsumer consumer3 = session.createConsumer(queue);
+
+         connection.start();
+
+         for (int j = 0; j < 100; j++) {
+            TextMessage message = session.createTextMessage();
+
+            message.setText("Message" + j);
+
+            producer.send(message);
+         }
+
+
+         //All msgs should go to the first consumer
+         for (int j = 0; j < 50; j++) {
+            TextMessage tm = (TextMessage) consumer1.receive(10000);
+
+            assertNotNull(tm);
+
+            assertEquals("Message" + j, tm.getText());
+
+            tm = (TextMessage) consumer2.receiveNoWait();
+            assertNull(tm);
+            tm = (TextMessage) consumer3.receiveNoWait();
+            assertNull(tm);
+         }
+         consumer1.close();
+
+         //All msgs should now go to the next consumer only, without any errors or exceptions
+         for (int j = 50; j < 100; j++) {
+            TextMessage tm = (TextMessage) consumer2.receive(10000);
+
+            assertNotNull(tm);
+
+            assertEquals("Message" + j, tm.getText());
+
+            tm = (TextMessage) consumer3.receiveNoWait();
+            assertNull(tm);
+         }
+      } finally {
+         connection.close();
+      }
+   }
+
+
+   @Test
+   public void testExclusiveTopicSharedConsumerFailover() throws Exception {
+      ConnectionFactory fact = getCF();
+      Connection connection = fact.createConnection();
+
+      try {
+
+         Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+
+         Destination topic = session.createTopic("mytopic");
+         MessageProducer producer = session.createProducer(topic);
+
+         String subscriptionName = "sharedsub";
+         Topic topicConsumer = session.createTopic("mytopic?exclusive=true");
+         MessageConsumer consumer1 = session.createSharedDurableConsumer(topicConsumer, subscriptionName);
+         MessageConsumer consumer2 = session.createSharedDurableConsumer(topicConsumer, subscriptionName);
+         MessageConsumer consumer3 = session.createSharedDurableConsumer(topicConsumer, subscriptionName);
+
+         connection.start();
+
+         for (int j = 0; j < 100; j++) {
+            TextMessage message = session.createTextMessage();
+
+            message.setText("Message" + j);
+
+            producer.send(message);
+         }
+
+
+         //All msgs should go to the first consumer
+         for (int j = 0; j < 50; j++) {
+            TextMessage tm = (TextMessage) consumer1.receive(10000);
+
+            assertNotNull(tm);
+
+            assertEquals("Message" + j, tm.getText());
+
+            tm = (TextMessage) consumer2.receiveNoWait();
+            assertNull(tm);
+            tm = (TextMessage) consumer3.receiveNoWait();
+            assertNull(tm);
+         }
+         consumer1.close();
+
+         //All msgs should now go to the next consumer only, without any errors or exceptions
+         for (int j = 50; j < 100; j++) {
+            TextMessage tm = (TextMessage) consumer2.receive(10000);
+
+            assertNotNull(tm);
+
+            assertEquals("Message" + j, tm.getText());
+
+            tm = (TextMessage) consumer3.receiveNoWait();
+            assertNull(tm);
+         }
+
+
+      } finally {
+         connection.close();
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/client/LVQTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/client/LVQTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/client/LVQTest.java
new file mode 100644
index 0000000..af4a20a
--- /dev/null
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/client/LVQTest.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.jms.client;
+
+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 javax.jms.Topic;
+
+import org.apache.activemq.artemis.api.core.Message;
+import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
+import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
+import org.apache.activemq.artemis.tests.util.JMSTestBase;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * LVQ Test
+ */
+public class LVQTest extends JMSTestBase {
+
+   @Override
+   @Before
+   public void setUp() throws Exception {
+      super.setUp();
+   }
+
+
+   protected ConnectionFactory getCF() throws Exception {
+      return cf;
+   }
+
+   @Test
+   public void testLastValueQueueUsingAddressQueueParameters() throws Exception {
+      ActiveMQConnectionFactory fact = (ActiveMQConnectionFactory) getCF();
+
+      //Set the consumer window size to 0 to not buffer any messages client side.
+      fact.setConsumerWindowSize(0);
+      Connection connection = fact.createConnection();
+
+      try {
+
+         Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+
+         Queue queue = session.createQueue("random?last-value=true");
+         assertEquals("random", queue.getQueueName());
+
+         ActiveMQDestination a = (ActiveMQDestination) queue;
+         assertTrue(a.getQueueAttributes().getLastValue());
+
+         MessageProducer producer = session.createProducer(queue);
+         MessageConsumer consumer1 = session.createConsumer(queue);
+
+         connection.start();
+         for (int j = 0; j < 100; j++) {
+            TextMessage message = session.createTextMessage();
+
+            message.setText("Message" + j);
+            message.setStringProperty(Message.HDR_LAST_VALUE_NAME.toString(), "key");
+            producer.send(message);
+         }
+
+         //Last message only should go to the consumer
+         TextMessage tm = (TextMessage) consumer1.receive(10000);
+
+         assertNotNull(tm);
+
+         assertEquals("Message99", tm.getText());
+
+      } finally {
+         connection.close();
+      }
+   }
+
+   @Test
+   public void testLastValueQueueTopicConsumerUsingAddressQueueParameters() throws Exception {
+      ActiveMQConnectionFactory fact = (ActiveMQConnectionFactory) getCF();
+
+      //Set the consumer window size to 0 to not buffer any messages client side.
+      fact.setConsumerWindowSize(0);
+      Connection connection = fact.createConnection();
+
+      try {
+
+         Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+
+         Topic topic = session.createTopic("topic?last-value=true");
+         assertEquals("topic", topic.getTopicName());
+
+         ActiveMQDestination a = (ActiveMQDestination) topic;
+         assertTrue(a.getQueueAttributes().getLastValue());
+
+         MessageProducer producer = session.createProducer(topic);
+         MessageConsumer consumer1 = session.createConsumer(topic);
+         MessageConsumer consumer2 = session.createConsumer(topic);
+
+         connection.start();
+         for (int j = 0; j < 100; j++) {
+            TextMessage message = session.createTextMessage();
+
+            message.setText("Message" + j);
+            message.setStringProperty(Message.HDR_LAST_VALUE_NAME.toString(), "key");
+            producer.send(message);
+         }
+
+
+
+         //Last message only should go to the consumer.
+         TextMessage tm = (TextMessage) consumer1.receive(10000);
+
+         assertNotNull(tm);
+
+         assertEquals("Message99", tm.getText());
+
+         //Last message only should go to the other consumer as well.
+         TextMessage tm2 = (TextMessage) consumer2.receive(10000);
+
+         assertNotNull(tm2);
+
+         assertEquals("Message99", tm2.getText());
+
+      } finally {
+         connection.close();
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlUsingCoreTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlUsingCoreTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlUsingCoreTest.java
index 9351fee..16d64fd 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlUsingCoreTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlUsingCoreTest.java
@@ -136,6 +136,16 @@ public class ActiveMQServerControlUsingCoreTest extends ActiveMQServerControlTes
          }
 
          @Override
+         public String updateQueue(@Parameter(name = "name", desc = "Name of the queue") String name,
+                                   @Parameter(name = "routingType", desc = "The routing type used for this address, MULTICAST or ANYCAST") String routingType,
+                                   @Parameter(name = "maxConsumers", desc = "The maximum number of consumers allowed on this queue at any one time") Integer maxConsumers,
+                                   @Parameter(name = "purgeOnNoConsumers", desc = "Delete this queue when the last consumer disconnects") Boolean purgeOnNoConsumers,
+                                   @Parameter(name = "exclusive", desc = "If the queue should route exclusively to one consumer") Boolean exclusive)
+            throws Exception {
+            return (String) proxy.invokeOperation("updateQueue", name, routingType, maxConsumers, purgeOnNoConsumers, exclusive);
+         }
+
+         @Override
          public void deleteAddress(@Parameter(name = "name", desc = "The name of the address") String name) throws Exception {
             proxy.invokeOperation("deleteAddress", name);
          }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/QueueControlUsingCoreTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/QueueControlUsingCoreTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/QueueControlUsingCoreTest.java
index 82c7a47..09621af 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/QueueControlUsingCoreTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/QueueControlUsingCoreTest.java
@@ -102,6 +102,16 @@ public class QueueControlUsingCoreTest extends QueueControlTest {
          }
 
          @Override
+         public boolean isExclusive() {
+            return (Boolean) proxy.retrieveAttributeValue("exclusive");
+         }
+
+         @Override
+         public boolean isLastValue() {
+            return (Boolean) proxy.retrieveAttributeValue("lastValue");
+         }
+
+         @Override
          public int getDeliveringCount() {
             return (Integer) proxy.retrieveAttributeValue("deliveringCount", Integer.class);
          }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/LVQRecoveryTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/LVQRecoveryTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/LVQRecoveryTest.java
index f121cbe..96c1fd2 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/LVQRecoveryTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/LVQRecoveryTest.java
@@ -170,7 +170,7 @@ public class LVQRecoveryTest extends ActiveMQTestBase {
       server = createServer(true, configuration);
       server.start();
 
-      qs = new AddressSettings().setLastValueQueue(true);
+      qs = new AddressSettings().setDefaultLastValueQueue(true);
       server.getAddressSettingsRepository().addMatch(address.toString(), qs);
       // then we create a client as normal
       locator = createInVMNonHALocator().setBlockOnAcknowledge(true).setAckBatchSize(0);
@@ -188,7 +188,7 @@ public class LVQRecoveryTest extends ActiveMQTestBase {
       // start the server
       server.start();
 
-      server.getAddressSettingsRepository().addMatch(address.toString(), new AddressSettings().setLastValueQueue(true));
+      server.getAddressSettingsRepository().addMatch(address.toString(), new AddressSettings().setDefaultLastValueQueue(true));
       // then we create a client as normal
       locator.close();
       locator = createInVMNonHALocator().setBlockOnAcknowledge(true).setAckBatchSize(0);

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/LVQTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/LVQTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/LVQTest.java
index 0706bc0..f262aed 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/LVQTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/LVQTest.java
@@ -648,7 +648,7 @@ public class LVQTest extends ActiveMQTestBase {
       // start the server
       server.start();
 
-      server.getAddressSettingsRepository().addMatch(address.toString(), new AddressSettings().setLastValueQueue(true));
+      server.getAddressSettingsRepository().addMatch(address.toString(), new AddressSettings().setDefaultLastValueQueue(true));
       // then we create a client as normalServer
       ServerLocator locator = createNettyNonHALocator().setBlockOnAcknowledge(true).setAckBatchSize(0);
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/message/MessageHeaderTest.java
----------------------------------------------------------------------
diff --git a/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/message/MessageHeaderTest.java b/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/message/MessageHeaderTest.java
index 6e1fff2..f249383 100644
--- a/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/message/MessageHeaderTest.java
+++ b/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/message/MessageHeaderTest.java
@@ -917,6 +917,12 @@ public class MessageHeaderTest extends MessageHeaderTestBase {
 
       }
 
+      @Override
+      public void createSharedQueue(SimpleString address, RoutingType routingType, SimpleString queueName, SimpleString filter,
+                                    boolean durable, Integer maxConsumers, Boolean purgeOnNoConsumers, Boolean exclusive, Boolean lastValue) throws ActiveMQException {
+
+      }
+
       /**
        * Creates a <em>non-temporary</em> queue.
        *
@@ -1018,6 +1024,13 @@ public class MessageHeaderTest extends MessageHeaderTestBase {
 
       }
 
+      @Override
+      public void createQueue(SimpleString address, RoutingType routingType, SimpleString queueName, SimpleString filter, boolean durable,
+                              boolean autoCreated, int maxConsumers, boolean purgeOnNoConsumers, Boolean exclusive, Boolean lastValue)
+         throws ActiveMQException {
+
+      }
+
       /**
        * Creates a <em>non-temporary</em>queue.
        *
@@ -1048,6 +1061,13 @@ public class MessageHeaderTest extends MessageHeaderTestBase {
 
       }
 
+      @Override
+      public void createQueue(String address, RoutingType routingType, String queueName, String filter, boolean durable,
+                              boolean autoCreated,
+                              int maxConsumers, boolean purgeOnNoConsumers, Boolean exclusive, Boolean lastValue) throws ActiveMQException {
+
+      }
+
       /**
        * Creates a <em>temporary</em> queue.
        *
@@ -1074,6 +1094,13 @@ public class MessageHeaderTest extends MessageHeaderTestBase {
 
       }
 
+      @Override
+      public void createTemporaryQueue(SimpleString address, RoutingType routingType, SimpleString queueName, SimpleString filter,
+                                       int maxConsumers, boolean purgeOnNoConsumers, Boolean exclusive, Boolean lastValue)
+         throws ActiveMQException {
+
+      }
+
       /**
        * Creates a <em>temporary</em> queue with a filter.
        *

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/postoffice/impl/FakeQueue.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/postoffice/impl/FakeQueue.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/postoffice/impl/FakeQueue.java
index f0afd9e..6e66057 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/postoffice/impl/FakeQueue.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/postoffice/impl/FakeQueue.java
@@ -48,6 +48,23 @@ public class FakeQueue extends CriticalComponentImpl implements Queue {
    }
 
    @Override
+   public boolean isExclusive() {
+      // no-op
+      return false;
+   }
+
+   @Override
+   public void setExclusive(boolean value) {
+      // no-op
+   }
+
+   @Override
+   public boolean isLastValue() {
+      // no-op
+      return false;
+   }
+
+   @Override
    public void setMaxConsumer(int maxConsumers) {
 
    }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/server/impl/fakes/FakePostOffice.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/server/impl/fakes/FakePostOffice.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/server/impl/fakes/FakePostOffice.java
index 98a7359..96c7451 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/server/impl/fakes/FakePostOffice.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/server/impl/fakes/FakePostOffice.java
@@ -46,7 +46,8 @@ public class FakePostOffice implements PostOffice {
    public QueueBinding updateQueue(SimpleString name,
                                    RoutingType routingType,
                                    Integer maxConsumers,
-                                   Boolean purgeOnNoConsumers) throws Exception {
+                                   Boolean purgeOnNoConsumers,
+                                   Boolean exclusive) throws Exception {
       return null;
    }
 

Reply | Threaded
Open this post in threaded view
|

[4/5] activemq-artemis git commit: ARTEMIS-853 Support for exclusive consumers

michaelpearce
In reply to this post by michaelpearce
http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java
----------------------------------------------------------------------
diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java
index cf2ec59..a0ccfcc 100644
--- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java
+++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java
@@ -52,6 +52,7 @@ import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.activemq.artemis.api.core.ActiveMQException;
 import org.apache.activemq.artemis.api.core.ActiveMQQueueExistsException;
+import org.apache.activemq.artemis.api.core.QueueAttributes;
 import org.apache.activemq.artemis.api.core.SimpleString;
 import org.apache.activemq.artemis.api.core.client.ClientConsumer;
 import org.apache.activemq.artemis.api.core.client.ClientProducer;
@@ -318,7 +319,7 @@ public class ActiveMQSession implements QueueSession, TopicSession {
                   if (jbd.isQueue() && response.isAutoCreateQueues()) {
                      // perhaps just relying on the broker to do it is simplest (i.e. purgeOnNoConsumers)
                      session.createAddress(jbd.getSimpleAddress(), RoutingType.ANYCAST, true);
-                     session.createQueue(jbd.getSimpleAddress(), RoutingType.ANYCAST, jbd.getSimpleAddress(), null, true, true, response.getDefaultMaxConsumers(), response.isDefaultPurgeOnNoConsumers());
+                     createQueue(jbd, RoutingType.ANYCAST, jbd.getSimpleAddress(), null, true, true, response.getDefaultMaxConsumers(), response.isDefaultPurgeOnNoConsumers(), response.isDefaultExclusive(), response.isDefaultLastValueQueue());
                   } else if (!jbd.isQueue() && response.isAutoCreateAddresses()) {
                      session.createAddress(jbd.getSimpleAddress(), RoutingType.MULTICAST, true);
                   } else {
@@ -629,16 +630,16 @@ public class ActiveMQSession implements QueueSession, TopicSession {
 
          queueName = ActiveMQDestination.createQueueNameForSubscription(durability == ConsumerDurability.DURABLE, connection.getClientID(), subscriptionName);
 
-         if (durability == ConsumerDurability.DURABLE) {
-            try {
-               session.createSharedQueue(dest.getSimpleAddress(), RoutingType.MULTICAST, queueName, coreFilterString, true);
-            } catch (ActiveMQQueueExistsException ignored) {
-               // We ignore this because querying and then creating the queue wouldn't be idempotent
-               // we could also add a parameter to ignore existence what would require a bigger work around to avoid
-               // compatibility.
+         try {
+            if (durability == ConsumerDurability.DURABLE) {
+               createSharedQueue(dest, RoutingType.MULTICAST, queueName, coreFilterString, true, response.getDefaultMaxConsumers(), response.isDefaultPurgeOnNoConsumers(), response.isDefaultExclusive(), response.isDefaultLastValueQueue());
+            } else {
+               createSharedQueue(dest, RoutingType.MULTICAST, queueName, coreFilterString, false, response.getDefaultMaxConsumers(), response.isDefaultPurgeOnNoConsumers(), response.isDefaultExclusive(), response.isDefaultLastValueQueue());
             }
-         } else {
-            session.createSharedQueue(dest.getSimpleAddress(), queueName, coreFilterString, false);
+         } catch (ActiveMQQueueExistsException ignored) {
+            // We ignore this because querying and then creating the queue wouldn't be idempotent
+            // we could also add a parameter to ignore existence what would require a bigger work around to avoid
+            // compatibility.
          }
 
          consumer = session.createConsumer(queueName, null, false);
@@ -699,7 +700,7 @@ public class ActiveMQSession implements QueueSession, TopicSession {
             if (!response.isExists() || !response.getQueueNames().contains(dest.getSimpleAddress())) {
                if (response.isAutoCreateQueues()) {
                   try {
-                     session.createQueue(dest.getSimpleAddress(), RoutingType.ANYCAST, dest.getSimpleAddress(), null, true, true, response.getDefaultMaxConsumers(), response.isDefaultPurgeOnNoConsumers());
+                     createQueue(dest, RoutingType.ANYCAST, dest.getSimpleAddress(), null, true, true, response.getDefaultMaxConsumers(), response.isDefaultPurgeOnNoConsumers(), response.isDefaultExclusive(), response.isDefaultLastValueQueue());
                   } catch (ActiveMQQueueExistsException e) {
                      // The queue was created by another client/admin between the query check and send create queue packet
                   }
@@ -733,7 +734,7 @@ public class ActiveMQSession implements QueueSession, TopicSession {
 
                queueName = new SimpleString(UUID.randomUUID().toString());
 
-               session.createTemporaryQueue(dest.getSimpleAddress(), RoutingType.MULTICAST, queueName, coreFilterString);
+               createTemporaryQueue(dest, RoutingType.MULTICAST, queueName, coreFilterString, response.getDefaultMaxConsumers(), response.isDefaultPurgeOnNoConsumers(), response.isDefaultExclusive(), response.isDefaultLastValueQueue());
 
                consumer = session.createConsumer(queueName, null, false);
 
@@ -756,7 +757,7 @@ public class ActiveMQSession implements QueueSession, TopicSession {
 
                if (!subResponse.isExists()) {
                   // durable subscription queues are not technically considered to be auto-created
-                  session.createQueue(dest.getSimpleAddress(), RoutingType.MULTICAST, queueName, coreFilterString, true, false, response.getDefaultMaxConsumers(), response.isDefaultPurgeOnNoConsumers());
+                  createQueue(dest, RoutingType.MULTICAST, queueName, coreFilterString, true, false, response.getDefaultMaxConsumers(), response.isDefaultPurgeOnNoConsumers(), response.isDefaultExclusive(), response.isDefaultLastValueQueue());
                } else {
                   // Already exists
                   if (subResponse.getConsumerCount() > 0) {
@@ -787,7 +788,7 @@ public class ActiveMQSession implements QueueSession, TopicSession {
                      session.deleteQueue(queueName);
 
                      // Create the new one
-                     session.createQueue(dest.getSimpleAddress(), RoutingType.MULTICAST, queueName, coreFilterString, true, false, response.getDefaultMaxConsumers(), response.isDefaultPurgeOnNoConsumers());
+                     createQueue(dest, RoutingType.MULTICAST, queueName, coreFilterString, true, false, response.getDefaultMaxConsumers(), response.isDefaultPurgeOnNoConsumers(), response.isDefaultExclusive(), response.isDefaultLastValueQueue());
                   }
                }
 
@@ -849,7 +850,7 @@ public class ActiveMQSession implements QueueSession, TopicSession {
          AddressQuery response = session.addressQuery(new SimpleString(activeMQDestination.getAddress()));
          if (!response.isExists()) {
             if (response.isAutoCreateQueues()) {
-               session.createQueue(activeMQDestination.getSimpleAddress(), RoutingType.ANYCAST, activeMQDestination.getSimpleAddress(), null, true, true, response.getDefaultMaxConsumers(), response.isDefaultPurgeOnNoConsumers());
+               createQueue(activeMQDestination, RoutingType.ANYCAST, activeMQDestination.getSimpleAddress(), null, true, true, response.getDefaultMaxConsumers(), response.isDefaultPurgeOnNoConsumers(), response.isDefaultExclusive(), response.isDefaultLastValueQueue());
             } else {
                throw new InvalidDestinationException("Destination " + activeMQDestination.getName() + " does not exist");
             }
@@ -1154,6 +1155,63 @@ public class ActiveMQSession implements QueueSession, TopicSession {
       }
    }
 
+   private void createTemporaryQueue(ActiveMQDestination destination, RoutingType routingType, SimpleString queueName, SimpleString filter, int maxConsumers, boolean purgeOnNoConsumers, Boolean exclusive, Boolean lastValue) throws ActiveMQException {
+      QueueAttributes queueAttributes = destination.getQueueAttributes();
+      if (queueAttributes == null) {
+         session.createTemporaryQueue(destination.getSimpleAddress(), routingType, queueName, filter, maxConsumers, purgeOnNoConsumers, exclusive, lastValue);
+      } else {
+         session.createTemporaryQueue(
+            destination.getSimpleAddress(),
+            routingType,
+            queueName,
+            filter,
+            queueAttributes.getMaxConsumers() == null ? maxConsumers : queueAttributes.getMaxConsumers(),
+            queueAttributes.getPurgeOnNoConsumers() == null ? purgeOnNoConsumers : queueAttributes.getPurgeOnNoConsumers(),
+            queueAttributes.getExclusive() == null ? exclusive : queueAttributes.getExclusive(),
+            queueAttributes.getLastValue() == null ? lastValue : queueAttributes.getLastValue()
+         );
+      }
+   }
+
+   private void createSharedQueue(ActiveMQDestination destination, RoutingType routingType, SimpleString queueName, SimpleString filter, boolean durable, int maxConsumers, boolean purgeOnNoConsumers, Boolean exclusive, Boolean lastValue) throws ActiveMQException {
+      QueueAttributes queueAttributes = destination.getQueueAttributes();
+      if (queueAttributes == null) {
+         session.createSharedQueue(destination.getSimpleAddress(), routingType, queueName, filter, durable, maxConsumers, purgeOnNoConsumers, exclusive, lastValue);
+      } else {
+         session.createSharedQueue(
+            destination.getSimpleAddress(),
+            routingType,
+            queueName,
+            filter,
+            durable,
+            queueAttributes.getMaxConsumers() == null ? maxConsumers : queueAttributes.getMaxConsumers(),
+            queueAttributes.getPurgeOnNoConsumers() == null ? purgeOnNoConsumers : queueAttributes.getPurgeOnNoConsumers(),
+            queueAttributes.getExclusive() == null ? exclusive : queueAttributes.getExclusive(),
+            queueAttributes.getLastValue() == null ? lastValue : queueAttributes.getLastValue()
+         );
+      }
+   }
+
+   private void createQueue(ActiveMQDestination destination, RoutingType routingType, SimpleString queueName, SimpleString filter, boolean durable, boolean autoCreated, int maxConsumers, boolean purgeOnNoConsumers, Boolean exclusive, Boolean lastValue) throws ActiveMQException {
+      QueueAttributes queueAttributes = destination.getQueueAttributes();
+      if (queueAttributes == null) {
+         session.createQueue(destination.getSimpleAddress(), routingType, queueName, filter, durable, autoCreated, maxConsumers, purgeOnNoConsumers, exclusive, lastValue);
+      } else {
+         session.createQueue(
+            destination.getSimpleAddress(),
+            routingType,
+            queueName,
+            filter,
+            durable,
+            autoCreated,
+            queueAttributes.getMaxConsumers() == null ? maxConsumers : queueAttributes.getMaxConsumers(),
+            queueAttributes.getPurgeOnNoConsumers() == null ? purgeOnNoConsumers : queueAttributes.getPurgeOnNoConsumers(),
+            queueAttributes.getExclusive() == null ? exclusive : queueAttributes.getExclusive(),
+            queueAttributes.getLastValue() == null ? lastValue : queueAttributes.getLastValue()
+         );
+      }
+   }
+
    // Inner classes -------------------------------------------------
 
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-jms-client/src/test/java/org/apache/activemq/artemis/jms/client/ActiveMQParameterTest.java
----------------------------------------------------------------------
diff --git a/artemis-jms-client/src/test/java/org/apache/activemq/artemis/jms/client/ActiveMQParameterTest.java b/artemis-jms-client/src/test/java/org/apache/activemq/artemis/jms/client/ActiveMQParameterTest.java
new file mode 100644
index 0000000..cf42fe3
--- /dev/null
+++ b/artemis-jms-client/src/test/java/org/apache/activemq/artemis/jms/client/ActiveMQParameterTest.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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.jms.client;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * Test Address queue parameters are correctly read.
+ */
+public class ActiveMQParameterTest {
+
+   @Test
+   public void testQueueParameters() {
+      ActiveMQDestination activeMQDestination = new ActiveMQQueue("jms.queue.foo?exclusive=true");
+      assertTrue(activeMQDestination.getQueueAttributes().getExclusive());
+
+      assertEquals("jms.queue.foo", activeMQDestination.getAddress());
+
+      activeMQDestination = new ActiveMQQueue("jms.queue.foo?exclusive=false");
+      assertFalse(activeMQDestination.getQueueAttributes().getExclusive());
+
+      activeMQDestination = new ActiveMQQueue("jms.queue.foo?last-value=true");
+      assertTrue(activeMQDestination.getQueueAttributes().getLastValue());
+
+      activeMQDestination = new ActiveMQQueue("jms.queue.foo?last-value=false");
+      assertFalse(activeMQDestination.getQueueAttributes().getLastValue());
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-protocols/artemis-hqclient-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/hornetq/client/HornetQClientSessionContext.java
----------------------------------------------------------------------
diff --git a/artemis-protocols/artemis-hqclient-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/hornetq/client/HornetQClientSessionContext.java b/artemis-protocols/artemis-hqclient-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/hornetq/client/HornetQClientSessionContext.java
index 185feaf..ee3520f 100644
--- a/artemis-protocols/artemis-hqclient-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/hornetq/client/HornetQClientSessionContext.java
+++ b/artemis-protocols/artemis-hqclient-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/hornetq/client/HornetQClientSessionContext.java
@@ -72,7 +72,7 @@ public class HornetQClientSessionContext extends ActiveMQSessionContext {
    public ClientSession.AddressQuery addressQuery(final SimpleString address) throws ActiveMQException {
       SessionBindingQueryResponseMessage response = (SessionBindingQueryResponseMessage) getSessionChannel().sendBlocking(new SessionBindingQueryMessage(address), PacketImpl.SESS_BINDINGQUERY_RESP);
 
-      return new AddressQueryImpl(response.isExists(), response.getQueueNames(), false, false, ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers(), ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers());
+      return new AddressQueryImpl(response.isExists(), response.getQueueNames(), false, false, ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers(), ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers(), ActiveMQDefaultConfiguration.getDefaultExclusive(), ActiveMQDefaultConfiguration.getDefaultLastValue());
    }
 
    @Override

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/CoreQueueConfiguration.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/CoreQueueConfiguration.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/CoreQueueConfiguration.java
index 6648b7e..236fac6 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/CoreQueueConfiguration.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/CoreQueueConfiguration.java
@@ -35,6 +35,10 @@ public class CoreQueueConfiguration implements Serializable {
 
    private String user = null;
 
+   private Boolean exclusive;
+
+   private Boolean lastValue;
+
    private Integer maxConsumers = ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers();
 
    private Boolean purgeOnNoConsumers = ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers();
@@ -64,6 +68,14 @@ public class CoreQueueConfiguration implements Serializable {
       return user;
    }
 
+   public Boolean isExclusive() {
+      return exclusive;
+   }
+
+   public Boolean isLastValue() {
+      return lastValue;
+   }
+
    /**
     * @param address the address to set
     */
@@ -120,6 +132,16 @@ public class CoreQueueConfiguration implements Serializable {
       return this;
    }
 
+   public CoreQueueConfiguration setExclusive(Boolean exclusive) {
+      this.exclusive = exclusive;
+      return this;
+   }
+
+   public CoreQueueConfiguration setLastValue(Boolean lastValue) {
+      this.lastValue = lastValue;
+      return this;
+   }
+
    public boolean getPurgeOnNoConsumers() {
       return purgeOnNoConsumers;
    }
@@ -147,6 +169,8 @@ public class CoreQueueConfiguration implements Serializable {
       result = prime * result + ((name == null) ? 0 : name.hashCode());
       result = prime * result + ((maxConsumers == null) ? 0 : maxConsumers.hashCode());
       result = prime * result + ((purgeOnNoConsumers == null) ? 0 : purgeOnNoConsumers.hashCode());
+      result = prime * result + ((exclusive == null) ? 0 : exclusive.hashCode());
+      result = prime * result + ((lastValue == null) ? 0 : lastValue.hashCode());
       return result;
    }
 
@@ -187,6 +211,18 @@ public class CoreQueueConfiguration implements Serializable {
       } else if (!purgeOnNoConsumers.equals(other.purgeOnNoConsumers)) {
          return false;
       }
+      if (exclusive == null) {
+         if (other.exclusive != null)
+            return false;
+      } else if (!exclusive.equals(other.exclusive)) {
+         return false;
+      }
+      if (lastValue == null) {
+         if (other.lastValue != null)
+            return false;
+      } else if (!lastValue.equals(other.lastValue)) {
+         return false;
+      }
       return true;
    }
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
index 8eee4dc..b5352ba 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
@@ -179,6 +179,10 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
 
    private static final String LVQ_NODE_NAME = "last-value-queue";
 
+   private static final String DEFAULT_LVQ_NODE_NAME = "default-last-value-queue";
+
+   private static final String DEFAULT_EXCLUSIVE_NODE_NAME = "default-exclusive-queue";
+
    private static final String REDISTRIBUTION_DELAY_NODE_NAME = "redistribution-delay";
 
    private static final String SEND_TO_DLA_ON_NO_ROUTE = "send-to-dla-on-no-route";
@@ -989,8 +993,10 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
             Validators.ADDRESS_FULL_MESSAGE_POLICY_TYPE.validate(ADDRESS_FULL_MESSAGE_POLICY_NODE_NAME, value);
             AddressFullMessagePolicy policy = Enum.valueOf(AddressFullMessagePolicy.class, value);
             addressSettings.setAddressFullMessagePolicy(policy);
-         } else if (LVQ_NODE_NAME.equalsIgnoreCase(name)) {
-            addressSettings.setLastValueQueue(XMLUtil.parseBoolean(child));
+         } else if (LVQ_NODE_NAME.equalsIgnoreCase(name) || DEFAULT_LVQ_NODE_NAME.equalsIgnoreCase(name)) {
+            addressSettings.setDefaultLastValueQueue(XMLUtil.parseBoolean(child));
+         } else if (DEFAULT_EXCLUSIVE_NODE_NAME.equalsIgnoreCase(name)) {
+            addressSettings.setDefaultExclusiveQueue(XMLUtil.parseBoolean(child));
          } else if (MAX_DELIVERY_ATTEMPTS.equalsIgnoreCase(name)) {
             addressSettings.setMaxDeliveryAttempts(XMLUtil.parseInt(child));
          } else if (REDISTRIBUTION_DELAY_NODE_NAME.equalsIgnoreCase(name)) {
@@ -1090,6 +1096,8 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
       int maxConsumers = ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers();
       boolean purgeOnNoConsumers = ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers();
       String user = null;
+      Boolean exclusive = null;
+      Boolean lastValue = null;
 
       NamedNodeMap attributes = node.getAttributes();
       for (int i = 0; i < attributes.getLength(); i++) {
@@ -1099,6 +1107,10 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
             Validators.MAX_QUEUE_CONSUMERS.validate(name, maxConsumers);
          } else if (item.getNodeName().equals("purge-on-no-consumers")) {
             purgeOnNoConsumers = Boolean.parseBoolean(item.getNodeValue());
+         } else if (item.getNodeName().equals("exclusive")) {
+            exclusive = Boolean.parseBoolean(item.getNodeValue());
+         } else if (item.getNodeName().equals("last-value")) {
+            lastValue = Boolean.parseBoolean(item.getNodeValue());
          }
       }
 
@@ -1117,7 +1129,8 @@ public final class FileConfigurationParser extends XMLConfigurationUtil {
          }
       }
 
-      return new CoreQueueConfiguration().setAddress(address).setName(name).setFilterString(filterString).setDurable(durable).setMaxConsumers(maxConsumers).setPurgeOnNoConsumers(purgeOnNoConsumers).setUser(user);
+      return new CoreQueueConfiguration().setAddress(address).setName(name).setFilterString(filterString).setDurable(durable).setMaxConsumers(maxConsumers).setPurgeOnNoConsumers(purgeOnNoConsumers).setUser(user)
+                                         .setExclusive(exclusive).setLastValue(lastValue);
    }
 
    protected CoreAddressConfiguration parseAddressConfiguration(final Node node) {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/ActiveMQServerControlImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/ActiveMQServerControlImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/ActiveMQServerControlImpl.java
index 4e80bb5..41d7b30 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/ActiveMQServerControlImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/ActiveMQServerControlImpl.java
@@ -823,12 +823,21 @@ public class ActiveMQServerControlImpl extends AbstractControl implements Active
                              String routingType,
                              Integer maxConsumers,
                              Boolean purgeOnNoConsumers) throws Exception {
+      return updateQueue(name, routingType, maxConsumers, purgeOnNoConsumers, null);
+   }
+
+   @Override
+   public String updateQueue(String name,
+                             String routingType,
+                             Integer maxConsumers,
+                             Boolean purgeOnNoConsumers,
+                             Boolean exclusive) throws Exception {
       checkStarted();
 
       clearIO();
 
       try {
-         final Queue queue = server.updateQueue(name, routingType != null ? RoutingType.valueOf(routingType) : null, maxConsumers, purgeOnNoConsumers);
+         final Queue queue = server.updateQueue(name, routingType != null ? RoutingType.valueOf(routingType) : null, maxConsumers, purgeOnNoConsumers, exclusive);
          if (queue == null) {
             throw ActiveMQMessageBundle.BUNDLE.noSuchQueue(new SimpleString(name));
          }
@@ -2077,7 +2086,7 @@ public class ActiveMQServerControlImpl extends AbstractControl implements Active
             .add("redeliveryMultiplier", addressSettings.getRedeliveryMultiplier())
             .add("maxRedeliveryDelay", addressSettings.getMaxRedeliveryDelay())
             .add("redistributionDelay", addressSettings.getRedistributionDelay())
-            .add("lastValueQueue", addressSettings.isLastValueQueue())
+            .add("lastValueQueue", addressSettings.isDefaultLastValueQueue())
             .add("sendToDLAOnNoRoute", addressSettings.isSendToDLAOnNoRoute())
             .add("addressFullMessagePolicy", policy)
             .add("slowConsumerThreshold", addressSettings.getSlowConsumerThreshold())
@@ -2163,7 +2172,7 @@ public class ActiveMQServerControlImpl extends AbstractControl implements Active
       addressSettings.setDeadLetterAddress(DLA == null ? null : new SimpleString(DLA));
       addressSettings.setExpiryAddress(expiryAddress == null ? null : new SimpleString(expiryAddress));
       addressSettings.setExpiryDelay(expiryDelay);
-      addressSettings.setLastValueQueue(lastValueQueue);
+      addressSettings.setDefaultLastValueQueue(lastValueQueue);
       addressSettings.setMaxDeliveryAttempts(deliveryAttempts);
       addressSettings.setPageCacheMaxSize(pageMaxCacheSize);
       addressSettings.setMaxSizeBytes(maxSizeBytes);

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/QueueControlImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/QueueControlImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/QueueControlImpl.java
index 0a1c385..cefcbf9 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/QueueControlImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/QueueControlImpl.java
@@ -382,6 +382,30 @@ public class QueueControlImpl extends AbstractControl implements QueueControl {
    }
 
    @Override
+   public boolean isExclusive() {
+      checkStarted();
+
+      clearIO();
+      try {
+         return queue.isExclusive();
+      } finally {
+         blockOnIO();
+      }
+   }
+
+   @Override
+   public boolean isLastValue() {
+      checkStarted();
+
+      clearIO();
+      try {
+         return queue.isLastValue();
+      } finally {
+         blockOnIO();
+      }
+   }
+
+   @Override
    public Map<String, Object>[] listScheduledMessages() throws Exception {
       checkStarted();
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/QueueView.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/QueueView.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/QueueView.java
index eb0f1a4..181b6ce 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/QueueView.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/QueueView.java
@@ -60,7 +60,9 @@ public class QueueView extends ActiveMQAbstractView<QueueControl> {
          .add("messagesAcked", toString(queue.getMessagesAcknowledged()))
          .add("deliveringCount", toString(queue.getDeliveringCount()))
          .add("messagesKilled", toString(queue.getMessagesKilled()))
-         .add("deliverDeliver", toString(q.isDirectDeliver()));
+         .add("deliverDeliver", toString(q.isDirectDeliver()))
+         .add("exclusive", toString(queue.isExclusive()))
+         .add("lastValue", toString(queue.isLastValue()));
       return obj;
    }
 
@@ -108,6 +110,10 @@ public class QueueView extends ActiveMQAbstractView<QueueControl> {
             return queue.getMessagesKilled();
          case "deliverDeliver":
             return q.isDirectDeliver();
+         case "exclusive":
+            return q.isExclusive();
+         case "lastValue":
+            return q.isLastValue();
          default:
             throw new IllegalArgumentException("Unsupported field, " + fieldName);
       }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/predicate/QueueFilterPredicate.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/predicate/QueueFilterPredicate.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/predicate/QueueFilterPredicate.java
index d8209a7..10a0e91 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/predicate/QueueFilterPredicate.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/view/predicate/QueueFilterPredicate.java
@@ -27,7 +27,7 @@ public class QueueFilterPredicate extends ActiveMQFilterPredicate<QueueControl>
    enum Field {
       ID, NAME, CONSUMER_ID, QUEUE, ADDRESS, MAX_CONSUMERS, FILTER, MESSAGE_COUNT, CONSUMER_COUNT, DELIVERING_COUNT,
       MESSAGES_ADDED, MESSAGES_ACKED, RATE, ROUTING_TYPE, USER, AUTO_CREATED, DURABLE, PAUSED, TEMPORARY,
-      PURGE_ON_NO_CONSUMERS, MESSAGES_KILLED, DIRECT_DELIVER
+      PURGE_ON_NO_CONSUMERS, MESSAGES_KILLED, DIRECT_DELIVER, LAST_VALUE, EXCLUSIVE
    }
 
    private Field f;
@@ -89,6 +89,10 @@ public class QueueFilterPredicate extends ActiveMQFilterPredicate<QueueControl>
                return matches(queue.isPurgeOnNoConsumers());
             case MESSAGES_KILLED:
                return matches(queue.getMessagesKilled());
+            case EXCLUSIVE:
+               return matches(queue.isExclusive());
+            case LAST_VALUE:
+               return matches(queue.isLastValue());
             default:
                return true;
          }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/QueueBindingInfo.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/QueueBindingInfo.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/QueueBindingInfo.java
index 7164cc1..00b7974 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/QueueBindingInfo.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/QueueBindingInfo.java
@@ -54,6 +54,10 @@ public interface QueueBindingInfo {
 
    void setPurgeOnNoConsumers(boolean purgeOnNoConsumers);
 
+   boolean isExclusive();
+
+   void setExclusive(boolean exclusive);
+
    byte getRoutingType();
 
    void setRoutingType(byte routingType);

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/AbstractJournalStorageManager.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/AbstractJournalStorageManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/AbstractJournalStorageManager.java
index 5441368..34d249e 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/AbstractJournalStorageManager.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/AbstractJournalStorageManager.java
@@ -1272,7 +1272,7 @@ public abstract class AbstractJournalStorageManager extends CriticalComponentImp
 
       SimpleString filterString = filter == null ? null : filter.getFilterString();
 
-      PersistentQueueBindingEncoding bindingEncoding = new PersistentQueueBindingEncoding(queue.getName(), binding.getAddress(), filterString, queue.getUser(), queue.isAutoCreated(), queue.getMaxConsumers(), queue.isPurgeOnNoConsumers(), queue.getRoutingType().getType());
+      PersistentQueueBindingEncoding bindingEncoding = new PersistentQueueBindingEncoding(queue.getName(), binding.getAddress(), filterString, queue.getUser(), queue.isAutoCreated(), queue.getMaxConsumers(), queue.isPurgeOnNoConsumers(), queue.isExclusive(), queue.getRoutingType().getType());
 
       readLock();
       try {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/codec/PersistentQueueBindingEncoding.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/codec/PersistentQueueBindingEncoding.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/codec/PersistentQueueBindingEncoding.java
index af2c675..d67b300 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/codec/PersistentQueueBindingEncoding.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/persistence/impl/journal/codec/PersistentQueueBindingEncoding.java
@@ -46,6 +46,8 @@ public class PersistentQueueBindingEncoding implements EncodingSupport, QueueBin
 
    public boolean purgeOnNoConsumers;
 
+   public boolean exclusive;
+
    public byte routingType;
 
    public PersistentQueueBindingEncoding() {
@@ -68,6 +70,8 @@ public class PersistentQueueBindingEncoding implements EncodingSupport, QueueBin
          maxConsumers +
          ", purgeOnNoConsumers=" +
          purgeOnNoConsumers +
+          ", exclusive=" +
+          exclusive +
          ", routingType=" +
          routingType +
          "]";
@@ -80,6 +84,7 @@ public class PersistentQueueBindingEncoding implements EncodingSupport, QueueBin
                                          final boolean autoCreated,
                                          final int maxConsumers,
                                          final boolean purgeOnNoConsumers,
+                                         final boolean exclusive,
                                          final byte routingType) {
       this.name = name;
       this.address = address;
@@ -88,6 +93,7 @@ public class PersistentQueueBindingEncoding implements EncodingSupport, QueueBin
       this.autoCreated = autoCreated;
       this.maxConsumers = maxConsumers;
       this.purgeOnNoConsumers = purgeOnNoConsumers;
+      this.exclusive = exclusive;
       this.routingType = routingType;
    }
 
@@ -164,6 +170,16 @@ public class PersistentQueueBindingEncoding implements EncodingSupport, QueueBin
    }
 
    @Override
+   public boolean isExclusive() {
+      return exclusive;
+   }
+
+   @Override
+   public void setExclusive(boolean exclusive) {
+      this.exclusive = exclusive;
+   }
+
+   @Override
    public byte getRoutingType() {
       return routingType;
    }
@@ -203,6 +219,12 @@ public class PersistentQueueBindingEncoding implements EncodingSupport, QueueBin
          purgeOnNoConsumers = ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers();
          routingType = ActiveMQDefaultConfiguration.getDefaultRoutingType().getType();
       }
+
+      if (buffer.readableBytes() > 0) {
+         exclusive = buffer.readBoolean();
+      } else {
+         exclusive = ActiveMQDefaultConfiguration.getDefaultExclusive();
+      }
    }
 
    @Override
@@ -215,6 +237,7 @@ public class PersistentQueueBindingEncoding implements EncodingSupport, QueueBin
       buffer.writeInt(maxConsumers);
       buffer.writeBoolean(purgeOnNoConsumers);
       buffer.writeByte(routingType);
+      buffer.writeBoolean(exclusive);
    }
 
    @Override
@@ -224,7 +247,8 @@ public class PersistentQueueBindingEncoding implements EncodingSupport, QueueBin
          SimpleString.sizeofNullableString(createMetadata()) +
          DataConstants.SIZE_INT +
          DataConstants.SIZE_BOOLEAN +
-         DataConstants.SIZE_BYTE;
+         DataConstants.SIZE_BYTE +
+         DataConstants.SIZE_BOOLEAN;
    }
 
    private SimpleString createMetadata() {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/PostOffice.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/PostOffice.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/PostOffice.java
index 2a8764e..b78883f 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/PostOffice.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/PostOffice.java
@@ -64,7 +64,8 @@ public interface PostOffice extends ActiveMQComponent {
    QueueBinding updateQueue(SimpleString name,
                             RoutingType routingType,
                             Integer maxConsumers,
-                            Boolean purgeOnNoConsumers) throws Exception;
+                            Boolean purgeOnNoConsumers,
+                            Boolean exclusive) throws Exception;
 
    List<Queue> listQueuesForAddress(SimpleString address) throws Exception;
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/PostOfficeImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/PostOfficeImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/PostOfficeImpl.java
index be4a0d5..9de5dcc 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/PostOfficeImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/postoffice/impl/PostOfficeImpl.java
@@ -464,7 +464,8 @@ public class PostOfficeImpl implements PostOffice, NotificationListener, Binding
    public QueueBinding updateQueue(SimpleString name,
                                    RoutingType routingType,
                                    Integer maxConsumers,
-                                   Boolean purgeOnNoConsumers) throws Exception {
+                                   Boolean purgeOnNoConsumers,
+                                   Boolean exclusive) throws Exception {
       synchronized (addressLock) {
          final QueueBinding queueBinding = (QueueBinding) addressManager.getBinding(name);
          if (queueBinding == null) {
@@ -504,6 +505,10 @@ public class PostOfficeImpl implements PostOffice, NotificationListener, Binding
             changed = true;
             queue.setPurgeOnNoConsumers(purgeOnNoConsumers);
          }
+         if (exclusive != null && queue.isExclusive() != exclusive.booleanValue()) {
+            changed = true;
+            queue.setExclusive(exclusive);
+         }
 
          if (changed) {
             final long txID = storageManager.generateID();

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/protocol/core/ServerSessionPacketHandler.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/protocol/core/ServerSessionPacketHandler.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/protocol/core/ServerSessionPacketHandler.java
index d47fbff..7b129ad 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/protocol/core/ServerSessionPacketHandler.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/protocol/core/ServerSessionPacketHandler.java
@@ -353,7 +353,7 @@ public class ServerSessionPacketHandler implements ChannelHandler {
                   CreateQueueMessage_V2 request = (CreateQueueMessage_V2) packet;
                   requiresResponse = request.isRequiresResponse();
                   session.createQueue(request.getAddress(), request.getQueueName(), request.getRoutingType(), request.getFilterString(), request.isTemporary(), request.isDurable(), request.getMaxConsumers(), request.isPurgeOnNoConsumers(),
-                                      request.isAutoCreated());
+                                      request.isExclusive(), request.isLastValue(), request.isAutoCreated());
                   if (requiresResponse) {
                      response = new NullResponseMessage();
                   }
@@ -371,7 +371,7 @@ public class ServerSessionPacketHandler implements ChannelHandler {
                case CREATE_SHARED_QUEUE_V2: {
                   CreateSharedQueueMessage_V2 request = (CreateSharedQueueMessage_V2) packet;
                   requiresResponse = request.isRequiresResponse();
-                  session.createSharedQueue(request.getAddress(), request.getQueueName(), request.getRoutingType(), request.isDurable(), request.getFilterString());
+                  session.createSharedQueue(request.getAddress(), request.getQueueName(), request.getRoutingType(), request.getFilterString(), request.isDurable(), request.getMaxConsumers(), request.isPurgeOnNoConsumers(), request.isExclusive(), request.isLastValue());
                   if (requiresResponse) {
                      response = new NullResponseMessage();
                   }
@@ -417,13 +417,13 @@ public class ServerSessionPacketHandler implements ChannelHandler {
                      if (!queueNames.isEmpty()) {
                         final List<SimpleString> convertedQueueNames = request.convertQueueNames(clientVersion, queueNames);
                         if (convertedQueueNames != queueNames) {
-                           result = new BindingQueryResult(result.isExists(), result.getAddressInfo(), convertedQueueNames, result.isAutoCreateQueues(), result.isAutoCreateAddresses(), result.isDefaultPurgeOnNoConsumers(), result.getDefaultMaxConsumers());
+                           result = new BindingQueryResult(result.isExists(), result.getAddressInfo(), convertedQueueNames, result.isAutoCreateQueues(), result.isAutoCreateAddresses(), result.isDefaultPurgeOnNoConsumers(), result.getDefaultMaxConsumers(), result.isDefaultExclusive(), result.isDefaultLastValue());
                         }
                      }
                   }
 
                   if (channel.supports(PacketImpl.SESS_BINDINGQUERY_RESP_V4)) {
-                     response = new SessionBindingQueryResponseMessage_V4(result.isExists(), result.getQueueNames(), result.isAutoCreateQueues(), result.isAutoCreateAddresses(), result.isDefaultPurgeOnNoConsumers(), result.getDefaultMaxConsumers());
+                     response = new SessionBindingQueryResponseMessage_V4(result.isExists(), result.getQueueNames(), result.isAutoCreateQueues(), result.isAutoCreateAddresses(), result.isDefaultPurgeOnNoConsumers(), result.getDefaultMaxConsumers(), result.isDefaultExclusive(), result.isDefaultLastValue());
                   } else if (channel.supports(PacketImpl.SESS_BINDINGQUERY_RESP_V3)) {
                      response = new SessionBindingQueryResponseMessage_V3(result.isExists(), result.getQueueNames(), result.isAutoCreateQueues(), result.isAutoCreateAddresses());
                   } else if (channel.supports(PacketImpl.SESS_BINDINGQUERY_RESP_V2)) {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServer.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServer.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServer.java
index 6af94ff..b8598b8 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServer.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServer.java
@@ -333,6 +333,9 @@ public interface ActiveMQServer extends ServiceComponent {
    void createSharedQueue(SimpleString address, RoutingType routingType, SimpleString name, SimpleString filterString,
                           SimpleString user, boolean durable) throws Exception;
 
+   void createSharedQueue(SimpleString address, RoutingType routingType, SimpleString name, SimpleString filterString,
+                          SimpleString user, boolean durable, int maxConsumers, boolean purgeOnNoConsumers, boolean exclusive, boolean lastValue) throws Exception;
+
    Queue createQueue(SimpleString address, RoutingType routingType, SimpleString queueName, SimpleString filter,
                      boolean durable, boolean temporary) throws Exception;
 
@@ -351,10 +354,18 @@ public interface ActiveMQServer extends ServiceComponent {
                      SimpleString user, boolean durable, boolean temporary, boolean autoCreated, Integer maxConsumers,
                      Boolean purgeOnNoConsumers, boolean autoCreateAddress) throws Exception;
 
+   Queue createQueue(AddressInfo addressInfo, SimpleString queueName, SimpleString filter,
+                     SimpleString user, boolean durable, boolean temporary, boolean autoCreated, Integer maxConsumers,
+                     Boolean purgeOnNoConsumers, Boolean exclusive, Boolean lastValue, boolean autoCreateAddress) throws Exception;
+
    Queue createQueue(SimpleString address, RoutingType routingType, SimpleString queueName, SimpleString filter,
                      SimpleString user, boolean durable, boolean temporary, boolean ignoreIfExists, boolean transientQueue,
                      boolean autoCreated, int maxConsumers, boolean purgeOnNoConsumers, boolean autoCreateAddress) throws Exception;
 
+   Queue createQueue(SimpleString address, RoutingType routingType, SimpleString queueName, SimpleString filter,
+                     SimpleString user, boolean durable, boolean temporary, boolean ignoreIfExists, boolean transientQueue,
+                     boolean autoCreated, int maxConsumers, boolean purgeOnNoConsumers, boolean exclusive, boolean lastValue, boolean autoCreateAddress) throws Exception;
+
    @Deprecated
    Queue createQueue(SimpleString address, SimpleString queueName, SimpleString filter, boolean durable, boolean temporary) throws Exception;
 
@@ -426,6 +437,12 @@ public interface ActiveMQServer extends ServiceComponent {
                      Integer maxConsumers,
                      Boolean purgeOnNoConsumers) throws Exception;
 
+   Queue updateQueue(String name,
+                     RoutingType routingType,
+                     Integer maxConsumers,
+                     Boolean purgeOnNoConsumers,
+                     Boolean exclusive) throws Exception;
+
    /*
             * add a ProtocolManagerFactory to be used. Note if @see Configuration#isResolveProtocols is tur then this factory will
             * replace any factories with the same protocol

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/BindingQueryResult.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/BindingQueryResult.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/BindingQueryResult.java
index 7f340b1..a76812c 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/BindingQueryResult.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/BindingQueryResult.java
@@ -37,13 +37,19 @@ public class BindingQueryResult {
 
    private final AddressInfo addressInfo;
 
+   private boolean defaultExclusive;
+
+   private boolean defaultLastValue;
+
    public BindingQueryResult(final boolean exists,
                              final AddressInfo addressInfo,
                              final List<SimpleString> queueNames,
                              final boolean autoCreateQueues,
                              final boolean autoCreateAddresses,
                              final boolean defaultPurgeOnNoConsumers,
-                             final int defaultMaxConsumers) {
+                             final int defaultMaxConsumers,
+                             final boolean defaultExclusive,
+                             final boolean defaultLastValue) {
       this.addressInfo = addressInfo;
 
       this.exists = exists;
@@ -57,6 +63,10 @@ public class BindingQueryResult {
       this.defaultPurgeOnNoConsumers = defaultPurgeOnNoConsumers;
 
       this.defaultMaxConsumers = defaultMaxConsumers;
+
+      this.defaultExclusive = defaultExclusive;
+
+      this.defaultLastValue = defaultLastValue;
    }
 
    public boolean isExists() {
@@ -86,4 +96,12 @@ public class BindingQueryResult {
    public int getDefaultMaxConsumers() {
       return defaultMaxConsumers;
    }
+
+   public boolean isDefaultExclusive() {
+      return defaultExclusive;
+   }
+
+   public boolean isDefaultLastValue() {
+      return defaultLastValue;
+   }
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/Queue.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/Queue.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/Queue.java
index b39f4da..ff4e82b 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/Queue.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/Queue.java
@@ -68,6 +68,12 @@ public interface Queue extends Bindable,CriticalComponent {
 
    void setPurgeOnNoConsumers(boolean value);
 
+   boolean isExclusive();
+
+   void setExclusive(boolean value);
+
+   boolean isLastValue();
+
    int getMaxConsumers();
 
    void setMaxConsumer(int maxConsumers);

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/QueueConfig.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/QueueConfig.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/QueueConfig.java
index e879966..75f859d 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/QueueConfig.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/QueueConfig.java
@@ -37,6 +37,8 @@ public final class QueueConfig {
    private final boolean autoCreated;
    private final RoutingType routingType;
    private final int maxConsumers;
+   private final boolean exclusive;
+   private final boolean lastValue;
    private final boolean purgeOnNoConsumers;
 
    public static final class Builder {
@@ -52,6 +54,8 @@ public final class QueueConfig {
       private boolean autoCreated;
       private RoutingType routingType;
       private int maxConsumers;
+      private boolean exclusive;
+      private boolean lastValue;
       private boolean purgeOnNoConsumers;
 
       private Builder(final long id, final SimpleString name) {
@@ -70,6 +74,8 @@ public final class QueueConfig {
          this.autoCreated = true;
          this.routingType = ActiveMQDefaultConfiguration.getDefaultRoutingType();
          this.maxConsumers = ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers();
+         this.exclusive = ActiveMQDefaultConfiguration.getDefaultExclusive();
+         this.lastValue = ActiveMQDefaultConfiguration.getDefaultLastValue();
          this.purgeOnNoConsumers = ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers();
          validateState();
       }
@@ -122,6 +128,17 @@ public final class QueueConfig {
          return this;
       }
 
+      public Builder exclusive(final boolean exclusive) {
+         this.exclusive = exclusive;
+         return this;
+      }
+
+      public Builder lastValue(final boolean lastValue) {
+         this.lastValue = lastValue;
+         return this;
+      }
+
+
       public Builder purgeOnNoConsumers(final boolean purgeOnNoConsumers) {
          this.purgeOnNoConsumers = purgeOnNoConsumers;
          return this;
@@ -153,7 +170,7 @@ public final class QueueConfig {
          } else {
             pageSubscription = null;
          }
-         return new QueueConfig(id, address, name, filter, pageSubscription, user, durable, temporary, autoCreated, routingType, maxConsumers, purgeOnNoConsumers);
+         return new QueueConfig(id, address, name, filter, pageSubscription, user, durable, temporary, autoCreated, routingType, maxConsumers, exclusive, lastValue, purgeOnNoConsumers);
       }
 
    }
@@ -197,6 +214,8 @@ public final class QueueConfig {
                        final boolean autoCreated,
                        final RoutingType routingType,
                        final int maxConsumers,
+                       final boolean exclusive,
+                       final boolean lastValue,
                        final boolean purgeOnNoConsumers) {
       this.id = id;
       this.address = address;
@@ -209,6 +228,8 @@ public final class QueueConfig {
       this.autoCreated = autoCreated;
       this.routingType = routingType;
       this.purgeOnNoConsumers = purgeOnNoConsumers;
+      this.exclusive = exclusive;
+      this.lastValue = lastValue;
       this.maxConsumers = maxConsumers;
    }
 
@@ -256,6 +277,14 @@ public final class QueueConfig {
       return maxConsumers;
    }
 
+   public boolean isExclusive() {
+      return exclusive;
+   }
+
+   public boolean isLastValue() {
+      return lastValue;
+   }
+
    public RoutingType deliveryMode() {
       return routingType;
    }
@@ -289,6 +318,10 @@ public final class QueueConfig {
          return false;
       if (maxConsumers != that.maxConsumers)
          return false;
+      if (exclusive != that.exclusive)
+         return false;
+      if (lastValue != that.lastValue)
+         return false;
       if (purgeOnNoConsumers != that.purgeOnNoConsumers)
          return false;
       return user != null ? user.equals(that.user) : that.user == null;
@@ -308,6 +341,8 @@ public final class QueueConfig {
       result = 31 * result + (autoCreated ? 1 : 0);
       result = 31 * result + routingType.getType();
       result = 31 * result + maxConsumers;
+      result = 31 * result + (exclusive ? 1 : 0);
+      result = 31 * result + (lastValue ? 1 : 0);
       result = 31 * result + (purgeOnNoConsumers ? 1 : 0);
       return result;
    }
@@ -326,6 +361,8 @@ public final class QueueConfig {
          + ", autoCreated=" + autoCreated
          + ", routingType=" + routingType
          + ", maxConsumers=" + maxConsumers
+         + ", exclusive=" + exclusive
+         + ", lastValue=" + lastValue
          + ", purgeOnNoConsumers=" + purgeOnNoConsumers + '}';
    }
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ServerSession.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ServerSession.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ServerSession.java
index d7e1ad2..59a400b 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ServerSession.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ServerSession.java
@@ -155,6 +155,18 @@ public interface ServerSession extends SecurityAuth {
                      SimpleString filterString,
                      boolean temporary,
                      boolean durable,
+                     int maxConsumers,
+                     boolean purgeOnNoConsumers,
+                     Boolean exclusive,
+                     Boolean lastValue,
+                     boolean autoCreated) throws Exception;
+
+   Queue createQueue(SimpleString address,
+                     SimpleString name,
+                     RoutingType routingType,
+                     SimpleString filterString,
+                     boolean temporary,
+                     boolean durable,
                      boolean autoCreated) throws Exception;
 
    Queue createQueue(AddressInfo addressInfo,
@@ -164,6 +176,15 @@ public interface ServerSession extends SecurityAuth {
                      boolean durable,
                      boolean autoCreated) throws Exception;
 
+   Queue createQueue(AddressInfo addressInfo,
+                     SimpleString name,
+                     SimpleString filterString,
+                     boolean temporary,
+                     boolean durable,
+                     Boolean exclusive,
+                     Boolean lastValue,
+                     boolean autoCreated) throws Exception;
+
    AddressInfo createAddress(SimpleString address,
                              EnumSet<RoutingType> routingTypes,
                              boolean autoCreated) throws Exception;
@@ -254,6 +275,16 @@ public interface ServerSession extends SecurityAuth {
    boolean isClosed();
 
    void createSharedQueue(SimpleString address,
+                     SimpleString name,
+                     RoutingType routingType,
+                     SimpleString filterString,
+                     boolean durable,
+                     Integer maxConsumers,
+                     Boolean purgeOnNoConsumers,
+                     Boolean exclusive,
+                     Boolean lastValue) throws Exception;
+
+   void createSharedQueue(SimpleString address,
                           SimpleString name,
                           RoutingType routingType,
                           boolean durable,

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
index 6ce681e..d7eb2b9 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
@@ -825,6 +825,8 @@ public class ActiveMQServerImpl implements ActiveMQServer {
       boolean autoCreateAddresses = addressSettings.isAutoCreateAddresses();
       boolean defaultPurgeOnNoConsumers = addressSettings.isDefaultPurgeOnNoConsumers();
       int defaultMaxConsumers = addressSettings.getDefaultMaxConsumers();
+      boolean defaultExclusive = addressSettings.isDefaultExclusiveQueue();
+      boolean defaultLastValie = addressSettings.isDefaultLastValueQueue();
 
       List<SimpleString> names = new ArrayList<>();
 
@@ -833,7 +835,7 @@ public class ActiveMQServerImpl implements ActiveMQServer {
       SimpleString bindAddress = new SimpleString(realAddress);
       if (managementService != null) {
          if (bindAddress.equals(managementService.getManagementAddress())) {
-            return new BindingQueryResult(true, null, names, autoCreateQeueus, autoCreateAddresses, defaultPurgeOnNoConsumers, defaultMaxConsumers);
+            return new BindingQueryResult(true, null, names, autoCreateQeueus, autoCreateAddresses, defaultPurgeOnNoConsumers, defaultMaxConsumers, defaultExclusive, defaultLastValie);
          }
       }
 
@@ -851,7 +853,7 @@ public class ActiveMQServerImpl implements ActiveMQServer {
 
       AddressInfo info = getAddressInfo(bindAddress);
 
-      return new BindingQueryResult(info != null, info, names, autoCreateQeueus, autoCreateAddresses, defaultPurgeOnNoConsumers, defaultMaxConsumers);
+      return new BindingQueryResult(info != null, info, names, autoCreateQeueus, autoCreateAddresses, defaultPurgeOnNoConsumers, defaultMaxConsumers, defaultExclusive, defaultLastValie);
    }
 
    @Override
@@ -863,6 +865,8 @@ public class ActiveMQServerImpl implements ActiveMQServer {
       boolean autoCreateQueues = getAddressSettingsRepository().getMatch(name.toString()).isAutoCreateQueues();
       boolean defaultPurgeOnNoConsumers = getAddressSettingsRepository().getMatch(name.toString()).isDefaultPurgeOnNoConsumers();
       int defaultMaxConsumers = getAddressSettingsRepository().getMatch(name.toString()).getDefaultMaxConsumers();
+      boolean defaultExclusiveQueue = getAddressSettingsRepository().getMatch(name.toString()).isDefaultExclusiveQueue();
+      boolean defaultLastValueQueue = getAddressSettingsRepository().getMatch(name.toString()).isDefaultLastValueQueue();
 
       QueueQueryResult response;
 
@@ -877,14 +881,14 @@ public class ActiveMQServerImpl implements ActiveMQServer {
 
          SimpleString filterString = filter == null ? null : filter.getFilterString();
 
-         response = new QueueQueryResult(name, binding.getAddress(), queue.isDurable(), queue.isTemporary(), filterString, queue.getConsumerCount(), queue.getMessageCount(), autoCreateQueues, true, queue.isAutoCreated(), queue.isPurgeOnNoConsumers(), queue.getRoutingType(), queue.getMaxConsumers());
+         response = new QueueQueryResult(name, binding.getAddress(), queue.isDurable(), queue.isTemporary(), filterString, queue.getConsumerCount(), queue.getMessageCount(), autoCreateQueues, true, queue.isAutoCreated(), queue.isPurgeOnNoConsumers(), queue.getRoutingType(), queue.getMaxConsumers(), queue.isExclusive(), queue.isLastValue());
       } else if (name.equals(managementAddress)) {
          // make an exception for the management address (see HORNETQ-29)
-         response = new QueueQueryResult(name, managementAddress, true, false, null, -1, -1, autoCreateQueues, true, false, false, RoutingType.MULTICAST, -1);
+         response = new QueueQueryResult(name, managementAddress, true, false, null, -1, -1, autoCreateQueues, true, false, false, RoutingType.MULTICAST, -1, false, false);
       } else if (autoCreateQueues) {
-         response = new QueueQueryResult(name, name, true, false, null, 0, 0, true, false, false, defaultPurgeOnNoConsumers, RoutingType.MULTICAST, defaultMaxConsumers);
+         response = new QueueQueryResult(name, name, true, false, null, 0, 0, true, false, false, defaultPurgeOnNoConsumers, RoutingType.MULTICAST, defaultMaxConsumers, defaultExclusiveQueue, defaultLastValueQueue);
       } else {
-         response = new QueueQueryResult(null, null, false, false, null, 0, 0, false, false, false, false, RoutingType.MULTICAST, 0);
+         response = new QueueQueryResult(null, null, false, false, null, 0, 0, false, false, false, false, RoutingType.MULTICAST, 0, null, null);
       }
 
       return response;
@@ -1672,9 +1676,25 @@ public class ActiveMQServerImpl implements ActiveMQServer {
 
    @Override
    public Queue createQueue(AddressInfo addressInfo, SimpleString queueName, SimpleString filter, SimpleString user, boolean durable, boolean temporary, boolean autoCreated, Integer maxConsumers, Boolean purgeOnNoConsumers, boolean autoCreateAddress) throws Exception {
-      return createQueue(addressInfo, queueName, filter, user, durable, temporary, false, false, autoCreated, maxConsumers, purgeOnNoConsumers, autoCreateAddress);
+      AddressSettings as = getAddressSettingsRepository().getMatch(addressInfo == null ? queueName.toString() : addressInfo.getName().toString());
+      return createQueue(addressInfo, queueName, filter, user, durable, temporary, false, false, autoCreated, maxConsumers, purgeOnNoConsumers, as.isDefaultExclusiveQueue(), as.isDefaultLastValueQueue(), autoCreateAddress);
    }
 
+   @Override
+   public Queue createQueue(AddressInfo addressInfo, SimpleString queueName, SimpleString filter, SimpleString user, boolean durable, boolean temporary, boolean autoCreated, Integer maxConsumers, Boolean purgeOnNoConsumers, Boolean exclusive, Boolean lastValue, boolean autoCreateAddress) throws Exception {
+      return createQueue(addressInfo, queueName, filter, user, durable, temporary, false, false, autoCreated, maxConsumers, purgeOnNoConsumers, exclusive, lastValue, autoCreateAddress);
+   }
+
+
+   @Override
+   public Queue createQueue(SimpleString address, RoutingType routingType, SimpleString queueName, SimpleString filter,
+                     SimpleString user, boolean durable, boolean temporary, boolean ignoreIfExists, boolean transientQueue,
+                     boolean autoCreated, int maxConsumers, boolean purgeOnNoConsumers, boolean autoCreateAddress) throws Exception {
+      AddressSettings as = getAddressSettingsRepository().getMatch(address == null ? queueName.toString() : address.toString());
+      return createQueue(address, routingType, queueName, filter, user, durable, temporary, ignoreIfExists, transientQueue, autoCreated, maxConsumers, purgeOnNoConsumers, as.isDefaultExclusiveQueue(), as.isDefaultLastValueQueue(), autoCreateAddress);
+   }
+
+
    @Deprecated
    @Override
    public Queue createQueue(final SimpleString address,
@@ -1692,6 +1712,21 @@ public class ActiveMQServerImpl implements ActiveMQServer {
                                  final SimpleString filterString,
                                  final SimpleString user,
                                  boolean durable) throws Exception {
+      AddressSettings as = getAddressSettingsRepository().getMatch(address == null ? name.toString() : address.toString());
+      createSharedQueue(address, routingType, name, filterString, user, durable, as.getDefaultMaxConsumers(), as.isDefaultPurgeOnNoConsumers(), as.isDefaultExclusiveQueue(), as.isDefaultLastValueQueue());
+   }
+
+   @Override
+   public void createSharedQueue(final SimpleString address,
+                                 RoutingType routingType,
+                                 final SimpleString name,
+                                 final SimpleString filterString,
+                                 final SimpleString user,
+                                 boolean durable,
+                                 int maxConsumers,
+                                 boolean purgeOnNoConsumers,
+                                 boolean exclusive,
+                                 boolean lastValue) throws Exception {
       //force the old contract about address
       if (address == null) {
          throw new NullPointerException("address can't be null!");
@@ -1705,7 +1740,7 @@ public class ActiveMQServerImpl implements ActiveMQServer {
          }
       }
 
-      final Queue queue = createQueue(address, routingType, name, filterString, user, durable, !durable, true, !durable, false, Queue.MAX_CONSUMERS_UNLIMITED, false, true);
+      final Queue queue = createQueue(address, routingType, name, filterString, user, durable, !durable, true, !durable, false, maxConsumers, purgeOnNoConsumers, exclusive, lastValue, true);
 
       if (!queue.getAddress().equals(address)) {
          throw ActiveMQMessageBundle.BUNDLE.queueSubscriptionBelongsToDifferentAddress(name);
@@ -2480,16 +2515,19 @@ public class ActiveMQServerImpl implements ActiveMQServer {
       for (CoreQueueConfiguration config : queues) {
          SimpleString queueName = SimpleString.toSimpleString(config.getName());
          ActiveMQServerLogger.LOGGER.deployQueue(config.getName(), config.getAddress());
-
+         AddressSettings as = addressSettingsRepository.getMatch(config.getAddress());
          // determine if there is an address::queue match; update it if so
          if (locateQueue(queueName) != null && locateQueue(queueName).getAddress().toString().equals(config.getAddress())) {
-            updateQueue(config.getName(), config.getRoutingType(), config.getMaxConsumers(), config.getPurgeOnNoConsumers());
+            updateQueue(config.getName(), config.getRoutingType(), config.getMaxConsumers(), config.getPurgeOnNoConsumers(),
+                        config.isExclusive() == null ? as.isDefaultExclusiveQueue() : config.isExclusive());
          } else {
             // if the address::queue doesn't exist then create it
             try {
                createQueue(SimpleString.toSimpleString(config.getAddress()), config.getRoutingType(),
                            queueName, SimpleString.toSimpleString(config.getFilterString()), SimpleString.toSimpleString(config.getUser()),
-                           config.isDurable(),false,false,false,false,config.getMaxConsumers(),config.getPurgeOnNoConsumers(),true);
+                           config.isDurable(),false,false,false,false,config.getMaxConsumers(),config.getPurgeOnNoConsumers(),
+                           config.isExclusive() == null ? as.isDefaultExclusiveQueue() : config.isExclusive(),
+                           config.isLastValue() == null ? as.isDefaultLastValueQueue() : config.isLastValue(), true);
             } catch (ActiveMQQueueExistsException e) {
                // the queue may exist on a *different* address
                ActiveMQServerLogger.LOGGER.warn(e.getMessage());
@@ -2668,6 +2706,8 @@ public class ActiveMQServerImpl implements ActiveMQServer {
                             final boolean autoCreated,
                             final int maxConsumers,
                             final boolean purgeOnNoConsumers,
+                            final boolean exclusive,
+                            final boolean lastValue,
                             final boolean autoCreateAddress) throws Exception {
       final QueueBinding binding = (QueueBinding) postOffice.getBinding(queueName);
       if (binding != null) {
@@ -2710,7 +2750,7 @@ public class ActiveMQServerImpl implements ActiveMQServer {
          throw ActiveMQMessageBundle.BUNDLE.invalidRoutingTypeForAddress(rt, info.getName().toString(), info.getRoutingTypes());
       }
 
-      final QueueConfig queueConfig = queueConfigBuilder.filter(filter).pagingManager(pagingManager).user(user).durable(durable).temporary(temporary).autoCreated(autoCreated).routingType(addrInfo.getRoutingType()).maxConsumers(maxConsumers).purgeOnNoConsumers(purgeOnNoConsumers).build();
+      final QueueConfig queueConfig = queueConfigBuilder.filter(filter).pagingManager(pagingManager).user(user).durable(durable).temporary(temporary).autoCreated(autoCreated).routingType(addrInfo.getRoutingType()).maxConsumers(maxConsumers).purgeOnNoConsumers(purgeOnNoConsumers).exclusive(exclusive).lastValue(lastValue).build();
 
       callBrokerPlugins(hasBrokerPlugins() ? plugin -> plugin.beforeCreateQueue(queueConfig) : null);
 
@@ -2776,6 +2816,8 @@ public class ActiveMQServerImpl implements ActiveMQServer {
                             final boolean autoCreated,
                             final int maxConsumers,
                             final boolean purgeOnNoConsumers,
+                            final boolean exclusive,
+                            final boolean lastValue,
                             final boolean autoCreateAddress) throws Exception {
 
       final QueueBinding binding = (QueueBinding) postOffice.getBinding(queueName);
@@ -2817,7 +2859,7 @@ public class ActiveMQServerImpl implements ActiveMQServer {
          throw ActiveMQMessageBundle.BUNDLE.invalidRoutingTypeForAddress(routingType, info.getName().toString(), info.getRoutingTypes());
       }
 
-      final QueueConfig queueConfig = queueConfigBuilder.filter(filter).pagingManager(pagingManager).user(user).durable(durable).temporary(temporary).autoCreated(autoCreated).routingType(routingType).maxConsumers(maxConsumers).purgeOnNoConsumers(purgeOnNoConsumers).build();
+      final QueueConfig queueConfig = queueConfigBuilder.filter(filter).pagingManager(pagingManager).user(user).durable(durable).temporary(temporary).autoCreated(autoCreated).routingType(routingType).maxConsumers(maxConsumers).purgeOnNoConsumers(purgeOnNoConsumers).exclusive(exclusive).lastValue(lastValue).build();
 
       callBrokerPlugins(hasBrokerPlugins() ? plugin -> plugin.beforeCreateQueue(queueConfig) : null);
 
@@ -2873,8 +2915,16 @@ public class ActiveMQServerImpl implements ActiveMQServer {
                             RoutingType routingType,
                             Integer maxConsumers,
                             Boolean purgeOnNoConsumers) throws Exception {
+      return updateQueue(name, routingType, maxConsumers, purgeOnNoConsumers, null);
+   }
 
-      final QueueBinding queueBinding = this.postOffice.updateQueue(new SimpleString(name), routingType, maxConsumers, purgeOnNoConsumers);
+   @Override
+   public Queue updateQueue(String name,
+                            RoutingType routingType,
+                            Integer maxConsumers,
+                            Boolean purgeOnNoConsumers,
+                            Boolean exclusive) throws Exception {
+      final QueueBinding queueBinding = this.postOffice.updateQueue(new SimpleString(name), routingType, maxConsumers, purgeOnNoConsumers, exclusive);
       if (queueBinding != null) {
          final Queue queue = queueBinding.getQueue();
          return queue;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/LastValueQueue.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/LastValueQueue.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/LastValueQueue.java
index 5951a01..7aada5e 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/LastValueQueue.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/LastValueQueue.java
@@ -60,6 +60,7 @@ public class LastValueQueue extends QueueImpl {
                          final boolean autoCreated,
                          final RoutingType routingType,
                          final Integer maxConsumers,
+                         final Boolean exclusive,
                          final Boolean purgeOnNoConsumers,
                          final ScheduledExecutorService scheduledExecutor,
                          final PostOffice postOffice,
@@ -68,7 +69,7 @@ public class LastValueQueue extends QueueImpl {
                          final ArtemisExecutor executor,
                          final ActiveMQServer server,
                          final QueueFactory factory) {
-      super(persistenceID, address, name, filter, pageSubscription, user, durable, temporary, autoCreated, routingType, maxConsumers, purgeOnNoConsumers, scheduledExecutor, postOffice, storageManager, addressSettingsRepository, executor, server, factory);
+      super(persistenceID, address, name, filter, pageSubscription, user, durable, temporary, autoCreated, routingType, maxConsumers, exclusive, purgeOnNoConsumers, scheduledExecutor, postOffice, storageManager, addressSettingsRepository, executor, server, factory);
    }
 
    @Override
@@ -162,6 +163,11 @@ public class LastValueQueue extends QueueImpl {
       super.refRemoved(ref);
    }
 
+   @Override
+   public boolean isLastValue() {
+      return true;
+   }
+
    private class HolderReference implements MessageReference {
 
       private final SimpleString prop;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/PostOfficeJournalLoader.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/PostOfficeJournalLoader.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/PostOfficeJournalLoader.java
index 96b6662..cfd06d9 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/PostOfficeJournalLoader.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/PostOfficeJournalLoader.java
@@ -150,6 +150,7 @@ public class PostOfficeJournalLoader implements JournalLoader {
             .autoCreated(queueBindingInfo.isAutoCreated())
             .purgeOnNoConsumers(queueBindingInfo.isPurgeOnNoConsumers())
             .maxConsumers(queueBindingInfo.getMaxConsumers())
+            .exclusive(queueBindingInfo.isExclusive())
             .routingType(RoutingType.getType(queueBindingInfo.getRoutingType()));
          final Queue queue = queueFactory.createQueueWith(queueConfigBuilder.build());
          queue.setConsumersRefCount(new QueueManagerImpl(((PostOfficeImpl)postOffice).getServer(), queueBindingInfo.getQueueName()));

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueFactoryImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueFactoryImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueFactoryImpl.java
index 64da8b0..7f23d09 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueFactoryImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueFactoryImpl.java
@@ -72,12 +72,11 @@ public class QueueFactoryImpl implements QueueFactory {
 
    @Override
    public Queue createQueueWith(final QueueConfig config) {
-      final AddressSettings addressSettings = addressSettingsRepository.getMatch(config.address().toString());
       final Queue queue;
-      if (addressSettings.isLastValueQueue()) {
-         queue = new LastValueQueue(config.id(), config.address(), config.name(), config.filter(), config.pageSubscription(), config.user(), config.isDurable(), config.isTemporary(), config.isAutoCreated(), config.deliveryMode(), config.maxConsumers(), config.isPurgeOnNoConsumers(), scheduledExecutor, postOffice, storageManager, addressSettingsRepository, executorFactory.getExecutor(), server, this);
+      if (config.isLastValue()) {
+         queue = new LastValueQueue(config.id(), config.address(), config.name(), config.filter(), config.pageSubscription(), config.user(), config.isDurable(), config.isTemporary(), config.isAutoCreated(), config.deliveryMode(), config.maxConsumers(), config.isExclusive(), config.isPurgeOnNoConsumers(), scheduledExecutor, postOffice, storageManager, addressSettingsRepository, executorFactory.getExecutor(), server, this);
       } else {
-         queue = new QueueImpl(config.id(), config.address(), config.name(), config.filter(), config.pageSubscription(), config.user(), config.isDurable(), config.isTemporary(), config.isAutoCreated(), config.deliveryMode(), config.maxConsumers(), config.isPurgeOnNoConsumers(), scheduledExecutor, postOffice, storageManager, addressSettingsRepository, executorFactory.getExecutor(), server, this);
+         queue = new QueueImpl(config.id(), config.address(), config.name(), config.filter(), config.pageSubscription(), config.user(), config.isDurable(), config.isTemporary(), config.isAutoCreated(), config.deliveryMode(), config.maxConsumers(), config.isExclusive(), config.isPurgeOnNoConsumers(), scheduledExecutor, postOffice, storageManager, addressSettingsRepository, executorFactory.getExecutor(), server, this);
       }
 
       server.getCriticalAnalyzer().add(queue);
@@ -102,8 +101,8 @@ public class QueueFactoryImpl implements QueueFactory {
       AddressSettings addressSettings = addressSettingsRepository.getMatch(address.toString());
 
       Queue queue;
-      if (addressSettings.isLastValueQueue()) {
-         queue = new LastValueQueue(persistenceID, address, name, filter, pageSubscription, user, durable, temporary, autoCreated, ActiveMQDefaultConfiguration.getDefaultRoutingType(), ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers(), ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers(),  scheduledExecutor, postOffice, storageManager, addressSettingsRepository, executorFactory.getExecutor(), server, this);
+      if (addressSettings.isDefaultLastValueQueue()) {
+         queue = new LastValueQueue(persistenceID, address, name, filter, pageSubscription, user, durable, temporary, autoCreated, ActiveMQDefaultConfiguration.getDefaultRoutingType(), ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers(), ActiveMQDefaultConfiguration.getDefaultExclusive(), ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers(),  scheduledExecutor, postOffice, storageManager, addressSettingsRepository, executorFactory.getExecutor(), server, this);
       } else {
          queue = new QueueImpl(persistenceID, address, name, filter, pageSubscription, user, durable, temporary, autoCreated, scheduledExecutor, postOffice, storageManager, addressSettingsRepository, executorFactory.getExecutor(), server, this);
       }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueImpl.java
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueImpl.java
index c527c46..dbf79e2 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/QueueImpl.java
@@ -257,6 +257,8 @@ public class QueueImpl extends CriticalComponentImpl implements Queue {
 
    private volatile int maxConsumers;
 
+   private volatile boolean exclusive;
+
    private volatile boolean purgeOnNoConsumers;
 
    private final AddressInfo addressInfo;
@@ -389,6 +391,29 @@ public class QueueImpl extends CriticalComponentImpl implements Queue {
                     final ArtemisExecutor executor,
                     final ActiveMQServer server,
                     final QueueFactory factory) {
+      this(id, address, name, filter, pageSubscription, user, durable, temporary, autoCreated, routingType, maxConsumers, null, purgeOnNoConsumers, scheduledExecutor, postOffice, storageManager, addressSettingsRepository, executor, server, factory);
+   }
+
+   public QueueImpl(final long id,
+                    final SimpleString address,
+                    final SimpleString name,
+                    final Filter filter,
+                    final PageSubscription pageSubscription,
+                    final SimpleString user,
+                    final boolean durable,
+                    final boolean temporary,
+                    final boolean autoCreated,
+                    final RoutingType routingType,
+                    final Integer maxConsumers,
+                    final Boolean exclusive,
+                    final Boolean purgeOnNoConsumers,
+                    final ScheduledExecutorService scheduledExecutor,
+                    final PostOffice postOffice,
+                    final StorageManager storageManager,
+                    final HierarchicalRepository<AddressSettings> addressSettingsRepository,
+                    final ArtemisExecutor executor,
+                    final ActiveMQServer server,
+                    final QueueFactory factory) {
       super(server == null ? EmptyCriticalAnalyzer.getInstance() : server.getCriticalAnalyzer(), CRITICAL_PATHS);
 
       this.id = id;
@@ -413,6 +438,8 @@ public class QueueImpl extends CriticalComponentImpl implements Queue {
 
       this.maxConsumers = maxConsumers == null ? ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers() : maxConsumers;
 
+      this.exclusive = exclusive == null ? ActiveMQDefaultConfiguration.getDefaultExclusive() : exclusive;
+
       this.purgeOnNoConsumers = purgeOnNoConsumers == null ? ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers() : purgeOnNoConsumers;
 
       this.postOffice = postOffice;
@@ -463,7 +490,18 @@ public class QueueImpl extends CriticalComponentImpl implements Queue {
       return user;
    }
 
+   @Override
    public boolean isExclusive() {
+      return exclusive;
+   }
+
+   @Override
+   public synchronized void setExclusive(boolean exclusive) {
+      this.exclusive = exclusive;
+   }
+
+   @Override
+   public boolean isLastValue() {
       return false;
    }
 
@@ -2190,6 +2228,10 @@ public class QueueImpl extends CriticalComponentImpl implements Queue {
                   }
                }
 
+               if (exclusive) {
+                  consumer = consumerList.get(0).consumer;
+               }
+
                HandleStatus status = handle(ref, consumer);
 
                if (status == HandleStatus.HANDLED) {
@@ -2237,7 +2279,7 @@ public class QueueImpl extends CriticalComponentImpl implements Queue {
 
             // Only move onto the next position if the consumer on the current position was used.
             // When using group we don't need to load balance to the next position
-            if (groupConsumer == null) {
+            if (!exclusive && groupConsumer == null) {
                pos++;
             }
 
@@ -2730,8 +2772,12 @@ public class QueueImpl extends CriticalComponentImpl implements Queue {
                }
             }
 
+            if (exclusive) {
+               consumer = consumerList.get(0).consumer;
+            }
+
             // Only move onto the next position if the consumer on the current position was used.
-            if (groupConsumer == null) {
+            if (!exclusive && groupConsumer == null) {
                pos++;
             }
 

Reply | Threaded
Open this post in threaded view
|

[5/5] activemq-artemis git commit: ARTEMIS-853 Support for exclusive consumers

michaelpearce
In reply to this post by michaelpearce
ARTEMIS-853 Support for exclusive consumers

Support exlusive consumer
Allow default address level settings for exclusive consumer
Allow queue level setting in broker.xml
Add the ability to set queue settings via Core JMS using address. Similar to ActiveMQ 5.X
Allow for Core JMS client to define exclusive consumer using address parameters
Add tests

Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/dc41f3ca
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/dc41f3ca
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/dc41f3ca

Branch: refs/heads/master
Commit: dc41f3ca491e96e199290a225fdaa07ac05d66df
Parents: 56e1df3
Author: Michael André Pearce <[hidden email]>
Authored: Tue Jan 30 17:43:14 2018 +0000
Committer: Michael Andre Pearce <[hidden email]>
Committed: Wed Feb 7 15:27:29 2018 +0000

----------------------------------------------------------------------
 .../artemis/api/core/ParameterisedAddress.java  | 117 +++++++
 .../artemis/api/core/QueueAttributes.java       |  79 +++++
 .../config/ActiveMQDefaultConfiguration.java    |  12 +
 .../artemis/api/core/client/ClientSession.java  |  77 +++++
 .../core/management/ActiveMQServerControl.java  |  16 +
 .../api/core/management/QueueControl.java       |  12 +
 .../core/client/impl/AddressQueryImpl.java      |  20 +-
 .../core/client/impl/ClientSessionImpl.java     |  96 +++++-
 .../core/client/impl/QueueQueryImpl.java        |  33 ++
 .../core/impl/ActiveMQSessionContext.java       |  45 ++-
 .../impl/wireformat/CreateQueueMessage_V2.java  |  41 ++-
 .../wireformat/CreateSharedQueueMessage_V2.java |  75 ++++-
 .../SessionBindingQueryResponseMessage_V4.java  |  35 +-
 .../SessionQueueQueryResponseMessage_V3.java    |  49 ++-
 .../artemis/core/server/QueueQueryResult.java   |  20 +-
 .../spi/core/remoting/SessionContext.java       |  25 ++
 .../artemis/jms/client/ActiveMQDestination.java |  28 +-
 .../jms/client/ActiveMQMessageProducer.java     |  26 +-
 .../artemis/jms/client/ActiveMQSession.java     |  88 ++++-
 .../jms/client/ActiveMQParameterTest.java       |  46 +++
 .../client/HornetQClientSessionContext.java     |   2 +-
 .../core/config/CoreQueueConfiguration.java     |  36 +++
 .../deployers/impl/FileConfigurationParser.java |  19 +-
 .../impl/ActiveMQServerControlImpl.java         |  15 +-
 .../core/management/impl/QueueControlImpl.java  |  24 ++
 .../core/management/impl/view/QueueView.java    |   8 +-
 .../view/predicate/QueueFilterPredicate.java    |   6 +-
 .../core/persistence/QueueBindingInfo.java      |   4 +
 .../journal/AbstractJournalStorageManager.java  |   2 +-
 .../codec/PersistentQueueBindingEncoding.java   |  26 +-
 .../artemis/core/postoffice/PostOffice.java     |   3 +-
 .../core/postoffice/impl/PostOfficeImpl.java    |   7 +-
 .../core/ServerSessionPacketHandler.java        |   8 +-
 .../artemis/core/server/ActiveMQServer.java     |  17 +
 .../artemis/core/server/BindingQueryResult.java |  20 +-
 .../activemq/artemis/core/server/Queue.java     |   6 +
 .../artemis/core/server/QueueConfig.java        |  39 ++-
 .../artemis/core/server/ServerSession.java      |  31 ++
 .../core/server/impl/ActiveMQServerImpl.java    |  78 ++++-
 .../core/server/impl/LastValueQueue.java        |   8 +-
 .../server/impl/PostOfficeJournalLoader.java    |   1 +
 .../core/server/impl/QueueFactoryImpl.java      |  11 +-
 .../artemis/core/server/impl/QueueImpl.java     |  50 ++-
 .../core/server/impl/ServerSessionImpl.java     |  71 ++++-
 .../core/settings/impl/AddressSettings.java     |  60 +++-
 .../resources/schema/artemis-configuration.xsd  |  22 +-
 .../impl/ScheduledDeliveryHandlerTest.java      |  15 +
 .../test/resources/artemis-configuration.xsd    |  23 +-
 .../tests/integration/amqp/JMSLVQTest.java      |   2 +-
 .../client/MultipleProducersTest.java           |   2 +-
 .../client/SessionCreateAndDeleteQueueTest.java |   2 +-
 .../integration/client/UpdateQueueTest.java     |   2 +-
 .../integration/jms/client/ExclusiveTest.java   | 319 +++++++++++++++++++
 .../tests/integration/jms/client/LVQTest.java   | 145 +++++++++
 .../ActiveMQServerControlUsingCoreTest.java     |  10 +
 .../management/QueueControlUsingCoreTest.java   |  10 +
 .../integration/server/LVQRecoveryTest.java     |   4 +-
 .../tests/integration/server/LVQTest.java       |   2 +-
 .../jms/tests/message/MessageHeaderTest.java    |  27 ++
 .../unit/core/postoffice/impl/FakeQueue.java    |  17 +
 .../core/server/impl/fakes/FakePostOffice.java  |   3 +-
 61 files changed, 1967 insertions(+), 130 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/ParameterisedAddress.java
----------------------------------------------------------------------
diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/ParameterisedAddress.java b/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/ParameterisedAddress.java
new file mode 100644
index 0000000..bbc3c4d
--- /dev/null
+++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/ParameterisedAddress.java
@@ -0,0 +1,117 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.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.api.core;
+
+import java.util.Map;
+
+public class ParameterisedAddress {
+
+   public static SimpleString toParameterisedAddress(SimpleString address, Map<String, String> parameters) {
+      if (parameters != null && parameters.size() > 0) {
+         return SimpleString.toSimpleString(toParameterisedAddress(address.toString(), parameters));
+      } else {
+         return address;
+      }
+   }
+
+   public static String toParameterisedAddress(String address, Map<String, String> parameters) {
+      if (parameters != null && parameters.size() > 0) {
+         StringBuilder stringBuilder = new StringBuilder(address).append(PARAMETER_MARKER);
+         return toParameterString(stringBuilder, parameters).toString();
+      } else {
+         return address;
+      }
+   }
+
+   private static StringBuilder toParameterString(StringBuilder stringBuilder, Map<String, String> parameters) {
+      boolean first = true;
+      for (Map.Entry<String, String> entry : parameters.entrySet()) {
+         if (first) {
+            first = false;
+         } else {
+            stringBuilder.append(PARAMETER_SEPERATOR);
+         }
+         stringBuilder.append(entry.getKey()).append(PARAMETER_KEY_VALUE_SEPERATOR).append(entry.getValue());
+      }
+      return stringBuilder;
+   }
+
+   public static char PARAMETER_SEPERATOR = '&';
+   public static char PARAMETER_KEY_VALUE_SEPERATOR = '=';
+   public static char PARAMETER_MARKER = '?';
+   public static String PARAMETER_SEPERATOR_STRING = Character.toString(PARAMETER_SEPERATOR);
+   public static String PARAMETER_KEY_VALUE_SEPERATOR_STRING = Character.toString(PARAMETER_KEY_VALUE_SEPERATOR);
+   public static String PARAMETER_MARKER_STRING = Character.toString(PARAMETER_MARKER);
+   private final SimpleString address;
+   private final QueueAttributes queueAttributes;
+
+   public SimpleString getAddress() {
+      return address;
+   }
+
+   public QueueAttributes getQueueAttributes() {
+      return queueAttributes;
+   }
+
+   public ParameterisedAddress(SimpleString address, QueueAttributes queueAttributes) {
+      this.address = address;
+      this.queueAttributes = queueAttributes;
+   }
+
+   public ParameterisedAddress(String address, QueueAttributes queueAttributes) {
+      this(SimpleString.toSimpleString(address), queueAttributes);
+   }
+
+   public ParameterisedAddress(SimpleString address) {
+      this(address.toString());
+   }
+
+   public ParameterisedAddress(String address) {
+      int index = address.indexOf(PARAMETER_MARKER);
+      if (index == -1) {
+         this.address = SimpleString.toSimpleString(address);
+         this.queueAttributes = null;
+      } else {
+         this.address = SimpleString.toSimpleString(address.substring(0, index));
+         String parametersString = address.substring(index + 1, address.length());
+         String[] parameterPairs = parametersString.split(PARAMETER_SEPERATOR_STRING);
+         QueueAttributes queueAttributes = new QueueAttributes();
+         for (String param : parameterPairs) {
+            String[] keyValue = param.split(PARAMETER_KEY_VALUE_SEPERATOR_STRING);
+            if (keyValue.length != 2) {
+               throw new IllegalArgumentException("Malformed parameter section " + param);
+            } else {
+               queueAttributes.set(keyValue[0], keyValue[1]);
+            }
+         }
+         this.queueAttributes = queueAttributes;
+      }
+   }
+
+   public boolean isParameterised() {
+      return this.queueAttributes != null;
+   }
+
+   public static boolean isParameterised(String address) {
+      return address.contains(PARAMETER_MARKER_STRING);
+   }
+
+   public static boolean isParameterised(SimpleString address) {
+      return address.contains(PARAMETER_MARKER);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/QueueAttributes.java
----------------------------------------------------------------------
diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/QueueAttributes.java b/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/QueueAttributes.java
new file mode 100644
index 0000000..6a43b39
--- /dev/null
+++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/api/core/QueueAttributes.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.api.core;
+
+import java.io.Serializable;
+
+public class QueueAttributes implements Serializable {
+
+   public static final String MAX_CONSUMERS = "max-consumers";
+   public static final String EXCLUSIVE = "exclusive";
+   public static final String LAST_VALUE = "last-value";
+   public static final String PURGE_ON_NO_CONSUMERS = "purge-on-no-consumers";
+
+   private Integer maxConsumers;
+   private Boolean exclusive;
+   private Boolean lastValue;
+   private Boolean purgeOnNoConsumers;
+
+   public void set(String key, String value) {
+      if (key != null && value != null) {
+         if (key.equals(MAX_CONSUMERS)) {
+            setMaxConsumers(Integer.valueOf(value));
+         } else if (key.equals(EXCLUSIVE)) {
+            setExclusive(Boolean.valueOf(value));
+         } else if (key.equals(LAST_VALUE)) {
+            setLastValue(Boolean.valueOf(value));
+         } else if (key.equals(PURGE_ON_NO_CONSUMERS)) {
+            setPurgeOnNoConsumers(Boolean.valueOf(value));
+         }
+      }
+   }
+
+   public Integer getMaxConsumers() {
+      return maxConsumers;
+   }
+
+   public void setMaxConsumers(Integer maxConsumers) {
+      this.maxConsumers = maxConsumers;
+   }
+
+   public Boolean getExclusive() {
+      return exclusive;
+   }
+
+   public void setExclusive(Boolean exclusive) {
+      this.exclusive = exclusive;
+   }
+
+   public Boolean getLastValue() {
+      return lastValue;
+   }
+
+   public void setLastValue(Boolean lastValue) {
+      this.lastValue = lastValue;
+   }
+
+   public Boolean getPurgeOnNoConsumers() {
+      return purgeOnNoConsumers;
+   }
+
+   public void setPurgeOnNoConsumers(Boolean purgeOnNoConsumers) {
+      this.purgeOnNoConsumers = purgeOnNoConsumers;
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java
index fe7e1bf..87f6dad 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java
@@ -465,6 +465,10 @@ public final class ActiveMQDefaultConfiguration {
 
    public static final int DEFAULT_MAX_QUEUE_CONSUMERS = -1;
 
+   public static final boolean DEFAULT_EXCLUSIVE = false;
+
+   public static final boolean DEFAULT_LAST_VALUE = false;
+
    public static final boolean DEFAULT_PURGE_ON_NO_CONSUMERS = false;
 
    public static final RoutingType DEFAULT_ROUTING_TYPE = RoutingType.MULTICAST;
@@ -1277,6 +1281,14 @@ public final class ActiveMQDefaultConfiguration {
       return DEFAULT_MAX_QUEUE_CONSUMERS;
    }
 
+   public static boolean getDefaultExclusive() {
+      return DEFAULT_EXCLUSIVE;
+   }
+
+   public static boolean getDefaultLastValue() {
+      return DEFAULT_EXCLUSIVE;
+   }
+
    public static boolean getDefaultPurgeOnNoConsumers() {
       return DEFAULT_PURGE_ON_NO_CONSUMERS;
    }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/ClientSession.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/ClientSession.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/ClientSession.java
index ce56013..ddc8168 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/ClientSession.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/ClientSession.java
@@ -75,6 +75,10 @@ public interface ClientSession extends XAResource, AutoCloseable {
       boolean isDefaultPurgeOnNoConsumers();
 
       int getDefaultMaxConsumers();
+
+      Boolean isDefaultLastValueQueue();
+
+      Boolean isDefaultExclusive();
    }
 
    /**
@@ -139,6 +143,10 @@ public interface ClientSession extends XAResource, AutoCloseable {
       boolean isPurgeOnNoConsumers();
 
       boolean isAutoCreated();
+
+      Boolean isExclusive();
+
+      Boolean isLastValue();
    }
 
    // Lifecycle operations ------------------------------------------
@@ -455,6 +463,23 @@ public interface ClientSession extends XAResource, AutoCloseable {
                           boolean durable) throws ActiveMQException;
 
    /**
+    * Creates Shared queue. A queue that will exist as long as there are consumers or is durable.
+    *
+    * @param address   the queue will be bound to this address
+    * @param routingType the delivery mode for this queue, MULTICAST or ANYCAST
+    * @param queueName the name of the queue
+    * @param filter    whether the queue is durable or not
+    * @param durable   if the queue is durable
+    * @param maxConsumers how many concurrent consumers will be allowed on this queue
+    * @param purgeOnNoConsumers whether to delete the contents of the queue when the last consumer disconnects
+    * @param exclusive    if the queue is exclusive queue
+    * @param lastValue    if the queue is last value queue
+    * @throws ActiveMQException in an exception occurs while creating the queue
+    */
+   void createSharedQueue(SimpleString address, RoutingType routingType, SimpleString queueName, SimpleString filter,
+                          boolean durable, Integer maxConsumers, Boolean purgeOnNoConsumers, Boolean exclusive, Boolean lastValue) throws ActiveMQException;
+
+   /**
     * Creates a <em>non-temporary</em> queue.
     *
     * @param address   the queue will be bound to this address
@@ -541,6 +566,24 @@ public interface ClientSession extends XAResource, AutoCloseable {
                     boolean durable, boolean autoCreated, int maxConsumers, boolean purgeOnNoConsumers) throws ActiveMQException;
 
    /**
+    * Creates a <em>non-temporary</em> queue.
+    *
+    * @param address      the queue will be bound to this address
+    * @param routingType  the delivery mode for this queue, MULTICAST or ANYCAST
+    * @param queueName    the name of the queue
+    * @param filter       only messages which match this filter will be put in the queue
+    * @param durable      whether the queue is durable or not
+    * @param autoCreated  whether to mark this queue as autoCreated or not
+    * @param maxConsumers how many concurrent consumers will be allowed on this queue
+    * @param purgeOnNoConsumers whether to delete the contents of the queue when the last consumer disconnects
+    * @param exclusive whether the queue should be exclusive
+    * @param lastValue whether the queue should be lastValue
+    * @throws ActiveMQException
+    */
+   void createQueue(SimpleString address, RoutingType routingType, SimpleString queueName, SimpleString filter,
+                    boolean durable, boolean autoCreated, int maxConsumers, boolean purgeOnNoConsumers, Boolean exclusive, Boolean lastValue) throws ActiveMQException;
+
+   /**
     * Creates a <em>non-temporary</em>queue.
     *
     * @param address     the queue will be bound to this address
@@ -570,6 +613,24 @@ public interface ClientSession extends XAResource, AutoCloseable {
                            int maxConsumers, boolean purgeOnNoConsumers) throws ActiveMQException;
 
    /**
+    * Creates a <em>non-temporary</em>queue.
+    *
+    * @param address     the queue will be bound to this address
+    * @param routingType the delivery mode for this queue, MULTICAST or ANYCAST
+    * @param queueName   the name of the queue
+    * @param filter      only messages which match this filter will be put in the queue
+    * @param durable     whether the queue is durable or not
+    * @param autoCreated whether to mark this queue as autoCreated or not
+    * @param maxConsumers how many concurrent consumers will be allowed on this queue
+    * @param purgeOnNoConsumers whether to delete the contents of the queue when the last consumer disconnects
+    * @param exclusive whether the queue should be exclusive
+    * @param lastValue whether the queue should be lastValue
+    * @throws ActiveMQException
+    */
+   void createQueue(String address, RoutingType routingType, String queueName, String filter, boolean durable, boolean autoCreated,
+                    int maxConsumers, boolean purgeOnNoConsumers, Boolean exclusive, Boolean lastValue) throws ActiveMQException;
+
+   /**
     * Creates a <em>temporary</em> queue.
     *
     * @param address   the queue will be bound to this address
@@ -596,6 +657,22 @@ public interface ClientSession extends XAResource, AutoCloseable {
     * @param routingType the delivery mode for this queue, MULTICAST or ANYCAST
     * @param queueName the name of the queue
     * @param filter    only messages which match this filter will be put in the queue
+    * @param maxConsumers how many concurrent consumers will be allowed on this queue
+    * @param purgeOnNoConsumers whether to delete the contents of the queue when the last consumer disconnects
+    * @param exclusive    if the queue is exclusive queue
+    * @param lastValue    if the queue is last value queue
+    * @throws ActiveMQException in an exception occurs while creating the queue
+    */
+   void createTemporaryQueue(SimpleString address, RoutingType routingType, SimpleString queueName, SimpleString filter, int maxConsumers,
+                             boolean purgeOnNoConsumers, Boolean exclusive, Boolean lastValue) throws ActiveMQException;
+
+   /**
+    * Creates a <em>temporary</em> queue with a filter.
+    *
+    * @param address   the queue will be bound to this address
+    * @param routingType the delivery mode for this queue, MULTICAST or ANYCAST
+    * @param queueName the name of the queue
+    * @param filter    only messages which match this filter will be put in the queue
     * @throws ActiveMQException in an exception occurs while creating the queue
     */
    void createTemporaryQueue(SimpleString address, RoutingType routingType, SimpleString queueName, SimpleString filter) throws ActiveMQException;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ActiveMQServerControl.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ActiveMQServerControl.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ActiveMQServerControl.java
index 7c9a40a..fc9de24 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ActiveMQServerControl.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ActiveMQServerControl.java
@@ -617,6 +617,22 @@ public interface ActiveMQServerControl {
                       @Parameter(name = "purgeOnNoConsumers", desc = "Delete this queue when the last consumer disconnects") Boolean purgeOnNoConsumers) throws Exception;
 
 
+   /**
+    * Update a queue.
+    *
+    * @param name                name of the queue
+    * @param routingType         the routing type used for this address, {@code MULTICAST} or {@code ANYCAST}
+    * @param maxConsumers        the maximum number of consumers allowed on this queue at any one time
+    * @param purgeOnNoConsumers delete this queue when the last consumer disconnects
+    * @return a textual summary of the queue
+    * @throws Exception
+    */
+   String updateQueue(@Parameter(name = "name", desc = "Name of the queue") String name,
+                      @Parameter(name = "routingType", desc = "The routing type used for this address, MULTICAST or ANYCAST") String routingType,
+                      @Parameter(name = "maxConsumers", desc = "The maximum number of consumers allowed on this queue at any one time") Integer maxConsumers,
+                      @Parameter(name = "purgeOnNoConsumers", desc = "Delete this queue when the last consumer disconnects") Boolean purgeOnNoConsumers,
+                      @Parameter(name = "exclusive", desc = "If the queue should route exclusively to one consumer") Boolean exclusive) throws Exception;
+
 
    /**
     * Deploy a durable queue.

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/QueueControl.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/QueueControl.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/QueueControl.java
index 9eec8e0..447417f 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/QueueControl.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/QueueControl.java
@@ -164,6 +164,18 @@ public interface QueueControl {
    @Attribute(desc = "delete this queue when the last consumer disconnects")
    boolean isPurgeOnNoConsumers();
 
+   /**
+    *
+    */
+   @Attribute(desc = "If the queue should route exclusively to one consumer")
+   boolean isExclusive();
+
+   /**
+    *
+    */
+   @Attribute(desc = "is this queue a last value queue")
+   boolean isLastValue();
+
    // Operations ----------------------------------------------------
 
    /**

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/AddressQueryImpl.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/AddressQueryImpl.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/AddressQueryImpl.java
index 79e2cc9..cb91919 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/AddressQueryImpl.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/AddressQueryImpl.java
@@ -36,18 +36,26 @@ public class AddressQueryImpl implements ClientSession.AddressQuery {
 
    private final int defaultMaxConsumers;
 
+   private final Boolean defaultExclusive;
+
+   private final Boolean defaultLastValue;
+
    public AddressQueryImpl(final boolean exists,
                            final List<SimpleString> queueNames,
                            final boolean autoCreateQueues,
                            final boolean autoCreateAddresses,
                            final boolean defaultPurgeOnNoConsumers,
-                           final int defaultMaxConsumers) {
+                           final int defaultMaxConsumers,
+                           final Boolean defaultExclusive,
+                           final Boolean defaultLastValue) {
       this.exists = exists;
       this.queueNames = new ArrayList<>(queueNames);
       this.autoCreateQueues = autoCreateQueues;
       this.autoCreateAddresses = autoCreateAddresses;
       this.defaultPurgeOnNoConsumers = defaultPurgeOnNoConsumers;
       this.defaultMaxConsumers = defaultMaxConsumers;
+      this.defaultExclusive = defaultExclusive;
+      this.defaultLastValue = defaultLastValue;
    }
 
    @Override
@@ -79,4 +87,14 @@ public class AddressQueryImpl implements ClientSession.AddressQuery {
    public int getDefaultMaxConsumers() {
       return defaultMaxConsumers;
    }
+
+   @Override
+   public Boolean isDefaultLastValueQueue() {
+      return defaultLastValue;
+   }
+
+   @Override
+   public Boolean isDefaultExclusive() {
+      return defaultExclusive;
+   }
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/ClientSessionImpl.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/ClientSessionImpl.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/ClientSessionImpl.java
index e5e91db..ab9888e 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/ClientSessionImpl.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/ClientSessionImpl.java
@@ -376,7 +376,7 @@ public final class ClientSessionImpl implements ClientSessionInternal, FailureLi
                           false,
                           ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers(),
                           ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers(),
-                          autoCreated);
+                          autoCreated, null, null);
    }
 
    @Override
@@ -400,12 +400,42 @@ public final class ClientSessionImpl implements ClientSessionInternal, FailureLi
                           false,
                           maxConsumers,
                           purgeOnNoConsumers,
-                          autoCreated);
+                          autoCreated, null, null);
+   }
+
+   @Override
+   public void createQueue(final SimpleString address, final RoutingType routingType, final SimpleString queueName, final SimpleString filterString,
+                           final boolean durable, final boolean autoCreated, final int maxConsumers, final boolean purgeOnNoConsumers, final Boolean exclusive, final Boolean lastValue) throws ActiveMQException {
+      internalCreateQueue(address,
+                          queueName, routingType,
+                          filterString,
+                          durable,
+                          false,
+                          maxConsumers,
+                          purgeOnNoConsumers,
+                          autoCreated,
+                          exclusive,
+                          lastValue);
    }
 
    @Override
    public void createQueue(final String address, final RoutingType routingType, final String queueName, final String filterString,
                            final boolean durable, final boolean autoCreated, final int maxConsumers, final boolean purgeOnNoConsumers) throws ActiveMQException {
+      createQueue(address,
+                  routingType,
+                  queueName,
+                  filterString,
+                  durable,
+                  autoCreated,
+                  maxConsumers,
+                  purgeOnNoConsumers,
+                  null,
+                  null);
+   }
+
+   @Override
+   public void createQueue(final String address, final RoutingType routingType, final String queueName, final String filterString,
+                           final boolean durable, final boolean autoCreated, final int maxConsumers, final boolean purgeOnNoConsumers, Boolean exclusive, Boolean lastValue) throws ActiveMQException {
       createQueue(SimpleString.toSimpleString(address),
                   routingType,
                   SimpleString.toSimpleString(queueName),
@@ -413,7 +443,9 @@ public final class ClientSessionImpl implements ClientSessionInternal, FailureLi
                   durable,
                   autoCreated,
                   maxConsumers,
-                  purgeOnNoConsumers);
+                  purgeOnNoConsumers,
+                  exclusive,
+                  lastValue);
    }
 
    @Override
@@ -432,15 +464,27 @@ public final class ClientSessionImpl implements ClientSessionInternal, FailureLi
    public void createTemporaryQueue(final SimpleString address,
                                     final RoutingType routingType,
                                     final SimpleString queueName,
-                                    final SimpleString filter) throws ActiveMQException {
+                                    final SimpleString filter,
+                                    final int maxConsumers,
+                                    final boolean purgeOnNoConsumers,
+                                    final Boolean exclusive,
+                                    final Boolean lastValue) throws ActiveMQException {
       internalCreateQueue(address,
                           queueName, routingType,
                           filter,
                           false,
                           true,
-                          ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers(),
-                          ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers(),
-                          false);
+                          maxConsumers,
+                          purgeOnNoConsumers,
+                          false, exclusive, lastValue);
+   }
+
+   @Override
+   public void createTemporaryQueue(final SimpleString address,
+                                    final RoutingType routingType,
+                                    final SimpleString queueName,
+                                    final SimpleString filter) throws ActiveMQException {
+      createTemporaryQueue(address, routingType, queueName, filter, ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers(), ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers(), null, null);
    }
 
    @Override
@@ -466,7 +510,7 @@ public final class ClientSessionImpl implements ClientSessionInternal, FailureLi
                           false,
                           ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers(),
                           ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers(),
-                          false);
+                          false, null, null);
    }
 
    /**
@@ -500,11 +544,31 @@ public final class ClientSessionImpl implements ClientSessionInternal, FailureLi
    @Override
    public void createSharedQueue(SimpleString address, RoutingType routingType, SimpleString queueName, SimpleString filter,
                                  boolean durable) throws ActiveMQException {
+      createSharedQueue(address, routingType, queueName, filter, durable, null, null, null, null);
+   }
+
+   /**
+    * Creates Shared queue. A queue that will exist as long as there are consumers or is durable.
+    *
+    * @param address      the queue will be bound to this address
+    * @param routingType the delivery mode for this queue, MULTICAST or ANYCAST
+    * @param queueName    the name of the queue
+    * @param filter       whether the queue is durable or not
+    * @param durable      if the queue is durable
+    * @param maxConsumers how many concurrent consumers will be allowed on this queue
+    * @param purgeOnNoConsumers whether to delete the contents of the queue when the last consumer disconnects
+    * @param exclusive    if the queue is exclusive queue
+    * @param lastValue    if the queue is last value queue
+    * @throws ActiveMQException in an exception occurs while creating the queue
+    */
+   @Override
+   public void createSharedQueue(SimpleString address, RoutingType routingType, SimpleString queueName, SimpleString filter,
+                                 boolean durable, Integer maxConsumers, Boolean purgeOnNoConsumers, Boolean exclusive, Boolean lastValue) throws ActiveMQException {
       checkClosed();
 
       startCall();
       try {
-         sessionContext.createSharedQueue(address, queueName, routingType, filter, durable);
+         sessionContext.createSharedQueue(address, queueName, routingType, filter, durable, maxConsumers, purgeOnNoConsumers, exclusive, lastValue);
       } finally {
          endCall();
       }
@@ -541,7 +605,7 @@ public final class ClientSessionImpl implements ClientSessionInternal, FailureLi
                           false,
                           ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers(),
                           ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers(),
-                          false);
+                          false, null, null);
    }
 
    /**
@@ -562,7 +626,7 @@ public final class ClientSessionImpl implements ClientSessionInternal, FailureLi
                           false,
                           ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers(),
                           ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers(),
-                          false);
+                          false, null, null);
    }
 
    /**
@@ -586,7 +650,7 @@ public final class ClientSessionImpl implements ClientSessionInternal, FailureLi
                           false,
                           ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers(),
                           ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers(),
-                          false);
+                          false, null, null);
    }
 
    /**
@@ -1847,7 +1911,9 @@ public final class ClientSessionImpl implements ClientSessionInternal, FailureLi
                                     final boolean temp,
                                     final int maxConsumers,
                                     final boolean purgeOnNoConsumers,
-                                    final boolean autoCreated) throws ActiveMQException {
+                                    final boolean autoCreated,
+                                    final Boolean exclusive,
+                                    final Boolean lastValue) throws ActiveMQException {
       checkClosed();
 
       if (durable && temp) {
@@ -1864,7 +1930,9 @@ public final class ClientSessionImpl implements ClientSessionInternal, FailureLi
                                     temp,
                                     maxConsumers,
                                     purgeOnNoConsumers,
-                                    autoCreated);
+                                    autoCreated,
+                                    exclusive,
+                                    lastValue);
       } finally {
          endCall();
       }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/QueueQueryImpl.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/QueueQueryImpl.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/QueueQueryImpl.java
index 71488c2..8dc35a9 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/QueueQueryImpl.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/QueueQueryImpl.java
@@ -48,6 +48,10 @@ public class QueueQueryImpl implements ClientSession.QueueQuery {
 
    private final int maxConsumers;
 
+   private final Boolean exclusive;
+
+   private final Boolean lastValue;
+
    public QueueQueryImpl(final boolean durable,
                          final boolean temporary,
                          final int consumerCount,
@@ -84,6 +88,23 @@ public class QueueQueryImpl implements ClientSession.QueueQuery {
                          final boolean autoCreated,
                          final boolean purgeOnNoConsumers,
                          final RoutingType routingType) {
+      this(durable, temporary, consumerCount, messageCount, filterString, address, name, exists, autoCreateQueues, maxConsumers, autoCreated, purgeOnNoConsumers, routingType, null, null);
+   }
+   public QueueQueryImpl(final boolean durable,
+                         final boolean temporary,
+                         final int consumerCount,
+                         final long messageCount,
+                         final SimpleString filterString,
+                         final SimpleString address,
+                         final SimpleString name,
+                         final boolean exists,
+                         final boolean autoCreateQueues,
+                         final int maxConsumers,
+                         final boolean autoCreated,
+                         final boolean purgeOnNoConsumers,
+                         final RoutingType routingType,
+                         final Boolean exclusive,
+                         final Boolean lastValue) {
       this.durable = durable;
       this.temporary = temporary;
       this.consumerCount = consumerCount;
@@ -97,6 +118,8 @@ public class QueueQueryImpl implements ClientSession.QueueQuery {
       this.autoCreated = autoCreated;
       this.purgeOnNoConsumers = purgeOnNoConsumers;
       this.routingType = routingType;
+      this.exclusive = exclusive;
+      this.lastValue = lastValue;
    }
 
    @Override
@@ -164,5 +187,15 @@ public class QueueQueryImpl implements ClientSession.QueueQuery {
       return autoCreated;
    }
 
+   @Override
+   public Boolean isExclusive() {
+      return exclusive;
+   }
+
+   @Override
+   public Boolean isLastValue() {
+      return lastValue;
+   }
+
 }
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/ActiveMQSessionContext.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/ActiveMQSessionContext.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/ActiveMQSessionContext.java
index 3a4878b..6037925 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/ActiveMQSessionContext.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/ActiveMQSessionContext.java
@@ -249,8 +249,21 @@ public class ActiveMQSessionContext extends SessionContext {
                                  SimpleString queueName,
                                  RoutingType routingType,
                                  SimpleString filterString,
+                                 boolean durable,
+                                 Integer maxConsumers,
+                                 Boolean purgeOnNoConsumers,
+                                 Boolean exclusive,
+                                 Boolean lastValue) throws ActiveMQException {
+      sessionChannel.sendBlocking(new CreateSharedQueueMessage_V2(address, queueName, routingType, filterString, durable, maxConsumers, purgeOnNoConsumers, exclusive, lastValue, true), PacketImpl.NULL_RESPONSE);
+   }
+
+   @Override
+   public void createSharedQueue(SimpleString address,
+                                 SimpleString queueName,
+                                 RoutingType routingType,
+                                 SimpleString filterString,
                                  boolean durable) throws ActiveMQException {
-      sessionChannel.sendBlocking(new CreateSharedQueueMessage_V2(address, queueName, routingType, filterString, durable, true), PacketImpl.NULL_RESPONSE);
+      createSharedQueue(address, queueName, routingType, filterString, durable, null, null, null, null);
    }
 
    @Override
@@ -325,19 +338,19 @@ public class ActiveMQSessionContext extends SessionContext {
       if (sessionChannel.supports(PacketImpl.SESS_BINDINGQUERY_RESP_V4, getServerVersion())) {
          Packet packet = sessionChannel.sendBlocking(new SessionBindingQueryMessage(address), PacketImpl.SESS_BINDINGQUERY_RESP_V4);
          SessionBindingQueryResponseMessage_V4 response = (SessionBindingQueryResponseMessage_V4) packet;
-         return new AddressQueryImpl(response.isExists(), response.getQueueNames(), response.isAutoCreateQueues(), response.isAutoCreateAddresses(), response.isDefaultPurgeOnNoConsumers(), response.getDefaultMaxConsumers());
+         return new AddressQueryImpl(response.isExists(), response.getQueueNames(), response.isAutoCreateQueues(), response.isAutoCreateAddresses(), response.isDefaultPurgeOnNoConsumers(), response.getDefaultMaxConsumers(), response.isDefaultExclusive(), response.isDefaultLastValue());
       } else if (sessionChannel.supports(PacketImpl.SESS_BINDINGQUERY_RESP_V3, getServerVersion())) {
          Packet packet = sessionChannel.sendBlocking(new SessionBindingQueryMessage(address), PacketImpl.SESS_BINDINGQUERY_RESP_V3);
          SessionBindingQueryResponseMessage_V3 response = (SessionBindingQueryResponseMessage_V3) packet;
-         return new AddressQueryImpl(response.isExists(), response.getQueueNames(), response.isAutoCreateQueues(), response.isAutoCreateAddresses(), ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers(), ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers());
+         return new AddressQueryImpl(response.isExists(), response.getQueueNames(), response.isAutoCreateQueues(), response.isAutoCreateAddresses(), ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers(), ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers(), null, null);
       } else if (sessionChannel.supports(PacketImpl.SESS_BINDINGQUERY_RESP_V2, getServerVersion())) {
          Packet packet = sessionChannel.sendBlocking(new SessionBindingQueryMessage(address), PacketImpl.SESS_BINDINGQUERY_RESP_V2);
          SessionBindingQueryResponseMessage_V2 response = (SessionBindingQueryResponseMessage_V2) packet;
-         return new AddressQueryImpl(response.isExists(), response.getQueueNames(), response.isAutoCreateQueues(), false, ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers(), ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers());
+         return new AddressQueryImpl(response.isExists(), response.getQueueNames(), response.isAutoCreateQueues(), false, ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers(), ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers(), null, null);
       } else {
          Packet packet = sessionChannel.sendBlocking(new SessionBindingQueryMessage(address), PacketImpl.SESS_BINDINGQUERY_RESP);
          SessionBindingQueryResponseMessage response = (SessionBindingQueryResponseMessage) packet;
-         return new AddressQueryImpl(response.isExists(), response.getQueueNames(), false, false, ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers(), ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers());
+         return new AddressQueryImpl(response.isExists(), response.getQueueNames(), false, false, ActiveMQDefaultConfiguration.getDefaultPurgeOnNoConsumers(), ActiveMQDefaultConfiguration.getDefaultMaxQueueConsumers(), null, null);
       }
    }
 
@@ -647,16 +660,32 @@ public class ActiveMQSessionContext extends SessionContext {
                            boolean temp,
                            int maxConsumers,
                            boolean purgeOnNoConsumers,
-                           boolean autoCreated) throws ActiveMQException {
+                           boolean autoCreated,
+                           Boolean exclusive,
+                           Boolean lastValue) throws ActiveMQException {
       if (sessionChannel.getConnection().isVersionBeforeAddressChange()) {
          CreateQueueMessage request = new CreateQueueMessage(address, queueName, filterString, durable, temp, true);
          sessionChannel.sendBlocking(request, PacketImpl.NULL_RESPONSE);
       } else {
-         CreateQueueMessage request = new CreateQueueMessage_V2(address, queueName, routingType, filterString, durable, temp, maxConsumers, purgeOnNoConsumers, autoCreated, true);
+         CreateQueueMessage request = new CreateQueueMessage_V2(address, queueName, routingType, filterString, durable, temp, maxConsumers, purgeOnNoConsumers, autoCreated, true, exclusive, lastValue);
          sessionChannel.sendBlocking(request, PacketImpl.NULL_RESPONSE);
       }
    }
 
+   @Deprecated
+   @Override
+   public void createQueue(SimpleString address,
+                           RoutingType routingType,
+                           SimpleString queueName,
+                           SimpleString filterString,
+                           boolean durable,
+                           boolean temp,
+                           int maxConsumers,
+                           boolean purgeOnNoConsumers,
+                           boolean autoCreated) throws ActiveMQException {
+      createQueue(address, routingType, queueName, filterString, durable, temp, maxConsumers, purgeOnNoConsumers, autoCreated, null, null);
+   }
+
    @Override
    public boolean reattachOnNewConnection(RemotingConnection newConnection) throws ActiveMQException {
 
@@ -741,7 +770,7 @@ public class ActiveMQSessionContext extends SessionContext {
       // they are defined in broker.xml
       // This allows e.g. JMS non durable subs and temporary queues to continue to be used after failover
       if (!queueInfo.isDurable()) {
-         CreateQueueMessage_V2 createQueueRequest = new CreateQueueMessage_V2(queueInfo.getAddress(), queueInfo.getName(), queueInfo.getRoutingType(), queueInfo.getFilterString(), false, queueInfo.isTemporary(), queueInfo.getMaxConsumers(), queueInfo.isPurgeOnNoConsumers(), queueInfo.isAutoCreated(), false);
+         CreateQueueMessage_V2 createQueueRequest = new CreateQueueMessage_V2(queueInfo.getAddress(), queueInfo.getName(), queueInfo.getRoutingType(), queueInfo.getFilterString(), false, queueInfo.isTemporary(), queueInfo.getMaxConsumers(), queueInfo.isPurgeOnNoConsumers(), queueInfo.isAutoCreated(), false, queueInfo.isExclusive(), queueInfo.isLastValue());
 
          sendPacketWithoutLock(sessionChannel, createQueueRequest);
       }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/wireformat/CreateQueueMessage_V2.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/wireformat/CreateQueueMessage_V2.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/wireformat/CreateQueueMessage_V2.java
index 4c4b737..4ffeb5c 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/wireformat/CreateQueueMessage_V2.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/wireformat/CreateQueueMessage_V2.java
@@ -19,6 +19,7 @@ package org.apache.activemq.artemis.core.protocol.core.impl.wireformat;
 import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
 import org.apache.activemq.artemis.api.core.SimpleString;
 import org.apache.activemq.artemis.api.core.RoutingType;
+import org.apache.activemq.artemis.utils.BufferHelper;
 
 public class CreateQueueMessage_V2 extends CreateQueueMessage {
 
@@ -30,6 +31,10 @@ public class CreateQueueMessage_V2 extends CreateQueueMessage {
 
    private boolean purgeOnNoConsumers;
 
+   private Boolean exclusive;
+
+   private Boolean lastValue;
+
    public CreateQueueMessage_V2(final SimpleString address,
                                 final SimpleString queueName,
                                 final RoutingType routingType,
@@ -39,7 +44,9 @@ public class CreateQueueMessage_V2 extends CreateQueueMessage {
                                 final int maxConsumers,
                                 final boolean purgeOnNoConsumers,
                                 final boolean autoCreated,
-                                final boolean requiresResponse) {
+                                final boolean requiresResponse,
+                                final Boolean exclusive,
+                                final Boolean lastValue) {
       this();
 
       this.address = address;
@@ -52,6 +59,8 @@ public class CreateQueueMessage_V2 extends CreateQueueMessage {
       this.routingType = routingType;
       this.maxConsumers = maxConsumers;
       this.purgeOnNoConsumers = purgeOnNoConsumers;
+      this.exclusive = exclusive;
+      this.lastValue = lastValue;
    }
 
    public CreateQueueMessage_V2() {
@@ -67,6 +76,8 @@ public class CreateQueueMessage_V2 extends CreateQueueMessage {
       buff.append(", routingType=" + routingType);
       buff.append(", maxConsumers=" + maxConsumers);
       buff.append(", purgeOnNoConsumers=" + purgeOnNoConsumers);
+      buff.append(", exclusive=" + exclusive);
+      buff.append(", lastValue=" + lastValue);
       buff.append("]");
       return buff.toString();
    }
@@ -103,6 +114,22 @@ public class CreateQueueMessage_V2 extends CreateQueueMessage {
       this.autoCreated = autoCreated;
    }
 
+   public Boolean isExclusive() {
+      return exclusive;
+   }
+
+   public void setExclusive(Boolean exclusive) {
+      this.exclusive = exclusive;
+   }
+
+   public Boolean isLastValue() {
+      return lastValue;
+   }
+
+   public void setLastValue(Boolean lastValue) {
+      this.lastValue = lastValue;
+   }
+
    @Override
    public void encodeRest(final ActiveMQBuffer buffer) {
       super.encodeRest(buffer);
@@ -110,6 +137,8 @@ public class CreateQueueMessage_V2 extends CreateQueueMessage {
       buffer.writeByte(routingType == null ? -1 : routingType.getType());
       buffer.writeInt(maxConsumers);
       buffer.writeBoolean(purgeOnNoConsumers);
+      BufferHelper.writeNullableBoolean(buffer, exclusive);
+      BufferHelper.writeNullableBoolean(buffer, lastValue);
    }
 
    @Override
@@ -119,6 +148,10 @@ public class CreateQueueMessage_V2 extends CreateQueueMessage {
       routingType = RoutingType.getType(buffer.readByte());
       maxConsumers = buffer.readInt();
       purgeOnNoConsumers = buffer.readBoolean();
+      if (buffer.readableBytes() > 0) {
+         exclusive = BufferHelper.readNullableBoolean(buffer);
+         lastValue = BufferHelper.readNullableBoolean(buffer);
+      }
    }
 
    @Override
@@ -129,6 +162,8 @@ public class CreateQueueMessage_V2 extends CreateQueueMessage {
       result = prime * result + (routingType.getType());
       result = prime * result + (maxConsumers);
       result = prime * result + (purgeOnNoConsumers ? 1231 : 1237);
+      result = prime * result + (exclusive == null ? 0 : exclusive ? 1231 : 1237);
+      result = prime * result + (lastValue == null ? 0 : lastValue ? 1231 : 1237);
       return result;
    }
 
@@ -147,7 +182,9 @@ public class CreateQueueMessage_V2 extends CreateQueueMessage {
          return false;
       if (purgeOnNoConsumers != other.purgeOnNoConsumers)
          return false;
-      if (purgeOnNoConsumers != other.purgeOnNoConsumers)
+      if (exclusive != other.exclusive)
+         return false;
+      if (lastValue != other.lastValue)
          return false;
       if (routingType == null) {
          if (other.routingType != null)

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/wireformat/CreateSharedQueueMessage_V2.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/wireformat/CreateSharedQueueMessage_V2.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/wireformat/CreateSharedQueueMessage_V2.java
index beebd12..8763043 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/wireformat/CreateSharedQueueMessage_V2.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/wireformat/CreateSharedQueueMessage_V2.java
@@ -19,16 +19,25 @@ package org.apache.activemq.artemis.core.protocol.core.impl.wireformat;
 import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
 import org.apache.activemq.artemis.api.core.SimpleString;
 import org.apache.activemq.artemis.api.core.RoutingType;
+import org.apache.activemq.artemis.utils.BufferHelper;
 
 public class CreateSharedQueueMessage_V2 extends CreateSharedQueueMessage {
 
    private RoutingType routingType;
+   Integer maxConsumers;
+   Boolean purgeOnNoConsumers;
+   private Boolean exclusive;
+   private Boolean lastValue;
 
    public CreateSharedQueueMessage_V2(final SimpleString address,
                                       final SimpleString queueName,
                                       final RoutingType routingType,
                                       final SimpleString filterString,
                                       final boolean durable,
+                                      final Integer maxConsumers,
+                                      final Boolean purgeOnNoConsumers,
+                                      final Boolean exclusive,
+                                      final Boolean lastValue,
                                       final boolean requiresResponse) {
       this();
 
@@ -36,8 +45,13 @@ public class CreateSharedQueueMessage_V2 extends CreateSharedQueueMessage {
       this.queueName = queueName;
       this.filterString = filterString;
       this.durable = durable;
-      this.requiresResponse = requiresResponse;
       this.routingType = routingType;
+      this.maxConsumers = maxConsumers;
+      this.purgeOnNoConsumers = purgeOnNoConsumers;
+      this.exclusive = exclusive;
+      this.lastValue = lastValue;
+      this.requiresResponse = requiresResponse;
+
    }
 
    public CreateSharedQueueMessage_V2() {
@@ -52,6 +66,38 @@ public class CreateSharedQueueMessage_V2 extends CreateSharedQueueMessage {
       this.routingType = routingType;
    }
 
+   public Integer getMaxConsumers() {
+      return maxConsumers;
+   }
+
+   public void setMaxConsumers(Integer maxConsumers) {
+      this.maxConsumers = maxConsumers;
+   }
+
+   public Boolean isPurgeOnNoConsumers() {
+      return purgeOnNoConsumers;
+   }
+
+   public void setPurgeOnNoConsumers(Boolean purgeOnNoConsumers) {
+      this.purgeOnNoConsumers = purgeOnNoConsumers;
+   }
+
+   public Boolean isExclusive() {
+      return exclusive;
+   }
+
+   public void setExclusive(Boolean exclusive) {
+      this.exclusive = exclusive;
+   }
+
+   public Boolean isLastValue() {
+      return lastValue;
+   }
+
+   public void setLastValue(Boolean lastValue) {
+      this.lastValue = lastValue;
+   }
+
    @Override
    public String toString() {
       StringBuffer buff = new StringBuffer(getParentString());
@@ -59,6 +105,11 @@ public class CreateSharedQueueMessage_V2 extends CreateSharedQueueMessage {
       buff.append(", queueName=" + queueName);
       buff.append(", filterString=" + filterString);
       buff.append(", durable=" + durable);
+      buff.append(", routingType=" + routingType);
+      buff.append(", maxConsumers=" + maxConsumers);
+      buff.append(", purgeOnNoConsumers=" + purgeOnNoConsumers);
+      buff.append(", exclusive=" + exclusive);
+      buff.append(", lastValue=" + lastValue);
       buff.append(", requiresResponse=" + requiresResponse);
       buff.append("]");
       return buff.toString();
@@ -72,6 +123,10 @@ public class CreateSharedQueueMessage_V2 extends CreateSharedQueueMessage {
       buffer.writeBoolean(durable);
       buffer.writeByte(routingType.getType());
       buffer.writeBoolean(requiresResponse);
+      BufferHelper.writeNullableInteger(buffer, maxConsumers);
+      BufferHelper.writeNullableBoolean(buffer, purgeOnNoConsumers);
+      BufferHelper.writeNullableBoolean(buffer, exclusive);
+      BufferHelper.writeNullableBoolean(buffer, lastValue);
    }
 
    @Override
@@ -82,6 +137,12 @@ public class CreateSharedQueueMessage_V2 extends CreateSharedQueueMessage {
       durable = buffer.readBoolean();
       routingType = RoutingType.getType(buffer.readByte());
       requiresResponse = buffer.readBoolean();
+      if (buffer.readableBytes() > 0) {
+         maxConsumers = BufferHelper.readNullableInteger(buffer);
+         purgeOnNoConsumers = BufferHelper.readNullableBoolean(buffer);
+         exclusive = BufferHelper.readNullableBoolean(buffer);
+         lastValue = BufferHelper.readNullableBoolean(buffer);
+      }
    }
 
    @Override
@@ -94,6 +155,10 @@ public class CreateSharedQueueMessage_V2 extends CreateSharedQueueMessage {
       result = prime * result + (durable ? 1231 : 1237);
       result = prime * result + routingType.getType();
       result = prime * result + (requiresResponse ? 1231 : 1237);
+      result = prime * result + (maxConsumers == null ? 0 : maxConsumers.hashCode());
+      result = prime * result + (purgeOnNoConsumers == null ? 0 : purgeOnNoConsumers ? 1231 : 1237);
+      result = prime * result + (exclusive == null ? 0 : exclusive ? 1231 : 1237);
+      result = prime * result + (lastValue == null ? 0 : lastValue ? 1231 : 1237);
       return result;
    }
 
@@ -127,6 +192,14 @@ public class CreateSharedQueueMessage_V2 extends CreateSharedQueueMessage {
          return false;
       if (requiresResponse != other.requiresResponse)
          return false;
+      if (maxConsumers != other.maxConsumers)
+         return false;
+      if (purgeOnNoConsumers != other.purgeOnNoConsumers)
+         return false;
+      if (exclusive != other.exclusive)
+         return false;
+      if (lastValue != other.lastValue)
+         return false;
       return true;
    }
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/wireformat/SessionBindingQueryResponseMessage_V4.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/wireformat/SessionBindingQueryResponseMessage_V4.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/wireformat/SessionBindingQueryResponseMessage_V4.java
index dc0e958..0d08d99 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/wireformat/SessionBindingQueryResponseMessage_V4.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/wireformat/SessionBindingQueryResponseMessage_V4.java
@@ -20,6 +20,7 @@ import java.util.List;
 
 import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
 import org.apache.activemq.artemis.api.core.SimpleString;
+import org.apache.activemq.artemis.utils.BufferHelper;
 
 public class SessionBindingQueryResponseMessage_V4 extends SessionBindingQueryResponseMessage_V3 {
 
@@ -27,12 +28,18 @@ public class SessionBindingQueryResponseMessage_V4 extends SessionBindingQueryRe
 
    private int defaultMaxConsumers;
 
+   private Boolean defaultExclusive;
+
+   private Boolean defaultLastValue;
+
    public SessionBindingQueryResponseMessage_V4(final boolean exists,
                                                 final List<SimpleString> queueNames,
                                                 final boolean autoCreateQueues,
                                                 final boolean autoCreateAddresses,
                                                 final boolean defaultPurgeOnNoConsumers,
-                                                final int defaultMaxConsumers) {
+                                                final int defaultMaxConsumers,
+                                                final Boolean defaultExclusive,
+                                                final Boolean defaultLastValue) {
       super(SESS_BINDINGQUERY_RESP_V4);
 
       this.exists = exists;
@@ -46,6 +53,10 @@ public class SessionBindingQueryResponseMessage_V4 extends SessionBindingQueryRe
       this.defaultPurgeOnNoConsumers = defaultPurgeOnNoConsumers;
 
       this.defaultMaxConsumers = defaultMaxConsumers;
+
+      this.defaultExclusive = defaultExclusive;
+
+      this.defaultLastValue = defaultLastValue;
    }
 
    public SessionBindingQueryResponseMessage_V4() {
@@ -60,11 +71,21 @@ public class SessionBindingQueryResponseMessage_V4 extends SessionBindingQueryRe
       return defaultMaxConsumers;
    }
 
+   public Boolean isDefaultExclusive() {
+      return defaultExclusive;
+   }
+
+   public Boolean isDefaultLastValue() {
+      return defaultLastValue;
+   }
+
    @Override
    public void encodeRest(final ActiveMQBuffer buffer) {
       super.encodeRest(buffer);
       buffer.writeBoolean(defaultPurgeOnNoConsumers);
       buffer.writeInt(defaultMaxConsumers);
+      BufferHelper.writeNullableBoolean(buffer, defaultExclusive);
+      BufferHelper.writeNullableBoolean(buffer, defaultLastValue);
    }
 
    @Override
@@ -72,6 +93,10 @@ public class SessionBindingQueryResponseMessage_V4 extends SessionBindingQueryRe
       super.decodeRest(buffer);
       defaultPurgeOnNoConsumers = buffer.readBoolean();
       defaultMaxConsumers = buffer.readInt();
+      if (buffer.readableBytes() > 0) {
+         defaultExclusive = BufferHelper.readNullableBoolean(buffer);
+         defaultLastValue = BufferHelper.readNullableBoolean(buffer);
+      }
    }
 
    @Override
@@ -80,6 +105,8 @@ public class SessionBindingQueryResponseMessage_V4 extends SessionBindingQueryRe
       int result = super.hashCode();
       result = prime * result + (defaultPurgeOnNoConsumers ? 1231 : 1237);
       result = prime * result + defaultMaxConsumers;
+      result = prime * result + (defaultExclusive == null ? 0 : defaultExclusive ? 1231 : 1237);
+      result = prime * result + (defaultLastValue == null ? 0 : defaultLastValue ? 1231 : 1237);
       return result;
    }
 
@@ -95,6 +122,8 @@ public class SessionBindingQueryResponseMessage_V4 extends SessionBindingQueryRe
       StringBuffer buff = new StringBuffer(super.getParentString());
       buff.append(", defaultPurgeOnNoConsumers=" + defaultPurgeOnNoConsumers);
       buff.append(", defaultMaxConsumers=" + defaultMaxConsumers);
+      buff.append(", defaultExclusive=" + defaultExclusive);
+      buff.append(", defaultLastValue=" + defaultLastValue);
       return buff.toString();
    }
 
@@ -111,6 +140,10 @@ public class SessionBindingQueryResponseMessage_V4 extends SessionBindingQueryRe
          return false;
       if (defaultMaxConsumers != other.defaultMaxConsumers)
          return false;
+      if (defaultExclusive != other.defaultExclusive)
+         return false;
+      if (defaultLastValue != other.defaultLastValue)
+         return false;
       return true;
    }
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/wireformat/SessionQueueQueryResponseMessage_V3.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/wireformat/SessionQueueQueryResponseMessage_V3.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/wireformat/SessionQueueQueryResponseMessage_V3.java
index bde6593..12f2a7b 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/wireformat/SessionQueueQueryResponseMessage_V3.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/wireformat/SessionQueueQueryResponseMessage_V3.java
@@ -22,6 +22,7 @@ import org.apache.activemq.artemis.api.core.client.ClientSession;
 import org.apache.activemq.artemis.core.client.impl.QueueQueryImpl;
 import org.apache.activemq.artemis.core.server.QueueQueryResult;
 import org.apache.activemq.artemis.api.core.RoutingType;
+import org.apache.activemq.artemis.utils.BufferHelper;
 
 public class SessionQueueQueryResponseMessage_V3 extends SessionQueueQueryResponseMessage_V2 {
 
@@ -33,12 +34,16 @@ public class SessionQueueQueryResponseMessage_V3 extends SessionQueueQueryRespon
 
    protected int maxConsumers;
 
+   protected Boolean exclusive;
+
+   protected Boolean lastValue;
+
    public SessionQueueQueryResponseMessage_V3(final QueueQueryResult result) {
-      this(result.getName(), result.getAddress(), result.isDurable(), result.isTemporary(), result.getFilterString(), result.getConsumerCount(), result.getMessageCount(), result.isExists(), result.isAutoCreateQueues(), result.isAutoCreated(), result.isPurgeOnNoConsumers(), result.getRoutingType(), result.getMaxConsumers());
+      this(result.getName(), result.getAddress(), result.isDurable(), result.isTemporary(), result.getFilterString(), result.getConsumerCount(), result.getMessageCount(), result.isExists(), result.isAutoCreateQueues(), result.isAutoCreated(), result.isPurgeOnNoConsumers(), result.getRoutingType(), result.getMaxConsumers(), result.isExclusive(), result.isLastValue());
    }
 
    public SessionQueueQueryResponseMessage_V3() {
-      this(null, null, false, false, null, 0, 0, false, false, false, false, RoutingType.MULTICAST, -1);
+      this(null, null, false, false, null, 0, 0, false, false, false, false, RoutingType.MULTICAST, -1, null, null);
    }
 
    private SessionQueueQueryResponseMessage_V3(final SimpleString name,
@@ -53,7 +58,9 @@ public class SessionQueueQueryResponseMessage_V3 extends SessionQueueQueryRespon
                                                final boolean autoCreated,
                                                final boolean purgeOnNoConsumers,
                                                final RoutingType routingType,
-                                               final int maxConsumers) {
+                                               final int maxConsumers,
+                                               final Boolean exclusive,
+                                               final Boolean lastValue) {
       super(SESS_QUEUEQUERY_RESP_V3);
 
       this.durable = durable;
@@ -81,6 +88,10 @@ public class SessionQueueQueryResponseMessage_V3 extends SessionQueueQueryRespon
       this.routingType = routingType;
 
       this.maxConsumers = maxConsumers;
+
+      this.exclusive = exclusive;
+
+      this.lastValue = lastValue;
    }
 
    public boolean isAutoCreated() {
@@ -115,6 +126,22 @@ public class SessionQueueQueryResponseMessage_V3 extends SessionQueueQueryRespon
       this.maxConsumers = maxConsumers;
    }
 
+   public Boolean isExclusive() {
+      return exclusive;
+   }
+
+   public void setExclusive(Boolean exclusive) {
+      this.exclusive = exclusive;
+   }
+
+   public Boolean isLastValue() {
+      return lastValue;
+   }
+
+   public void setLastValue(Boolean lastValue) {
+      this.lastValue = lastValue;
+   }
+
    @Override
    public void encodeRest(final ActiveMQBuffer buffer) {
       super.encodeRest(buffer);
@@ -122,6 +149,8 @@ public class SessionQueueQueryResponseMessage_V3 extends SessionQueueQueryRespon
       buffer.writeBoolean(purgeOnNoConsumers);
       buffer.writeByte(routingType.getType());
       buffer.writeInt(maxConsumers);
+      BufferHelper.writeNullableBoolean(buffer, exclusive);
+      BufferHelper.writeNullableBoolean(buffer, lastValue);
    }
 
    @Override
@@ -131,6 +160,10 @@ public class SessionQueueQueryResponseMessage_V3 extends SessionQueueQueryRespon
       purgeOnNoConsumers = buffer.readBoolean();
       routingType = RoutingType.getType(buffer.readByte());
       maxConsumers = buffer.readInt();
+      if (buffer.readableBytes() > 0) {
+         exclusive = BufferHelper.readNullableBoolean(buffer);
+         lastValue = BufferHelper.readNullableBoolean(buffer);
+      }
    }
 
    @Override
@@ -141,6 +174,8 @@ public class SessionQueueQueryResponseMessage_V3 extends SessionQueueQueryRespon
       result = prime * result + (purgeOnNoConsumers ? 1231 : 1237);
       result = prime * result + routingType.hashCode();
       result = prime * result + maxConsumers;
+      result = prime * result + (exclusive == null ? 0 : exclusive ? 1231 : 1237);
+      result = prime * result + (lastValue == null ? 0 : lastValue ? 1231 : 1237);
       return result;
    }
 
@@ -158,12 +193,14 @@ public class SessionQueueQueryResponseMessage_V3 extends SessionQueueQueryRespon
       buff.append(", purgeOnNoConsumers=" + purgeOnNoConsumers);
       buff.append(", routingType=" + routingType);
       buff.append(", maxConsumers=" + maxConsumers);
+      buff.append(", exclusive=" + exclusive);
+      buff.append(", lastValue=" + lastValue);
       return buff.toString();
    }
 
    @Override
    public ClientSession.QueueQuery toQueueQuery() {
-      return new QueueQueryImpl(isDurable(), isTemporary(), getConsumerCount(), getMessageCount(), getFilterString(), getAddress(), getName(), isExists(), isAutoCreateQueues(), getMaxConsumers(), isAutoCreated(), isPurgeOnNoConsumers(), getRoutingType());
+      return new QueueQueryImpl(isDurable(), isTemporary(), getConsumerCount(), getMessageCount(), getFilterString(), getAddress(), getName(), isExists(), isAutoCreateQueues(), getMaxConsumers(), isAutoCreated(), isPurgeOnNoConsumers(), getRoutingType(), isExclusive(), isLastValue());
    }
 
    @Override
@@ -179,6 +216,10 @@ public class SessionQueueQueryResponseMessage_V3 extends SessionQueueQueryRespon
          return false;
       if (purgeOnNoConsumers != other.purgeOnNoConsumers)
          return false;
+      if (exclusive != other.exclusive)
+         return false;
+      if (lastValue != other.lastValue)
+         return false;
       if (routingType == null) {
          if (other.routingType != null)
             return false;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/server/QueueQueryResult.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/server/QueueQueryResult.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/server/QueueQueryResult.java
index cf88d62..6497e3f 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/server/QueueQueryResult.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/server/QueueQueryResult.java
@@ -47,6 +47,10 @@ public class QueueQueryResult {
 
    private int maxConsumers;
 
+   private Boolean exclusive;
+
+   private Boolean lastValue;
+
    public QueueQueryResult(final SimpleString name,
                            final SimpleString address,
                            final boolean durable,
@@ -59,7 +63,9 @@ public class QueueQueryResult {
                            final boolean autoCreated,
                            final boolean purgeOnNoConsumers,
                            final RoutingType routingType,
-                           final int maxConsumers) {
+                           final int maxConsumers,
+                           final Boolean exclusive,
+                           final Boolean lastValue) {
       this.durable = durable;
 
       this.temporary = temporary;
@@ -85,6 +91,10 @@ public class QueueQueryResult {
       this.routingType = routingType;
 
       this.maxConsumers = maxConsumers;
+
+      this.exclusive = exclusive;
+
+      this.lastValue = lastValue;
    }
 
    public boolean isExists() {
@@ -142,4 +152,12 @@ public class QueueQueryResult {
    public void setAddress(SimpleString address) {
       this.address = address;
    }
+
+   public Boolean isExclusive() {
+      return exclusive;
+   }
+
+   public Boolean isLastValue() {
+      return lastValue;
+   }
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/remoting/SessionContext.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/remoting/SessionContext.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/remoting/SessionContext.java
index 1c85f08..058e606 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/remoting/SessionContext.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/spi/core/remoting/SessionContext.java
@@ -171,12 +171,24 @@ public abstract class SessionContext {
     * @param routingType
     * @param filterString
     * @param durable
+    * @param exclusive
+    * @param lastValue
     * @throws ActiveMQException
     */
    public abstract void createSharedQueue(SimpleString address,
                                           SimpleString queueName,
                                           RoutingType routingType,
                                           SimpleString filterString,
+                                          boolean durable,
+                                          Integer maxConsumers,
+                                          Boolean purgeOnNoConsumers,
+                                          Boolean exclusive,
+                                          Boolean lastValue) throws ActiveMQException;
+
+   public abstract void createSharedQueue(SimpleString address,
+                                          SimpleString queueName,
+                                          RoutingType routingType,
+                                          SimpleString filterString,
                                           boolean durable) throws ActiveMQException;
 
    public abstract void createSharedQueue(SimpleString address,
@@ -199,6 +211,7 @@ public abstract class SessionContext {
                                     boolean temp,
                                     boolean autoCreated) throws ActiveMQException;
 
+   @Deprecated
    public abstract void createQueue(SimpleString address,
                                     RoutingType routingType,
                                     SimpleString queueName,
@@ -209,6 +222,18 @@ public abstract class SessionContext {
                                     boolean purgeOnNoConsumers,
                                     boolean autoCreated) throws ActiveMQException;
 
+   public abstract void createQueue(SimpleString address,
+                                    RoutingType routingType,
+                                    SimpleString queueName,
+                                    SimpleString filterString,
+                                    boolean durable,
+                                    boolean temp,
+                                    int maxConsumers,
+                                    boolean purgeOnNoConsumers,
+                                    boolean autoCreated,
+                                    Boolean exclusive,
+                                    Boolean lastVale) throws ActiveMQException;
+
    public abstract ClientSession.QueueQuery queueQuery(SimpleString queueName) throws ActiveMQException;
 
    public abstract void forceDelivery(ClientConsumer consumer, long sequence) throws ActiveMQException;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQDestination.java
----------------------------------------------------------------------
diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQDestination.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQDestination.java
index a5ab245..c5e4884 100644
--- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQDestination.java
+++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQDestination.java
@@ -24,8 +24,10 @@ import java.util.Properties;
 import java.util.UUID;
 
 import org.apache.activemq.artemis.api.core.Pair;
+import org.apache.activemq.artemis.api.core.QueueAttributes;
 import org.apache.activemq.artemis.api.core.SimpleString;
 import org.apache.activemq.artemis.jndi.JNDIStorable;
+import org.apache.activemq.artemis.api.core.ParameterisedAddress;
 
 /**
  * ActiveMQ Artemis implementation of a JMS Destination.
@@ -250,6 +252,11 @@ public class ActiveMQDestination extends JNDIStorable implements Destination, Se
    private SimpleString simpleAddress;
 
    /**
+    * Queue parameters;
+    */
+   private QueueAttributes queueAttributes;
+
+   /**
     * Needed for serialization backwards compatibility.
     */
    @Deprecated
@@ -280,7 +287,10 @@ public class ActiveMQDestination extends JNDIStorable implements Destination, Se
    protected ActiveMQDestination(final SimpleString address,
                                  final TYPE type,
                                  final ActiveMQSession session) {
-      this.simpleAddress = address;
+
+      if (address != null) {
+         setSimpleAddress(address);
+      }
 
       this.thetype = type;
 
@@ -319,8 +329,16 @@ public class ActiveMQDestination extends JNDIStorable implements Destination, Se
       if (address == null) {
          throw new IllegalArgumentException("address cannot be null");
       }
-      this.address = address.toString();
-      this.simpleAddress = address;
+      if (ParameterisedAddress.isParameterised(address)) {
+         ParameterisedAddress parameteredAddress = new ParameterisedAddress(address);
+         this.simpleAddress = parameteredAddress.getAddress();
+         this.address = parameteredAddress.getAddress().toString();
+         this.queueAttributes = parameteredAddress.getQueueAttributes();
+      } else {
+         this.simpleAddress = address;
+         this.address = address.toString();
+         this.queueAttributes = null;
+      }
    }
 
    public void delete() throws JMSException {
@@ -351,6 +369,10 @@ public class ActiveMQDestination extends JNDIStorable implements Destination, Se
       return simpleAddress;
    }
 
+   public QueueAttributes getQueueAttributes() {
+      return queueAttributes;
+   }
+
    public String getName() {
       return name != null ? name : getAddress();
    }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/dc41f3ca/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessageProducer.java
----------------------------------------------------------------------
diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessageProducer.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessageProducer.java
index 9f86e49..ae1d270 100644
--- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessageProducer.java
+++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessageProducer.java
@@ -37,6 +37,7 @@ import javax.jms.TopicPublisher;
 import org.apache.activemq.artemis.api.core.ActiveMQException;
 import org.apache.activemq.artemis.api.core.ActiveMQInterruptedException;
 import org.apache.activemq.artemis.api.core.ActiveMQQueueExistsException;
+import org.apache.activemq.artemis.api.core.QueueAttributes;
 import org.apache.activemq.artemis.api.core.SimpleString;
 import org.apache.activemq.artemis.api.core.client.ClientMessage;
 import org.apache.activemq.artemis.api.core.client.ClientProducer;
@@ -412,7 +413,7 @@ public class ActiveMQMessageProducer implements MessageProducer, QueueSender, To
                         // TODO is it right to use the address for the queue name here?
                         clientSession.createTemporaryQueue(address, RoutingType.ANYCAST, address);
                      } else {
-                        clientSession.createQueue(address, RoutingType.ANYCAST, address, null, true, true, query.getDefaultMaxConsumers(), query.isDefaultPurgeOnNoConsumers());
+                        createQueue(destination, RoutingType.ANYCAST, address, null, true, true, query.getDefaultMaxConsumers(), query.isDefaultPurgeOnNoConsumers(), query.isDefaultExclusive(), query.isDefaultLastValueQueue());
                      }
                   } else if (!destination.isQueue() && query.isAutoCreateAddresses()) {
                      clientSession.createAddress(address, RoutingType.MULTICAST, true);
@@ -427,7 +428,7 @@ public class ActiveMQMessageProducer implements MessageProducer, QueueSender, To
                      if (destination.isTemporary()) {
                         clientSession.createTemporaryQueue(address, RoutingType.ANYCAST, address);
                      } else {
-                        clientSession.createQueue(address, RoutingType.ANYCAST, address, null, true, true, query.getDefaultMaxConsumers(), query.isDefaultPurgeOnNoConsumers());
+                        createQueue(destination, RoutingType.ANYCAST, address, null, true, true, query.getDefaultMaxConsumers(), query.isDefaultPurgeOnNoConsumers(), query.isDefaultExclusive(), query.isDefaultLastValueQueue());
                      }
                   }
                }
@@ -535,6 +536,27 @@ public class ActiveMQMessageProducer implements MessageProducer, QueueSender, To
       }
    }
 
+   private void createQueue(ActiveMQDestination destination, RoutingType routingType, SimpleString queueName, SimpleString filter, boolean durable, boolean autoCreated, int maxConsumers, boolean purgeOnNoConsumers, Boolean exclusive, Boolean lastValue) throws ActiveMQException {
+      QueueAttributes queueAttributes = destination.getQueueAttributes();
+      if (queueAttributes == null) {
+         clientSession.createQueue(destination.getSimpleAddress(), routingType, queueName, filter, durable, autoCreated, maxConsumers, purgeOnNoConsumers, exclusive, lastValue);
+      } else {
+         clientSession.createQueue(
+            destination.getSimpleAddress(),
+            routingType,
+            queueName,
+            filter,
+            durable,
+            autoCreated,
+            queueAttributes.getMaxConsumers() == null ? maxConsumers : queueAttributes.getMaxConsumers(),
+            queueAttributes.getPurgeOnNoConsumers() == null ? purgeOnNoConsumers : queueAttributes.getPurgeOnNoConsumers(),
+            queueAttributes.getExclusive() == null ? exclusive : queueAttributes.getExclusive(),
+            queueAttributes.getLastValue() == null ? lastValue : queueAttributes.getLastValue()
+         );
+      }
+   }
+
+
    private static final class CompletionListenerWrapper implements SendAcknowledgementHandler {
 
       private final CompletionListener completionListener;