...
Common Bus Configuration Properties
The follow following properties are common to all bus implementations (unless specifically noted otherwise) and can be specified in a bus descriptor either as parameters in a descriptor URL or as properties in the buses' configuration settings when specified in its decomposed form.
Property Name | Default Value | Description | ||||||
---|---|---|---|---|---|---|---|---|
set_bus_and_channel_on_receipt | false | Controls whether the bus and channel name are set on received messages. Setting the channel and bus name on inbound messages incurs performance overhead. Performance sensitive applications should avoid enabling this property. | ||||||
set_key_on_receipt | false | Controls whether the message key is set on received messages. Not all binding implementations transport the key on the wire, this property has no effect for bindings that don't transport the key. Setting the key on inbound message messages incurs a performance overhead. Performance sensitive applications should avoid enabling this property. | ||||||
topic_starts_with_channel | true | Controls whether topic names start with the channel name for the bus. For bus bindings that support topic routing this property controls whether or not the resolved key is prefixed with the channel name. | ||||||
additional_properties_file | false | Specifies the path to an external file , that is used to load additional bus configuration properties from. The external file format is a plain java Properties file. Properties specified in the external file will be merged into configuration property set for the bus. This file is loaded at runtime, so the file is retrieved from the local file system on the host where the configured XVM will run. |
...
- The application creates a message.
- The application calls send, passing the message and channel name.
- The engine looks up the channel and uses it to resolves the physical destination on which the message will be sent via the configured channel key.
- The engine queues the message for send sending until the associated state changes for the message handler are stabilized to the application's store (e.g replication and transaction log write).
- When the transaction is committed the message is serialized to its backing buffer, packaged in a message bus provider specific message along with message metadata containing the message type information used by receivers to deserialize the message.
...
Note |
---|
Sending a message through an AepEngine transfers ownership of the message to the engine. When a message is sent from within an application event handler, the application may not retain the message or any of its nested entities beyond the scope of the message handler as pooling may invalidate them. If a message is created, but not sent, it is up to the application to call dispose() on the message to return it the pool. Failing to return the message to a pool will not result in a memory leak, but it will mean that subsequent create() calls won't result in object allocation and promotion. |
...
- A static key uses the channel key as the actual topic on which to send the message. For example, "Orders/USA".
- A dynamic key contains variable components that are resolved at runtime either at startup or during a send call to resolve the specific topic. For example, "Orders/${Region}".
- Channel key functions allow portions of the key to be resolved using a function. For example, "Orders/#[orderProcessorShard = hash(${orderId}, 2)]", would resolve to Orders/1 or Orders/2 based on the hashcode of the orderId field in the message.
By default, a message channel will prepend the channel name to the beginning of the topic as the first level in the topic name. This mechanism prevents multiple channel definitions from conflicting with one another. This behavior can be disabled by configuring the bus provider with the bus property topic_starts_with_channel=false.
...
Note |
---|
Note that when using EventSourcing as the HAPolicy, using a key resolution table set on the message channel is not supported. The reason for this is that message buses are only started for applications that are operating in a Primary role. Consequently, messages sent by application logic on the backup instance will not have received an AepChannelUpEvent and won't have a key resolution table which could lead to divergent key resolution. |
...
- variableName: Names the variable portion of the key. Naming The naming of the variable portion defined by the function is important as it allows the portion to be referenced when defining channel filters (see channel filters below)
- functionName: The name of the static registered channel key function to use.
- args: The arguments to pass to the function. The arguments can either be static values, or ${variable} values sourced from the message or key resolution tables.
Built-In Functions
The following table describe describes the currently available set of built-in channel key functions provided by the platform:
...
An application may define its own channel key functions by setting the value of `nv.sma.channelkeyfunctioncontainers` to a comma-separated list of class classes that contain additional channel key functions.
...
When resolving topics dynamically from a messages message's fields it may be important to validate that value from the message field doesn't introduce additional levels in the topic or illegal characters or result in empty topic levels. To prevent this a message bus can be configured to 'clean' the dynamic variable portions of the topic at the cost of additional overhead by setting the following environment properties:
Property | Default | Description | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
nv.sma.maxresolvedkeylength | 0 | Controls the maximum resolved key length for resolved and static message keys. When set to a length greater than 0 the length of the message key is checked to ensure that the length is not greater this value. For maximum portability between bindings, this property can be set to the lowest value for destination lengths supported amongst the bindings that will be used. If this property is not set and "nv.sma.validatemessagekey" is set a message bus binding instance should still validate that a resolved message key is not too long. For example, the solace binding only supports topics that are 250 characters long and would enforce the resolved topic length as part of key validation.
| ||||||||||||||||||
nv.sma.cleanmessagekey | false | Controls whether or not variable key parts in channel keys are sanitized by replacing any non-letter or digit character with an '_' when resolving a variable key. For example: if the channel key is specified as "/Orders/${Region}" and key resolution is performed using a message that returns a value of "Asia/Pac" for getRegion(), then the resolved key value will be "/Orders/Asia_Pac" rather than "/Orders/Asia/Pac" when this property is set to This property applies to values coming from a key resolution table or via message reflection but not to channel key functions.
| ||||||||||||||||||
nv.sma.allowemptykeyfield | false | Controls whether or not variable key parts in channel keys may be substituted with an empty String value. For example: if the channel key is specified as "/Orders/${Region}/${Department}" and key resolution is performed using a message that returns a value of "" for getRegion(), then this property specifies that key resolution should fail when set to This property applies to values coming from a key resolution table or via message reflection but not to channel key functions.
| ||||||||||||||||||
nv.sma.treatemptykeyfieldasnull
| false | The XRuntime property controlling whether or not an empty key value is treated as null when resolving message keys. When this property is set it takes precedence over the value set for "nv.sma.allowemptykeyfield". If a variable key value is resolved from a message or a key resolution table as an empty string it is treated as if the value were not set at all. Unlike nv.sma.allowemptykeyfield=false, this value allows the key resolution to continue to look for valid values from other sources or the default value configured for the channel key variable, only resulting in an exception if the value can't be resolved at all. Users should take care when setting this property to
| ||||||||||||||||||
nv.sma.validatemessagekey | false | Controls whether or not message key validation is done prior to sending a message. When this property is |
...
It is also possible for the caller to provide the message key directly in the send call. In this case, the supplied key will be used as is for the topic. This can be useful in certain situations , but should be used with care because it breaks the ability for the topic to be changed at runtime and receivers will not have knowledge of how to subscribe to such sends.
...
- The message bus binding implementation receives a serialized, message provider specific message.
- Using an application supplied message view factory (generated by ADM), and using SMA message metadata also transported with the provider-specific message, the bus wraps the serialized message in a view object (also ADM generated).
- Using message metadata transported with the message, the binding looks up the message channel on which to dispatch the received message.
- The message view is wrapped in a MessageEvent along with its message channel and is dispatched to the application's AepEngine, where it is enqueued for processing.
- The AepEngine picks up the message event and dispatches to each application event handler that has a signature matching the message type.
- Once the AepEngine stabilizes the results of the application's message processing, a message acknowledgment is dispatched back to the binding.
...
If a variable portion of the channel key is omitted in a filter, it will result in the subscription being joined in a wildcard fashion (, assuming the underlying bus implementation supports wildcards). So given a channel key of "NEWORDERS/${Region}/${Department}"
and a channel filter of "Region=US|EMEA"
, it would result in the following subscriptions being would be issued during join:
- NEWORDERS/US/*
- NEWORDERS/EMEA/*
...
As of the 3.8 Release, channel filter cleaning has been enhanced to not replace certain wildcard characters that are legal for use in subscriptions.
...
Message Field | Type | Description |
---|---|---|
MessageSender | int | A globally unique id that identifies the sender of a message. By default, an AepEngine uses the hashcode of the engine name as the sender id. |
MessageSno | long | A monotonically increasing sequence number. |
MessageFlow | int | Indicates the flow to which the message belongs. Flows allow for partitioning of message traffic in conjunction with application state and allow intra-application state partitioning. ![]() |
As an AepEngine processes message messages, it keeps track of the last seen sequence number for each sender that has sent to it as part of its HA state. Consequently, when an application fails over to a backup or is restarted it will remember the last message seen from senders sending to it and can filter duplicates on behalf of the application. When an application's state is wiped or reinitialized it will restart its sending stream sequence to 1 which alerts downstream applications not to consider its newly lowered sequence numbers as duplicates.
...
The following table summarizes aeo AEP engine configuration properties that have an impact on duplicate detection:
...
It is worth noting that for a cluster application only the primary instance of the application establishes message bus connections. In the event of a failure, a backup member will be elected and reestablish messaging connections. From a programming standpoint, this has the biggest impact on applications using the EventSourcing HA Policy as it means that even though their handlers are being invoked message channels will not have been established for the applications.
During live operation, the primary application keeps track of the last transaction for which outbound messages were acknowledged. This id, known as the stableTransactionId is persisted in the applications transaction log and replicated to backups. After failure or recovery backup applications will retransmit outbound messages that are part of transactions that have not stabilized and rely on downstream applications to use the duplicate detection to eliminate any duplicates.
...
Code Block | ||||
---|---|---|---|---|
| ||||
@EventHandler public void onEngineStopping(final AepEngineStoppingEvent event) { if(event.getPreserveChannelJoins()) { tracer.log("Overriding unsubscribe behavior on application stop to remove subscriptions."); event.setPreserveChannelJoins(false); } } |
In the above case, the value set programmatically overrides the configured value for the application.
...