The Talon Manual

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
div
idtoc
classtoc
div
classtocTitle

On This Page

div
classtocContents

Table of Contents
maxLevel23
indent8px
stylenone

Excerpt

The platform's solace binding includes both a java based and jni JNI-based implementation and allows connectivity to a solace message router.

JNI vs JAVA Binding

The JNI binding support zero garbage messaging while in steady state, but is only supported on linux. The Java binding uses solace's JCSMP api while the JNI binding uses solace's CCSMP api. The JNI binding supports zero garbage messaging while in steady state, but only works on linux platforms while the . The Java binding is not zero garbage but works on all platform supported by X. Other differences between the two bindings are:

  • UnhandledMesssageEvents issued by the JNI binding return the subscription name rather than the sent topic name.
  • UnhandledMesssageEvents issued by the JNI binding return a session specific sequence number rather than the appliance wide sequence number in the transport specific message id. 
  • The provider properties passed through to the underlying property differ depending on the underlying solace library used. The  
    (warning) The binding rationalizes some of the common properties between the two implementations. See the configuration section below for more details. , but if properties are used that are specific to JCSMP or JNI and are not rationalized, it is important to consider whether JNI is enabled or not. 

The JNI binding is currently only available on Linux platforms. Usage of the JNI binding is controlled by the following properties:

PropertyDefaultDescription
usejni-When set to true mandates that JNI be used. If JNI is not available an exception is thrown and binding creation fails. When set to false JNI is not used even if available.
preferjnitrue

Unlike usejni which forces usage one way or another, when preferjni=true the binding will silently fall back to using JCSMP when JNI is not available. When false the binding will not use JNI even if available.

As of 3.12, this property is ignored if a value for usejni is provided, in prior releases preferjni is used if usejni is not present or is set to false

Status
colourGreen
titleSince 3.10

Bus Descriptor Format

A solace message bus can be configured via a descriptor string as follows which takes the connection information followed by a list of provider properties. 

...

An example bus descriptor for solace Solace would look like like:

No Format
solace://<address>:<port>&usejni=true&vpn_name=default&username=test& /
password=test&usejni=true&vpn_name=default&username=test&password=test

DDL

In a DDL config file, a solace Solace bus can equivalently be configured in one of two ways

Code Block
titleDecomposed
<buses>
  <bus name="my-bus">
    <provider>solace</provider>
    <address>192.168.1.9</address>
    <port>55555</port>
    <properties>
      <usejni>true</usejni>
      <vpn_name>default</vpn_name>
      <username>test</username>
      <password>test</password>
    </properties>
    <channels>
      ...
    </channels>
  </bus>
</buses>

...

Passed Through Properties

The solace JCSMP and JNI apis APIs on which the platform's solace binding is built allow configuration of the connection by specifying properties.  The provider properties specified in the bus descriptor for the binding are passed through to the solace connection as follows:

  • Properties that are not described as in the SolaceBindingProperties javadoc are stripped out. 
  • General Bus properties defined in  MessageBusDescriptor javadoc are also stripped out.

  • Properties listed as 'Rationalized Properties' below are translated according to whether the jni or java binding implementation will be used these.
  • If "usejni" is true, then any remaining properties that don't start with "FLOW_" or "SESSION_" are are stripped, the rest are passed through opaquely.
  • If "usejni" is false, then any remaining properties that don't start with "jcsmp" are are stripped, the rest are passed through opaquely.

See the solace documentation for more information on JCSMP and CCSMP. Neeve, does not test properties not explicitly called out on this page or in the javadoc. End users should therefore do their own due diligence in testing any passed through properties. 

Rationalized Pass Through Properties

To make is easier for applications to switch between using the jni (c) and jcsmp (java) binding implementations, several commonly used pass through binding properties are automatically translated by the binding. These are summarized in the table below. If your application doesn't use any additional solace configuration properties then switching between the java a c

Binding PropertyJCSMP PropertyCCSMP Property
"vpn_name""jcsmp.vpn_name""SESSION_VPN_NAME"
"username""jcsmp.usename""SESSION_USERNAME"
"password""jcsmp.password""SESSION_PASSWORD"
"publish_window_size""jcsmp.pub_ack_window_size""SESSION_PUB_WINDOW_SIZE"
"reconnect_retry_count""jcsmp.CLIENT_CHANNEL_PROPERTIES.ReconnectRetries""SESSION_RECONNECT_RETRIES"
"connect_retry_count""jcsmp.CLIENT_CHANNEL_PROPERTIES.ConnectRetries""SESSION_CONNECT_RETRIES"
"tcp_nodelay""jcsmp.CLIENT_CHANNEL_PROPERTIES.tcpNoDelay""SESSION_TCP_NODELAY"
"reapply_subscriptions""jcsmp.REAPPLY_SUBSCRIPTIONS""SESSION_REAPPLY_SUBSCRIPTIONS"
"ignore_subscriptions_error""jcsmp.IGNORE_DUPLICATE_SUBSCRIPTION_ERROR""SESSION_IGNORE_DUP_SUBSCRIPTION_ERROR"

MessageBusDescriptor.PROPNAME_ADDRESS

(the value from the bus descriptor address)

"jcsmp.HOST""SESSION_HOST"

Additional Properties

See the SolaceBindingProperties javadoc for the listing full of additional provider properties specific to binding properties that can be used to configure the solace binding, those not called out as rationalized properties control the binding itself. 

Auto Tuning

When not explicitly as binding property, the following properties are automatically set on the binding based on the global optimization value.

Working with the Solace Binding

Solace Topic Format

Solace topics can be specified hierarchically with each level in the topic separated by a '/' character. Solace topics cannot exceed 250 characters in length. For more details on Solace topics refer to solace documentation.

Wildcard Topics

Solace supports two wildcard character sequences that can be used in Channel Filters to match multiple sending topics. Wildcard characters are not applied to sent topics and are treated as character literals. The solace binding implementation is sensitive to the following wildcards when nv.sma.cleanchannelfilter=true and will preserve these characters rather than replace them with an '_':

Wildcard
Description
*

Matches 0 or more characters and can only be used at the end of a topic level

For example orders/gin*

would match sends to

  • orders/gin
  • orders/ginseng

But not

  • orders
  • orders/in
  • orders/gin/foo
>

Matches multiple topic levels and may only be used as the only character last level in a topic filter strings

For example orders/>

would match sends to

  • orders/events/MSFT
  • orders/updates/APPL
  • orders/cancels/US/IBM

But not

  • orders
  • order-updates

Example

In the following example Solace messaging is configured with a dynamic channel key to resolve topics for new orders in a trading application. The variable portions of the dynamic key are used to allow receiving applications to select which traffic they shall receive: 

Code Block
xml
xml
<buses>
  <bus name="trading" descriptor="solace://solacehost:55555&amp;topic_starts_with_channel=false">
    <channels>
      <channel name="orders">
		<qos>Guaranteed</qos>
        <key>${InitiatingClient::NONE}${Region::NONE}/${Symbol::NONE}/
      </channel>
    <channels>
  </bus>
</buses>
 
<apps>
  <app name="order-manager">
	<messaging>
      <buses>
        <bus name="trading">
          <channels>
            <channel name="orders>
              <filter>Region="US";Symbol=A*|MSFT</filter>
            <channel>
          </channels>
        </bus>
      </buses>
    </messaging>
  </app>
 
  <app name="client">
	<messaging>
      <buses>
        <bus name="trading" join="true">
          <channels>
            <channel name="orders" join="false" />
          </channels>
        </bus>
      </buses>
    </messaging>
  </app>
</apps>
 

In the above example, the order-manager application uses a channel filter of  <filter>Region="US";Symbol=A*|MSFT</filter> which results in it creating the following subscriptions:

  • */US/A*
  • */US/MSFT*

In other words, it selects messages from any InitiatingClient in the 'US' region for the symbol MSFT or any Symbol starting with an 'A'. The order-manager app would receive the following message sent from a client with the following content:

Code Block
json
json
{InitatingClient : "CLIENTA", Region: "US", Symbol: "MSFT"} // resolved to topic CLIENTA/US/MSFT ... matches */US/MSFT
{InitatingClient : "CLIENTA", Region: "US", Symbol: "APPL"} // resolved to topic CLIENTA/US/APPL ... matches */US/A*
{Region: "US", Symbol: "MSFT"}                              // resolved to topic NONE/US/MSFT    ... matches */US/MSFT

But the order-manager would not receive messages sent from a client with the following content:

Code Block
json
json
{InitatingClient : "CLIENTA", Region: "US", Symbol: "IBM"}  //resolved to topic CLIENTA/US/IBM   ... matches neither */US/MSFT nor */US/A*
{Symbol: "IBM"}                                             //resolved to topic NONE/NONE/IBM    ... matches neither */US/MSFT nor */US/A*

Message Metadata Version

When a message is sent through the solace binding SMA metadata is sent with the message to assist receivers in determining how to deserialize and dispatch the message. By default, the solace binding sends messages using the V1 version of metadata to ensure that older receivers (pre-Talon 1.8.396) can deserialize messages. The difference between the V1 and V2 metadata is that the V2 encodes the message type (prior to the introduction of V2 metadata receivers needed to introspect the serialized message content and use the xRogType field encoded in the message).

Tip

If you know that there will be no downstream receivers using a version prior to 1.8.396, you can set sma_metadata_version=2 as a solace binding property to use the newer metadata format which is more efficient.

Other settings

Property nameDefaultDescription
set_key_on_receipt
falsesets the Topic on a per-message basis. This is accessed via `message.getMessageKeyAsRaw`
provision_queuetrueallows solace to create queues on your behalf. If you disable this, you will have to create the queue's manually
queue_nameN/Alimits the queue that your application will read.

 

Orphan Subscription Checks

When a solace Solace message bus binding has a queue name specified it is capable of issue guaranteed subscriptions against that queue. When a binding is started it is possible that there may already be existing subscriptions on the queue that don't match those that the application is issuing. Such subscriptions are considered to be 'orphan' subscriptions - presumably, those left over leftover from an early session that were was not removed.

The following policy can be configured to check for orphan subscriptions

 Policy Desecription Description
None

With this policy, the appliance is not queried for subscriptions

This is the default policy

Ignore

With this policy enabled the appliance is queried for subscriptions, but no action is taken other than tracing the orphans orphan's subscriptions at the info level.

One other difference between SolaceOrphanSubscriptionCheckPolicy.None and SolaceOrphanSubscriptionCheckPolicy.Ignore is the the query subscriptions are reported to a subscription validator if registered. 

LogExceptionAndContinue

With this policy enabled the appliance is queried for subscriptions and if orphands orphans are found an exception is logged.

NoOrphan

With this policy enabled the appliance is queried for subscriptions and an exception is thrown from the message binding start method.

UnsubscribeWith this policy enabled, the appliance is queried for subscriptions and orphan subscriptions are then removed (unsubscribed) from the appliance

Configuration

To check for existing subscription subscriptions SEMP must be enabled for the binding to retrieve the list of subscriptions over the messaging connection. The following provider properties must be specified on the bus descriptor to perform subscription checks:

PropertyUsageDefaultDescription
enable_semprequiredoptionalfalse

Property controlling whether or not Solace semp over messaging requests are enabled.

Controls whether or not semp over messaging requests are enabled. This property must be enabled in order to query the solace appliance for existing subscriptions. This requires that the appliance has semp over messaging-enabled and that the user is authorized to make semp requests.

(warning) NOTE: SEMP operations are currently an experimental feature. Enabling semp is not recommended in production without should be enabled in production with caution and with rigorous end user testing, and it . It should be noted that solace could drop support for SEMP over messaging in the future. Reliance on SEMP operations may also limit the ability to connect to solace appliance versions that don't have a compatibles SEMP model.

orphan_subscription_checkrequiredoptionalNone

Property controlling the orphan subscription check policy.

This policy controls checks for orphaned Guaranteed subscriptions done when the solace binding is started. The check for orphaned is performed after the bindings subscription are created, but just before messaging is started. The solace appliance is queried for the list of Guaranteed subscriptions on the Queue and compared to the subscriptions that were issued. Any subscriptions on the queue that were not issued by the binding are deemed to be orphans.

When using a policy other than None , "enable_semp" must be set to true. 

semp_versionrecommendedsoltr/7_1_1The version of semp requests must match that supported by the messaging appliance. If this property is not set semp requests will be retried using the version reported in the error response if a version mismatch is detected. Setting this property correctly avoids the need to make the initial request to determine the semp version.
semp_request_timeoutrecommended10000

Property controlling what timeout to use for semp requests in milliseconds.

It is recommended that you test against your appliance and application under load to ensure that the default timeout of 10 seconds is sufficient.

subscription_validatorunsupported-This is a legacy property that allows the an application registered callback to perform additional subscription validation. This should only be used on guidance for Neeve support.

Enforcing Max Queue Bind Count

When using Solace with Guaranteed messaging, a queue to hold messages for the application must be provisioned to provide the required store and forward capabilities. When using a queue it is recommended that the queue is provisioned with a max bind count of 1, to ensure that only one instance of an application can bind to the queue. This provides an extra level of protection against network partitioning between a primary and backup member by ensuring that two instances can't both consume messages. As an extra check that the queue has been provisioned with a max bind count of 1, the binding can be configured to make a SEMP call to enforce the expected bind count and cause the bus binding startup to fail. The configuration properties below can be set to allow this:
Status
colourGreen
titleSince 3.8
PropertyUsageDefaultDescription
enable_sempoptionalfalse

Property controlling whether or not Solace semp over messaging requests are enabled.

Controls whether or not semp over messaging requests are enabled. This property must be enabled in order to query the solace appliance for existing subscriptions. This requires that the appliance has semp over messaging-enabled and that the user is authorized to make semp requests.

(warning) NOTE: SEMP operations are currently an experimental feature. Enabling semp is not recommended in production without rigorous end user testing, and it should be noted that solace could drop support for SEMP over messaging in the future. Reliance on SEMP operations may also limit the ability to connect to Solace appliance versions that don't have a compatibles SEMP model.

enforce_max_bind_countoptional0

Can be set to a positive value to enforce match against a provisioned queue's max bind count.

When set the binding will issue a SEMP request when the binding is started to check that the max bind count for the provisioned queue matches the value of this property. This can be used to ensure that exclusive connectivity to the queue when it is provisioned with a max bind count of 1, to disallow 2 application instances for concurrently connecting to a queue.

This property is ignored if the binding is not configured with a queue or if the value of the property is less than or equal to 0.

(warning) NOTE: Setting this property to a positive value requires that SEMP is enabled and available because the max bind count for the provisioned queue is retrieved via a SEMP request. If the SEMP is disabled, SEMP requests cannot be issued or the response is invalid the binding will fail to open when this property is specified and set to a positive value.

Sending and Receiving from External Applications

Anchor
ExternalApplications
ExternalApplications

This section describes how to send to Talon applications from non-Talon applications and from Talon applications to non-Talon applications over solace. This is an uncommon use-case ... see Sending and Receiving Messages for information on sending from within a Talon application. The sections below utilize the ADM generated messages for convenience, but this is not required. For example, if your messages are encoded in protobuf (or Xbuf) you could encode/decode the message yourself without using ADM. One such example of this might be if you were using C and generated a protobuf message from the IDL generated by ADM. 

Sending Messages

The platform's Solace binding transports encoded messages in a BytesMessage. The encoded messages is set as the message data, and the metadata is stored as serialized MessageMetadata in the "x-sma-metadata" property. The example below shows how an external application can send a message natively using the solace JCSMP client:

Code Block
java
java
// populate a message
OrderEventMessage orderEvent = OrderEventMessage.create();
orderEvent.setOrderId(1);

// serialize the payload to a byte buffer
byte [] serializedPayload = view.serializeToByteArray();

// prepare message metadata
MessageMetadata metadata = MessageMetadataFactory.getInstance().createMessageMetadata();
metadata.serializeV2(view.getMessageEncodingType(),
                     view.getVfid(),
                     view.getType(),
                     0,  // message sender id
                     0,  // message flow
                     0,  // message sequence number (unsequenced)
                     -1, // channel id (unspecified)
                     XString.create("order-events"));

// prepare solace message
com.solacesystems.jcsmp.BytesMessage message = producer.createBytesMessage();
message.setData(serializedPayload);
message.setDeliveryMode(DeliveryMode.DIRECT);
SDTMap props = producer.createMap();
if (serializedMetadata != null) {
  props.putBytes("x-sma-metadata", serializedMetadata);
}
message.setProperties(props);

// send 
com.solacesystems.jcsmp.Topic topic = producer.createTopic("order-events");
producer.send(message, topic);

// dispose
orderEvent.dispose();
metadata.dispose(); 

Receiving Messages

The following code sample shows how an external application using the Solace JCSMP api directly can unpack a message sent over the platform's built in Solace binding and materialize it into a message view. 

Code Block
java
java
public void onMessage(BytesXMLMessage message) {
  if (!message instanceof if (message instanceof BytesMessage) {
     // not an x message. 
     handleNonXMessage(message);
     return;
  }
  BytesMessage message = (BytesMessage) message); 
 
  // extract sma metadata
  final SDTMap props = message.getProperties();
  final ByteBuffer serializedMetadata = null;
  if (props != null) {
    // metadata
    serializedMetadataBytes = props.getBytes("x-sma-metadata");
    if (serializedMetadataBytes != null) {
      serializedMetadata = ByteBuffer.wrap(serializedMetadataBytes);
    }
  }
 
  if(serializedMetadata == null) {
     // not an x message. 
     handleNonXMessage(message);
     return;
  }
  final byte encodingType = MessageMetadata.getMessageEncodingType(serializedMetadata);
  final short vfid = MessageMetadata.getMessageViewFactory(serializedMetadata)
  final short vtype = MessageMetadata.getMessageViewType(serializedMetadata)
 
  // extract payload
  byte [] payloadBytes = ((BytesMessage)message).getData();
  Object payload = payloadBytes ;
  if(encodingType == MessageView.ENCODING_TYPE_JSON) {
     payload = new String(payloadBytes);
  }
 
  // lookup factory
  // (assumes that view factory have already been registered)
  MessageViewFactory factory = viewFactoryRegistry.getMessageViewFactory(vfid);
  if (factory != null) {
    MessageView view = factory.wrap(vtype, encodingType, message);
    if(view instanceof OrderEventMessage) {
      handleOrderEvent((OrderEventMessage) message);
    }
  }
  else {
    handleNonXMessage(message); 
    return;
  }
}

Trace Logging

The Solace binding logs trace messages using the following loggers:

  • The nv.sma logger
  • The nv.sol logger

These loggers are configured like any other logger in the X runtime. Refer to Working with Logging for information on how to configure trace loggers.

The nv.sma logger

This logger is used to control the trace level and log trace messages emitted by the binding code i.e. as opposed to the Solace client library runtime code. 

The nv.sol logger

This logger is used to control the trace level and log messages emitted by the Solace client runtime. How this logger is used by the binding depends on whether binding is configured to use JNI or not. 

JNI Enabled (CCSMP)

The Solace binding uses the Solace CCSMP client library when configured to use JNI. In such a configuration, the binding performs the following steps related to the logging of trace messages emitted by the CCSMP runtime

  1. Use the nv.sol logger trace level to set the CCSMP runtime trace level
  2. Register a callback with the CCSMP runtime to intercept all trace messages emitted by CCSMP
  3. Log trace messages emitted by the CCSMP runtime using the nv.sol logger.

Regarding step 1, the following table specifies how the binding maps the nv.sol logger trace level to the CCSMP trace level

nv.sol Trace LevelCCSMP Trace Level
SEVEREERROR
WARNINGWARNING
INFONOTICE
CONFIGNOTICE
FINEINFO
FINERINFO
DIAGNOSEINFO
VERBOSEINFO
FINESTDEBUG
DEBUGDEBUG
ALLDEBUG
OFF

-

Regarding step 3, the binding uses the following table to determine the level used by the binding to log the message with the nv.sol logger

CCSMP Trace Levelnv.sol Trace Level
CRITICALSEVERE
ERRORSEVERE
WARNINGWARNING
NOTICEINFO
INFOFINE
DEBUGFINEST

JNI Disabled (JCSMP)

The Solace binding uses the Solace JCSMP client library when configured to not use JNI. In such a configuration, the binding performs the following steps related to the logging of trace messages emitted by the JCSMP runtime

  1. Use the nv.sol logger trace level to set the JCSMP logger's trace level
    1. The binding assumes that the JCSMP runtime uses a java.util.logging logger named com.solacesystems.jcsmp to perform its logging i.e. the binding uses the log level of the nv.sol logger to set the log level of the com.solacesystems.jcsmp logger and assumes that all logging done by the JCSMP runtime is done via this logger. The binding does not configure the com.solacesystems.jcsmp logger beyond setting its trace log level

Regarding step 1, the following table specifies how the binding maps the nv.sol logger trace level to the JCSMP logger trace level

nv.sol Trace Levelcom.solacesystems.jcsmp Trace Level
SEVERESEVERE
WARNINGWARNING
INFOINFO
CONFIGCONFIG
FINEFINE
FINERFINER
DIAGNOSEFINEST
VERBOSEFINEST
FINESTFINEST
DEBUGALL
ALLALL
OFF

-