Im trying to invoke specific flow service based on the input.
And this is the logic :
if the partner is A then execute flow service A.
and if the partner is B then execute flow service B.
But I want to avoid using branch if else.
The partner variables will be stored in the database.
There will be a flow service that call it base on the partner name input and will throw the flow service that need to be executed.
Is there any built in flow service that I can use?
Or should I use java service for this?
I have tried to use this java service : (contextInvoke)
"
String host = (String) ValuesEmulator.get(pipeline, “host”);
String user = (String) ValuesEmulator.get(pipeline, “user”);
String pass = (String) ValuesEmulator.get(pipeline, “pass”);
String ifc = (String) ValuesEmulator.get(pipeline, “ifc”);
String svc = (String) ValuesEmulator.get(pipeline, “svc”);
IDataCursor idcPipeline = pipeline.getCursor();
if (host == null || pass == null || ifc == null || svc == null)
throw new ServiceException(“Missing or Invalid Parameters!”);
Context c = null;
try {
c = new Context();
IDataCursor idc = pipeline.getCursor();
//get inputs
String svcName=null;
NSName svcNSName=null;
IData input = IDataFactory.create();
if (idc.first("svcName")) {
svcName=IDataUtil.getString(idc,"svcName");
} else {
throw new ServiceException("Parameter 'svcName' must be provided");
}
if (idc.first("input")) {
input=IDataUtil.getIData(idc,"input");
}
//call isValidService to determine whether service exists in this namespace
if (!(isValidService(svcName))) {
throw new ServiceException("Error: service name " + svcName + " does not exist.");
}
svcNSName = NSName.create(svcName);
try{
IData results=IDataFactory.create();
IData inputClone = IDataUtil.deepClone(input);
results = Service.doInvoke(svcNSName, inputClone);
if (idc.first("results")) idc.delete();
idc.insertAfter("results",results);
} catch (Exception ex) {
throw new ServiceException("The following exception occured while invoking service \"" + svcName + "\" - \n" + ex);
} finally {
idc.destroy();
}
You need to define the following imports in the “Imports” area of the “Shared” tab:
com.wm.app.b2b.server.ServiceThread
com.wm.lang.ns.NSName
com.wm.app.b2b.server.ns.Namespace
This java service also requires an “isValidService” method to be defined in the “Source” area of the “Shared” tab:
public static boolean isValidService(String svcName) throws ServiceException {
//verify that the service exists in the current namespace
try {
//create NSName object from fully qualified service name
NSName svc = NSName.create(svcName);
//create Namespace object for current namespace
Namespace nspace = Namespace.current();
//use nodeExists method to test for existence of specified service name in the current namespace
if (nspace.nodeExists(svc)) {
return true;
} else {
return false;
}
} catch (Exception ex) {
return false;
}
}
I hope you find this useful. It, along with a similar service “doThreadedInvoke”, are part of my standard toolkit and get used on almost every project. My standard custom soap processor design uses “doInvoke” to dynamically invoke the correct processing service after deriving or looking up the name of the service to be invoked to handle a particular soap request.
Code sample is provided “as-is”. No warranties expressed or implied.
Your code is very useful… Many thanks for this.
But, The doinvoke code was working well only for invoking the flow service that has no input and get the return value.
If we want to invoke the flow service that has input grabbed from the pipeline, the return value was not correct.
Actually the service will be placed in the middle of whole process.
Before invoking the doinvoke service there were pipeline value floating in the memory and some of the value will be used as input for some flow service.
If we use the branch if else, it will work fine because it get connected directly, but if we use doinvoke service, seems the pipeline and the input of the flow service that was being invoked by doinvoke was not connected. Hence the return value is not correct.
When you invoke the doInvoke utility service, map the inputs of the service to be invoked as children of the “input” document. Results will be placed into the “results” document. Try it with a simple service like debugLog (which returns nothing except its inputs) or addInts (which returns its input parameters and the “result” variable).
Sorry for confusing, because im newbie in java.
Finally I got it. Now I am able to deliver the input into the invoked service.
Tried with the string already.
But with the document as the input child it should be fine also, right?
Will try after this.
Actually, yes it can. The parameters simply need to exist in the pipeline before calling the Java service. The service called in invoke will have access to the entire pipeline (it’s being passed as a parameter) and the outputs of the service will be in a document named “results.”
thanks for the explanation. Seems I need to explore more for java service since im new to it.
but, for my project, I will use the service that given by Mark.
Hope there is no copyright for this…
Are these external partners? Are you using TN? If not, then take a look at it. One of the things TN provides are Processing Rules, and one of the capabilities of a Processing Rule is that it allows you to execute a service based on the sender and/or receiver of a document.
I guess Processing Rules do somewhat resemble a big and fancy IF-THEN-ELSE statement, but they could be what you’re looking for.
Yes, A and B is the external partners. And we will use TN because this code will be placed under the inbound map of RosettaNet PIPs. Im not sure if it can use the processing rule…
Can you give me a little bit detail please.
thank you.
-Fanny-
If you’re not familiar with TN yet, start with the Trading Networks Concepts Guide and then move on to the User’s Guide. They should have all the information you need.