IncludeURL in JavaScript policy of shared flow referencing JavaScript file at the proxy level

Not applicable

We have a requirement where there is a shared flow containing a JavaScript policy that references different files using the IncludeURL .We want one of the files referenced in the IncludeURL to be dynamically picked up at the proxy level as it will be different for every proxy.The code processing these files will be common hence we want to place this in the shared flow.Is there any way to achieve this?

Solved Solved
0 5 1,735
1 ACCEPTED SOLUTION

Hmmmmmmmmmmmmmm

I don't know, I've never tried it. But I think it will not work.

I understand that you have a sharedflow... and it includes a JS policy. And you want that JS policy within the sharedflow to reference a JavaScript module that is attached to the proxy.

Here's the problem: you need to deploy the sharedflow (with its JS policy) independently of deploying any of the proxies. That deployment of the sharedflow needs to resolve all the JS source modules, at the time it occurs. That means the sharedflow cannot reference the JS source in your API proxies.

There's a better solution.

Rather than designing the JS policy to rely on an externally-provided JavaScript module.... you could design the JS policy to depend on DATA provided by the API Proxy. The data might be retrieved from the KVM map, indexed by API Proxy. Or, the data might be provided in context variables set/hardcoded by a previously executed JS policy or AssignMessage. The logic within the shared JS module can examine the inbound data and execute logic conditionally.


As a fallback, I generally don't like the idea of eval() , but you could rely on that, if you choose. Pass in the JS code as text, and then eval() it within in your SharedFlow-scoped JavaScript module, to get the function you want.

The JS within the sharedflow might look like this:

context.setVariable('SF-EvalJS', true);
var source = context.getVariable("js-source");
var compiledFn = eval( source );
var input = compiledFn();
// now do something with that...

To provide source to the SharedFlow, you would need to set a "well known variable" with inputs. Maybe like this:

<AssignMessage name='AM-1'>
  <DisplayName>AM-1</DisplayName>
  <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
  <AssignVariable>
    <Name>js-source</Name>
    <Value>
function(){
  return context.getVariable("system.time");
}
    </Value>
  </AssignVariable>
</AssignMessage>

You must take care that the value of the "js-source" is valid JavaScript.

View solution in original post

5 REPLIES 5

Hmmmmmmmmmmmmmm

I don't know, I've never tried it. But I think it will not work.

I understand that you have a sharedflow... and it includes a JS policy. And you want that JS policy within the sharedflow to reference a JavaScript module that is attached to the proxy.

Here's the problem: you need to deploy the sharedflow (with its JS policy) independently of deploying any of the proxies. That deployment of the sharedflow needs to resolve all the JS source modules, at the time it occurs. That means the sharedflow cannot reference the JS source in your API proxies.

There's a better solution.

Rather than designing the JS policy to rely on an externally-provided JavaScript module.... you could design the JS policy to depend on DATA provided by the API Proxy. The data might be retrieved from the KVM map, indexed by API Proxy. Or, the data might be provided in context variables set/hardcoded by a previously executed JS policy or AssignMessage. The logic within the shared JS module can examine the inbound data and execute logic conditionally.


As a fallback, I generally don't like the idea of eval() , but you could rely on that, if you choose. Pass in the JS code as text, and then eval() it within in your SharedFlow-scoped JavaScript module, to get the function you want.

The JS within the sharedflow might look like this:

context.setVariable('SF-EvalJS', true);
var source = context.getVariable("js-source");
var compiledFn = eval( source );
var input = compiledFn();
// now do something with that...

To provide source to the SharedFlow, you would need to set a "well known variable" with inputs. Maybe like this:

<AssignMessage name='AM-1'>
  <DisplayName>AM-1</DisplayName>
  <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
  <AssignVariable>
    <Name>js-source</Name>
    <Value>
function(){
  return context.getVariable("system.time");
}
    </Value>
  </AssignVariable>
</AssignMessage>

You must take care that the value of the "js-source" is valid JavaScript.

Thank you for the reply Dino.I tried creating a context variable called oas1 to pass data to the JS policy in the shared flow and then tried to use the data in the shared flow but it doesn't seem to be working for some reason.I have attached the proxy and shared flow here.oas-validation1-rev2-2018-08-14.zipadd-3-rev7-2018-08-14.zip

I suggest that you store the OpenAPI Spec as a string.

var oas = {
  "swagger": "2.0",
  "info": {

  },
  "consumes": [
    "application/json"
  ],
  "produces": [
    "application/json"
  ],
  "paths": {
...
};

context.setVariable("oas1", JSON.stringify(oas));

...and then do the converse (JSON.parse) in the JS within the SharedFlow.

Another interesting possibility is to expose a Microservice (maybe another API Proxy) that returns the spec for a given API Proxy.

Then within the sharedflow, you could do a ServiceCallout to that service, make that result available in a context variable (maybe oasResponse.content) and then reference that variable within the validation logic in the SharedFlow.

Thanks @Dino-at-Google .I saved the spec as a string and used JSON.parse in the shared flow but still no luck!oas-validation1-rev2-2018-08-14-1.zipadd-3-rev8-2018-08-14.zip

I have used this way on my shared flow, then I have seen this post later on, the only thing Dino is that we would like to avoid each developer to add JS policy each time in the proxy flow, thats why referencing it from SF is pretty usefull and transparent for developer