How to configure target.url in api proxy target request flow

Hello,

I am trying to set dynamically backend url with target.url variable.

I pick up the target URL from encrypted KVM and set the value to target.url variable with assign message policy.

But when I call the api proxy, I get the following error.

{"fault":{"faultstring":"Request path cannot be empty","detail":{"errorcode":"protocol.http.EmptyPath"}}}

I checked the variable in the trace tool, it seems that there are two target.url displayedin the "Variables" category.

One target.url vaule is the URL which I dynamically got from KVM

Another target.url is the URL I configured in the TargetEndpoint XML file

Is this the cause of the current error status?

I thought the URL in the TargetEndpoint XML would be overwritten if we set target.url dynamically in api proxy flow.

Thanks in advance.

0 14 4,165
14 REPLIES 14

It may be as simple as ... you need to supply a path. If there is no path, provide a slash.

context.setVariable('target.url', 'https://foo.bar'); // not OK
context.setVariable('target.url', 'https:/foo.bar/'); // OK

Also - be aware that setting target.url works only when done within the TARGET request flow.

Not in the API Proxy request flow.

@Dino,

Thanks for your answer.

I supplied a path in the value of the variable.

Then, the proxy successfullyy worked, but it forwarded mock apigee target server.

I intended to forward the request to a local apache server instead.

Do you have any idea of the reason?

I attach some screenshots of the trace tool snippet.

Though the request looks like to be sent to the local ip address of apache...

trace-variables.png

request-to-target-server.png

Hi, Can you explain what you mean by this?

Though the request looks like to be sent to the local ip address of apache...

I see in the PNG file that the Proxy is attempting a call to http://192.168.1.2 . That address represents a node on a private network. What that means is, a request sent to that address will never be forwarded off a LAN.

I think maybe what you are doing is this:

  • you have an Apache Server running somewhere. Maybe on your laptop/desktop.
  • The self-reported IP address of that machine is 192.168.1.2
  • You have configured an API Proxy in Apigee Edge to connect to 192.168.1.2
  • Apigee Edge is not successfully connecting to your local Apache Server

This is as expected.

When a machine in the cloud tries to connect to 192.168.x.x, it will never reach your local LAN. It cannot, because all addresses in that range are private network addresses. That address will be resolved to a machine that is on the same subnet as the client, which in this case is the Apigee Edge server, the Message Processor.

It may be possible for you to configure Apigee Edge to connect to your local Apache Server, but not via 192.168.1.2 . Instead you need to use an externally reachable address. Which address? The answer to that question is not simple.

If you are on a LAN, then you need to configure a router or switch to forward packets to your machine, when it receives requests for a particular IP or hostname. This is usually not possible on a corporate LAN, which means there is no address you could use. if you are on a home LAN, or a LAN that you directly control, then it's usually possible for you to configure your router to do that. Here is a tip on that. You will need to be handy configuring the port-forwarding on your LAN's router.

Hello,

Sorry for confusing.

The 192.168.1.2 is not the actual LAN address. I deliverately changed the ip address.

In my environment I am using amyLAN ip address as apache server.

I set the TargetEndpoint XML as

<URL>http://mocktarget.apgiee.net</URL>

In the target request flow, I got an URL as

"http://myLANipaddress/" from KVM and then set the url to target.url.

myLANipaddress is my local apache ip address (not 192.168..

I expected the api request would be sent to may local apache server, but the response of api was what mocktarget.apigee.net sent.

Thanks for your help.

ok, so it seems that setting target.url is ineffective. Is that right?

I don't understand the 192.168.1.2 address. If you are not using it, why did I see it in the screenshot? But anyway....

You need to make sure you are setting target.url in the target request flow. Are you doing that?

I suggest that maybe you could simplify things, and use.... instead of the KVM and the mocktarget and so on.... use a single JS callout with a fixed address, as I have shown in my original response here.

The original target might use an address like http://this.does.not.exist/

Simplify things and you may be able to solve this.

Yes, that is right. target.url configured is not working as expected.

>I don't understand the 192.168.1.2 address

That is easy. Because I changed the orignal LAN ip address to dummy "192.168.1.2" and called the api with trace "ON" to get the screenshot.
But it is not the main matter.

As you suggested, it may be simple to use single JS to set target.url.

The reason why I used KVM is the use case is written in "KVM scenrios" on the page as below.

https://docs.apigee.com/api-services/content/key-value-maps

You have an API proxy that needs to call one target (or Service Callout) URL in a test environment and another target URL in a production environment. Instead of hard-coding URLs in your proxy, you can have the proxy detect which environment it's in, execute the related Key Value Map Operations policy, and retrieve the correct target URL from one of the KVMs you created. And later, if one or both of your targets change, you simply update the the KVMs with the new URLs. The proxy picks up the new values, and no proxy redeployment is required.

I will try to use JS policy instead of KVM policy, but as long as I use target.url varilable, the same problem might happen, that is my concern.

Thanks.

Hi @Dino,

To make it simple, I tried setting target.url with JS Policy.

The code is as follows.

if (context.flow=="TARGET_REQ_FLOW") {
     var url = "http://mocktarget.apigee.net/"
     context.setVariable("target.url", url);
}

But the same thing happens even with JS policy.
when I call the API, the request is still forwarded to my local apache server, which was originally defined in the TargetEndpoint XML.

Is there any missing point?

I am using Edge for Private Cloud v4.17.1.

Thanks,
Takuro

hi - yes, where is the JS policy attached? in which flow?

It is not enough to include a conditional in the JS logic. in fact, if you have attached the policy correctly, that conditional is superfluous.

Each Policy in Apigee Edge is attached to a particular place. If you . have attached it in the correct place, then that conditional will always evaluate true. If you have attached it in the incorrect place, it will always evaluate false.

Have you reviewed "Understanding flows and resources" ?

And "Flow configurations" ?

Have you attached the JS policy in the Target Request flow?

Show me your target.xml.

Thanks for your help.

I think I attached the policy in the target request flow.

Here is my target.xml

default.zip

Hi

I'm sorry that you are continuing to experience problems with this task. I have constructed an API proxy that dynamically assigns the target URL using a Javascript callout, here. Can you download it and try it, and see if it works for you?

I don't know what the issue might be for you. The technique is pretty straightforward. It's not complicated.

Thanks, but I seems that I cannot download the sample api proxy with the error status 403 and description "Access to the specified resource () has been forbidden."

Could you pls upload the api proxy again?


Your proxy is perfectly working.

Regarding my proxy, it also works if I dynamically add some suffix with JS policy to the original target.url which is defined in the target.xml.

It seems to me if we change the target.url completely including the domain or ip address from the original one, it still forward the requrest to the original target even though JS policy successfully change the target.url value.

I don't understand what you are saying. I don't understand the situation.

But that's ok. It seems that the proxy I gave you is working. So perhaps you can use my proxy as a starting point to accomplish exactly what you want.

good luck!