You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by cl...@apache.org on 2016/01/19 23:43:34 UTC

[4/5] activemq-artemis git commit: ARTEMIS-347 - supporting URIs on the cluster connection

ARTEMIS-347 - supporting URIs on the cluster connection


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

Branch: refs/heads/master
Commit: 3f23c9916e694abeed281cd03ba476e183ecf866
Parents: 17a443b
Author: Clebert Suconic <cl...@apache.org>
Authored: Thu Jan 14 18:07:12 2016 -0500
Committer: Clebert Suconic <cl...@apache.org>
Committed: Tue Jan 19 17:35:12 2016 -0500

----------------------------------------------------------------------
 .../activemq/artemis/utils/uri/URIFactory.java  |   9 +
 .../activemq/artemis/utils/uri/URISchema.java   |   7 +
 .../activemq/artemis/utils/uri/URISupport.java  | 560 +++++++++++++++++++
 .../activemq/artemis/utils/URIParserTest.java   |   6 +-
 .../config/ActiveMQDefaultConfiguration.java    |   8 +
 .../artemis/api/core/client/TopologyMember.java |   2 +
 .../core/client/impl/TopologyMemberImpl.java    |  13 +
 .../uri/AbstractServerLocatorSchema.java        |  30 -
 .../AbstractTransportConfigurationSchema.java   |  26 -
 .../activemq/artemis/uri/ConnectionOptions.java |  76 ---
 .../ConnectorTransportConfigurationParser.java  |   6 +-
 .../artemis/uri/InVMServerLocatorSchema.java    |  57 --
 .../uri/InVMTransportConfigurationSchema.java   |  69 ---
 .../artemis/uri/JGroupsServerLocatorSchema.java |  89 ---
 .../artemis/uri/ServerLocatorParser.java        |   4 +
 .../artemis/uri/TCPServerLocatorSchema.java     | 121 ----
 .../uri/TCPTransportConfigurationSchema.java    |  90 ---
 .../artemis/uri/UDPServerLocatorSchema.java     |  82 ---
 .../AbstractTransportConfigurationSchema.java   |  26 +
 .../InVMTransportConfigurationSchema.java       |  69 +++
 .../TCPTransportConfigurationSchema.java        |  89 +++
 .../AbstractServerLocatorSchema.java            |  30 +
 .../schema/serverLocator/ConnectionOptions.java |  76 +++
 .../serverLocator/InVMServerLocatorSchema.java  |  57 ++
 .../JGroupsServerLocatorSchema.java             |  89 +++
 .../serverLocator/TCPServerLocatorSchema.java   | 121 ++++
 .../serverLocator/UDPServerLocatorSchema.java   |  81 +++
 .../artemis/utils/ConfigurationHelper.java      |  31 +-
 .../apache/activemq/artemis/uri/InVMSchema.java |   2 +
 .../activemq/artemis/uri/JGroupsSchema.java     |   1 +
 .../artemis/uri/JMSConnectionOptions.java       |   1 +
 .../apache/activemq/artemis/uri/TCPSchema.java  |   2 +
 .../apache/activemq/artemis/uri/UDPSchema.java  |   1 +
 .../jms/server/embedded/EmbeddedJMS.java        |  16 +-
 .../config/ClusterConnectionConfiguration.java  | 129 ++++-
 .../artemis/core/config/Configuration.java      |   6 +
 .../core/config/impl/ConfigurationImpl.java     |  35 +-
 .../deployers/impl/FileConfigurationParser.java |  21 +-
 .../core/server/ActiveMQServerLogger.java       |   2 +-
 .../core/server/cluster/BackupManager.java      |  14 +-
 .../cluster/ClusterConfigurationUtil.java       |  87 ---
 .../core/server/cluster/ClusterManager.java     |  40 +-
 .../core/server/cluster/ha/ScaleDownPolicy.java |  26 +-
 .../cluster/impl/MessageLoadBalancingType.java  |  31 +
 .../core/server/embedded/EmbeddedActiveMQ.java  |  43 +-
 .../impl/SharedNothingLiveActivation.java       |  17 +-
 .../AcceptorTransportConfigurationParser.java   |   6 +-
 .../ClusterConnectionConfigurationParser.java   |  31 +
 ...nVMAcceptorTransportConfigurationSchema.java |  27 -
 ...TCPAcceptorTransportConfigurationSchema.java |  34 --
 ...nVMAcceptorTransportConfigurationSchema.java |  28 +
 ...TCPAcceptorTransportConfigurationSchema.java |  35 ++
 .../ClusterConnectionMulticastSchema.java       |  48 ++
 .../ClusterConnectionStaticSchema.java          |  61 ++
 .../resources/schema/artemis-configuration.xsd  |  60 +-
 .../impl/FileConfigurationParserTest.java       |  18 +
 .../uri/ClusterConnectionConfigurationTest.java |  65 +++
 .../clustered-static-discovery-uri/pom.xml      | 244 ++++++++
 .../clustered-static-discovery-uri/readme.html  |  58 ++
 .../example/StaticClusteredQueueExample.java    | 173 ++++++
 .../main/resources/activemq/server0/broker.xml  |  70 +++
 .../main/resources/activemq/server1/broker.xml  |  70 +++
 .../main/resources/activemq/server2/broker.xml  |  66 +++
 .../main/resources/activemq/server3/broker.xml  |  67 +++
 .../clustered/clustered-topic-uri/pom.xml       | 156 ++++++
 .../clustered/clustered-topic-uri/readme.html   |  46 ++
 .../jms/example/ClusteredTopicExample.java      | 129 +++++
 .../main/resources/activemq/server0/broker.xml  |  89 +++
 .../main/resources/activemq/server1/broker.xml  |  87 +++
 examples/features/clustered/pom.xml             |   4 +
 .../cluster/distribution/ClusterTestBase.java   |  18 +
 .../distribution/URISimpleClusterTest.java      | 130 +++++
 72 files changed, 3327 insertions(+), 891 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/URIFactory.java
----------------------------------------------------------------------
diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/URIFactory.java b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/URIFactory.java
index dae6faa..ca31e8f 100644
--- a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/URIFactory.java
+++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/URIFactory.java
@@ -59,6 +59,10 @@ public class URIFactory<T, P> {
       return schemaFactory.newObject(uri, param);
    }
 
+   public T newObject(String uri, P param) throws Exception {
+      return newObject(new URI(uri), param);
+   }
+
    public void populateObject(URI uri, T bean) throws Exception {
       URISchema<T, P> schemaFactory = schemas.get(uri.getScheme());
 
@@ -69,6 +73,11 @@ public class URIFactory<T, P> {
       schemaFactory.populateObject(uri, bean);
    }
 
+
+   public void populateObject(String uri, T bean) throws Exception {
+      populateObject(new URI(uri), bean);
+   }
+
    public URI createSchema(String scheme, T bean) throws Exception {
       URISchema<T, P> schemaFactory = schemas.get(scheme);
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/URISchema.java
----------------------------------------------------------------------
diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/URISchema.java b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/URISchema.java
index 9ee206b..0d6940e 100644
--- a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/URISchema.java
+++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/URISchema.java
@@ -27,6 +27,7 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.commons.beanutils.BeanUtilsBean;
+import org.apache.commons.beanutils.Converter;
 
 public abstract class URISchema<T, P> {
 
@@ -99,6 +100,12 @@ public abstract class URISchema<T, P> {
 
    private static final BeanUtilsBean beanUtils = new BeanUtilsBean();
 
+   public static void registerConverter(Converter converter, Class type) {
+      synchronized (beanUtils) {
+         beanUtils.getConvertUtils().register(converter, type);
+      }
+   }
+
    static {
       // This is to customize the BeanUtils to use Fluent Proeprties as well
       beanUtils.getPropertyUtils().addBeanIntrospector(new FluentPropertyBeanIntrospectorWithIgnores());

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/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
new file mode 100644
index 0000000..4b21b6c
--- /dev/null
+++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/URISupport.java
@@ -0,0 +1,560 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.utils.uri;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Utility class that provides methods for parsing URI's
+ *
+ * This class can be used to split composite URI's into their component parts and is used to extract any
+ * URI options from each URI in order to set specific properties on Beans.
+ *
+ * (copied from activemq 5)
+ */
+public class URISupport {
+
+   /**
+    * A composite URI can be split into one or more CompositeData object which each represent the
+    * individual URIs that comprise the composite one.
+    */
+   public static class CompositeData {
+
+      private String host;
+      private String scheme;
+      private String path;
+      private URI[] components;
+      private Map<String, String> parameters;
+      private String fragment;
+
+      public URI[] getComponents() {
+         return components;
+      }
+
+      public String getFragment() {
+         return fragment;
+      }
+
+      public Map<String, String> getParameters() {
+         return parameters;
+      }
+
+      public String getScheme() {
+         return scheme;
+      }
+
+      public String getPath() {
+         return path;
+      }
+
+      public String getHost() {
+         return host;
+      }
+
+      public URI toURI() throws URISyntaxException {
+         StringBuffer sb = new StringBuffer();
+         if (scheme != null) {
+            sb.append(scheme);
+            sb.append(':');
+         }
+
+         if (host != null && host.length() != 0) {
+            sb.append(host);
+         }
+         else {
+            sb.append('(');
+            for (int i = 0; i < components.length; i++) {
+               if (i != 0) {
+                  sb.append(',');
+               }
+               sb.append(components[i].toString());
+            }
+            sb.append(')');
+         }
+
+         if (path != null) {
+            sb.append('/');
+            sb.append(path);
+         }
+         if (!parameters.isEmpty()) {
+            sb.append("?");
+            sb.append(createQueryString(parameters));
+         }
+         if (fragment != null) {
+            sb.append("#");
+            sb.append(fragment);
+         }
+         return new URI(sb.toString());
+      }
+   }
+
+   /**
+    * Give a URI break off any URI options and store them in a Key / Value Mapping.
+    *
+    * @param uri The URI whose query should be extracted and processed.
+    * @return A Mapping of the URI options.
+    * @throws java.net.URISyntaxException
+    */
+   public static Map<String, String> parseQuery(String uri) throws URISyntaxException {
+      try {
+         uri = uri.substring(uri.lastIndexOf("?") + 1); // get only the relevant part of the query
+         Map<String, String> rc = new HashMap<String, String>();
+         if (uri != null && !uri.isEmpty()) {
+            parseParameters(rc, uri.split("&"));
+            parseParameters(rc, uri.split(";"));
+         }
+         return rc;
+      }
+      catch (UnsupportedEncodingException e) {
+         throw (URISyntaxException) new URISyntaxException(e.toString(), "Invalid encoding").initCause(e);
+      }
+   }
+
+   private static void parseParameters(Map<String, String> rc,
+                                       String[] parameters) throws UnsupportedEncodingException {
+      for (int i = 0; i < parameters.length; i++) {
+         int p = parameters[i].indexOf("=");
+         if (p >= 0) {
+            String name = URLDecoder.decode(parameters[i].substring(0, p), "UTF-8");
+            String value = URLDecoder.decode(parameters[i].substring(p + 1), "UTF-8");
+            rc.put(name, value);
+         }
+         else {
+            rc.put(parameters[i], null);
+         }
+      }
+   }
+
+   /**
+    * Given a URI parse and extract any URI query options and return them as a Key / Value mapping.
+    *
+    * This method differs from the {@link parseQuery} method in that it handles composite URI types and
+    * will extract the URI options from the outermost composite URI.
+    *
+    * @param uri The URI whose query should be extracted and processed.
+    * @return A Mapping of the URI options.
+    * @throws java.net.URISyntaxException
+    */
+   public static Map<String, String> parseParameters(URI uri) throws URISyntaxException {
+      if (!isCompositeURI(uri)) {
+         return uri.getQuery() == null ? emptyMap() : parseQuery(stripPrefix(uri.getQuery(), "?"));
+      }
+      else {
+         CompositeData data = URISupport.parseComposite(uri);
+         Map<String, String> parameters = new HashMap<String, String>();
+         parameters.putAll(data.getParameters());
+         if (parameters.isEmpty()) {
+            parameters = emptyMap();
+         }
+
+         return parameters;
+      }
+   }
+
+   /**
+    * Given a Key / Value mapping create and append a URI query value that represents the mapped entries, return the
+    * newly updated URI that contains the value of the given URI and the appended query value.
+    *
+    * @param uri             The source URI that will have the Map entries appended as a URI query value.
+    * @param queryParameters The Key / Value mapping that will be transformed into a URI query string.
+    * @return A new URI value that combines the given URI and the constructed query string.
+    * @throws java.net.URISyntaxException
+    */
+   public static URI applyParameters(URI uri, Map<String, String> queryParameters) throws URISyntaxException {
+      return applyParameters(uri, queryParameters, "");
+   }
+
+   /**
+    * Given a Key / Value mapping create and append a URI query value that represents the mapped entries, return the
+    * newly updated URI that contains the value of the given URI and the appended query value.  Each entry in the query
+    * string is prefixed by the supplied optionPrefix string.
+    *
+    * @param uri             The source URI that will have the Map entries appended as a URI query value.
+    * @param queryParameters The Key / Value mapping that will be transformed into a URI query string.
+    * @param optionPrefix    A string value that when not null or empty is used to prefix each query option key.
+    * @return A new URI value that combines the given URI and the constructed query string.
+    * @throws java.net.URISyntaxException
+    */
+   public static URI applyParameters(URI uri,
+                                     Map<String, String> queryParameters,
+                                     String optionPrefix) throws URISyntaxException {
+      if (queryParameters != null && !queryParameters.isEmpty()) {
+         StringBuffer newQuery = uri.getRawQuery() != null ? new StringBuffer(uri.getRawQuery()) : new StringBuffer();
+         for (Map.Entry<String, String> param : queryParameters.entrySet()) {
+            if (param.getKey().startsWith(optionPrefix)) {
+               if (newQuery.length() != 0) {
+                  newQuery.append('&');
+               }
+               final String key = param.getKey().substring(optionPrefix.length());
+               newQuery.append(key).append('=').append(param.getValue());
+            }
+         }
+         uri = createURIWithQuery(uri, newQuery.toString());
+      }
+      return uri;
+   }
+
+   @SuppressWarnings("unchecked")
+   private static Map<String, String> emptyMap() {
+      return Collections.EMPTY_MAP;
+   }
+
+   /**
+    * Removes any URI query from the given uri and return a new URI that does not contain the query portion.
+    *
+    * @param uri The URI whose query value is to be removed.
+    * @return a new URI that does not contain a query value.
+    * @throws java.net.URISyntaxException
+    */
+   public static URI removeQuery(URI uri) throws URISyntaxException {
+      return createURIWithQuery(uri, null);
+   }
+
+   /**
+    * Creates a URI with the given query, removing an previous query value from the given URI.
+    *
+    * @param uri   The source URI whose existing query is replaced with the newly supplied one.
+    * @param query The new URI query string that should be appended to the given URI.
+    * @return a new URI that is a combination of the original URI and the given query string.
+    * @throws java.net.URISyntaxException
+    */
+   public static URI createURIWithQuery(URI uri, String query) throws URISyntaxException {
+      String schemeSpecificPart = uri.getRawSchemeSpecificPart();
+      // strip existing query if any
+      int questionMark = schemeSpecificPart.lastIndexOf("?");
+      // make sure question mark is not within parentheses
+      if (questionMark < schemeSpecificPart.lastIndexOf(")")) {
+         questionMark = -1;
+      }
+      if (questionMark > 0) {
+         schemeSpecificPart = schemeSpecificPart.substring(0, questionMark);
+      }
+      if (query != null && query.length() > 0) {
+         schemeSpecificPart += "?" + query;
+      }
+      return new URI(uri.getScheme(), schemeSpecificPart, uri.getFragment());
+   }
+
+   /**
+    * Given a composite URI, parse the individual URI elements contained within that URI and return
+    * a CompsoteData instance that contains the parsed URI values.
+    *
+    * @param uri The target URI that should be parsed.
+    * @return a new CompsiteData instance representing the parsed composite URI.
+    * @throws java.net.URISyntaxException
+    */
+   public static CompositeData parseComposite(URI uri) throws URISyntaxException {
+
+      CompositeData rc = new CompositeData();
+      rc.scheme = uri.getScheme();
+      String ssp = stripPrefix(uri.getRawSchemeSpecificPart().trim(), "//").trim();
+
+      parseComposite(uri, rc, ssp);
+
+      rc.fragment = uri.getFragment();
+      return rc;
+   }
+
+   /**
+    * Examine a URI and determine if it is a Composite type or not.
+    *
+    * @param uri The URI that is to be examined.
+    * @return true if the given URI is a Compsote type.
+    */
+   public static boolean isCompositeURI(URI uri) {
+      String ssp = stripPrefix(uri.getRawSchemeSpecificPart().trim(), "//").trim();
+
+      if (ssp.indexOf('(') == 0 && checkParenthesis(ssp)) {
+         return true;
+      }
+      return false;
+   }
+
+   /**
+    * Given a string and a position in that string of an open parend, find the matching close parend.
+    *
+    * @param str   The string to be searched for a matching parend.
+    * @param first The index in the string of the opening parend whose close value is to be searched.
+    * @return the index in the string where the closing parend is located.
+    * @throws java.net.URISyntaxException fi the string does not contain a matching parend.
+    */
+   public static int indexOfParenthesisMatch(String str, int first) throws URISyntaxException {
+      int index = -1;
+
+      if (first < 0 || first > str.length()) {
+         throw new IllegalArgumentException("Invalid position for first parenthesis: " + first);
+      }
+
+      if (str.charAt(first) != '(') {
+         throw new IllegalArgumentException("character at indicated position is not a parenthesis");
+      }
+
+      int depth = 1;
+      char[] array = str.toCharArray();
+      for (index = first + 1; index < array.length; ++index) {
+         char current = array[index];
+         if (current == '(') {
+            depth++;
+         }
+         else if (current == ')') {
+            if (--depth == 0) {
+               break;
+            }
+         }
+      }
+
+      if (depth != 0) {
+         throw new URISyntaxException(str, "URI did not contain a matching parenthesis.");
+      }
+
+      return index;
+   }
+
+   /**
+    * Given a composite URI and a CompositeData instance and the scheme specific part extracted from the source URI,
+    * parse the composite URI and populate the CompositeData object with the results.  The source URI is used only
+    * for logging as the ssp should have already been extracted from it and passed here.
+    *
+    * @param uri The original source URI whose ssp is parsed into the composite data.
+    * @param rc  The CompsositeData instance that will be populated from the given ssp.
+    * @param ssp The scheme specific part from the original string that is a composite or one or more URIs.
+    * @throws java.net.URISyntaxException
+    */
+   private static void parseComposite(URI uri, CompositeData rc, String ssp) throws URISyntaxException {
+      String componentString;
+      String params;
+
+      if (!checkParenthesis(ssp)) {
+         throw new URISyntaxException(uri.toString(), "Not a matching number of '(' and ')' parenthesis");
+      }
+
+      int p;
+      int initialParen = ssp.indexOf("(");
+      if (initialParen == 0) {
+
+         rc.host = ssp.substring(0, initialParen);
+         p = rc.host.indexOf("/");
+
+         if (p >= 0) {
+            rc.path = rc.host.substring(p);
+            rc.host = rc.host.substring(0, p);
+         }
+
+         p = indexOfParenthesisMatch(ssp, initialParen);
+         componentString = ssp.substring(initialParen + 1, p);
+         params = ssp.substring(p + 1).trim();
+
+      }
+      else {
+         componentString = ssp;
+         params = "";
+      }
+
+      String[] components = splitComponents(componentString);
+      rc.components = new URI[components.length];
+      for (int i = 0; i < components.length; i++) {
+         rc.components[i] = new URI(components[i].trim());
+      }
+
+      p = params.indexOf("?");
+      if (p >= 0) {
+         if (p > 0) {
+            rc.path = stripPrefix(params.substring(0, p), "/");
+         }
+         rc.parameters = parseQuery(params.substring(p + 1));
+      }
+      else {
+         if (params.length() > 0) {
+            rc.path = stripPrefix(params, "/");
+         }
+         rc.parameters = emptyMap();
+      }
+   }
+
+   /**
+    * Given the inner portion of a composite URI, split and return each inner URI as a string
+    * element in a new String array.
+    *
+    * @param str The inner URI elements of a composite URI string.
+    * @return an array containing each inner URI from the composite one.
+    */
+   private static String[] splitComponents(String str) {
+      List<String> l = new ArrayList<String>();
+
+      int last = 0;
+      int depth = 0;
+      char[] chars = str.toCharArray();
+      for (int i = 0; i < chars.length; i++) {
+         switch (chars[i]) {
+            case '(':
+               depth++;
+               break;
+            case ')':
+               depth--;
+               break;
+            case ',':
+               if (depth == 0) {
+                  String s = str.substring(last, i);
+                  l.add(s);
+                  last = i + 1;
+               }
+               break;
+            default:
+         }
+      }
+
+      String s = str.substring(last);
+      if (s.length() != 0) {
+         l.add(s);
+      }
+
+      String[] rc = new String[l.size()];
+      l.toArray(rc);
+      return rc;
+   }
+
+   /**
+    * String the given prefix from the target string and return the result.
+    *
+    * @param value  The string that should be trimmed of the given prefix if present.
+    * @param prefix The prefix to remove from the target string.
+    * @return either the original string or a new string minus the supplied prefix if present.
+    */
+   public static String stripPrefix(String value, String prefix) {
+      if (value.startsWith(prefix)) {
+         return value.substring(prefix.length());
+      }
+      return value;
+   }
+
+   /**
+    * Strip a URI of its scheme element.
+    *
+    * @param uri The URI whose scheme value should be stripped.
+    * @return The stripped URI value.
+    * @throws java.net.URISyntaxException
+    */
+   public static URI stripScheme(URI uri) throws URISyntaxException {
+      return new URI(stripPrefix(uri.getSchemeSpecificPart().trim(), "//"));
+   }
+
+   /**
+    * Given a key / value mapping, create and return a URI formatted query string that is valid and
+    * can be appended to a URI.
+    *
+    * @param options The Mapping that will create the new Query string.
+    * @return a URI formatted query string.
+    * @throws java.net.URISyntaxException
+    */
+   public static String createQueryString(Map<String, ? extends Object> options) throws URISyntaxException {
+      try {
+         if (options.size() > 0) {
+            StringBuffer rc = new StringBuffer();
+            boolean first = true;
+            for (String key : options.keySet()) {
+               if (first) {
+                  first = false;
+               }
+               else {
+                  rc.append("&");
+               }
+               String value = (String) options.get(key);
+               rc.append(URLEncoder.encode(key, "UTF-8"));
+               rc.append("=");
+               rc.append(URLEncoder.encode(value, "UTF-8"));
+            }
+            return rc.toString();
+         }
+         else {
+            return "";
+         }
+      }
+      catch (UnsupportedEncodingException e) {
+         throw (URISyntaxException) new URISyntaxException(e.toString(), "Invalid encoding").initCause(e);
+      }
+   }
+
+   /**
+    * Creates a URI from the original URI and the remaining parameters.
+    *
+    * When the query options of a URI are applied to certain objects the used portion of the query options needs
+    * to be removed and replaced with those that remain so that other parts of the code can attempt to apply the
+    * remainder or give an error is unknown values were given.  This method is used to update a URI with those
+    * remainder values.
+    *
+    * @param originalURI The URI whose current parameters are remove and replaced with the given remainder value.
+    * @param params      The URI params that should be used to replace the current ones in the target.
+    * @return a new URI that matches the original one but has its query options replaced with the given ones.
+    * @throws java.net.URISyntaxException
+    */
+   public static URI createRemainingURI(URI originalURI, Map<String, String> params) throws URISyntaxException {
+      String s = createQueryString(params);
+      if (s.length() == 0) {
+         s = null;
+      }
+      return createURIWithQuery(originalURI, s);
+   }
+
+   /**
+    * Given a URI value create and return a new URI that matches the target one but with the scheme value
+    * supplied to this method.
+    *
+    * @param bindAddr The URI whose scheme value should be altered.
+    * @param scheme   The new scheme value to use for the returned URI.
+    * @return a new URI that is a copy of the original except that its scheme matches the supplied one.
+    * @throws java.net.URISyntaxException
+    */
+   public static URI changeScheme(URI bindAddr, String scheme) throws URISyntaxException {
+      return new URI(scheme, bindAddr.getUserInfo(), bindAddr.getHost(), bindAddr.getPort(), bindAddr.getPath(), bindAddr.getQuery(), bindAddr.getFragment());
+   }
+
+   /**
+    * Examine the supplied string and ensure that all parends appear as matching pairs.
+    *
+    * @param str The target string to examine.
+    * @return true if the target string has valid parend pairings.
+    */
+   public static boolean checkParenthesis(String str) {
+      boolean result = true;
+      if (str != null) {
+         int open = 0;
+         int closed = 0;
+
+         int i = 0;
+         while ((i = str.indexOf('(', i)) >= 0) {
+            i++;
+            open++;
+         }
+         i = 0;
+         while ((i = str.indexOf(')', i)) >= 0) {
+            i++;
+            closed++;
+         }
+         result = open == closed;
+      }
+      return result;
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-commons/src/test/java/org/apache/activemq/artemis/utils/URIParserTest.java
----------------------------------------------------------------------
diff --git a/artemis-commons/src/test/java/org/apache/activemq/artemis/utils/URIParserTest.java b/artemis-commons/src/test/java/org/apache/activemq/artemis/utils/URIParserTest.java
index 5e4849d..f2fd107 100644
--- a/artemis-commons/src/test/java/org/apache/activemq/artemis/utils/URIParserTest.java
+++ b/artemis-commons/src/test/java/org/apache/activemq/artemis/utils/URIParserTest.java
@@ -17,14 +17,14 @@
 
 package org.apache.activemq.artemis.utils;
 
+import java.net.URI;
+import java.util.Map;
+
 import org.apache.activemq.artemis.utils.uri.URIFactory;
 import org.apache.activemq.artemis.utils.uri.URISchema;
 import org.junit.Assert;
 import org.junit.Test;
 
-import java.net.URI;
-import java.util.Map;
-
 public class URIParserTest {
 
    /**

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/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 462e597..b4fc493 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
@@ -160,6 +160,9 @@ public final class ActiveMQDefaultConfiguration {
    // the name of the address that consumers bind to receive management notifications
    private static SimpleString DEFAULT_MANAGEMENT_NOTIFICATION_ADDRESS = new SimpleString("activemq.notifications");
 
+   // The default address used for clustering
+   private static String DEFAULT_CLUSTER_ADDRESS = "jms";
+
    // Cluster username. It applies to all cluster configurations.
    private static String DEFAULT_CLUSTER_USER = "ACTIVEMQ.CLUSTER.ADMIN.USER";
 
@@ -499,6 +502,11 @@ public final class ActiveMQDefaultConfiguration {
       return DEFAULT_MANAGEMENT_NOTIFICATION_ADDRESS;
    }
 
+   /** The default Cluster address for the Cluster connection*/
+   public static String getDefaultClusterAddress() {
+      return DEFAULT_CLUSTER_ADDRESS;
+   }
+
    /**
     * Cluster username. It applies to all cluster configurations.
     */

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/TopologyMember.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/TopologyMember.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/TopologyMember.java
index 26de0dc..4247b43 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/TopologyMember.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/TopologyMember.java
@@ -92,4 +92,6 @@ public interface TopologyMember {
     */
    boolean isMember(TransportConfiguration configuration);
 
+
+   String toURI();
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/TopologyMemberImpl.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/TopologyMemberImpl.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/TopologyMemberImpl.java
index 50bb50b..c646059 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/TopologyMemberImpl.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/client/impl/TopologyMemberImpl.java
@@ -19,7 +19,11 @@ package org.apache.activemq.artemis.core.client.impl;
 import org.apache.activemq.artemis.api.core.Pair;
 import org.apache.activemq.artemis.api.core.TransportConfiguration;
 import org.apache.activemq.artemis.api.core.client.TopologyMember;
+import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
 import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
+import org.apache.activemq.artemis.utils.ConfigurationHelper;
+
+import java.util.Map;
 
 public final class TopologyMemberImpl implements TopologyMember {
 
@@ -118,6 +122,15 @@ public final class TopologyMemberImpl implements TopologyMember {
    }
 
    @Override
+   public String toURI() {
+      TransportConfiguration liveConnector = getLive();
+      Map<String, Object> props = liveConnector.getParams();
+      String host = ConfigurationHelper.getStringProperty(TransportConstants.HOST_PROP_NAME, "localhost", props);
+      int port = ConfigurationHelper.getIntProperty(TransportConstants.PORT_PROP_NAME, 0, props);
+      return "tcp://" + host + ":" + port;
+   }
+
+   @Override
    public String toString() {
       return "TopologyMember[id = " + nodeId + ", connector=" + connector + ", backupGroupName=" + backupGroupName + ", scaleDownGroupName=" + scaleDownGroupName + "]";
    }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/AbstractServerLocatorSchema.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/AbstractServerLocatorSchema.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/AbstractServerLocatorSchema.java
deleted file mode 100644
index 3fe97bb..0000000
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/AbstractServerLocatorSchema.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.uri;
-
-import org.apache.activemq.artemis.api.core.client.ServerLocator;
-import org.apache.activemq.artemis.utils.uri.URISchema;
-
-import java.net.URI;
-import java.util.Map;
-
-public abstract class AbstractServerLocatorSchema extends URISchema<ServerLocator, String> {
-
-   protected ConnectionOptions newConnectionOptions(URI uri, Map<String, String> query) throws Exception {
-      return setData(uri, new ConnectionOptions(), query);
-   }
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/AbstractTransportConfigurationSchema.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/AbstractTransportConfigurationSchema.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/AbstractTransportConfigurationSchema.java
deleted file mode 100644
index b76fa7f..0000000
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/AbstractTransportConfigurationSchema.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.uri;
-
-import org.apache.activemq.artemis.api.core.TransportConfiguration;
-import org.apache.activemq.artemis.utils.uri.URISchema;
-
-import java.util.List;
-
-public abstract class AbstractTransportConfigurationSchema extends URISchema<List<TransportConfiguration>, String> {
-
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/ConnectionOptions.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/ConnectionOptions.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/ConnectionOptions.java
deleted file mode 100644
index f08bfd7..0000000
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/ConnectionOptions.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.activemq.artemis.uri;
-
-/**
- * This will represent all the possible options you could setup on URLs
- * When parsing the URL this will serve as an intermediate object
- * And it could also be a pl
- */
-public class ConnectionOptions {
-
-   private boolean ha;
-
-   private String host;
-
-   private int port;
-
-   public ConnectionOptions setHost(String host) {
-      this.host = host;
-      return this;
-   }
-
-   public String getHost() {
-      return host;
-   }
-
-   public ConnectionOptions setPort(int port) {
-      this.port = port;
-      return this;
-   }
-
-   public int getPort() {
-      return port;
-   }
-
-   public boolean isHa() {
-      return ha;
-   }
-
-   public void setHa(boolean ha) {
-      this.ha = ha;
-   }
-
-   /**
-    * Se need both options (ha / HA in case of typos on the URI)
-    */
-   public boolean isHA() {
-      return ha;
-   }
-
-   public void setHA(boolean ha) {
-      this.ha = ha;
-   }
-
-   @Override
-   public String toString() {
-      return "ConnectionOptions{" +
-         "ha=" + ha +
-         '}';
-   }
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/ConnectorTransportConfigurationParser.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/ConnectorTransportConfigurationParser.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/ConnectorTransportConfigurationParser.java
index 650a3b8..627575d 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/ConnectorTransportConfigurationParser.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/ConnectorTransportConfigurationParser.java
@@ -16,12 +16,14 @@
  */
 package org.apache.activemq.artemis.uri;
 
+import java.util.List;
+
 import org.apache.activemq.artemis.api.core.TransportConfiguration;
 import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
+import org.apache.activemq.artemis.uri.schema.connector.InVMTransportConfigurationSchema;
+import org.apache.activemq.artemis.uri.schema.connector.TCPTransportConfigurationSchema;
 import org.apache.activemq.artemis.utils.uri.URIFactory;
 
-import java.util.List;
-
 public class ConnectorTransportConfigurationParser extends URIFactory<List<TransportConfiguration>, String> {
 
    public ConnectorTransportConfigurationParser() {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/InVMServerLocatorSchema.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/InVMServerLocatorSchema.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/InVMServerLocatorSchema.java
deleted file mode 100644
index 5bbad37..0000000
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/InVMServerLocatorSchema.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.uri;
-
-import org.apache.activemq.artemis.api.core.TransportConfiguration;
-import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
-import org.apache.activemq.artemis.api.core.client.ServerLocator;
-import org.apache.activemq.artemis.utils.uri.SchemaConstants;
-import org.apache.activemq.artemis.utils.uri.URISchema;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Map;
-
-public class InVMServerLocatorSchema extends AbstractServerLocatorSchema {
-
-   @Override
-   public String getSchemaName() {
-      return SchemaConstants.VM;
-   }
-
-   @Override
-   protected ServerLocator internalNewObject(URI uri, Map<String, String> query, String name) throws Exception {
-      TransportConfiguration tc = InVMTransportConfigurationSchema.createTransportConfiguration(uri, query, name, "org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnectorFactory");
-      ServerLocator factory = ActiveMQClient.createServerLocatorWithoutHA(tc);
-      return URISchema.setData(uri, factory, query);
-   }
-
-   @Override
-   protected URI internalNewURI(ServerLocator bean) throws Exception {
-      return getUri(bean.getStaticTransportConfigurations());
-   }
-
-   public static URI getUri(TransportConfiguration[] configurations) throws URISyntaxException {
-      String host = "0";
-      if (configurations != null && configurations.length > 0) {
-         TransportConfiguration configuration = configurations[0];
-         Map<String, Object> params = configuration.getParams();
-         host = params.get("serverId") == null ? host : params.get("serverId").toString();
-      }
-      return new URI(SchemaConstants.VM, null, host, -1, null, null, null);
-   }
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/InVMTransportConfigurationSchema.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/InVMTransportConfigurationSchema.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/InVMTransportConfigurationSchema.java
deleted file mode 100644
index b473ba4..0000000
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/InVMTransportConfigurationSchema.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.uri;
-
-import org.apache.activemq.artemis.api.core.TransportConfiguration;
-import org.apache.activemq.artemis.utils.uri.SchemaConstants;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class InVMTransportConfigurationSchema extends AbstractTransportConfigurationSchema {
-
-   /* This is the same as org.apache.activemq.artemis.core.remoting.impl.invm.TransportConstants.CONNECTIONS_ALLOWED,
-    * but this Maven module can't see that class.
-    */
-   public static final String CONNECTIONS_ALLOWED = "connectionsAllowed";
-
-   @Override
-   public String getSchemaName() {
-      return SchemaConstants.VM;
-   }
-
-   @Override
-   protected List<TransportConfiguration> internalNewObject(URI uri,
-                                                            Map<String, String> query,
-                                                            String name) throws Exception {
-      List<TransportConfiguration> configurations = new ArrayList<>();
-      configurations.add(createTransportConfiguration(uri, query, name, getFactoryName()));
-      return configurations;
-   }
-
-   @Override
-   protected URI internalNewURI(List<TransportConfiguration> bean) throws Exception {
-      return null;
-   }
-
-   protected String getFactoryName() {
-      return "org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnectorFactory";
-   }
-
-   public static TransportConfiguration createTransportConfiguration(URI uri,
-                                                                     Map<String, String> query,
-                                                                     String name,
-                                                                     String factoryName) {
-      Map<String, Object> inVmTransportConfig = new HashMap<>();
-      inVmTransportConfig.put("serverId", uri.getHost());
-      if (query.containsKey(CONNECTIONS_ALLOWED)) {
-         inVmTransportConfig.put(CONNECTIONS_ALLOWED, query.get(CONNECTIONS_ALLOWED));
-      }
-      return new TransportConfiguration(factoryName, inVmTransportConfig, name);
-   }
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/JGroupsServerLocatorSchema.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/JGroupsServerLocatorSchema.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/JGroupsServerLocatorSchema.java
deleted file mode 100644
index 1749d9d..0000000
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/JGroupsServerLocatorSchema.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.uri;
-
-import org.apache.activemq.artemis.api.core.BroadcastEndpointFactory;
-import org.apache.activemq.artemis.api.core.DiscoveryGroupConfiguration;
-import org.apache.activemq.artemis.api.core.JGroupsFileBroadcastEndpointFactory;
-import org.apache.activemq.artemis.api.core.JGroupsPropertiesBroadcastEndpointFactory;
-import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
-import org.apache.activemq.artemis.api.core.client.ServerLocator;
-import org.apache.activemq.artemis.utils.uri.SchemaConstants;
-
-import java.io.NotSerializableException;
-import java.net.URI;
-import java.util.Map;
-
-public class JGroupsServerLocatorSchema extends AbstractServerLocatorSchema {
-
-   @Override
-   public String getSchemaName() {
-      return SchemaConstants.JGROUPS;
-   }
-
-   @Override
-   protected ServerLocator internalNewObject(URI uri, Map<String, String> query, String name) throws Exception {
-      ConnectionOptions options = newConnectionOptions(uri, query);
-
-      DiscoveryGroupConfiguration dcConfig = getDiscoveryGroupConfiguration(uri, query, name);
-
-      if (options.isHa()) {
-         return ActiveMQClient.createServerLocatorWithHA(dcConfig);
-      }
-      else {
-         return ActiveMQClient.createServerLocatorWithoutHA(dcConfig);
-      }
-   }
-
-   @Override
-   protected URI internalNewURI(ServerLocator bean) throws Exception {
-      DiscoveryGroupConfiguration dgc = bean.getDiscoveryGroupConfiguration();
-      BroadcastEndpointFactory endpoint = dgc.getBroadcastEndpointFactory();
-      String auth;
-      if (endpoint instanceof JGroupsFileBroadcastEndpointFactory) {
-         auth = ((JGroupsFileBroadcastEndpointFactory) endpoint).getChannelName();
-      }
-      else if (endpoint instanceof JGroupsPropertiesBroadcastEndpointFactory) {
-         auth = ((JGroupsPropertiesBroadcastEndpointFactory) endpoint).getChannelName();
-      }
-      else {
-         throw new NotSerializableException(endpoint + "not serializable");
-      }
-      String query = getData(null, bean, dgc, endpoint);
-      dgc.setBroadcastEndpointFactory(endpoint);
-      return new URI(SchemaConstants.JGROUPS, null, auth, -1, null, query, null);
-   }
-
-   public static DiscoveryGroupConfiguration getDiscoveryGroupConfiguration(URI uri,
-                                                                            Map<String, String> query,
-                                                                            String name) throws Exception {
-      BroadcastEndpointFactory endpointFactory;
-      if (query.containsKey("file")) {
-         endpointFactory = new JGroupsFileBroadcastEndpointFactory().setChannelName(uri.getAuthority());
-      }
-      else {
-         endpointFactory = new JGroupsPropertiesBroadcastEndpointFactory().setChannelName(uri.getAuthority());
-      }
-
-      setData(uri, endpointFactory, query);
-
-      DiscoveryGroupConfiguration dcConfig = new DiscoveryGroupConfiguration().setName(name).setBroadcastEndpointFactory(endpointFactory);
-
-      setData(uri, dcConfig, query);
-      return dcConfig;
-   }
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/ServerLocatorParser.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/ServerLocatorParser.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/ServerLocatorParser.java
index 2bf11a4..3d47fdd 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/ServerLocatorParser.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/ServerLocatorParser.java
@@ -17,6 +17,10 @@
 package org.apache.activemq.artemis.uri;
 
 import org.apache.activemq.artemis.api.core.client.ServerLocator;
+import org.apache.activemq.artemis.uri.schema.serverLocator.InVMServerLocatorSchema;
+import org.apache.activemq.artemis.uri.schema.serverLocator.JGroupsServerLocatorSchema;
+import org.apache.activemq.artemis.uri.schema.serverLocator.TCPServerLocatorSchema;
+import org.apache.activemq.artemis.uri.schema.serverLocator.UDPServerLocatorSchema;
 import org.apache.activemq.artemis.utils.uri.URIFactory;
 
 public class ServerLocatorParser extends URIFactory<ServerLocator, String> {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/TCPServerLocatorSchema.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/TCPServerLocatorSchema.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/TCPServerLocatorSchema.java
deleted file mode 100644
index a7c7652..0000000
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/TCPServerLocatorSchema.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.uri;
-
-import java.net.URI;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.activemq.artemis.api.core.TransportConfiguration;
-import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
-import org.apache.activemq.artemis.api.core.client.ServerLocator;
-import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory;
-import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
-import org.apache.activemq.artemis.utils.IPV6Util;
-import org.apache.activemq.artemis.utils.uri.SchemaConstants;
-import org.apache.activemq.artemis.utils.uri.URISchema;
-
-public class TCPServerLocatorSchema extends AbstractServerLocatorSchema {
-   @Override
-   public String getSchemaName() {
-      return SchemaConstants.TCP;
-   }
-
-   @Override
-   protected ServerLocator internalNewObject(URI uri, Map<String, String> query, String name) throws Exception {
-      ConnectionOptions options = newConnectionOptions(uri, query);
-
-      List<TransportConfiguration> configurations = TCPTransportConfigurationSchema.getTransportConfigurations(uri, query, TransportConstants.ALLOWABLE_CONNECTOR_KEYS, name, NettyConnectorFactory.class.getName());
-      TransportConfiguration[] tcs = new TransportConfiguration[configurations.size()];
-      configurations.toArray(tcs);
-      if (options.isHa()) {
-         return ActiveMQClient.createServerLocatorWithHA(tcs);
-      }
-      else {
-         return ActiveMQClient.createServerLocatorWithoutHA(tcs);
-      }
-   }
-
-   @Override
-   protected URI internalNewURI(ServerLocator bean) throws Exception {
-      String query = URISchema.getData(null, bean);
-      TransportConfiguration[] staticConnectors = bean.getStaticTransportConfigurations();
-      return getURI(query, staticConnectors);
-   }
-
-   public static URI getURI(String query, TransportConfiguration[] staticConnectors) throws Exception {
-      if (staticConnectors == null || staticConnectors.length < 1) {
-         throw new Exception();
-      }
-      StringBuilder fragment = new StringBuilder();
-      for (int i = 1; i < staticConnectors.length; i++) {
-         TransportConfiguration connector = staticConnectors[i];
-         Map<String, Object> params = escapeIPv6Host(connector.getParams());
-         URI extraUri = new URI(SchemaConstants.TCP, null, getHost(params), getPort(params), null, createQuery(params, null), null);
-         if (i > 1) {
-            fragment.append(",");
-         }
-         fragment.append(extraUri.toASCIIString());
-
-      }
-      Map<String, Object> params = escapeIPv6Host(staticConnectors[0].getParams());
-      return new URI(SchemaConstants.TCP, null, getHost(params), getPort(params), null, createQuery(params, query), fragment.toString());
-   }
-
-   @SuppressWarnings("StringEquality")
-   private static Map<String, Object> escapeIPv6Host(Map<String, Object> params) {
-      String host = (String) params.get("host");
-      String newHost = IPV6Util.encloseHost(host);
-
-      // We really want to check the objects here
-      // Some bug finders may report this as an error, hence the SuppressWarnings on this method
-      if (host != newHost) {
-         params.put("host", "[" + host + "]");
-      }
-
-      return params;
-   }
-
-   private static int getPort(Map<String, Object> params) {
-      Object port = params.get("port");
-      if (port instanceof String) {
-         return Integer.valueOf((String) port);
-      }
-      return port != null ? (int) port : 61616;
-   }
-
-   private static String getHost(Map<String, Object> params) {
-      return params.get("host") != null ? (String) params.get("host") : "localhost";
-   }
-
-   private static String createQuery(Map<String, Object> params, String query) {
-      StringBuilder cb;
-      if (query == null) {
-         cb = new StringBuilder();
-      }
-      else {
-         cb = new StringBuilder(query);
-      }
-      for (String param : params.keySet()) {
-         if (cb.length() > 0) {
-            cb.append("&");
-         }
-         cb.append(param).append("=").append(params.get(param));
-      }
-      return cb.toString();
-   }
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/TCPTransportConfigurationSchema.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/TCPTransportConfigurationSchema.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/TCPTransportConfigurationSchema.java
deleted file mode 100644
index 10fda78..0000000
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/TCPTransportConfigurationSchema.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.uri;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.activemq.artemis.api.core.TransportConfiguration;
-import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory;
-import org.apache.activemq.artemis.utils.uri.SchemaConstants;
-import org.apache.activemq.artemis.utils.uri.URISchema;
-
-public class TCPTransportConfigurationSchema extends AbstractTransportConfigurationSchema {
-
-   private final Set<String> allowableProperties;
-
-   public TCPTransportConfigurationSchema(Set<String> allowableProperties) {
-      this.allowableProperties = allowableProperties;
-   }
-
-   @Override
-   public String getSchemaName() {
-      return SchemaConstants.TCP;
-   }
-
-   @Override
-   protected List<TransportConfiguration> internalNewObject(URI uri,
-                                                            Map<String, String> query,
-                                                            String name) throws Exception {
-      return getTransportConfigurations(uri, query, allowableProperties, name, getFactoryName(uri));
-   }
-
-   @Override
-   protected URI internalNewURI(List<TransportConfiguration> bean) throws Exception {
-      return null;
-   }
-
-   public static List<TransportConfiguration> getTransportConfigurations(URI uri,
-                                                                         Map<String, String> query,
-                                                                         Set<String> allowableProperties,
-                                                                         String name,
-                                                                         String factoryName) throws URISyntaxException {
-      HashMap<String, Object> props = new HashMap<>();
-
-      URISchema.setData(uri, props, allowableProperties, query);
-      List<TransportConfiguration> transportConfigurations = new ArrayList<>();
-
-      transportConfigurations.add(new TransportConfiguration(factoryName, props, name));
-      String connectors = uri.getFragment();
-
-      if (connectors != null && !connectors.trim().isEmpty()) {
-         String[] split = connectors.split(",");
-         for (String s : split) {
-            URI extraUri = new URI(s);
-            HashMap<String, Object> newProps = new HashMap<>();
-            URISchema.setData(extraUri, newProps, allowableProperties, query);
-            URISchema.setData(extraUri, newProps, allowableProperties, URISchema.parseQuery(extraUri.getQuery(), null));
-            transportConfigurations.add(new TransportConfiguration(factoryName, newProps, name + ":" + extraUri.toString()));
-         }
-      }
-      return transportConfigurations;
-   }
-
-   protected String getFactoryName(URI uri) {
-      //here for backwards compatibility
-      if (uri.getPath() != null && uri.getPath().contains("hornetq")) {
-         return "org.hornetq.core.remoting.impl.netty.NettyConnectorFactory";
-      }
-      return NettyConnectorFactory.class.getName();
-   }
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/UDPServerLocatorSchema.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/UDPServerLocatorSchema.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/UDPServerLocatorSchema.java
deleted file mode 100644
index b3a85fc..0000000
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/UDPServerLocatorSchema.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.artemis.uri;
-
-import org.apache.activemq.artemis.api.core.DiscoveryGroupConfiguration;
-import org.apache.activemq.artemis.api.core.UDPBroadcastEndpointFactory;
-import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
-import org.apache.activemq.artemis.api.core.client.ServerLocator;
-import org.apache.activemq.artemis.utils.uri.SchemaConstants;
-import org.apache.activemq.artemis.utils.uri.URISchema;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-public class UDPServerLocatorSchema extends AbstractServerLocatorSchema {
-
-   protected static List<String> IGNORED = new ArrayList<>();
-
-   static {
-      IGNORED.add("localBindAddress");
-      IGNORED.add("localBindPort");
-   }
-
-   @Override
-   public String getSchemaName() {
-      return SchemaConstants.UDP;
-   }
-
-   @Override
-   protected ServerLocator internalNewObject(URI uri, Map<String, String> query, String name) throws Exception {
-      ConnectionOptions options = newConnectionOptions(uri, query);
-
-      DiscoveryGroupConfiguration dgc = getDiscoveryGroupConfiguration(uri, query, getHost(uri), getPort(uri), name);
-
-      if (options.isHa()) {
-         return ActiveMQClient.createServerLocatorWithHA(dgc);
-      }
-      else {
-         return ActiveMQClient.createServerLocatorWithoutHA(dgc);
-      }
-   }
-
-   @Override
-   protected URI internalNewURI(ServerLocator bean) throws Exception {
-      DiscoveryGroupConfiguration dgc = bean.getDiscoveryGroupConfiguration();
-      UDPBroadcastEndpointFactory endpoint = (UDPBroadcastEndpointFactory) dgc.getBroadcastEndpointFactory();
-      dgc.setBroadcastEndpointFactory(endpoint);
-      String query = URISchema.getData(IGNORED, bean, dgc, endpoint);
-      return new URI(SchemaConstants.UDP, null, endpoint.getGroupAddress(), endpoint.getGroupPort(), null, query, null);
-   }
-
-   public static DiscoveryGroupConfiguration getDiscoveryGroupConfiguration(URI uri,
-                                                                            Map<String, String> query,
-                                                                            String host,
-                                                                            int port,
-                                                                            String name) throws Exception {
-      UDPBroadcastEndpointFactory endpointFactoryConfiguration = new UDPBroadcastEndpointFactory().setGroupAddress(host).setGroupPort(port);
-
-      URISchema.setData(uri, endpointFactoryConfiguration, query);
-
-      DiscoveryGroupConfiguration dgc = URISchema.setData(uri, new DiscoveryGroupConfiguration(), query).setName(name).setBroadcastEndpointFactory(endpointFactoryConfiguration);
-
-      URISchema.setData(uri, dgc, query);
-      return dgc;
-   }
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/connector/AbstractTransportConfigurationSchema.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/connector/AbstractTransportConfigurationSchema.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/connector/AbstractTransportConfigurationSchema.java
new file mode 100644
index 0000000..a8fb1de
--- /dev/null
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/connector/AbstractTransportConfigurationSchema.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.uri.schema.connector;
+
+import java.util.List;
+
+import org.apache.activemq.artemis.api.core.TransportConfiguration;
+import org.apache.activemq.artemis.utils.uri.URISchema;
+
+public abstract class AbstractTransportConfigurationSchema extends URISchema<List<TransportConfiguration>, String> {
+
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/connector/InVMTransportConfigurationSchema.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/connector/InVMTransportConfigurationSchema.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/connector/InVMTransportConfigurationSchema.java
new file mode 100644
index 0000000..8e8b966
--- /dev/null
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/connector/InVMTransportConfigurationSchema.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.uri.schema.connector;
+
+import org.apache.activemq.artemis.api.core.TransportConfiguration;
+import org.apache.activemq.artemis.utils.uri.SchemaConstants;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class InVMTransportConfigurationSchema extends AbstractTransportConfigurationSchema {
+
+   /* This is the same as org.apache.activemq.artemis.core.remoting.impl.invm.TransportConstants.CONNECTIONS_ALLOWED,
+    * but this Maven module can't see that class.
+    */
+   public static final String CONNECTIONS_ALLOWED = "connectionsAllowed";
+
+   @Override
+   public String getSchemaName() {
+      return SchemaConstants.VM;
+   }
+
+   @Override
+   protected List<TransportConfiguration> internalNewObject(URI uri,
+                                                            Map<String, String> query,
+                                                            String name) throws Exception {
+      List<TransportConfiguration> configurations = new ArrayList<>();
+      configurations.add(createTransportConfiguration(uri, query, name, getFactoryName()));
+      return configurations;
+   }
+
+   @Override
+   protected URI internalNewURI(List<TransportConfiguration> bean) throws Exception {
+      return null;
+   }
+
+   protected String getFactoryName() {
+      return "org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnectorFactory";
+   }
+
+   public static TransportConfiguration createTransportConfiguration(URI uri,
+                                                                     Map<String, String> query,
+                                                                     String name,
+                                                                     String factoryName) {
+      Map<String, Object> inVmTransportConfig = new HashMap<>();
+      inVmTransportConfig.put("serverId", uri.getHost());
+      if (query.containsKey(CONNECTIONS_ALLOWED)) {
+         inVmTransportConfig.put(CONNECTIONS_ALLOWED, query.get(CONNECTIONS_ALLOWED));
+      }
+      return new TransportConfiguration(factoryName, inVmTransportConfig, name);
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/connector/TCPTransportConfigurationSchema.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/connector/TCPTransportConfigurationSchema.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/connector/TCPTransportConfigurationSchema.java
new file mode 100644
index 0000000..309e3e4
--- /dev/null
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/connector/TCPTransportConfigurationSchema.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.uri.schema.connector;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.activemq.artemis.api.core.TransportConfiguration;
+import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory;
+import org.apache.activemq.artemis.utils.uri.SchemaConstants;
+
+public class TCPTransportConfigurationSchema extends AbstractTransportConfigurationSchema {
+
+   private final Set<String> allowableProperties;
+
+   public TCPTransportConfigurationSchema(Set<String> allowableProperties) {
+      this.allowableProperties = allowableProperties;
+   }
+
+   @Override
+   public String getSchemaName() {
+      return SchemaConstants.TCP;
+   }
+
+   @Override
+   protected List<TransportConfiguration> internalNewObject(URI uri,
+                                                            Map<String, String> query,
+                                                            String name) throws Exception {
+      return getTransportConfigurations(uri, query, allowableProperties, name, getFactoryName(uri));
+   }
+
+   @Override
+   protected URI internalNewURI(List<TransportConfiguration> bean) throws Exception {
+      return null;
+   }
+
+   public static List<TransportConfiguration> getTransportConfigurations(URI uri,
+                                                                         Map<String, String> query,
+                                                                         Set<String> allowableProperties,
+                                                                         String name,
+                                                                         String factoryName) throws URISyntaxException {
+      HashMap<String, Object> props = new HashMap<>();
+
+      setData(uri, props, allowableProperties, query);
+      List<TransportConfiguration> transportConfigurations = new ArrayList<>();
+
+      transportConfigurations.add(new TransportConfiguration(factoryName, props, name));
+      String connectors = uri.getFragment();
+
+      if (connectors != null && !connectors.trim().isEmpty()) {
+         String[] split = connectors.split(",");
+         for (String s : split) {
+            URI extraUri = new URI(s);
+            HashMap<String, Object> newProps = new HashMap<>();
+            setData(extraUri, newProps, allowableProperties, query);
+            setData(extraUri, newProps, allowableProperties, parseQuery(extraUri.getQuery(), null));
+            transportConfigurations.add(new TransportConfiguration(factoryName, newProps, name + ":" + extraUri.toString()));
+         }
+      }
+      return transportConfigurations;
+   }
+
+   protected String getFactoryName(URI uri) {
+      //here for backwards compatibility
+      if (uri.getPath() != null && uri.getPath().contains("hornetq")) {
+         return "org.hornetq.core.remoting.impl.netty.NettyConnectorFactory";
+      }
+      return NettyConnectorFactory.class.getName();
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/serverLocator/AbstractServerLocatorSchema.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/serverLocator/AbstractServerLocatorSchema.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/serverLocator/AbstractServerLocatorSchema.java
new file mode 100644
index 0000000..e1a5f2b
--- /dev/null
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/serverLocator/AbstractServerLocatorSchema.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.uri.schema.serverLocator;
+
+import org.apache.activemq.artemis.api.core.client.ServerLocator;
+import org.apache.activemq.artemis.utils.uri.URISchema;
+
+import java.net.URI;
+import java.util.Map;
+
+public abstract class AbstractServerLocatorSchema extends URISchema<ServerLocator, String> {
+
+   protected ConnectionOptions newConnectionOptions(URI uri, Map<String, String> query) throws Exception {
+      return setData(uri, new ConnectionOptions(), query);
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/serverLocator/ConnectionOptions.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/serverLocator/ConnectionOptions.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/serverLocator/ConnectionOptions.java
new file mode 100644
index 0000000..8931dd6
--- /dev/null
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/serverLocator/ConnectionOptions.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.uri.schema.serverLocator;
+
+/**
+ * This will represent all the possible options you could setup on URLs
+ * When parsing the URL this will serve as an intermediate object
+ * And it could also be a pl
+ */
+public class ConnectionOptions {
+
+   private boolean ha;
+
+   private String host;
+
+   private int port;
+
+   public ConnectionOptions setHost(String host) {
+      this.host = host;
+      return this;
+   }
+
+   public String getHost() {
+      return host;
+   }
+
+   public ConnectionOptions setPort(int port) {
+      this.port = port;
+      return this;
+   }
+
+   public int getPort() {
+      return port;
+   }
+
+   public boolean isHa() {
+      return ha;
+   }
+
+   public void setHa(boolean ha) {
+      this.ha = ha;
+   }
+
+   /**
+    * Se need both options (ha / HA in case of typos on the URI)
+    */
+   public boolean isHA() {
+      return ha;
+   }
+
+   public void setHA(boolean ha) {
+      this.ha = ha;
+   }
+
+   @Override
+   public String toString() {
+      return "ConnectionOptions{" +
+         "ha=" + ha +
+         '}';
+   }
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/3f23c991/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/serverLocator/InVMServerLocatorSchema.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/serverLocator/InVMServerLocatorSchema.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/serverLocator/InVMServerLocatorSchema.java
new file mode 100644
index 0000000..ace312a
--- /dev/null
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/uri/schema/serverLocator/InVMServerLocatorSchema.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.uri.schema.serverLocator;
+
+import org.apache.activemq.artemis.api.core.TransportConfiguration;
+import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
+import org.apache.activemq.artemis.api.core.client.ServerLocator;
+import org.apache.activemq.artemis.uri.schema.connector.InVMTransportConfigurationSchema;
+import org.apache.activemq.artemis.utils.uri.SchemaConstants;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Map;
+
+public class InVMServerLocatorSchema extends AbstractServerLocatorSchema {
+
+   @Override
+   public String getSchemaName() {
+      return SchemaConstants.VM;
+   }
+
+   @Override
+   protected ServerLocator internalNewObject(URI uri, Map<String, String> query, String name) throws Exception {
+      TransportConfiguration tc = InVMTransportConfigurationSchema.createTransportConfiguration(uri, query, name, "org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnectorFactory");
+      ServerLocator factory = ActiveMQClient.createServerLocatorWithoutHA(tc);
+      return setData(uri, factory, query);
+   }
+
+   @Override
+   protected URI internalNewURI(ServerLocator bean) throws Exception {
+      return getUri(bean.getStaticTransportConfigurations());
+   }
+
+   public static URI getUri(TransportConfiguration[] configurations) throws URISyntaxException {
+      String host = "0";
+      if (configurations != null && configurations.length > 0) {
+         TransportConfiguration configuration = configurations[0];
+         Map<String, Object> params = configuration.getParams();
+         host = params.get("serverId") == null ? host : params.get("serverId").toString();
+      }
+      return new URI(SchemaConstants.VM, null, host, -1, null, null, null);
+   }
+}