Message Broker Dev Guide
Message Broker Dev Guide
Message Broker Dev Guide
Message Broker
Developers Guide and API Reference
VERSION 6.0.3
Table of Contents
Introduction .................................................................................................... vii
Intended audience ............................................................................................................. vii
Overview of chapters ...................................................................................................... viii
Related documentation ..................................................................................................... ix
About Sybase ...................................................................................................................... xii
About Sybase Online Banking..................................................................................... xii
About Financial Markets Solutions ............................................................................ xii
Contacting Sybase ............................................................................................................ xiii
Sales and general inquiries.......................................................................................... xiii
Technical support......................................................................................................... xiii
Documentation inquiries ............................................................................................ xiv
Chapter 1
Chapter 2
Table of Contents
ii
Table of Contents
Table of Contents
Chapter 5
Chapter 6
iii
Table of Contents
iv
Chapter 7
Chapter 8
Table of Contents
Table of Contents
Chapter 9
Appendix A
Table of Contents
vi
Table of Contents
Introduction
About this
chapter
This chapter describes the intended audience for this guide, a chapter overview, a
description of the documentation set and how to contact Sybase.
Topics include:
Intended audience (p. vii)
Overview of chapters (p. viii)
Related documentation (p. ix)
About Sybase (p. xii)
Contacting Sybase (p. xiii)
Intended audience
Message Broker is a tool kit that allows communication between multiple message
formats and applications.This guide is intended for software developers who will
be implementing and customizing Message Broker. The guide provides a closer
look at the Message Broker architecture, the tasks you can perform and a
description of the API.
vii
Overview of chapters
Overview of chapters
This guide includes the following chapters:
Chapter 1
Chapter 3
Chapter 4
Chapter 5
Creating API templates covers the procedures for creating, modifying, and
Using flows introduces the concept of Flow and how you can use it to specify
Using the Message Broker run-time API explains how to use the Message
Broker run-time API in stand-alone Java applications or in server components such
as Enterprise JavaBeans.
Chapter 8
Using Message Broker Server introduces the Message Broker Server and how
it is used to execute flows. It also discusses how to monitor, stop and start
Message Broker Server from the Message Broker Manager. The Message Broker
run-time API is also provided.
viii
Introduction
Related documentation
Chapter 9
Appendix A
Related documentation
This Message Broker Developers Guide and API Reference belongs to both the Sybase
GlobalFIX and Sybase Online Banking documentation sets, which include:
GlobalFIX TradeForce GlobalFIX provides the complete solution to the
straight through processing (STP) requirements of the brokerage industry.
Through its XML-enabled Message Broker component, GlobalFIX facilitates
communication between various message formats and applications, and allows
financial institutions to define messages and rules for industry standard
protocols such as FIX, SWIFT, and STEP. TradeForce GlobalFIX also supports
most in-house proprietary protocols.
GlobalFIX Quick Start Guide for individuals who will be running the
GlobalFIX demo.
Sybase Online Banking Sybase Corporate Online Banking enables you to
administer company accounts with many individual accounts and users per
company client. Sybase Retail Online Banking enables you to manage individual
customer clients. Business Central works dynamically with both Sybase
Corporate Online Banking and Sybase Retail Online Banking, enabling banks
to manage business and consumer accounts, as well as bank employees.
ix
Related documentation
Sybase Corporate Online Banking Feature Guide for end users, system
administrators, and purchasing executives who evaluate Sybase Corporate
Online Banking to determine the features and functionality it offers.
Sybase Retail Online Banking Feature Guide for end users, system
administrators, and purchasing executives who evaluate Sybase Retail
Online Banking to determine the features and functionality it offers.
Introduction
Related documentation
Bill Payment and Transfer Warehouse Feature Guide for end users,
system administrators, and purchasing executives who evaluate BPTW to
determine the features and functionality it offers.
One-to-One Marketing One-to-One Marketing is a marketing message tool
that enables you to create, manage, and deliver targeted marketing messages
to customers who use Web transaction products such as online banking and
bill payment software.
xi
About Sybase
About Sybase
Sybase provides integrated financial solutions to more than 200 of the world's
leading financial institutions. Sybase maintains strategic technology relationships
with BEA, IBM, Microsoft, Sun Microsystems, and SWIFT. We supply service and
support in 60 countries and are a wholly owned subsidiary of SAP, Inc. (NYSE: SY)
xii
Introduction
Contacting Sybase
Contacting Sybase
The following sections provide contact information for Sales, Technical Support,
and Technical Publications.
Technical support
Sybase uses the Sybase Case Management System to log and track all support
issues.
If you have a mysybase account, go to www.sybase.com/support
If you do not have a mysybase account or are uncertain if you do, call
1-800-8SYBASE and a customer service representative will assist you.
xiii
Contacting Sybase
Documentation inquiries
For documentation issues or concerns, review the following information.
Contact information
To contact the Sybase Technical Publications team:
Mailing address:
(519) 747-4971
E-mail:
pubs@sybase.com
xiv
Introduction
1
Welcome to Message Broker
About this
chapter
This chapter introduces the features, concepts, definitions, and advantages unique
to Message Broker.
Topics include:
What is Message Broker? (p. 1-1)
Message Broker architecture (p. 1-3)
Understanding messages (p. 1-6)
Using API templates (p. 1-10)
Using SQL adapter templates (p. 1-10)
Using flows (p. 1-11)
1-1
fields: atomic, composite and union fields. In addition, fields can be defined to
be repeating as well as optional.
Extending and distributing message formats. Predefined message formats
can be distributed in the form of XML files that follow the Message Broker
DTD.
Administration GUI. Message Broker Manager is a graphical interface that
facilitates the creation and modification of message definitions in Message
Broker.
Run-time API. The run-time API allows you to develop custom applications
that make use of the Message Broker run-time components (parse, validate,
route, transform, build, flow, persistence).
1-2
1-3
Once message sets and rules have been defined in the design-time environment,
they must be transferred to the run-time environment through a deployment
process invoked from the graphical user interface, Message Broker Manager.
During the deployment process, IDL and Java classes are created for the message
sets and rules, and data is transferred from the design-time repository to the runtime repository.
For further details on the design-time and run-time environments, review the
following sections:
What is the design-time phase? on page 1-4
What is the run-time phase? on page 1-5
NOTE: Message Broker requires a JDBC driver to connect to its design-time and runtime repositories. A Sybase jConnect driver and Adaptive Server Anywhere
(ASA) sample database file are provided as part of the Financial Fusion
installation package.
trailer, message body, and field information. Field information includes field
type and data type. Refer to Understanding messages on page 1-6 for more
information.
Validation rules: These rules enforce message conformance. Refer to
Validating a message on page 1-8 for more information.
Routing rules: These rules specify a Sybase Enterprise Application Server
(EAServer) component, a Java class, or an Enterprise JavaBean (EJB) to which
a message is routed. Refer to Routing a message on page 1-9 for more
information.
1-4
1-5
Understanding messages
Understanding messages
A message is a structure that holds information. It can contain a header and a
trailer, as well as the message body. Headers, trailers, and message bodies can
contain multiple fields. The fields comprising a message vary from protocol to
protocol.
A protocol such as SWIFT contains various message sets. Each set contains a
group of messages that has a specific format and performs a specific task. For
example, the FIX protocol requires a header and trailer for each message. The
header identifies the message type, length, destination, sequence number,
origination point, and time.
Other protocols may not require a header, or require headers that contain
different information. You should be familiar with the various protocols that you
are working with to effectively use Message Broker to create message sets,
validation rules, routing rules, and other configuration tasks.
The message body, also called the message definition, if it exists, is located
between the header and the trailer. Each message definition shares the header and
trailer of that message set.
The next sections discuss the role of fields in messages and parsing, validating,
routing and transforming messages.
What are fields? on page 1-6
Parsing a message on page 1-8
Validating a message on page 1-8
Routing a message on page 1-9
Transforming a message on page 1-9
Understanding messages
Figure 1-2:
Determining field
length.
At run time, this field information is compiled into message definition classes and
used by the parser to parse the incoming message.
With Message Broker, you can define other field characteristics as well, such as:
the type of data contained in the field
whether or not the field itself can contain other fields
whether or not a field is optional or can be repeated
You can also select the data type that the parser outputs. Keep in mind that all
incoming user data is read as characters.
1-7
Understanding messages
Parsing a message
When you deploy to the run-time repository, your message definitions are
compiled into message class definitions. From within your application, create a
Message Broker instance and call the IParser API, which parses the incoming
message.
To parse a message:
1. Send the unparsed message to the application.
2. The application creates a Message Broker instance (if one is not already
Validating a message
Message Broker validates incoming messages by verifying that the message meets
the criteria you have specified for your message definitions. There are two types of
validation: implicit and explicit.
Implicit validation
Implicit validation is specified as part of the field definition. You define the field and
ensure that the incoming message fits the criteria you established in the message
definition so that it will be recognized as a valid message. For example, you could
define a fixed value that contains FIX.4.0 in the header. The parser verifies that the
header contains this value as part of implicit validation. No Java code is required
for implicit validation.
Explicit validation
Explicit validation allows you to write validation rules in Java code. These rules are
compiled at run time and referenced by the Message Broker IValidation API.
Explicit validation provides greater control in verifying message content. For
example, you could write Java code that checks for the existence of a particular
character string at the beginning of a field. In the case of an e-mail address, if a user
wanted to verify that a particular field represents an e-mail address, they would
need to explicitly write code to verify that what they have is an e-mail address.
1-8
Understanding messages
Routing a message
Routing passes a message to business logic whenever a condition is true. You write
a routing condition in Java code that returns either true or false. At run time,
Message Broker compiles the routing code and routes a parsed message to an
EAServer component, a Java class, or an EJB, if the condition is true. As the figure
below illustrates, you could write a routing rule that checks the header and routes
any message that contains the FIX 4.0 string to an EAServer component.
Figure 1-3:
Sample routing rule.
Transforming a message
Transformation rules convert a message type to a different message type. For each
destination field in the target message, transformation rules instruct Message
Broker how to fill in the destination field, given the values in the source fields. At
run time, the Message Broker ITransformation API transforms a message, field by
field, from the source message type to the destination message type.
For example, you can define transformation rules that convert FIX messages into
SWIFT messages. The ITransformation API changes the FIX message to a SWIFT
message based on the transformation rules that are stored in the run-time
repository, then forwards the message to the SWIFT server for processing.
1-9
1-10
Using flows
Using flows
Flows are used to perform a sequence of message processing operations. These
operations include invoking the Message Broker run-time API, working with JMS
queues, creating database connections, and calling into custom Java classes and
EJBs.
Flows are specified in a declarative manner using XML. The format of the XML is
defined by a Flow DTD which is included with Message Broker.
Flows are executed using the run-time API or the Message Broker Server. For
more information on Flows see Chapter 6: Using flows. For details on Message
Broker Server, see Chapter 8: Using Message Broker Server.
1-11
Using flows
1-12
2
Connecting to repositories
and running the samples
About this
chapter
This chapter describes how to configure and connect to the Message Broker
repositories and introduces the Message Broker samples.
Topics include:
Getting started (p. 2-1)
Connecting to repositories (p. 2-2)
Importing the Message Broker samples (p. 2-7)
Reporting problems (p. 2-9)
Getting started
Before you connect to the repositories and run the samples, review the following
steps:
1. You can create and connect to the repositories supported by Message Broker.
Message Broker. See Importing the Message Broker samples on page 2-7.
3. To contact Financial Fusion with any issues, see Reporting problems on
page 2-9.
2-1
Connecting to repositories
Connecting to repositories
After you have started Message Broker, you can create and connect to the
Message Broker repositories. Message Broker uses the following two repositories:
Design-time repository. This repository is a set of database tables where
Auto Reconnect
The auto-reconnect feature tests the status of the repository connection before
performing operations which require repository access. If the connection to the
repository has been closed (most often due to a connection timeout from the
database server), Message Broker automatically attempts to reconnect to the
repository. If the connection is re-established, Message Broker proceeds with the
operation and it appears as if nothing out of the ordinary has happened. If the
connection cannot be automatically re-established, an error is issued informing the
2-2
Connecting to repositories
user that the connection to the repository has been lost and that they need to
manually reconnect to the repository and repeat the operation.
The auto-reconnect feature works with design-time and run-time repositories. For
example, it works in the design-time repository before importing/exporting/
deploying sets, expanding fields, or copying-pasting fields, and in the run-time
repository before loading a message set, routing set, and so on.
NOTE:
2-3
Connecting to repositories
samples/mbdemo on Unix.
NOTE:
NT users can launch the demonstration database from the NT Start menu, for
example, if you installed Message Broker in the default directory, select Start
> Program> Financial Fusion> Message Broker 6.0> Message
Broker Demo database.
list.
4. Enter the connection information for the database where you want to store
the repository.
5. Enter these values to use the sample ASA database:
The user ID and password are case sensitive. To use a different database,
make sure the database is case sensitive for string compares.
You can now use this connection profile to connect to the repository. The first
time you connect to a design-time repository, Message Broker creates the
required database tables.
collections.
2-4
Connecting to repositories
To connect to run-time repositories on Oracle via the OCI8 (thick client) driver,
Message Broker supports lookup of database connection parameters from the
TNSNAMES.ORA configuration file. To have Message Broker obtain the
connection information from the TNSNAMES.ORA configuration file, specify
the Oracle SID for the database instance in the database name field and leave
the machine name field blank (the port number field is ignored in this case).
This method of specifying the connection parameters is required for connecting
to Oracle Parallel Server (OPS).
Manager.
2. Click New.
3. Enter a name for the connection profile, for example, MBView. Make sure the
profile type is Message Broker and click OK.
NOTE:
2-5
Connecting to repositories
list.
3. Enter the connection information for the database where you want to store
the run-time repository. You can use the same database to store the run-time
and design-time repositories.
4. To use the sample database, enter the following values:
The user ID and password are case sensitive. To use a different database,
make sure the database is case sensitive for string compares.
You have now defined a connection profile that you can use whenever you want to
connect and view the repository.
You must deploy to the run-time repository before you can view its contents.
You can also right-click the desired repository and select Disconnect.
For the most recent information on the samples, refer to the readme file in the
samples directory of your Message Broker installation.
Import. You can either import all of the XML files at the same time or import
MessageSets.xml first if you are importing them one at a time. Message Broker
imports the sample message definitions into the design-time repository.
5. Add a class path to your design-time repository. To do this in the Message
Broker Manager:
2-7
a.
b.
Select Properties.
c.
d.
Enter the full path of the Message Broker samples directory into the text
field.
e.
Click Add.
repository, deploy them to the run-time repository to make them available for
use.
b.
c.
d.
2. Build the sample by executing make.bat, located in the samples directory. The
samples can only be built after the message collection has been deployed
because they depend on the files that are generated by the Message Broker
deployment process.
3. Deploy the routing collection and transformation collection respectively.
RoutingCollection can only be deployed after the samples have been built
since it references the RouteTarget class.
4. Make sure the run-time repository database is running before executing
run.bat. Run the samples one at a time by using the following batch files:
run FlowTest.bat
runParseBuild.bat
runParsePersist.bat
runParseTransformBuild.bat
runParseValidate.bat
Explanations of the samples are provided via comments in the Java files. The batch
files assume that jConnect is installed and that the MB60JCONNECTDIR
environment variable is set to the jConnect location. The samples assume the use
2-8
Reporting problems
of ASA and jConnect. If you are using a database other than ASA for the run-time
repository then the Java source files need to be modified accordingly.
Once the deployment is complete, you can use the sample parser and builder on
your compiled message definitions in the run-time environment.
For an example of how to invoke the parser and builder, see the comments in the
file ParseBuild.java in the samples directory. This sample uses the sample definitions
provided in XML format to parse the information in the file and then build a buffer
which can be viewed as an output file.
Reporting problems
Report any problems with this build to your Financial Fusion representative. Please
have the following information ready before contacting Financial Fusion:
The build number for the version of Message Broker that you are using
The error message given
If possible, a list of steps required to reproduce the problem
2-9
Reporting problems
2-10
3
Using the Message Broker
design-time environment
About this
chapter
This chapter discusses the Message Broker design-time configuration tasks that are
performed from Message Broker Manager.
Topics include:
Getting started (p. 3-2)
Defining message collections (p. 3-3)
Understanding message sets (p. 3-3)
Adding message sets (p. 3-5)
Request/response message model (p. 3-15)
Understanding field elements and properties (p. 3-16)
Understanding rules (p. 3-26)
Defining validation rules (p. 3-29)
Creating routing rules (p. 3-32)
Transforming messages (p. 3-39)
Defining adapter collections (p. 3-45)
Importing and exporting repository information (p. 3-50)
Specifying the Java class path (p. 3-51)
Deploying to the run-time repository (p. 3-51)
3-1
Getting started
Getting started
To use this chapter effectively, review the following steps:
1. To perform the tasks in this chapter, you must:
that include header, trailer, message body, and field information. Field
information includes field type and data type. For details, see Defining
message collections on page 3-3 and Understanding message sets on
page 3-3, as appropriate.
3. Review Understanding rules on page 3-26.
4. Define Validation rules. These rules enforce message conformance. For
find it faster and easier to define them in XML first, then import them into the
design-time repository. For details, see Importing and exporting repository
information on page 3-50.
9. Make sure that the locations of all the extra class files used by your code have
been entered in the repository properties. If classes are missing, you will get
compile errors during deployment. For details, see Specifying the Java class
path on page 3-51.
10. Before you can invoke Message Brokers run-time API, you must deploy the
design-time repository to the run-time repository. See Deploying to the runtime repository on page 3-51.
3-2
the header can contain multiple fields. You can establish a field that is the
message-type indicator, which is used by the parser, to identify a message
body from this field.
Trailer (optional): You can define only one trailer for each message set. Like
the header, the trailer can contain multiple fields.
Message definitions: This is the body of the message where you can include
field definitions and validation rules for your message set. Each message
definition in the set uses the same header and trailer, if defined.
3-3
Enumerations: You can create and add enumerations used to validate the
header, trailer, and message fields. For details, refer to About enumerations
on page 3-23.
User-defined Types: You can define fields and data types in the User-defined
Type folder. Refer to About user-defined types on page 3-24 and Attaching
validation rules to user-defined types on page 3-31 for more information.
Unknown Field Handler: You can register a Java method that is invoked by
the parser at run time if it encounters an unordered composite member that
it does not recognize. Refer to Defining unknown field handlers on page 325 for more information.
Delimiters: You can define delimiters and pad characters for all fields in all
messages belonging to the message set. You can override these setting at the
field level. Refer to About field definitions on page 3-16 for additional
information.
3-4
Defining a header
To define a header for a message set:
1. Highlight the message set to which you are adding a header.
2. Double-click the Add Header icon.
3. Follow the wizards instructions.
When defining the message set header remember to specify whether the fields of
the message set header must be ordered. If unordered, the header must contain all
3-5
defined fields. Also specify the delimiters and tags. Refer to About field delimiters
and tags on page 3-22 for more information.
NOTE: To use a header field as the message-type indicator select File > Use as
Message-Type Indicator. Refer to Defining a field on page 3-6 to
see how a message is located from its header when the message-type
indicator is set. You can also specify atomic user data types as messagetype indicators.
Defining a trailer
To define a trailer for a message set:
1. Highlight the message set to which you are adding a trailer.
2. Double-click the Add Trailer icon.
3. Follow the wizards instructions, keeping the following in mind:
a.
b.
You should also specify whether the trailer is optional. If you select This
trailer is optional, messages are considered valid if they do not contain a
trailer, as long as the rest of the message is valid.
c.
Also specify the delimiters and tags. Refer to About field delimiters and
tags on page 3-22 for additional information.
Adding a field
To add a field to a header, trailer, or message:
1. Highlight the header, trailer, or message to which you are adding a field.
2. Double-click the Add Field icon.
3. Follow the wizards instructions.
Defining a field
To define a message:
1. Highlight the Message Definitions folder.
2. Double-click the Add Message Definition icon.
3. Follow the wizards instructions as outlined below.
3-6
a.
b.
Create a header field called messageType and mark it as the messagetype indicator.
c.
Include the value that you expect in the messageType field for each
message body you create. For example, in the customer sample that
comes with Message Broker, the message-type indicator in the header is
called msgType. The enumeration msgType is defined to accept the values
Add or Del. There is one message body called AddCustomer that
corresponds to the message type Add and a message body called
DeleteCustomer that corresponds to Del.
When the parser encounters the message-type indicator, it finds the message
body that corresponds to the value in the message-type indicator. In the
figure below, the parser finds the Add Customer message body based on the
Add message-type value.
d.
Specify a request or response message. If you are using the API template
generation feature and if the message is part of a request/response model,
3-7
f.
Specify the delimiters and tags. Refer to About field delimiters and tags
on page 3-22 for additional information.
Modifying a field
To modify a field in a header, trailer, or message:
1. Highlight the field you want to modify.
2. Select File > Properties.
3. Modify the field properties as needed. You cannot modify those field
You cannot change the structure of an XML-based message set. For this
reason, features such as, drag-and-drop, copy and paste, deleting and creating
new fields are not available.
3-8
Choose XML-based when asked to specify the type of message set you
want to create.
b.
c.
d.
e.
At this point Message Broker allows you to alter the names and data types of
any fields in the message set to be created.
Message Broker will now complete the process of importing the DTD into the
design-time repository. This could take some time, depending on the size of the
DTD to be imported.
3-9
<!ELEMENT A (B|C)>
B
C
D
E
(#PCDATA)>
(B)>
(B,C)>
ANY>
#PCDATA becomes an atomic field called data with the data type of String. If
#PCDATA is the only content allowed, then the atomic is marked as required
by default, and it would be an error to have markup with an open tag followed
immediately by a close tag with no text between. In the previous example,
user-defined type B would have an atomic subfield called data.
If an element is referenced, an instance of a user-defined type is created as a
subfield. In the previous example, user-defined type C would have an instance
of user-defined type B as its subfield.
Modifiers on a field are treated as follows:
? makes the field optional
+ makes the field repeated with a minimum repeat count of 1
* makes the field repeated with a minimum repeat count of 0
For example, in <!ELEMENT F (A?,B+,C*)> the user-defined type F is an
ordered composite where subfield A is optional, subfield B is repeated with a
minimum repeat count of 1, and subfield C is repeated with a minimum repeat
count of 0. A, B, and C are each instances of user-defined types with the same
name.
If the top-level content specification has modifiers, it is treated as if there
were an extra set of parentheses around the entire content specification, for
example, <!ELEMENT G (B)?> would be treated as if it were <!ELEMENT G
((B)?)>.
Any internal set of parentheses becomes a subfield whose name is the name
of the parent subfield plus an underscore, plus a number, for example,
<!ELEMENT H ((B|C),D)> would have subfield H_1, which is a union and D,
which is an instance of user-defined type D. H_1 in turn would contain two
subfields, B and C, which were instances of the user-defined types of the same
name.
In order to properly map the DTD into Message Broker, it is sometimes
necessary for Message Broker to treat the content specification as if it were
written in an equivalent but different manner. In particular, if a subfield in a
choice can be missing because it has the ? or * modifier, then the subfield is
3-10
made required by removing the ? or changing the * into +. The choice is made
optional by changing its modifier from + to * or by adding ? if there was no
modifier. This is repeated until no subfield of a choice is optional, for example,
<!ELEMENT | (((A|B?)|C)+,D)> would become (((A|B)?|C)+,D) which would then
become (((A|B)|C)*,D). This last stage would be used for the import.
If any element has an ANY content specification, a user-defined type called
ANY is created to match the specification (#PCDATA|A|B>>>)* where all the
elements defined in the DTD appear after the #PCDATA. The user-defined
type for the element then gets an instance of the ANY user-defined type as a
subfield. In the previous example, user-defined type E would contain a subfield
called ANY, which is an instance of the ANY user-defined type.
If there is an attribute declaration for an element, then the element will get a
subfield called elementName_attributes, which appears as the last subfield in
the field. Each attribute defined for the element appears as a subfield of the
attributes subfield as illustrated in the following example:
<!ATTLIST A a1 (val1|val2)#REQUIRED>
3-11
definitions.
2. Select the root element from the list of defined elements. A root element is
A
B
C
D
E
(
(
(
(
(
#PCDATA
#PCDATA
#PCDATA
#PCDATA
(A,B) |
) >
) >
) >
) >
(C,D?) ) >
then Message Broker will display all elements defined in the DTD and prompt
you for the root element, A, B, C, D, or E. You need to be aware of the
structure of your DTD to know which element is the root. Also, keep in mind
that you can choose multiple root elements.
The DTD file defines the elements and attributes of your message set. When
you import the file, each element and attribute becomes a composite in the
User-defined Types folder. For example, if you import the above elements, A,
B, C, and D become structures in your User-defined Types folder.
For more information, refer to About user-defined types on page 3-24 and
Attaching validation rules to user-defined types on page 3-31.
3-12
a.
Choose SQL-based when asked to specify the type of message set you
want to create, then click Next.
b.
c.
Select one or more tables you want to transform into message definitions,
then click Next. To select multiple tables, hold down the CTRL key while
clicking individual table names.
d.
Select one or more columns you want to transform into message fields,
then click Next. To select multiple columns, hold down the CTRL key
while clicking individual table names.
e.
Select Map Names and Data types to alter the names and data types of
any fields in the message set, then click. Refer to the guidelines described
in the section on Mapping SQL types to Message Broker field types on
page 3-14.
f.
Click Save to save your changes, then click Close to close the dialog box.
g.
h.
3-13
BIT
Boolean
TINYINT
32-bit Integer
SMALLINT
16-bit Integer
INTEGER
BIGINT
FLOAT
REAL
DOUBLE
NUMERIC
DECIMAL
CHAR
String
VARCHAR
String
LONGVARCHAR
String
DATE
Date, DATE_YYYYMMDD
TIME
Date, DATE_TIME_TIMEZONE
TIMESTAMP
Date, DATE_YYYYMMDDHHMMSS
BINARY
Bytes
VARBINARY
Bytes
BLOB
Bytes
CLOB
String
If any of these field types can contain a null value in the message definition,
Message Broker marks that field as optional. Also, if you do not supply a value in a
column, a default value is inserted, however, this default value does not affect the
generated field type in Message Broker.
3-14
3-15
Field type
The three field types, atomic, composite, and union, are defined as follows:
Atomic: An atomic field represents some data from the message and does
not have subfields. It can contain only one field as a member and may be
either fixed-length, variable-length, or tagged/delimited.
Composite: A composite field can contain subfields. If a subfield is a
composite, it can also contain subfields. Specify whether the fields within a
composite must be ordered or not. An ordered composite requires that the
message contain the subfields in the order they appear in Message Broker. If a
composite is unordered, the subfields may occur in any order.
NOTE: If a composite is unordered, the parser may perform more quickly if the
subfields are ordered to match the most likely order in a message.
3-16
Union: A union, like a composite, can contain subfields, but only one of the
subfields can be present in the message. Union subfields should be ordered so
that the most likely members appear first.
Data type
If you select atomic as the field type, you must also specify the data type. The
parser uses this information to determine how to read the data and generate the
output.
Incoming field data is read as text and parsed according to the data type you
select. Your output options are strings, bytes, boolean, integers, floats and doubles,
enumerations, and dates.
Strings: If you select this option you can choose a picture code
representation. A picture code allows you to specify the type, number, and
placement of characters in the string. A string must match the picture code to
be valid. Refer to About picture codes on page 3-21 for more information.
Bytes: The parser output is in bytes.
Boolean: The parser output is boolean.
Integers, floats, and doubles: You may choose the format of the integer,
float, or double output.
Enumerations: Select Enumeration from the drop-down list, which will only
contain enumerations whose data type matches the currently selected data
type for the field. The input must be a value of the selected enumeration to be
valid. An enumeration may be associated with a field in two ways.
First, if Represent field data as has anything but Enumeration selected and
an enumeration is selected from the Enumeration drop-down list, then the
field will be represented as the specified type, but the value will be
validated against the values in the enumeration.
3-17
Dates: The output is in date format and uses the notation identified in the
following table.
Date/Time Element
Format
year
YYYY
month/minutes
MM
day
DD
hours
HH
seconds
SS
milliseconds
XXX
TZ
Example
YYYYMMDD
(19990821)
YYYY-MM-DD
(19999-08-21)
YYYYMMDD-HH:MM:SS
(19990821-13:334:57)
MMDD
(0821)
YYMMDD
(990821)
YYYYMMDDHHMMSS
(19990821133457)
YYYYMMDDHHMMSS.XXX
(19990821133457.623)
YYYYMMDDHHMMSS.XXX [GMT
offset: TZ name]
(19990821133457.623 [-5:EST])
The last two options in the table are date/time combinations for the OFX
protocol. These formats have some special cases that allow various parts of
the date and time information to be missing from the right side. For the
3-18
Field length
If you select atomic as the field type, you can choose either a fixed length, variablelength, or tagged/delimited field. If you select composite or union, you must use a
tagged/delimited field.
For a fixed field length, enter a number to represent the required (maximum)
length of the field, for example, if you enter 4, the field must contain a maximum of
four characters. Refer to About field delimiters and tags on page 3-22 for more
information.
3-19
If a field is tagged/delimited, then the length of the field is determined by the tags
and delimiters on the current field and also on the fields around it. If the field is
marked as length field indicated, then the length of the field, excluding any tags and
delimiters for the field, is given by the parsed value of the previous field, which
must be a numeric atomic field.
If the field is a variable length then the length of the field is determined by reading
Length bytes before the beginning of the field, interpreting that as a binary
representation of an integer n and using the next n characters for the field.
3-20
Description
Blank space
+ or - character
Any character
0 or 1
cs
\uXXXX
\r
\n
\t
Tab character
\s
\\
Backslash character
\#
NOTE:
3-21
B0E33860 is the data being parsed. You could define these delimiters and tags:
Begin field delimiter: {
End field delimiter: }
Begin tag delimiter: None
End tag delimiter: :
Pre-value tag: MAC
Post-value tag: None
For the example below the delimiters and tags are defined as follows:
{<foo>data</foo>}
3-22
About enumerations
An enumeration belongs to a message set and is a list of all allowed values for the
enumeration. An enumeration must match the data type of the field to which it
belongs. At run time, the parser validates an enumeration by checking that a fields
value belongs to its enumeration set, for example, the first field in the header of a
FIX message contains a string that identifies the version, FIX.4.0 or FIX.4.1. You
could do the following:
1. Define an enumeration called fix_version that is a string data type.
2. Add two members to the enumeration, fix_version4_0 with a value of FIX.4.0,
Defining an enumeration
To define an enumeration:
1. Highlight the Enumerations folder from within the message set you want to
add.
2. Double-click the Add Enumeration icon.
3. Follow the subsequent wizard instructions to define your enumeration.
a.
b.
c.
d.
Add members by entering a symbolic name and a value for the member.
Member names must be unique within an enumeration and correspond to
a valid Java identifier. The value must correspond to the selected data
type.
e.
3-23
b.
c.
Click Finish.
3-24
Class name: the name of the Java class to which the handler belongs.
Method name: the unknown field handler method.
Static method: Select this check box if this is a static method.
NOTE: See Using a handler for unknown fields on page 7-6 for information on
coding the unknown field handler.
3-25
Understanding rules
Reordering fields
Message Broker uses drag-and-drop features to reorder fields. The following table
describes each of the drag-and-drop features. You can reorder fields by holding
down the Shift key while dragging a field.
Drag source
Drag target
Key
pressed
Action
User-defined type
None
Creates a link to
the target field
User-defined type
Ctrl
Creates a copy of
the user-defined
field in the target
Atomic, composite,
union (excluding
user-defined type)
None
Atomic, composite,
union (excluding
user-defined type)
Ctrl
Creates a copy of
the field in the
target
Atomic, composite,
union
User-defined types
Container
None
Understanding rules
This section describes guidelines for writing rules, defining validation rules, and
user-defined type rules.
Guidelines for writing rules on page 3-27.
Examples of rules on page 3-28.
3-26
Understanding rules
Optional fields
To check for the existence of an optional field, check a boolean value consisting of
the field name with Exists appended to the end, for example
if (AddCustomer.CompositeField1Exists) {...
Check the Exists field before referencing the field since the data may be invalid. If,
however, the field is an optional atomic with a default value, then the field always
contains valid data and the Exists field indicates whether the data was present
when parsed.
If a rule is established for an optional field, Message Broker checks for the fields
existence before invoking the rule at run time.
Repeated fields
When you are writing a rule for a field that is marked as repeated, the field
variable will be an array holding all repetitions. To validate each repetition, write a
loop to iterate through the repetitions.
For fields that are not marked as repeated, but are contained within a repeated
field, the variable field represents a single instance of the field and Message Broker
takes care of applying the single rule to each repetition instance.
3-27
Understanding rules
Enumeration checking
To write a condition that includes checking a fields value against an enumeration,
invoke the function
ValueSet<EnumerationName>.contains
Although you can write rules for enumerations, the built-in validation that
enumerations provide is sufficient unless you want to check more than one
enumeration list.
User data
In the condition of a rule, you can reference the predefined userData Java variable.
In your run-time application, you can pass any descendant class of java.lang.Object
to the method that triggers execution of the rules. The object is made available to
the rule code as the predefined userData Java variable.
When routing to an EAServer component or EJB, userData must be of type
TypeUserData.
Examples of rules
This section contains validation rule examples for a repeated composite field and
its member fields. The elements used for the examples are:
+AddCustomer
+CompositeField1[ ]
+AtomicField1
+AtomicField2 ?
3-28
{sum += field[i].AtomicField2;
}
// validation fails if the sum of
// the two fields exceeds 100
if( sum > 100 ) {return false;
}
}
return true;
3-29
For additional guidelines for writing validation rules, refer to Guidelines for
writing rules on page 3-27.
NOTE: To deploy explicit validation rules you need to modify the class path on the
repository. See Specifying the Java class path on page 3-51 for more
information.
3-30
displayed on the left side and the validation condition on the right.
3. Edit the validation condition as required.
4. Make your modifications and click Save. To cancel your changes click Revert.
To use method 2:
1. Select File > Properties.
2. To view and modify the general properties of the validation rule, select the
Condition tab.
3.
3-31
The next sections describe routing rules and how to use routing rule templates:
Guidelines for routing rules on page 3-32
Using routing rule templates on page 3-33
3-32
where MsgName is the name of the message definition. The target method
receives the message instance and the Java object is passed as the userData
parameter to the IRouter.route method.
An EAServer component method that is a routing target must have an IDL
signature, such as:
void myMethod( MsgName::TypeMsgName msg, TypeUserData userData);
where MsgName is the name of the message type and TypeUserData is a Java class
that you supply.
To route to EJBs, you must configure the EJB routing properties to allow
connections to the host EJB server.
3-33
Custom signature
The routing target method signature for a routing rule template is known as the
custom signature. The custom signature must consist of at least one parameter.
The parameters can be of standard Java types or user-defined classes. If userdefined classes are used, the appropriate imports must be set in the routing set
properties. A return type can also be specified for the custom signature.
Message Broker allows you to edit routing rule templates after they have been
created. Like routing rules, routing rule templates fall under the routing set and are
contained within the Routing Rule Templates folders.
IRouter
IRouter contains the following method for routing to a template:
public Object routeToTemplate( IMBMessage msg,
String routingSetName, String routingTemplateName,
Vector parameterList )
throws MBException, Exception;
To route to a template, you call this method, passing in the message instance and
name of the routing set, the routing rule template, and a vector containing the
parameters for the custom signature.
Since a vector contains objects, if the custom signature consists of any primitive
types, such as int, boolean, short, and so on, they must be wrapped in their
respective wrapper classes, that is, Integer, Boolean, Short, and so forth. The
generated code will automatically take care of extracting the primitive type values
from the vector.
The result is that routeToTemplate( ) returns whatever was returned from the
routing target. If the custom signature is defined to return a Java primitive type, the
generated code will automatically wrap the value in the appropriate wrapper class
and return it.
NOTE: You may use substitutions such as #MessageName, #MessageType, #Request
Type, and #ResponseType in the condition code, target method name, and
custom signature.
3-34
collection.
To add a routing rule:
1. Highlight the Routing Rules folder in the routing set to which you are adding
a routing rule.
2. Double-click the Add Routing Rule icon.
3. Follow the wizards instructions to add a routing rule to the routing set,
Select the message body definition to which the routing rule applies.
b.
c.
Enter the condition for the routing rule and select Next. The condition
must return either true or false.
d.
e.
f.
g.
Click Finish.
NOTE: To reference message fields and elements directly, place your cursor in the
edit screen where you want to place the element, then expand and select
the element of the message definition you want to reference. You can also
drag and drop elements. When you select the element, it appears in the
edit screen.
3-35
There are two methods to modify and existing routing rule. Use method 1 or 2 to
modifying an existing routing rule.
Method 1:
1. Highlight the routing rule you want to modify.
2. Select File > Edit Rule. An edit screen appears with the message definitions
displayed on the left side and the routing condition on the right. Edit the
routing condition as required.
3. Make your modifications and click Save. To cancel your changes, click Revert.
Method 2:
1. Select File > Properties. You can view and modify the general properties of
the routing rule, which include the ordinal (the order in which the rule is
applied), or the name.
2. Edit the rule by selecting the Condition tab and clicking the Edit button.
3. Modify the target by selecting the Routing Target tab.
To specify the user data class:
The user data class is used as the userData variable in the Java code for the routing
rule and you must pass an instance of the class in place of the userData parameter
when calling IRouter.route. The TypeUserData class is also used as a parameter to
the target component or EJB.
To create the TypeUserData class:
1. Create a Java class named TypeUserData.
2. Select the Imports tab in the Routing Set properties dialog box.
3. Check whether the package containing the TypeUserData class is already listed
in the packages to import. If it is not, enter the package name in the Import
field and select Add.
If you are routing to EJBs, you must configure the properties that allow the
Message Broker run-time repository to connect to the server that hosts the EJBs.
To add a routing rule template:
1. Highlight the Routing Rule Templates folder in the routing set to which you
3-36
3. Follow the wizards instructions to add a routing rule template to the routing
b.
c.
Enter the condition for the routing template and click Next. The
condition must return either true or false.
d.
Click Edit to enter your condition in a text editor. An edit screen appears
with the message definitions displayed on the left side and the routing
condition on the right.
e.
f.
g.
Define the custom signature for the routing target method. The custom
signature must consist of at least one parameter. You may specify standard
Java types or non-standard, user-defined classes for the parameters. You
may also specify a return type for the routing target method.
h.
Click Finish.
displayed on the left side and the routing conditions on the right. Edit the
routing condition as required.
3. Make your modifications and click Save to capture your changes or Revert to
3-37
includes the ordinal (the order in which the rule is applied) or the name.
3. Edit the rule by selecting the Condition tab and clicking the Edit button.
4. Modify the target by selecting the Routing Target tab.
5. Modify the signature of the routing target method by selecting the Custom
Signature tab.
To configure EJB routing properties:
1. Display the EJB Settings in the Routing Set properties dialog box.
2. Configure the fields by providing the following information:
EJB context property in an EJB client program. See your EJB server
documentation for details on the URL syntax.
3-38
Transforming messages
Transforming messages
This section describes the process of transforming messages, headers and trailers,
and specifying transformation rules.
Message Broker allows you to transform a source message into a target message
by specifying transformation rules for the target message fields. When you deploy
to the run-time environment, the transformation rules are compiled.
In run-time applications, call the ITransformation class methods to execute the
transformation rules. Message Broker applies the rules to incoming source
messages, transforming them to the target message format.
NOTE: Implicit validation checking does not occur during transformation, so it is up to
you to ensure that the fields in the transformed message do not violate the
implicit validation rules. It is possible, however, to invoke the builder on the
transformed message to validate it.
3-39
Transforming messages
3. Define a transformation, specifying a source and target message. For each field
in the target message, provide a set of rules that indicate how to fill in the
target field, for example, SWIFT to FIX - Target Field: PosDupFlag:
if (MT502.seqA.tag23G.function == NEWM &&
MT502.seqA.tag23G.subfunction == DUP)
FixEnvelope.MessageHeader.PosDupFlag = Y
In this example, the source message is MT502 and the target message is
FixEnvelope. The function and subfunction message fields of the MT502
message definition of the SWIFT message set are the source fields for the
transformation rule. These source fields are applied to the transformed
PosDupFlag field in the FixEnvelope message definition of the FIX message set.
4. Deploy to the run-time repository. When the ITransformation transform
method is called, the transformation rules are applied to the source message.
To add a transformation collection:
1. Highlight the Transformation Collections folder.
2. Double-click the Add Transformation Collection icon.
3. Follow the wizards instructions.
transformation set.
3. Double-click the Add Transformation Set icon.
4. Follow the wizards instructions to add a transformation set to the
Select a source message set from the display of available message sets,
then click Next.
b.
Select a target message set for this transformation, then click Next.
c.
d.
Select Finish.
NOTE: You can only transform messages from existing message sets. In addition,
to add a transformation there must be a message definition for the source
and a target message set.
3-40
Transforming messages
To add a transformation:
1. Highlight the transformation set to which you are adding a transformation.
2. Double-click the Add Transformation icon.
3. Follow the wizards instructions to add your transformation, keeping the
following in mind:
a.
Select the message body definition for both the source and target. You
can select from any of the message bodies defined within the source and
target message set.
b.
c.
Click Finish.
Once you have defined source and target message bodies, you can define the
transformation rules.
To define a transformation rule:
1. Highlight the transformation to which you are adding the transformation rule.
2. Select File > Edit Rules. The edit screen appears, along with the source and
The field appears in the message screen, for example, if the source message is
AddCustomer and you select the AddCustomer header icon, AddCustomer header
appears in the edit screen.
4. You can also drag and drop source and target message field names or type
3-41
Transforming messages
or trailer-to-trailer transformation.
2. Double-click the Add Transformation icon.
3. Follow the wizards instructions to add your transformation, keeping the
following in mind:
a.
Choose the header or trailer for both the source and target. The header/
trailer is mapped to the header/trailer of the target message set.
b.
You can supplement or override portions of your header-to-header and trailer-totrailer transformations when you create your message transformation rules. For
example, you may want to override or add one field to the target header for a
particular message.
When all of your transformation rules are written and deployed, they are invoked
in the following order:
1. If a header-to-header transformation exists, the source header is transformed
3-42
Transforming messages
Atomic fields match if they have the same name and data type (int, float, etc.)
and if they are both either repeated or not repeated. If both fields are
repeated, then the target fields maximum repeat count must be greater than
or equal to the source fields maximum repeat count.
Composite fields match if both fields have the same name and their repeats
match as above for atomics.
Unions follow the same matching rules as for composites.
REPEAT(sourceField, targetField, expression): This macro allows you to
get the variable source which represents a repetition instance for the
expression, for example, you could enter:
REPEAT(SourceMsg.list, field, source + 3)
3-43
Transforming messages
If a rule exists on a subfield of a required field, but the required field has no
rule, Message Broker will generate an instance of the required field. If the
required field is repeated, Message Broker generates an array of length 1.
If a rule exists on a subfield of an optional field, no code is generated to
automatically instantiate the field.
There is no need to set the _preValueTag field in unions because the builder
doesnt use this field. This particular field is only meant to be used when the
results from the parser are checked.
NOTE: You can use transformation rules to partially fill in a message, but all nonoptional fields must be filled in before the IMBMessage object is passed to any
other MB run-time interface or a run-time exception will occur.
SWIFT to FIX
If the source message name is MT502, the target message name is FixEnvelope,
and the target field is SenderCompID, the transformation rule would look like the
following:
if(MT502.sequenceB.subseqB2.tag95R.qualifier == BUYR) {
FixEnvelope.MessageHeader.SenderCompID
=MT502.sequenceB.subseqB2.tag95R.proprietary_code
} else {
if(MT502.sequenceB.subseqB2.tag95R.qualifier == INVR) {
FixEnvelope.MessageHeader.SenderCompID
=MT502.sequenceB.subseqB2.tag95R.proprietary_code
}
FIX to SWIFT
If the source message name is NewOrderSingle, the target message name is MT502,
and the target field is SubSeqB2 with the tag 22F, the transformation rule would
look like the following:
if (NewOrderSingle.tag204 != null)
{
MT502.sequenceB.subseqB2.tag22F.qualifier = TRCA;
MT502.sequenceB.subseqB2.tag22F.issuerCode = null;
MT502.subseqB2.tag22F.indicator =
(NewOrderSingle.tag204 == 0) ? AGEN : PRIN;
}
3-44
templates that are created within this adapter set will be able to save
messages in the selected message set.
3-45
5. Enter a unique name for the adapter set. (A default name is provided.)
6. (Optional) Enter a comment for the adapter set.
7. To create the adapter set, click Finish.
You specify the type of template you are creating when defining the template using
the SQL Adapter Template wizard.
3-46
7. Select the SQL adapter template type from the drop-down list. To add a
following steps:
a.
b.
By default, the SQL adapter template will only save unparsed messages to
the database. If you wish to save unparsed messages, click Select Fields...
This option opens the Specify Fields dialog. Here you can select fields in
the header and trailer and add them to the database table.
NOTE: You may only select non-repeated atomic fields.
For each selected field, defaults are provided for the name, as well as the
data type of the column that is generated in the table. You may override
these defaults.
c.
To save your changes and close the Specify Fields dialog, click Save.
d.
Click Next.
e.
Enter any custom columns you want included in the table, then click
Next. For each column, you need to specify the column name and the
column type.
f.
g.
h.
Click Finish.
steps:
a.
Select the messages you want to add to the template and click Next.
b.
For each message, enter the name of the database table and click Next.
c.
By default, the SQL adapter template will only save unparsed messages to
the database. If you wish to save unparsed messages, click Select Fields...
This option opens the Specify Fields dialog. Here you can select fields in
the header and trailer and add them to the database table.
3-47
For each selected field, defaults are provided for the name, as well as the
data type of the column that is generated in the table. You may override
these defaults.
d.
To save your changes and close the Specify Fields dialog, click Save.
e.
Click Next.
f.
Enter any custom columns you want included in the table, then click
Next. For each column, you need to specify the column name and the
column type.
g.
h.
i.
j.
Click Finish.
NOTE: If you do not specify column types, Message Broker generates default column
types during deployment. If you want to add a uniqueness constraint to a
column, you need to provide a column type and add the word unique to the
end of the sentence.
For a generic SQL adapter template, Message Broker will generate a single table
with the table name provided by the user. For message-specific SQL adapter
templates, Message Broker will generate one table per message definition.
3-48
First column
An id column ("__messageID") will be generated as the first column in each table.
This column holds a unique identifying label for each message. The intent is that
this identifier can be used to retrieve or update the message data. The id column
is the primary key for the table. For flexibility, the type of this column is alphanumeric.
Second column
The second column in the table stores the message name. This is the name that
may need to be passed in order to parse the message (in the case where there is
no message type indicator field). This column is not generated for message-specific
SQL adapter templates since we already know which message type goes into
which table.
Third column
The third column in the table stores the raw data of the message. The name of the
column is "__rawData" and the column type is one of TEXT, VARCHAR, CHAR,
IMAGE, VARBINARY, BINARY, or RAW, depending on the target database type.
The rawData column can be null.
The next set of columns in the table is generated based on the message fields that
have been selected. For example, suppose the following fields have been selected
from the header (selected fields are shown in italic):
Header
Atomic1, String, mandatory
Composite1, mandatory
Atomic2, int32, mandatory
Atomic3, float, optional
Atomic4, date, YYMMDD, mandatory
3-49
If you specify any custom columns then they will be generated after the field
columns in the create table statement.
Finally, any additional DDL provided by you will be copied into the generated SQL
file after the table definition. This allows you to add any create index statements
(or any other DDL) that they wish to have included.
3-50
3. Enter the name of the XML file to which you are exporting your design-time
repository. After the export completes you can modify the XML file, or
import it into another design-time repository.
NOTE: You can also right-click on most objects and choose Export to be more
selective about what you are exporting.
icon.
2.
3-51
user applications to parse, validate, route and transform incoming messages. For
more information about your deployed message definitions, refer to
Chapter 10: IDL/Java Message Representation.
NOTE: You should first attempt to deploy the parts that need access to user classes,
such as routing templates, before trying to deploy the entire repository. This
approach results in a quicker detection of any problems that may exist with
class paths, package names, or routing targets. If the entire repository is
deployed from the start, errors related to these items may take hours to
discover.
When you deploy a message set, Message Broker automatically generates IDL
modules, API templates, and SQL Adapter templates. You can modify your
deployment options to choose which of these activities occur during deployment.
To modify the IDL and API template deployment options:
1. Open the Message Collections folder.
2. Open the message collection which stores the message set you want to
modify.
3. Highlight the message set you want to modify.
4. Click File > Properties.
5. Click the Deployment Options tab.
6. Select or de-select the Generate IDL or Generate API Template
checkboxes as necessary.
7. Click Apply, then click OK.
3-52
If you chose to generate the IDL modules, they are automatically deployed to the
run-time database. If you chose to generate the API templates, you can now
deploy the API templates to the run-time database.
To deploy the Adapter Set:
If you chose to generate the SQL Adapter templates, you can deploy the SQL
Adapter template or the adapter set to the run-time database.
1. Open the Adapter Collections folder.
2. Open the adapter collection which stores the adapter set you want to deploy.
3. Highlight the adapter set or template you want to deploy.
4. Click File > Deploy.
5. Enter the User ID and password to connect to the Message Broker run-time
repository, then click OK.
If you chose to generate the SQL Adapter templates, you can deploy the SQL
Adapter template or the adapter set to the run-time database.
To deploy a SQL Adapter template:
1. Open the Adapter Collections folder.
2. Open the adapter collection and adapter set which stores the template you
want to deploy.
3. Highlight the adapter set or template you want to deploy.
4. Click File > Deploy.
5. Enter the User ID and password to connect to the Message Broker run-time
3-53
If you have defined a connection profile for a run-time repository, you can deploy
to it directly, without having to re-enter connection information.
To deploy to a Connection Profile:
1. Highlight the Design-time Repository icon.
2. Select File > Deploy to Connection Profile.
3. Select a connection profile from the list of defined run-time connection
profiles.
4. Click Connect.
3-54
4
Understanding the Message
Broker DTD
About this
chapter
This chapter discusses the elements of the Message Broker document type
definition (DTD). The Message Broker DTD enables you to create valid XML
documents that contain Message Broker definitions that you can import into the
design-time repository.
Topics include:
Getting started (p. 4-1)
An introduction to XML (p. 4-2)
Understanding the Message Broker DTD (p. 4-4)
NOTE: This chapter assumes prior knowledge of XML. For detailed information about
XML, refer to the www.w3c.org Web site or any of the other Web sites and
books on the subject.
Getting started
Depending on the amount of information you need to define, creating and
importing Message Broker definitions from an XML file may be faster and easier
than creating them in the Message Broker Manager. You can modify the imported
definitions from the Message Broker Manager and then deploy to the runtime
repository, or export to another XML file.
To create valid XML files for importing into the Message Broker design-time
repository:
1. You must understand XML. For details, see An introduction to XML on
page 4-2.
4-1
An introduction to XML
2. You must understand Message Broker DTD. The Message Broker DTD is
An introduction to XML
An XML document must be valid, well-formed, or both. A valid document must
satisfy a document type definition (DTD), which is a separate document that
defines the tags that are allowed in XML documents, and how those tags can be
used in relation to each other. A well-formed document satisfies a set of generic
syntax rules provided by XML.
Processing well-formed documents is faster than processing valid documents
because the parser does not have to verify against the DTD. When valid
documents are transmitted, the DTD must also be transmitted if the receiver does
not already possess it. Well-formed documents can be sent without any other
information.
XML documents should conform to a DTD if they are going to be used by more
than one application. If they are not valid, there is no way to guarantee that various
applications will be able to understand each other.
The examples in this chapter are valid documents which use the Message Broker
DTD.
NOTE: Generated XML for XML-based message sets should not be modified.
Modification of the XML can result in runtime errors and unexplained
behavior.
4-2
An introduction to XML
<MBR.Repository.ProductVersion/>
<MBR.MessageCollection>
<MBR.MessageCollectionName>People
</MBR.MessageCollectionName>
</MBR.MessageCollection>
<MBR.MessageSet>
<MBR.MessageSetName>Customers
</MBR.MessageSetName>
<MBR.MessageCollectionName>People
</MBR.MessageCollectionName>
</MBR.MessageSet>
<MBR.Repository>
Any complete XML document starts with an XML declaration (see the first line in
the example above). The second and third lines define the document type
(MBR.Repository) and provide a path to the DTD which is used to validate the
elements in this XML file. These XML files use forward slashes to locate the DTD
for all operating systems.
If you imported this XML document into Message Broker, a message collection
named People and message set named Customers would be added to the designtime repository.
The Message Broker DTD for documents like this example, contain rules for
defining Message Broker elements, such as message collections, message sets,
routing collections, and so on. This XML file contains:
<MBR.Repository.ProductVersion/>
The (#PCDATA) attribute indicates that string data is expected for this element.
The MessageCollectionName element accepts input in the XML file. Like most
entries, there are beginning and ending tags.
4-3
4-4
When you are defining a message set you must include a message set name and a
message collection name, as indicated by the MBR.MessageSetName and
MBR.MessageCollectionName entries above.
4-5
a message set.
Validation imports. If you have validation rules compiled into Java classes for
use by the runtime APIs, include an import statement that indicates the
location of the compiled validation rules. You can call your own Java classes
from within validation rules. If you do, you need to import those Java classes,
for example, the entry
<MBR.ValidationImports>
<MBR.ImportStatement>com.msgbroker.sample.*
</MBR.ImportStatement>
</MBR.ValidationImports>
The following XML entry creates a message set called Customers that belongs to
the message collection named People.
<MBR.MessageSet>
<MBR.MessageSetName>Customers</MBR.MessageSetName>
<MBR.MessageCollectionName>People
</MBR.MessageCollectionName>
</MBR.MessageSet>
NOTE:
4-6
You can change field names and types during DTD import for XML-based
message sets.
Defining a message
This section adds a message definition, AddCustomer, to the Customers
message set created above.
<!ELEMENT MBR.MessageName (#PCDATA)>
<!ELEMENT MBR.MessageTypeValue (#PCDATA)>
<!ENTITY % MBR.MessageProperties
'MBR.MessageName,
MBR.MessageSetName,
MBR.MessageTypeValue,
MBR.Optional?,
MBR.Unordered?,
%MBR.TaggedDelimited;,
MBR.ValidationRules?'>
<!ENTITY % MBR.MessageAssociations
'(MBR.Composite | MBR.Union | MBR.Atomic |
MBR.UserDefinedInstance)+'>
<!ELEMENT MBR.Message (%MBR.MessageProperties;,
%MBR.MessageAssociations;)>
The message is defined by the entities within the MBR.Message element. The
%MBR.TaggedDelimited member can be part of a header, trailer, or message and is
defined as:
<!ENTITY % MBR.TaggedDelimited
'(MBR.BeginFieldDelim?,
MBR.EndFieldDelim?,
MBR.BeginTagDelim?,
MBR.EndTagDelim?,
MBR.PreValueTag?,
MBR.PostValueTag?)?'>
4-7
Using enumerations
The following XML entry creates the enumeration named ServiceType, and two
members, GOLD and STANDARD. The values that GOLD and STANDARD
accept are gold and std respectively. Once an enumeration is defined, you can
add it to a message field.
<MBR.Enumeration>
<MBR.EnumerationName>ServiceType
</MBR.EnumerationName>
<MBR.MessageSetName>Customers
</MBR.MessageSetName>
<MBR.EnumDataType>
<MBR.StringDataType/>
</MBR.EnumDataType>
<MBR.EnumMember>
<MBR.EnumMemberName>GOLD</MBR.EnumMemberName>
<MBR.EnumMemberValue>gold</MBR.EnumMemberValue>
</MBR.EnumMember>
<MBR.EnumMember>
<MBR.EnumMemberName>STANDARD</MBR.EnumMemberName>
4-8
<MBR.EnumMemberValue>std</MBR.EnumMemberValue>
</MBR.EnumMember>
</MBR.Enumeration>
A composite field can contain subfields. If subfields are composites, they can also
contain subfields. You can repeat fields using the MBR.Repeated element and specify
if the fields within a composite must be ordered by using the MBR.Unordered
element.
<!ELEMENT MBR.Repeated (MBR.RepeatMin?,MBR.RepeatMax?)>
<!ENTITY % MBR.CompositeProperties
'MBR.FieldName,
MBR.Optional?,
MBR.Unordered?,
4-9
MBR.Repeated?,
%MBR.TaggedDelimited;,
MBR.ValidationRules?'>
<!ENTITY % MBR.CompositeAssociations
'(MBR.Composite | MBR.Union | MBR.Atomic |
MBR.UserDefinedInstance)+'>
<!ELEMENT MBR.Composite (%MBR.CompositeProperties;,
%MBR.CompositeAssociations;)>
Like a composite, a union can contain subfields, but only one of the subfields can
be present in the message.
<!ENTITY % MBR.UnionProperties
'MBR.FieldName,
MBR.Optional?,
MBR.Repeated?,
%MBR.TaggedDelimited;,
MBR.ValidationRules?'>
<!ENTITY % MBR.UnionAssociations
'(MBR.Atomic | MBR.Composite |
MBR.UserDefinedInstance)+'>
<!ELEMENT MBR.Union (%MBR.UnionProperties;,
%MBR.UnionAssociations;)>
The XML entry below creates a composite field, Address, that belongs to the Userdefined Types folder in the Customers message set. Address contains the atomic
fields street, city, stateProvince, country, and postalZipCode.
<MBR.UserDefinedType>
<MBR.MessageSetName>Customers</MBR.MessageSetName>
<MBR.Composite>
<MBR.FieldName>Address</MBR.FieldName>
<MBR.EndFieldDelim>\r\n</MBR.EndFieldDelim>
<MBR.Atomic>
<MBR.FieldName>street</MBR.FieldName>
<MBR.TrailingPad>\s</MBR.TrailingPad>
<MBR.FixedLength>20</MBR.FixedLength>
<MBR.String/>
</MBR.Atomic>
<MBR.Atomic>
<MBR.FieldName>city</MBR.FieldName>
<MBR.TrailingPad>\s</MBR.TrailingPad>
<MBR.FixedLength>15</MBR.FixedLength>
<MBR.String/>
</MBR.Atomic>
<MBR.Atomic>
<MBR.FieldName>stateProvince</MBR.FieldName>
<MBR.TrailingPad>\s</MBR.TrailingPad>
<MBR.FixedLength>2</MBR.FixedLength>
<MBR.String/>
</MBR.Atomic>
<MBR.Atomic>
<MBR.FieldName>country</MBR.FieldName>
4-10
<MBR.TrailingPad>\s</MBR.TrailingPad>
<MBR.FixedLength>20</MBR.FixedLength>
<MBR.String/>
</MBR.Atomic>
<MBR.Atomic>
<MBR.FieldName>postalZipCode</MBR.FieldName>
<MBR.TrailingPad>\s</MBR.TrailingPad>
<MBR.FixedLength>10</MBR.FixedLength>
<MBR.String/>
</MBR.Atomic>
</MBR.Composite>
</MBR.UserDefinedType>
Routing collections
Routing collections describe how to route a message to a Java class. The following
XML file defines a routing rule for the PeopleRouting set, which is part of the
Demo routing collection. The routing rule is a compiled Java class file that routes a
message to either a Sybase EAServer component, a Java class, or an EJB file if the
message satisfies the routing condition.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE MBR.Repository SYSTEM "file:/d:/MBINSTALL/dtd/
mbrep40.dtd">
<MBR.Repository>
<MBR.Repository.ProductVersion xmi.value="4.0"/>
<MBR.ClassPath>
<MBR.ClassPathItem>d:\MBINSTALL\samples
</MBR.ClassPathItem>
<MBR.RoutingCollection>
<MBR.RoutingCollectionName>Demo
</MBR.RoutingCollectionName>
<MBR.Comment><![CDATA[Routing demonstration.]]>
</MBR.Comment>
</MBR.RoutingCollection>
<MBR.RoutingSet>
<MBR.RoutingSetName>PeopleRouting
</MBR.RoutingSetName>
<MBR.RoutingCollectionName>Demo
</MBR.RoutingCollectionName>
<MBR.MessageSetName>Customers
</MBR.MessageSetName>
<MBR.RoutingImports>
<MBR.ImportStatement>com.ffusion.msgbroker.sample.*
</MBR.ImportStatement>
</MBR.RoutingImports>
</MBR.RoutingSet>
4-11
<MBR.RoutingRules>
<MBR.RoutingSetName>PeopleRouting
</MBR.RoutingSetName>
<MBR.MessageName>AddCustomer
</MBR.MessageName>
<MBR.RoutingRule>
<MBR.RoutingRuleName>TexanBonus
</MBR.RoutingRuleName>
<MBR.RoutingRuleCondition>
<![CDATA[java.lang.String state = new String
(AddCustomer.shipAddress.stateProvince);
return state.equalsIgnoreCase("TX");]]>
</MBR.RoutingRuleCondition>
<MBR.JavaClassTarget>
<MBR.ClassName>com.ffusion.msgbroker.sample.ParseRoute</
MBR.ClassName>
<MBR.MethodName>texanBonus</MBR.MethodName>
<MBR.StaticMethod xmi.value="false"/>
</MBR.JavaClassTarget>
</MBR.RoutingRule>
</MBR.RoutingRules>
<MBR.RoutingTemplates>
<MBR.RoutingSetName>PeopleRouting</MBR.RoutingSetName>
<MBR.RoutingTemplate>
<MBR.RoutingTemplateName>everyone</
MBR.RoutingTemplateName>
<MBR.TemplateMessageType xmi.value="all"/>
<MBR.RoutingRuleCondition><![CDATA[return true;]]></
MBR.RoutingRuleCondition>
<MBR.JavaClassTarget>
<MBR.ClassName>com.ffusion.msgbroker.sample.ParseRoute</
MBR.ClassName>
<MBR.MethodName>bonus#MessageType</
MBR.MethodName>
<MBR.StaticMethod xmi.value="false"/>
</MBR.JavaClassTarget>
<MBR.CustomSignature>
<MBR.ReturnType>double</MBR.ReturnType>
<MBR.ParameterType>#MessageType</
MBR.ParameterType>
<MBR.ParameterType>String</MBR.ParameterType>
</MBR.CustomSignature>
</MBR.RoutingTemplate>
</MBR.RoutingTemplates>
4-12
</MBR.Repository>
This XML file uses the following elements to check if a routing condition is met
and then routes it to the appropriate Java method.
The following examples give the code the needed to identify routing, validation, or
transformation rules and the conditions that need to be met for the rules to be
applied.
To indicate the location of any user-defined classes that are invoked from any
validation, routing, or transformation rules use
<MBR.ClassPathItem>d:\MBINSTALL\samples
The import statement that identifies user-defined classes invoked from rules
is
<MBR.ImportStatement>com.ffusion.msgbroker.sample.*
If this condition is met, the routing rule is applied and the message is sent to
JavaClassTarget.
To identify the class name and method to be applied to any message that
meets the RoutingRuleCondition use
<MBR.JavaClassTarget>
<MBR.ClassName> com.ffusion.msgbroker.sample.ParseRoute
</MBR.ClassName>
<MBR .MethodName>texanBonus</MBR.MethodName>
<MBR.StaticMethod xmi.value="false"/>
</MBR.JavaClassTarget>
To describe the custom signature for the routing rule template use:
<MBR.CustomSignature>
<MBR.ReturnType>double</MBR.ReturnType>
<MBR.ParameterType>#MessageType</MBR.ParameterType>
<MBR.ParameterType>String</MBR.ParameterType>
</MBR.CustomSignature>
4-13
4-14
5
Creating API templates
About this
chapter
This chapter covers the procedures for creating, modifying, and deploying API
templates.
Getting started (p. 5-1)
What is an API template? (p. 5-2)
Selecting message types to process (p. 5-2)
Creating an API template (p. 5-3)
Modifying template properties (p. 5-4)
Specifying method implementation patterns (p. 5-6)
Deploying a template (p. 5-7)
Getting started
To use this chapter, review the following steps:
1. For an overview of on API template and how it is used in Message Broker,
5-1
6. When you have finished creating a template, you need to deploy it. Review
5-2
message fields.
5. Specify if the template should be applied to all messages, request messages, or
response messages.
6. Specify whether the template generates an EJB 1.1, EJB 2.0, or a CORBA
(IDL) component.
7. Enter the code that appears in the beans implementation class outside of the
message-processing methods. You can edit the code again later if necessary.
8. Enter the code pattern for the methods that process messages. You can type
the pattern directly or click Edit to launch the template editor, which contains
icons for each available macro. You can edit the code again later if necessary.
9. Enter an optional comment that describes the intended use of the template.
10. To create a new template with the specified properties, click Finish.
5-3
5-4
component.
such as variable declarations and one or more ejbCreate methods for an EJB
template. For an IDL template, you can specify #include directives, or declare
data structures that are used in the implementation pattern.
For an EJB template, you must preserve the default EJB template code. Any
code you add must be valid for an EJB stateless session bean. Do not enter
Java import statements here. Instead, specify the Java import statements in the
Message Set Properties dialog box. The default code for a new EJB template
is an ejbCreate method declared as follows:
public void ejbCreate() throws CreateException,
RemoteException
{
}
Edit the return type and parameter definitions as necessary, and add a method
body to fully specify each generated Java methods implementation. For more
information about using macros, refer to Specifying method implementation
patterns on page 5-6 The default for a new IDL template is:
5-5
You can edit the return type and parameter definitions using the macros
described in the next section.
template macro.
3. Double-click the icon to insert a macro. This step is optional.
the Message Broker Manager. In code patterns, this macro is typically used in
variable and method names.
#MessageType: The Java or IDL type of the message being processed, as
displayed in the Message Broker Manager. In code patterns, use this macro to
declare variables, parameters, or method return types.
#RequestName: If the messages Request-Response property is Request,
#RequestName has the same value as #MessageName. If the message currently
being processed is a response, then #RequestName represents the name of
the request that is paired with the response.
#RequestType: The Java or IDL type of the #RequestName message.
#ResponseName: If the messages Request-Response property is Response,
#ResponseName has the same value as #MessageName. If the message
currently being processed is a request, then #ResponseName is the response
that is paired with the request.
#ResponseType: The Java or IDL type of the #ResponseName message.
5-6
Deploying a template
Deploying a template
You can deploy templates individually or as part of the message set that contains
them. Refer to Deploying to the run-time repository on page 3-51 for
instructions.
MessageSet is the name of the message set and Template is the name of the
template.
After deployment, you can view the generated IDL file by right-clicking File >
View IDL on the template.
5-7
Deploying a template
5-8
6
Using flows
About this
chapter
This chapter introduces the concept of Flow and how you can use it to specify
sequences of message processing events without having to code directly to the
API.
Topics include:
What is a flow? (p. 6-1)
Defining a flow (p. 6-3)
Using operators (p. 6-9)
Creating a flow using the Message Broker Manager (p. 6-24)
Deploying the flow (p. 6-26)
What is a flow?
A flow is a sequence of message processing events specified in a declarative
manner. More specifically, a Flow is a set of defined Activities chained together with
Control Links.
A Flow has an execution context. Initially, this context is empty. As the Flow
executes, output from the Activities adds or modifies named objects in the
execution context. Prior to the execution of a Flow, the caller can infuse objects
into the initial execution context through an API.
The following section describe some Flow concepts:
Activities on page 6-2
Control links on page 6-2
Sub-flows on page 6-2
Loops on page 6-3
Forks on page 6-3
6-1
What is a flow?
Activities
Within a flow are Activities. An Activity represents an action that needs to be
performed. These actions are known as operators. There are several ready-to-use
operators for invoking Message Broker functionality (such as parsing, transforming,
and building messages), opening a database connection, and creating, sending, and
receiving messages to and from a JMS queue. In addition, operators are provided
to facilitate calling into user-defined Java classes and EJBs as well as invoking other
flows (known as Sub-Flows). An Activity accepts a sequence of input arguments
for its associated operator and either returns an output or a fault argument.
Two types of Activities include a Start Activity and an End Activity. A Start Activity
is placed at the beginning of a Flow definition and has no incoming Control Links.
An End Activity is an activity with no outgoing Control Links. When an End
Activity is reached, execution along that path stops. Execution of the Flow is
considered complete when all End Activities are completed.
Every Activity has an Exit Condition. An Exit Condition is a Boolean expression
that determines whether an activity has finished. The Exit Condition is optional; if
it is not present, the state defaults to true. A true state indicates that the task
is complete and execution can continue as defined by the Control Links. If the Exit
Condition is false, the Activity is executed again. Typically, an activity would
execute once and have an Exit Condition that was always true.
Control links
Control Links define the sequence in which Activities are executed, and more than
one Control Link can be defined from a given source Activity.
A Boolean Transition Condition associated with the Control Link determines
which of the Control Links are executed. The Transition Condition may reference
any of the named objects in the execution context that have been produced by the
Flow. The Transition Condition is optional; if it is not present, the state defaults to
true.
Sub-flows
Sub-Flows allow you to nest Flows. A Sub-Flow is an Activity representing another
Flow that will execute in its own context. Input can be accepted from and output
returned to the parent Flow. Sub-Flows are executed using the Internal Execute
operator.
6-2
Using flows
Defining a flow
Loops
Looping is controlled via the Exit Condition on an activity - if the Exit Condition
evaluates to false the activity is invoked again. When an Exit Condition is applied
to an activity using the Internal Execute operator it allows a sequence of activities
in a Sub-Flow to be executed in a loop.
Forks
You can create a fork by defining two or more Control Links from a source
Activity to multiple target Activities. The Transition Conditions of more than one
of the Control Links may evaluate to true.
Defining a flow
A Flow is defined in an XML file. The XML conforms to mbflow60.dtd in
%MB60INSTALLDIR%\dtd. You can use any method you are familiar with to create
this file, or you can use the Message Broker Manager. Instructions for using the
Message Broker Manager to define a Flow are found later in Creating a flow using
the Message Broker Manager on page 6-24.
The root element of the Flow definition is the flowModel element. The name
attribute names the flow.
The Message Broker Manager includes an Add Flow Definition wizard that walks
you through the steps of naming and describing your Flow and includes an editor
and template that you can use to define your Flow. Step-by-step instructions for
using the wizard are included later in this chapter.
6-3
Defining a flow
Activities
As stated earlier, Activities are actions or tasks to be completed. Activities accept
input arguments, perform some task, and then return an output or a fault
argument.
When you define an Activity, you include the names of the objects from the
execution context that should be passed as input arguments. These are specified
using the "<input name=""/>" syntax. The order of the input elements implies
the order of the parameters in the underlying operation.
Constant values can also be passed using the "<input value="" type=""/>"
syntax. You can specify the Java type (i.e. Integer, Boolean, String, etc.) of
the constant value, but this is optional. The Flow uses the following defaults if the
type of the constant value is not specified:
6-4
Using flows
Defining a flow
The implement element specifies which service provider and operator method
to invoke for this particular activity.
Exit conditions
The Exit Condition, if any, is specified using the exitCondition attribute as shown
in the example below. Note that the Exit Condition could have been omitted in
this instance since the value supplied is true. If no Exit Condition is specified, the
default is true.
<activity name=ValidateMessage exitCondition=true >
<input name=msg/>
<input value=null />
<fault name=mbException />
<implement serviceProviderType=MessageBroker
operation=validate />
</activity>
Control links
Control Links specify the order in which Activities are executed. Each control link
is also associated with two activities - a source activity and a target activity. After
an Activity is completed, all Control Links with the completed Activity as its
source are examined. Control will then go to any target Activity for which the
Transition Condition is true. (The Transition Condition is optional and defaults
to true.)
6-5
Defining a flow
Control links are defined using the controlLink element. The syntax looks like
this:
<controlLink
source=getMessageFromQueue
target=parseMessage
transitionCondition=msReceiveException==null &&
outputMsg != null" />
The source attribute specifies the name of the source Activity, and the target
attribute specifies the name of the target Activity. The transition condition is
specified using the transitionCondition attribute.
Service providers
A Service Provider Type declaration contains information necessary to access an
operator. The syntax looks like this:
<serviceProviderType name="SWIFTAdapter" type="EJB" >
<property name="initialContextFactory"
value="weblogic.jndi.WLInitialContextFactory" />
<property name="serverURL" value="t3://localhost:9101" />
<property name="userName" value="system" />
<property name="password" value="ffsserver" />
<property name="jndiName" value="CASmfAdapter" />
</serviceProviderType>
6-6
Using flows
Defining a flow
6-7
Defining a flow
6-8
Using flows
Using operators
<implement serviceProviderType="SWIFTAdapter"
operation="send"/>
</activity>
<!-- Control Links -->
<controlLink
source="jmsReceive"
target="parse"
transitionCondition="jmsReceiveException==null &&
receivedMessage!=null"
/>
<controlLink
source="parse"
target="validate"
transitionCondition="parseException==null"
/>
<controlLink
source="validate"
target="adptSend"
transitionCondition="validateException==null"
/>
</flowModel>
Using operators
There are several ready-to-use operators that you can call as activities in a Flow
definition. These operators are:
Internal operators on page 6-10
Message Broker operators on page 6-10
EJB Operators on page 6-16
Java Operators on page 6-17
JMS Operators on page 6-18
Database operators on page 6-23
6-9
Using operators
Internal operators
The single Internal operator is execute.
execute
This operator executes a Sub-Flow. The Flow executes in its own execution
context. The first two input elements specify the Flow Set Name and Flow
Definition name of the Sub-Flow. Any remaining input elements are the arguments
passed to the Sub-Flow (the number of these should match the number of input
elements within the flowSource element of the Sub-Flow). Upon completion of
the Sub-Flow, the output of the Sub-Flow will be added to the execution context
of the parent Flow with the name specified as the output element. If execution
of the Sub-Flow results in an exception, the exception will be added to the
execution context of the parent Flow with the name specified as the fault
element.
The following is an example of how this operator gets associated with an Activity:
<activity name="" >
<input name="flowSetName" />
<input name="flowDefinitionName" />
<input name="flowInput1" />
<input name="flowInput2" />
<output name="subFlowOutput" />
<fault name="mbsException" />
<implement serviceProviderType="Internal"
operation="execute"/>
</activity>
6-10
Using flows
Using operators
buildString
Description
Syntax
buildBytes
Description
Syntax
This operator invokes the Message Broker Builder to produce a byte array.
public byte[] IBuilder.buildBytes( IMBMessage msg )
throws MBException;
parse
Description
Syntax
6-11
Using operators
Here are two examples of how this operator can be associated with an Activity:
<activity name="">
<input name="MessageString" />
<input name="msgSetName" />
<output name="MessageObject" />
<fault name="mbException" />
<implement serviceProviderType="MessageBroker"
operation="parse"/>
</activity>
<activity name="">
<input name="MessageBytes" />
<input name="msgSetName" />
<input name="msgName" />
<output name="MessageObject" />
<fault name="mbException" />
<implement serviceProviderType="MessageBroker"
operation="parse"/>
</activity>
transform
Description
Syntax
6-12
Using flows
Using operators
validate
Description
Syntax
route
Description
Syntax
routeToTemplate
Description
Syntax
6-13
Using operators
<implement serviceProviderType="MessageBroker"
operation="routeToTemplate"/>
</activity>
sqlInsert
Description
sqlUpdate
Description
6-14
Using flows
Using operators
sqlSelect
Description
sqlDelete
Description
This operator deletes a message from a database using an SQL template. Here are
two examples of how this operator can be associated with an Activity:
<activity name="">
<input name="dbConnection" />
<input name="adapterSetName" />
<input name="sqlTemplateName" />
<input name="msgID" />
<fault name="mbException" />
<implement serviceProviderType="MessageBroker"
operation="sqlDelete"/>
</activity>
<activity name="">
<input name="dbConnection" />
6-15
Using operators
EJB Operators
The EJB Operator allows you to call methods on an EJB. The EJBs being invoked
must be declared in the Flow. To obtain a reference to an EJB, use these values:
initial context factory
server URL
user name
password
JNDI name
An EJB is declared using the serviceProviderType element. The input values in
the example below correspond to the information listed above.
<serviceProviderType name="<EJBName>" type="EJB" >
<property name="initialContextFactory
value="com.sybase.ejb.InitialContextFactory" />
<property name="serverURL" value="iiop://localhost:9009" />
<property name="userName" value="username" />
<property name="password" value="password" />
<property name="jndiName" value="FIX/SendReceive" />
</serviceProviderType>
6-16
Using flows
Using operators
When invoking an EJB operator, the type of the output and fault elements must be
specified. Otherwise, the output type will be assumed to be java.lang.String and the
fault type will be assumed to be java.lang.Throwable.
Java Operators
The Java Operator is provided so that you can access Java class methods from a
Flow. Java classes must be declared in the flow, and the fully-qualified name of the
Java class is required.
A Java class is declared using the serviceProviderType element. The values in the
example that follows correspond to the information listed above.
<serviceProviderType name="<JavaName>" type="Java" >
<property name="className"
value="com.ffusion.myProduct.myComponent.myClass" />
</serviceProviderType>
The following example shows how a Java class method is associated with an
Activity. The input values correspond to the parameters of the method. The
output and fault names are the names assigned to return and exception values
as they are placed into the execution context. The types of the output and fault
elements must be specified. If they are not specified, the type of the output
defaults to java.lang.String and the type of the fault object defaults to
java.lang.Throwable.
<activity name="">
<input name="myParameter1" />
<input name="myParameter2" />
<output name="myReturnValue" type="int" />
<fault name="adException" />
<implement serviceProviderType="<JavaName>"
operation="<methodName>"/>
</activity>
6-17
Using operators
JMS Operators
JMS Operators are provided so you can access JMS queues from a Flow. JMS
queues must be declared in the Flow. The following information is required in
order to identify a JMS queue:
To locate the QueueConnectionFactory:
initial context factory
server URL
user name
password
JNDI name of queue connection factory
To locate the Queue:
JNDI name of queue
To create a QueueConnection:
user name (optional)
password (optional)
To create a QueueSession:
transacted
acknowledge mode
To create a QueueSender:
no additional information needed
To create a QueueReceiver:
message selector (optional)
A JMS queue is declared using the serviceProviderType element. The input values in
the example that follows correspond to the information listed above.
<serviceProviderType name="<JMSName>" type="JMS" >
<property name="initialContextFactory"
value="weblogic.jndi.WLInitialContextFactory"/>
<property name="serverURL" value="t3://localhost:9101"/>
<property name="password" value="password" />
<property name="connectionFactoryName"
value="ConnectionFactoryJNDIName" />
<property name="queueName" value="FIXQueueJNDIName" />
<property name="queueUserName" value="queueUserName" />
<property name="queuePassword" value="queuePassword" />
<property name="transacted" value="false" />
6-18
Using flows
Using operators
<property name="acknowledgeMode"
value="Session.AUTO_ACKNOWLEDGE" />
<property name=messageSelector" value="JMSType = 'Omgeo'" />
</serviceProviderType>
createStringMessage
Description
6-19
Using operators
createObjectMessage
Description
getMessagePropertyString
Description
Gets the value of a string property on a JMS Message object. The first argument
specifies the JMS Message object to retrieve the property value from and the
second argument specifies the name of the property. Here is an example of how
this operator gets associated with an Activity:
<activity name="">
<input name="jmsMessage" />
<input name="propertyName" />
<output name="propertyValue" />
<fault name="jmsException" />
<implement serviceProviderType="<JMSName>"
operation="getMessagePropertyString"/>
</activity>
receiveMessage
Description
Receives a JMS Message from a queue. The first argument specifies whether to
wait, and the second argument specifies how long to wait. If a waiting period of 0
is supplied, then the call waits forever. If the timeout period expires, then the
output argument will be null. If this is the first use of the queue, an initialization
of the queue will be performed.
Here is an example of how this operator gets associated with an Activity:
<activity name="">
<input value="true" />
<input value="100" />
<output name="jmsMessage" />
<fault name="jmsException" />
6-20
Using flows
Using operators
<implement serviceProviderType="<JMSName>"
operation="receiveMessage"/>
</activity>
receiveString
Description
Receives a message string from a queue. The first argument specifies whether to
wait, and the second argument specifies how long to wait in milliseconds. If a
waiting period of "0" is supplied, then the call waits forever. If the timeout period
expires, then the "output" argument will be null. If this is the first use of the queue,
an initialization of the queue will be performed.
This operator can only be called if the Message object returned by JMS is of type
TextMessage.
Here is an example of how this operator gets associated with an Activity:
<activity name="">
<input value="true" />
<input value="100" />
<output name="messageString" />
<fault name="jmsException" />
<implement serviceProviderType="<JMSName>"
operation="receiveString"/>
</activity>
receiveObject
Description
Receives a message object from a queue respectively. The first argument specifies
whether to wait, and the second argument specifies how long to wait in
milliseconds. If a waiting period of "0" is supplied, then the call waits forever. If the
timeout period expires, then the "output" argument will be null. If this is the first
use of the queue, an initialization of the queue will be performed.
This operator can only be called if the Message object returned by JMS is of type
ObjectMessage.
Here is an example of how this operator gets associated with an Activity:
<activity name="">
<input value="true" />
<input value="100" />
<output name="messageObject" />
<fault name="jmsException" />
<implement serviceProviderType="<JMSName>"
operation="receiveObject"/>
</activity>
6-21
Using operators
send
Description
Sends a message string or object to a queue. The first argument specifies the
message string or object data, the second argument specifies the delivery mode
(either javax.jms.DeliveryMode.NON_PERSISTENT or
javax.jms.DeliveryMode.PERSISTENT), the third argument specifies the priority (as
an integer), and the fourth argument specifies the lifetime of the message in
milliseconds. If this is the first use of the queue, an initialization of the queue will
be performed. Based on the type of the message data (String or object) the JMS
Message object will be a TextMessage or ObjectMessage. This operator is
equivalent to calling createStringMessage or createObjectMessage (depending on
the type of the message data) and sendMessage in sequence.
Here is an example of how this operator gets associated with an Activity:
<activity name="">
<input name="messageString" />
<input name="deliveryMode" />
<input value="javax.jms.DeliveryMode.NON_PERSISTENT"
type="Integer" />
<input name="priority" />
<input name="timeToLive" />
<fault name="jmsException" />
<implement serviceProviderType="<JMSName>"
operation="send"/>
</activity>
sendMessage
Description
Sends a JMS Message object to a queue. The first argument specifies the JMS
Message object, the second argument specifies the delivery mode (either
javax.jms.DeliveryMode.NON_PERSISTENT or
javax.jms.DeliveryMode.PERSISTENT), the third argument specifies the priority (as
an integer), and the fourth argument specifies the lifetime of the message in
milliseconds. If this is the first use of the queue, then the initialization of the queue
is performed. The JMS Message object will be a TextMessage or ObjectMessage.
Here is an example of how this operator gets associated with an Activity:
<activity name="">
<input name="jmsMessage" />
<input name="deliveryMode" />
<input name="priority" />
<input name="timeToLive" />
<fault name="jmsException" />
<implement serviceProviderType="<JMSName>"
operation="sendMessage"/>
6-22
Using flows
Using operators
</activity>
setMessageProperty
Description
Sets the value of a string property on a JMS Message object. The first argument
specifies the JMS Message object, the second argument specifies the name of the
property, and the third parameter specifies the value of the property. The JMS
Message object will be a TextMessage or ObjectMessage. Only string properties
are supported in this version.
Here is an example of how this operator gets associated with an Activity:
<activity name="">
<input name="jmsMessage" />
<input name="propertyName" />
<input name="propertyValue" />
<fault name="jmsException" />
<implement serviceProviderType="<JMSName>"
operation="setMessageProperty"/>
</activity>
Database operators
Since database connections cannot be passed via the EJB API, Database Operators
are provided.
Database properties must be declared in the Flow. The following information is
required to identify a database:
database URL of the form jdbc:subprotocol:subname
user name
password
A database connection is declared using the serviceProviderType element. The first
three input values correspond in the following example to the information listed
above.
Any properties other than those listed above will be considered to be named
properties specific to the particular type of database being used.
<serviceProviderType name="<DBConnectionType>" type="Database" >
<property name="databaseURL" value="jdbc:blah:blah" />
<property name="userName" value="sa" />
<property name="password" value="sysadmin" />
<property name="myProperty1" value="xxx" />
<property name="myProperty2" value="yyy" />
6-23
</serviceProviderType>
connect
Description
Establish a connection to the database. Here is how this operator gets associated
with an Activity:
<activity name="">
<output name="dbConnection" />
<fault name="sqlException" />
<implement serviceProviderType="<DBConnectionType>"
operation="connect"/>
</activity>
disconnect
Description
Disconnect from the database. Here is how this operator gets associated with an
Activity:
<activity name="">
<input name="dbConnection" />
<fault name="sqlException" />
<implement serviceProviderType="<DBConnectionType>"
operation="disconnect"/>
</activity>
6-24
Using flows
3. Right-click on Flow Collection and select New Flow Collection.You can also
click on Add Flow Collection in the right pane or select New Flow
Collection from the File menu.
4. Enter a name for your collection and click Next.
5. Enter a comment describing your flow collection and click Finish.
6. Right-click on your newly created flow collection in the right-hand pane and
select New Flow Set.
7. Enter a name for your flow set and click Next.
8. Enter a comment describing your flow set and click Finish.
9. Right-click on your newly created flow set in the right-hand pane and select
New Flow Definition.
10. Enter a name for your new flow definition and click Next.
11. If you were importing a previously defined flow definition file, you would enter
the name of the file on this screen. Click Next.
12. Click Edit and define your flow.
13. Click Next.
14. Enter a name for your flow definition and click Next.
15. Enter a comment to describe your flow definition and click Finish.
6-25
6-26
Using flows
input.add( "Customers" );
flow.setContext( input );
// Execute the flow
HashMap output = flow.execute( "flowSet",
"flowParseBuild"
);
NOTE: For more information on the methods in IFlow, see Chapter 11: Runtime
Application Interfaces.
6-27
6-28
Using flows
7
Using the Message Broker
run-time API
About this
chapter
This chapter explains how to use the Message Broker run-time API in stand-alone
Java applications or in server components such as Enterprise JavaBeans.
Topics include:
Getting started (p. 7-2)
Understanding program flow (p. 7-3)
Connecting to the run-time repository (p. 7-4)
Parsing text-encoded messages (p. 7-5)
Constructing IDL/Java message instances (p. 7-7)
Invoking message validation rules (p. 7-8)
Invoking message routing rules (p. 7-8)
Transforming messages to another format (p. 7-9)
Building messages (p. 7-9)
Persisting messages using SQL adapter templates (p. 7-11)
Executing a flow (p. 7-14)
For detailed API information, see the following areas of the Javadocs:
Building
Interface
Interface
Interface
com.ffusion.msgbroker.interfaces.IBuilder
com.ffusion.msgbroker.interfaces.IMBInstance
com.ffusion.msgbroker.interfaces.IMBMessage
7-1
Getting started
Getting started
To use this chapter, review the following steps:
1. To learn about Message Broker applications and their components, see
page 7-9.
9. For information about how Message Broker persists messages in a relational
database, see Persisting messages using SQL adapter templates on page 711.
10. For message data type formats, refer to Chapter 9: IDL/Java message
representation.
7-2
IMBInstance classes.
2. Call IMBInstance.disconnect to disconnect from the repository database.
3. Create, parse, and process messages. Applications typically perform one or
Class
com.ffusion.msgbroker.factory.MBInstanceFactory
Disconnecting
Interface
com.ffusion.msgbroker.interfaces.IMBInstance
Message
Processing
Package
Class
com.ffusion.msgbroker.interfaces
com.ffusion.msgbroker.factory.MBMessageFactory
7-3
7-4
Connecting
Class
com.ffusion.msgbroker.factory.MBInstanceFactory
Disconnecting
Interface
com.ffusion.msgbroker.interfaces.IMBInstance
Message Broker includes a debug version of the parser that outputs a trace of
message fields as they are parsed. The debug parser is useful for
troubleshooting ambiguous parse rules. To create a debug parser instance, call
the IMBInstance.createDebugParser. The debug parser usage is the same as
for regular IParser instances.
For detailed API information, see the following areas of the Javadocs:
Parsing
Interface
Interface
Interface
com.ffusion.msgbroker.interfaces.IMBParser
com.ffusion.msgbroker.interfaces.IMBInstance
com.ffusion.msgbroker.interfaces.IMBMessage
7-5
In this signature, buffer is the message content being parsed, startPosition is the
position within the buffer where the unknown data begins, and unknowns is a
java.util.Vector instance where you can append any objects that you wish. Typically,
you will append objects representing parsed fields. The parse method must return
the new buffer position or -1 if the field is not recognized.
The following code shows an example of a parse method:
public int parse( String buffer, int startPosition, Vector unknow
ns )
{
System.out.println( "Custom parse: " + startPosition );
int soh;
int equ;
int newPos = -1;
int tagNum;
String pretag;
// look for the equals sign
equ = buffer.indexOf( '=', startPosition );
if( equ != -1 ) {
// extract the tag
pretag = buffer.substring( startPosition, equ );
// convert to a number and check whether this tag
// is within a known range
tagNum = Integer.parseInt( pretag );
if( tagNum > 1000 ) {
// we have a tag out of range
// look for \u0001
soh = buffer.indexOf( '\u0001', equ + 1 );
if( soh != -1 ) {
// move to just after the SOH
newPos = soh + 1;
// and put the skipped data in the vector
7-6
unknowns.addElement(
buffer.substring( startPosition, soh ) );
}
return( newPos );
}
Class
Interface
com.ffusion.msgbroker.factory.MBMessageFactory
com.ffusion.msgbroker.interfaces.IMBMessage
7-7
Interface
Interface
Interface
com.ffusion.msgbroker.interfaces.IValidation
com.ffusion.msgbroker.interfaces.IMBInstance
com.ffusion.msgbroker.interfaces.IMBMessage
component instance that invokes routing. For information about how to define
routing rules in the Message Broker Manager, refer to Creating routing rules on
page 3-32.
For detailed API information, see the following areas of the Javadocs:
Routing
Interface
Interface
Interface
com.ffusion.msgbroker.interfaces.IRouter
com.ffusion.msgbroker.interfaces.IMBInstance
com.ffusion.msgbroker.interfaces.IMBMessage
com.ffusion.msgbroker.interfaces.ITransformation
com.ffusion.msgbroker.interfaces.IMBInstance
com.ffusion.msgbroker.interfaces.IMBMessage
Building messages
Use the IBuilder interface to convert message objects into a data stream; that is,
the encoded message is written to a byte or string buffer. For example, a message
gateway application might parse messages received in one format, transform them
to Java message objects in another format, then use the builder interface to
forward a data stream to another server.
The IMBInstance.createBuilder method returns an IBuilder interface. Call the
IBuilder.buildBytes or IBuilder.buildString method to create a byte or text stream,
in that order. You cannot use a single builder instance simultaneously on multiple
7-9
Building messages
threads. If you use the builder in server components, one builder instance can be
used by one component instance only.
NOTE: You can use an instance in multiple components if you use explicit thread
synchronization; however, restricting use to one component yields better
performance and a simpler application design.
For detailed API information, see the following areas of the Javadocs:
Building
7-10
Interface
Interface
Interface
com.ffusion.msgbroker.interfaces.ITransformation
com.ffusion.msgbroker.interfaces.IMBInstance
com.ffusion.msgbroker.interfaces.IMBMessage
You can invoke the generated Java code using the ISQLAdapter component. To
obtain a reference to a ISQLAdapter component please call
IMBInstance.createSQLAdapter method. The ISQLAdapter interface contains
methods such as insert, select, update and delete which lets you persist Message
Broker messages encapsulated in an IMBSQLMessage object.
A single ISQLAdapter instance cannot be used by multiple threads or server
component instances. You must create an ISQLAdapter instance for each thread
or server component instance that invokes ISQLAdapter. For more information of
how to use ISQLAdapter component, see sample code at the end of this section.
Understanding transactions
You may want to invoke the persistence methods as part of a larger transaction.
For this reason, the ISQLAdapter interface offers a setCommit method. The
default behavior is that a commit is performed for all database activities (as if
setCommit( true ) was called). If you invoke setCommit( false ), then a
commit will not be issued.
Since you supply the JDBC connection object used by the persistence operator
(via java.sql.Connection parameter of the IMBInstance.createSQLAdapter
method), you can also control the commit behavior by supplying a connection
object for which autoCommit has been turned on. If autoCommit is on, database
activities are implicitly committed, regardless of the setting of
ISQLAdapter.setCommit.
7-11
Sample code
This sample code shows inserting a message:
// User has an MBInstance
IMBInstance mbInst = ;
// User has an open JDBC connection
Java.SQL.Connection conn = ;
// User has a message object to be persisted
IMBMessage msg = ;
// User has a Vector in which the custom column values are held
Vector myCustomColumns;
ISQLAdapter sql;
IMBSQLMessage sqlMsg;
try {
sql = mbInst.createSQLAdapter( conn );
sqlMsg = MBSQLMessageFactory.createSQLMessage( msg, 12345
);
sqlMsg.setCustomColumns( myCustomData );
sql.insert( adapterSetName, sqlAdapterTemplateName, sqlMsg );
} catch( MBException ex ) {
// do error handling
}
7-12
7-13
Executing a flow
Executing a flow
The IFlow interface contains methods to execute a flow, retrieve the output of a
flow and retrieve any error that occurs during the execution of a flow.
Use the IMBInstance.createFlow method to create a flow instance.
For detailed API information, see the following areas of the Javadocs:
Flow
7-14
Interface
Interface
com.ffusion.msgbroker.interfaces.IFlow
com.ffusion.msgbroker.interfaces.IMBInstance
8
Using Message Broker Server
About this
chapter
This chapter introduces the Message Broker Server and how it is used to execute
flows. It also discusses how to monitor, stop and start Message Broker Server
from the Message Broker Manager. The Message Broker run-time API is also
provided.
Topics include:
Getting started (p. 8-1)
What is the Message Broker Server? (p. 8-2)
Using Message Broker Manager (p. 8-4)
The Message Broker Server run-time API (p. 8-5)
Message Broker Server examples (p. 8-6)
Getting started
To use this chapter effectively, review the following steps:
1. For an overview of Message Broker Server, see What is the Message Broker
8-1
%MB60INSTALLDIR%\MBServer\bin\startMBServer.bat
On Solaris:
$MB60INSTALLDIR/MBServer/bin/startMBServer.sh
8-2
%MB60INSTALLDIR%\MBServer\bin\stopMBServer.bat
On Solaris:
$MB60INSTALLDIR/MBServer/bin/stopMBServer.sh
Executing flows
After the host application server is started, you can begin using the Message
Broker Server by invoking methods on the Message Broker Server Admin EJB. For
details, see The Message Broker Server run-time API on page 8-5.
The first step when executing flows is to start the Message Broker Server instance
by calling the startServer() method. The server instance needs to connect to a
Message Broker run-time repository the repository connection information is
specified in the call to startServer(). Once the server instance is started, you call
initializeFlow() to create a flow instance. This method returns a flow instance ID
that you use to reference the flow instance in subsequent API calls. A flow instance
is not bound to a specific flow; it can be used to execute several different flows.
NOTE: A flow instance can only be used by one client at a given time. If several clients
need to execute flows simultaneously, they must each initialize their own flow
instance.
You can now use the flow instance to execute a flow. If the flow requires input
parameters (which are specified by the flowSource element in the flow XML),
then you make a call to setFlowContext() to set the input values. Once these
required inputs have been set, you execute the flow by calling executeFlow() or
executeFlowNoWait(). In the case of executeFlow(), the method blocks until the
flow execution is complete. If the execution completed without error, the method
returns a HashMap containing the output parameters (as specified by the
flowSink element in the flow XML) from the flow.
If executeFlowNoWait() was called, the method returns immediately and you must
call getFlowStatus() to determine when the flow execution has completed. Once
this execution is complete, you can obtain the flow output by calling
getFlowOutput().
8-3
connection.
3. Select Message Broker Server.
4. Enter the connection information for the application server that is hosting the
Message Broker Server you want to connect to and click OK.
Once connected to the Message Broker Server you can monitor its status on the
right side of the screen as well as start and stop the server instance.
To start a Message Broker Server:
1. Right-click on the server you wish to start.
2. Select Start and enter the connection information for the Message Broker
run-time repository. Click OK.
8-4
Package
com.ffusion.msgbroker.server.adminEJB
In order to use the Message Broker Server Run-time API, your client application
needs to import the com.ffusion.msgbroker.interfaces and
com.ffusion.msgbroker.server.adminEJB packages. You also need to include the
following in the classpath:
%MB60INSTALLDIR%\server\mbserv60.jar
%MB60INSTALLDIR%\MBServer\<appServer>\client\MBServerAdminClient.
jar
Any application server specific Jar files or classes that are required in order to
connect to the application server.
NOTE: If the repository was deployed from a different machine than the one running
the Message Broker Server, you must manually transfer the run-time Jar file
(%MB60INSTALLDIR%\runtime\<repositoryName>.jar) over to the machine
that is running the Message Broker Server.
8-5
3. Infuse the message string into the execution context of the Flow Instance:
sendOptions = new Properties();
sendOptions.setProperty( "sessionID", "Counter-party" );
context = new Vector();
context.add( myMessageString );
context.add( sendOptions );
context.add( "FIX41" );
mbsbean.setContext( flowInstanceID, context );
8-6
Alternatively, you could execute the Flow without waiting for its execution to
complete. In this case, you would perform the following actions:
1. Get a reference to the MB Server Admin EJB:
ctx = getInitialContext(url, user, password, jndiFactory);
home = (MBSAdmin) ctx.lookup( "MBServer/MBSAdmin" );
mbsbean = home.create();
3. Infuse the message string into the execution context of the Flow Instance:
sendOptions = new Properties();
sendOptions.setProperty( "sessionID", "Counter-party" );
context = new Vector();
context.add( myMessageString );
context.add( sendOptions );
context.add( "FIX41" );
mbsbean.setContext( flowInstanceID, context );
5. At this point, you would occasionally poll to see if the Flow has completed.
6. Once complete, retrieve the output of the Flow:
MBSFlowStatusInfo flowStatus;
flowStatus = mbsbean.getFlowStatus( flowInstanceID );
if( flowStatus.flowState == IMBFlowState.MBS_FLOWSTATE_COMPLETED
)
{
// The Flow is done. Get the output.
HashMap flowOutput;
flowOutput = mbsbean.getFlowOutput( flowInstanceID );
}
8-7
The Flow itself would be defined as follows. The Flow parses the message (in
preparation for the next step), validates the message, and then sends the message
to GlobalFIX.
<flowModel name="MyFIXSendFlow">
<!-- Flow start and end definitions -->
<flowSource name="ParseFIX">
<input name="fixString">
<input name="sendOptions" type="Properties">
<input name="messageSetName">
</flowSource>
<flowSink name="SendFIX">
<output name="messageReference">
</flowSink>
<!-- Service Providers -->
<serviceProviderType name="GFIX" type="EJB" >
<property name="initialContextFactory"
value="com.sybase.ejb.InitialContextFactory" />
<property name="serverURL" value="iiop://localhost:9009" />
<property name="userName" value="username" />
<property name="password" value="password" />
<property name="jndiName" value="FIX/IAdapter" />
</serviceProviderType>
<!-- Activities -->
<!-- parse the FIX message string -->
<activity name="ParseFIX">
<input name="fixString"/>
<input name="messageSetName"/>
<output name="fixMessageObject"/>
<fault name="mbparseError"/>
<implement serviceProviderType="MessageBroker"
operation="parse"/>
</activity>
<!-- validate FIX message object -->
<activity name="ValidateFIX">
<input name="fixMessageObject"/>
8-8
<input value="null"/>
<fault name="mbValidateError"/>
<implement serviceProviderType="MessageBroker"
operation="validate"/>
</activity>
<!-- send the message string to GFIX -->
<activity name="SendFIX">
<input name="fixString"/>
<input name="sendOptions">
<output name="messageReference"/>
<fault name="fixSendError"/>
<implement serviceProviderType="GFIX"
operation="send"/>
</activity>
<!-- Control Links -->
<controlLink
source="ParseFIX"
target="ValidateFIX">
<controlLink
source="ValidateFIX"
target="SendFIX">
</flowModel>
8-9
8-10
<flowSink name="SendFIXMessage">
<output name="fixString">
</flowSink>
<!-- Service Providers -->
<serviceProviderType name="GFIX" type="EJB" >
<property name="initialContextFactory"
value="com.sybase.ejb.InitialContextFactory" />
<property name="serverURL" value="iiop://localhost:9009" />
<property name="userName" value="username" />
<property name="password" value="password" />
<property name="jndiName" value="FIX/IAdapter" />
</serviceProviderType>
<serviceProviderType name="myJMSProvider" type="JMS" >
<property name="initialContextFactory"
value="com.sybase.ejb.InitialContextFactory" />
<property name="serverURL" value="iiop://localhost:9009" />
<property name="userName" value="userName" />
<property name="password" value="password" />
<property name="connectionFactoryName"
value="ConnectionFactoryJNDIName" />
<property name="queueName" value="FIXQueueJNDIName" />
<property name="queueUserName" value="queueUserName" />
<property name="queuePassword" value="queuePassword" />
<property name="transacted" value="false" />
<property name="acknowledgeMode"
value="Session.AUTO_ACKNOWLEDGE" />
<property name=messageSelector" value="JMSType = 'FIX'" />
</serviceProviderType>
<!-- Activities -->
<!-- parse the FIX message string -->
<activity name="ReadJMSQueue">
<input value="true" />
<input value="100" />
<output name="fixString"/>
<fault name="jmsError"/>
<implement serviceProviderType="myJMSProvider"
operation="receiveString"/>
</activity>
8-11
8-12
9
IDL/Java message
representation
About this
chapter
This chapter discusses how to define message formats, map for various data types
and fields, and view generated Java and IDL code.
Topics include:
Getting started (p. 9-2)
Overview (p. 9-3)
Location of generated files (p. 9-3)
Mapping for message bodies, headers, and trailers (p. 9-5)
Mapping for atomic types (p. 9-6)
Mapping for enumerations (p. 9-7)
Mapping for composite types (p. 9-12)
Mapping for unions (p. 9-13)
Mapping for user-defined types (p. 9-14)
Using optional fields (p. 9-15)
Mapping of repeated fields (p. 9-15)
Mapping for SQL Type (p. 9-16)
Viewing generated Java and IDL code (p. 9-17)
9-1
Getting started
Getting started
To use this chapter effectively, review the following steps:
1. For details of what happens at deployment time, see Overview on page 9-3.
2. For the location of IDL-generated files, see Location of generated files on
page 9-3.
3. To map message bodies, headers and trailers to IDL structures or Java classes,
review Mapping for message bodies, headers, and trailers on page 9-5.
4. For a list of primitive types supported by Message Broker and their
equivalents in IDL and Java, see Mapping for atomic types on page 9-6.
5. For an overview of enumerations, see Mapping for enumerations on page 9-
7.
6. For an overview of composite types and how they group related fields
page 9-14.
9. For information on optional fields, see Using optional fields on page 9-15.
10. To learn about repeated fields, see Mapping of repeated fields on page 9-15.
11. For a list of the data types supported by Message Broker. see Mapping for
types and fields, review Viewing generated Java and IDL code on page 9-17.
9-2
Overview
Overview
At run time, Message Broker represents message instances using standard IDL and
Java. At deployment time, Message Broker creates IDL modules to define the
format of messages and fields, then compiles these into Java classes that can be
manipulated in user applications. If you are using EAServer components to process
messages, you can use the generated IDL modules to define the component
interfaces using message objects as parameters and return values.
Message Broker defines message formats using the IDL primitive types, structures,
and enumerations. The Java representation follows the standard IDL/Java type
mappings and applies to parameter and return types in Enterprise JavaBean
methods.
To learn how to deploy message collections to a run-time repository, refer to
Deploying to the run-time repository on page 3-51. You must deploy a
collection to generate the IDL and Java types that represent messages in the
collection.
IDL is not generated for message sets marked as recursive because IDL does
not support self-referencing structures.
9-3
subdirectory.
2. Restart the server.
Each time you deploy from the Message Broker Manager, Message Broker compiles
the generated classes and adds them to the run-time Java Archive (JAR) file,
runtime/<repositoryName>.jar. (Note that <repositoryName> is a placeholder for
the name of the repository. For example, if the default repository name of
"MessageBroker" is used, the name and location of the Jar file would be runtime/
MessageBroker.jar.) Add this file to the CLASSPATH environment variable for your
applications.
When you define and deploy a SQL Adapter template, Message Broker generates
Java class methods that allow you to insert, select, update, or delete a message.
Message Broker compiles the generated classes and adds them to the run-time
JAR file, runtime/<repositoryName>.jar in the Message Broker installation directory.
9-4
The header and trailer fields follow the mappings for the primitive types,
composite types, unions, and enumerations described in this chapter. A message
body maps to an IDL structure. If the message set has a header, the first field in the
structure refers to the message header. If the message set has a trailer, the next
field refers to the message trailer. The remaining fields follow the mappings for
primitive types, composite types, unions, and enumerations.
The mapping for a message AddCustomer that has both a header and trailer is as
follows:
struct TypeAddCustomer {
TypeHeader header;
TypeTrailer trailer;
... message body fields ...
};
9-5
9-6
Display type
name
IDL type
Java type
string
string
java.lang.String
date
string
java.lang.String
All date values are formatted as strings
according to the format specifier for the field.
You can use the methods in the JDK
java.text.SimpleDateFormat class to convert
java.util.Date instances to formatted strings
and vice-versa.
bytes
sequence <octet>
byte[]
boolean
boolean
boolean
int16
short
short
int32
long
int
int64
long
long
float32
float
float
double64
double
double
The base-type representation is easier to use if your application requires the field
value in its base-type representation. The IDL enumeration representation is
easier to use if your application contains logic to branch to different execution
paths based on the field value, for example, a Java switch statement. For either
representation, Message Broker generates an additional Java class named
ValueSetEnumerationName, where EnumerationName is the name of the Message
Broker enumeration.
The definition of enumerated fields in the Message Broker Manager determines
which representation is used at run time. To use the IDL enumeration
representation, choose Enumeration for the Represent field data as setting. To use
the base-type representation, choose the Represent field data as setting as the
base type for the enumeration. In either case, you must specify the enumeration
name in the Enumeration drop-down list.
9-7
Value
red
yellow
purple
In Java, each Message Broker enumeration maps to a class with the following
structure:
public final class EnumEnumeration {
// One pair for each member_name in the IDL enum.
// The integer sequence_value constants have no
// relation to values in the Message Broker
// enumeration.
public static final int _member_name = sequence_value;
public static final Enumeration member_name = new Enumeration
( _member_name );
// Return integer code for current value
public int value() {...}
// Return an enum for a specified sequence_value
public static Enumeration from_int(int sequence_value);
// Constructor is private
private Enumeration(int) { ... }
}
The Java class has the name EnumEnumeration, where Enumeration is the name of
the Message Broker enumeration type. For each member in the enumeration, the
Java class has two members. One refers to the integer constant that corresponds
to the member name, and the other refers to an instance of the enumeration class
9-8
To use enumeration values in switch statements, use the field that is prefixed with
an underscore as shown in the following example:
switch (myEnum.value()) {
case Colors._purple:
... do something ...\
};
To refer to an instance with a specific value, use the field with the same name as
the desired member, for example, the following statement returns an instance of
the Colors enumeration with value purple:
Colors thePurpleOne = EnumColors.purple;
NOTE:
With Enum usage, the integer constant for each member name is determined
when the IDL is compiled into Java. Constants are shown here only for
example. Do not code enumeration constants into your programs. If you do not
have any fields in a message set that use the IDL enumeration, Message
Broker does not generate the EnumEnumeration Java class.
You can call the contains method to check whether a value is in the enumeration's
set of allowable values, for example, the following code might be used in a
validation or routing rule to refer to the value set class generated for an
enumeration named ServiceType:
if( !ValueSetServiceType.contains( theField ) ) {
return false;
}
return true;
9-9
NOTE:
where <enumDataType> is the base data type of the enumeration, such as string,
16-bit integer, and so on. Invoking getValue (index), where index is the integer
constant associated with the enumeration member, returns the value associated
with that member. The integer constant for the enumeration member can be
retrieved by calling the value( ) method on the Enum<Enumeration> object.
For example, consider the enumeration Colors defined previously of base type
integer with the following member/value pairs:
Member name
Value
red
yellow
purple
The variable color would contain one of the values from the Color
enumerations value set {1, 2, 3}.
9-10
where <enumDataType> is the data type of the enumeration, such as string, 16-bit
integer, and so on. This method performs the opposite functionality to the
ValueSet<Enumeration>.getValue( ) method described previously.
Invoking getIndex(Value), where Value is an entity in the enumerations value set, will
return the integer constant for the enumeration member that is associated with
the given value. Using the integer constant, you can obtain an Enum<Enumeration>
object by calling the static from_int() method on the Enum<Enumeration> class.
The getIndex() method together with getValue() is useful for mapping between two
different enumerations, such as within a transformation.
As an example, consider the previous enumeration Colors of data type integer and
with the following member/value pairs:
Member name
Value
red
yellow
purple
Value
RocketRed
MellowYellow
To map from Colors to RoadsterColors, you could use the following code:
EnumColors instanceEnumColors = ; // parsed enum instance
EnumRoadsterColors instanceEnumRoadsterColors =
EnumRoadsterColors.from_int(
ValueSetRoadsterColors.getIndex(
ValueSetColors.getValue(
InstanceEnumColors.value() ) );
9-11
After doing this, you can also find the value associated with the new enumeration
instance as follows:
integer roadsterColor = ValueSetRoadsterColors.getValue
(instanceEnumRoadsterColors.value() );
NOTE:
The value 3 that represents the color purple in the Colors enumeration is not
part of the value set for the enumeration RoadsterColors. Calling getIndex()
with an invalid value such as this will result in a
java.lang.IllegalArgumentException being thrown.
IDL mapping
In IDL, composite types map to a structure declared as
struct TypeCompositeName {
... field declarations ...
};
In this structure, CompositeName is the name of the composite field or userdefined composite type. The field declarations follow the mappings for primitive
types, composite types, unions, and enumerations. Each field maps to a field of the
same name in the IDL structure.
Java mapping
In Java, each composite type maps to a Java class declared as follows:
public class TypeCompositeName {
... field declarations ...
public TypeCompositeName();
public TypeCompositeName( Type1 field1, Type2 field2, ... );
}
9-12
in the Java class. The class has a default constructor and a constructor that takes a
parameter for each field in the composite, in the ordinal order of the composite.
Mapping in IDL
In IDL, unions are mapped to a structure with the following fields:
struct TypeUnionName {
string __preValueTag;
string __memberName;
... field declarations ...
}
UnionName is the name of the union field or user-defined union type. The
_preValueTag field is filled in when the active union member has a pre-value tag
defined in the Message Broker Manager. If the active member does not have a prevalue tag, then the parser will simply leave the field with a null value. The IDL field
holds the corresponding string value for each tag. The __memberName name field
indicates the name of the active union member. The remaining fields follow the
mappings for primitive types, composite types, unions, and enumerations. Each
field in the Message Broker union maps to a field of the same name in the IDL
structure.
Mapping in Java
In Java, unions are mapped to a class with the following declarations:
public class TypeUnionName {
public String __preValueTag;
public String __memberName;
... field declarations ...
public TypeUnionName();
public TypeUnionName( String preValueTag, String memberName,
type1 field1, type2 field2, ...);
}
9-13
UnionName is the name of the union field or user-defined union type. The
_preValueTag field is filled in when the active union member has a pre-value tag
defined in the Message Broker Manager. If the active member has no pre-value tag,
then the parser will leave the field with a null value. The Java field holds the
corresponding string value for each tag. The _memberName field indicates the
name of the active union member.
The remaining fields follow the mappings for primitive types, composite types,
unions, and enumerations. Each field in the Message Broker union maps to a public
field of the same name in the Java class. The class has a default constructor and a
constructor that takes parameters for the pre-value tag, member name field, and
each field in the Message Broker union. You can pass a value for the field being set
and null for all other fields.
NOTE:
9-14
Default values
If a message or composite field uses an optional field with an atomic data type, you
can specify a default value for the field in the Message Broker Manager. When
parsing messages with optional fields, Message Broker uses the default value when
the field is not present in the message data. To determine whether the value of an
optional field was actually supplied in the message data, test this variable.
9-15
9-16
MB Data
Type
ASA Type
ASE Type
Oracle Type
DB2 Type
STRING
TEXT if 32767
characters, or
VARCHAR if
not fixed length,
or CHAR if
fixed length. If
length is
unknown,
default to
VARCHAR 255.
TEXT if 255
characters, or
VARCHAR if
not fixed
length, or
CHAR if fixed
length. If length
is unknown,
default to
VARCHAR
255.
CLOB if 2000
characters, or
VARCHAR if
not fixed
length, or
CHAR if fixed
length. If length
is unknown,
default to
VARCHAR
255.
CLOB if 4000
characters, or
VARCHAR if
not fixed
length, or
CHAR if fixed
length. If length
is unknown,
default to
VARCHAR
255.
BYTES
IMAGE if 32767
bytes, or
VARBINAry if
not fixed length,
or BINARY if
fixed length.
IMAGE if 255
bytes, or
VARBINAry if
not fixed
length, or
BINARY if fixed
length.
BLOB if 2000
characters or
RAW.
BLOB
BOOLEAN
SMALLINT
SMALLINT
SMALLINT
SMALLINT
INT16
INTEGER
INTEGER
INTEGER
INTEGER
INT32
INTEGER
INTEGER
INTEGER
INTEGER
INT64
DECIMAL (20,
0)
DECIMAL (20,
0)
DECIMAL (20,
0)
DECIMAL (20,
0)
FLOAT32
REAL
REAL
REAL
REAL
DOUBLE64
DOUBLE
DOUBLE
DOUBLE
DOUBLE
DATE
Same as String
Same as String
Same as String
Same as String
ENUM
SMALLINT
SMALLINT
SMALLINT
SMALLINT
For an enumeration, you can also view the Java code for the generated
value set class. Choose File > View Value Set Java.
9-17
9-18
A
Javadoc
About this
chapter
This appendix provides you with the information to effectively use the Javadocs for
Message Broker.
A-1
In the right frame, you can select items on the navigation bar at the top to see
various views.
A-2
Javadoc
Index
adapter collections
adding 3-45
adapter set
adding 3-45
adding
fields 3-6
members to enumerations 3-24
message sets 3-5
routing collections 3-34
routing rules 3-35
routing set 3-35
transformation collections 3-40
transformation sets 3-40
transformations 3-41
XML-based message sets 3-11
API templates
creating 5-1
deploying 5-7, 5-8
macros 5-6
modifying 5-4
overview of 1-10
properties 5-4
template editor 5-6
APIs
IBuilder 7-9
IMBMessageFactory 7-7
IParser 1-8, 7-5
IRouter 7-8
ITransformation 1-9, 7-9
B
begin field delimiter 3-22
begin tag delimiter 3-22
build number 2-9
C
code, generated
viewing in Sybase Central 9-17
composites
defining 3-16
runtime type mapping for 9-12
Connecting 2-4
connecting
IX - 1
D
datatypes
atomic 9-6
composite 9-12
for runtime representation of messages 9-1
IDL 9-1
Java 9-1
mapping dialog 3-15
representing enumerations 9-7
representing unions 9-13
user-defined 9-14
Defining 4-9
defining
enumerations 3-23
explicit validation rules 3-31
field delimiters 3-6
field tags 3-6
headers 3-5
message set 3-3
message type indicator 3-7
messages 1-6, 3-6
trailers 3-6
transformation rules 3-41
validation rules 3-29
delimiters
defining 3-6
field 3-22
deploying
design information 1-5
to the runtime repository 2-9, 3-2,
3-51
design repository 2-2
IX-2
Index
disconnecting
Message Broker repositories 2-7
document type definition
DTD 4-1
XML 4-2
drag-and-drop features 3-26
DTD
mapping from 3-9
Message Broker 4-4
overview 4-1
XML 4-2
E
editing
routing rules 3-32
transformation rules 3-41
validation rules 3-29
EJB
as a routing rule target 3-38
routing to 3-32
end field delimiter 3-22
enumerations 3-23, 4-8
adding members to 3-24
defining 3-23
guidelines for writing rules for 3-28
message set 3-4
runtime types to represent 9-7
explicit validation rules
defining 3-31
overview of 1-8
exporting
repository information to an XML
file 3-50
F
field characteristics
defining 1-7
field delimiters 3-22
field length
defining 1-6
field tags 3-22
field types
atomic, composite, union 3-16
fields
adding 3-6
adding to a message 4-8
atomic 3-16
composite 3-16
modifying 3-8
optional 9-15
picture code 3-21
union 3-16
fields, atomic
defining 3-16
fields, optional
default values for 9-15
G
generated code
viewing in Sybase Central 9-17
guidelines
for writing rules 3-27
IMBMessageFactory
Java class 7-7
implicit validation rules
explanation of 1-8
importing
repository information from an XML
file 3-50
samples 2-7
insignificant white space
definition of 3-4
IParser
Java class 1-8, 7-5
IRouter
Java class 7-8
ITransformation
Java class 1-9, 3-39, 3-40, 7-9
IValidation
Java class 3-29, 7-8
J
Java
message instances 7-7
See also APIs
types to represent message data 9-1
viewing in Sybase Central 9-17
H
handlers
for unknown fields 7-6
headers
defining 3-5
message set 3-3
run-time type mapping for 9-5
header-to-header
transformations 3-42
I
IBuilder
Java class 7-9
IDL
message instances 7-7
types to represent message data 9-1
viewing in Sybase Central 9-17
IMBInstance
Java class 7-4
M
mapping
from the DTD to Message Broker 39
name and data type mapping dialog
3-15
MBInstanceFactory
Java class 7-4
Message Broker
definition of 1-1
DTD 4-1, 4-4
interface 1-5
samples 2-7
Message Broker Plug-in
registering 2-2
IX-3
O
optional fields
default values for 9-15
guidelines for writing rules for 3-27
overriding
user-defined types 3-25
IX-4
Index
P
parsing
messages 1-8
runtime API for 7-5
text-encoded messages 7-5
picture code
field 3-21
post-value tag 3-22
pre-value tag 3-22
problems
reporting 2-9
R
registering
Message Broker Plug-in 2-2
repeat Java utility
transformation rules 3-43
repeated fields
guidelines for writing rules for 3-27
reporting problems 2-9
repositories
connecting to the design-time repository 2-4
connecting to the runtime repository 2-6, 7-4
disconnecting 2-7
temporary connections 2-6
routing
example of 1-9
messages 1-9
runtime API for 7-8
to an EJB 3-38
routing collections 4-11
adding 3-34
creating 3-32
routing rule 4-11
routing rules
adding 3-35
definition of 1-4
invoking at runtime 3-33, 7-8
modifying 3-36
S
samples 2-7
building and running 2-8
importing sample definitions 2-7
of transformation rules 3-44
source message
transformation set 3-40
T
tags
defining 3-6
field 3-22
templates
EJB 5-7
IDL 5-7
templates, API
overview of 1-10
temporary
U
unions
as field type 3-16
defining 3-17
runtime representation of 9-13
IX-5
unknown field
handler 3-4
unknown fields
handling 7-6
user data
guidelines for writing rules using 328
user-defined types 3-4, 3-24
overriding 3-25
runtime representation of 9-14
validation rules for 3-31
V
valid documents
XML 4-2
validating
messages 1-8
validation
explicit 1-8
implicit 1-8
runtime API for 7-8
validation rules
defining 3-29
definition of 1-4
for user-defined types 3-31
invoking at runtime 3-29, 7-8
modifying 3-31
W
well-formed documents
XML 4-2
X
XML
document type definitions 4-2
DTD 4-2
importing and exporting from 3-50
importing definitions from 1-5
introduction 4-2
valid documents 4-2
well-formed documents 4-2
IX-6
Index
R
Reader Comment Form
About this form
We welcome your feedback on this publication. Your comments can be of great value
in helping us improve our information products.
Document Title
Version
Date
Accuracy
Clarity
5 = Excellent
Completeness
4 = Good
Organization
3 = Adequate
Appearance
2 = Fair
Examples
1 = Poor
Illustrations
0 = Not applicable
Question resolution
Overall satisfaction
3. Write any additional comments you may have below. If necessary, include
extra sheets with page numbers (where applicable).
Phone
Fax
Thank you for your evaluation of this publication. Your feedback is very important to
us. Choose one of the following methods to send us this information:
1. Fax this form to (519) 747-4971.
2. Mail it to:
Sybase, an SAP Company