Is the XPath within an ExtractVariables policy, a Message Template?

@Anil Sagar

I'd like to extract stuff from an App Entity, specifically the consumer secret from an App entity.

According to the docs, the App entity looks like this:

<App name="thomas-app">
    <ApiProducts/>
    <Credentials>
        <Credential>
            <Attributes/>
            <ConsumerKey>wrqOOOiPArFI0WRoB1gAJMRbOguekJ5w</ConsumerKey>
            <ConsumerSecret>WvOhDrJ8m6kzz7Ni</ConsumerSecret>
            <ApiProducts>
                <ApiProduct>
                    <Name>FreeProduct</Name>
                    <Status>approved</Status>
                </ApiProduct>
            </ApiProducts>
            <Scopes/>
            <Status>approved</Status>
        </Credential>
    </Credentials>
    <AppId>ab308c13-bc99-4c50-8434-0e0ed1b86075</AppId>
    <Attributes>
        <Attribute>
            <Name>DisplayName</Name>
            <Value>Tom's Weather App</Value>
        </Attribute>
    </Attributes>
    <CallbackUrl>http://tom.app/login</CallbackUrl>
    <CreatedAt>1362502872727</CreatedAt>
    <CreatedBy>admin@apigee.com</CreatedBy>
    <DeveloperId>PFK8IwOeAOW01JKA</DeveloperId>
    <Scopes/>
    <Status>approved</Status>
</App>

Then, to get the Display Name and consumer secret I need to use this ExtractVariables. But because there can be multiple credentials, I need to use a predicate on the Credential element, to get the consumer secret for that credential.

<ExtractVariables name='EV-1'>
  <Source>AccessEntity.AE-1</Source>
  <VariablePrefix>extracted</VariablePrefix>
  <XMLPayload>
    <Variable name='app_display_name' type='string'>
      <XPath>/App/Attributes/Attribute[Name='DisplayName']/Value/text()</XPath>
    </Variable>
    <Variable name='consumer_secret' type='string'>
      <XPath>/App/Credentials/Credential[ConsumerKey='wrqOOOiPArFI0WRoB1gAJMRbOguekJ5w']/ConsumerSecret/text()</XPath>
    </Variable>
  </XMLPayload>
</ExtractVariables>

My question is, can I have the XPath be dynamically generated based on a template? Can I do this?:

<ExtractVariables name='EV-1'>
  <Source>AccessEntity.AE-1</Source>
  <VariablePrefix>extracted</VariablePrefix>
  <XMLPayload>
    <Variable name='consumer_secret' type='string'>
      <XPath>/App/Credentials/Credential[ConsumerKey='{client_id}']/ConsumerSecret/text()</XPath>
    </Variable>
  </XMLPayload>
</ExtractVariables>
Solved Solved
1 8 958
1 ACCEPTED SOLUTION

The answer is : nope.

The value of XPath , today, cannot accept a Message Template, in the same way the value of JSONPath today can.


Edit:

The good news is that there's a feature coming soon (b/123246424) that would allow you to execute a dynamic XPath today using the message template and AssignMessage. For example.

<AssignMessage name='AM-1'>
  <AssignVariable>
    <Name>xpath</Name>
    <Template>/App/Credentials/Credential[ConsumerKey='{client_id}']/ConsumerSecret/text()</Template>
  </AssignVariable>
  <AssignVariable>
    <Name>private.consumer_secret</Name>
    <Template>{xpath(xpath,AccessEntity.AE1)}</Template>
  </AssignVariable>
</AssignMessage>

That featurer is not yet available as of September 2019. The workaround today is to transform the XML to JSON and use a dynamic JSONPath, of the same form.

View solution in original post

8 REPLIES 8

I just ran across this and am curious to know the answer. Does anyone know if variable substitution can be used in this XMLPayload example?

This is valid, which seems to be the same basic pattern:

<JSONPayload>
 <Variable name="desired_mp_pod_name">
    <JSONPath>$.[?(@.region=='{request.header.region}')].name</JSONPath>   </Variable>
</JSONPayload>

Not today! Not possible today.

Update: You can do it with AssignMessage though, and the jsonpath function available in Message Template.

Check the documentation.

The answer is : nope.

The value of XPath , today, cannot accept a Message Template, in the same way the value of JSONPath today can.


Edit:

The good news is that there's a feature coming soon (b/123246424) that would allow you to execute a dynamic XPath today using the message template and AssignMessage. For example.

<AssignMessage name='AM-1'>
  <AssignVariable>
    <Name>xpath</Name>
    <Template>/App/Credentials/Credential[ConsumerKey='{client_id}']/ConsumerSecret/text()</Template>
  </AssignVariable>
  <AssignVariable>
    <Name>private.consumer_secret</Name>
    <Template>{xpath(xpath,AccessEntity.AE1)}</Template>
  </AssignVariable>
</AssignMessage>

That featurer is not yet available as of September 2019. The workaround today is to transform the XML to JSON and use a dynamic JSONPath, of the same form.

It seems as of today, dynamic XPath evaluation is not supported by ApigeeX? What is the best way to solve for the problem described in this post

Did you try the xpath function that is available in Message Templates?

This works today

 

<AssignMessage name='AM-1'>
  <AssignVariable>
    <Name>path0</Name>
    <Template>/App/Credentials/Credential[ConsumerKey='{client_id}']/ConsumerSecret/text()</Template>
  </AssignVariable>
  <AssignVariable>
    <Name>private.consumer_secret</Name>
    <Template>{xpath(path0,AccessEntity.AE1)}</Template>
  </AssignVariable>
</AssignMessage>

 

What's going on there:

  • on line 4, you're building an xpath dynamically, using a message template. The client_id is being inserted into the xpath expression, so if the variable client_id is abcde then the resulting value that gets stored into path0 is /App/Credentials/Credential[ConsumerKey='abcde']/ConsumerSecret/text() .
  • On line 8, the template evaluates that xpath expression against the XML contained within the variable AccessEntity.AE1 .

I am just curious to know why we need to have message templating here?

As we can only generate the one credentials set for the at a time on apigee apps. Also in the extract variable it should be straight forward to get the consumer secret.

<XMLPayload><Variablename='consumer_secret'type='string'><XPath>/App/Credentials/ConsumerSecret/text()</XPath></Variable></XMLPayload>

to get the consumer secret. 

we can only generate the one credentials set for the at a time on apigee apps.

This is not a correct assumption. It is possible to associate more than one set of credentials to an app.

Probably that will explain why it would be nice to have message templating.