Active IQ Unified Manager Discussions

perl webservices client

kleemola

Has anybody written any code to use perl to connect to WFA webservices?  Can it be done?  The only example provided in the webservices guide uses a MS-specific auth method.  I'm trying to write some perl, but I'm stuck at the auth piece.  I'm a bit of a webservices newbie here.

10 REPLIES 10

Re: perl webservices client

goodrum

I have done this with PHP but I assume that it will be very similar.  The key is to look at the function in the WSDL to determine what values need to be passed and how. 

<code php>

$soapClient   = new SoapClient("http://wfaServer/wfa-ws/WorkflowService_doc?wsdl",

   array(

   'login'=>'admin',

   'password'=>'admin'))

$client->executeWorkflow (array ("workflowId" => WorkflowNumber, "userInputsEqualsValues" =>

        array ("userInput1=Value1", "userInput2=Value2")

        )

);

</code php>

Re: perl webservices client

pwl
NetApp Alumni

Re: perl webservices client

girirp

Hi,

here is a sample code.

=================================================

#!perl -w

use SOAP::Lite;

my $lite = SOAP::Lite -> service('http://wfa_ip_address/wfa-ws/WorkflowService_doc?wsdl');

print "After creating Service \n";

my $res = $lite->getAllWorkflows();

print "After calling getAllworkflows\n";

sub SOAP::Transport::HTTP::Client::get_basic_credentials {

    return 'username' => 'password';

}

================================================

Re: perl webservices client

tp7317

None of the examples here work for me.   The PHP example I get:

PHP Parse error:  syntax error, unexpected T_VARIABLE in /root/wfa/wfa.php on line 20

And the Perl Example the variable is empty even though the script completes without error.

Re: perl webservices client

kleemola

I'm having some success using the SOAP::WSDL module.

1a.  Install SOAP::WSDL and SOAP::Lite from cpan. 

1b. Libexpat-dev is required on the system first!!

2.  wsdl2perl.pl -b /usr/lib/perl5/ http://wfaserver/wfa-ws/WorkflowService_doc?wsdl

where: /usr/lib/perl is somewhere in your @INC path and the second arg is the url of the doc/literal service for your WFA inst.

3.  Here's what I've got so far.  Replace $user and $password.  Authentication works fine, though I'd prefer to use the WSDL module auth.  The result comes back as the body of the SOAP message.  I'm now working on parsing it.  If anybody has any input on that, please speak up. 

#!/usr/bin/perl

use SOAP::Lite;
#use SOAP::Lite +autodispatch, +trace => debug;
use MyInterfaces::WorkflowService::WorkflowService_docPort;
use MyTypes::getAllWorkflows;
use MyElements::getAllWorkflows;
use MyTypemaps::WorkflowService;
use SOAP::WSDL;
use SOAP::WSDL::Client;
use SOAP::WSDL::Transport::HTTP;

my $user = "myuser";
my $password = "mypassword";

sub SOAP::Transport::HTTP::Client::get_basic_credentials {
return $user => $password ;
}

## Connect to service
my $service = MyInterfaces::WorkflowService::WorkflowService_docPort->new();

## Print results
#my $result = MyTypes::getAllWorkflows;
my $result = $service->getAllWorkflows();
die $result if not $result;
my $xml = $result;
print "\nMy xml:\n $xml \n\n";

Re: perl webservices client

arndt

I'm trying this sample code to call getAllWorkflows, and I have XML output enabled to help me debug this  I get the following error when using the _doc service address:

<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'><env:Header></env:Header><env:Body><env:Fault xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'><faultcode>env:Server</faultcode><faultstring>Request struct cannot be null</faultstring></env:Fault></env:Body></env:Envelope>

I've also tried the _rpc service address, and then I get the following error:

<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'><env:Header></env:Header><env:Body><env:Fault xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'><faultcode>env:VersionMismatch</faultcode><faultstring>Invalid SOAP envelope namespace: http://schemas.xmlsoap.org/wsdl/soap/</faultstring></env:Fault></env:Body></env:Envelope>

I do believe that my authentication is working, as I get a different error if I put in the wrong URL or wrong user/pass.  My code is below....any thoughts?  Thanks!

#!/usr/bin/perl -w

use strict;

use SOAP::Lite;

my $user    = "admin";

my $pass    = "admin";

my $soapurl = "http://WFA_IP/wfa-ws/WorkflowService_doc?wsdl";

my $usexml  = 1;

sub SOAP::Transport::HTTP::Client::get_basic_credentials {

        return $user => $pass;

}

my $service = SOAP::Lite -> service($soapurl);

$service->outputxml($usexml);

my $result = $service->getAllWorkflows();

print "R:$result\n";

Re: perl webservices client

kleemola

Try:

use SOAP::Lite +autodispatch;

And/or:

use SOAP::Lite +autodispatch, +trace => debug;

See my post elsewhere in the thread.  I'm having better success using the SOAP::WSDL module.  I believe the WFA team is working on some official documentation on WFA/perf webservice integration, so stay tuned.

Re: perl webservices client

arndt

OK, I finally got this figured out by looking at the XML request being sent by the perl script that was not working with a PHP script that was working.  The Perl script was not properly setting the namespace, so I modified the way that the Perl script connects as shown below.  Below is also an example of parsing the output sent back for the GetAllWorkflows call.  Note that I also had to use the _rpc interface instead of the _doc interface to the WFA web services.  Hope this helps someone else looking to connect to WFA web services via Perl.

#!/usr/bin/perl -w

use strict;

use SOAP::Lite;

my $user      = "admin";

my $pass      = "admin";

my $namespace = 'http://ws.wfa.netapp.com/';

my $soapurl   = 'http://WFA_IP/wfa-ws/WorkflowService_rpc?wsdl';

sub SOAP::Transport::HTTP::Client::get_basic_credentials {

        return $user => $pass;

}

my $service = new SOAP::Lite

        uri   => $namespace,

        proxy => $soapurl,

;

my $som    = $service->getAllWorkflows();

my $result = $som->result;

my $items  = $result->{'item'};

for my $item (@$items) {

        print "Workflow ID:          $item->{'id'}\n";

        print "Workflow Category:    $item->{'category'}\n";

        print "Workflow Name:        $item->{'name'}\n";

        print "Workflow Description: $item->{'description'}\n";

        print "Workflow Input: \n";

        my $inputs = $item->{'userInput'};

        for my $input (sort @$inputs) {

                print "  $input->{'name'} ($input->{'type'})\n";

        }

        print "\n";

}

Re: perl webservices client

pwl
NetApp Alumni

Great work mike!

Re: perl webservices client

arndt

Here are some more examples of using Perl to interact with WFA via SOAP...along with comments that give some hints about where I had struggles.  I'm not sure if my struggles were due to the immaturity of the SOAP::Lite module or my own lack of SOAP experience, but I suspect it's a combination of both .

wfa_get_all_workflows.pl

------------------------------------

#!/usr/bin/perl -w

use strict;

# Use 'trace' if you need to debug the XML interactions.

#use SOAP::Lite 'trace';

use SOAP::Lite;

# We have to use the RPC interface for SOAP calls that don't have

# any arguments.  Google xsi:nil true soap::lite if you want the gory

# details about how SOAP::Lite is broken.  Thankfully, WFA supports

# both doc and rpc interfaces.

my $soapurl   = 'http://WFA_IP/wfa-ws/WorkflowService_rpc?wsdl';

my $namespace = 'http://ws.wfa.netapp.com/';

my $user      = "admin";

my $pass      = "admin";

sub SOAP::Transport::HTTP::Client::get_basic_credentials {

        return $user => $pass;

}

my $service = new SOAP::Lite

        uri   => $namespace,

        proxy => $soapurl,

;

$service->ns($namespace);

# Setting autotype is not really necessary, but I like it when debugging.

$service->autotype('0');

# The use_prefix setting is deprecated, but I think it makes debbuing easier

# if you have tracing enabled.

#$service->use_prefix('0');

my $som    = $service->getAllWorkflows();

my $result = $som->result;

my $items  = $result->{'item'};

for my $item (@$items) {

        print "Workflow ID:          $item->{'id'}\n";

        print "Workflow Category:    $item->{'category'}\n";

        print "Workflow Name:        $item->{'name'}\n";

        print "Workflow Description: $item->{'description'}\n";

        print "Workflow Input: \n";

        my $inputs = $item->{'userInput'};

        for my $input (sort @$inputs) {

                print "  $input->{'name'} ($input->{'type'})\n";

        }

        print "\n";

}

------------------------------------

wfa_run_workflow.pl

----------------------------

#!/usr/bin/perl -w

use strict;

# Use 'trace' if you need to debug the XML interactions.

#use SOAP::Lite 'trace';

use SOAP::Lite;

# Oddly, the doc interface works and the rpc interface does not work when

# making a SOAP call with arguments.  The opposite is true when making

# SOAP calls with no arguments.  Good thing WFA supports both.  SOAP is fun.

my $soapurl   = 'http://WFA_IP/wfa-ws/WorkflowService_doc?wsdl';

my $namespace = 'http://ws.wfa.netapp.com/';

my $user      = "admin";

my $pass      = "admin";

sub SOAP::Transport::HTTP::Client::get_basic_credentials {

        return $user => $pass;

}

my $service = new SOAP::Lite

        uri   => $namespace,

        proxy => $soapurl,

;

$service->ns($namespace);

# Setting autotype is not really necessary, but I like it when debugging.

$service->autotype('0');

# The use_prefix setting is deprecated, but I think it makes debbuing easier

# if you have tracing enabled.

#$service->use_prefix('0');

my $wfid      = 31;

my $wfidparam = SOAP::Data->name('workflowId')->value($wfid);

my $wfparams  = SOAP::Data->name('userInputsEqualsValues')->value

([

        'controllerName=demo3020a.demo.ntapmn.com',

        'vfilerName=dmvfiler1',

        'volName_1=arndt_test',

        'qtreeName_1=wfasoapqt4',

        'qtreeStyle_1=unix',

        'create_Share_1=no',

        'create_Export_1=yes',

        'rootHosts=10.26.69.212:10.26.69.213',

]);

# I had to set even the optional arguments to make this work.

my $wftime   = SOAP::Data->name('executionDateAndTime')->value('');

my $wfcom    = SOAP::Data->name('comment')->value('');

my $som = $service->runWorkflow($wfidparam,$wfparams,$wftime,$wfcom);

if ($som->faultcode) {

        print "Fault Code:", $som->faultcode, "\n";

        print "Fault String:", $som->faultstring, "\n";

} else {

        my $result   = $som->result;

        print "Job $result has been submitted.\n";

}

----------------------------

wfa_get_job_status.pl

-------------------------------

#!/usr/bin/perl -w

use strict;

# Use 'trace' if you need to debug the XML interactions.

#use SOAP::Lite 'trace';

use SOAP::Lite;

# Oddly, the doc interface works and the rpc interface does not work when

# making a SOAP call with arguments.  The opposite is true when making

# SOAP calls with no arguments.  Good thing WFA supports both.  SOAP is fun.

my $soapurl   = 'http://WFA_IP/wfa-ws/WorkflowService_doc?wsdl';

my $namespace = 'http://ws.wfa.netapp.com/';

my $user      = "admin";

my $pass      = "admin";

sub SOAP::Transport::HTTP::Client::get_basic_credentials {

        return $user => $pass;

}

my $service = new SOAP::Lite

        uri   => $namespace,

        proxy => $soapurl,

;

$service->ns($namespace);

# Setting autotype is not really necessary, but I like it when debugging.

$service->autotype('0');

# The use_prefix setting is deprecated, but I think it makes debbuing easier

# if you have tracing enabled.

#$service->use_prefix('0');

my $jobid      = 392;

my $jobidparam = SOAP::Data->name('jobId')->value($jobid);

my $som = $service->getJobStatus($jobidparam);

if ($som->faultcode) {

        print "Fault Code:", $som->faultcode, "\n";

        print "Fault String:", $som->faultstring, "\n";

} else {

        my $result   = $som->result;

        print "Job start time: $result->{'startTime'}\n";

        print "Job end time:   $result->{'endTime'}\n" if ($result->{'endTime'});

        print "Job status:     $result->{'jobStatus'}\n";

        print "Job messages:   $result->{'errorMessage'}\n" if ($result->{'errorMessage'});

}

-------------------------------

View solution in original post

Earn Rewards for Your Review!
GPI Review Banner
All Community Forums
Public