Pluggable transport

B2Bi supports transport extensibility through pluggable transports for customized message consumption and production. This enables custom code to control message exchanges with any back-end application without changing the base code.

Integration exchanges define the connection points between the B2Biand back-end systems. Inbound and outbound messages are exchanged between these systems using exchange points. B2Bi supports many types of exchange points, including file system, JMS, MQSeries and FTP. Typically, you configure several exchange points when you implement B2Bi an enterprise infrastructure. When customized integration is desired, developers can use the pluggable transport API to create a new transport and deploy it to the B2Bi trading engine. Once developed, application administrators can use the user interface to configure the custom integration.

In the user interface, a pluggable transport exchange point appears as just another transport option.

A pluggable transport can be used to:

  • Provide tight integration between B2Bi and a back-end application using a third-party API.
  • Exchange additional document metadata such as routing IDs with a back-end server.
  • Exchange messages with back-end systems using a proprietary mechanism such as a database or web service.
  • Enable a file system transport that supports directory multiplexing for inbound delivery.

Java interfaces and configuration file

The pluggable transport framework interacts abstractly with external transport servers via three Java interfaces and an XML configuration file.

The three interfaces are: PluggableClient, PluggableSettings, and PluggableMessage. These offer an implementation-agnostic connection method for exchanging messages with external servers.

The XML file, pluggabletransports.xml, enables the B2Bi trading enging to learn of new pluggable transports and create instances of them at runtime.

The following sections provide more details about the interfaces and the configuration file.

PluggableClient

The PluggableClient interface defines methods for B2Bi to generically communicate with transport servers. B2Bi has no knowledge of the actual communication protocol. Rather, it simply calls the methods of this interface in a particular order. The interface defines methods such as connect(), authenticate(), consume()/produce(), list() and disconnect(). There also are methods to describe the capabilities of the protocol (for example, if polling is supported).

Each pluggable transport is realized by its own Java class that implements the methods described by this interface. PluggableClient objects are created and called by B2Bi at runtime.

PluggableSettings

The PluggableSettings interface stores information required by a PluggableClient implementation to communicate with a particular exchange point. PluggableSettings provides methods to access this information generically. It mirrors the data structure of pluggabletransports.xml.

There are three types of information available in a PluggableSettings object:

  • Descriptive information such as a name and Java class.
  • Settings provided by the user when an exchange point is configured in the user interface.
  • Constant settings provided by the developer.

This configuration approach allows information (such as protocol, host, port, location, and credentials) to be generically persisted in B2Bi database. B2Bi creates a PluggableSettings object at runtime and passes it to the PluggableClient implementation each time the PluggableClient is instantiated.

PluggableMessage

The PluggableMessage interface stores information about the messages being processed. You can set and get the payload data as well as metadata about the payload.

A message object may only have one payload, which can be retrieved for parsing or transformations. You also can set a new payload in the message. This effectively replaces the previous payload with the new one. The PluggableMessage class exposes the payload through a mechanism called VirtualData, which is a payload file wrapper. VirtualData provides complete access and control of the payload file, but adds a layer of extraction that enables the B2Bi trading engine to add in-memory caching, streaming and backup directory management. Although the file can be accessed directly, we strongly recommended using VirtualData.

As a message is processed, it is continuously loaded with additional information about the payload and the context in which it has been processed. This information is called metadata. The PluggableMessage object offers setters and getters for string-based metadata. Each metadata item has a name and a value. These are stored in an accessible map. The name values are defined by two Java interfaces:

  • com.cyclonecommerce.collaboration.MetadataDictionary
  • com.cyclonecommerce.webservices.collaboration.ebxml.EbxmlMetadataDictionary.

pluggabletransports.xml

System administrators deploy pluggable transports to B2Bi by editing the pluggabletransports.xml file in <B2Bi_install_directory>/InterchangeActivator/conf. The user interface reads the file at runtime whenever an application administrator configures a new exchange point.

Adding pluggable transports to this file enables B2Bi to dynamically extend its integration capabilities without the need for base code changes. As mentioned earlier, the structure of pluggable transport configurations in this file closely mirrors the methods available in the PluggableSettings interface. Details about the file structure are provided in Deploy a pluggable transport. The XML schema for pluggabletransports.xml is defined by conf/pluggabletransports.xsd.

There is no need to restart B2Bi after editing the pluggabletransports.xml file.

Runtime use of pluggable transports

The following describes how PluggableClients, PluggableSettings and PluggableMessages are used together at runtime to exchange a message. For detailed information on each method, see the Swagger API Javadoc.

To open Swagger and consult the Javadoc, open a browser and enter the URL https://<host>:<port>/apidocs/ui.

When an application administrator configures exchange points in the user interface, the information describing them is persisted to the database. Whenever interaction with a transport server is required during runtime, B2Bi creates a PluggableSettings object based on the persisted information, instantiates the appropriate PluggableClient object, and passes the PluggableSettings to the PluggableClient’s init() method. At this point, the PluggableClient is ready to poll, consume or produce messages.

The PluggableClient implementation must have a default constructor.

Message polling

The interval for polling for documents to consume is set in the user interface for each consumer exchange point. At the polling interval, the scheduler calls the methods for the newly instantiated and initialized PluggableClient to get a list of waiting messages. The PluggableClient methods are then called to consume the messages.

The order in which PluggableClient methods are called depends on whether isPollable() returns true or false.

If isPollable() is true

init() à connect() à authenticate() à isPollable() à list() à disconnect()

If isPollable() is false

init() à connect() à authenticate() à isPollable() à consume() à disconnect()

Some servers cannot efficiently return a list of unique message references, such as e-mail, JMS, and IBM MQSeries. For these, the isPollable() method should return false. In this case, B2Bi repeatedly calls the consume() method until a null value is returned.

At this point, B2Bi compares the list of returned references against a master copy stored in the database. Any new entries are added to the master copy. This prevents files from being consumed twice.

Message consumption

Once B2Bi has a list of messages to consume, it creates a PluggableMessage and PluggableClient for each. The methods of PluggableClient are then called in the following order to consume the messages:

init() à connect() à authenticate() à consume() à delete() à disconnect()

The PluggableMessage passed to consume() stores information about the message payload and any available metadata. The payload file is stored in the B2Bi trading engine backup directory. A reference to the file and the metadata are stored in the database. The message is then submitted to the remainder of the pipeline for processing.

Message production

As messages approach the completion of processing, they are packaged or unpackaged and populated with metadata. When a message is ready to be produced, B2Bi creates a PluggableClient and passes to it the PluggableMessage, which was created during consumption.

The PluggableClient methods are called in the following order:

init() à connect() à authenticate() à produce() à disconnect()

Implement a pluggable transport

A developer must implement the pluggable transport interface defined in com.cyclonecommerce.tradingengine.transport.pluggable.api.PluggableClient.

Use the API Javadoc for a detailed description of each method.

The following are the general steps needed to implement a pluggable transport:

  1. Determine the types of parameters needed to configure the new type of pluggable transport to communicate with the new type of transport server. What does the user need to provide to configure the transport? For example, a file system PluggableClient only needs to know a directory name. In contrast, an MQSeries PluggableClient needs many more fields such as host, port, channel, and user information. Decide whether any of these parameters can change or whether users should be allowed to change them. Add constant parameters to the constant section of the TransportDefinition.
  2. Create a TransportDefinition element in pluggabletransports.xml that describes the pluggable transport and its required parameters. See Deploy a pluggable transport.
  3. Create a Java class that implements the PluggableClient interface. Use the PluggableMessage passed into init() as the source of the configuration information. Although all the methods must be defined in order to implement the interface, not all methods have to actually do anything. For example, there is no "connection" to a file system. The connect() method for a file system pluggable transport implementation would simply return without doing anything.
  4. Deploy the new PluggableClient to the trading engine by copying the JAR file you created to <install directory>/jars. Any files in this directory are automatically added to the classpath at startup.

Although changes to the pluggabletransports.xml file are read dynamically by the user interface, Java does not support dynamic reloading of Java classes. Therefore, a restart of B2Bi after recompiling the pluggable transport is required.

Deploy a pluggable transport

After a developer creates and tests a pluggable transport, a system administrator deploys it by adding a TransportDefinition to the pluggabletransports.xml file.

Each TransportDefinition describes one pluggable transport. Each pluggable transport defined in pluggabletransports.xml appears in the user interface as another transport option.

The following is an example of a pluggable transport definition in pluggabletransports.xml. See conf/pluggabletransports.xsd for descriptions of each element and attribute.

<TransportDefinition

name="Custom file system consumer"

description="Consumes messages from the file system."

available="true">

<Class>com.cyclonecommerce.tradingengine.transport.pluggable.

api.PluggableClientExample</Class>

 

<Usages>

<Consume>

<Integration/>

</Consume>

 </Usages>

 <SettingDefinitions>

  <SettingDefinition

   name="Directory"

   description="Directory from which files will be consumed."

   type="string"

   required="true"

   defaultValue="/var/local/data/outbound"

   encrypt="false"

   mask="false"/>

  </SettingDefinitions>

 <ConstantSettings>

  <ConstantSetting

   name="Fum3 XPath"

   value="/foo/fum[3]"/>

 </ConstantSettings>

</TransportDefinition>

A pluggable transport is described by a TransportDefinition element containing four sub-elements: Class, Usages, SettingsDefinitions and ConstantSettings. Each element is described separately.

TransportDefinition

TransportDefinition is the top-most element of the pluggable transport definition and is similar to:

<TransportDefinition

 name="Custom file system consumer"

 description="Consumes messages from the file system."

 available="true">

The following describes the element attributes.

Name

A friendly name for this type of transport. This name is displayed in the user interface when adding or configuring a transport.

Description

Text to be displayed in the user interface to describe the transport.

Available

Specifies whether the transport is shown in the user interface.

Class

The Class element configures the class name of the PluggableClient implementation. There can be multiple pluggable transports implemented with the same Java class. The Class elements value is the fully qualified Java class name. For example:

<Class>com.examples.transport.PluggableClientExample</Class>

Usages

The Usages element tells B2Bi whether to display the transport in the user interface as a consumer or a producer of files or both. You choose the message protocol to associate with the transport. For example, the following snippet allows the transport to be offered as an inbound or outbound integration option:

<Usages>

<Consume>

<Integration/>

</Consume>

<Produce>

<Integration/>

</Produce>

</Usages>

Pluggable transports are supported only for integration and not for trading protocols such as AS1 and AS2.

SettingsDefinitions

The SettingsDefinitions element describes the configuration parameters to display in the user interface for the pluggable transport exchange point. Each parameter is defined by its own SettingDefinition element. There can be zero or more of these. For example, SettingsDefinitions could be created for parameters such as URL, username, password or a preference offered by the PluggableClient implementation. The following is an example of a parameter for a file system directory. There are several other available attributes described in the XML schema.

<SettingDefinition

name="Directory"

description="Directory from which files will be consumed."

type="string"

required="true"

defaultValue="/var/local/data/outbound"

encrypt="false"

mask="false"/>

The following describes the element attributes.

Name

The parameter name displayed as a field in the user interface when adding or configuring a transport.

Description

Text to be displayed in the user interface to describe the parameter.

Type

The type of data for the parameter. One of {string, number, multiString}

Required

Specifies whether the user interface indicates this is a required field.

defaultValue

Default value displayed in the user interface the first time the field appears.

Encrypt

Specifies whether this setting's value is encrypted when written to the database. This is used for sensitive data such as passwords.

Mask

Specifies whether the user interface masks the value of this setting instead of displaying it. This is used for sensitive data such as passwords.

ConstantSettings

The ConstantSettings element describes parameters with constant values for the PluggableClient. This is an optional list of settings whose values are supplied in the pluggabletransports.xml file. ConstantSettings and their values can display in the user interface, but can only be changed in the XML file.

This element is for describing parameters with unchanging values that a developer does not want to embed in the code. The following is an example of this element for describing an XPath constant:

<ConstantSettings>

 <ConstantSetting

  name="Fum3 XPath"

  value="/foo/fum[3]"/>

 </ConstantSettings>

The following describes the element attributes:

Name

Name of the constant setting.

Value

Value of the constant setting.

Description

Optional description to be displayed in the user interface to help the user understand the use of the constant setting.

Visible

Indicates whether the constant setting should be visible in the user interface.

Pluggable transports in the UI

After a software developer has written the code and a system administrator has deployed it to B2Bi, an application administrator can configure exchange points using the new custom functionality.

The user interface reads the pluggabletransports.xml file each time a user wants to add or modify an exchange point. The name of the pluggable transport displays along with the standard transport options. When a pluggable transport is selected, the user is prompted to complete configuration fields, just as for any transport. Once the configuration is saved, the pluggable transport is ready for use.

Pluggable transport examples

The following provides directions for running pluggable transport examples. For more information about the example classes, see the Swagger API Javadoc.

To open Swagger and consult the Javadoc, open a browser and enter the URL https://<host>:<port>/apidocs/ui.

All examples require editing of the pluggabletransports.xml file in <B2Bi_install_directory>/InterchangeActivator/conf. Inside the TransportDefinitions element, a TransportDefinition element must be added for each transport.

PluggableFileSysClient

For the PluggableFileSysClient example, add the following element to the file:

<TransportDefinition

 name="Custom file system consumer"

 description="Consumes messages from the file system.">

 <Class> examples.transport.PluggableFileSysClient</Class>

 <Usages>

   <Consume>

   <Integration/>

   </Consume>

 </Usages>

 <SettingDefinitions>

   <SettingDefinition

    name="Directory"

    description="Directory from which files will be consumed"

    type="string"

    required="true"

    defaultValue="/var/local/data/outbound"

    encrypt="false"

    mask="false"/>

 </SettingDefinitions>

 <ConstantSettings>

   <ConstantSetting

    name="Fum3 XPath"

    value="/foo/fum[3]"/>

 </ConstantSettings>

</TransportDefinition>

CustomFtpClient

For the CustomFtpClient example, add the following element to the file:

<TransportDefinition

name="Custom Ftp Client"

description="This class acts as an interface between Interchange and the Jakarta commons FTP client."

available="true">

 <Class>examples.transport.CustomFtpClient</Class>

 <Usages>

   <Consume>

   <Integration/>

   </Consume>

 </Usages>

 <SettingDefinitions>

   <SettingDefinition

    name="Directory"

    description="Directory from which files will be consumed"

    type="string"

    required="true"

    defaultValue="/var/local/data/outbound"

    encrypt="false"

    mask="false"/>

 </SettingDefinitions>

 <ConstantSettings>

   <ConstantSetting

    name="Fum3 XPath"

    value="/foo/fum[3]"/>

 </ConstantSettings>

</TransportDefinition>

DBIntegrationClient

For the DBIntegrationClient example, add the following element to the file:

<TransportDefinition

name="Outbound from DB via JDBC"

description="Consumes outbound messages from a database"

available="true">

 <Class>examples.transport.DBIntegrationClient</Class>

 <Usages>

   <Consume>

   <Integration/>

   </Consume>

 </Usages>

 <SettingDefinitions>

   <SettingDefinition

    name="Instance Name"

    description="Describe the instance from which messages will be consumed."

    type="string"

    required="true"

    defaultValue="/var/local/data/outbound"

    encrypt="false"

    mask="false"/>

 </SettingDefinitions>

 <ConstantSettings>

   <ConstantSetting

    name="Sender routing id type"

    value="string"

    description="The type qualifier for the Sender's routing id"/>

   <ConstantSetting

    name="Receiver routing id type"

    value="string"

    description="The type qualifier for the Receiver's routing id"/>

   <ConstantSetting

    name="Service type"

    value="string"

    description="The type qualifier of the Service"/>

 </ConstantSettings>

</TransportDefinition>

Related topics

Related Links