Note that variable substitution may not work as expected in the AssignMessage policy. You will need to set the full URL as a variable first, and then reference the variable in the section. Better to use Javascript policy
Any update for Set Path.Kindly let me know if the issue has been fixed.
The bug with Set Path has not been prioritized since there’s a workaround in place. I just bumped up the priority for the bug: https://apigeesc.atlassian.net/browse/APIRT-1894
Late reply, but hopefully you can help. Where would you get the base URL from? target.url isn’t set during the target preflow as far as I can see.
Guys! There has been a year and this issue is still open. Do something with it!
Remember, Javascript has a performance penalty compared to policies. Doing this completely in policies would be best unless the path is too complex or dynamic.
This is a consolidated answer that takes the current findings into account. The current findings are that:
- Using the element along with the target.copy.pathsuffix set to false doesn’t work. That’s what the current open bug will address if and when it’s fixed. We’ll update the Assign Message docs to reflect this current outage.
- Resetting the target.url variable IN THE TARGET ENDPOINT is ultimately the way to rewrite the target URL. You can do this either with the Assign Message policy or the JavaScript policy. JavaScript introduces a performance hit (as mentioned in this thread), but it lets you perform more elaborate, dynamic URL rewriting if that’s what you need.
Rewriting the target.url in the TargetEndpoint is pretty simple and has already been covered in this thread. But what if you need to figure out back in the ProxyEndpoint, when the request first comes into the proxy, that the target.url needs to be rewritten with a certain value? You can’t rewrite the target.url yet, because the flow hasn’t reached the TargetEndpoint.
The attached API proxy shows you how.
To test it, add one of the following query parameters to the proxy URL:
?lebowski=true or ?lebowski=false
The functionality is similar in concept to doing conditional routing to different Target Endpoints. The attached proxy has comments in the XML, but here’s the logic in a nutshell:
- The ProxyEndpoint has a conditional flow that checks the request for the value of the ‘lebowski’ query parameter.
- If the query parameter is ‘true’, a ‘lebowski’ variable gets populated with a hard-coded URL using an Assign Message policy.
- Now the TargetEndpoint has a conditional flow that checks whether or not the ‘lebowski’ variable has a value. If it does, it replaces the target.url with that value. If the ‘lebowski’ variable is null, the default TargetEndoint URL is used.
Here’s a snapshot of the Assign Message policies:
ProxyEndpoint
Conditionally execute the following if (request.queryparam.lebowski = “true”). This sets the URL to use for overriding the target.url later, stored in a variable called ‘lebowski’.)
<AssignMessage async="false" continueOnError="false" enabled="true" name="Assign-Message-1">
...
<AssignVariable>
<Name>lebowski</Name>
<Value>http://mocktarget.apigee.net/user?user=Dude</Value>
</AssignVariable>
TargetEndpoint (where target.url needs to be overridden)
Conditionally execute the following policy if (lebowski != null). That is, if the ‘lebowski’ variable has a URL in it, use it to override the target.url.
<AssignMessage async="false" continueOnError="false" enabled="true" name="Assign-Message-2">
...
<AssignVariable>
<Name>target.url</Name>
<Ref>lebowski</Ref> <!-- References the variable created earlier. -->
</AssignVariable>
Note that you could also handle the conditional logic (reading request.queryparam.lebowski) in the TargetEndpoint only. So this is just a more extreme example if you ever do need to set the URL in the ProxyEndpoint.
Hope this helps.
The @Floyd abides!
The AssignVariable/Value element does not accept a Message Template. This means you cannot use a string like {myhost}/foo/bar.php?{request.querystring} and expect it to resolve those things within curly braces as variables.
Update: it is now possible to use a template in AssignVariable. Use …
Instead what happens is: your variable gets the value {myhost}/foo/bar.php?{request.querystring} .
I just tested this with this policy:
<AssignMessage name="AM-1">
<AssignVariable>
<Name>foo.bar</Name>
<!-- will not work>
<Value>{system.timestamp}/foo/bar.php?{proxy.name}</Value>
</AssignVariable>
<AssignVariable>
<Name>foo.do-templates-work</Name>
<Value>We-shall-see</Value>
</AssignVariable>
</AssignMessage>
And when I ran a request, I got this result:
…which shows me that the Value element inside AssignVariable does not interpret curly braces as variable references.
There is a ticket asking for this behavior, APIRT-1180. The capability is not yet available in the product.
Update: Example of using a template in assignvariable:
<AssignMessage name="AM-1">
<AssignVariable>
<Name>foo.bar</Name>
<Template>{system.timestamp}/foo/bar.php?{proxy.name}</Template>
</AssignVariable>
</AssignMessage>
@arghya das unfortunately there is no workaround available when you use a ‘Target Server’ configuration for HTTPTargetConnection. This is a blocker for such use cases.
Target URL is not enough. In my case, I need point to target connection
<HTTPTargetConnection>
<LoadBalancer>
<Server name="httpbin-test-ue1"/>
<Server name="httpbin-test-uw2">
<IsFallback>true</IsFallback>
</Server>
</LoadBalancer>
<Path>/</Path>
</HTTPTargetConnection>
If I can set HTTPTargetConnection in javascript, it is great
If HTTPTargetConnection => LoadBalancer => Server can be variable. It will be great.
However, seems impossible.
Any update on this? It’s been 8 years.
We’re using a LoadBalancer and can’t just hardcode the path variable.
I can’t extract the original target.url and adjust it because the variable is not defined during target preflow. No workaround works.
Ultimately ended up doing this to fix it:
Attach this JS policy to target endpoint pre-flow with a condition to only trigger on the path we want it on:
context.setVariable('target.copy.pathsuffix', false);
context.setVariable('dynamicSuffix', '/desired_suffix');
Set up the load balancer like this:
<HTTPTargetConnection>
<LoadBalancer>
<Server name="our_server"/>
</LoadBalancer>
<Path>/v1/{dynamicSuffix}</Path>
</HTTPTargetConnection>
Finally apply this AssignMessage policy to target pre-flow one step before our JS policy, this time with no condition. Without this, the requests to paths we aren’t transforming will fail as dynamicSuffix will be unresolved.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage continueOnError="false" enabled="true" name="AM-SetEmptyDynamicSuffix">
<DisplayName>AM-SetEmptyDynamicSuffix</DisplayName>
<Properties/>
<AssignVariable>
<Name>dynamicSuffix</Name>
<Value/>
</AssignVariable>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>
Way more complicated than it should be, but at least it works for my use case. Maybe someone will find this helpful.
