Hi Team,
I have requirement to read multiple API proxies names and that includes request path with comma (“,”) separated from keyvaule maps as metioned below
KVM name is SF-KVM and the key name is globalvar that contains a value
apiproxyname1,apiproxyname12,apiproxyname3,apiproxyname4,/apiproxyname1/sample/json2xml
I have used a KVM policy to retrieve value and written a java script policy to construct the conditional string to execute one of the policy based on condition in a shared flow default flow.
var kvalue=context.getVariable("kvm-val");
var conditionStr="";
var arr="";
if(kvalue.indexOf(',') > -1) {
arr = kvalue.split(',');
for(i=0; i<=arr.length-1; i++) {
if(arr[i].indexOf('/') > -1 && arr[i].indexOf('/') === 0) {
conditionStr+="or" + " (request.path = " + arr[i].toString() + ") "
} else {
conditionStr+="or" + " (apiproxy.name = " + arr[i].toString() + ") "
}
}
} else {
if(kvalue.indexOf('/') > -1 && kvalue.indexOf('/') === 0) {
conditionStr+="or" + " (request.path = " + kvalue.toString() + ") "
} else {
conditionStr+="or" + " (apiproxy.name = " + kvalue.toString() + ")"
}
}
}
context.setVariable("condStr",conditionStr);
print(conditionStr)
I am successfully able to construct the conditional string dynamically as mentioned below and is this possible to use dynamically constructed conditional string in an shared flow default
condStr= (apiproxy.name = apiproxyname1) or (apiproxy.name =apiproxyname2) or (apiproxy.name = apiproxyname3) or (apiproxy.name = apiproxyname4) or (request.path /apiproxyname1/sample/json2xml)
sharedflow default xml file content as mentioned below
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<SharedFlow name="default">
<Step>
<Name>kvm-policy</Name>
</Step>
<Step>
<Name>KVM-javascript</Name>
</Step>
<Step>
<Name>RaiseFault</Name>
<Condition>condStr</Condition> this is step is not at all working
</Step>
</SharedFlow>
I have requirement to apply this shared flow on environment level using a flow-hook
I appreciate any help regarding this.
Regards
Nandeesha
Solved! Go to Solution.
It is not possible to have a dynamic condition in Apigee DSL. You cannot do this:
<Step>
<Name>RaiseFault-1</Name>
<Condition>variable-here</Condition> <!-- will not work -->
</Step>
Also, there is no ref= attribute on a Condition. You also cannot do this :
<Step>
<Name>RaiseFault-1</Name>
<Condition ref='variable-here'/> <!-- will not work -->
</Step>
The condition expression needs to be static, and must follow the syntax outlined in the Condition reference.
If you want to have a "dynamic condition" then a good way to do it is to use the JavaScript policy, not to construct the string, but to evaluate the value and set a flag. For example
var kvalue = context.getVariable("kvm-val");
var result = false;
var requestPath = context.getVariable("request.path");
var proxyName = context.getVariable("apiproxy.name");
// split() will work whether there is a comma or not
kvalue.split(',')
.forEach(function(item) {
if ( ! result) {
if (item.indexOf('/') === 0) {
result = result || (requestPath === item);
}
else {
result = result || (proxyName === item);
}
}
});
context.setVariable('kvm_rules_matched', String(result)); // "true" or "false"
Then use it in a Condition:
<Condition>kvm_rules_matched = "true"</Condition>
If you want to use more functional idioms in your JS you can do this:
var kvalue = context.getVariable("kvm-val");
var requestPath = context.getVariable("request.path");
var proxyName = context.getVariable("apiproxy.name");
var result =
kvalue
.split(',')
.find(function(item) {
return ((item.indexOf('/') === 0) && (requestPath === item)) ||
((item.indexOf('/') === -1) && (proxyName === item));
});
context.setVariable('kvm_rules_matched', String(!!result)); // "true" or "false"
That feels more readable to me, but YMMV.
It is not possible to have a dynamic condition in Apigee DSL. You cannot do this:
<Step>
<Name>RaiseFault-1</Name>
<Condition>variable-here</Condition> <!-- will not work -->
</Step>
Also, there is no ref= attribute on a Condition. You also cannot do this :
<Step>
<Name>RaiseFault-1</Name>
<Condition ref='variable-here'/> <!-- will not work -->
</Step>
The condition expression needs to be static, and must follow the syntax outlined in the Condition reference.
If you want to have a "dynamic condition" then a good way to do it is to use the JavaScript policy, not to construct the string, but to evaluate the value and set a flag. For example
var kvalue = context.getVariable("kvm-val");
var result = false;
var requestPath = context.getVariable("request.path");
var proxyName = context.getVariable("apiproxy.name");
// split() will work whether there is a comma or not
kvalue.split(',')
.forEach(function(item) {
if ( ! result) {
if (item.indexOf('/') === 0) {
result = result || (requestPath === item);
}
else {
result = result || (proxyName === item);
}
}
});
context.setVariable('kvm_rules_matched', String(result)); // "true" or "false"
Then use it in a Condition:
<Condition>kvm_rules_matched = "true"</Condition>
If you want to use more functional idioms in your JS you can do this:
var kvalue = context.getVariable("kvm-val");
var requestPath = context.getVariable("request.path");
var proxyName = context.getVariable("apiproxy.name");
var result =
kvalue
.split(',')
.find(function(item) {
return ((item.indexOf('/') === 0) && (requestPath === item)) ||
((item.indexOf('/') === -1) && (proxyName === item));
});
context.setVariable('kvm_rules_matched', String(!!result)); // "true" or "false"
That feels more readable to me, but YMMV.