KVM value not resolving in URL of HttpTargetConnection

I have a KVM policy that is trying to fetch environment value that is defined in the environment scope. It is encrypted. I want to substitute in url without need of redeloyment across environments.

KVM Policy:

<Get assignTo="private.environment"> <Key> <Parameter>env</Parameter> </Key> </Get>

Referring in Target endpoint proxy:

<URL>https://mobile-{private.environment}-host.com</URL>

</HTTPTargetConnection>

Error:

{ "okapi_error": "CLIENT ERROR: OKAPI does not host a proxy endpoint for 'mobile-{private.environment}-host.com'" }

Solved Solved
1 4 595
1 ACCEPTED SOLUTION

It seems that error is coming from your upstream system? So Apigee is actually sending out a request to a hostname with curly braces. And some virtual IP is responding saying "sorry, that endpoint is unknown." Is my understanding correct?

This could be caused by a failure to retrieve the expected data from the KVM.

Can you introduce an AssignMessage policy into your flow, directly after the KVM policy, to see if the KVM is actually retrieving the data?

Something like this:

<AssignMessage name='AM-Diagnostics'>
  <AssignVariable>   
    <Name>retrieved</Name>
    <Ref>private.environment</Ref>
  </AssignVariable>
</AssignMessage>

And then, view your proxy in trace as you send a request.

You should see the correct value in the "retrieved" variable after the AssignMessage executes.

If you don't see the expected value, then, something is not right with the KVM Get. The key parameter is not right, the mapname is not right, or you haven't populated the KVM properly. Fix that and your hostname should get populated.

if you DO see the expected variable... then.... hmmm, Maybe the URL is not a message template? (I'm pretty sure it is, but maybe not?) in which case, the way to do what you want is to introduce an AssignMessage that sets target.url. Like this:

<AssignMessage name='AM-TargetHost'>


  <AssignVariable>
    <Name>target_host</Name>
    <Template>mobile-{private.environment}-host.com</Template>
  </AssignVariable>


  <AssignVariable>
    <Name>target.url</Name>
    <Template>https://{target_host}{proxy.pathsuffix}</Template>
  </AssignVariable>


</AssignMessage>


That policy needs to be attached in the target request flow. If the variable target.url is set, it overrides the hard-coded value in the TargetEndpoint configuration.

The other thing I would suggest is, to include a check somewhere in your flow on the data you expect to retrieve from KVM, so that at runtime in the future, if there is some problem with the lookup in KVM, and the expected value is not retrieved, you throw a fault from within the proxy, rather than sending the malformed request to the upstream. You could do this implicitly with the AssignMessage by using a line like this:

<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>

This will cause the AssignMessage to throw a fault if "private.environment" is unresolvable - in other words, it has not been loaded by the KVM GET.

View solution in original post

4 REPLIES 4

It seems that error is coming from your upstream system? So Apigee is actually sending out a request to a hostname with curly braces. And some virtual IP is responding saying "sorry, that endpoint is unknown." Is my understanding correct?

This could be caused by a failure to retrieve the expected data from the KVM.

Can you introduce an AssignMessage policy into your flow, directly after the KVM policy, to see if the KVM is actually retrieving the data?

Something like this:

<AssignMessage name='AM-Diagnostics'>
  <AssignVariable>   
    <Name>retrieved</Name>
    <Ref>private.environment</Ref>
  </AssignVariable>
</AssignMessage>

And then, view your proxy in trace as you send a request.

You should see the correct value in the "retrieved" variable after the AssignMessage executes.

If you don't see the expected value, then, something is not right with the KVM Get. The key parameter is not right, the mapname is not right, or you haven't populated the KVM properly. Fix that and your hostname should get populated.

if you DO see the expected variable... then.... hmmm, Maybe the URL is not a message template? (I'm pretty sure it is, but maybe not?) in which case, the way to do what you want is to introduce an AssignMessage that sets target.url. Like this:

<AssignMessage name='AM-TargetHost'>


  <AssignVariable>
    <Name>target_host</Name>
    <Template>mobile-{private.environment}-host.com</Template>
  </AssignVariable>


  <AssignVariable>
    <Name>target.url</Name>
    <Template>https://{target_host}{proxy.pathsuffix}</Template>
  </AssignVariable>


</AssignMessage>


That policy needs to be attached in the target request flow. If the variable target.url is set, it overrides the hard-coded value in the TargetEndpoint configuration.

The other thing I would suggest is, to include a check somewhere in your flow on the data you expect to retrieve from KVM, so that at runtime in the future, if there is some problem with the lookup in KVM, and the expected value is not retrieved, you throw a fault from within the proxy, rather than sending the malformed request to the upstream. You could do this implicitly with the AssignMessage by using a line like this:

<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>

This will cause the AssignMessage to throw a fault if "private.environment" is unresolvable - in other words, it has not been loaded by the KVM GET.

Thanks for such a detailed write up. I will give this a try and reply back.

I tried to log this using AM policy as you shared here. But it never showed up in trace logs. I tried to set the 'IgnoreUnresolvedVariables' to false but no error.

I am resorting to TargetServer approach and it is working as expected. Thanks!

The answer is correct. But if you see not working for you, just set the target.url variable in a javascript in the target request flow. This will work in simillar way.