How to get name of current service

I would like to get the name of the currently running service into the pipeline without using a literal, so it can be copied, renamed etc. and continue to operate correctly.
Does anyone know how to do this?
Even better still can a called service get the name of its caller, or the ultimate parent?

Hi,

Use the callStack available from the Java API eg:

// required imports 
// java.util.Stack 
// com.wm.app.b2b.server.InvokeState 
// com.wm.app.b2b.server.ServerAPI 
// com.wm.lang.ns.NSService 
 
String serviceName = null; 
Stack callStack = InvokeState.getCurrentState().getCallStack();  
int size = callStack.size();  
 
if (size >= 2) {  
 NSService myService = (NSService) callStack.elementAt (size - 2);  
 serviceName = myService.getNSName().getFullName();  
}  
 
// pipeline out 
IDataCursor pipelineCursor = pipeline.getCursor(); 
IDataUtil.put(pipelineCursor, "serviceName", serviceName); 
pipelineCursor.destroy(); 

Absolutely splendid. Just goes to show how much I still don’t know (which already takes my breath away!)
Thanks heaps.
Russ.

You can also import com.wm.app.b2b.server.Service and use

Service.getCallingService() to gain the handle on the NSService .

Um… sorry, I should have checked first.

The method you want is actually Service.getServiceEntry() ;

Nick

Hi, Russ.

Danie and Nick_F areright, you should use the webMethods API to get this done. You can access the API directy from the Developer tool menu using “Help > webMethods API”.

Specifically, look at the ServiceAPI class. Two helpful services are:

getCallingService() – a member of the com.wm.app.b2b.server.Service class. Returns the service that invoked the service from which getCallingService is being executed.

getPackageName() – a member of the com.wm.app.b2b.server.Service class. Returns the name of the current package directory.

Thank you all for your help. You have done well so far - now for the final test.
My service runs as a job from the scheduler. It runs once, and reschedules itself to run in the future. As it stands, I am using Danie’s solution to find the name of the scheduled service as the first step. A deeply nested service decides to reschedule, and hopes to find the service name intact in the pipeline.

A neater solution might be to ask ‘what is the name of the outermost service.’
Now clearly it will be in the call stack somewhere, (possibly even the first thing). Are there any other solutions?

Russ.

Hi,
I’ve tried to get this running. If you just execute a flow that calls this functions, everything is working fine and I’m getting the right servicename. But if you run the parent flow in a debug mode (step) in the Developer you get “wm.server.flow:stepFlow” instead of the parent flow name. Did everybody solved that?

Michael

Hi all,

I don’t know if something’s changed in wm since this posting, but it now appears that the “calling service” is actually 3 steps back in the stack.

I’ve extended DFMALAN’s code from above, as follows. This provides full details about the service (as per the PSUtilities getService), as well as a flag indicating if a parent caller was found.

// getCallingService

// Leverages code taken from forum post by Daniel F. Malan
// at http://wmusers.com/forum/showthread.php?t=4558

// If service A calls service B, then service B calls this service, this service will return
// the details of service A (and serviceFound will be “true”).

// If Service B is the top-level service (ie service A does not exist), then no
// details will be returned (and serviceFound will be “false”).

// NB the CommonUtilities version of this service utilises the API function Service.getCallingService()
// which appears to actually provide details about service B, not service A.
// ie that service is actually only useful to provide a service with details about itself,
// not about its caller.

// required imports
// java.util.Stack
// com.wm.app.b2b.server.InvokeState
// com.wm.app.b2b.server.ServerAPI
// com.wm.lang.ns.NSService
NSService callingService = null;
String serviceFound = “true”;
String callingServiceName = “”;
Stack callStack = InvokeState.getCurrentState().getCallStack();
int size = callStack.size();
if (size >= 3)
{
callingService = (NSService) callStack.elementAt (size - 3);
callingServiceName = callingService.getNSName().getFullName();
}
else
{
serviceFound = “false”;
}
// pipeline out
IDataCursor pipelineCursor = pipeline.getCursor();
IDataUtil.put( pipelineCursor, “ServiceFound”, serviceFound);
IDataUtil.put( pipelineCursor, “CallingServiceName”, callingServiceName);
IDataUtil.put( pipelineCursor, “CallingService”, callingService);
pipelineCursor.destroy();

Sepster,

What version are you on - 6.1 or 6.5? On 6.1 I am still able to get the name of any service in the following manner:

  • I have created a Java service that return service name as follows:

    [list]
  • serviceName = Service.getCallingService().toString();
    [/list]
  • Call this Java service from which ever service you want the name of and you will get the right name.

HTH, Rohit

Hi Rohit,

I’m using 6.5sp2.

Yes, you’re right - the getCallingService method does return the name of the service that called it.

What I wanted to do was this…
Service A calls service B.
Service B calls some “magic” service C, in order to determine the name of service A.

The “magic” service you’ve suggested provides the details of Service B, not A.

By going further up the call stack (3 levels) we get Service A.

ie by me calling getCallingService, I want to know “who called me?”, not “who called the service I’m calling?”.

The reason I’m trying to do this is as follows:

I have a “CommonExceptionHandler” package. This package is available for use in handling exceptions in a consistent way across all my other custom packages. eg write a pipeline dump, email a system administrator, write an event to a database log, etc.

However, for each custom package, I have some configurable options about how an exception should be handled - eg where to write a dump of the pipeline to, who should be alerted via email, logging levels, etc.

I want to store these settings with the particular package to which they’re relevant, not in the CommonExceptionHandler. This means when a package is exported, all its settings go with it.

So, when my CommonExceptionHandler is called, it needs to know who called it, in order to pick up the settings relevant to the caller.

I realise I could just pass the name of the package/service in to the common event handler… but that just seems absolutely povvo to me! It’s more junk in the pipeline than necessary I think.

Ah I see! You’re right… with the getCallingService approach, you are gonna have to invoke the “magic” service in each service that may call CommonExceptionHandler, get its name and then pass it to CommonExceptionHandler in the invoke. Though this will still work but it is not clean.

Your approach makes it much simpler by having a “better-magic” service that returns “who called my caller”, thus needs to be invoked centrally - only in CommonExceptionHandler.

Thanks for sharing.
Rohit

Hi Russ/All,

I am exactly looking for what Russ has asked. I need to get the list of scheduler service properties from that calling service. Please help.

Regards,
Satish