Specifying a dynamic path in ServiceCallout, depending on Apigee environment

I have created a shared flow which has a service callout policy

The service call out policy has call to generate access token endpoint

This generate access token endpoint URL is different for Test and Prod.

How can I add a condition in shared flow to call appropriate URL using environment.name flow variable

Prod proxy should call prod URL and test proxy should refer test URL

Below HTTPTargetConnectionURL is for TEST

 <HTTPTargetConnection>
        <Properties/>
        <URL>https://abc.workday.com/ccx/oauth2/TEST/token</URL>
    </HTTPTargetConnection>

Below HTTPTargetConnection URL is for Prod

 <HTTPTargetConnection>
        <Properties/>
        <URL>https://abc.workday.com/ccx/oauth2/PROD/token</URL>
    </HTTPTargetConnection>
1 2 271
2 REPLIES 2

Yes,

you can do this with a "conditional assignment" as you describe.

To allow this to happen, somewhere you need to specify the url segment values that your proxies should use when running in the various apigee environments. Eg your API proxy must be able to access this data at runtime:

environment.name IDP path segment
test TEST123
stage whatever
prod PROD456

One way to do this is to store it in a JSON file, coded like this:

{
  "test" : "TEST123",
  "stage" : "whatever"
  "prod" : "PROD456",
  "you-can-add-others" : "here"
}

Then at runtime in the API proxy you an execute a JS step, which performs this logic:

  var mapping = JSON.parse(context.getVariable('mapping'));
  var envname = context.getVariable('environment.name');
  var workdayEnv = mapping[envname] || 'UNKNOWN';
  context.setVariable('workday-environment', workdayEnv);

In place of using "unknown", you may want to throw an Exception there. This will result in a fault in the API proxy.

OK at this point you have the workday environment in a variable. Then you need to just refer to it in the ServiceCallout policy, in the Path element, like this:

<ServiceCallout name='SC-PostToken'>
  <Request variable='tokenRequest'>
    <Set>
      <Verb>POST</Verb>
      <Path>/ccx/oauth2/{workday-environment}/token</Path>
      <Payload contentType='...'>...</Payload>
    </Set>
  </Request>
  <Response>tokenResponse</Response>
  <HTTPTargetConnection>
    <SSLInfo>
      <Enabled>true</Enabled>
      <IgnoreValidationErrors>false</IgnoreValidationErrors>
    </SSLInfo>
    <Properties>
      <Property name='success.codes'>2xx</Property>
    </Properties>
    <URL>https://abc.workday.com</URL>
  </HTTPTargetConnection>
</ServiceCallout>

That is one way to do it. It means you need to have that same table available in every API Proxy, in some way.

Another way to do this - a cleaner way, I would say - is to just use the environment-scoped KVM to store the specific workday environment, for each Apigee environment.

apigee environment value in KVM
test TEST123
stage whatever
prod PROD456

And then you can just load that value directly into a variable with a KVM GET:

<KeyValueMapOperations name="KVM-GetWorkdayEnvironment" mapIdentifier="settings">
    <ExclusiveCache>false</ExclusiveCache>
    <ExpiryTimeInSecs>30</ExpiryTimeInSecs>
    <Get assignTo="workday-environment">
        <Key>
            <Parameter>workday-environment</Parameter>
        </Key>
    </Get>
    <Scope>environment</Scope>
</KeyValueMapOperations>

This eliminates the need for the JavaScript step I described above. You keep the ServiceCallout the same.

In this case, the "mapping" is done not at runtime, but at configuration time, when you load into the environment-scoped KVM, the specific url segment values for each workday environment.

I would just store the variable in KVM and create this in each environment where this is required.

This has the advantage of being able to update it anytime without having to re-deploy the proxy.