Invoke service with service name in the input

Hi all,

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();

c.connect(host, user, pass);
ValuesEmulator.put(pipeline, “result”, c.invoke(ifc, svc, pipeline));
c.disconnect();
} catch (Exception e) {
if (c != null) {
try {
c.disconnect();
} catch (Exception ee) {
// ignore this…
}
}
// throw new ServiceException("Error during invoke: " + e.getMessage());
IDataUtil.put( idcPipeline, “Exception”, "Error during invoke: " + e.getMessage());
}

"
But the problem using it is cannot invoke flow service that contain input and output (return value).

Need somebody expert on this matter.

Thank you.

Try this…

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.

Mark

Hi Mark,

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.

Perhaps do you have any further advise?

Thank you very much.
Fanny

Pretty sure I don’t understand your question.

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).

Mark

Hi Mark,

Sorry for confusing, because im newbie in java. :slight_smile:
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.

Thank you very much Mark. :slight_smile:

with the document as the input child also working fine.

thank you very much Mark. :slight_smile:

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.”

The key line in the Java code is this:

ValuesEmulator.put(pipeline, “result”, c.invoke(ifc, svc, pipeline));

The input/output mapping technique Mark describes, which is a good design time aid, can also be used for the service you posted.

The bottom line is that both Java services posted will work, though Mark’s is more robust.

Hi rob,

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… :slight_smile:

btw, is there any java documentation that I can read so I could understand the java command that being used by webMethods?

thanks in advanced.

Yes. In Developer, select Help | Java API Reference from the menu.

Hi Rob, yes, got it.
Just need some times to read it. Thank you…:slight_smile:

Hi -

Going back to the original post where you stated:

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.

  • Percio

Hi Percio,

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.

  • Percio