Destinations can be configured in a configuration file or defined at run-time using the API provided by WebORB. These destinations are called dynamic as the client may have no prior knowledge about them. Dynamic destinations provide a lot of flexibility enabling both hub-and-spoke as well as point-to-point message distribution paradigms. Destinations can be created either in-process by invoking the API factory methods directly or out-of-process via remote method invocation.
The class containing the factory methods for creating dynamic destinations is weborb.management.messaging.DestinationFactory. For in-process invocations use the default class constructor to create an instance of the class. Available methods are:
public String createMessagingDestination( String name ) throws Exception
where:
name - the name of the dynamic destination to create.
Return value: the method returns the name of the created destination. This is the same value as the name argument.
The method throws an exception if an internal error occurs.
public String createMessagingDestination( String name, String serviceHandlerClassName ) throws Exception
where:
name - the name of the dynamic destination to create.
serviceHandlerClassName - the name of the messaging service handler class to associate with the created destination. The class must be an implementation of the weborb.v3types.core.IServiceHandler interface. The following implementations are included with WebORB:
weborb.messaging.v3.MessagingServiceHandler - used for WebORB internal message routing on a single (non-clustered) computer.
weborb.messaging.v3.cluster.WeborbClusterServiceHandler - used for WebORB internal message routing in a clustered environment. See Clustered Publish/Subscribe Messaging for additional information.
Return value: the method returns the name of the created destination. This is the same value as the name argument.
The method throws an exception if an internal error occurs.
public String createJMSMessagingDestination( String name ) throws Exception
where:
name - the name of the dynamic destination to create.
Creates a dynamic destination which uses the JMS Message Routing. Destinations created using this method contain the following properties:
transacted-sessions - false
acknowledge-mode - AUTO_ACKNOWLEDGE
delivery-mode - NOT_PERSISTENT
message-priority - 6
Return value: the method returns the name of the created destination. This is the same value as the name argument.
The method throws an exception if an internal error occurs.
public void removeDestination( String name ) throws ConfigException
where:
name - the name of the dynamic destination to remove.
The method throws an exception if an internal error occurs.
public List<MessagingDestination> getDynamicDestinations()
Returns a list of dynamic destinations registered with the instance of WebORB.
Publishing/Subscribing to a Dynamic Destination
All client types except for Flex/AIR can publish/subscribe to a dynamic destination using the same API as with a statically defined one. See the Subscribing to a Destination section for coding samples. The Flex/AIR must use a slightly modified approach. The reason is with the statically defined destinations, Flex/AIR applications embed destination information (endpoint URI, etc) at the compile time. As a result, the same API for publishing/subscribing to a dynamic destination will not work. Consider the following sample of creating a Flex/AIR producer and consumer objects with a dynamic destination:
private function destinationCreated( evt:ResultEvent ):void
{
consumer = new Consumer();
consumer.destination = evt.result as String;
// for AMF destinations, create the AMFChannel. weborb.wo is a relative URL in the
// line below, alternatively, it could be an absolute URL
//var channel:AMFChannel = new AMFChannel( "custom-amf-channel", "weborb.wo" );
// for RTMP destinations, create WeborbMessagingChannel - you need to add weborb.swc into the Flash Build Path of the project
var channel:WeborbMessagingChannel = new WeborbMessagingChannel( "custom-rtmp-channel", "rtmp://localhost/root" );
var channelSet:ChannelSet = new ChannelSet();
channelSet.addChannel( channel );
consumer.channelSet = channelSet;
consumer.addEventListener( MessageEvent.MESSAGE, gotMessage );
consumer.subscribe();
producer = new Producer();
producer.destination = evt.result as String;
producer.channelSet = channelSet;
}
Low Level Destination Factory API
The factory methods described above may not provide the flexibility needed when constructing a dynamic destination. This section documents the low level APIs which can be used to construct a dynamic destination to achieve maximum flexibility specifically with the properties assigned to it. Consider the following example demonstrating the usage of the API registering a dynamic destination:
package demo.messaging.destination;
import weborb.ORBConstants;
import weborb.config.FlexMessagingServiceConfig;
import weborb.config.ORBConfig;
import weborb.config.ORBServerConfig;
import weborb.management.messaging.FlexMessagingDestination;
import weborb.messaging.v3.MessagingDestination;
import weborb.messaging.v3.MessagingServiceHandler;
import weborb.v3types.core.DataServices;
import java.util.Hashtable;
public class DestinationFactory
{
public String createMessagingDestination( String name ) throws Exception
{
// create destination object. This is as basic as it gets, constructor with the destination name
MessagingDestination destination = new MessagingDestination( name );
// setup the most basic properties - the name of the class handling subscriptions and publications
// and a class where the messages are stored until they are retrieved by the consumers.
Hashtable properties = new Hashtable();
properties.put( ORBConstants.MESSAGE_STORAGE_POLICY, "weborb.messaging.v3.MemoryStoragePolicy" );
properties.put( ORBConstants.MESSAGE_SERVICE_HANDLER, "weborb.messaging.v3.MessagingServiceHandler" );
// register properties
destination.setProperties( properties );
// initialize handler from the properties
destination.setConfigServiceHandler();
// register the destination
DataServices dataServices = ORBConfig.getORBConfig().getDataServices();
dataServices.getDestinationManager().addDestination( name, destination );
// REGISTERING THE DESTINATION SO IT IS VISIBLE IN THE MANAGEMENT CONSOLE
// The following two lines are needed if you would like the destination
// to appear in the management console, therefore the code below is optional
// set the channel name, so the console knows how to connect to the destination in the "Test Drive" mode.
destination.setChannelName( "my-polling-amf" );
FlexMessagingServiceConfig serviceConfig = ORBServerConfig.getFlexMessagingServiceConfig();
serviceConfig.addFlexMessagingDestination( FlexMessagingDestination.getDestinationScope( destination ) );
return name;
}
}
The process of creating a dynamic destination using the low-level APIs consists of the following steps:
| 1. | Add weborb.jar to the classpath of your project |
| 2. | Create an instance of weborb.messaging.v3.MessagingDestination. The name of the destination must be passed into the constructor of the class. |
| 3. | Create an instance of java.util.Hashtable which will contain the properties of the destination. |
| 4. | For the WebORB's Internal Message Routing, set the following properties in the hashtable object created in step 3 (see the sample code above): key: weborb.ORBConstants.MESSAGE_SERVICE_HANDLER value: "weborb.messaging.v3.MessagingServiceHandler" key: weborb.ORBConstants.MESSAGE_STORAGE_POLICY value: "weborb.messaging.v3.MemoryStoragePolicy" |
| 5. | For JMS Message Routing, the property should be configured as shown in the code below. Hashtable jmsProperties = new Hashtable(); // the value corresponding to the <transacted-sessions> element in a statically defined destination jmsProperties.put( ORBConstants.TRANSACTED_SESSIONS, "false" ); // the value corresponding to the <acknowledge-mode> element in a statically defined destination jmsProperties.put( ORBConstants.ACKNOWLEDGE_MODE, "AUTO_ACKNOWLEDGE" ); // the value corresponding to the <message-factory> element in a statically defined destination jmsProperties.put( ORBConstants.MESSAGE_HANDLER, "weborb.messaging.v3.jms.JmsObjectMessageFactory" ); // optional. the value corresponding to the <delivery-mode> element in a statically defined destination jmsProperties.put( ORBConstants.DELIVERY_MODE, "NOT_PERSISTENT" ); // optional. the value corresponding to the <message-priority> element in a statically defined destination jmsProperties.put( ORBConstants.MESSAGE_PRIORITY, "6" ); // create the top level properties object. This is the object which must be registered with the destination Hashtable properties = new Hashtable(); // the properties defined above MUST be mapped to the "jms" key. properties.put( "jms", jmsProperties ); // register JMS message handler: properties.put( ORBConstants.MESSAGE_SERVICE_HANDLER, "weborb.messaging.v3.jms.JmsServiceHandler" ); |
| 6. | Register the properties with the destination object. destination.setProperties( properties ); |
| 7. | Register the destination with the WebORB Data Services engine: DataServices dataServices = ORBConfig.getORBConfig().getDataServices(); dataServices.getDestinationManager().addDestination( name, destination ); |
| 8. | Optional: By default the destination does not appear in the console. There is an additional step to register a dynamic destination so it can be managed from the console: // set the channel name. This is the channel the console will use to communicate with the destination in the Test Drive mode. destination.setChannelName( "my-polling-amf" ); FlexMessagingServiceConfig serviceConfig = ORBServerConfig.getFlexMessagingServiceConfig(); serviceConfig.addFlexMessagingDestination( FlexMessagingDestination.getDestinationScope( destination ) ); |