Update code from https://github.com/dmi-try/marionette-collective
[packages/precise/mcollective.git] / website / deploy / middleware / activemq.md
1 ---
2 title: "MCollective » Deploy » Middleware » ActiveMQ Config"
3 subtitle: "ActiveMQ Config Reference for MCollective Users"
4 layout: default
5 ---
6
7 [Wildcard]: http://activemq.apache.org/wildcards.html
8 [minimal_example]: http://github.com/puppetlabs/marionette-collective/raw/master/ext/activemq/examples/single-broker/activemq.xml
9 [maximal_example]: https://github.com/puppetlabs/marionette-collective/tree/master/ext/activemq/examples/multi-broker
10 [template_example]: TODO
11 [apache_activemq_config_docs]: http://activemq.apache.org/version-5-xml-configuration.html
12
13 [subcollectives]: /reference/basic/subcollectives.html
14 [activemq_connector]: /reference/plugins/connector_activemq.html
15 [mcollective_connector_tls]: /mcollective/reference/integration/activemq_ssl.html
16
17
18 Summary
19 -----
20
21 Apache ActiveMQ is the primary middleware we recommend with MCollective. It's good software, but its XML config file is large and unwieldy, and you may need to edit many sections of it in a complex MCollective deployment. This reference guide attempts to describe every major ActiveMQ setting that matters to MCollective.
22
23 ### How to Use This Page
24
25 * This page **doesn't** describe the complete format of the activemq.xml config file, and will sometimes use incomplete shorthand to describe elements of it.
26 * You should definitely refer to an example config file while reading, so you can see each element's full syntax in context.
27 * You don't need to read this entire page when setting up a new deployment. We recommend that you:
28     * Start with an example config file (see directly below).
29     * Make heavy use of the table of contents above.
30     * Skim the sections of this page you currently care about, and edit your config as needed.
31     * Refer back to this page later when you need to expand your broker infrastructure.
32 * If you are a new user, we recommend that you:
33     * Start with the [single-broker example config][minimal_example].
34     * Change the [user account passwords](#authentication-users-and-groups).
35     * [Set up TLS](#tls-credentials).
36
37 ### Example Config Files
38
39 We have several. 
40
41 * [Minimal config example][minimal_example] --- single broker <!-- , minimal authorization. -->
42 * [Maximal config example][maximal_example] --- multi-broker <!--  with extensive authorization. -->
43
44 <!-- 
45 * [Template-based example][template_example] --- reduces configuration down to a handful of variables; shows how those few decisions ramify into many config edits.
46  -->
47
48
49 > **Note:** Some config data needs to be set in both MCollective and ActiveMQ; your configuration of one will affect the other. In this page, we call out that information with headers labeled "Shared Configuration."
50
51 ### Version Limits
52
53 This document is about the "new" MCollective/ActiveMQ interface, which means it requires the following:
54
55 * MCollective 2.0.0 or newer
56 * ActiveMQ 5.5.0 or newer
57 * Stomp gem 1.2.2 or newer
58 * The [activemq connector][activemq_connector] plugin (included with MCollective 2.0.0 and newer)
59
60 ([↑ Back to top](#content))
61
62 How MCollective Uses ActiveMQ
63 -----
64
65 MCollective connects to ActiveMQ over the Stomp protocol, and presents certain credentials:
66
67 * It provides a username and password, with which ActiveMQ can do what it pleases. 
68 * If TLS is in use, it will also present a certificate (and verify the ActiveMQ server's certificate).
69
70 Once allowed to connect, MCollective will use the Stomp protocol to create subscriptions. It will then produce and consume a lot of traffic on queues and topics whose names begin with `mcollective`. (See "Topic and Queue Names" directly below.)
71
72 ### Absolute Minimum Requirements
73
74 ActiveMQ defaults to believing that it is routing traffic between processes in a single JVM instance: it doesn't assume it is connected to the network, and it uses a loose-to-nonexistent security model.
75
76 This means that if you do nothing but enable Stomp traffic, MCollective will work fine. (Albeit with terrible security and eventual out-of-control memory usage.)
77
78 ### Topic and Queue Names
79
80 MCollective uses the following destination names. This list uses standard [ActiveMQ destination wildcards][wildcard]. "COLLECTIVE" is the name of the collective being used; by default, this is `mcollective`, but if you are using [subcollectives][], each one is implemented as an equal peer of the default collective.
81
82 Topics: 
83
84 - `ActiveMQ.Advisory.>` (built-in topics that all ActiveMQ producers and consumers need all permissions on)
85 - `COLLECTIVE.*.agent` (for each agent plugin, where the `*` is the name of the plugin)
86
87 Queues:
88
89 - `COLLECTIVE.nodes` (used for direct addressing; this is a single destination that uses JMS selectors, rather than a group of destinations)
90 - `COLLECTIVE.reply.>` (where the continued portion is a request ID)
91
92 > #### Shared Configuration
93
94 > Subcollectives must also be configured in the MCollective client and server config files. ActiveMQ must allow traffic on any subcollective that MCollective servers and clients expect to use.
95
96 ([↑ Back to top](#content))
97
98 Config File Location and Format
99 -----
100
101 ActiveMQ's config is usually called activemq.xml, and is kept in ActiveMQ's configuration directory (`/etc/activemq` with Puppet Labs's Red Hat-like packages, or a subdirectory of `/etc/activemq/instances-enabled` with the standard Debian or Ubuntu packages). Any other files referenced in activemq.xml will be looked for in the same directory.
102
103 The config file is in Java's Beans XML format. Note that all of the settings relevant to MCollective are located inside activemq.xml's `<broker>` element. 
104
105 This document won't describe the complete format of the activemq.xml config file, and will sometimes use incomplete shorthand to describe elements of it. You should definitely [refer to an example config file](#example-config-files) while reading, so you can see each element's full syntax in context.
106
107 You can also read external documentation for a more complete understanding.
108
109 > **Bug Warning:** In ActiveMQ 5.5, the first-level children of the `<broker>` element must be arranged in alphabetical order. There is no good reason for this behavior, and it was fixed in ActiveMQ 5.6.
110
111 ### External ActiveMQ Documentation
112
113 The Apache ActiveMQ documentation contains important information, but it is often incomplete, badly organized, and confusing. The Fuse documentation (a commercially supported release of ActiveMQ) is significantly better written and better organized, although it requires signing up for an email newsletter, but it may be out of sync with the most recent ActiveMQ releases.
114
115 * [Apache ActiveMQ Documentation][apache_activemq_config_docs]
116 * [Fuse Documentation](http://fusesource.com/documentation/fuse-message-broker-documentation/)
117
118 ### Wildcards
119
120 You'll see a lot of [ActiveMQ destination wildcards][wildcard] below. In short:
121
122 * Segments in a destination name are separated with dots (`.`)
123 * A `*` represents _one segment_ (i.e. any sequence of non-dot characters)
124 * A `>` represents _the whole rest of the name_ after a prefix
125
126
127 ([↑ Back to top](#content))
128
129 Required Settings
130 -----
131
132 One way or another, you must set all of the following.
133
134 ### Transport Connector(s)
135
136 It's generally best to only enable the transport connectors you need. For example, if you're using Stomp over TLS, don't leave a bare Stomp transport open. If you're not using a network of brokers, close the OpenWire transport.
137
138 The `name` attribute of a transport connector doesn't seem to matter as long as it's locally unique.
139
140 #### Stomp
141
142 ActiveMQ must listen over the network for Stomp connections; otherwise, MCollective can't reach it. Enable this with a `<transportConnector>` element inside the `<transportConnectors>` element. We generally recommend using TLS.
143
144 {% highlight xml %}
145     <transportConnectors>
146       <transportConnector name="stomp+nio" uri="stomp+nio://0.0.0.0:61613"/>
147     </transportConnectors>
148 {% endhighlight %}
149
150 * Note that the protocol/port/arguments for Stomp URIs can differ:
151     * Unencrypted: `stomp+nio://0.0.0.0:61613`
152     * CA-verified TLS: `stomp+ssl://0.0.0.0:61614?needClientAuth=true`
153     * Anonymous TLS: `stomp+ssl://0.0.0.0:61614`
154 * You can choose to restrict the interface/hostname to use instead of listening on `0.0.0.0`.
155
156 > **If you are using TLS,** note that you must also:
157
158 > * [Configure ActiveMQ's TLS credentials](#tls-credentials) (see below)
159 > * [Configure MCollective to use TLS credentials][mcollective_connector_tls]
160
161 #### OpenWire
162
163 If you are using a network of brokers instead of just one ActiveMQ server, they talk to each other over OpenWire, and will all need a transport connector for that protocol too:
164
165 {% highlight xml %}
166     <transportConnector name="openwire+ssl" uri="ssl://0.0.0.0:61617?needClientAuth=true"/>
167 {% endhighlight %}
168
169 * Note that the protocol/port/arguments for OpenWire URIs can differ:
170     * Unencrypted: `tcp://0.0.0.0:61616`
171     * CA-verified TLS: `ssl://0.0.0.0:61617?needClientAuth=true`
172     * Anonymous TLS: `ssl://0.0.0.0:61617`
173 * You can choose to restrict the interface/hostname to use instead of listening on `0.0.0.0`.
174
175
176
177 #### Standard Ports for Stomp and OpenWire
178
179 Alas, there aren't any; just a rough consensus.
180
181 * 61613 for unencrypted Stomp
182 * 61614 for Stomp with TLS
183 * 61616 for unencrypted OpenWire
184 * 61617 for OpenWire with TLS
185
186 All of our documentation assumes these ports.
187
188 > #### Shared Configuration
189
190 > MCollective needs to know the following:
191
192 > * The port to use for Stomp traffic
193 > * The hostname or IP address to reach ActiveMQ at
194 > * Whether to use TLS
195
196 > In a network of brokers, the other ActiveMQ servers need to know the following:
197
198 > * The port to use for OpenWire traffic
199 > * The hostname or IP address to reach peer ActiveMQ servers at
200 > * Whether to use TLS
201
202
203 ### Reply Queue Pruning
204
205 MCollective sends replies on uniquely-named, single-use queues with names like `mcollective.reply.<UNIQUE ID>`. These have to be deleted after about five minutes, lest they clog up ActiveMQ's available memory. By default, queues live forever, so you have to configure this.
206
207 Use a `<policyEntry>` element for `*.reply.>` queues, with `gcInactiveDestinations` set to true and `inactiveTimoutBeforeGC` set to 300000 ms (five minutes). 
208
209 {% highlight xml %}
210     <destinationPolicy>
211       <policyMap>
212         <policyEntries>
213           <policyEntry queue="*.reply.>" gcInactiveDestinations="true" inactiveTimoutBeforeGC="300000" />
214           <policyEntry topic=">" producerFlowControl="false"/>
215         </policyEntries>
216       </policyMap>
217     </destinationPolicy>
218 {% endhighlight %}
219
220 ### Disable Producer Flow Control on Topics
221
222 In the example above, you can also see that `producerFlowControl` is set to false for all topics. This is highly recommended; setting it to true can cause MCollective servers to appear blocked when there's heavy traffic.
223
224
225 ([↑ Back to top](#content))
226
227 Recommended Settings
228 -----
229
230 ### TLS Credentials
231
232 If you are using TLS in either your Stomp or OpenWire [transport connectors](#transport-connectors), ActiveMQ needs a keystore file, a truststore file, and a password for each:
233
234 {% highlight xml %}
235     <sslContext>
236       <sslContext
237          keyStore="keystore.jks" keyStorePassword="secret"
238          trustStore="truststore.jks" trustStorePassword="secret"
239       />
240     </sslContext>
241 {% endhighlight %}
242
243 **Note:** This example is for CA-verified TLS. If you are using anonymous TLS, you may optionally skip the truststore attributes.
244
245 The redundant nested `<sslContext>` elements are not a typo; for some reason ActiveMQ actually needs this.
246
247 ActiveMQ will expect to find these files in the same directory as activemq.xml.
248
249 > #### Creating a Keystore and Truststore
250
251 > There is a [separate guide that covers how to create keystores.][activemq_keystores]
252
253 [activemq_keystores]: ./activemq_keystores.html
254
255
256 ### Authentication (Users and Groups)
257
258 When they connect, MCollective clients and servers provide a username, password, and optionally an SSL certificate. ActiveMQ can use any of these to authenticate them. 
259
260 By default, ActiveMQ ignores all of these and has no particular concept of "users." Enabling authentication means ActiveMQ will only allow users with proper credentials to connect. It also gives you the option of setting up per-destination authorization (see below). 
261
262 You set up authentication by adding the appropriate element to the `<plugins>` element. [The Fuse documentation has a more complete description of ActiveMQ's authentication capabilities;][fuse_security] the [ActiveMQ docs version][activemq_security] is less organized and less complete. In summary:
263
264 - `simpleAuthenticationPlugin` defines users directly in activemq.xml. It's well-tested and easy. It also requires you to edit activemq.xml and restart the broker every time you add a new user. The activemq.xml file will contain sensitive passwords and must be protected.
265 - `jaasAuthenticationPlugin` lets you use external text files (or even an LDAP database) to define users and groups. You need to make a `login.config` file in the ActiveMQ config directory, and possibly two more files. You can add users and groups without restarting the broker. The external users file will contain sensitive passwords and must be protected.
266 - `jaasCertificateAuthenticationPlugin` ignores the username and password that MCollective presents; instead, it reads the distinguished name of the certificate and maps that to a username. It requires TLS, a `login.config` file, and two other external files. It is also impractical unless your servers are all using the same SSL certificate to connect to ActiveMQ; the currently recommended approach of re-using Puppet certificates makes this problematic, but you can probably ship credentials around and figure out a way to make it work. This is not currently well-tested with MCollective.
267
268 [fuse_security]: http://fusesource.com/docs/broker/5.5/security/front.html
269 [activemq_security]: http://activemq.apache.org/security.html
270
271 The example below uses `simpleAuthenticationPlugin`.
272
273 {% highlight xml %}
274     <plugins>
275       <simpleAuthenticationPlugin>
276         <users>
277           <authenticationUser username="mcollective" password="marionette" groups="mcollective,everyone"/>
278           <authenticationUser username="admin" password="secret" groups="mcollective,admins,everyone"/>
279         </users>
280       </simpleAuthenticationPlugin>
281       <!-- ... authorization goes below... -->
282     </plugins>
283 {% endhighlight %}
284
285 This creates two users, with the expectation that MCollective servers will log in as `mcollective` and admin users issuing commands will log in as `admin`. 
286
287 Note that unless you set up authorization (see below), these users have the exact same capabilities. 
288
289 > #### Shared Configuration
290
291 > MCollective servers and clients both need a username and password to use when connecting. That user **must** have appropriate permissions (see "Authorization," directly below) for that server or client's role. 
292
293
294
295 ### Authorization (Group Permissions)
296
297 By default, ActiveMQ allows everyone to **read** from any topic or queue, **write** to any topic or queue, and create (**admin**) any topic or queue. 
298
299 By setting rules in an `<authorizationPlugin>` element, you can regulate things a bit. Some notes:
300
301 * Authorization is done **by group.**
302 * The exact behavior of authorization doesn't seem to be documented anywhere. Going by observation, it appears that ActiveMQ first tries the most specific rule available, then retreats to less specific rules. This means if a given group isn't allowed an action by a more specific rule but is allowed it by a more general rule, it still gets authorized to take that action. If you have any solid information about how this works, please email us at <faq@puppetlabs.com>.
303 * MCollective creates subscriptions before it knows whether there will be any content coming. That means any role able to **read** from or **write** to a destination must also be able to **admin** that destination. Think of "admin" as a superset of both read and write.
304
305 #### Simple Restrictions
306
307 The following example grants all permissions on destinations beginning with `mcollective` to everyone in group `mcollective`:
308
309 {% highlight xml %}
310     <plugins>
311       <!-- ...authentication stuff... -->
312       <authorizationPlugin>
313         <map>
314           <authorizationMap>
315             <authorizationEntries>
316               <authorizationEntry queue=">" write="admins" read="admins" admin="admins" />
317               <authorizationEntry topic=">" write="admins" read="admins" admin="admins" />
318               <authorizationEntry topic="mcollective.>" write="mcollective" read="mcollective" admin="mcollective" />
319               <authorizationEntry queue="mcollective.>" write="mcollective" read="mcollective" admin="mcollective" />
320               <authorizationEntry topic="ActiveMQ.Advisory.>" read="everyone" write="everyone" admin="everyone"/>
321             </authorizationEntries>
322           </authorizationMap>
323         </map>
324       </authorizationPlugin>
325     </plugins>
326 {% endhighlight %}
327
328 This means admins can issue commands and MCollective servers can read those commands and reply. However, it also means that servers can issue commands, which you probably don't want.
329
330 Note that the `everyone` group (as seen in the `ActiveMQ.Advisory.>` topics) **isn't special.** You need to manually make sure all users are members of it. ActiveMQ does not appear to have any kind of real wildcard "everyone" group, unfortunately.
331
332 #### Detailed Restrictions
333
334 The following example splits permissions along a simple user/server model:
335
336 {% highlight xml %}
337     <plugins>
338       <!-- ...authentication stuff... -->
339       <authorizationPlugin>
340         <map>
341           <authorizationMap>
342             <authorizationEntries>
343               <authorizationEntry queue=">" write="admins" read="admins" admin="admins" />
344               <authorizationEntry topic=">" write="admins" read="admins" admin="admins" />
345               <authorizationEntry queue="mcollective.>" write="admins" read="admins" admin="admins" />
346               <authorizationEntry topic="mcollective.>" write="admins" read="admins" admin="admins" />
347               <authorizationEntry queue="mcollective.nodes" read="mcollective" admin="mcollective" />
348               <authorizationEntry queue="mcollective.reply.>" write="mcollective" admin="mcollective" />
349               <authorizationEntry topic="mcollective.*.agent" read="mcollective" admin="mcollective" />
350               <authorizationEntry topic="mcollective.registration.agent" write="mcollective" read="mcollective" admin="mcollective" />
351               <authorizationEntry topic="ActiveMQ.Advisory.>" read="everyone" write="everyone" admin="everyone"/>
352             </authorizationEntries>
353           </authorizationMap>
354         </map>
355       </authorizationPlugin>
356     </plugins>
357 {% endhighlight %}
358
359 This means admins can issue commands and MCollective servers can read those commands and reply. This time, though, servers can't issue commands. The exception is the `mcollective.registration.agent` destination, which servers DO need the ability to write to if you've turned on registration. 
360
361 Admins, of course, can also read commands and reply, since they have power over the entire `mcollective.>` destination set. This isn't considered much of an additional security risk, considering that admins can already control your entire infrastructure.
362
363 #### Detailed Restrictions with Multiple Subcollectives
364
365 Both of the above examples assume only a single `mcollective` collective. If you are using additional [subcollectives][] (e.g. `uk_collective`, `us_collective`, etc.), their destinations will start with their name instead of `mcollective`. If you need to separately control authorization for each collective, it's best to use a template to do so, so you can avoid repeating yourself. 
366
367 {% highlight xml %}
368     <plugins>
369       <!-- ...authentication stuff... -->
370       <authorizationPlugin>
371         <map>
372           <authorizationMap>
373             <authorizationEntries>
374               <!-- "admins" group can do anything. -->
375               <authorizationEntry queue=">" write="admins" read="admins" admin="admins" />
376               <authorizationEntry topic=">" write="admins" read="admins" admin="admins" />
377
378               <%- @collectives.each do |collective| -%>
379               <authorizationEntry queue="<%= collective %>.>" write="admins,<%= collective %>-admins" read="admins,<%= collective %>-admins" admin="admins,<%= collective %>-admins" />
380               <authorizationEntry topic="<%= collective %>.>" write="admins,<%= collective %>-admins" read="admins,<%= collective %>-admins" admin="admins,<%= collective %>-admins" />
381               <authorizationEntry queue="<%= collective %>.nodes" read="servers,<%= collective %>-servers" admin="servers,<%= collective %>-servers" />
382               <authorizationEntry queue="<%= collective %>.reply.>" write="servers,<%= collective %>-servers" admin="servers,<%= collective %>-servers" />
383               <authorizationEntry topic="<%= collective %>.*.agent" read="servers,<%= collective %>-servers" admin="servers,<%= collective %>-servers" />
384               <authorizationEntry topic="<%= collective %>.registration.agent" write="servers,<%= collective %>-servers" read="servers,<%= collective %>-servers" admin="servers,<%= collective %>-servers" />
385               <%- end -%>
386
387               <authorizationEntry topic="ActiveMQ.Advisory.>" read="everyone" write="everyone" admin="everyone"/>
388             </authorizationEntries>
389           </authorizationMap>
390         </map>
391       </authorizationPlugin>
392     </plugins>
393 {% endhighlight %}
394
395 This example divides your users into several groups:
396
397 * `admins` is the "super-admins" group, who can command all servers.
398 * `servers` is the "super-servers" group, who can receive and respond to commands on any collective they believe themselves to be members of.
399 * `COLLECTIVE-admins` can only command servers on their specific collective. (Since all servers are probably members of the default `mcollective` collective, the `mcollective-admins` group are sort of the "almost-super-admins.")
400 * `COLLECTIVE-servers` can only receive and respond to commands on their specific collective.
401
402 Thus, when you define your users in the [authentication setup](#authentication-users-and-groups), you could allow a certain user to command both the EU and UK collectives (but not the US collective) with `groups="eu_collective-admins,uk_collective-admins"`. You would probably want most servers to be "super-servers," since each server already gets to choose which collectives to ignore.
403
404 #### MCollective's Exact Authorization Requirements
405
406 As described above, any user able to read OR write on a destination must also be able to admin that destination. 
407
408 Topics: 
409
410 - `ActiveMQ.Advisory.>` --- Everyone must be able to read and write. 
411 - `COLLECTIVE.*.agent` --- Admin users must be able to write. Servers must be able to read. 
412 - `COLLECTIVE.registration.agent` --- If you're using registration, servers must be able to read and write. Otherwise, it can be ignored.
413
414 Queues:
415
416 - `COLLECTIVE.nodes` --- Admin users must be able to write. Servers must be able to read.
417 - `COLLECTIVE.reply.>` --- Servers must be able to write. Admin users must be able to read.
418
419
420 > #### Shared Configuration
421
422 > Subcollectives must also be configured in the MCollective client and server config files. If you're setting up authorization per-subcollective, ActiveMQ must allow traffic on any subcollective that MCollective servers and clients expect to use.
423
424
425 ([↑ Back to top](#content))
426
427 Settings for Networks of Brokers
428 -----
429
430 You can group multiple ActiveMQ servers into networks of brokers, and they can route local MCollective traffic amongst themselves. There are a lot of reasons to do this:
431
432 * Scale --- we recommend a maximum of about 800 MCollective servers per ActiveMQ broker, and multiple brokers let you expand past this.
433 * High availability --- MCollective servers and clients can attempt to connect to mupltiple brokers in a failover pool.
434 * Partition resilience --- if an inter-datacenter link goes down, each half's local MCollective system will still work fine.
435 * Network isolation and traffic limiting --- if your clients default to only sending messages to local machines, you can get better performance in the most common case while still being able to command a global collective when you need to. 
436 * Security --- destination filtering can prevent certain users from sending requests to certain datacenters.
437
438 This is naturally more complicated than configuring a single broker.
439
440 Designing your broker network's topology is beyond the scope of this reference. The [ActiveMQ Clusters guide](/mcollective/reference/integration/activemq_clusters.html) has a brief description of an example network; see [the ActiveMQ docs][NetworksOfBrokers] or [the Fuse docs][fuse_cluster] for more detailed info. For our purposes, we assume you have already decided:
441
442 * Which ActiveMQ brokers can communicate with each other.
443 * What kinds of traffic should be excluded from other brokers.
444
445 [NetworksOfBrokers]: http://activemq.apache.org/networks-of-brokers.html
446 [fuse_cluster]: http://fusesource.com/docs/broker/5.5/clustering/index.html
447
448
449 ### Broker Name
450
451 _Required._
452
453 The main `<broker>` element has a `brokerName` attribute. In single-broker deployments, this can be anything and defaults to `localhost`. In a network of brokers, each broker's name must be globally unique across the deployment; duplicates can cause message loops.
454
455 {% highlight xml %}
456     <broker xmlns="http://activemq.apache.org/schema/core" brokerName="uk-datacenter-broker" dataDirectory="${activemq.base}/data" destroyApplicationContextOnStop="true">
457 {% endhighlight %}
458
459 ### OpenWire Transports
460
461 _Required._
462
463 All participants in a network of brokers need OpenWire network transports enabled. [See "Transport Connectors" above](#transport-connectors) for details.
464
465 ### Network Connectors
466
467 _Required._
468
469 If you are using a network of brokers, you need to configure which brokers can talk to each other. 
470
471 On **one** broker in each linked pair, set up **two** bi-directional network connectors: one for topics, and one for queues. (The only difference between them is the `conduitSubscriptions` attribute, which must be false for the queue connector.)  
472
473 This is done with a pair of `<networkConnector>` elements inside the `<networkConnectors>` element. Note that the queues connector excludes topics and vice-versa.
474
475 {% highlight xml %}
476     <networkConnectors>
477       <networkConnector
478         name="stomp1-stomp2-topics"
479         uri="static:(tcp://stomp2.example.com:61616)"
480         userName="amq"
481         password="secret"
482         duplex="true"
483         decreaseNetworkConsumerPriority="true"
484         networkTTL="2"
485         dynamicOnly="true">
486         <excludedDestinations>
487           <queue physicalName=">" />
488         </excludedDestinations>
489       </networkConnector>
490       <networkConnector
491         name="stomp1-stomp2-queues"
492         uri="static:(tcp://stomp2.example.com:61616)"
493         userName="amq"
494         password="secret"
495         duplex="true"
496         decreaseNetworkConsumerPriority="true"
497         networkTTL="2"
498         dynamicOnly="true"
499         conduitSubscriptions="false">
500         <excludedDestinations>
501           <topic physicalName=">" />
502         </excludedDestinations>
503       </networkConnector>
504     </networkConnectors>
505 {% endhighlight %}
506
507 Notes: 
508
509 * If you're using TLS for OpenWire, you'll need to change the URIs to something like `static:(ssl://stomp2.example.com:61617)` --- note the change of both protocol and port. 
510 * You will need to adjust the TTL for your network's conditions.
511 * A username and password are required. The broker with the `<networkConnector>` connects to the other broker as this user. This user should have **full rights** on **all** queues and topics, unless you really know what you're doing. (See [authentication](#authentication-users-and-groups) and [authorization](#authorization-group-permissions) above.)
512 * The `name` attribute on each connector must be globally unique. Easiest way to do that is to combine the pair of hostnames involved with the word "queues" or "topics."
513 * Alternately, you can set up two uni-directional connectors on both brokers; see the Fuse or ActiveMQ documentation linked above for more details. 
514
515
516 ### Destination Filtering
517
518 [fuse_filtering]: http://fusesource.com/docs/broker/5.5/clustering/Networks-Filtering.html
519
520 _Optional._
521
522 Relevant external docs:
523
524 * [Fuse filtering guide][fuse_filtering]
525
526 If you want to prevent certain traffic from leaving a given datacenter, you can do so with `<excludedDestinations>` or `<dynamicallyIncludedDestinations>` elements **inside each `<networkConnector>` element.** This is mostly useful for noise reduction, by blocking traffic that other datacenters don't care about, but it can also serve security purposes. Generally, you'll be filtering on [subcollectives][], which, as described above, begin their destination names with the name of the collective.
527
528 Both types of filter element can contain `<queue>` and `<topic>` elements, with their `physicalName` attributes defining a destination name with the normal wildcards.
529
530 **Remember to retain the all-queues/all-topics exclusions as [shown above](#network-connectors).**
531
532 #### Examples
533
534 Assume a star network topology. 
535
536 This topology can be achieved by either having each edge broker connect to the central broker, or having the central broker connect to each edge broker. You can achieve the same filtering in both situations, but with slightly different configuration. The two examples below have similar but not identical effects; the ramifications are subtle, and we _really_ recommend reading the external ActiveMQ and Fuse documentation if you've come this far in your deployment scale.
537
538 If your central broker is connecting to the UK broker, and you want it to only pass on traffic for the global `mcollective` collective and the UK-specific `uk_collective` collective:
539
540 {% highlight xml %}
541     <dynamicallyIncludedDestinations>
542       <topic physicalName="mcollective.>" />
543       <queue physicalName="mcollective.>" />
544       <topic physicalName="uk_collective.>" />
545       <queue physicalName="uk_collective.>" />
546     </dynamicallyIncludedDestinations>
547 {% endhighlight %}
548
549 In this case, admin users connected to the central broker can command nodes on the `uk_collective`, but admin users connected to the UK broker can't command nodes on the `us_collective`, etc. 
550
551 Alternately, if your UK broker is connecting to your central broker and you want it to refrain from passing on UK-specific traffic that no one outside that datacenter cares about:
552
553 {% highlight xml %}
554     <excludedDestinations>
555        <topic physicalName="uk_collective.>" />
556        <queue physicalName="uk_collective.>" />
557     </excludedDestinations>
558 {% endhighlight %}
559
560 In this case, admin users connected to the central broker **cannot** command nodes on the `uk_collective`; it's expected that they'll be issuing commands to the main `mcollective` collective if they need to (and are authorized to) cross outside their borders. 
561
562 ([↑ Back to top](#content))
563
564 Tuning
565 -----
566
567 The minor adjustments listed below (turn off dedicated task runner, increase heap, and increase memory and temp usage in activemq.xml) will generally let you reach about 800 MCollective nodes connected to a single ActiveMQ server, depending on traffic and usage patterns, number of topics and queues, etc. Any more detailed tuning is beyond the scope of this reference, and is likely to be unnecessary for your deployment. 
568
569 ### Don't Use Dedicated Task Runner
570
571 Set `-Dorg.apache.activemq.UseDedicatedTaskRunner=false` when starting ActiveMQ. MCollective creates a lot of queues and topics, so _not_ using a thread per destination will save you a lot of memory usage.
572
573 This setting is **not** configured in activemq.xml; it's an extra argument to the JVM, which should be provided when ActiveMQ starts up. The place to put this varies, depending on the package you installed ActiveMQ with; it usually goes in the wrapper config file. Check your init script for clues about this file's location. With the common TanukiWrapper scripts, it would look something like this:
574
575     wrapper.java.additional.4=-Dorg.apache.activemq.UseDedicatedTaskRunner=false
576
577 ### Increase JVM Heap if Necessary
578
579 Likewise, the max heap is usually configured in the wrapper config file (`wrapper.java.maxmemory=512`) or on the command line (`-Xmx512m`).
580
581 ### Memory and Temp Usage for Messages (`systemUsage`)
582
583 Since ActiveMQ expects to be embedded in another JVM application, it won't automatically fill up the heap with messages; it has extra limitations on how much space to take up with message contents. 
584
585 As your deployment gets bigger, you may need to increase the `<memaryUsage>` and `<tempUsage>` elements in the `<systemUsage>` element. Unfortunately, we lack a lot of solid data for what to actually set these to. Most users leave the defaults for memory and temp until they have problems, then double the defaults and see whether their problems go away. This isn't perfectly effecient, but anecdotally it appears to work.
586
587 The many redundant nested elements are not a typo; for some reason, ActiveMQ seems to require this.
588
589 {% highlight xml %}
590     <!--
591       The systemUsage controls the maximum amount of space the broker will 
592       use for messages.
593
594       - memoryUsage is the amount of memory ActiveMQ will take up with
595         *actual messages;* it doesn't include things like thread management.
596       - tempUsage is the amount of disk space it will use for stashing
597         non-persisted messages if the memoryUsage is exceeded (e.g. in the
598         event of a sudden flood of messages).
599       - storeUsage is the amount of disk space dedicated to persistent
600         messages (which MCollective doesn't use directly, but which may be
601         used in networks of brokers to avoid duplicates).           
602
603       If producer flow control is on, ActiveMQ will slow down producers
604       when any limits are reached; otherwise, it will use up the
605       memoryUsage, overflow into tempUsage (assuming the default cursor
606       settings aren't changed), and start failing message deliveries after
607       tempUsage is spent. In MCollective, the latter behavior is generally
608       preferable. For more information, see:
609
610       http://activemq.apache.org/producer-flow-control.html
611       http://activemq.apache.org/javalangoutofmemory.html
612     -->
613     <systemUsage>
614         <systemUsage>
615             <memoryUsage>
616                 <memoryUsage limit="20 mb"/>
617             </memoryUsage>
618             <storeUsage>
619                 <storeUsage limit="1 gb"/>
620             </storeUsage>
621             <tempUsage>
622                 <tempUsage limit="100 mb"/>
623             </tempUsage>
624         </systemUsage>
625     </systemUsage>
626 {% endhighlight %}
627
628
629 ([↑ Back to top](#content))
630
631 Boilerplate
632 -----
633
634 There's little reason to care about these settings in most conditions, but they're in the example config files anyway.
635
636 ### Persistence
637
638 MCollective rarely uses this. It's only necessary in networks of brokers, where it is used to prevent routing loops. Leave it enabled; it has no notable performance penalty and its disk usage is limited by the `<storeUsage>` element described above.
639
640 {% highlight xml %}
641     <persistenceAdapter>
642       <kahaDB directory="${activemq.base}/data/kahadb"/>
643     </persistenceAdapter>
644 {% endhighlight %}
645  
646 ### Management Context
647
648 This is for monitoring. MCollective doesn't use this and the examples have it turned off, but you may want it for your own purposes.
649
650 {% highlight xml %}
651     <!-- 
652       The managementContext is used to configure how ActiveMQ is exposed in 
653       JMX. By default, ActiveMQ uses the MBean server that is started by 
654       the JVM. For more information, see: 
655     
656       http://activemq.apache.org/jmx.html 
657     -->
658
659     <managementContext>
660       <managementContext createConnector="false"/>
661     </managementContext>
662 {% endhighlight %}
663
664 ### Statistics Broker
665
666 MCollective doesn't use this.
667
668 {% highlight xml %}
669     <plugins>
670       <!--
671         Enable the statisticsBrokerPlugin to allow ActiveMQ to collect
672         statistics.
673       -->
674       <statisticsBrokerPlugin/>
675       <!-- ...auth, etc... -->
676     </plugins>
677 {% endhighlight %}
678
679
680 ### Jetty (Web Consoles, APIs, etc.)
681
682 The activemq.xml file will often either contain Jetty settings or import them from another file. MCollective doesn't use this. If you're not using it to manage ActiveMQ, leaving it enabled may be a security risk. Note that this configuration is **outside** the `<broker>` element. 
683
684 {% highlight xml %}
685     <!-- 
686       Enable web consoles, REST and Ajax APIs and demos
687       It also includes Camel (with its web console), see ${ACTIVEMQ_HOME}/conf/camel.xml for more info
688         
689       Take a look at ${ACTIVEMQ_HOME}/conf/jetty.xml for more details 
690     -->
691     <import resource="jetty.xml"/>
692 {% endhighlight %}
693
694 ([↑ Back to top](#content))