You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ro...@apache.org on 2015/06/11 18:47:54 UTC

[3/3] qpid-jms git commit: QPIDJMS-72: make the discovery. and discovered. prefix usage more consistent with the failover URI options, support the actual failover options as a fallback, and add some basic docs for the discovery bits

QPIDJMS-72: make the discovery. and discovered. prefix usage more consistent with the failover URI options, support the actual failover options as a fallback, and add some basic docs for the discovery bits


Project: http://git-wip-us.apache.org/repos/asf/qpid-jms/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-jms/commit/79e76862
Tree: http://git-wip-us.apache.org/repos/asf/qpid-jms/tree/79e76862
Diff: http://git-wip-us.apache.org/repos/asf/qpid-jms/diff/79e76862

Branch: refs/heads/master
Commit: 79e76862b017d0097590b048b5b0be247a55c729
Parents: fb3ffd9
Author: Robert Gemmell <ro...@apache.org>
Authored: Thu Jun 11 17:44:33 2015 +0100
Committer: Robert Gemmell <ro...@apache.org>
Committed: Thu Jun 11 17:46:58 2015 +0100

----------------------------------------------------------------------
 .../qpid/jms/provider/ProviderWrapper.java      |   2 +-
 .../failover/FailoverProviderFactory.java       |  14 +-
 .../discovery/DiscoveryProviderFactory.java     |  31 ++--
 .../discovery/DiscoveryProviderFactoryTest.java | 141 +++++++++++++++++++
 qpid-jms-docs/Configuration.md                  |  29 ++++
 5 files changed, 206 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/79e76862/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/ProviderWrapper.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/ProviderWrapper.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/ProviderWrapper.java
index 44b4789..734a2cd 100644
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/ProviderWrapper.java
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/ProviderWrapper.java
@@ -187,7 +187,7 @@ public class ProviderWrapper<E extends Provider> implements Provider, ProviderLi
     }
 
     /**
-     * @return the wrapped AsyncProvider.
+     * @return the wrapped Provider.
      */
     public Provider getNext() {
         return next;

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/79e76862/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/failover/FailoverProviderFactory.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/failover/FailoverProviderFactory.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/failover/FailoverProviderFactory.java
index 8799c34..4f48625 100644
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/failover/FailoverProviderFactory.java
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/failover/FailoverProviderFactory.java
@@ -30,13 +30,23 @@ import org.apache.qpid.jms.util.URISupport.CompositeData;
  */
 public class FailoverProviderFactory extends ProviderFactory {
 
+    /**
+     * Prefix used for all properties that apply specifically to the FailoverProvider
+     */
+    public static final String FAILOVER_OPTION_PREFIX = "failover.";
+
+    /**
+     * Prefix addion used for all nested properties that should be applied to any remote URIs.
+     */
+    public static final String FAILOVER_NESTED_OPTION_PREFIX_ADDON = "nested.";
+
     @Override
     public Provider createProvider(URI remoteURI) throws Exception {
         CompositeData composite = URISupport.parseComposite(remoteURI);
         Map<String, String> options = composite.getParameters();
 
-        Map<String, String> filtered = PropertyUtil.filterProperties(options, "failover.");
-        Map<String, String> nested = PropertyUtil.filterProperties(filtered, "nested.");
+        Map<String, String> filtered = PropertyUtil.filterProperties(options, FAILOVER_OPTION_PREFIX);
+        Map<String, String> nested = PropertyUtil.filterProperties(filtered, FAILOVER_NESTED_OPTION_PREFIX_ADDON);
 
         FailoverProvider provider = new FailoverProvider(composite.getComponents(), nested);
         Map<String, String> unused = PropertyUtil.setProperties(provider, filtered);

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/79e76862/qpid-jms-discovery/src/main/java/org/apache/qpid/jms/provider/discovery/DiscoveryProviderFactory.java
----------------------------------------------------------------------
diff --git a/qpid-jms-discovery/src/main/java/org/apache/qpid/jms/provider/discovery/DiscoveryProviderFactory.java b/qpid-jms-discovery/src/main/java/org/apache/qpid/jms/provider/discovery/DiscoveryProviderFactory.java
index a989f49..e70ef02 100644
--- a/qpid-jms-discovery/src/main/java/org/apache/qpid/jms/provider/discovery/DiscoveryProviderFactory.java
+++ b/qpid-jms-discovery/src/main/java/org/apache/qpid/jms/provider/discovery/DiscoveryProviderFactory.java
@@ -18,12 +18,14 @@ package org.apache.qpid.jms.provider.discovery;
 
 import java.net.URI;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.qpid.jms.provider.Provider;
 import org.apache.qpid.jms.provider.ProviderFactory;
 import org.apache.qpid.jms.provider.failover.FailoverProvider;
+import org.apache.qpid.jms.provider.failover.FailoverProviderFactory;
 import org.apache.qpid.jms.util.PropertyUtil;
 import org.apache.qpid.jms.util.URISupport;
 import org.apache.qpid.jms.util.URISupport.CompositeData;
@@ -39,9 +41,9 @@ public class DiscoveryProviderFactory extends ProviderFactory {
     public static final String DISCOVERY_OPTION_PREFIX = "discovery.";
 
     /**
-     * Prefix used for all properties that should be applied to any discovered remote URIs.
+     * Prefix addon used for all properties that should be applied to any discovered remote URIs.
      */
-    public static final String DISCOVERED_OPTION_PREFIX = "discovered.";
+    public static final String DISCOVERY_DISCOVERED_OPTION_PREFIX_ADON = "discovered.";
 
     @Override
     public Provider createProvider(URI remoteURI) throws Exception {
@@ -49,21 +51,34 @@ public class DiscoveryProviderFactory extends ProviderFactory {
         CompositeData composite = URISupport.parseComposite(remoteURI);
         Map<String, String> options = composite.getParameters();
 
+        // Gather failover and discovery options.
+        Map<String, String> failoverOptions = PropertyUtil.filterProperties(options, FailoverProviderFactory.FAILOVER_OPTION_PREFIX);
+        Map<String, String> failoverNestedOptions = PropertyUtil.filterProperties(failoverOptions, FailoverProviderFactory.FAILOVER_NESTED_OPTION_PREFIX_ADDON);
+
         Map<String, String> discoveryOptions = PropertyUtil.filterProperties(options, DISCOVERY_OPTION_PREFIX);
-        Map<String, String> discoveredOptions = PropertyUtil.filterProperties(options, DISCOVERED_OPTION_PREFIX);
+        Map<String, String> discoveredOptions = PropertyUtil.filterProperties(discoveryOptions, DISCOVERY_DISCOVERED_OPTION_PREFIX_ADON);
+
+        // Combine the provider options, and the nested/discovered options.
+        Map<String, String> mainOptions = new HashMap<String, String>();
+        mainOptions.putAll(failoverOptions);
+        mainOptions.putAll(discoveryOptions);
+
+        Map<String, String> nestedOptions = new HashMap<String, String>();
+        nestedOptions.putAll(failoverNestedOptions);
+        nestedOptions.putAll(discoveredOptions);
 
         // Failover will apply the nested options to each URI while attempting to connect.
-        FailoverProvider failover = new FailoverProvider(discoveredOptions);
-        discoveryOptions = PropertyUtil.setProperties(failover, discoveryOptions);
+        FailoverProvider failover = new FailoverProvider(nestedOptions);
+        Map<String, String> leftOverDiscoveryOptions = PropertyUtil.setProperties(failover, mainOptions);
 
         DiscoveryProvider discovery = new DiscoveryProvider(remoteURI, failover);
-        discoveryOptions = PropertyUtil.setProperties(discovery, discoveryOptions);
+        Map<String, String> unusedOptions = PropertyUtil.setProperties(discovery, leftOverDiscoveryOptions);
 
-        if (!discoveryOptions.isEmpty()) {
+        if (!unusedOptions.isEmpty()) {
             String msg = ""
                 + " Not all options could be set on the Discovery provider."
                 + " Check the options are spelled correctly."
-                + " Unused parameters=[" + discoveryOptions + "]."
+                + " Unused parameters=[" + unusedOptions + "]."
                 + " This Provider cannot be started.";
             throw new IllegalArgumentException(msg);
         }

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/79e76862/qpid-jms-discovery/src/test/java/org/apache/qpid/jms/provider/discovery/DiscoveryProviderFactoryTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-discovery/src/test/java/org/apache/qpid/jms/provider/discovery/DiscoveryProviderFactoryTest.java b/qpid-jms-discovery/src/test/java/org/apache/qpid/jms/provider/discovery/DiscoveryProviderFactoryTest.java
new file mode 100644
index 0000000..fd92e47
--- /dev/null
+++ b/qpid-jms-discovery/src/test/java/org/apache/qpid/jms/provider/discovery/DiscoveryProviderFactoryTest.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.qpid.jms.provider.discovery;
+
+import static org.junit.Assert.*;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.qpid.jms.provider.Provider;
+import org.apache.qpid.jms.provider.failover.FailoverProvider;
+import org.apache.qpid.jms.provider.failover.FailoverProviderFactory;
+import org.junit.Test;
+
+public class DiscoveryProviderFactoryTest {
+
+    @Test
+    public void testCreateDiscoveryProvider() throws Exception {
+        URI discoveryUri = new URI("discovery:(multicast://default)");
+        Provider provider = DiscoveryProviderFactory.create(discoveryUri);
+
+        assertNotNull("Provider was not created", provider);
+        assertEquals("Provider was not of expected type", DiscoveryProvider.class, provider.getClass());
+
+        DiscoveryProvider discovery = (DiscoveryProvider) provider;
+
+        assertNotNull("Next provider was not present", discovery.getNext());
+        assertEquals("Next Provider was not of expected type", FailoverProvider.class, discovery.getNext().getClass());
+
+        FailoverProvider failoverProvider = (FailoverProvider) discovery.getNext();
+        assertTrue("Expected no nested options", failoverProvider.getNestedOptions().isEmpty());
+    }
+
+    @Test
+    public void testCreateDiscoveryProviderWithFailoverSyntaxMainOption() throws Exception {
+        String optionPrefix = FailoverProviderFactory.FAILOVER_OPTION_PREFIX;
+        assertEquals("Unexpected option prefix", "failover.", optionPrefix);
+        doCreateDiscoveryProviderWithMainOptionTestImpl(optionPrefix);
+    }
+
+    @Test
+    public void testCreateDiscoveryProviderWithDiscoverSyntaxMainOption() throws Exception {
+        String optionPrefix = DiscoveryProviderFactory.DISCOVERY_OPTION_PREFIX;
+        assertEquals("Unexpected option prefix", "discovery.", optionPrefix);
+        doCreateDiscoveryProviderWithMainOptionTestImpl(optionPrefix);
+    }
+
+    private void doCreateDiscoveryProviderWithMainOptionTestImpl(String optionPrefix) throws URISyntaxException, Exception {
+        String optionKey = "reconnectBackOffMultiplier";
+        double option = 3.14159;
+        String optionValue = String.valueOf(option);
+
+        assertFalse(String.valueOf(FailoverProvider.DEFAULT_RECONNECT_BACKOFF_MULTIPLIER).equals(optionValue));
+
+        URI discoveryUri = new URI("discovery:(multicast://default)?" + optionPrefix  + optionKey + "=" + optionValue);
+        Provider provider = DiscoveryProviderFactory.create(discoveryUri);
+
+        assertNotNull("Provider was not created", provider);
+        assertEquals("Provider was not of expected type", DiscoveryProvider.class, provider.getClass());
+
+        DiscoveryProvider discovery = (DiscoveryProvider) provider;
+
+        assertNotNull("Next provider was not present", discovery.getNext());
+        assertEquals("Next Provider was not of expected type", FailoverProvider.class, discovery.getNext().getClass());
+
+        FailoverProvider failoverProvider = (FailoverProvider) discovery.getNext();
+
+        assertEquals("option not as expected", option, failoverProvider.getReconnectBackOffMultiplier(), 0.0);
+    }
+
+    @Test
+    public void testCreateDiscoveryProviderWithFailoverSyntaxNestedOptions() throws Exception {
+        String optionPrefix = FailoverProviderFactory.FAILOVER_OPTION_PREFIX + FailoverProviderFactory.FAILOVER_NESTED_OPTION_PREFIX_ADDON;
+        assertEquals("Unexpected option prefix", "failover.nested.", optionPrefix);
+        doCreateDiscoveryProviderWithNestedOptionsTestImpl(optionPrefix);
+    }
+
+    @Test
+    public void testCreateDiscoveryProviderWithDiscoveredSyntaxNestedOption() throws Exception {
+        String optionPrefix = DiscoveryProviderFactory.DISCOVERY_OPTION_PREFIX + DiscoveryProviderFactory.DISCOVERY_DISCOVERED_OPTION_PREFIX_ADON;
+        assertEquals("Unexpected option prefix", "discovery.discovered.", optionPrefix);
+        doCreateDiscoveryProviderWithNestedOptionsTestImpl(optionPrefix);
+    }
+
+    private void doCreateDiscoveryProviderWithNestedOptionsTestImpl(String optionPrefix) throws URISyntaxException, Exception {
+        String clientIdOptionKey = "jms.clientID";
+        String clientIdValue = "myTestClientID";
+        URI discoveryUri = new URI("discovery:(multicast://default)?" + optionPrefix  + clientIdOptionKey + "=" + clientIdValue);
+        Provider provider = DiscoveryProviderFactory.create(discoveryUri);
+
+        assertNotNull("Provider was not created", provider);
+        assertEquals("Provider was not of expected type", DiscoveryProvider.class, provider.getClass());
+
+        DiscoveryProvider discovery = (DiscoveryProvider) provider;
+
+        assertNotNull("Next provider was not present", discovery.getNext());
+        assertEquals("Next Provider was not of expected type", FailoverProvider.class, discovery.getNext().getClass());
+
+        FailoverProvider failoverProvider = (FailoverProvider) discovery.getNext();
+        failoverProvider.getNestedOptions();
+
+        assertEquals("Expected nested options", 1, failoverProvider.getNestedOptions().size());
+        assertTrue("Expected nested clientID option to be present", failoverProvider.getNestedOptions().containsKey(clientIdOptionKey));
+        assertEquals("nested clientID option not as expected", clientIdValue, failoverProvider.getNestedOptions().get(clientIdOptionKey));
+    }
+
+    @Test
+    public void testCreateDiscoveryProviderWithFailoverSyntaxUnusedMainOption() throws Exception {
+        doCreateDiscoveryProviderWithUnusedMainOptionTestImpl(FailoverProviderFactory.FAILOVER_OPTION_PREFIX);
+    }
+
+    @Test
+    public void testCreateDiscoveryProviderWithDiscoverSyntaxUnusedMainOption() throws Exception {
+        doCreateDiscoveryProviderWithUnusedMainOptionTestImpl(DiscoveryProviderFactory.DISCOVERY_OPTION_PREFIX);
+    }
+
+    private void doCreateDiscoveryProviderWithUnusedMainOptionTestImpl(String optionPrefix) throws URISyntaxException, Exception {
+        URI discoveryUri = new URI("discovery:(multicast://default)?" + optionPrefix  + "unusedOption=something");
+
+        try {
+            DiscoveryProviderFactory.create(discoveryUri);
+            fail("Expected exception to be thrown");
+        } catch (IllegalArgumentException iae) {
+            // expected
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/79e76862/qpid-jms-docs/Configuration.md
----------------------------------------------------------------------
diff --git a/qpid-jms-docs/Configuration.md b/qpid-jms-docs/Configuration.md
index 55f5ae5..91baa85 100644
--- a/qpid-jms-docs/Configuration.md
+++ b/qpid-jms-docs/Configuration.md
@@ -172,6 +172,35 @@ These options apply to the behaviour of certain AMQP functionality.
 + **amqp.idleTimeout** The idle timeout in milliseconds after which the connection will be failed if the peer sends no AMQP frames. Default is 60000.
 + **amqp.vhost** The vhost to connect to. Used to populate the Sasl and Open hostname fields. Default is the main hostname from the Connection URI.
 
+
+### Discovery Configuration options
+
+The client has an optional Discovery module, which provides a customised failover layer where the broker URIs to connect to are not given in the initial URI, but discovered as the client operates via associated discovery agents. There are currently two discovery agent implementations, a file watcher that loads URIs from a file, and a multicast listener that works with ActiveMQ 5 brokers which have been configured to broadcast their broker addresses for listening clients.
+
+The general set of failover related options when using discovery are the same as those detailed earlier, with the main prefix updated from *failover.* to *discovery.*, and with the 'nested' options prefix used to supply URI options common to all the discovered broker URIs bring updated from *failover.nested.* to *discovery.discovered*. For example, a general discovery URI might look like:
+
+    discovery:(<agent-uri-details>)?discovery.maxReconnectAttempts=20&discovery.discovered.jms.clientID=foo
+
+To use the file watcher discovery agent, utilise a URI of the form:
+
+    discovery:(file:///path/to/monitored-file?updateInterval=60000)?discovery.maxReconnectAttempts=20&discovery.discovered.jms.clientID=foo
+
+The URI options for the file watcher discovery agent are listed below:
+
++ **updateInterval** Controls the frequency in milliseconds which the file is inspected for change. The default value is 30000.
+
+
+To use the multicast discovery agent with an ActiveMQ 5 broker, utilise a URI of the form:
+
+    discovery:(multicast://default?group=default)?discovery.maxReconnectAttempts=20&discovery.discovered.jms.clientID=foo
+
+Note that the use of *default* as the host in the multicast agent URI above is a special value (which is substituted with "239.255.2.3:6155" by the agent). You may change this to specify the actual IP and port in use in your multicast configuration.
+
+The URI options for the multicast discovery agent are listed below:
+
++ **group** Controls which multicast group messages are listened for on. The default value is "default".
+
+
 ## Logging
 
 The client makes use of the SLF4J API, allowing users to select a particular logging implementation based on their needs by supplying a SLF4J 'binding', such as *slf4j-log4j* in order to use Log4J. More details on SLF4J are available from http://www.slf4j.org/.


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org