You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ro...@apache.org on 2024/04/11 15:00:32 UTC

(activemq-artemis-examples) branch development updated: ARTEMIS-4720 Add an example of AMQP federation over SSL

This is an automated email from the ASF dual-hosted git repository.

robbie pushed a commit to branch development
in repository https://gitbox.apache.org/repos/asf/activemq-artemis-examples.git


The following commit(s) were added to refs/heads/development by this push:
     new 064b177  ARTEMIS-4720 Add an example of AMQP federation over SSL
064b177 is described below

commit 064b177decaa9c9920e17c9514ab73b68e0c12cc
Author: Timothy Bish <ta...@gmail.com>
AuthorDate: Thu Apr 11 09:17:54 2024 -0400

    ARTEMIS-4720 Add an example of AMQP federation over SSL
    
    Adds an example that shows how to configure broker connections for AMQP
    federation over an SSL connection.
---
 .../amqp-federation-over-ssl/pom.xml               | 158 +++++++++++++++++++++
 .../amqp-federation-over-ssl/readme.md             |  19 +++
 .../jms/example/BrokerFederationExample.java       |  86 +++++++++++
 .../src/main/resources/activemq/server0/broker.xml | 123 ++++++++++++++++
 .../activemq/server0/server-ca-truststore.p12      | Bin 0 -> 1270 bytes
 .../resources/activemq/server0/server-keystore.p12 | Bin 0 -> 5000 bytes
 .../src/main/resources/activemq/server1/broker.xml | 106 ++++++++++++++
 .../activemq/server1/server-ca-truststore.p12      | Bin 0 -> 1270 bytes
 .../resources/activemq/server1/server-keystore.p12 | Bin 0 -> 5000 bytes
 .../amqp-federation-over-ssl/store-generation.txt  |  62 ++++++++
 examples/features/broker-connection/pom.xml        |   2 +
 scripts/run-examples.sh                            |   2 +
 12 files changed, 558 insertions(+)

diff --git a/examples/features/broker-connection/amqp-federation-over-ssl/pom.xml b/examples/features/broker-connection/amqp-federation-over-ssl/pom.xml
new file mode 100644
index 0000000..28dd50d
--- /dev/null
+++ b/examples/features/broker-connection/amqp-federation-over-ssl/pom.xml
@@ -0,0 +1,158 @@
+<?xml version='1.0'?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+   <modelVersion>4.0.0</modelVersion>
+
+   <parent>
+      <groupId>org.apache.activemq.examples.broker-connection</groupId>
+      <artifactId>broker-connections</artifactId>
+      <version>2.34.0-SNAPSHOT</version>
+   </parent>
+
+   <artifactId>amqp-federation-over-ssl</artifactId>
+   <packaging>jar</packaging>
+   <name>amqp-federation-over-ssl</name>
+
+   <properties>
+      <activemq.basedir>${project.basedir}/../../../..</activemq.basedir>
+   </properties>
+
+   <dependencies>
+      <dependency>
+         <groupId>org.apache.qpid</groupId>
+         <artifactId>qpid-jms-client</artifactId>
+      </dependency>
+   </dependencies>
+
+   <build>
+      <plugins>
+         <plugin>
+            <groupId>org.apache.activemq</groupId>
+            <artifactId>artemis-maven-plugin</artifactId>
+            <executions>
+               <execution>
+                  <id>create0</id>
+                  <goals>
+                     <goal>create</goal>
+                  </goals>
+                  <configuration>
+                     <ignore>${noServer}</ignore>
+                     <instance>${basedir}/target/server0</instance>
+                     <allowAnonymous>true</allowAnonymous>
+                     <configuration>${basedir}/target/classes/activemq/server0</configuration>
+                     <!-- this makes it easier in certain envs -->
+                     <javaOptions>-Djava.net.preferIPv4Stack=true</javaOptions>
+                  </configuration>
+               </execution>
+               <execution>
+                  <id>create1</id>
+                  <goals>
+                     <goal>create</goal>
+                  </goals>
+                  <configuration>
+                     <ignore>${noServer}</ignore>
+                     <instance>${basedir}/target/server1</instance>
+                     <allowAnonymous>true</allowAnonymous>
+                     <configuration>${basedir}/target/classes/activemq/server1</configuration>
+                     <!-- this makes it easier in certain envs -->
+                     <javaOptions>-Djava.net.preferIPv4Stack=true</javaOptions>
+                  </configuration>
+               </execution>
+               <!-- we first start broker 1, to avoid reconnecting statements -->
+               <execution>
+                  <id>start1</id>
+                  <goals>
+                     <goal>cli</goal>
+                  </goals>
+                  <configuration>
+                     <ignore>${noServer}</ignore>
+                     <spawn>true</spawn>
+                     <location>${basedir}/target/server1</location>
+                     <testURI>tcp://localhost:5770?sslEnabled=true&amp;trustStorePath=activemq/server1/server-ca-truststore.p12&amp;trustStorePassword=securepass&amp;trustStoreType=PKCS12</testURI>
+                     <args>
+                        <param>run</param>
+                     </args>
+                     <name>server1</name>
+                  </configuration>
+               </execution>
+               <execution>
+                  <id>start0</id>
+                  <goals>
+                     <goal>cli</goal>
+                  </goals>
+                  <configuration>
+                     <spawn>true</spawn>
+                     <ignore>${noServer}</ignore>
+                     <location>${basedir}/target/server0</location>
+                     <testURI>tcp://localhost:5660?sslEnabled=true&amp;trustStorePath=activemq/server0/server-ca-truststore.p12&amp;trustStorePassword=securepass&amp;trustStoreType=PKCS12</testURI>
+                     <args>
+                        <param>run</param>
+                     </args>
+                     <name>server0</name>
+                  </configuration>
+               </execution>
+               <execution>
+                  <id>runClient</id>
+                  <goals>
+                     <goal>runClient</goal>
+                  </goals>
+                  <configuration>
+                     <!-- you may have to set export MAVEN_OPTS="-Djava.net.preferIPv4Stack=true"
+                          if you are on MacOS for instance -->
+                     <clientClass>org.apache.activemq.artemis.jms.example.BrokerFederationExample</clientClass>
+                  </configuration>
+               </execution>
+               <execution>
+                  <id>stop0</id>
+                  <goals>
+                     <goal>stop</goal>
+                  </goals>
+                  <configuration>
+                     <ignore>${noServer}</ignore>
+                     <location>${basedir}/target/server0</location>
+                  </configuration>
+               </execution>
+               <execution>
+                  <id>stop1</id>
+                  <goals>
+                     <goal>stop</goal>
+                  </goals>
+                  <configuration>
+                     <ignore>${noServer}</ignore>
+                     <location>${basedir}/target/server1</location>
+                  </configuration>
+               </execution>
+            </executions>
+            <dependencies>
+               <dependency>
+                  <groupId>org.apache.activemq.examples.broker-connection</groupId>
+                  <artifactId>amqp-federation-over-ssl</artifactId>
+                  <version>${project.version}</version>
+               </dependency>
+            </dependencies>
+         </plugin>
+         <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-clean-plugin</artifactId>
+         </plugin>
+      </plugins>
+   </build>
+</project>
diff --git a/examples/features/broker-connection/amqp-federation-over-ssl/readme.md b/examples/features/broker-connection/amqp-federation-over-ssl/readme.md
new file mode 100644
index 0000000..c3ec7f7
--- /dev/null
+++ b/examples/features/broker-connection/amqp-federation-over-ssl/readme.md
@@ -0,0 +1,19 @@
+# AMQP Broker Connection demonstrating Federation over SSL connections
+
+To run the example, simply type **mvn verify** from this directory, or **mvn -PnoServer verify** if you want to create and start the broker manually.
+
+This example demonstrates how you can federate messages sent to an Address on a remote server back to the local server and also instruct the remote server to federate messages sent to a Queue on the local server back to itself over a single AMQP connection. The connection is made using a connector and acceptor with SSL configured.
+
+The broker accepting the connection needs an acceptor on the remote to connect to which is configured as follows
+
+    <acceptor name="ssl-acceptor">tcp://localhost:5770?sslEnabled=true;keyStorePath=server-keystore.p12;keyStorePassword=securepass;keyStoreType=PKCS12</acceptor>
+
+While the connecting broker needs to configure its broker connection URI to enable SSL and provide a trust store that include the broker certificate or certificate of the signing authority indicating the remote certificate can be trusted.
+
+    <broker-connections>
+      <amqp-connection uri="tcp://localhost:5770?sslEnabled=true;trustStorePath=server-ca-truststore.p12;trustStorePassword=securepass;trustStoreType=PKCS12" name="federation-example" retry-interval="100">
+        ...
+      </amqp-connection>
+    </broker-connections>
+
+The keystore and trustores used in the example were generated with store-generation.txt
\ No newline at end of file
diff --git a/examples/features/broker-connection/amqp-federation-over-ssl/src/main/java/org/apache/activemq/artemis/jms/example/BrokerFederationExample.java b/examples/features/broker-connection/amqp-federation-over-ssl/src/main/java/org/apache/activemq/artemis/jms/example/BrokerFederationExample.java
new file mode 100644
index 0000000..0ed3dd2
--- /dev/null
+++ b/examples/features/broker-connection/amqp-federation-over-ssl/src/main/java/org/apache/activemq/artemis/jms/example/BrokerFederationExample.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.jms.example;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+
+import org.apache.qpid.jms.JmsConnectionFactory;
+
+/**
+ * This example is demonstrating how messages are federated between two brokers with the
+ * federation configuration located on only one broker (server0) and only a single outbound
+ * connection is configured from server0 to server1 over an SSL connection.
+ */
+public class BrokerFederationExample {
+
+   public static void main(final String[] args) throws Exception {
+
+      final ConnectionFactory connectionFactoryServer0 = new JmsConnectionFactory(
+         "amqps://localhost:5660" +
+         "?transport.trustStoreLocation=src/main/resources/activemq/server0/server-ca-truststore.p12" +
+         "&transport.trustStoreType=PKCS12&" +
+         "transport.trustStorePassword=securepass");
+      final ConnectionFactory connectionFactoryServer1 = new JmsConnectionFactory(
+         "amqps://localhost:5770" +
+         "?transport.trustStoreLocation=src/main/resources/activemq/server1/server-ca-truststore.p12" +
+         "&transport.trustStoreType=PKCS12" +
+         "&transport.trustStorePassword=securepass");
+
+      final Connection connectionOnServer0 = connectionFactoryServer0.createConnection();
+      final Connection connectionOnServer1 = connectionFactoryServer1.createConnection();
+
+      connectionOnServer0.start();
+      connectionOnServer1.start();
+
+      final Session sessionOnServer0 = connectionOnServer0.createSession(Session.AUTO_ACKNOWLEDGE);
+      final Session sessionOnServer1 = connectionOnServer1.createSession(Session.AUTO_ACKNOWLEDGE);
+
+      final Topic ordersTopic = sessionOnServer0.createTopic("orders");
+      final Queue trackingQueue = sessionOnServer1.createQueue("tracking");
+
+      // Federation from server1 back to server0 on the orders address
+      final MessageProducer ordersProducerOn1 = sessionOnServer1.createProducer(ordersTopic);
+      final MessageConsumer ordersConsumerOn0 = sessionOnServer0.createConsumer(ordersTopic);
+
+      final TextMessage orderMessageSent = sessionOnServer1.createTextMessage("new-order");
+
+      ordersProducerOn1.send(orderMessageSent);
+
+      final TextMessage orderMessageReceived = (TextMessage) ordersConsumerOn0.receive(5_000);
+
+      System.out.println("Consumer on server 0 received order message from producer on server 1 " + orderMessageReceived.getText());
+
+      // Federation from server0 to server1 on the tracking queue
+      final MessageProducer trackingProducerOn0 = sessionOnServer0.createProducer(trackingQueue);
+      final MessageConsumer trackingConsumerOn1 = sessionOnServer1.createConsumer(trackingQueue);
+
+      final TextMessage trackingMessageSent = sessionOnServer0.createTextMessage("new-tracking-data");
+
+      trackingProducerOn0.send(trackingMessageSent);
+
+      final TextMessage trackingMessageReceived = (TextMessage) trackingConsumerOn1.receive(5_000);
+
+      System.out.println("Consumer on server 1 received tracking data from producer on server 0 " + trackingMessageReceived.getText());
+   }
+}
diff --git a/examples/features/broker-connection/amqp-federation-over-ssl/src/main/resources/activemq/server0/broker.xml b/examples/features/broker-connection/amqp-federation-over-ssl/src/main/resources/activemq/server0/broker.xml
new file mode 100644
index 0000000..ee4b1b1
--- /dev/null
+++ b/examples/features/broker-connection/amqp-federation-over-ssl/src/main/resources/activemq/server0/broker.xml
@@ -0,0 +1,123 @@
+<?xml version='1.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.
+-->
+
+<configuration xmlns="urn:activemq"
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+               xmlns:xi="http://www.w3.org/2001/XInclude"
+               xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
+
+   <core xmlns="urn:activemq:core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="urn:activemq:core ">
+
+      <name>0.0.0.0</name>
+
+      <persistence-enabled>false</persistence-enabled>
+
+      <journal-type>NIO</journal-type>
+
+      <!-- should the broker detect dead locks and other issues -->
+      <critical-analyzer>true</critical-analyzer>
+
+      <critical-analyzer-timeout>120000</critical-analyzer-timeout>
+
+      <critical-analyzer-check-period>60000</critical-analyzer-check-period>
+
+      <critical-analyzer-policy>HALT</critical-analyzer-policy>
+
+      <page-sync-timeout>44000</page-sync-timeout>
+
+      <acceptors>
+         <!-- Acceptor for every supported protocol -->
+         <acceptor name="artemis">tcp://0.0.0.0:5660?sslEnabled=true;keyStoreType=PKCS12;keyStorePath=server-keystore.p12;keyStorePassword=securepass</acceptor>
+      </acceptors>
+
+      <broker-connections>
+         <amqp-connection uri="tcp://localhost:5770?sslEnabled=true;trustStorePath=server-ca-truststore.p12;trustStorePassword=securepass;trustStoreType=PKCS12" name="federation-example" retry-interval="100">
+            <!-- This will create a federation connection between servers, the local
+                 server will federate messages sent to the address 'orders' from the
+                 remote and the remote will federate message sent to the tracking queue
+                 on the local broker to itself. -->
+            <federation>
+               <local-address-policy name="address-federation-from-remote">
+                  <include address-match="orders" />
+               </local-address-policy>
+               <remote-queue-policy name="queue-federation-to-remote">
+                  <include address-match="#" queue-match="tracking" />
+               </remote-queue-policy>
+            </federation>
+         </amqp-connection>
+      </broker-connections>
+
+      <security-settings>
+         <security-setting match="#">
+            <permission type="createNonDurableQueue" roles="guest"/>
+            <permission type="deleteNonDurableQueue" roles="guest"/>
+            <permission type="createDurableQueue" roles="guest"/>
+            <permission type="deleteDurableQueue" roles="guest"/>
+            <permission type="createAddress" roles="guest"/>
+            <permission type="deleteAddress" roles="guest"/>
+            <permission type="consume" roles="guest"/>
+            <permission type="browse" roles="guest"/>
+            <permission type="send" roles="guest"/>
+            <permission type="manage" roles="guest"/>
+         </security-setting>
+      </security-settings>
+
+      <address-settings>
+         <!-- if you define auto-create on certain queues, management has to be auto-create -->
+         <address-setting match="activemq.management#">
+            <dead-letter-address>DLQ</dead-letter-address>
+            <expiry-address>ExpiryQueue</expiry-address>
+            <redelivery-delay>0</redelivery-delay>
+            <!-- with -1 only the global-max-size is in use for limiting -->
+            <max-size-bytes>-1</max-size-bytes>
+            <message-counter-history-day-limit>10</message-counter-history-day-limit>
+            <address-full-policy>PAGE</address-full-policy>
+            <auto-create-queues>true</auto-create-queues>
+            <auto-create-addresses>true</auto-create-addresses>
+         </address-setting>
+         <!--default for catch all-->
+         <address-setting match="#">
+            <dead-letter-address>DLQ</dead-letter-address>
+            <expiry-address>ExpiryQueue</expiry-address>
+            <redelivery-delay>0</redelivery-delay>
+            <!-- with -1 only the global-max-size is in use for limiting -->
+            <max-size-bytes>-1</max-size-bytes>
+            <message-counter-history-day-limit>10</message-counter-history-day-limit>
+            <address-full-policy>PAGE</address-full-policy>
+            <auto-create-queues>true</auto-create-queues>
+            <auto-create-addresses>true</auto-create-addresses>
+         </address-setting>
+      </address-settings>
+
+      <addresses>
+         <address name="orders">
+            <multicast>
+            </multicast>
+         </address>
+         <address name="tracking">
+            <anycast>
+               <queue name="tracking" />
+            </anycast>
+         </address>
+      </addresses>
+
+   </core>
+</configuration>
diff --git a/examples/features/broker-connection/amqp-federation-over-ssl/src/main/resources/activemq/server0/server-ca-truststore.p12 b/examples/features/broker-connection/amqp-federation-over-ssl/src/main/resources/activemq/server0/server-ca-truststore.p12
new file mode 100644
index 0000000..82bffbb
Binary files /dev/null and b/examples/features/broker-connection/amqp-federation-over-ssl/src/main/resources/activemq/server0/server-ca-truststore.p12 differ
diff --git a/examples/features/broker-connection/amqp-federation-over-ssl/src/main/resources/activemq/server0/server-keystore.p12 b/examples/features/broker-connection/amqp-federation-over-ssl/src/main/resources/activemq/server0/server-keystore.p12
new file mode 100644
index 0000000..269af9d
Binary files /dev/null and b/examples/features/broker-connection/amqp-federation-over-ssl/src/main/resources/activemq/server0/server-keystore.p12 differ
diff --git a/examples/features/broker-connection/amqp-federation-over-ssl/src/main/resources/activemq/server1/broker.xml b/examples/features/broker-connection/amqp-federation-over-ssl/src/main/resources/activemq/server1/broker.xml
new file mode 100644
index 0000000..7a251cc
--- /dev/null
+++ b/examples/features/broker-connection/amqp-federation-over-ssl/src/main/resources/activemq/server1/broker.xml
@@ -0,0 +1,106 @@
+<?xml version='1.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.
+-->
+
+<configuration xmlns="urn:activemq"
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+               xmlns:xi="http://www.w3.org/2001/XInclude"
+               xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
+
+   <core xmlns="urn:activemq:core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="urn:activemq:core ">
+
+      <name>0.0.0.0</name>
+
+      <persistence-enabled>false</persistence-enabled>
+
+      <journal-type>NIO</journal-type>
+
+      <!-- should the broker detect dead locks and other issues -->
+      <critical-analyzer>true</critical-analyzer>
+
+      <critical-analyzer-timeout>120000</critical-analyzer-timeout>
+
+      <critical-analyzer-check-period>60000</critical-analyzer-check-period>
+
+      <critical-analyzer-policy>HALT</critical-analyzer-policy>
+
+      <page-sync-timeout>44000</page-sync-timeout>
+
+      <acceptors>
+         <!-- Acceptor for every supported protocol -->
+         <acceptor name="artemis">tcp://0.0.0.0:5770?sslEnabled=true;keyStoreType=PKCS12;keyStorePath=server-keystore.p12;keyStorePassword=securepass</acceptor>
+      </acceptors>
+
+      <security-settings>
+         <security-setting match="#">
+            <permission type="createNonDurableQueue" roles="guest"/>
+            <permission type="deleteNonDurableQueue" roles="guest"/>
+            <permission type="createDurableQueue" roles="guest"/>
+            <permission type="deleteDurableQueue" roles="guest"/>
+            <permission type="createAddress" roles="guest"/>
+            <permission type="deleteAddress" roles="guest"/>
+            <permission type="consume" roles="guest"/>
+            <permission type="browse" roles="guest"/>
+            <permission type="send" roles="guest"/>
+            <permission type="manage" roles="guest"/>
+         </security-setting>
+      </security-settings>
+
+      <address-settings>
+         <!-- if you define auto-create on certain queues, management has to be auto-create -->
+         <address-setting match="activemq.management#">
+            <dead-letter-address>DLQ</dead-letter-address>
+            <expiry-address>ExpiryQueue</expiry-address>
+            <redelivery-delay>0</redelivery-delay>
+            <!-- with -1 only the global-max-size is in use for limiting -->
+            <max-size-bytes>-1</max-size-bytes>
+            <message-counter-history-day-limit>10</message-counter-history-day-limit>
+            <address-full-policy>PAGE</address-full-policy>
+            <auto-create-queues>true</auto-create-queues>
+            <auto-create-addresses>true</auto-create-addresses>
+         </address-setting>
+         <!--default for catch all-->
+         <address-setting match="#">
+            <dead-letter-address>DLQ</dead-letter-address>
+            <expiry-address>ExpiryQueue</expiry-address>
+            <redelivery-delay>0</redelivery-delay>
+            <!-- with -1 only the global-max-size is in use for limiting -->
+            <max-size-bytes>-1</max-size-bytes>
+            <message-counter-history-day-limit>10</message-counter-history-day-limit>
+            <address-full-policy>PAGE</address-full-policy>
+            <auto-create-queues>true</auto-create-queues>
+            <auto-create-addresses>true</auto-create-addresses>
+         </address-setting>
+      </address-settings>
+
+      <addresses>
+         <address name="orders">
+            <multicast>
+            </multicast>
+         </address>
+         <address name="tracking">
+            <anycast>
+               <queue name="tracking" />
+            </anycast>
+         </address>
+      </addresses>
+
+   </core>
+</configuration>
diff --git a/examples/features/broker-connection/amqp-federation-over-ssl/src/main/resources/activemq/server1/server-ca-truststore.p12 b/examples/features/broker-connection/amqp-federation-over-ssl/src/main/resources/activemq/server1/server-ca-truststore.p12
new file mode 100644
index 0000000..82bffbb
Binary files /dev/null and b/examples/features/broker-connection/amqp-federation-over-ssl/src/main/resources/activemq/server1/server-ca-truststore.p12 differ
diff --git a/examples/features/broker-connection/amqp-federation-over-ssl/src/main/resources/activemq/server1/server-keystore.p12 b/examples/features/broker-connection/amqp-federation-over-ssl/src/main/resources/activemq/server1/server-keystore.p12
new file mode 100644
index 0000000..269af9d
Binary files /dev/null and b/examples/features/broker-connection/amqp-federation-over-ssl/src/main/resources/activemq/server1/server-keystore.p12 differ
diff --git a/examples/features/broker-connection/amqp-federation-over-ssl/store-generation.txt b/examples/features/broker-connection/amqp-federation-over-ssl/store-generation.txt
new file mode 100644
index 0000000..5d513be
--- /dev/null
+++ b/examples/features/broker-connection/amqp-federation-over-ssl/store-generation.txt
@@ -0,0 +1,62 @@
+!/bin/bash
+# ---------------------------------------------------------------------------
+# 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.
+# ---------------------------------------------------------------------------
+# The various SSL stores and certificates were created with the following commands:
+# This can be run as a script by sourcing the file, e.g ". store-generation.txt"
+# Requires use of JDK 8+ keytool command.
+set -e
+
+KEY_PASS=securepass
+STORE_PASS=securepass
+CA_VALIDITY=365000
+VALIDITY=36500
+LOCAL_SERVER_NAMES="dns:localhost,dns:localhost.localdomain,dns:artemis.localtest.me,ip:127.0.0.1"
+
+# Clean up existing files
+# --------------------------------------------------------------------------------------------------------------
+rm -f *.crt *.csr openssl-* *.jceks *.jks *.p12 *.pem *.pemcfg
+
+# Create a key and self-signed certificate for the CA, to sign server certificate requests and use for trust:
+# --------------------------------------------------------------------------------------------------------------
+keytool -storetype pkcs12 -keystore server-ca-keystore.p12 -storepass $STORE_PASS -keypass $KEY_PASS -alias server-ca -genkey -keyalg "RSA" -keysize 2048 -dname "CN=ActiveMQ Artemis Server Certification Authority, OU=Artemis, O=ActiveMQ" -validity $CA_VALIDITY -ext bc:c=ca:true
+keytool -storetype pkcs12 -keystore server-ca-keystore.p12 -storepass $STORE_PASS -alias server-ca -exportcert -rfc > server-ca.crt
+
+# Create trust store with the server CA cert:
+# --------------------------------------------------------------------------------------------------------------
+keytool -storetype pkcs12 -keystore server-ca-truststore.p12 -storepass $STORE_PASS -keypass $KEY_PASS -importcert -alias server-ca -file server-ca.crt -noprompt
+
+# Create a key pair for the server, and sign it with the CA:
+# --------------------------------------------------------------------------------------------------------------
+keytool -storetype pkcs12 -keystore server-keystore.p12 -storepass $STORE_PASS -keypass $KEY_PASS -alias server -genkey -keyalg "RSA" -keysize 2048 -dname "CN=ActiveMQ Artemis Server, OU=Artemis, O=ActiveMQ, L=AMQ, S=AMQ, C=AMQ" -validity $VALIDITY -ext bc=ca:false -ext eku=sA -ext "san=dns:server.artemis.activemq,$LOCAL_SERVER_NAMES"
+
+keytool -storetype pkcs12 -keystore server-keystore.p12 -storepass $STORE_PASS -alias server -certreq -file server.csr
+keytool -storetype pkcs12 -keystore server-ca-keystore.p12 -storepass $STORE_PASS -alias server-ca -gencert -rfc -infile server.csr -outfile server.crt -validity $VALIDITY -ext bc=ca:false -ext eku=sA -ext "san=dns:server.artemis.activemq,$LOCAL_SERVER_NAMES"
+
+keytool -storetype pkcs12 -keystore server-keystore.p12 -storepass $STORE_PASS -keypass $KEY_PASS -importcert -alias server-ca -file server-ca.crt -noprompt
+keytool -storetype pkcs12 -keystore server-keystore.p12 -storepass $STORE_PASS -keypass $KEY_PASS -importcert -alias server -file server.crt
+
+# Copy the stores into place
+# --------------------------------------------------------------------------------------------------------------
+cp server-ca-truststore.p12 src/main/resources/activemq/server0/
+cp server-keystore.p12 src/main/resources/activemq/server0/
+
+cp server-ca-truststore.p12 src/main/resources/activemq/server1/
+cp server-keystore.p12 src/main/resources/activemq/server1/
+
+# Clean up tmp files
+# --------------------------------------------------------------------------------------------------------------
+rm -f *.crt *.csr *.p12
\ No newline at end of file
diff --git a/examples/features/broker-connection/pom.xml b/examples/features/broker-connection/pom.xml
index 5beb627..09c2d86 100644
--- a/examples/features/broker-connection/pom.xml
+++ b/examples/features/broker-connection/pom.xml
@@ -52,6 +52,7 @@ under the License.
             <module>amqp-receiving-messages</module>
             <module>amqp-sending-overssl</module>
             <module>amqp-federation</module>
+            <module>amqp-federation-over-ssl</module>
             <module>amqp-federation-multicast-hub-spoke</module>
             <module>amqp-federation-multicast-ring</module>
             <module>amqp-federation-multicast-fanout</module>
@@ -69,6 +70,7 @@ under the License.
             <module>amqp-receiving-messages</module>
             <module>amqp-sending-overssl</module>
             <module>amqp-federation</module>
+            <module>amqp-federation-over-ssl</module>
             <module>amqp-federation-multicast-hub-spoke</module>
             <module>amqp-federation-multicast-ring</module>
             <module>amqp-federation-multicast-fanout</module>
diff --git a/scripts/run-examples.sh b/scripts/run-examples.sh
index 7b84221..eba389d 100755
--- a/scripts/run-examples.sh
+++ b/scripts/run-examples.sh
@@ -175,9 +175,11 @@ cd amqp-sending-messages; mvn verify; cd ..
 cd amqp-sending-overssl; mvn verify; cd ..
 cd disaster-recovery; mvn verify; cd ..
 cd amqp-federation; mvn verify; cd ..
+cd amqp-federation-over-ssl; mvn verify; cd ..
 cd amqp-federation-multicast-hub-spoke; mvn verify; cd ..
 cd amqp-federation-multicast-fanout; mvn verify; cd ..
 cd amqp-federation-multicast-ring; mvn verify; cd ..
 cd amqp-federation-queue-dual-federation; mvn verify; cd ..
 cd amqp-federation-queue-priority; mvn verify; cd ..
+cd amqp-federation-queue-multiple-brokers; mvn verify; cd ..