How do I access SourceGear Web services using SOAP::Lite?
For some reason SourceGear provide an undocumented Web service on their installations. They actually ask developers to use the API instead because the Web service is kinda messy, but this is a problem in my case because I cannot use this API on a Perl environment, so their solution for my specific case is to use the Web service.
This shouldn't be a problem. Using SOAP::Lite I have connected to several Web services in the past in the same way. But the lack of documentation is a major chaos if you don't know where the SOAP calls can be made. I only have an XML to decipher where to and how to make these calls. It would be great if a real SOAP genius could help me out in this.
This is an example of the login call and the expected r开发者_高级运维esponse:
Request
POST /fortress/dragnetwebservice.asmx HTTP/1.1
Host: velecloudserver
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://www.sourcegear.com/schemas/dragnet/LoginPlainText"
<?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>
<LoginPlainText xmlns="http://www.sourcegear.com/schemas/dragnet">
<strLogin>string</strLogin>
<strPassword>string</strPassword>
</LoginPlainText>
</soap:Body>
</soap:Envelope>
Response
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?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>
<LoginPlainTextResponse xmlns="http://www.sourcegear.com/schemas/dragnet">
<LoginPlainTextResult>int</LoginPlainTextResult>
<strAuthTicket>string</strAuthTicket>
</LoginPlainTextResponse>
</soap:Body>
</soap:Envelope>
I'm looking for a way to be able to assemble this somehow. This is my Perl example:
my $soap = SOAP::Lite -> uri ('http://velecloudserver/fortress/dragnetwebservice.asmx') -> proxy('http://velecloudserver/fortress/dragnetwebservice.asmx/LoginPlainText');
my $som = $soap->call('LoginPlainText', SOAP::Data->name('LoginPlainText')->value(
\SOAP::Data->value([
SOAP::Data->name('strLogin')->value( 'admin' ),
SOAP::Data->name('strPassword')->value('Adm1234'),
]))
);
Any tip would be appreciated.
Start by pointing wget/curl/lwp/etc. at http://velecloudserver/fortress/dragnetwebservice.asmx?WSDL and see if you get a WSDL file back.
If you do, then compare it to the four types listed in the SOAP::Lite POD. Your Request example looks like the Docment/Literal form, so you might end up writing something like this:
use SOAP::Lite;
my $soap = SOAP::Lite->new( file => 'http://velecloudserver/fortress/dragnetwebservice.asmx?WSDL');
$soap->on_action( sub { "urn:dragnetservice#LoginPlainText" });
$soap->autotype(0);
$soap->default_ns('urn:LoginPlainText');
my $som = $soap->call("LoginPlainText",
SOAP::Data->name('strLogin')->value( 'admin' ),
SOAP::Data->name('strPassword')->value('Adm1234'),
);
die $som->fault->{ faultstring } if ($som->fault);
print $som->result, "\n";
If you don't get WSDL back, I'd try replacing the constructor call with:
my $soap = SOAP::Lite->new( proxy => 'http://velecloudserver/fortress/dragnetwebservice.asmx');
The last time I worked with SOAP::Lite, I wrote a short program similar to the one above, and I ran it under the debugger. Before I executed the $soap->call() line, I peeked at the guts of the $soap object and looked at the request payload to see if the XML matched some working XML that I had by using the soapUI.org java client.
I had to read the POD a couple of times, and I dug into the source to figure our how some of the methods like default_ns() affected the generated XML. Once I did that, it all made a lot more sense.
Note: SOAP::Lite likes to die() when it fails. Wrap your calls in an eval{} for production use.
精彩评论