SoapWsdlClient, setHeader value not propogated down to SOAP requests?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

SoapWsdlClient, setHeader value not propogated down to SOAP requests?

Thomas Gagné-2
I'm trying to talk to SalesForce's API.  I've successfully completed a
login, but subsequent requests fail because I'm not properly setting a
SOAP header SessionHeader with the SessionId returned from the login
request.

The Java Code in the example resembles:

        SessionHeader sh = new SessionHeader();
        sh.setSessionId(loginResult.getSessionId());
        /** Next, the sample client application calls the setHeader method of the
         *  SoapBindingStub to add the header to all subsequent method calls. This  
         *  header will persist until the SoapBindingStub is destroyed until the header
         *  is explicitly removed. The "SessionHeader" parameter is the name of the
         *  header to be added.
         */
        // set the session header for subsequent call authentication
        binding.setHeader(new SforceServiceLocator().getServiceName().getNamespaceURI(),
                          "SessionHeader", sh);

My Smalltalk code resembles:

    "client is aSoapWsdlClient"

    ( client headerFor: #SessionHeader)
        value: ( SForce.SessionHeader new
                sessionId: loginResult sessionId;
                yourself).

Admittedly, my code doesn't have everything the Java code does, but the
web services documentation suggests #headerFor: should percolate down to
SOAP:

    When using WsdlClient to make SOAP requests, you can add header
    entries using the same API. To illustrate, we can use class
    WsdlClient to
    make a SOAP request with a header. When using WsdlClient, you can add
    header entries using the same API, or else assemble the SoapMessage in
    your application code.

--
Visit <http://tggagne.blogspot.com/>,<http://gagne.homedns.org/> or
      <http://gagne.homedns.org/~tgagne/> for more great reading.

Reply | Threaded
Open this post in threaded view
|

Re: SoapWsdlClient, setHeader value not propogated down to SOAP requests?

Thomas Gagné-2
I just noticed the WsdlClient's #executeRequest doesn't even pass a
reference of itself so other objects may correctly populate their headers.

    executeRequest
        "In case of persistent transport client set to nil old values"
        response := nil.
        responseValue := nil.
        "Execute request and set new response"
        response := self request executeWith: self transportClient.
        ^(self request isOneWay and: [ response isNil] )
            ifTrue: [nil]
            ifFalse: [ responseValue := response value ]

Neither "request" or "transportClient" have a reference to the
WsdlClient and so can't possibly get its header values (as far as I can
tell).

--
Visit <http://tggagne.blogspot.com/>,<http://gagne.homedns.org/> or
      <http://gagne.homedns.org/~tgagne/> for more great reading.

Reply | Threaded
Open this post in threaded view
|

Re: SoapWsdlClient, setHeader value not propogated down to SOAP requests?

Thomas Gagné-2
I've a kludge that works.

WsdlClient>>#executeSelector:args:

    executeSelector: aSymbol args: aCollection
        request == nil ifTrue: [ request := self newRequest].
        request smalltalkEntity: (Message selector: aSymbol arguments:
    aCollection).
    "add this line to make it work"
        request header: self header.
        ^self executeRequest

I realize this will overwrite any headers that may already be in the
request, and it would be better to iterate over the client's headers,
but this works for now.

Perhaps someone at Cincom could tell me what the better solution is.

--
Visit <http://tggagne.blogspot.com/>,<http://gagne.homedns.org/> or
      <http://gagne.homedns.org/~tgagne/> for more great reading.

Reply | Threaded
Open this post in threaded view
|

RE: SoapWsdlClient, setHeader value not propogated down to SOAP requests?

Kogan, Tamara
We provided better header handling solution for the WSOpentalkClient subclasses than for WsdlClient. As it is right now the only way to add headers to Wsdl client  request:

( client headerFor: #'Header1')
        value: ( Header1 new setString: 'String'; yourself ).
struct := WebServices.Struct new.
req := client newRequest.
req setHeaderFrom: client header.
req smalltalkEntity: (Message selector:  #echoString arguments: (Array with: 'body string' )).
value := client  executeRequest: req.

We should add setting headers for request (#setHeaderFrom:) to: client>>executeSelector:args:
I'll open an AR.

Tamara Kogan
Smalltalk development,
Cincom Systems

> -----Original Message-----
> From: Thomas Gagné [mailto:[hidden email]]
> Sent: Wednesday, November 14, 2007 2:27 PM
> To: vwnc
> Subject: Re: SoapWsdlClient, setHeader value not propogated down to SOAP
> requests?
>
> I've a kludge that works.
>
> WsdlClient>>#executeSelector:args:
>
>     executeSelector: aSymbol args: aCollection
>         request == nil ifTrue: [ request := self newRequest].
>         request smalltalkEntity: (Message selector: aSymbol arguments:
>     aCollection).
>     "add this line to make it work"
>         request header: self header.
>         ^self executeRequest
>
> I realize this will overwrite any headers that may already be in the
> request, and it would be better to iterate over the client's headers,
> but this works for now.
>
> Perhaps someone at Cincom could tell me what the better solution is.
>
> --
> Visit <http://tggagne.blogspot.com/>,<http://gagne.homedns.org/> or
>       <http://gagne.homedns.org/~tgagne/> for more great reading.

Reply | Threaded
Open this post in threaded view
|

Re: SoapWsdlClient, setHeader value not propogated down to SOAP requests?

Thomas Gagné-2
Kogan, Tamara wrote:
> We provided better header handling solution for the WSOpentalkClient subclasses than for WsdlClient. As it is right now the only way to add headers to Wsdl client  request:
>
> ( client headerFor: #'Header1')
> value: ( Header1 new setString: 'String'; yourself ).
> struct := WebServices.Struct new.
>  
What does that line do?  'struct' isn't used afterward...
> req := client newRequest.
> req setHeaderFrom: client header.
> req smalltalkEntity: (Message selector:  #echoString arguments: (Array with: 'body string' )).
> value := client  executeRequest: req.
>
> We should add setting headers for request (#setHeaderFrom:) to: client>>executeSelector:args:
> I'll open an AR.
>  
So a better work-around would be to modify
SoapWsdlClient>>#executeRequest to include:
    self request setHeaderFrom: self header.
??

--
Visit <http://tggagne.blogspot.com/>,<http://gagne.homedns.org/> or
      <http://gagne.homedns.org/~tgagne/> for more great reading.

Reply | Threaded
Open this post in threaded view
|

RE: SoapWsdlClient, setHeader value not propogated down to SOAP requests?

Kogan, Tamara
> > struct := WebServices.Struct new.
> >
> What does that line do?  'struct' isn't used afterward...

It does nothing. Sorry, it was just wrong copy and paste.

> > req := client newRequest.
> > req setHeaderFrom: client header.
> > req smalltalkEntity: (Message selector:  #echoString arguments: (Array
> with: 'body string' )).
> > value := client  executeRequest: req.
> >
> > We should add setting headers for request (#setHeaderFrom:) to:
> client>>executeSelector:args:
> > I'll open an AR.
> >
> So a better work-around would be to modify
> SoapWsdlClient>>#executeRequest to include:
>     self request setHeaderFrom: self header.
> ??

Yes, the fix will use:
client>>executeSelector:args:
...
     self request setHeaderFrom: self header.

Tamara