Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

SOAP::Transport::HTTP::Daemon and XML

by rppowell (Novice)
on Nov 22, 2007 at 01:52 UTC ( #652291=perlquestion: print w/ replies, xml ) Need Help??
rppowell has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to fake SOAP server functions for testing purposes. I use a the following code as a SOAP client:
SOAP return: use strict; use Data::Dumper; use SOAP::Lite + "trace"; my $soap = SOAP::Lite -> uri('http://www.perlmonks.org/FileQueue') -> proxy('http://localhost:88') ; my $rslt = $soap->getServerInfo()->result;
This generates the following output from the Real SOAP server:
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/env +elope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xm +lns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http:/ +/www.w3.org/1999/XMLSchema" xmlns:lwq="http://www.perlmonks.com/FileQ +ueue"> <SOAP-ENV:Body> <pmq:getServerInfoResponse> <info> <version>0.1.dev</version> <validTypes> <filetype>txt</filetype> <filetype>txt</filetype> </validTypes> <statistics> <documentsProcessed>0</documentsProcessed> </statistics> </info> </pmq:getServerInfoResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
Here is the code for the Fake SOAP Server:
use strict; use SOAP::Lite + "trace"; use SOAP::Transport::HTTP; use Data::Dumper; my $serverinfo = { version => "0.1.dev", validTypes => { filetype => "txt", filetype => "html", }, statistics => { documentsProcessed => 0, }, }; sub FileQueue::getServerInfo { return $serverinfo; } my $daemon = SOAP::Transport::HTTP::Daemon -> new (LocalPort => 88) -> dispatch_to('FileQueue') ; print "Contact to SOAP server at ", $daemon->url, "\n"; $daemon->handle;
This produces the following SOAP response:
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/env +elope/" xmlns:namesp2="http://xml.apache.org/xml-soap" xmlns:xsi="htt +p://www.w3.org/1999/XMLSchema-instance" xmlns:SOAP-ENC="http://schema +s.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/1999/XMLSc +hema" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encodin +g/"> <SOAP-ENV:Body> <namesp3:getServerInfoResponse xmlns:namesp3="http://www.perlmonks +.org/FileQueue"> <s-gensym6 xsi:type="namesp2:SOAPStruct"> <statistics xsi:type="namesp2:SOAPStruct"> <documentsProcessed xsi:type="xsd:int">0</documentsProcessed +> </statistics> <version xsi:type="xsd:string">0.1.dev</version> <validTypes xsi:type="namesp2:SOAPStruct"> <filetype xsi:type="xsd:string">html</filetype> </validTypes> </s-gensym6> </namesp3:getServerInfoResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
How can I get precise control on the generated XML?

In the Real SOAP response, in the SOAP-ENV:Body, there is <pmq:getServerInfoResponse> node, how do I generate on in the Fake SOAP response?

In some of the XML code, there are xsi:type="xsd:string" values, how do I generate XML without it?

Any help would be appreciated;
-rppowell

Comment on SOAP::Transport::HTTP::Daemon and XML
Select or Download Code
Re: SOAP::Transport::HTTP::Daemon and XML
by erroneousBollock (Curate) on Nov 22, 2007 at 02:33 UTC

    Request

    Copy the real service's WSDL description, then serve it from http://fakeserver/service?WDSL. Then you can use SOAP::WSDL to make the request. Because it gets the same WSDL from both services, it will send the same request to both.

    Response

    validTypes and statistics should probably be returned as array refs, rather than hash refs.

    The main problem seems to be that you're not returning the node name info with your data, so SOAP::Lite is using a gensym value.

    I can't remember exactly the incantation (I mainly deal with .NET services), but try:

      return bless { info => $serverinfo }, 'getServerInfoResponse';

    -David

      I have the WSDL description, but only in file form. Is it necessary that WSDL file be web served? I don't see how to use it as local file, is it possible?
        I have the WSDL description, but only in file form.
        Are you sure?

        Web-services commonly serve their WSDL from the proxy URL with '?WSDL' appended.

        The SOAP::Transport::HTTP::Server subclasses don't make it easy to serve your WSDL from the same service, so what I do is the following:

        1. use the HTTP::Request->parse constructor from HTTP::Request to build a request from the raw incoming request, then
        2. (depending on the $request->uri) I either:
          • build a response containing WSDL, or
          • pass $request directly to SOAP::Transport::HTTP::Server like this:

            my $soap = SOAP::Transport::HTTP::Server -> new(%args) -> dispatch_to(@classes); $soap->request($request); $soap->handle; my $response = $soap->response;

        Is it necessary that WSDL file be web served? I don't see how to use it as local file, is it possible?
        Sure, do something like this:

        my $soap = SOAP::WSDL->new(); $soap->wsdl('file:/path/to/file.wsdl'); $soap->proxy('http://server/service.cgi'); $soap->wsdlinit(caching => 1);
        Loading from the file saves some time on script startup, using caching saves a lot of work on each request.

        Update: Fixed my URLs.

        -David

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://652291]
Approved by vcTheGuru
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (15)
As of 2014-08-20 14:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (115 votes), past polls