Do we have Global Policy having Route Rule appplicable to all API Proxies ?

Hi

I have a Use Case where when client send a request to API Proxy Endpoint , it specifies one request query param (eg. target=t1) , then we need to direct that request to Target Endpoint URL(eg. http://{target.host}:{target.port}/rest/v1/Person) configured , which will be dynamically replaced by http://t1:8080/rest/v1/Person.

This should be done not at every API Proxy level where we can specify route rule, but should be done as a Global Route rule and we can have multiple target servers like t1, t2, t3 and there should be a way to configure create/update these Global Rules at run time.

Please let me know how I can achieve this in best and easiest way possible.

Thanks

0 14 732
14 REPLIES 14

adas
Participant V

@GAURAV

For your requirement, you don't need a global route rule. If I understood your usecase correctly, you are saying that the client request would havea query param like target=t1 and at runtime the target url for your proxy should be replaced with t1, t2, t3 etc.

For instance,

t1=api.mydomain.com

t2=api.yourdomain.com

t3=api.example.com

In this case, you can have a simple javascript policy, which can use a global javascript resource file. The javascript can be something like this:

var target = context.getVariable("request.queryparam.target");

var targetUrl = "http://" + target + ":8080/v1/example/resource"

context.setVariable("target.url", targetUrl);

Attached are the policy(rename .txt to .js before upload) and proxy bundle. Please let me know, if this works for you.

To import the js file as a org level resource use the following management API call:

curl -X POST -H "Content-type:multipart/form-data" -F file=@targetsetter.js \
https://api.enterprise.apigee.com/v1/organizations/myorg/resourcefiles

resourcefiles?"name=targetsetter&type=jsc" -u email:password

targetsetter.txttarget-switch-rev2-2015-12-28.zip

Thanks @arghya das

My usecase is slightly differrent where my target url is not actually set in javascript policy as you mentioned:

var target = context.getVariable("request.queryparam.target");

var targetUrl = "http://" + target + ":8080/v1/example/resource"

context.setVariable("target.url", targetUrl);

We will have something like this in TargetEndPoint URL

<HTTPTargetConnection> <Properties/> <URL>http://{target.url}/wfc/restcall/legacy_api/v1/Person/</URL> </HTTPTargetConnection>

and we need to replace above {target.url} from the global javascript resource file.

we will have many API Proxies on the same line and we need to replace the {target.url} in all API Proxies at run time when that proxy is accessed.

Thanks

@GAURAV Doesn't matter. You can have any dummy url set in the TargetEndpoint, but the javascript policy in the example would override that with the target.url flow variable. So it would work the same way. If you want to replace a specific portion of the url, you can do some string manipulation to achieve the same. In the javascript policy do the following:

context.setVariable("customTargetURL", targetUrl);

And in your HTTPTargetConnection you can have:

http://{customTargetURL}/wfc/restcall/..../.

The example just demonstrates the use of flow variables and global resources, its upto you how you want to manipulate the URL eventually.

Since we do not have the concept of a global policy yet (we might be coming up with something very soon), this is one of the ways to achieve this. The org level resource file ensures that you are not duplicating the logic in each and every policy, however you still have to add that extra javascript policy which makes use of this resource file. Try out the example and see if it works for you.

Hi @arghya das

I tried your approach and it didn't work.

First I used the global JS resource and then I tried with js file in the API Proxy itself. Both cases it didn't work. Attached is the sample proxy bundle

and the URL which I am hitting

http://10.131.141.28:9002/v1/sampleauthrestservice?access_token=bd75f68c-9f74-482f-9028-43c459f8b1ba...

Please let me know what I missed here.

thanks

sampleauthrestservice-rev1-2015-10-20-rev3-2015-12.zip

@GAURAV

The proxy looks okay, form your request I do not see the target query param being sent. The javascript policy assumes that you are sending a request query param like target=demo.example.com

Secondly, I see that you created the javascript resource file in the proxy itself. You can simply upload that as a resource at the org level and refer to that in the javascript policy.

@arghya das

I am sending the target as query param below

http://10.131.141.28:9002/v1/sampleauthrestservice?access_token=5d4aaca1-204a-491b-a00e-3a9b3049cc29...

Also just for testing I have included the java script resource file in proxy itself, I'll move this at org level

I think it is not taking & character..but if you see

rhel7-8.int.kronos.com

is my target param

There was a minor issue. The proxy resource that you were referring to, was "targetsetter.js" whereas in your policy you were refering to the org level resource. So it was picking up the wrong definition of the javascript file and maybe the code was different in the two versions. In the javascript policy you have:1715-sampleauthrestservice-rev1-2015-10-20-rev3-20.zip

<ResourceURL>jsc://targetsetter</ResourceURL>
It should be <ResourceURL>jsc://targetsetter.js</ResourceURL>

I made that change in the attached proxy bundle and also disabled all other policies which were making service callouts and other stuff based on the service callout for my testing. Please try the attached bundle. Once its working, you can enable all the other policies that you have in the bundle.

Not applicable

Hi,

I toot have the same requirement but instead of replacing the target url, i want to replace the ip and port in the target url specified in the HTTPTargetConnection. Is it possible to do this with any kind of Javascripting?

Any help on this would be highly appreciated.

Thanks

..........

@Ravi Gopalan The same approach should work. In the example that I attached, I was simply updating the hostname and nothing else, however you can do the complete thing as well.

Refer to the following link to implement a simple URL parser and then use a replace function to replace specific portions of the URL: http://www.sitepoint.com/url-parsing-isomorphic-javascript/

Thanks @arghya das for your support

sampleauthrestservice-rev1-2015-10-20-rev4-2015-12.zip

It is working with attached bundle.

I have to change the javascript code ,it was not working with dynamic substitution of parameter {customTargetURL}. I have to use target.url as attached.

targetsetter.txt

Also we don't want to send full target host in query param like target=rhel7-8.int.kronos.com but we will send like target=t1 and there should be map/properties file where these mapping would be available like t1=rhel7-8.int.kronos.com.

Then in javascript we can just read that map/properties file and get the corresponding target url and set it in actual Target Endpoint URL so that we don't have to update the javascript but only the properties/map when there is new target endpoint.

thanks

adas
Participant V

Yes you can store the literals in a map along with the actual url or hostname. Please checkout the example keyvaluemap policy for implementing that solution.

@arghya das

Did you mean Key Value Map Operations Policy ?

Also does this policy will be per proxy level or can we upload this as a resource at oraganization level as we did with java script policy ?

If we can upload this as organization resource , does it have Management API's for CRUD operation?

Do you have any sample bundle for this implementation ?

thanks