Apigee - How to send XML payload using POST method using Apigee API Development Platform - post

I am supposed to access a a publicly accessible API (https://ABCInsuranceCoreApp.ng.bluemix.net/ABCInsurance/ProductService) using POST method. It accepts an XML Payload of the form
<Customer>
<Age>40</Age>
<Gender>M</Gender>
<Location>IBM</Location>
</Customer>
and returns a list of products. The API works in a REST-Client and tested.
What I have done in the Apigee API Dev Platform is as follows.
Default ProxyEndpoint:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
<Flows>
<Flow name="default">
<Request>
<Step>
<Name>AssignCustomerData</Name>
</Step>
<Step>
<Name>ExecuteProductService</Name>
</Step>
</Request>
<Response>
<Step>
<Name>ParseProductList</Name>
</Step>
</Response>
</Flow>
</Flows>
<HTTPProxyConnection>
<BasePath>/v1/abcinsproductservice</BasePath>
<VirtualHost>default</VirtualHost>
</HTTPProxyConnection>
<RouteRule name="default"/>
</ProxyEndpoint>
AssignCustomerData is an AssignMessage Policy and it looks like..
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="AssignCustomerData">
<DisplayName>AssignCustomerData</DisplayName>
<AssignTo createNew="true" type="request">CustomerData</AssignTo>
<Set>
<Payload contentType="text/xml">
<Customer>
<Age>40</Age>
<Gender>M</Gender>
<Location>IBM</Location>
</Customer>
</Payload>
<Verb>POST</Verb>
</Set>
</AssignMessage>
ExecuteProductService is a service callout and it looks like..
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ServiceCallout async="false" continueOnError="false" enabled="true" name="ExecuteProductService">
<!-- Send the message we just made to the target, and save the result -->
<Request variable="CustomerData"/>
<Response>ProductList</Response>
<HTTPTargetConnection>
<URL>https://ABCInsuranceCoreApp.ng.bluemix.net/ABCInsurance/ProductService</URL>
</HTTPTargetConnection>
</ServiceCallout>
and ParseProductList is an ExtractVriable Policy which looks like..
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="false" enabled="true" name="ParseProductList">
<DisplayName>ParseProductList</DisplayName>
<FaultRules/>
<Properties/>
<VariablePrefix>products</VariablePrefix>
<XMLPayload>
<Variable name="name" type="string">
<XPath>//Products/Product[1]/Name</XPath>
</Variable>
</XMLPayload>
</ExtractVariables>
I have dilligently followed the samples, however the arrangement does not work. I am confused as to where the error is.
The trace is not working either..
Can you pls help out..
Many thanks in advance
Amitava

I looks like you need to add Source to your ExtractVariables policy, as in:
<Source clearPayload="false">ProductList</Source>
Also, I'm curious why you are doing this with a ServiceCallout (rather than just routing to your target service via a TargetEndpoint)? I don't see a RouteRule in your ProxyEndpoint. Without a RouteRule, you are creating an Echo Server will will simply reflect back whatever comes in. To stop that from happening, you would need to add a RaiseFault policy after your ExtractVariables policy to terminate the call.
Or, perhaps you are just showing us a snippet and there is really more to it?

The way I see it is,
<Step>
<Name>ParseProductList</Name>
</Step>
Should be a Request Step.
So your proxy becomes,
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
<Flows>
<Flow name="default">
<Request>
<Step>
<Name>AssignCustomerData</Name>
</Step>
<Step>
<Name>ExecuteProductService</Name>
</Step>
<Step>
<Name>ParseProductList</Name>
</Step>
</Request>
<Response/>
</Flow>
</Flows>
<HTTPProxyConnection>
<BasePath>/v1/abcinsproductservice</BasePath>
<VirtualHost>default</VirtualHost>
</HTTPProxyConnection>
<RouteRule name="default"/>
</ProxyEndpoint>

Related

Specify separate data to each user in Tsung

I am using Tsung for load testing. Here is the config file for Tsung.
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE tsung SYSTEM "/usr/share/tsung/tsung-1.0.dtd" []>
<tsung loglevel="warning">
<clients>
<client host="t1" cpu="2" maxusers="30000000"/>
<client host="t2" cpu="2" maxusers="30000000"/>
</clients>
<servers>
<server host="localhost" port="9200" type="tcp"/>
</servers>
<load>
<arrivalphase phase="1" duration="1" unit="minute">
<users arrivalrate="5" unit="second"/>
</arrivalphase>
</load>
</tsung>
But, I want the following:
Only one user per client everytime
Specific data to be read from file for each user. As in, I want to read data from a user1.json for user1 (on client 1) and from user2.json for user2 (on client2).
Is this possible in Tsung? I went through the docs, but didn't find any option to do so. Can someone help me out with this?
Not exactly what you're asking for. But something similar is possible, with one input file.
<options>
<option name="file_server" id="inputUsers" value="/tmp/users.txt"/>
</options>
<sessions>
<session probability="100" name="test" type="ts_http" >
<setdynvars sourcetype="file" fileid="inputUsers" delimiter=";" order="iter">
<var name="userId"/>
<var name="deviceMac"/>
<var name="tKey"/>
</setdynvars>
<request subst="true">
<http url="/abc/%%_userId%%/%%_deviceMac%%?arg=%%_tKey%%" version="1.1"></http>
</request>
<request subst="true">
<http url="/123/%%_userId%%" version="1.1"></http>
</request>
</session>
</sessions>
Where /tmp/users.txt contains colon separated user specific values - something like this (userId;deviceMac;tKey):
97099;05d4e99de98a;4xrwgyyze54kefnwsd74kj4ghvn5f1
Considering the setdynvars order value is "iter", it will iterate through each line, and use that input data as request parameters.
In the above example case, it would make these two requests:
/abc/97099/05d4e99de98a?arg=4xrwgyyze54kefnwsd74kj4ghvn5f1
/123/97099
You can achieve "user specific" load test scenario this way.

Intuit QBO SDK v3 Setting Customer PreferredDeliveryMethod to None does not seem to be working correctly

I use Intuit QBO SDK v3 DataService.FindById to get a Customer entity, modify some of the attributes including PreferredDeliveryMethod then call DataService.Update. When I set PreferredDeliveryMethod to 'Print' or 'Email', the Customer is modified correctly as shown by the response object. When I set PreferredDeliveryMethod to 'None', the response comes back with 'Print' regardless of what it was before I applied the modification. How do I set PreferredDeliveryMethod to 'None' for a proper response?
Update: This issue was with a Sandbox Company. When I tried it with a Production Company, the update worked correctly. There is some suspicion Company settings are involved but I don't know what yet.
Request:
<?xml version="1.0"?>
<Customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" domain="QBO" sparse="false" xmlns="http://schema.intuit.com/finance/v3">
<Id>3</Id>
<SyncToken>2</SyncToken>
<MetaData>
<CreateTime>2014-09-19T19:51:22-04:00</CreateTime>
<LastUpdatedTime>2015-02-10T09:53:30-05:00</LastUpdatedTime>
</MetaData>
<GivenName>Grace</GivenName>
<FamilyName>Pariente</FamilyName>
<FullyQualifiedName>Cool Cars</FullyQualifiedName>
<CompanyName>Cool Cars</CompanyName>
<DisplayName>Cool Cars</DisplayName>
<PrintOnCheckName>Cool Cars</PrintOnCheckName>
<Active>true</Active>
<PrimaryPhone>
<FreeFormNumber>(415) 555-9933</FreeFormNumber>
</PrimaryPhone>
<AlternatePhone />
<Fax />
<PrimaryEmailAddr>
<Address>Cool_Cars#intuit.com</Address>
</PrimaryEmailAddr>
<DefaultTaxCodeRef />
<Taxable>false</Taxable>
<BillAddr>
<Id>4</Id>
<Line1>65 Ocean Dr.</Line1>
<City>Half Moon Bay</City>
<CountrySubDivisionCode>CA</CountrySubDivisionCode>
<PostalCode>94213</PostalCode>
<Lat>37.4300318</Lat>
<Long>-122.4336537</Long>
</BillAddr>
<ShipAddr />
<Job>false</Job>
<BillWithParent>false</BillWithParent>
<SalesTermRef />
<Balance>0</Balance>
<BalanceWithJobs>0</BalanceWithJobs>
<PreferredDeliveryMethod>None</PreferredDeliveryMethod>
</Customer>
Response:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2015-02-10T06:53:55.320-08:00">
<Customer domain="QBO" sparse="false">
<Id>3</Id>
<SyncToken>3</SyncToken>
<MetaData>
<CreateTime>2014-09-19T16:51:22-07:00</CreateTime>
<LastUpdatedTime>2015-02-10T06:53:55-08:00</LastUpdatedTime>
</MetaData>
<GivenName>Grace</GivenName>
<FamilyName>Pariente</FamilyName>
<FullyQualifiedName>Cool Cars</FullyQualifiedName>
<CompanyName>Cool Cars</CompanyName>
<DisplayName>Cool Cars</DisplayName>
<PrintOnCheckName>Cool Cars</PrintOnCheckName>
<Active>true</Active>
<PrimaryPhone><FreeFormNumber>(415) 555-9933</FreeFormNumber></PrimaryPhone>
<PrimaryEmailAddr><Address>Cool_Cars#intuit.com</Address></PrimaryEmailAddr>
<Taxable>false</Taxable>
<BillAddr>
<Id>4</Id>
<Line1>65 Ocean Dr.</Line1>
<City>Half Moon Bay</City>
<CountrySubDivisionCode>CA</CountrySubDivisionCode>
<PostalCode>94213</PostalCode>
<Lat>37.4300318</Lat>
<Long>-122.4336537</Long>
</BillAddr>
<Job>false</Job>
<BillWithParent>false</BillWithParent>
<Balance>0</Balance>
<BalanceWithJobs>0</BalanceWithJobs>
<PreferredDeliveryMethod>Print</PreferredDeliveryMethod>
</Customer>
</IntuitResponse>
Can you capture and share the raw request/response XML.
I tried the following java code and it worked fine.
Customer customer = new Customer();
customer.setId("1");
Customer cust = this.service.findById(customer);
System.out.println(cust.getPreferredDeliveryMethod());
cust.setPreferredDeliveryMethod("None");
this.service.update(cust);
System.out.println("Updated - " + cust.getPreferredDeliveryMethod());
GetById
<IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2015-02-10T02:10:51.595-08:00">
<Customer domain="QBO" sparse="false">
<Id>1</Id>
<SyncToken>4</SyncToken>
<MetaData>
<CreateTime>2015-02-02T20:34:19-08:00</CreateTime>
<LastUpdatedTime>2015-02-10T02:10:39-08:00</LastUpdatedTime>
</MetaData>
<GivenName>John</GivenName>
<FamilyName>Doe</FamilyName>
<FullyQualifiedName>John Doe</FullyQualifiedName>
...
<Job>false</Job>
<BillWithParent>false</BillWithParent>
<Balance>242.25</Balance>
<BalanceWithJobs>242.25</BalanceWithJobs>
<PreferredDeliveryMethod>Print</PreferredDeliveryMethod>
</Customer>
</IntuitResponse>
Update PrefDelMethod to 'None'
<Customer domain="QBO" sparse="false" xmlns="http://schema.intuit.com/finance/v3">
<Id>1</Id>
<SyncToken>4</SyncToken>
<MetaData>
<CreateTime>2015-02-02T20:34:19-08:00</CreateTime>
<LastUpdatedTime>2015-02-10T02:10:39-08:00</LastUpdatedTime>
</MetaData>
<GivenName>John</GivenName>
<FamilyName>Doe</FamilyName>
<FullyQualifiedName>John Doe</FullyQualifiedName>
...
<BalanceWithJobs>242.25</BalanceWithJobs>
<PreferredDeliveryMethod>None</PreferredDeliveryMethod>
</Customer>
Update response
<IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2015-02-10T02:10:53.800-08:00">
<Customer domain="QBO" sparse="false">
<Id>1</Id>
<SyncToken>5</SyncToken>
<MetaData>
<CreateTime>2015-02-02T20:34:19-08:00</CreateTime>
<LastUpdatedTime>2015-02-10T02:10:53-08:00</LastUpdatedTime>
</MetaData>
<GivenName>John</GivenName>
<FamilyName>Doe</FamilyName>
<FullyQualifiedName>John Doe</FullyQualifiedName>
...
<BalanceWithJobs>242.25</BalanceWithJobs>
<PreferredDeliveryMethod>None</PreferredDeliveryMethod>
</Customer>
</IntuitResponse>
Per Intuit Developer Community, "Most probably it is a sandbox issue as it has data already setup which can sometimes cause data issues."
Yes, I have seen other data issues with Sandbox. This is the accepted answer.

Using Servicestack WSDL with php

I am trying to use ServiceStack to replace WCF for a self hosted service, accessed with a PHP client that forms its messages from on the WSDL.
The WSDL produced by ServiceStack has "part names" called "par" eg:
<wsdl:message name="GetServiceDetailsIn">
<wsdl:part name="par" element="tns:GetServiceDetails" />
</wsdl:message>
Then the SOAP request produced by PHP looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body><par/></SOAP-ENV:Body>
</SOAP-ENV:Envelope>
instead of this from the built-in help:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetServiceDetails xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:Shout" />
</soap:Body>
</soap:Envelope>
The PHP client has used a par tag instead of GetServiceDetails and it gets a blank response. Can the "part name" definition can be renamed or removed in ServiceStack?
It seems you can't doing anything about this in ServiceStack and its not designed to work with PHP anyway. However you can get it working if you get PHP to tweak the XML tags with find-and-replace, or XSLTs, before sending it.

Cordys BPM - Create an E-mail Model based on an XML Schema Document

I have created a standalone email model and generated a web service based on the email model. I followed the same steps as described in the Cordys documentation ( https://wiki.cordys.com/display/bop41/Creating+an+E-mail+Model ) but when I try to invoke the web service I am getting a fault like "Do not understand method TAT_Email_Model_WebserviceOperation of type NSCUST".
I have linked my WebServiceInterface to an Email service container ( correct me if I am done wrong over here).
The complete description of the fault is as below. Any suggestions.
<ErrorDetails>
<Request>
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP:Header xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
<header xmlns="http://schemas.cordys.com/General/1.0/">
<Logger xmlns="http://schemas.cordys.com/General/1.0/" />
</header>
<i18n:international xmlns:i18n="http://www.w3.org/2005/09/ws-i18n">
<locale xmlns="http://www.w3.org/2005/09/ws-i18n">en-US</locale>
</i18n:international>
</SOAP:Header>
<SOAP:Body>
<TAT_Email_Model_WebserviceOperation xmlns="http://schemas.cordys.com/1.0/email">
<SOURCE>Notification Custom Method</SOURCE>
<MESSAGE_DATA>
<Application>
<data>
<message_data />
<message_metadata />
</data>
</Application>
</MESSAGE_DATA>
<SUBJECT>PARAMETER</SUBJECT>
<attachments>
<attachment name="" encoded="false">PARAMETER</attachment>
</attachments>
<SENDER_ADDRESS>
<MAIL_ID>PARAMETER</MAIL_ID>
<DISPLAY_NAME>PARAMETER</DISPLAY_NAME>
</SENDER_ADDRESS>
<RECEIVERS>
<MAILING_LIST>
<to>
<address>
<displayName>PARAMETER</displayName>
<emailAddress>PARAMETER</emailAddress>
</address>
</to>
<cc>
<address>
<displayName>PARAMETER</displayName>
<emailAddress>PARAMETER</emailAddress>
</address>
</cc>
<bcc>
<address>
<displayName>PARAMETER</displayName>
<emailAddress>PARAMETER</emailAddress>
</address>
</bcc>
</MAILING_LIST>
</RECEIVERS>
</TAT_Email_Model_WebserviceOperation>
</SOAP:Body>
</SOAP:Envelope>
</Request>
<Response>
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP:Header xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
<header xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://schemas.cordys.com/General/1.0/">
<msg-id>000C297F-0536-11E3-E944-DF0951D0118E</msg-id>
<license>License has expired since 138 day(s)</license>
</header>
</SOAP:Header>
<SOAP:Body>
<SOAP:Fault>
<faultcode>MustUnderstand</faultcode>
<faultstring xml:lang="en-US">Do not understand method TAT_Email_Model_WebserviceOperation of type NSCUST</faultstring>
<faultactor>http://schemas.cordys.com/1.0/email</faultactor>
<detail>
<cordys:FaultDetails xmlns:cordys="http://schemas.cordys.com/General/1.0/">
<cordys:LocalizableMessage xmlns:cordys="http://schemas.cordys.com/General/1.0/">
<cordys:MessageCode xmlns:cordys="http://schemas.cordys.com/General/1.0/" />
</cordys:LocalizableMessage>
</cordys:FaultDetails>
</detail>
</SOAP:Fault>
</SOAP:Body>
</SOAP:Envelope>
</Response>
</ErrorDetails>
You have bound it to the wrong service container, you have to attach it to the Notification Service Container.
The error tells you that the current handling service container cannot handle requests of type NSCUST. This is available in the implementation of the webservice.
NOTE: you license has been expired on that server. With the License Manager in Cordys you can update it.

Delphi 2007 isn't generating the XML I want to send to my Java-WS web service

I have a Java web service to which I've linked from a Delphi 2007 app using the WSDL Importer. Setting it up has been a rocky road but I'm almost there!
I now have the situation where my arrays aren't being serialized in a way that my Java web service can consume. I've written the same app in .Net to test it out (it works fine) and the XML I'm looking to generate looks like this: -
<?xml version="1.0"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body xmlns:NS2="http://path.to.service">
<NS1:addActivities xmlns:NS1="http://path.to.service/">
<login href="#1"/>
<project xsi:type="xsd:string">PROJ001</project>
<activities>
<id xsi:type="xsd:string">DELPHITEST</id>
<name xsi:type="xsd:string">This is a test</name>
</activities>
<activities>
<id xsi:type="xsd:string">DELPHITEST2</id>
<name xsi:type="xsd:string">This is another test</name>
</activities>
</NS1:addActivities>
<NS2:login id="1" xsi:type="NS2:login">
<database xsi:type="xsd:string">My_database</database>
<password xsi:type="xsd:string">neverUmind</password>
<username xsi:type="xsd:string">bob</username>
</NS2:login>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
However, the XML that Delphi generates is as follows: -
<?xml version="1.0"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body xmlns:NS2="http://path.to.service/">
<NS1:addActivities xmlns:NS1="http://path.to.service/">
<login href="#1"/>
<project xsi:type="xsd:string">PROJ001</project>
<activities xsi:type="SOAP-ENC:Array"
SOAP-ENC:arrayType="NS2:activity[2]">
<item href="#2"/>
<item href="#3"/>
</activities>
</NS1:addActivities>
<NS2:login id="1" xsi:type="NS2:login">
<database xsi:type="xsd:string">My_database</database>
<password xsi:type="xsd:string">neverUmind</password>
<username xsi:type="xsd:string">bob</username>
</NS2:login>
<NS2:activity id="2" xsi:type="NS2:activity">
<id xsi:type="xsd:string">DELPHITEST</id>
<name xsi:type="xsd:string">This is a test</name>
</NS2:activity>
<NS2:activity id="3" xsi:type="NS2:activity">
<id xsi:type="xsd:string">DELPHITEST2</id>
<name xsi:type="xsd:string">This is another test</name>
</NS2:activity>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Basically, I need Delphi to stop creating activity elements within the activities element and instead just put each ID and Name inside the an activities element (as .Net does and Java seems to expect).
I've buggered about with the InvRegistry.RegisterInvokeOptions and the RemClassRegistry.RegisterSerializeOptions but none of the combinations seem to work. To be honest I'm on the verge of writting my own XML parser for this as it's taking way to long to figure out. However, if anyone has any suggestions on how this should work I'd be very grateful.
Surely somebody out there must have consumed a Java-WS web service via Delphi 2007 before :)
TIA
It seems the XMLDocument component in Delphi 2007 is broken. I've installed the Alcinoe component instead and that works a charm. That was only a week wasted ... grrrr

Resources