TIP Dynamically calling services from within B2B flows

PROBLEM:
How to minimize the use of switches (BRANCH statements) within a flow while still allowing each customer to have its own mapping sequence easily located by the B2B Server.

SCENARIO:
A wm.db:query service polls a database for records satisfying certain criteria. If a record is found, it is processed as an outbound document to a customer. The customer is not known at the time of the query. After several generic steps (mapping the results to a record, logging the record to file, and some preliminary mapping), a node is queried to identify the target customer and, hence, the appropriate mapping sequence.

SOLUTION:

  1. Create a remote server with the name “localhost” whose parameters match your B2B Server.
  2. Do a remote invoke to call your mapping sequence. The $alias is “localhost” and the service is the generic namespace of your customer mapping flows. For example, my generic service is “Customers.%customerID%:mapFromXMLto%customerID%XML”.

The need to branch is eliminated and new customers can be added without bothering with adding additional switches to BRANCH statements.

When adding new customers, the mapping flows must reside in the generic path specified by your service call (e.g. “Customers.%customerID%:mapFromXMLto%customerID%XML”).

SOLUTION 2:

  1. Invoke the WmRoot service wm.server.xidl.adminui:testService. This service accepts the parameters “service” and “interface” and is the same service used by the Adminstration GUI to test services.

SOLUTION 1 is preferred because it allows the developer to maintain complete control of the pipeline.

SOLUTION 3:
Create a simple Java service that accepts (in this case) the customerID as an input string. Then the service would generate the folder (aka interface) and service names, and call Service.doInvoke().

This would be slightly more efficient than SOLUTION 1, because it avoid having to HTTP to localhost. Also, since it doesn’t require a remote server alias Administrator acces to the server is not needed.

Great solution. I implemented it with no problem and have pasted the code below for the rest of the user community.

Thanks for your help!

[begin code]
// This service calls a customer’s outbound mapping service by using the customer’s name to build the namespace of the flow.

// IMPORTS
// com.wm.app.b2b.server.Service
// INPUTS
// customerName – the name of the customer
// OUTPUTS
// errorMessage – used only when the service fails, the exception message is written to this string

// pipeline
IDataHashCursor pipelineCursor = pipeline.getHashCursor();
pipelineCursor.first( “customerName” );
String customerName = (String) pipelineCursor.getValue();

// Set the interface namespace
String intf = customerName;

// Build the flow namespace
String srv = “manage” + customerName + “OutboundMap”;

try {
Service.doInvoke(intf, srv, pipeline);
}
catch (Exception e) {
String err = e.getMessage();
IDataHashCursor pipelineCursor2 = pipeline.getHashCursor();
pipelineCursor2.last();
pipelineCursor2.insertAfter( “errorMessage”, err );
pipelineCursor2.destroy();
}
[end code]

No prob. Bear in mind that the IDataHashCursor (along with the IDataIndexCursor) was deprecated with version 4.0. All of their methods were subsumed by the IDataCursor. The Integrator still generates code for IDataHashCursor, so you’ll need to add the “-d” flag (compile deprecated code without warnings) to the watt.server.compile parameter in the Extended Server Settings.

watt.server.compile=javac -classpath {0} -d {1} {2}

Cheers.