| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd"> |
| <!-- |
| 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. |
| Architecture |
| --> |
| <html lang="en"> |
| <head> |
| <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> |
| <meta content="ActiveMQ's next generation of messaging" name="description"/> |
| <meta content="messaging,stomp,jms,activemq,apollo" name="keywords"/> |
| <meta content="Apollo" name="author"/> |
| <script src="../scripts/jquery.js"></script> |
| <link type="text/css" rel="stylesheet" href="../styles/impact/css/pygmentize.css"/> |
| <link type="text/css" rel="stylesheet" href="../styles/impact/css/site.css"/> |
| <title></title> |
| </head> |
| <body> |
| <div id="navigation"> |
| <div class="wrapper"> |
| <ul> |
| <li><a href="../index.html">Apollo 1.7.1</a></li> |
| <li><a href="../community/developers.html">Developers</a></li> |
| <li><a href="../community/index.html">Community</a></li> |
| <li><a href="../download.html">Download</a></li> |
| </ul> <div></div> |
| </div> |
| </div> |
| <div id="content"> |
| <div class="wrapper"> |
| <h1 id = "Apollo_1_7_1_Extending_Guide">Apollo 1.7.1 Extending Guide</h1> |
| |
| <p><div class="toc"><ul style="list-style:none;"> |
| <li><a href="#Overview">Overview</a></li> |
| <li><ul style="list-style:none;"> |
| <li><a href="#Adding_your_Extensions_to_the_Apollo_Class_Path">Adding your Extensions to the Apollo Class Path</a></li> |
| <li><a href="#Extension_Discovery">Extension Discovery</a></li> |
| <li><a href="#Extending_the_Data_Model">Extending the Data Model</a></li> |
| <li><ul style="list-style:none;"> |
| <li><a href="#Polymorphic_Data_Configuraiton_objects_Objects">Polymorphic Data/Configuraiton objects Objects</a></li> |
| </ul></li> |
| <li><a href="#Using_a_custom__code_VirtualHost__code__implementation">Using a custom <code>VirtualHost</code> implementation</a></li> |
| <li><a href="#Plugging_into_the_Broker_Lifecycle">Plugging into the Broker Lifecycle</a></li> |
| </ul></li> |
| </ul></div></p> |
| |
| <h2 id = "Overview">Overview</h2> |
| |
| <p>Apollo support being extended in several ways. This guide documents |
| all the supported extension points.</p> |
| |
| <h3 id = "Adding_your_Extensions_to_the_Apollo_Class_Path">Adding your Extensions to the Apollo Class Path</h3> |
| |
| <p>Just create a <code>.jar</code> out of out code and add it to the <code>${apollo.home}/lib</code> |
| directory. When Apollo restarts it will add the new jar to it's class path.</p> |
| |
| <h3 id = "Extension_Discovery">Extension Discovery</h3> |
| |
| <p>Apollo discovers your extensions by looking for extension resource files in |
| all the jar files in it's classpath. For example, the <code>apollo-broker</code> jar |
| file contains the following a resource file <code>META-INF/services/org.apache.activemq.apollo/protocol-codec-factory.index</code> |
| It contains the class names of the protocol codec factories that are implemented |
| in the <code>broker-core</code> module. It's contents are:</p> |
| |
| <pre><code>org.apache.activemq.apollo.broker.protocol.AnyProtocolFactory |
| org.apache.activemq.apollo.broker.protocol.UdpProtocolFactory |
| org.apache.activemq.apollo.broker.protocol.RawProtocolFactory</code></pre> |
| |
| <p>All three of the the listed classes implement the <a href="api/apollo-broker/index.html#org.apache.activemq.apollo.broker.protocol.ProtocolFactory"><code>ProtocolFactory</code></a> |
| interface. Here's a list of extension points supported by Apollo:</p> |
| |
| <ul> |
| <li><p>Data Model: <code>META-INF/services/org.apache.activemq.apollo/dto-module.index</code> → |
| <a href="api/apollo-util/index.html#org.apache.activemq.apollo.util.DtoModule"><code>org.apache.activemq.apollo.util.DtoModule</code></a></p></li> |
| <li><p>Transports: <code>META-INF/services/org.apache.activemq.apollo/transport-factory.index</code> → |
| <a href="api/apollo-broker/index.html#org.apache.activemq.apollo.broker.transport.TransportFactory$$Provider"><code>org.apache.activemq.apollo.broker.transport.TransportFactory.Provider</code></a></p></li> |
| <li><p>Protocols: <code>META-INF/services/org.apache.activemq.apollo/protocol-factory.index</code> → |
| <a href="api/apollo-broker/index.html#org.apache.activemq.apollo.broker.protocol.ProtocolFactory"><code>org.apache.activemq.apollo.broker.protocol.ProtocolFactory</code></a></p></li> |
| <li><p>Broker Factories: <code>META-INF/services/org.apache.activemq.apollo/broker-factory.index</code> → |
| <a href="api/apollo-broker/index.html#org.apache.activemq.apollo.broker.BrokerFactoryTrait"><code>org.apache.activemq.apollo.broker.BrokerFactoryTrait</code></a></p></li> |
| <li><p>Connectors: <code>META-INF/services/org.apache.activemq.apollo/connector-factory.index</code> → |
| <a href="api/apollo-broker/index.html#org.apache.activemq.apollo.broker.ConnectorFactory"><code>org.apache.activemq.apollo.broker.ConnectorFactory</code></a></p></li> |
| <li><p>Virtual Hosts: <code>META-INF/services/org.apache.activemq.apollo/virtual-host-factory.index</code> → |
| <a href="api/apollo-broker/index.html#org.apache.activemq.apollo.broker.VirtualHostFactory"><code>org.apache.activemq.apollo.broker.VirtualHostFactory</code></a></p></li> |
| <li><p>Route Listeners: <code>META-INF/services/org.apache.activemq.apollo/router-listener-factory.index</code> → |
| <a href="api/apollo-broker/index.html#org.apache.activemq.apollo.broker.RouterListenerFactory"><code>org.apache.activemq.apollo.broker.RouterListenerFactory</code></a></p></li> |
| <li><p>Stores: <code>META-INF/services/org.apache.activemq.apollo/store-factory.index</code> → |
| <a href="api/apollo-broker/index.html#org.apache.activemq.apollo.broker.store.StoreFactory"><code>org.apache.activemq.apollo.broker.store.StoreFactory</code></a></p></li> |
| <li><p>Web Admin Components: <code>META-INF/services/org.apache.activemq.apollo/web-module.index</code> → |
| <code>org.apache.activemq.apollo.web.WebModule</code></p></li> |
| <li><p>Web Servers → <code>META-INF/services/org.apache.activemq.apollo/web-server-factory.index</code>→ |
| <a href="api/apollo-broker/index.html#org.apache.activemq.apollo.broker.web.WebServerFactory"><code>org.apache.activemq.apollo.broker.web.WebServerFactory</code></a></p></li> |
| </ul> |
| |
| <!-- These might go away... |
| * `META-INF/services/org.apache.activemq.apollo/binding-factory.index`: |
| `org.apache.activemq.apollo.broker.BindingFactory` |
| * `META-INF/services/org.apache.activemq.apollo/protocol-codec-factory.index` : |
| `org.apache.activemq.apollo.broker.protocol.ProtocolCodecFactory.Provider` |
| --> |
| |
| <h3 id = "Extending_the_Data_Model">Extending the Data Model</h3> |
| |
| <p>If you want to extend the Apollo xml configuration model to understand some |
| custom JAXB object you have defined in your own packages, then you need |
| to implement a <code>Module</code> class and then create a <code>META-INF/services/org.apache.activemq.apollo/dto-module.index</code> |
| resource file in which you list it's class name.</p> |
| |
| <p>Example module class:</p> |
| |
| <div class="syntax"><pre name='code' class='brush: scala; gutter: false;'><code> |
| package org.example |
| import org.apache.activemq.apollo.util.DtoModule |
| |
| class Module extends DtoModule { |
| |
| def dto_package = "org.apache.activemq.apollo.broker.store.leveldb.dto" |
| def extension_classes = Array(classOf[LevelDBStoreDTO], classOf[LevelDBStoreStatusDTO]) |
| |
| } |
| </code></pre></div> |
| |
| <p>Example <code>META-INF/services/org.apache.activemq.apollo/dto-module.index</code> resource:</p> |
| |
| <pre><code>org.example.Module</code></pre> |
| |
| <h4 id = "Polymorphic_Data_Configuraiton_objects_Objects">Polymorphic Data/Configuraiton objects Objects</h4> |
| |
| <p>The following objects in the Apollo data model can be extended:</p> |
| |
| <ul> |
| <li><a href="api/apollo-dto/org/apache/activemq/apollo/dto/VirtualHostDTO.html"><code>VirtualHostDTO</code></a></li> |
| <li><a href="api/apollo-dto/org/apache/activemq/apollo/dto/ConnectorTypeDTO.html"><code>ConnectorTypeDTO</code></a></li> |
| <li><a href="api/apollo-dto/org/apache/activemq/apollo/dto/ConnectionStatusDTO.html"><code>ConnectionStatusDTO</code></a></li> |
| <li><a href="api/apollo-dto/org/apache/activemq/apollo/dto/ProtocolDTO.html"><code>ProtocolDTO</code></a></li> |
| <li><a href="api/apollo-dto/org/apache/activemq/apollo/dto/StoreDTO.html"><code>StoreDTO</code></a></li> |
| <li><a href="api/apollo-dto/org/apache/activemq/apollo/dto/StoreStatusDTO.html"><code>StoreStatusDTO</code></a></li> |
| </ul> |
| |
| <!-- Not sure we should expose this one... |
| * [`DestinationDTO`](api/apollo-dto/org/apache/activemq/apollo/dto/DestinationDTO.html) |
| --> |
| |
| <h3 id = "Using_a_custom__code_VirtualHost__code__implementation">Using a custom <code>VirtualHost</code> implementation</h3> |
| |
| <p>Virtual hosts control the lifescycle of destinations and how producers |
| and consumers are connected to those destinations. You can subclass the |
| default virtual host implemenation to override the default behaviour |
| that Apollo provides.</p> |
| |
| <p>To create your own VirtualHost extension, you first extend the <a href="api/apollo-broker/index.html#org.apache.activemq.apollo.broker.VirtualHost"><code>org.apache.activemq.apollo.broker.VirtualHost</code></a> class and override it's implemenation suite your needs. Example:</p> |
| |
| <pre><code>package example; |
| class MyVirtualHost(broker: Broker, id:String) extends VirtualHost(broker, id) { |
| // ... todo: override |
| }</code></pre> |
| |
| <p>Then, to allow an <code>apollo.xml</code> configration file you your extended version of the virtual host you need to |
| extend the <a href="api/apollo-dto/org/apache/activemq/apollo/dto/VirtualHostDTO.html"><code>VirtualHostDTO</code></a> class to define |
| a new XML emlement for your new virtual host type. </p> |
| |
| <pre><code>package example; |
| @XmlRootElement(name = "my_virtual_host") |
| @XmlAccessorType(XmlAccessType.FIELD) |
| class MyVirtualHostDTO extends VirtualHostDTO { |
| // example config attribute |
| @XmlAttribute(name="trace") |
| public Boolean trace; |
| }</code></pre> |
| |
| <p>Since this is extending the data model, we follow the direction in the |
| <a href="#Extending_the_Data_Model">'Extending the Data Model'</a> section of this guide and add a |
| <code>Module</code> class:</p> |
| |
| <pre><code>package example; |
| class Module extends DtoModule { |
| def dto_package = "example" |
| def extension_classes = Array(classOf[MyVirtualHostDTO]) |
| }</code></pre> |
| |
| <p>and a <code>META-INF/services/org.apache.activemq.apollo/dto-module.index</code> resource file containing:</p> |
| |
| <pre><code>example.Module</code></pre> |
| |
| <p>Now that we can define an XML element to configure the custom virtual host and create it, |
| lets define a factory class which will be used to create a <code>MyVirtualHost</code> when a <code><my_virtual_host></code> |
| xml element is used in the configuration file:</p> |
| |
| <pre><code>package example; |
| object MyVirtualHostFactory extends VirtualHostFactory { |
| |
| def create(broker: Broker, dto: VirtualHostDTO): VirtualHost = dto match { |
| case dto:MyVirtualHostDTO => |
| val rc = new MyVirtualHostDTO(broker, dto.id) |
| rc.config = dto |
| rc |
| case _ => null |
| } |
| }</code></pre> |
| |
| <p>and a <code>META-INF/services/org.apache.activemq.apollo/virtual-host-factory.index</code> resource file containing:</p> |
| |
| <pre><code>example.MyVirtualHostFactory</code></pre> |
| |
| <h3 id = "Plugging_into_the_Broker_Lifecycle">Plugging into the Broker Lifecycle</h3> |
| |
| <p>You can implement custom <a href="api/apollo-util/index.html#org.apache.activemq.apollo.util.Service">Service</a> |
| objects which get started / stopped when |
| the broker starts and stops. Once you have packaged your custom |
| service, and added it to the Apollo class path, you can |
| update the <code>apollo.xml</code> to add the service so it gets started when |
| apollo starts:</p> |
| |
| <div class="syntax"><pre name='code' class='brush: xml; gutter: false;'><code> |
| <service id='myservice' kind='org.example.MyService'/> |
| </code></pre></div> |
| |
| <p>The <code>id</code> attribute is a unique service name of your service, and the |
| <code>kind</code> attribute is the class name of your service. </p> |
| |
| <p>If your service needs a reference to the Broker object which is running |
| in, add the following field definition to your class:</p> |
| |
| <div class="syntax"><pre name='code' class='brush: scala; gutter: false;'><code> |
| var broker:Broker = null |
| </code></pre></div> |
| |
| <p>The broker instance will be injected into your class instance before it gets |
| started.</p> |
| |
| <p>Your service can also get reference to to the configuration element used |
| to define it if it defines the following field.</p> |
| |
| <div class="syntax"><pre name='code' class='brush: scala; gutter: false;'><code> |
| var config: CustomServiceDTO |
| </code></pre></div> |
| |
| <p>This field will also get injected before getting started. The <code>CustomServiceDTO.other</code> |
| field will contain any additional configuration elements defined within service |
| element. For example, if you configured the service as follows:</p> |
| |
| <div class="syntax"><pre name='code' class='brush: xml; gutter: false;'><code> |
| <service id='myservice' kind='org.example.MyService'/> |
| <options xmlns="http://example.org/myservice"> |
| <search>google.com</search> |
| </options> |
| </service> |
| </code></pre></div> |
| |
| <p>Then you could access the options DOM element using:</p> |
| |
| <div class="syntax"><pre name='code' class='brush: scala; gutter: false;'><code> |
| val options = config.other.get(1).asInstanceOf[Element] |
| </code></pre></div> |
| |
| <p>If you had defined JAXB object mappings for the <code><options></code> class |
| then <code>config</code> will hold that object instead of generic |
| DOM <code>Element</code>.</p> |
| <div></div> |
| </div> |
| </div> |
| </body> |
| </html> |