From a shared flow, how can one find out where it was invoked from?

For example, I have a common js code that when invoked directly from within a proxy uses context.flow to find out in which part of the proxy it is being invoked from.

When I move this policy/js code into a shared flow, the context.flow variable always returns "SHARED_FLOW".

I need to know whether the code is being invoked from the request or response flow as well as whether it is in the proxy or target side, or in error handling.

Basically, I need to get the same values as context.flow returns when invoked directly from within the proxy and not in a shared flow, or an alternative to that.

Solved Solved
5 11 1,389
1 ACCEPTED SOLUTION

As of Public Cloud release 19.03.01 a bug was fixed that allows a JavaScript policy used in a shared flow to identify the flow state, the key is the "currentstep.flowstate" variable. For example, given a shared flow (e.g. to set logging values) placed on each of the Flow Hook locations, the flow state can be accessed using:

var flow = String(context.getVariable("currentstep.flowstate"));
print( "Flow value is " + flow);

// Flow hook locations
switch (flow) {
    case "PROXY_REQ_FLOW":
        print( "PROXY_REQ_FLOW");
        break;

    case 'TARGET_REQ_FLOW':
        print( "TARGET_REQ_FLOW");
        break;

    case 'TARGET_RESP_FLOW':
        print( "TARGET_RESP_FLOW");
        break;
        
    case 'PROXY_RESP_FLOW':
        print( "PROXY_RESP_FLOW");
        break;
        
    case 'ERROR':
        print( "ERROR");
	var error_state = context.getVariable("error.state");
        print( "ERROR error.state: " + error_state);
	// error.state will be PROXY_REQ_FLOW, etc.
        break;

    default:
        print( "Uncaught currentstep.flowstate is " + flow);
        break;
}

View solution in original post

11 REPLIES 11

Interesting question, Ricardo! It's a little disappointing that you cannot tell from reading "context.flow" .

I am trying to do the same, have you come up with a solution?

I think it's a bug! ref: b/66214414

And there's no workaround that I know of.

Have you tried "current.flow.name"?

Here's a work around that I came up with, use the combination of the variables "route.name", "response", and "current.flow.name". For example:

var routeName = context.getVariable('route.name');
var response = context.getVariable( 'response');
var flowName = context.getVariable('current.flow.name');

var proxytarget = routeName === null ? 'PROXY' : 'TARGET';
var reqresp = response === null ? 'REQ' : 'RESP';
var prepost = flowName === 'PreFlow' ? 'PRE' : 
             (flowName === 'PostFlow' ? 'POST' : 'COND');

flow = proxytarget + '_' + reqresp + '_' + prepost + '_FLOW';

print( 'FLOW: ' + flow);

Values will be like: TARGET_RESP_POST_FLOW

Great tip! But I think the 'current.flow.name' can be either:

  • PreFlow (if the customer follows the convention to use "PreFlow" on the PreFlow element)
  • PostFlow (ditto)
  • or the custom name of a conditional flow., in either the proxy or target endpoint.

Therefore your logic around 'prepost' is not quite right.

You're right, thanks for the catch, I've corrected the logic.

Actually, the flow part is just extra, the context.flow is either PROXY_REQ_FLOW, TARGET_REQ_FLOW, TARGET_RESP_FLOW, or PROXY_RESP_FLOW.

The logic around "PreFlow" and "PostFlow" assumes those values are used for the name attribute on the respective elements.

@Kurt Kanaskie
I guess the above code will never print PROXY_RESP_FLOW as once the execution reaches target endpoint, the value for context.getVariable('route.name') will always be the routerule which evaluated to true.

Hi,

If I use the sf for error handling then can use error.state as my goto variable.

<Condition>(((error.state =="TARGET_REQ_FLOW") or (error.state =="TARGET_RESP_FLOW")) or ((error.state =="REQ_SENT") or (error.state=="RESP_START")))</Condition>

As of Public Cloud release 19.03.01 a bug was fixed that allows a JavaScript policy used in a shared flow to identify the flow state, the key is the "currentstep.flowstate" variable. For example, given a shared flow (e.g. to set logging values) placed on each of the Flow Hook locations, the flow state can be accessed using:

var flow = String(context.getVariable("currentstep.flowstate"));
print( "Flow value is " + flow);

// Flow hook locations
switch (flow) {
    case "PROXY_REQ_FLOW":
        print( "PROXY_REQ_FLOW");
        break;

    case 'TARGET_REQ_FLOW':
        print( "TARGET_REQ_FLOW");
        break;

    case 'TARGET_RESP_FLOW':
        print( "TARGET_RESP_FLOW");
        break;
        
    case 'PROXY_RESP_FLOW':
        print( "PROXY_RESP_FLOW");
        break;
        
    case 'ERROR':
        print( "ERROR");
	var error_state = context.getVariable("error.state");
        print( "ERROR error.state: " + error_state);
	// error.state will be PROXY_REQ_FLOW, etc.
        break;

    default:
        print( "Uncaught currentstep.flowstate is " + flow);
        break;
}

If you're using a nested FC, as you would to build a ProxyResponse SF or flow hook, you'll need to pass that variable as a parameter and set the variable, for example.

<FlowCallout async="false" continueOnError="false" enabled="true" name="FC-GetLogValues">
    <DisplayName>FC-GetLogValues</DisplayName>
    <Parameters>
        <!-- In a nested FC, need to set currentstep.flowstate, its SHARED_FLOW otherwise -->
        <Parameter name="currentstep.flowstate">{currentstep.flowstate}</Parameter>
    </Parameters>
    <SharedFlowBundle>GetLogValues</SharedFlowBundle>
</FlowCallout>

Couple notes on uses in a FlowHook:

  1. The value in the ProxyResponseFlowHook is "RESP_SENT", so you will need to detect that, I just check at the beginning of my JS and set the variable to "PROXY_RESP_FLOW".
  2. When the target sends an error response, in the TargetResponseFlowHook, the value is still "TARGET_RESP_FLOW" since the proxy did not start processing the response yet. In that case you can use "isError" in your JS to detect an error, I just check at the beginning and set the variable to "ERROR".

6 years passed and it is still an amazing approach. Thanx