Combining JS policy+ ExtractVariables policy + ServiceCallout policy

Not applicable

Hi everyone,

I'm introducing myself to apigee, and I'm trying to make some chaining with different policies.

I've added to my Proxy Endpoint postFlow, callout to an external service, extraction of some values obtained in the previous step and JS policies in order to combine the response of the callout and the main response.

I'm not getting the chaining of these policy but I'm not sure where is the problem

If I trace my api proxy I can see the body of the service callout response with the expected response, which is like that:

<?xml version="1.0"?>
<CUSTOMER xmlns:xlink="http://www.w3.org/1999/xlink">
    <ID>1</ID>
    <FIRSTNAME>Susanne</FIRSTNAME>
    <LASTNAME>King</LASTNAME>
    <STREET>366 - 20th Ave.</STREET>
    <CITY>Olten</CITY> 
</CUSTOMER>

My Configuration is like that:

PostFlow:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
    <Description/>
    <FaultRules/>
    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Name>Spike-Arrest-1</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>
    <PostFlow name="PostFlow">
        <Request/>
        <Response>
            <Step>
                <Name>XML-to-JSON-1</Name>
            </Step>
            <Step>
                <Name>Service-Callout-1</Name>
            </Step>
            <Step>
                <Name>Extract-Variables-1</Name>
            </Step>
            <Step>
                <Name>JS-cambiaSaludo</Name>
            </Step>
        </Response>
    </PostFlow>
    <Flows/>
    <HTTPProxyConnection>
        <BasePath>/v1/hellopolicies</BasePath>
        <Properties/>
        <VirtualHost>default</VirtualHost>
        <VirtualHost>secure</VirtualHost>
    </HTTPProxyConnection>
    <RouteRule name="default">
        <TargetEndpoint>default</TargetEndpoint>
    </RouteRule>
</ProxyEndpoint>

XML-to-JSON:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<XMLToJSON async="false" continueOnError="false" enabled="true" name="XML-to-JSON-1">
    <DisplayName>XML to JSON-1</DisplayName>
    <Properties/>
    <Format>yahoo</Format>
    <OutputVariable>response</OutputVariable>
    <Source>response</Source>
</XMLToJSON>

Callout:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ServiceCallout async="false" continueOnError="false" enabled="true" name="Service-Callout-1">
    <DisplayName>customerCallout</DisplayName>
    <Request variable="myRequest"/>
    <Response>calloutResponse</Response>
    <HTTPTargetConnection>
        <URL>http://www.thomas-bayer.com/sqlrest/CUSTOMER/1/</URL>
    </HTTPTargetConnection>
</ServiceCallout>

Extract Variable:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="false" enabled="true" name="Extract-Variables-1">
    <DisplayName>Extract Variables-1</DisplayName>
    <Source>calloutResponse</Source>
    <VariablePrefix>customerResponse</VariablePrefix>
    <XMLPayload>
        <Variable name="id" type="integer">
            <XPath>/CUSTOMER/ID</XPath>
        </Variable>
        <Variable name="nombre" type="string">
            <XPath>/CUSTOMER/FIRSTNAME</XPath>
        </Variable>
        <Variable name="apellido" type="string">
            <XPath>/CUSTOMER/LASTNAME</XPath>
        </Variable>
        <Variable name="city" type="string">
            <XPath>/CUSTOMER/CITY</XPath>
        </Variable>
        <Variable name="city" type="string">
            <XPath>/CUSTOMER/STREET</XPath>
        </Variable>
    </XMLPayload>
</ExtractVariables>

JS policy config

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" name="JS-cambiaSaludo">
    <DisplayName>JS-cambiaSaludo</DisplayName>
    <Properties/>
    <ResourceURL>jsc://JS-cambiaSaludo.js</ResourceURL>
    <IncludeURL>jsc://pretty.js</IncludeURL>
</Javascript>

JS(Source code)

//Parse the respose from the target.
var res = JSON.parse(context.proxyResponse.content);
//Pull out only the information we want to see in the response.
var estado = res.root.state;
if (estado == "CA"){
    estado = "California";
}
var formatedResponse =  "\n" + 
                        "\n" + 
                        "\n" + 
                        "El resultado de la consulta es el siguiente:" + "\n" + 
                        "\n" + 
                        "Ciudad: " + res.root.city + "\n" + 
                        "Estado: " + estado + "\n" + 
                        "Nombre: " + res.root.firstName + "\n" + 
                        "Apellido: " + res.root.lastName + "\n" + 
                        "PrettyDate: " + prettyDate("2016-12-18T22:24:17Z") + 
                        "\n" + 
                        "\n" + 
                        "\n" + customerResponse;
//Set the response variable. 
context.proxyResponse.content = formatedResponse;

so,

What am I doing wrong? I think there is something I have not understood...

How can I extract the values from the callout result, for using it in my JS policy?.

Thanks in advance

Best regards.

Solved Solved
0 5 733
1 ACCEPTED SOLUTION

nmallesh
Participant V

Hi @J M,

Kindly go through this post - Fetching Servicecallout response

Have used assign message policy instead of JS policy.

Let me know if you need any help.

Keep us posted, thank you

View solution in original post

5 REPLIES 5

nmallesh
Participant V

Hi @J M,

Kindly go through this post - Fetching Servicecallout response

Have used assign message policy instead of JS policy.

Let me know if you need any help.

Keep us posted, thank you

If your payload is like this:

<CUSTOMER xmlns:xlink="http://www.w3.org/1999/xlink">
    <ID>1</ID>
    <FIRSTNAME>Susanne</FIRSTNAME>
    <LASTNAME>King</LASTNAME>
    <STREET>366 - 20th Ave.</STREET>
    <CITY>Olten</CITY> 
</CUSTOMER>

...then assuming the "customer" prefix is associated to the XML namespace of "http://www.w3.org/1999/xlink", the Xpath like this:

/customer:CUSTOMER/customer:FIRSTNAME

...will not resolve to anything. here's why: The "http://www.w3.org/1999/xlink" namespace does not apply to any element in the document. The namespace is defined at the top of the document but is not used anywhere.

The namespace in the original document that is associated with the "xlink" namespace prefix, the same namespace that you associated to the "customer" prefix in the ExtractVariables, is never used in the XML document you showed. Therefore the XML document you showed is equivalent to:

<CUSTOMER>
    <ID>1</ID>
    <FIRSTNAME>Susanne</FIRSTNAME>
    <LASTNAME>King</LASTNAME>
    <STREET>366 - 20th Ave.</STREET>
    <CITY>Olten</CITY> 
</CUSTOMER>

You can interactively try this out yourself using an online Xpath evaluator tool, like this one. If you are using a Windows machine, you can try this tool out to visualize your xpath query results.

I think maybe the xpath you want is:

/CUSTOMER/FIRSTNAME

or

/CUSTOMER/FIRSTNAME/text()

When I use THAT in the interactive online xpath tester tool, I get "Susanne" as a result. Similarly omit the namespace prefix for every other xpath you have in that ExtractVariables policy, and you should be good.

For more on XML namespaces and how to use them in xpath, check this out. An oldie but a goodie.

Hi, and thanks for the question. I'm afraid I've lost the trail at this point.

I don't understand the specific problem.

The Xpath in your original question had some clear problems, and I corrected those in my answer. Then you changed your question and it is now quite long, and I don't know what specifically you are asking.

I understand you're having difficulty, combining 3 policies, but specifically what is the difficulty?

Let's maybe open a new question, shall we? And can you keep it really simple? I know you have a task in front of you that requires 3 or 4 policies. I understand that. But let's break it down and solve it one step at a time. Let's keep the questions clear and simple, that way we can help you. If you need to ask 3 or 4 simpler questions, rather than one very long question, please be patient, we'll answer them, and we'll get you the help you need.

Hi!

Sorry @Dino for my extera-large-post. I have resumed it, for a more comprehensive reading.

By the way, I've got to solve my problem.

I thought the variable extraction was failing because I cannot see the result in the trace, however, despite of being empty in that screen, the variable had value. The problem was the way I was using to access it. In my JS I was using the name of the output variable of the extraction (customerResponse), but now I'm using the formula

context.getVariable("customerResponse.id");

context.getVariable("customerResponse.nombre");

context.getVariable("customerResponse.apellido");

... and so on.

In that way, I get a good result.

Sorry again for the mess, and thank you so much for the help.

Oh! Good! I'm glad you were able to sort it out.

Thanks for the reply.