Middleware Abstraction Layer

To make XTT work with various middlewares, I created an abstraction layer. My primary design requirement has been that users XTT should not need have implicit links to a particular middleware in the code.

This layer does not attempt to provide every bit of functionality, but just enough to get XTT to run.

The basic idea is that the connection information you have in your code specifies three things:
  1. A channel name
  2. A data selector, which usually specifies at least the type of data that you're interested in
  3. The type you'd like the data to be converted to

This information will then be mapped to the specific middleware you're using. In particular, the "channel" is an abstract concept that maps to whatever middleware you're using. In XCF, the channel would be a memory, in RSB it would be a scope, and in ROS it would be a topic.

In most cases, the mapping should be transparent to the user. However, in some cases (currently only when using hierarchical scopes on RSB), additional information may be necessary. Here are the mappings that are currently supported:

Common Name middleware channel selector type
XCF xcf memory name xpath not used, always XML
RSB rsb scope name not currently used class name of the type
ROS ros topic name n/a message type name

Notes

  • XCF: For the selector, it is commonly quite convenient to use just a the root tag name, e.g. "utterance".
  • RSB doesn't require a filter, because the scope name already includes a filter, and the type information is an implicit type filter. Filter expression could be usable, but would need to take into account that different message serializations are not currently inspectable in a common way.
  • ROS does not support selectors out of the box, but support for topic_tools could be useful.

Caveats

At the moment, the type is fairly specific to the middleware, which still creates a coupling. XTT always uses XML data, so that is not as much of a problem, but to be a general middleware abstraction layer, more capable type mappings would be required. We're working on that -- if you're interested in progress information, send Ingo an e-mail.

Source Code

The layer is currently contained in the de.unibi.agai.eb package of XTT. I'm working on factoring it out, stay stuned!

Using the Layer

I will first give a simple example here, and then explain how the defaults can be overriden using property configuration.

Example

Lets say our source is called "xtt_test" and its speech recognizer input as XML with an "speech_hyp" tag at the root.

To get the client bus for this configuration, use

TaskBus clientBus = TaskBusFactory.createClientBus("xtt_test", "spech_hyp", nu.xom.Document.class);

This specifies that the channel is "xtt_test", the type on the bus is called "isr", and you'd like to receive the input as an instance of class "nu.xom.Document".

Use with XCF

For XCF, no further configuration is required, but you can override some values, if so desired.

By default, the above statement would create a memory-connection to memory "xtt_test", and set up a filter expression called "/speech_hyp". Because XCF always uses XML with nu.xom.Document, it is passed through.

Example for RSB

For RSB, we need a bit more information, because it supports different types and uses hierarchical scopes. You'd do it like this:

-Deb.rsb.isr.channel=/isr/hyp -Deb.rsb.isr.type=String

Note that in RSB, selectors are not currently supported, and you have to specify a type (XCF's default and only type is XML, so you need not give it). It still works, because the isr only published hypotheses on that scope.

Configuration in general

The layer is configured using environment variables. The names are built as follows:
eb.<middleware>.<name>.<variable>. For example, eb.xcf.speech.type would be the variable to configure the message type for port "speech", and using the "xcf" middleware.

The layer will search all configured middlewares, so you can easily provide duplicate configurations (e.g. for both XCF and RSB), and the layer will pick the one that is available. If both middleware implementations are available, both will be tried, and the first one that works is chosen. This can result in unpredictable behavior, so there is also a variable called "eb.middleware_order", with comma-separated values. E.g. -Deb.middleware_order=rsb,xcf can be used to prefer rsb over xcf.