public abstract class TopicOrientedApplication extends Object implements MessageSender, MessageInjector
Hornet's primary function is to simplify application with a rich topic space by mapping messages to message channels
via configuration rather than via application code. To accomplish this a light weight xml 'service' schema (x-tsml) is
used that allows the mapping of message types to a channel. Each message may be mapped to a single channel, though several message may
map to the same channel.
The simplest usage of Hornet is for an application to configure a single bus with the same
name as the application that specifies only the provider and connection details. The channel definitions and the messages that
flow over them will be provided by service definitions returned by the application's ServiceDefinitionLocator.
Messages will be sent on the channel that the message type is mapped to, and subscription are issued on the channel if
there is a message handler for a type mapped to it.
Using these service definitions a Hornet application:
sent without specifying a message channel (the service defined
mapping indicates the channel to use).
join the channel
to which the message is mapped.
To perform the mapping the set of services is solicited from the application via a ServiceDefinitionLocator.
The services are then iterated in 2 passes:
Note: If two services map the same message to a different channel, the last mapping iterated is the one used for sending messages .
If the key is not null and a ChannelInitialKeyResolutionTableProvider returns a key
resolution table for the channel then it will be used to resolve variable portions of the key
up front.
Qos of the channel is initially
set to value predefined via the initial configuration in DDL if the channel is preconfigured.
If the channel is not specified in configuration the MessageChannel.Qos is set to MessageChannel.Qos.Guaranteed.
If any ChannelQosProvider returns a Qos for the channel then that Qos will be used
for the channel and if two providers return different Qos values the the highest Qos (Guaranteed) will
be used. See ChannelQosProvider for specifics.
Note: some binding implementations may require both the sending and receiving parties use
the same Qos for a channel (for example the loopback and direct bus implementations). Therefore care
must be taken when using ChannelQosProviders to ensure that the same Qos is elected across applications.
joined if the application has an EventHandler
annotated method for a type that was determined to map to the channel for the service in the first
pass above.
If any ChannelJoinProvider returns a non Default TopicOrientedApplication.ChannelJoin value for the channel then it will
determine whether or not the channel is joined. It is not legal for two providers to return a different value.
See ChannelJoinProvider.getChannelJoin(..) for additional specifics.
If there isn't a handler for the message and no ChannelJoinProvider returns a
value, but the channel is pre-configured for the application via DDL configuration then the preconfigured
value for join will be used. In summary, the precedence for determining channel join is as follows:
Default join value.
If any ChannelFilterProvider returns a channel filter that filter will be used to filter the join
in the event that the application joins the channel. It is not legal for two providers to return a different value.
See ChannelFilterProvider.getChannelFilter(..) for additional details.
If no channel filter provider returns a filter, but one is pre-configured via DDL configuration that filter will be used, otherwise no channel filter will be defined.
Mapping Channels to Buses:
If the channel definition in the service doesn't declare a bus, the bus name defaults to a bus with the
same name as the application being configured. This means that applications may simply configure a single bus
with the same name as the application via DDL configuration and rely on Hornet to fill in the channel definitions
based on those discovered in services.
If multiple message buses are needed, then well named buses must be defined via DDL configuration that match those named in services.
Message Factory Registration
Rumi requires that messages being received from a message bus or written to a transaction log have
their corresponding factories registered with the runtime to allow the message to be deserialized. Hornet
will automatically register factories for ADM generated messages that are declared in a service or are
discovered in an application exposed message handler.
Application designers must ensure that no unknown messages types flow on the channels that are joined
by the application or it will result in the emission of UnhandledMessageEvents as the unrecognized
messages are received. This scenario is at best inefficient, and at worst can cause unintended acknowledgment of
of messages that are not processed by the application
SrvAppLoader into a AppInjectionPoint annotated method to let the application first see the server and its SrvConfigAppDescriptor.
The SrvAppLoader provides the application with the ability to inspect the identity of the server in which it is being launched.
AppInjectionPoint for SrvAppLoader,
subclasses can instead override onAppLoaderInjected(SrvAppLoader).
AepEngineDescriptor into an AppInjectionPoint annotated method to let the app customize its AepEngine. The application may
augment the AepEngineDescriptor, and to inspect the configuration of the application being launched.
AppInjectionPoint for AepEngineDescriptor,
subclasses can instead override onEngineDescriptorInjected(AepEngineDescriptor).
getManagedObjectLocator() and call its ManagedObjectLocator.locateManagedObjects(Set) method to find objects that expose
Command, AppStat, Configured or EventHandler annotations.
Configured configuration injection on the set of objects returned by the ManagedObjectLocator.
getServiceDefinitionLocator() and invoke its ServiceDefinitionLocator.locateServices(Set). TopicOrientedApplication parses the
service models returned by the ServiceDefinitionLocator and maps service defined messages to channels. Based on interest defined by the application's
EventHandlers determines which channels to join.
onConfigured(). At this point the application can call getServiceModels() or getServiceModel(String) to examine the parsed
service model.
AppStateFactoryAccessor annotated method to retrieve the application's state factory (for use with state replication engines).
AepEngineDescriptor, IAepApplicationStateFactory, and EventHandlers, registering the
SrvAppLoader as a IAepWatcher for the engine.
AepEngine into a AppInjectionPoint annotated method to provide the application access to its AepEngine.
AppInjectionPoint for AepEngine,
subclasses can instead override onEngineInjected(AepEngine). In most cases, the application should not use the AepEngine directly and instead use the
corresponding facilities provided by TopicOrientedApplication (MessageSender, MessageInjector, EngineClock etc).
AppStat. This implies that by the time the call to onEngineInjected(AepEngine) returns,
all application defined stats should have been constucted by the application.
onAppInitialized() to indicate that the applications has been successfully initialized.
TopicOrientedApplication utilizes the AppInitializer annotation to implement this, applications must not use the AppInitializer
annotation.
AppMain annotation, spin up Main Thread for the application when the AepEngine becomes Primary and invoke it.
For an application that is responsive (i.e. reacts to messages), an application may register additional Aep LifecycleEvent EventHandlers to
respond to various application lifecycle events (see link below)
onAppFinalized() method on the app and join its AppMainn thread if started.
TopicOrientedApplication utilizes the AppFinalizer annotation to implement this, applications must not use the AppInitializer
annotation.
AepEngine lifecycle, see
X Application Lifecycle)
TopicOrientedApplication class reserves usage of several AepEngine features for its own use. For the most part this allows it to implement
the lifecycle describer above, and in some cases it allows functionality that extends that supported by Rumi.
TopicOrientedApplication reserves the sole right to set AepEngine.setPredispatchMessageHandler(IAepPredispatchMessageHandler).
Applications may register delegate handlers via addPredispatchMessageHandler(IAepPredispatchMessageHandler).
TopicOrientedApplication reserves the sole right to set AepEngine.setPostdispatchMessageHandler(IAepPostdispatchMessageHandler).
Applications may register delegate handlers via addPostdispatchMessageHandler(IAepPostdispatchMessageHandler).
AppInjectionPointTopicOrientedApplication currently implements these injection points, Subclasses may
override the following methods instead:
AppInitializer, use onAppFinalized()
AppFinalizer, use onAppFinalized()
AppEventHandlerContainersAccessor, @AppStatContainersAccessor, AppConfiguredAccessor and @AppCommandHandlerContainersAccessorTopicOrientedApplication implements the accessors for application event
and command handlers, and instead exposes a single collection point for all objects of interest to the server for introspection
via a ManagedObjectLocator. The default ManagedObjectLocator retrieves such objects via the methods:
So a subclass can override these methods to add such objects or alternatively provide its own ManagedObjectLocator to return a set of objects that
will be introspected for EventHandlers, App Stats, Configured object and Command Handlers.
TopicOrientedApplication to support clustering, subclasses
must be annotated with an AppHAPolicy annotation.| Modifier and Type | Class and Description |
|---|---|
static class |
TopicOrientedApplication.ChannelJoin
Enumerates the channel join options that a
ChannelJoinProvider
can specify. |
| Modifier and Type | Field and Description |
|---|---|
protected Tracer |
_tracer |
static String |
PROP_ALERT_TRACE_LEVEL
Property that controls the default level at which alert events are traced to the
'nv.toa' trace logger.
|
static String |
PROP_ALERT_TRACE_LEVEL_DEFAULT
The default value for
PROP_ALERT_TRACE_LEVEL_DEFAULT ("warning"). |
static String |
PROP_DEFAULT_INJECTION_DELAY
Property that controls the default delay (or priority) for messages injected by this application.
|
static int |
PROP_DEFAULT_INJECTION_DELAY_DEFAULT
The default value for
PROP_ALERT_TRACE_LEVEL_DEFAULT ("warning"). |
static String |
PROP_DISABLE_COMPAT_CHECK
Property used to disable the runtime check against compatibility with Rumi
When the Hornet runtime is loaded a compatibility check against
the version of nvx-rumi found on the class path is performed to check for a version of
nvx-rumi that is known to be incompatible with the current Hornet runtime.
|
static boolean |
PROP_DISABLE_COMPAT_CHECK_DEFAULT
The default value for
PROP_DISABLE_COMPAT_CHECK (false). |
static String |
PROP_ENABLED_DELAYED_ACK_CONTROLLER
Property used to enabled the delayed ack controller functionality.
|
static boolean |
PROP_ENABLED_DELAYED_ACK_CONTROLLER_DEFAULT
The default value for
PROP_ENABLED_DELAYED_ACK_CONTROLLER (false). |
static String |
PROP_FAIL_ON_SERVICE_CHANNEL_NAME_COLLISION
Property used to indicate whether Hornet messaging configuration should fail if two services
result in the same channel name being used on the same bus.
|
static boolean |
PROP_FAIL_ON_SERVICE_CHANNEL_NAME_COLLISION_DEFAULT
The default value for
PROP_FAIL_ON_SERVICE_CHANNEL_NAME_COLLISION (true). |
static String |
PROP_GENERIC_HANDLER_JOINS_ALL
Property that indicates whether a MessageView or MessageEvent handler will cause all channel types to be joined.
|
static boolean |
PROP_GENERIC_HANDLER_JOINS_ALL_DEFAULT
The default value for
PROP_GENERIC_HANDLER_JOINS_ALL (false). |
static String |
PROP_IGNORE_UNMAPPED_CHANNELS
Property used to indicate whether Hornet processes service channels that are not mapped
by a message type.
|
static boolean |
PROP_IGNORE_UNMAPPED_CHANNELS_DEFAULT
The default value for
PROP_IGNORE_UNMAPPED_CHANNELS (false). |
static String |
PROP_USE_BUS_CONFIGURATION_TO_RESOLVE_CHANNEL_BUS
Property used to indicate that channel-bus relationships should not be used to resolve a channel's bus
When true the
TopicOrientedApplication will use bus configuration to resolve a channel's bus
if a bus has not been explicitly configured for a channel in the service definition. |
static boolean |
PROP_USE_BUS_CONFIGURATION_TO_RESOLVE_CHANNEL_BUS_DEFAULT
The default value for
PROP_USE_BUS_CONFIGURATION_TO_RESOLVE_CHANNEL_BUS (true). |
| Modifier | Constructor and Description |
|---|---|
protected |
TopicOrientedApplication()
Default constructor.
|
| Modifier and Type | Method and Description |
|---|---|
protected void |
addAppCommandHandlerContainers(Set<Object> containers)
This method may be overridden by subclasses to add additional objects that contain
methods with
Command annotations. |
protected void |
addAppStatContainers(Set<Object> containers)
This method may be overridden by subclasses to add additional objects that contain
methods with
AppStat annotations. |
protected void |
addChannelFilterProviders(Set<Object> containers)
This method may be overridden by subclasses to add additional objects that implement
ChannelFilterProvider. |
protected void |
addChannelInitialKeyResolutionTableProviders(Set<Object> containers)
This method may be overridden by subclasses to add additional objects that implement
ChannelQosProvider. |
protected void |
addChannelJoinProviders(Set<Object> containers)
This method may be overridden by subclasses to add additional objects that implement
ChannelJoinProvider. |
protected void |
addChannelQosProviders(Set<Object> containers)
This method may be overridden by subclasses to add additional objects that implement
ChannelQosProvider. |
protected void |
addConfiguredContainers(Set<Object> containers)
This method may be overridden by subclasses to add additional objects that contain
methods with
Configured annotations. |
protected void |
addHandlerContainers(Set<Object> containers)
This method may be overridden by subclasses to add additional objects that contain
methods with
EventHandler annotations. |
void |
addPostdispatchMessageHandler(IAepPostdispatchMessageHandler handler)
Adds a message handler to be invoked after 'normal' message handler dispatch.
|
void |
addPredispatchMessageHandler(IAepPredispatchMessageHandler handler)
Adds a message handler to be invoked before 'normal' message handler dispatch.
|
protected void |
addTopicResolverProviders(Set<Object> containers)
This method may be overridden by subclasses to add additional objects that implement
TopicResolverProvider. |
AepMessageSender |
getAepMessageSender()
Returns the
AepMessageSender implementation for sending non service defined messages. |
protected String |
getChannelFilter(ToaService serviceName,
ToaServiceChannel channelName)
This method may be overridden by subclasses to associate a channel filter
with the application.
|
protected TopicOrientedApplication.ChannelJoin |
getChannelJoin(ToaService service,
ToaServiceChannel channel)
Subclasses may override this method to change whether or not a channel should be joined.
|
protected MessageChannel.Qos |
getChannelQos(ToaService service,
ToaServiceChannel channel)
This method may be overridden by subclasses to specify the
MessageChannel.Qos for
the provided service channel. |
Configurer |
getConfigurer()
Returns this application's bootstrap configurer.
|
DelayedAcknowledgmentController |
getDelayedAcknowledgmentController()
Return the DelayedAcknowledgment Controller for the application.
|
AepEngine |
getEngine()
Returns this application's
AepEngine. |
EngineClock |
getEngineClock()
Return an interface which may be used to get the
AepEngine
time. |
protected Properties |
getInitialChannelKeyResolutionTable(ToaService service,
ToaServiceChannel channel)
This method may be overridden by subclasses to perform initial key resolution on a channel
at the time it is configured which allows all or a portion of a channel's dynamic key parts
to be determined statically at configuration time by returning a initial Key Resolution Table
(KRT).
|
protected ManagedObjectLocator |
getManagedObjectLocator()
Subclasses may override this method to change the strategy for locating an application's
managed objects.
|
MessageInjector |
getMessageInjector()
Returns the
MessageSender implementation which is this class. |
MessageSender |
getMessageSender()
Returns the
MessageSender implementation which is this class. |
protected ServiceDefinitionLocator |
getServiceDefinitionLocator()
Subclasses may override this method to change the way service xmls are located.
|
protected ToaService |
getServiceModel(String fullServiceName)
Looks up a parsed service model by fully qualified name.
|
protected Collection<ToaService> |
getServiceModels()
Returns the application's parsed service definitions.
|
protected TopicResolver<?> |
getTopicResolver(ToaService serviceName,
ToaServiceChannel channelName,
Class<?> messageType)
This method may be overridden by subclasses to return a
TopicResolver for
messages of the given type sent on the given channel. |
void |
injectMessage(IRogMessage message)
Enqueue a message into an application's
AepEngine's event multiplexer. |
void |
injectMessage(IRogMessage message,
boolean nonBlocking)
Enqueue a message into an application's
AepEngine's event multiplexer. |
void |
injectMessage(IRogMessage message,
boolean nonBlocking,
IEventAcknowledger acknowledger)
Enqueue a message into an application's
AepEngine's event multiplexer. |
void |
injectMessage(IRogMessage message,
boolean nonBlocking,
int delay)
Enqueue a message into an application's
AepEngine's event multiplexer. |
void |
injectMessage(IRogMessage message,
boolean nonBlocking,
int delay,
IEventAcknowledger acknowledger)
Enqueue a message into an application's
AepEngine's event multiplexer. |
void |
injectMessage(IRogMessage message,
IEventAcknowledger acknowledger)
Enqueue a message into an application's
AepEngine's event multiplexer. |
protected void |
onAppFinalized()
This is called after the application's
AepEngine has been successfully created
and injected into the application. |
protected void |
onAppInitialized()
This is called after the application's
AepEngine has been successfully created
and injected into the application. |
protected void |
onAppLoaderInjected(SrvAppLoader loader)
Called when the SrvAppLoader is injected into the application.
|
protected void |
onConfigured()
Called after configuration of messaging and services has been successfully completed.
|
protected void |
onEngineDescriptorInjected(AepEngineDescriptor engineDescriptor)
Called when the
AepEngineDescriptor is injected into the application. |
protected void |
onEngineInjected(AepEngine engine)
Called when the
AepEngine is injected into the application. |
void |
sendMessage(IRogMessage message)
Sends a message using the message's default channel.
|
void |
sendMessage(IRogMessage message,
MessageChannel.RawKeyResolutionTable rawKeyResolutionTable)
Sends a message using the provide zero garbage key resolution table.
|
void |
sendMessage(IRogMessage message,
Properties keyResolutionTable)
Sends a message using the provided key resolution table.
|
void |
sendMessage(IRogMessage message,
String topic)
Sends a message using the given topic as the channel key.
|
void |
sendMessage(IRogMessage message,
XString topic)
Sends a message using the given topic as the channel key (zero garbage variant).
|
public static final String PROP_ALERT_TRACE_LEVEL
When the 'nv.toa' trace level is at or above this level given by the name of a
Tracer.Level, then alerts will be trace logged.
Property name: "nv.toa.alerttracelevel"
Default value: "warning"
Valid values: Any valid Tracer.Level other than Tracer.Level.ALL. If
Tracer.Level.ALL is specified the trace level will use "warning".
public static final String PROP_ALERT_TRACE_LEVEL_DEFAULT
PROP_ALERT_TRACE_LEVEL_DEFAULT ("warning").public static final String PROP_DEFAULT_INJECTION_DELAY
This is the default value delay value used for injection via injectMessage(IRogMessage, boolean, int)
when called from a variant that doesn't supply the delay.
Property name: "nv.toa.defaultinjectiondelay"
Default value: 0
public static final int PROP_DEFAULT_INJECTION_DELAY_DEFAULT
PROP_ALERT_TRACE_LEVEL_DEFAULT ("warning").public static final String PROP_GENERIC_HANDLER_JOINS_ALL
TopicOrientedApplication's default behavior is to join channels for which the application exposes
an EventHandler annotated method. When this property is set to "true" if an event handler
discovered that handles a MessageView or a MessageEvent then the channel join logic will
join channels associated with any type.
Note that an application registered ChannelJoinProvider takes precedence over this setting so if
this property is set to true and a ChannelJoinProvider TopicOrientedApplication.ChannelJoin.NoJoin
then the channel will not be joined.
Property name: "nv.toa.generichandlerjoinsall"
Default value: false
public static final boolean PROP_GENERIC_HANDLER_JOINS_ALL_DEFAULT
PROP_GENERIC_HANDLER_JOINS_ALL (false).public static final String PROP_IGNORE_UNMAPPED_CHANNELS
By default Hornet will add channels to a message bus even if they are not mapped by a message
type. Setting this property to true will ignore unmapped channels.
Property name: "nv.toa.ignoreunmappedchannels"
Default value: false
public static final boolean PROP_IGNORE_UNMAPPED_CHANNELS_DEFAULT
PROP_IGNORE_UNMAPPED_CHANNELS (false).public static final String PROP_FAIL_ON_SERVICE_CHANNEL_NAME_COLLISION
By default Hornet prefixes channels declared in a service by the lowercase value of the of the service name to prevent collisions between channels declared in two separate services.
In cases where either (a) the service is declared not to prefix channel names or (b) where two services in different namespaces, but with the same name declare the same channel name it can result in both services creating the same channel resulting in the messages from both services flowing over the same message channel. In most cases this behavior is undesirable and configuration of messaging should fail.
This property allows changing the behavior not to fail when two services create channels with the same name.
Property name: "nv.toa.failonchannelnamecollision"
Default value: true
public static final boolean PROP_FAIL_ON_SERVICE_CHANNEL_NAME_COLLISION_DEFAULT
PROP_FAIL_ON_SERVICE_CHANNEL_NAME_COLLISION (true).public static final String PROP_DISABLE_COMPAT_CHECK
When the Hornet runtime is loaded a compatibility check against the version of nvx-rumi found on the class path is performed to check for a version of nvx-rumi that is known to be incompatible with the current Hornet runtime.
Property name: "nv.toa.disablecompatcheck"
Default value: false
public static final boolean PROP_DISABLE_COMPAT_CHECK_DEFAULT
PROP_DISABLE_COMPAT_CHECK (false).public static final String PROP_ENABLED_DELAYED_ACK_CONTROLLER
When true the TopicOrientedApplication will create a DelayedAcknowledgmentController
which can be use to delay inbound message acknowledgments. Usage of the DelayedAcknowledgmentController
requires that the application not be configured with a store.
Property name: "nv.toa.enabledelayedackcontroller"
Default value: false
public static final boolean PROP_ENABLED_DELAYED_ACK_CONTROLLER_DEFAULT
PROP_ENABLED_DELAYED_ACK_CONTROLLER (false).public static final String PROP_USE_BUS_CONFIGURATION_TO_RESOLVE_CHANNEL_BUS
When true the TopicOrientedApplication will use bus configuration to resolve a channel's bus
if a bus has not been explicitly configured for a channel in the service definition. If the channel's
bus cannot be resolved via the config, then the channel would be assigned a bus with the same name
as the application's engine. If false, then the bus configuration will not be used to resolve
a channel's bus i.e. if the bus is not configured explicitly in the service definition, then the channel
will be associated with a bus of the same name as the application's engine
Property name: "nv.toa.usebusconfigtoresolvechannelbus"
Default value: true
public static final boolean PROP_USE_BUS_CONFIGURATION_TO_RESOLVE_CHANNEL_BUS_DEFAULT
PROP_USE_BUS_CONFIGURATION_TO_RESOLVE_CHANNEL_BUS (true).protected final Tracer _tracer
protected TopicOrientedApplication()
protected void addHandlerContainers(Set<Object> containers)
EventHandler annotations.
This method is called by the DefaultManagedObjectLocator, if an application
provides its own ManagedObjectLocator then it is up to that locator as
to whether or not this method will be invoked.
This method is called by the application during the configuration phase
allowing the application subclass to register event handler containers
by adding objects having methods annotated with EventHandler that
will serve as the application's message and event handlers.
This class is automatically added as an event handler container, subclasses should not add itself to the set.
containers - Objects with EventHandler methods should be added to this set.protected void addAppCommandHandlerContainers(Set<Object> containers)
Command annotations.
This method is called by the DefaultManagedObjectLocator, if an application
provides its own ManagedObjectLocator then it is up to that locator as
to whether or not this method will be invoked.
This method is called by the application during the configuration phase
allowing the application subclass to register command handler containers
by adding objects having methods annotated with Command that
will serve as the application's command handlers.
This class is automatically added as an command handler container, subclasses should not add itself to the set.
containers - Objects with Command methods should be added to this set.protected void addAppStatContainers(Set<Object> containers)
AppStat annotations.
This method is called by the DefaultManagedObjectLocator, if an application
provides its own ManagedObjectLocator then it is up to that locator as
to whether or not this method will be invoked.
This method is called by the application during the configuration phase
allowing the application subclass to register command handler containers
by adding objects having methods annotated with AppStat that
will serve as the application's command handlers.
This class is automatically added as an command handler container, subclasses should not add itself to the set.
containers - Objects with AppStat should be added to this set.protected void addConfiguredContainers(Set<Object> containers)
Configured annotations.
This method is called by the DefaultManagedObjectLocator, if an application
provides its own ManagedObjectLocator then it is up to that locator as
to whether or not this method will be invoked.
This method is called by the application during the configuration phase
allowing the application subclass to register command handler containers
by adding objects having methods annotated with Configured that
will serve as the application's command handlers.
This class is automatically added as an command handler container, subclasses should not add itself to the set.
containers - Objects with Configured should be added to this set.protected void addChannelFilterProviders(Set<Object> containers)
ChannelFilterProvider.
This method is called by the DefaultManagedObjectLocator, if an application
provides its own ManagedObjectLocator then it is up to that locator as
to whether or not this method will be invoked.
This method is called by the application during the configuration phase
allowing the application subclass to register ChannelFilterProviders
The default implementation of this method adds a filter provider that calls
getChannelFilter(ToaService, ToaServiceChannel)
containers - Objects implementing ChannelFilterProvider should be added to this set.protected void addTopicResolverProviders(Set<Object> containers)
TopicResolverProvider.
This method is called by the DefaultManagedObjectLocator, if an application
provides its own ManagedObjectLocator then it is up to that locator as
to whether or not this method will be invoked.
This method is called by the application during the configuration phase
allowing the application subclass to register TopicResolverProviders
The default implementation of this method adds 2 TopicResolverProviders:
getChannelFilter(ToaService, ToaServiceChannel), allowing
subclasses to return a TopicResolver.
containers - Objects implementing ChannelFilterProvider should be added to this set.protected TopicResolver<?> getTopicResolver(ToaService serviceName, ToaServiceChannel channelName, Class<?> messageType)
TopicResolver for
messages of the given type sent on the given channel.
This method will not be called unless addTopicResolverProviders(Set) is
called on this class. This is done by the DefaultManagedObjectLocator,
but may not be called if the application defines its own ManagedObjectLocator.
serviceName - The service name.channelName - The name of the channel to filter.messageType - The concrete class of the message.TopicResolver for the message when it is sent of the given channel.protected String getChannelFilter(ToaService serviceName, ToaServiceChannel channelName)
This method will not be called unless addChannelFilterProviders(Set) is
called on this class. This is done by the DefaultManagedObjectLocator,
but may not be called if the application defines its own ManagedObjectLocator.
serviceName - The service name.channelName - The name of the channel to filter.protected void addChannelQosProviders(Set<Object> containers)
ChannelQosProvider.
This method is called by the DefaultManagedObjectLocator, if an application
provides its own ManagedObjectLocator then it is up to that locator as
to whether or not this method will be invoked.
This method is called by the application during the configuration phase
allowing the application subclass to register ChannelQosProviders
The default implementation of this method adds a ChannelQosProvider that calls
getChannelQos(ToaService, ToaServiceChannel) on this class.
If multiple ChannelQosProviders return differing MessageChannel.Qos values
for the same service and channel the highest quality of service will be
selected (e.g. Guaranteeed).
containers - Objects implementing ChannelQosProvider should be added to this set.protected MessageChannel.Qos getChannelQos(ToaService service, ToaServiceChannel channel)
MessageChannel.Qos for
the provided service channel.
This method will not be called unless addChannelQosProviders(Set) is
called on this class. This is done by the DefaultManagedObjectLocator,
but may not be called if the application defines its own ManagedObjectLocator
or overrides addChannelQosProviders(Set) without delegating to this
base class.
service - The servicechannel - The channel.protected void addChannelJoinProviders(Set<Object> containers)
ChannelJoinProvider.
This method is called by the DefaultManagedObjectLocator, if an application
provides its own ManagedObjectLocator then it is up to that locator as
to whether or not this method will be invoked.
This method is called by the application during the configuration phase
allowing the application subclass to register ChannelJoinProviders
The default implementation of this method adds a ChannelJoinProvider that calls
getChannelJoin(ToaService, ToaServiceChannel) on this class.
containers - Objects implementing ChannelJoinProvider should be added to this set.protected TopicOrientedApplication.ChannelJoin getChannelJoin(ToaService service, ToaServiceChannel channel)
See ChannelJoinProvider.getChannelJoin(ToaService, ToaServiceChannel) for the semantics
of this method.
This method returns TopicOrientedApplication.ChannelJoin.Default when not overridden.
service - The service that defined the channel.channel - The channel.protected void addChannelInitialKeyResolutionTableProviders(Set<Object> containers)
ChannelQosProvider.
This method is called by the DefaultManagedObjectLocator, if an application
provides its own ManagedObjectLocator then it is up to that locator as
to whether or not this method will be invoked.
This method is called by the application during the configuration phase
allowing the application subclasses to register ChannelInitialKeyResolutionTableProviders
The default implementation of this method adds a ChannelQosProvider that calls
getInitialChannelKeyResolutionTable(ToaService, ToaServiceChannel) on this class.
containers - Objects implementing ChannelInitialKeyResolutionTableProvider should be added to this set.protected Properties getInitialChannelKeyResolutionTable(ToaService service, ToaServiceChannel channel)
This method will not be called unless addChannelQosProviders(Set) is
called on this class. This is done by the DefaultManagedObjectLocator,
but may not be called if the application defines its own ManagedObjectLocator.
Example:
Given:With the above KRT, the channel would be intialized with a key of
- A channel, channel1 with a configured key of: ORDERS/${Region}/${Product}
- An initial KRT returned by this method of: {"Region": "US", "HostName": MyPC}
ORDERS/US/${Product}. The dynamic 'Region' portion of the key has become static while the 'Product' portion remains dynamic and eligible for substitution with a runtime KRT or from values reflected from a message reflector.
NOTE:
The returned key resolution table is not used for individual send calls, if
the channel key still contains dynamic portions then dynamic key resolution
can be done on a per send basis using either the message's message reflector
or a key resolution table provide as a argument to the send call.
If more than one service share the same channel on the same bus, they will share the same channel key; at this time it is not possible to perform individual channel key resolution on a per service basis. In this sense the initial channel key resolution is global to a channel name. The serviceName is provided here as a hint to assist the application in locating a key resolution table for a channel.
service - The service name.channel - The channel for which to perform key resolutionprotected ServiceDefinitionLocator getServiceDefinitionLocator()
The default implementation returns a new instance of DefaultServiceDefinitionLocator.
This is called prior to constructing the application's underlying AepEngine at this
point the SrvAppLoader will have been injected via onAppLoaderInjected(SrvAppLoader)
and the AepEngineDescriptor will have been injected via onEngineDescriptorInjected(AepEngineDescriptor)
so they may be used to figure out information about the application's identity.
ServiceDefinitionLocator to use to load the application's services.DefaultServiceDefinitionLocatorprotected ManagedObjectLocator getManagedObjectLocator()
The default implementation returns a new instance of DefaultManagedObjectLocator.
This is called prior to locating and parsing an application's service model and also prior to construction of the
application's underlying AepEngine At this point the SrvAppLoader will have been injected via
onAppLoaderInjected(SrvAppLoader) and the AepEngineDescriptor will have been injected via
onEngineDescriptorInjected(AepEngineDescriptor) so they may be used to figure out information about
the application's identity.
ManagedObjectLocator to use to load the application's services.DefaultManagedObjectLocatorpublic final AepEngine getEngine()
AepEngine. The engine is injected
just before the application is initialized, and this method will return
null before that occurs.
TopicOrientedApplication subclasses should use the processing facilities
provided by this class for most operations, and only utilize the underlying
AepEngine for functionality not provided by TOA. In particular,
all message sends should go through this application's MessageSender api
and message injection should be done through the MessageInjector unless
there is a compelling reason to bypass TOA.
AepEnginepublic final EngineClock getEngineClock()
AepEngine
time.
The default implementation of EngineClock returned simply
make a pass through call to the AepEngine.getEngineTime()
unless the engine for this application has not yet been set in
which case the returned clock will just return System.currentTimeMillis().
EngineClock.public final DelayedAcknowledgmentController getDelayedAcknowledgmentController()
The delayed acknowledgment controller can be used from within a message handler to suspend the acknowledgment (and consequently transaction completion) of the message being processed.
DelayedAcknowledgmentController or null if not enabled.DelayedAcknowledgmentControllerpublic final Configurer getConfigurer()
For applications launched from the Rumi server Main class this will
return the external Configurer for the application. For an embedded
Rumi server constructed by user code this will return whatever object the application
passed to the SrvController.setBootstrapConfigurer(Object).
The Rumi server injects the Configurer immediately after instantiating the TopicOrientedApplication.
protected final Collection<ToaService> getServiceModels()
An application's service definitions are parsed just after the application
calls addHandlerContainers(Set).
The returned collection must not be modified.
IllegalStateException - if services have not yet been parsed.protected final ToaService getServiceModel(String fullServiceName)
An application's service definitions are parsed just after the application
calls addHandlerContainers(Set).
The returned ToaService must not be modified.
null if no model was parsed.IllegalStateException - if services have not yet been parsed.public final MessageSender getMessageSender()
MessageSender implementation which is this class.
This method is useful for dependency injection frameworks.
Note that the
thread safety of the returned implementation is the same as that of using
this class directly ... send calls are not thread safe and may only be
called from an EventHandler, or in a non concurrent fashion by
an unsolicited 'sender' thread if this is a purely producer application.
public final AepMessageSender getAepMessageSender()
AepMessageSender implementation for sending non service defined messages.
An AepMessageSender assists in sending messages that are not defined in Hornet
service definitions. This sender allows the caller to specify the bus and message channel
on which the message should be sent.
Note that the thread safety of the returned implementation is the same as that
for send calls done directly through an AepEngine
AepMessageSender for this application.public final void sendMessage(IRogMessage message)
MessageSenderAepEngine.sendMessage(MessageChannel, IRogMessage),
with the message channel resolved based on this application's service definition for the message type and the provided message.sendMessage in interface MessageSendermessage - The message to send.AepEngine.sendMessage(MessageChannel, IRogMessage)public final void sendMessage(IRogMessage message, String topic)
MessageSenderAepEngine.sendMessage(MessageChannel, IRogMessage, String, Properties),
with the message channel resolved based on this application's service definition for the message type, the provided message, the provided
topic as the channel key, and no key resolution table.sendMessage in interface MessageSendermessage - The message to send.AepEngine.sendMessage(MessageChannel, IRogMessage)public final void sendMessage(IRogMessage message, Properties keyResolutionTable)
MessageSenderAepEngine.sendMessage(MessageChannel, IRogMessage, Properties),
with the message channel resolved based on this application's service definition for the message type, the provided message,
key, and the provided message key.sendMessage in interface MessageSendermessage - The message to send.AepEngine.sendMessage(MessageChannel, IRogMessage)public final void sendMessage(IRogMessage message, XString topic)
MessageSenderAepEngine.sendMessage(MessageChannel, IRogMessage, XString, MessageChannel.RawKeyResolutionTable),
with the message channel resolved based on this application's service definition for the message type, the provided message, the provided
topic as the channel key, and no key resolution table.sendMessage in interface MessageSendermessage - The message to send.AepEngine.sendMessage(MessageChannel, IRogMessage)public final void sendMessage(IRogMessage message, MessageChannel.RawKeyResolutionTable rawKeyResolutionTable)
MessageSenderAepEngine.sendMessage(MessageChannel, IRogMessage, MessageChannel.RawKeyResolutionTable),
with the message channel resolved based on this application's service definition for the message type, the provided message,
and no key resolution table.sendMessage in interface MessageSendermessage - The message to send.AepEngine.sendMessage(MessageChannel, IRogMessage)public final MessageInjector getMessageInjector()
MessageSender implementation which is this class.
This method is useful for dependency injection frameworks.
Note that the
thread safety of the returned implementation is the same as that of using
this class directly ... send calls are not thread safe and may only be
called from an EventHandler, or in a non concurrent fashion by
an unsolicited 'sender' thread if this is a purely producer application.
public final void injectMessage(IRogMessage message)
MessageInjectorAepEngine's event multiplexer.
This method is the same as injectMessage(message, false, defaultInjectionDelay, null).
(where default injection delay is set by PROP_DEFAULT_INJECTION_DELAY).
injectMessage in interface MessageInjectormessage - The message to enqueue.AepEngine.injectMessage(IRogMessage)public final void injectMessage(IRogMessage message, IEventAcknowledger acknowledger)
MessageInjectorAepEngine's event multiplexer.
This method is the same as injectMessage(message, false, defaultInjectionDelay, acknowledger).
(where default injection delay is set by PROP_DEFAULT_INJECTION_DELAY).
injectMessage in interface MessageInjectormessage - The message to enqueue.acknowledger - The acknowledger that will be invoked when the processing of the transaction
containing the injected message is complete. Note that such notifications will only occur on
engines operating in the Primary role. This parameter can be null.AepEngine.injectMessage(IRogMessage, IEventAcknowledger)public final void injectMessage(IRogMessage message, boolean nonBlocking)
MessageInjectorAepEngine's event multiplexer.
This method is the same as injectMessage(message, nonBlocking, defaultInjectionDelay, null)
(where default injection delay is set by PROP_DEFAULT_INJECTION_DELAY).
injectMessage in interface MessageInjectormessage - The message to enqueue.nonBlocking - Indicates whether the multiplexing should be a
non-blocking action or not. If blocking, then the calling thread
will block if the engine's input multiplexer queue is full and wait until
space is available. If non-blocking, then the method will not
wait but rather enque the message in a feeder queue fronting the engine's
input multiplexer queue.AepEngine.injectMessage(IRogMessage, boolean),
PROP_DEFAULT_INJECTION_DELAYpublic final void injectMessage(IRogMessage message, boolean nonBlocking, IEventAcknowledger acknowledger)
MessageInjectorAepEngine's event multiplexer.
This method is the same as injectMessage(message, nonBlocking, defaultInjectionDelay, acknowledger)
(where default injection delay is set by PROP_DEFAULT_INJECTION_DELAY).
injectMessage in interface MessageInjectormessage - The message to enqueue.nonBlocking - Indicates whether the multiplexing should be a
non-blocking action or not. If blocking, then the calling thread
will block if the engine's input multiplexer queue is full and wait until
space is available. If non-blocking, then the method will not
wait but rather enque the message in a feeder queue fronting the engine's
input multiplexer queue.acknowledger - The acknowledger that will be invoked when the processing of the transaction
containing the injected message is complete. Note that such notifications will only occur on
engines operating in the Primary role. This parameter can be null.AepEngine.injectMessage(IRogMessage, boolean),
PROP_DEFAULT_INJECTION_DELAYpublic final void injectMessage(IRogMessage message, boolean nonBlocking, int delay)
MessageInjectorAepEngine's event multiplexer.
This method is the same as the corresponding AepEngine.injectMessage(IRogMessage, boolean, int, IEventAcknowledger)
method except that this method disallows injection of message from the AepEngine's
dispatch thread (i.e. from a message handler).
injectMessage in interface MessageInjectormessage - The IRogMessage to enqueue.nonBlocking - Indicates whether the multiplexing should be a
non-blocking action or not. If blocking, then the calling thread
will block if the engine's input multiplexer queue is full and wait until
space is available. If non-blocking, then the method will not
wait but rather enque the message in a feeder queue fronting the engine's
input multiplexer queue.delay - The delay in milliseconds at which the message should be injected.public final void injectMessage(IRogMessage message, boolean nonBlocking, int delay, IEventAcknowledger acknowledger)
MessageInjectorAepEngine's event multiplexer.
This method is the same as the corresponding AepEngine.injectMessage(IRogMessage, boolean, int, IEventAcknowledger)
method except that this method disallows injection of message from the AepEngine's
dispatch thread (i.e. from a message handler).
injectMessage in interface MessageInjectormessage - The IRogMessage to enqueue.nonBlocking - Indicates whether the multiplexing should be a
non-blocking action or not. If blocking, then the calling thread
will block if the engine's input multiplexer queue is full and wait until
space is available. If non-blocking, then the method will not
wait but rather enque the message in a feeder queue fronting the engine's
input multiplexer queue.delay - The delay in milliseconds at which the message should be injected.acknowledger - The acknowledger that will be invoked when the processing of the transaction
containing the injected message is complete. Note that such notifications will only occur on
engines operating in the Primary role. This parameter can be null.protected void onEngineDescriptorInjected(AepEngineDescriptor engineDescriptor) throws Exception
AepEngineDescriptor is injected into the application.
This is called prior to creating the engine allowing applications to further customize
the AepEngine prior to its construction.
Because TopicOrientedApplication already provides an AppInjectionPoint for AepEngineDescriptor,
this method provides subclasses with a means to listen for AepEngineDescriptor injection.
engineDescriptor - the AepEngineDescriptorException - An application throwing an exception from this method will cause loading of the application to fail.protected void onConfigured()
throws Exception
At this point the AepEngine is still not available, but ToaServices and the
the Configurer are.
Applications may override this method to examine either of these objects.
Exception - An application throwing an exception from this method will cause loading of the application to fail.protected void onEngineInjected(AepEngine engine) throws Exception
AepEngine is injected into the application.
This is called after the AepEngine has been created, but before it is started.
Because TopicOrientedApplication already provides an AppInjectionPoint for AepEngine,
this method provides subclasses with a means to listen for AepEngine injection.
engine - the AepEngineException - An application throwing an exception from this method will cause loading of the application to fail.public final void addPredispatchMessageHandler(IAepPredispatchMessageHandler handler)
TopicOrientedApplication messages are dispatched by the underlying
AepEngine to @EventHandler annotated methods exposed by the
application. This method, allows an applications to add generic pre dispatch handlers
to do pre processing before message dispatch to the 'normal' handlers.
If multiple pre dispatch message handlers are registered and one of them throws an
exception, remaining handlers will not be called and the engine will dispatch
an AepApplicationExceptionEvent.
Handler addition is not permitted after the call to onEngineInjected(AepEngine)
and will thrown an IllegalStateException.
IllegalStateException - if this method is called after onEngineInjected(AepEngine).public final void addPostdispatchMessageHandler(IAepPostdispatchMessageHandler handler)
TopicOrientedApplication messages are dispatched by the underlying
AepEngine to @EventHandler annotated methods exposed by the
application. This method, allows an applications to add generic post dispatch handlers
to do post processing after message dispatch to the 'normal' handlers.
If a message handler throws an exception prior to the IAepPostdispatchMessageHandler
being invoked, then the IAepPostdispatchMessageHandler will not be invoked, and the
engine will instead dispatch an AepApplicationExceptionEvent, so
an IAepPostdispatchMessageHandler may want to handle this event as well if it needs to
be notified in the event of an unsuccessful dispatch.
Handler addition is not permitted after the call to onEngineInjected(AepEngine)
and will thrown an IllegalStateException.
IllegalStateException - if this method is called after onEngineInjected(AepEngine).protected void onAppLoaderInjected(SrvAppLoader loader) throws Exception
This is called just after application class is constructed providing the means for an application to examine the configuration of the server that is loading it.
Because TopicOrientedApplication already provides an AppInjectionPoint for SrvAppLoader,
this method provides subclasses with a means to listen for SrvAppLoader injection.
loader - the SrvAppLoaderException - An application throwing an exception from this method will cause loading of the application to fail.protected void onAppInitialized()
throws Exception
AepEngine has been successfully created
and injected into the application. Subclasses may override this method
to do any final initialization prior to the application being started.Exception - An application throwing an exception from this method will cause loading of the application to fail.protected void onAppFinalized()
throws Exception
AepEngine has been successfully created
and injected into the application. Subclasses may override this method
to do any final initialization prior to the application being started.Exception - An application throwing an exception from this method will cause the app finalization to terminate with an error.Copyright © 2016 N5 Technologies, Inc. All Rights Reserved.