Contents
Note
This document describes an outdated and deprecated set of JMS adapters. To use StreamBase's most up-to-date and fully supported JMS connectivity solution, see Using the JMS and TIBCO EMS Operators.
The TIBCO StreamBase® Legacy Adapter for JMS allows StreamBase to integrate with a JMS-compliant message bus. The Java Message Service (JMS) API is a Java message-oriented middleware API for sending messages between two or more clients.
The StreamBase JMS adapters work with a JMS-compliant message bus. Java Message Service (JMS) is an API orginally defined by Sun Microsystems (now part of Oracle Corporation) for invoking operations on enterprise messaging systems. The JMS specification allows for multiple implementations called JMS providers. The StreamBase JMS adapter works with the JMS implementation of any JMS provider, but must be configured differently for each provider. This document uses configuration examples from four JMS providers:
-
TIBCO Enterprise Messaging Service™ (EMS)
-
Apache ActiveMQ
-
IBM WebSphere Application Server
-
Solace Systems
If you are connecting to a JMS server from another JMS provider, you must adapt the configuration examples and discussion on this page for the particulars of your JMS provider.
The JMS Embedded Input Adapter is called the JMS Reader on this page. The JMS Reader is an embedded adapter that subscribes to messages from a JMS message bus.
The JMS Embedded Output Adapter is called the JMS Writer on this page. The JMS Writer is an embedded adapter that publishes messages to a JMS message bus.
An embedded adapter is an adapter that runs in the same process as StreamBase Server. The JMS Reader listens for messages from a JMS Message bus. When it receives a message, the JMS Reader creates a tuple from the message, and then sends that tuple to the operator that is downstream from it in its StreamBase application. Conversely, the JMS Writer receives tuples from StreamBase Server, creates a JMS message from it, and publishes it to the JMS Message bus.
The JMS Embedded Adapters serialize the messages they receive. That is, the StreamBase Server will process messages in the same order as they are initially received by the JMS Reader, and the JMS broker will be sent messages in the same order that the corresponding tuples are received by the JMS Writer.
The adapters have many options for configuring connections and messages, described in The JMS Embedded Adapters' Configuration File. You can edit a JMS configuration file's XML syntax directly or graphically using the JMS Configuration File Editor.
By default, the JMS adapters only try to connect to a JNDI or JMS server one time before giving up. However, you can configure
the adapter to retry the connection a certain number of times at set intervals before giving up. To do this, set the server-num-retries
and server-reconnect-interval
attributes of the relevant <jms-server>
section in the adapter's configuration file. The server-num-retries
attribute controls the number of times the adapter will try to connect before giving up. The default value of this attribute
is 0, which specifies no retries; the maximum value is MAX_INT. The server-reconnect-interval
attribute controls the number of seconds to wait between connection attempts. The default value is 30 seconds.
Note that these values apply to both the JNDI and JMS servers configured in this <jms-server>
section.
This functionality, used in conjunction with the Command Input and Status Output ports described here, can be used to implement logic to fully control the adapter's connection logic to the JMS servers it is configured to use.
When the JMS Reader receives a message, it translates this message into a Tuple and when the JMS Writer receives a Tuple,
it translates it into a JMS message. There are five JMS message types: MapMessage
, TextMessage
, BytesMessage
, ObjectMessage
and StreamMessage
. The JMS adapters include built-in support for the first three of these; this support is described in this section.
The message translation class used by the adapter for a given destination is specified using its fully-qualified Java class
name in the <destination>
tag's message-to-tuple-converter
attribute (for JMS Readers) or tuple-to-message-converter
(for JMS Writers) -- see JMS Configuration File Elements for examples.
Converter class names:
-
com.streambase.sb.adapter.common.jms.enqueue.DefaultFromJMSMapMessageConverter
(JMS Reader) -
com.streambase.sb.adapter.common.jms.dequeue.DefaultToJMSMapMessageConverter
(JMS Writer)
MapMessage
is the type into which tuples translate most readily. Like a tuple, a MapMessage
is a set of name-value pairs, making the translation of these two message types relatively straightforward. The JMS Reader
includes a class that converts JMS MapMessages
to StreamBase tuples, com.streambase.sb.adapter.common.jms.enqueue.DefaultFromJMSMapMessageConverter
. Similarly the JMS Writer adapter provides com.streambase.sb.adapter.common.jms.dequeue.DefaultToJMSMapMessageConverter
to translate from a Tuple to a JMS MapMessages
.
StreamBase tuples and JMS MapMessages are essentially collections of name-value pairs. The JMS Reader pairs the fields held
by a JMS MapMessage
with fields in a StreamBase schema that have the same names and compatible types. If the name of a field in the MapMessage
doesn't exist in the StreamBase schema then that field is dropped. Similarly, if the name of a field in the Schema doesn't
exist in the MapMessage then there is no input value for that field and it is nulled.
In the case of the JMS Writer, all fields in the incoming Tuple are added to the MapMessage.
Converter class names:
-
com.streambase.sb.adapter.common.jms.enqueue.DefaultFromJMSTextMessageConverter
(JMS Reader) -
com.streambase.sb.adapter.common.jms.dequeue.DefaultToJMSTextMessageConverter
(JMS Writer)
TextMessages
only contain one field, used to carry a text-only payload. The JMS Reader adapter will look for a suitable field (of type
STRING
) in its output schema to contain the payload of an incoming message using the following heuristics:
-
If a
converter-custom-settings
attribute was specified for this destination, its value will be taken as the name of the StreamBase field to use. -
If the above search fails but a field named
text
,Text
,payload
orPayload
is present, this will be used. -
If neither of the above searches have yielded an appropriate candidate, the first field of type
STRING
in the schema will be used.
The same heuristics will be employed by the JMS Writer adapter to locate the payload of incoming tuples to place in the outgoing JMS message.
Note
A common usage idiom for JMS TextMessages is to place XML data in the text payload of the message. This can easily be accommodated in a StreamBase application by combining the JMS adapters with the XML-To-Tuple and Tuple-To-XML operators to decode/encode the XML payloads.
Converter class names:
-
com.streambase.sb.adapter.common.jms.enqueue.DefaultFromJMSBytesMessageConverter
(JMS Reader) -
com.streambase.sb.adapter.common.jms.dequeue.DefaultToJMSBytesMessageConverter
(JMS Writer)
BytesMessages
only contain one field, used to carry a binary payload. The JMS Reader adapter will use the same heuristics as for the TextMessage
converters to look for a suitable field (of type BLOB
) in its output schema to contain the payload of an incoming message:
-
If a
converter-custom-settings
attribute was specified for this destination, its value will be taken as the name of the StreamBase field to use. -
If the above search fails but a field named
bytes
,Bytes
,payload
orPayload
is present, this will be used. -
If neither of the above searches have yielded an appropriate candidate, the first field of type
BLOB
in the schema will be used.
The same heuristics will be employed by the JMS Writer adapter to locate the BLOB
payload of incoming tuples to place in the outgoing JMS message.
Converter class names:
-
com.streambase.sb.adapter.common.jms.enqueue.DefaultFromJMSSimpleMessageConverter
(JMS Reader) -
com.streambase.sb.adapter.common.jms.dequeue.DefaultToJMSSimpleMessageConverter
(JMS Writer)
So-called "simple" JMS messages (returned when calling javax.jms.Session.createMessage()
) contain no body fields. The JMS Reader adapter will produce a tuple containing only the message's header fields (if any
are configured in the schema).
Similarly, the JMS Writer adapter will send a JMS message with no body payload.
Interface class names:
-
com.streambase.sb.adapter.common.jms.enqueue.FromJMSMessageConverter
(JMS Reader) -
com.streambase.sb.adapter.common.jms.dequeue.ToJMSMessageConverter
(JMS Writer)
An interface is used to represent a class that can convert a JMS Message to a StreamBase tuple. This interface, com.streambase.sb.adapter.common.jms.enqueue.FromJMSMessageConverter
, includes a method, Object convertFromJMSMessage(Message message) throws StreamBaseException
that provides the implementation of the translation. A different translation class can be implemented, and the JMS Reader
can then be configured to use this implementation. In this way, a converter to translate one of the other JMS message types
can be specified, or an alternate implementation of an existing converter can be specified.
As expected, the JMS Writer also provides a similar interface, com.streambase.sb.adapter.common.jms.dequeue.ToJMSMessageConverter
which includes the Message convertToJMSMessage(Object object) throws StreamBaseException
method to do the opposite conversion.
A JMS message consists of two primary pieces, a header and a payload (body). In addition, properties can be set on a JMS message.
By default, the JMS Embedded Adapters map the fields of a MapMessage to the fields of a StreamBase schema. The JMS Reader looks for entries in the payload of a MapMessage that have the same names as the fields of the StreamBase schema. The JMS Writer simply creates entries in the outgoing Message to match all the fields of the incoming StreamBase schema.
The JMS Embedded Adapters also provide facilities for handling other mappings, specified in the configuration file. For example, a name map can be used to map a field on a MapMessage to a field on a StreamBase schema that has a different name. Similarly, the fields in the header of a JMS message can be mapped to the fields of a StreamBase schema. In the same way, JMS properties can also be mapped to the fields of a StreamBase schema.
Note
Some JMS message headers are read-only. As such, the JMS Writer will not be able to change them even if there is an entry to that effect in the header map. When configuring header maps for use by the JMS Writer, keep in mind that only the following headers are mutable:
-
JMSCorrelationID
-
JMSReplyTo
An attempt to map any other headers for the JMS Writer results in an error.
Because the JMS Reader simply reads the JMS headers, all headers can be mapped.
The JMS Reader consumes messages from JMS destinations. The manner in which these messages are acknowledged is configurable within the JMS Reader. The setting for the acknowledge mode can impact the performance of the reader.
The JMS Reader fully supports acknowledge modes of AUTO_ACKNOWLEDGE
and DUPS_OK_ACKNOWLEDGE
. The reader also fully supports the use of TIBCO EMS' proprietary acknowledge mode, NO_ACKNOWLEDGE
. Of course, use of this acknowledge mode implies that TIBCO's EMS message bus is being used with the reader. The JMS Reader
only partially supports CLIENT_ACKNOWLEDGE
, TIBCO EMS' EXPLICIT_CLIENT_ACKNOWLEDGE
and Apache ActiveMQ's INDIVIDUAL_ACKNOWLEDGE
; while there is no way for the StreamBase application to trigger an explicit acknowledgement of the message, if one of these
modes is selected the adapter will wait until the tuple is fully processed by the application before acknowledging the message.
This gives the application a chance to, for example, persist the message to ensure later retrieval if needed.
The acknowledge mode for a given JMS server is specified in the <jms-server>
section of the configuration file, using the attribute <acknowledge-mode>
.
Note also that the JMS Reader makes no effort to prevent or in any way handle the delivery of duplicate JMS messages. If a JMS server delivers the same message twice, the JMS Reader will simply consume it twice.
The JMS Writer will create JMS messages and deliver them to a JMS message bus. JMS messages can be delivered with either of
two delivery modes, DeliveryMode.PERSISTENT
or DeliveryMode.NON_PERSISTENT
. The delivery mode for a JMS destination is specified in the destination section of the configuration file, using the delivery-mode
attribute.
The semantics of JMS delivery modes is beyond the scope of this discussion. In general, a delivery mode of PERSISTENT
implies a higher quality of service for the JMS destination. Some performance penalty is also implied, however. In particular,
if a delivery mode of PERSISTENT
is specified, and there are durable subscribers for the message, then the JMS message will need to be persisted before the
JMS server can acknowledge the message producer.
Note
for TIBCO EMS users: an additional EMS-specific delivery mode is supported, RELIABLE_DELIVERY
.
The JMS Writer dequeues tuples from StreamBase streams, translates them into JMS messages, and routes them to JMS destinations.
The adapter relies on two fields in the dequeued tuple to determine which destination on which JMS server to send the translated
message. The two fields must be called __JMSServerName
and __JMSDestinationName
. These fields must contain the name of a configured JMS server and destination, respectively. These fields are optional if
only one destination is specified in the configuration; they are required if the configuration specifies more than one destination
(that is, more than one server or more than one destination in a single server).
When one of the JMS Embedded Adapters executes, it needs to connect to an executing instance of a JMS message bus. Typically, this bus will be from one of the JMS providers. In order to connect to the JMS provider's JMS bus, JAR files supplied by the JMS provider must be made available to the JMS Adapters. This is true whether the adapter is executing from within StreamBase Studio or at a command-line invocation of StreamBase Server:
-
If the adapter is started from Studio, then the vendor's JMS JAR file or files must be imported into the Studio project or added to the Java Build Path of the Studio project.
-
If the adapter is executed from a command-line invocation of StreamBase Server, then the location of the vendor's JAR file or files must be specified in the
<java-vm>
section of the server's configuration file. -
As an alternative, you can instead copy the JAR files to
, which will make them available to both StreamBase Studio and StreamBase Server.streambase-install-dir
/lib/ext
- Examples for ActiveMQ users:
-
The following JAR files must be made available to StreamBase Studio and/or to StreamBase Server in order to successfully connect to an ActiveMQ server:
-
(adjusting filename for your installed version of ActiveMQ)activemq_installdir
/lib/activemq-core-5.10.0.jar -
activemq_installdir
/lib/geronimo-j2ee-management_1.1_spec-1.0.1.jar -
activemq_installdir
/lib/hawtbuf-1.10.jar
-
- Examples for TIBCO EMS users:
-
The following JAR file must be made available to StreamBase Studio and/or to StreamBase Server in order to successfully connect to a TIBCO EMS server:
-
TIBCO_EMS_installdir
/lib/tibjms.jar -
TIBCO_EMS_installdir
/lib/jms-2.0.jar
-
- Examples for Solace JMS users:
-
The following JAR files must be made available to StreamBase Studio and/or to StreamBase Server in order to successfully connect to a Solace JMS server:
-
STREAMBASE_installdir
/lib/ext/commons-lang-2.2.jar -
(adjusting filename for your installed version of Solace)STREAMBASE_installdir
/lib/ext/sol-common-5.1.1.1.jar -
(adjusting filename for your installed version of Solace)STREAMBASE_installdir
/lib/ext/sol-jcsmp-5.1.1.1.jar -
(adjusting filename for your installed version of Solace)STREAMBASE_installdir
/lib/ext/sol-jms-5.1.1.1.jar
-
Important
Regardless of the JMS vendor used, you must also provide a copy of jms.jar
. This file should be included in your JMS vendor's product installation alongside its other JAR files such as those mentioned
above.
Settings are used to control most of the behavior of the adapter. The settings are grouped under several tabs in the Properties view in StreamBase Studio.
In the table in this section, the Property column shows each property name as found in the one or more adapter properties tabs of the Properties view for this adapter.
When using this adapter in a StreamSQL program with the APPLY JAVA statement, you may refer to property names using the StreamSQL parameter name, also included in the Property column.
Name: Use this field to specify or change the component's name, which must be unique in the application. The name must contain only alphabetic characters, numbers, and underscores, and no hyphens or other special characters. The first character must be alphabetic or an underscore.
Adapter: A read-only field that shows the formal name of the adapter.
Class: A field that shows the fully qualified class name that implements the functionality of this adapter. Use this class name when loading the adapter in StreamSQL programs with the APPLY JAVA statement. You can right-click this field and select Copy from the context menu to place the full class name in the system clipboard.
Start with application: If this field is set to Yes or to a module parameter that evaluates to true, an instance of this adapter starts as part of the containing StreamBase Server. If this field is set to No or to a module parameter that evaluates to false, the adapter is loaded with the server, but does not start until you send an sbadmin resume command, or until you start the component with StreamBase Manager. With this option set to No or false, the adapter does not start even if the application as a whole is suspended and later resumed. The recommended setting is selected by default.
Enable Error Output Port: Select this check box to add an Error Port to this component. In the EventFlow canvas, the Error Port shows as a red output port, always the last port for the component. See Using Error Ports and Error Streams to learn about Error Ports.
Description: Optionally enter text to briefly describe the component's purpose and function. In the EventFlow canvas, you can see the description by pressing Ctrl while the component's tooltip is displayed.
There is only one required property for either of the JMS Embedded Adapters: its configuration file. Configuration of the adapter is fairly involved, and so is not accomplished through its properties, but rather through its configuration file. Keep in mind that just the name of the configuration file, rather than its path, should be specified in the property. The named file will be searched for using the path specified in the configuration for StreamBase itself.
There are also two optional properties to control whether the adapter should accept JMS connection/disconnection commands from the application and whether status tuples should be issued when JMS servers or destinations become available or unavailable.
The JMS Reader is similar to an input stream that gets its input from a JMS Message bus. As with an input stream, a Schema needs to be specified for the JMS Reader. The Schema used by the JMS Reader is specified in the Edit Schema tab of the Properties View in StreamBase Studio.
Property | Description | Default |
---|---|---|
Configuration File (required string)
StreamSQL name: |
The name of the adapter configuration file. | None |
Capture Transform Strategy | The strategy to use when transforming capture fields for this operator: FLATTEN or NEST. | FLATTEN |
Log On When Application Starts (optional)
StreamSQL name: |
When set, the adapter will attempt to connect to the configured server(s) when the applications is started. Otherwise the adapter will wait for an explicit "Connect" command (see Command Input Port Schema) before attempting connection. | True |
Add Command Input Port (optional)
StreamSQL name: |
If checked, this option will cause the adapter to expose a new input port that will be used to receive commands from the application.
The schema and semantics of this port are described below. |
None |
Add JMS Status OutputPort (optional)
StreamSQL name: |
If checked, this option causes the adapter to expose a new output port used to send status tuples when interesting events
occur on the configured JMS server(s).
The schema and semantics of this port are described below. |
None |
Log Level | Controls the level of verbosity the adapter uses to send notifications to the console. This setting can be higher than the containing application's log level. If set lower, the system log level will be used. Available values, in increasing order of verbosity, are: OFF, ERROR, WARN, INFO, DEBUG, TRACE, and ALL. | INFO |
Log Level (optional)
StreamSQL name: |
Controls the level of verbosity the adapter uses to issue informational traces to the console. This setting is independent of the containing application's overall log level. Available values, in increasing order of verbosity, are: OFF, ERROR, WARN, INFO, DEBUG, TRACE, and ALL. | INFO |
Log Full Callstacks (optional)
StreamSQL name: |
When set, the adapter will print full call stacks when an exception happens, regardless of the Log Level set above. Otherwise only an exception's message will be printed unless the Log Level is DEBUG. | False |
The JMS Embedded Adapters are configured using an XML configuration file having a .jmsconf
file extension. This configuration file consists of two types of information, JMS configuration and configuration concerning
the translation of JMS messages to tuples and back.
You can edit a JMS configuration file's XML syntax directly or graphically using the JMS Configuration File Editor.
It may be that many JMS destinations need to be specified in the configuration file for the JMS Embedded Adapters. Where applicable, it is possible to specify a default value for a configuration attribute of a destination. The default can then be overridden by specifying a value for a particular destination.
A sample configuration file for both the JMS Reader and JMS Writer are included with the JMS sample that is included in the
StreamBase distribution, under the configurationFileReference
subdirectory of the sample. These files include comments describing the various XML elements and attributes that make up
the configuration. These sample configuration files can be used as a template for configuration files. These files can also
be obtained by executing the jmsadapter.jar
JAR file. For Linux:
java -jar streambase-install-dir
/lib/adapter/jmsadapter.jar reader
For Windows:
java -jar "streambase-install-dir
\lib\adapter\jmsadapter.jar reader"
Similarly, the JMS Writer has a sample configuration file which can be displayed by executing the jmsadapter.jar
JAR file with a different parameter. For Linux:
java -jar streambase-install-dir
/lib/adapter/jmsadapter.jar writer
For Windows:
java -jar "streambase-install-dir
\lib\adapter\jmsadapter.jar writer"
Here are some typical settings for connecting to JMS servers from TIBCO EMS, ActiveMQ, IBM WebSphere, and Solace Systems:
TIBCO EMS (using JNDI)
<jms-servers> <jms-server name="EMSServer" provider-context-factory="com.tibco.tibjms.naming.TibjmsInitialContextFactory" provider-url="tibjmsnaming://localhost:7222" connection-factory-name="ConnectionFactory" acknowledge-mode="NO_ACKNOWLEDGE"/> </jms-servers>
ActiveMQ version 5.x (using JNDI)
<jms-servers> <jms-server name="ActiveMQServer" provider-context-factory="org.apache.activemq.jndi.ActiveMQInitialContextFactory" provider-url="tcp://localhost:61616" connection-factory-name="ConnectionFactory" acknowledge-mode="AUTO_ACKNOWLEDGE"/> </jms-servers>
IBM WebSphere Application Server version 6.1's Default JMS Implementation (using JNDI)
<jms-servers> <jms-server name="server1" provider-context-factory="com.ibm.websphere.naming.WsnInitialContextFactory" provider-url="iiop://localhost:2809" connection-factory-name="jms/MyConnFactory" jndi-initial-context-builder="com.streambase.sb.adapter.common.jms.common.WASJNDIInitialContextBuilder" create-destinations="false" acknowledge-mode="AUTO_ACKNOWLEDGE"/> </jms-servers>
Solace default JMS Implementation (using JNDI)
<jms-servers> <jms-server name="solaceJms" provider-context-factory="com.solacesystems.jndi.SolJNDIInitialContextFactory" provider-url="smf://MyProviderHost:MyProviderPort" connection-factory-name="MyConnFactory" acknowledge-mode="AUTO_ACKNOWLEDGE" jndi-security-principal="MySecurityPrincipal" jndi-security-credentials="MySecurityCredentials" jndi-initial-context-builder="com.streambase.sb.adapter.common.jms.common.SolaceJNDIInitialContextBuilder" username="MyUsername" create-destinations="true" password="MyPassword" > <jndi-extra-properties> <extra-property name='Solace_JMS_OptimizeDirect' value='false'/> <extra-property name='Solace_JMS_VPN' value='MyJmsVpn'/> </jndi-extra-properties> </jms-server> </jms-servers>
The JMS configuration file is in XML format. For reference, the following listing shows the complete set of valid elements for the JMS input configuration file.
<?xml version="1.0" encoding="UTF-8"?> <sb-jms-adapter-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.streambase.com/schemas/sbjmsreader/" adapter-class="com.streambase.sb.adapter.jms.enqueue.JMSReader" > <!-- NAME MAPS By default, this adapter will match JMS fields with StreamBase fields when they share the same name. This behavior can be overridden with a 'name map'. A name map is used to associate a JMS field and a StreamBase field when they do not share the same name. A set of name maps can be specified. Each configured destination can use a different name map. Name maps are themselves named and are referred to by name. --> <name-maps> <name-map name="MyNameMap"> <!-- A name map consists of a set of mappings, each associates a JMS field with a StreamBase field that has a different name. --> <mapping jms-name="symbol" sb-name="ticker_symbol"/> <mapping jms-name="bid" sb-name="value"/> </name-map> <!-- A second name map. --> <name-map name="MSFTConversion"> <mapping jms-name="MSFTsymbol" sb-name="ticker_symbol"/> </name-map> </name-maps> <!-- If many destinations use the same name map, it may be convenient to specify a default. --> <default-name-map>MyNameMap</default-name-map> <!-- JMS HEADER MAPS A JMS message is delivered with a set of standard JMS header fields. Header fields can be mapped to StreamBase fields using a jms-header-map. A set of header maps can be specified. Each configured destination can use a different header map. Header maps are named and are referred to by name. --> <jms-header-maps> <jms-header-map name="MyHeaderMap"> <!-- A JMS header map consists of a set of mappings. Each mapping associates a JMS header with a StreamBase field. The value of the JMS header field will be written to the StreamBase field. --> <mapping jms-name="JMSTimestamp" sb-name="jms_timestamp"/> </jms-header-map> </jms-header-maps> <!-- If many destinations use the same header map, it may be convenient to specify a default. --> <default-jms-header-map>MyHeaderMap</default-jms-header-map> <!-- JMS PROPERTY MAPS Either a JMS provider or a message creator can add properties to a JMS message. Properties can be thought of as provider or user defined headers. As with headers, a map is used to associate a property with a StreamBase field. A mapping associates a JMS property with a StreamBase field, causing the value of the property to be written to the StreamBase field. A set of property maps can be specified. Each configured destination can use a different property map. Property maps are named and are referred to by name. --> <jms-property-maps> <jms-property-map name="MyJMSPropertyMap"> <!-- A JMS property map consists of a set of mappings. Each mapping associates a JMS property with a StreamBase field. The value of the JMS property will be written to the StreamBase field. --> <mapping jms-name="StartTime" sb-name="start_time"/> <mapping jms-name="EndTime" sb-name="end_time"/> </jms-property-map> </jms-property-maps> <!-- If many destinations use the same property map, it may be convenient to specify a default. --> <default-jms-property-map>MyJMSPropertyMap</default-jms-property-map> <!-- TIMESTAMP FORMATS StreamBase represents a timestamp as a type com.streambase.sb.Timestamp. Fields, properties or headers delivered in a JMS message may represent timestamps, but they will not be of this type. A timestamp format can be used when a JMS field, header, or property delivers a timestamp that is represented as a string. The timestamp format is used to specify the format of the string so that it can be translated to a com.streambase.sb.Timestamp. A set of timestamp formats can be specified. Each configured destination can use a different timestamp format. Timestamp formats are named and are referred to by name. --> <timestamp-formats> <timestamp-format name="MyTimestampFormat" format="MM/dd/yyyy hh:mm:ss aa"/> </timestamp-formats> <!-- If many destinations use the same timestamp format, it may be convenient to specify a default. --> <default-timestamp-format>MyTimestampFormat</default-timestamp-format> <!-- DEFAULT DELIVERY TIME FIELD It may be useful to mark a StreamBase tuple with a timestamp indicating when the tuple was delivered to the StreamBase application. The delivery time attribute is used to specify a field on the StreamBase tuple to mark with the delivery time. If many destinations set the same delivery time field, it may be convenient to set a default. --> <default-delivery-time-field>arrival_time</default-delivery-time-field> <!-- DEFAULT MESSAGE TO TUPLE CONVERTER This adapter converts JMS messages to StreamBase tuples. The software responsible for this functionality is represented by an interface, com.streambase.sb.adapter.common.jms.enqueue.FromJMSMessageConverter. A default implementation of FromJMSMessageConverter is supplied. It may be that a custom implementation of FromJMSMessageConverter is needed however. For each configured destination, it is possible to specify a custom implementation of FromJMSMessageConverter. If many destinations set the same FromJMSMessageConverter, it may be convenient to set a default value. --> <default-message-to-tuple-converter>com.streambase.sb.adapter.common.jms.enqueue.DefaultFromJMSMapMessageConverter</default-message-to-tuple-converter> <!-- DEFAULT CONVERTER CUSTOM SETTINGS If many destinations set the same converter custom settings, it may be convenient to set a default. Because the format of this string is arbitrary, some care should be taken to keep it valid within this XML file. For example, embedding a "greater than" sign may require the use of ">" --> <default-converter-custom-settings>Insert your default custom settings here</default-converter-custom-settings> <!-- JMS SERVERS This adapter subscribes to messages from one or more JMS message buses. Each JMS message bus is configured using a jms-server element in this config file. --> <jms-servers> <!-- JMS SERVER A JMS server is configured using the attributes of the jms-server element. Two different sets of attributes are supported, one for connecting to a JMS server using JNDI, and one for connecting to a JMS server without using JNDI. Name is used in either case. - name: Each JMS server is named and can be referred to by name. This parameter is required. To connect to a JMS server using JNDI (LDAP, etc.) an initial JNDI Context is instantiated using values for Context.INITIAL_CONTEXT_FACTORY and Context.PROVIDER_URL (among others; see below.) Values for these are specified as attributes on the JMS server element: - provider-context-factory: This attribute is used to specify a value for Context.INITIAL_CONTEXT_FACTORY. This parameter is required. - provider-url: This attribute is used to specify a value for Context.PROVIDER_URL. This parameter is required. - connection-factory-name: A connection factory to be looked up by name via a JNDI lookup. This will then be used to construct the connection object. This parameter is required. In addition, a host of optional settings are available to help set up the proper InitialContext for JNDI lookups: - jndi-security-principal: Corresponds to javax.naming.Context.SECURITY_PRINCIPAL - jndi-security-credentials: Corresponds to javax.naming.Context.SECURITY_CREDENTIALS - jndi-security-authentication: Corresponds to javax.naming.Context.SECURITY_AUTHENTICATION - jndi-security-protocol: Corresponds to javax.naming.Context.SECURITY_PROTOCOL - jndi-authoritative: Corresponds to javax.naming.Context.AUTHORITATIVE - jndi-dns-url: Corresponds to javax.naming.Context.DNS_URL - jndi-referral: Corresponds to javax.naming.Context.REFERRAL - jndi-initial-context-builder: Full-qualified name of the Java class implementing com.streambase.sb.adapter.common.jms.common.JNDIInitialContextBuilder, which is responsible for creating the JNDI InitialContext object based on the settings described here. - jndi-extra-properties: Defines additional properties that may be required beyond those defined in javax.naming.Context. This latter node is expected to contain an arbitrary number of sub-nodes named 'extra-property' with attributes named 'name' and 'value'. To connect to JMS WITHOUT using JNDI, you must specify the name of a class implementing javax.jms.ConnectionFactory, as well as the URL to use: - connection-factory-class: The name of the connection factory class to instantiate. It is assumed that this class implements a constructor taking one String parameter that represents the URL of the JMS broker. - connection-factory-url: The broker URL to pass to the connection factory at construction time. The following optional settings are available to help create and manage a connection to JMS: - client-id: If desired, a specific ClientID value may be set on the connection. This will result in the adapter calling javax.jms.Connection.setClientID() with the supplied value. - subscriber-name: If specified, causes a durable subscription to be made/used with the specified subscriber name. Valid only when used in conjunction with destinations that are Topics. - username: The username to use when connecting to JMS. - password: The password to use when connecting to JMS. - acknowledge-mode: The mode that is used to acknowledge JMS messages. Defaults to AUTO_ACKNOWLEDGE. Other values include: - DUPS_OK_ACKNOWLEDGE - CLIENT_ACKNOWLEDGE - NO_ACKNOWLEDGE (TIBCO EMS-specific) - EXPLICIT_CLIENT_ACKNOWLEDGE (TIBCO EMS-specific) - EXPLICIT_CLIENT_DUPS_OK_ACKNOWLEDGE (TIBCO EMS-specific) - INDIVIDUAL_ACKNOWLEDGE (Apache ActiveMQ-specific) - create-destinations: Whether destinations should be created or looked up in JNDI. If supported by the JMS provider, destinations can be created even if they exist. Creating destinations is faster than looking them up in JNDI. By default destinations are created. - cache-destinations: Whether destinations should be cached once created. The default value of "true" offers better performance, however if you are creating thousands of destinations caching them may adversely affect your memory footprint. - use-topics: If this attribute is true, then destinations will be treated as Topics, otherwise they will be treated as Queues. The default is to treat destinations as Topics (i.e. "true"). - server-num-retries: The number of times the adapter should retry to connect to the JMS server (and/or the JNDI server) before giving up. Negative values are not allowed, and the highest allowed value is 2147483647 (Java's Integer.MAX_VALUE). - server-reconnect-interval: The number of seconds to wait between each connection retry. - destination-monitor-interval: The number of milliseconds to wait between attempts to monitor the health of subscribed destinations on this server. A value of 0 (which is the default) indicates no monitoring should be attempted, and so the StreamBase application will never be notified of availability/unavailability of destinations on this server. - connection-builder: The fully-qualified name of a class that implements com.streambase.sb.adapter.common.jms.common.ConnectionBuilderInterface, which will be responsible for creating and initializing JMS Connection objects. If this parameter is not specified, the adapter's default implementation will be used. You may use the "custom-settings" attribute (see below) to pass along arbitrary strings to this class. - custom-settings: An arbitrary string passed verbatim to the implementer of the CustomConnectionBuilder interface (see the connection-builder attribute above.) DEFAULT VALUES FOR JMS-SERVERS SECTION It may be convenient to set default values for some of the settings above. These will be used for every jms-server entry below unless noted otherwise. Available default settings are: - default-server-num-retries - default-server-reconnect-interval - default-client-id - default-subscriber-name - default-jndi-security-principal - default-jndi-security-credentials - default-jndi-security-authentication - default-jndi-security-protocol - default-jndi-authoritative - default-jndi-dns-url - default-jndi-referral - default-connection-builder - default-jms-server-custom-settings - default-destination-monitor-interval - default-jndi-initial-context-builder - default-jndi-extra-properties This latter contains sub-nodes called 'extra-property', whose 'name' and 'value' attributes are passed to the JNDI InitialContext as additional environment properties. This can be useful when dealing with JNDI providers that require custom environment properties beyond those defined in the javax.naming.Context interface. --> <default-jndi-security-principal>MySecurityPrincipal</default-jndi-security-principal> <default-jndi-extra-properties> <extra-property name="DefaultSetting1" value="Value1" /> <extra-property name="DefaultSetting2" value="Value2" /> </default-jndi-extra-properties> <jms-server name="EMS-SERVER" description="This describes the JMS server" provider-name="TIBCO EMS" provider-context-factory="com.tibco.tibjms.naming.TibjmsInitialContextFactory" provider-url="tibjmsnaming://localhost:7222" connection-factory-name="GenericConnectionFactory" acknowledge-mode="NO_ACKNOWLEDGE" create-destinations="true" server-num-retries="3" server-reconnect-interval="5" use-topics="true"> <!-- To connect to the server without using JNDI, specify connection-factory-class and connection-factory-url. --> <!-- <jms-server name="tibcoServer2" create-destinations="true" use-topics="true" connection-factory-class="com.tibco.tibjms.TibjmsTopicConnectionFactory" connection-factory-url="localhost"/> --> <!-- These (optional) settings will be passed to the JNDI InitialContext as additional Context environment properties. This can be useful when the JNDI service provider requires custom properties in addition to the standard properties defined in the javax.naming.Context interface. --> <jndi-extra-properties> <extra-property name="Setting1" value="Value1" /> <extra-property name="Setting2" value="Value2" /> </jndi-extra-properties> <!-- The set of destinations on this JMS server that the adapter subscribes to is listed here. --> <destinations> <!-- Each destination is configured with a set of attributes. A default is provided where possible as there may be many destinations. If an attribute is left unspecified for a destination, then the default value of that attribute is used. For example, if the name map is left unspecified then the default name map is used. If the attribute is left unspecified and no default is specified, then the associated operation is not done. For example, if no name map is specified and there is no default name map, then no name mapping is done. - name: A destination is created or looked by name. - is-topic: 'true' if this destination is a topic, 'false' if it's a queue. - message-selector: The message selector expression (if any) to use for this destination. - name-map: The name map used for this destination. If specified, the name map must be included in 'name-maps'. - jms-header-map: The header map used for this destination. If specified, the header map must be included in 'jms-header-maps'. - jms-property-map: The property map used for this destination. If specified, the property map must be included in 'jms-property-maps'. - timestamp-format: The string format used by timestamp fields delivered by this destination. The timestamp format must be specified in the timestamp-formats section. - delivery-time-field: The field on the StreamBase tuple that will be marked with the delivery time. - message-to-tuple-converter: The class used to translate JMS messages to StreamBase tuples. If message-to-tuple-converter is not specified, then default-message-to-tuple-converter is used. - converter-custom-settings: This is a string that is passed verbatim to the specified message-to-tuple-converter. It allows implementers to pass arbitrary values to their converter. The implementing converter code is the sole responsible for parsing and interpreting this string. --> <destination name="topics.IN.MSFT" name-map="MSFTConversion" jms-header-map="MyHeaderMap" jms-property-map="MyJMSPropertyMap" timestamp-format="MyTimestampFormat" delivery-time-field="arrival_time" converter-custom-settings="ArbitraryKey=ArbitraryValue,AnotherKey=AnotherValue" message-to-tuple-converter="com.streambase.sb.adapter.common.jms.enqueue.DefaultFromJMSMapMessageConverter" is-topic="true" /> <!-- In addition to explicit destination definitions handled by the <destination> tags, a <default-destination> may be specified which will be used when creating new destinations (i.e. when the <jms-server create-destinations=true />). The syntax is the same as for the <destination> tag above except the 'name' attribute is ignored. At most ONE <default-destination> tag may be specified for each <jms-server>. --> <default-destination name-map="MyNameMap" jms-header-map="MyHeaderMap" jms-property-map="MyJMSPropertyMap" timestamp-format="MyTimestampFormat" delivery-time-field="arrival_time" converter-custom-settings="" message-to-tuple-converter="com.streambase.sb.adapter.common.jms.enqueue.DefaultFromJMSMapMessageConverter" /> </destinations> </jms-server> </jms-servers> </sb-jms-adapter-config>
The command input port may be used by the application to request connections or disconnections to a configured JMS server, or to pause or resume processing for a JMS destination.
If the adapter is configured to expose a command input port, its schema is expected to have the following fields:
Field Name | Type | Description | Required |
---|---|---|---|
server |
string | The name of the JMS server to which this command applies. | Yes |
destination |
string | The name of the JMS destination to which this command applies. This field may be left null if the command applies to the entire server instead of a single destination. | Yes |
command |
string | The actual command to execute. Accepted values are described below. Note that case is unimportant. | Yes |
Permitted values for the command
field are the following (case is unimportant):
-
Connect
: Establish a connection to the specified JMS server. Attempting to connect to an already-connected JMS server has no effect. When usingConnect
, thedestination
field is ignored and can be left null. -
Disconnect
: Sever the connection to the specified JMS server. Disconnecting from an already-disconnected JMS server has no effect. When usingDisconnect
, thedestination
field is ignored and can be left null. -
Pause
: For an enqueuing adapter, JMS messages are still read from the specified destination on the specified server but are longer converted to tuples and sent to the application. For a dequeuing adapter, tuples are still dequeued from the application's stream, but are no longer converted to JMS messages and sent to the specified destination on the specified server. Pausing an already-paused destination has no effect. -
Resume
: For an enqueuing adapter, JMS messages are read from the specified destination on the specified server, and will now be converted to tuples and sent to the application. For an dequeuing adapter, tuples dequeued from the application's stream are now converted to JMS messages and sent to the specified destination on the specified server. Resuming an already-resumed destination has no effect. -
CreateDestination
: This command is only recognized by enqueuing adapters. It will cause the adapter to attempt to create the specified destination on the specified JMS server (or on all configured JMS Servers if theserver
field is leftnull
). This command will only be successful if thecreate-destinations="true"
attribute was specified in the configuration file's JMS server definition, and adefault-destination
section was also specified for that server (see Dynamic Endpoints).
The status output port can be used by the application to receive tuples describing status events for configured JMS servers (connection and disconnection) and optionally for destinations (available or unavailable.)
If the adapter is configured to expose a status output port, its schema has the following fields:
Field Name | Type | Description | Required |
---|---|---|---|
server |
string | The name of the JMS server on which this event occurred. | Yes |
destination |
string | The name of the JMS destination for which this event is generated. This field may be left null if the event applies to the entire server instead of a single destination. | Yes |
status |
string | The actual event that occurred. Possible values are described below. | Yes |
time |
timestamp | The time at which this event was detected. | Yes |
Possible values for the status
field are:
-
Connecting
: The adapter is attempting to connect to the named JMS server. Note that thedestination
field is left null. -
Connected
: The named JMS server is now connected. Note that thedestination
field is left null. -
Disconnected
: The named JMS server has disconnected. Note that thedestination
field is left null. -
Available
: The named destination on the named JMS server is now available. -
Unavailable
: The named destination on the named JMS server is now unavailable. -
Connection Failed
: The connection attempt to the named JMS server failed. Note that thedestination
field is left null. -
Connection Retries Exceeded
: The number of connection attempts specified in the adapter's cofiguration file for the named JMS server have been exhausted. No more attempts will be made unless a newConnect
command is issued (see Command Input Port Schema). Note that thedestination
field is left null.
Monitoring of JMS server connections is always enabled. However, in order to receive status tuples relating to destinations
becoming available or unavailable, the adapter must periodically check whether a destination is active. Because this is an
intrusive process (at least minimally), this functionality is disabled by default. To enable monitoring of JMS destinations
on a given JMS server, add a destination-monitor-interval
attribute to this JMS server's <jms-server>
section in the adapter's configuration file. The value for this attribute is the number of milliseconds the adapter should
wait between destination health checks. A value of 0 disables the functionality, as does removing the attribute.
By default the JMS adapters expect the endpoints (topics or queues) it will use to have been defined in the destinations
section of their respective JMS server definitions in the configuration file. However, in some cases it may be desirable
to have endpoints created on the fly instead (assuming the JMS server allows it). This section describes how to configure
and use the JMS adapters to accomplish this.
First, you must tell the JMS adapter what kind of destination you wish to create by adding a default-destination
entry to your JMS server's destinations
section in the adapter's configuration file. The syntax to this section is identical to that of regular destination
entries, except that the name
attribute is ignored. You must also make sure that the JMS server's definition includes a create-destinations="true"
attribute:
<jms-servers> <jms-server name="myJMSServer" provider-context-factory="..." provider-url="..." connection-factory-name="MyConnFactory" acknowledge-mode="AUTO_ACKNOWLEDGE" jndi-security-principal="MySecurityPrincipal" jndi-security-credentials="MySecurityCredentials" jndi-initial-context-builder="..." create-destinations="true" username="MyUsername" password="MyPassword" > <destinations> <default-destination name-map="MyNameMap" use-topics="true"/> <destination name="topics.test1" name-map="MyNameMap"/> </destinations> </jms-server> </jms-servers>
The way endpoints are created dynamically at runtime depends on whether you wish to publish or subscribe to the new endpoint — in other words, it depends on whether you are using the JMS Reader or JMS Writer adapter.
To create, subscribe to, and receive JMS messages from a dynamic endpoint, you must send a CreateDestination command to the adapter's Command port (see Command Input Port Schema).
To create and send JMS messages to a dynamic endpoint, send a tuple to the adapter's message port as you would normally, setting
the __JMSServerName
appropriately and the __JMSDestinationName
to the name of the endpoint you wish to create. If the name of the destination is not found among the list of pre-configured
destinations, it will create it before sending the message.
The JMS Reader performs two checks during typechecking. The JMS Reader ensures that a Schema has been defined and that a value for its configuration file has been specified.
The JMS Writer performs two checks during typechecking. It ensures that a value for its configuration file has been specified
and that the input schema contains the fields __JMSServerName
and __JMSDestinationName
, if they are required.
If the Add Command Input Port
or Add JMS Output Port
options are selected, the adapters ensure that the corresponding schemas contain the expected fields. See here for a description of the expected schemas for these ports.
On suspend, if either of the JMS Embedded Adapters is currently processing a message, it finishes processing that message or tuple to completion before suspending. That is, the StreamBase application itself finishes processing the message or tuple before the JMS adapter returns from a suspend command. Once this has occurred, the JMS Reader unsubscribes for messages. If any messages (or tuples for the JMS Writer) are delivered while the JMS adapter is suspended, it drops the messages or tuples and fails to acknowledge them.
On resume, the JMS Reader resubscribes for messages. The JMS adapters begin processing newly delivered messages/tuples once it has returned from the resume command.