1
votes

I'm currently trying to call Amazon Product Retail Web Service in Salesforce.

As I mentioned in Getting WSDL parse error while generating Apex code from WSDL in Salesforce

I was initially unable to generate apex stub class, but I followed the method suggested by @Ballinger and created apex class. I wrote an apex class to use that stub and to set request parameters. The class i wrote is as follows

public class AmazonProductStubNew
{
 public static void getResults()
 { 
        System.Debug(' getResults start ');
        AmazonWS.AWSECommerceServicePortUS stub = new AmazonWS.AWSECommerceServicePortUS();

        stub.inputHttpHeaders_x = new Map<String,String>();
        stub.inputHttpHeaders_x.put('AWSAccessKeyId','MyAmazonAWSAccessKeyId');
        stub.inputHttpHeaders_x.put('Timestamp','2012-11-28T12:11:30Z');
        stub.inputHttpHeaders_x.put('Signature','Encrypted Secret Code');
        String MarketplaceDomain = '';
        String AWSAccessKeyId = 'MyAmazonAWSAccessKeyId';
        String AssociateTag = '';
        String XMLEscaping = '';
        String Validate = '';
        AmazonWS.ItemSearchRequest Shared = new AmazonWS.ItemSearchRequest();
        Shared.SearchIndex = 'DVD';
        AmazonWS.ItemSearchRequest[] Request = new AmazonWS.ItemSearchRequest[1];
        Request[0] = new AmazonWS.ItemSearchRequest();
        Request[0].Title = 'Inception';
        AmazonWS.ItemSearchResponse_element response = stub.ItemSearch(MarketplaceDomain,AWSAccessKeyId,AssociateTag,XMLEscaping,Validate,Shared,Request);
        AmazonWS.Items_element[] localItems = response.Items;
        System.Debug(localItems[0].TotalResults);
 }
 }

Even though I've added HTTP headers to stub, I'm not getting it in XML Request message XML Request is as follows

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Header />
<env:Body>
<ItemSearch xmlns="http://webservices.amazon.com/AWSECommerceService/2011-08-01">
<MarketplaceDomain>
</MarketplaceDomain>
<AWSAccessKeyId>MyAWSAccessKeyId</AWSAccessKeyId>
<AssociateTag></AssociateTag>
<XMLEscaping></XMLEscaping>
<Validate></Validate>
<Shared><SearchIndex>DVD</SearchIndex></Shared>
<Request><Title>Inception</Title>
</Request></ItemSearch>
</env:Body></env:Envelope>

Since headers are not there in SOAP Request, There is a SOAP fault asking for Signature from Amazon Server.

As you can see, I'm new to Salesforce Apex. I followed the steps in

http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content/apex_web_services_wsdl2apex.htm#http_header_support

to set the headers.

Any idea on why the header isn't getting added?

P.S I added headers manually and tried in SOAP UI, I'm getting proper response.

Thanks :)

1
can you clarify your question, the title talks about HTTP headers, but your question seems to be about SOAP message headers, which is it ?superfell
Thanks for ur reply :) AWSAccessKeyId, Timestamp, Signature all three should be present for the request to get processed, in SOAP UI while constructing a request message, I specified these in <env:Header> and it worked fine. But when I add via apex classes it is not getting added as shown by the empty <env:Header> . Is my setting of header wrong in apex code? Thats my question. As per the Apex tutorial, the stub had inputHttpHeaders_x map. is this clear now?Satty
can you fix the title of your question then.superfell
done. removed HTTP. sorry if that was confusing.Satty

1 Answers

1
votes

I think you're using wrong functions :) (question is indeed confusing).

SOAP (or generally HTTP) communication consists of sending headers and actual message (payload if you like). Headers are short text thingies, message is often a giant XML.

Your code is setting HTTP headers (which are used in web communication to authenticate, provide info about your browser, preferred languages, set cookies, return status codes like 404 page not found...) Please don't be offended with the "for dummies" but I realize the wikipedia article is a bit too much, this might be simpler: http://net.tutsplus.com/tutorials/other/http-headers-for-dummies/

And what I suspect Amazon's webservice wants is just some fields inside the <env:Header>...</env:Header> tag? Just check the generated apex code for existence of subclass called "Header" (you can also search for the variable names like "Signature". This is going to be a total wild guess but I think you'll have to write something like that:

AmazonWS.AWSECommerceServicePortUS stub = new AmazonWS.AWSECommerceServicePortUS();
AmazonWS.Header h = new AmazonWS.Header();
h.AWSAccessKeyId = 'MyAmazonAWSAccessKeyId';
h.Timestamp = '2012-11-28T12:11:30Z';
h.Signature = 'Encrypted Secret Code';
stub.Header = h; // plug it into the request

// create and plug other required tags
AmazonWS.ItemSearchRequest Shared = new AmazonWS.ItemSearchRequest();
Shared.SearchIndex = 'DVD';
AmazonWS.ItemSearchRequest[] Request = new AmazonWS.ItemSearchRequest[1];
Request[0] = new AmazonWS.ItemSearchRequest();
Request[0].Title = 'Inception';
// ...

Now, to make it more confusing you might still have to use a HTTP header, there's a special one called SOAPAction. But generally speaking I believe you're after placing your data in the XML, not in http headers.


Funny enough, I've downloaded the Java example from http://aws.amazon.com/code/Product-Advertising-API/2478 and if I read it correctly they're passing the signature in the URL (endpoint), not in the XML. Probably because it's a REST GET method (if you can access that API it could save you a lot of hair pulled, SOAP is clunky).