Link to home
Start Free TrialLog in
Avatar of excngexpdp
excngexpdp

asked on

How to make webservice call in Perl?

I am very new to Perl. I need to find a solution to make client-side call to webservices using Perl.
Any sample code or direction would be very helpful.

Thank you very much.
Avatar of Carl Bohman
Carl Bohman
Flag of United States of America image

Something like this?

http://guide.soaplite.com/
Avatar of excngexpdp
excngexpdp

ASKER

Thank you bounsy,
I will go through it.
what kind of call? soap lite only handles rpc/encoded. if you want to call a document/literal service, maybe some thing more like WSDL-SOAP (http://search.cpan.org/~mkutter/SOAP-WSDL-2.00.10/lib/SOAP/WSDL.pm). The documentation for the module outlines how to use it.
I personally looked at most of the SOAP modules and they all have shortcomings, including lack of HTTP Basic Authentication for some of them (including SOAP::Lite).

I roll my own with LWP and just do the SOAP encapsulation and XMl parsing with custom code.  I've literally wasted more time trying to get the "proper" SOAP modules even halfway working for one simple real-world application than it took to do an entire client by hand with LWP.
I agree that SOAP in perl is weak, but soap-lite does have the ability for HTTP Basic Authentication (used it before). I guess the real problem is that soap-lite works fine for rpc/encoded services, works not at all for other types (even the de facto standard) and is poorly documented.

rolling your own soap message is doable in most cases, but even then, you lose some things and have to be knowledgeable about soap messaging.
As I had to take break for some days from my work, I am re-starting to solve this problem from this morning & no success yet. I can't figure out what is the problem, here is beginning to end of what I am trying to do ........

Step 1. For testing purpose I have created a  class in Salesforce.com


public class PERL_WSDL_TEST {

public void updateAccountData()
{

  Account[] a = [SELECT NumberOfEmployees,AnnualRevenue FROM Account WHERE NumberOfEmployees >1000];
 
   if(a.size()>0)
   {
    for(Account ac: a)
    {
     ac.AnnualRevenue = 100000;
    }
   }
 
  update a;
}

}
-------------------------------------------------------------------------------------------

Step 2. Created WSDL of the above class using salesforce feature

<?xml version="1.0" encoding="UTF-8"?>
<!--
 Web Services API : TEST.PERL_WSDL_TEST
-->
<definitions targetNamespace="http://soap.sforce.com/schemas/class/Test/PERL_WSDL_TEST" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://soap.sforce.com/schemas/class/Test/PERL_WSDL_TEST">
 <types>
  <xsd:schema elementFormDefault="qualified" targetNamespace="http://soap.sforce.com/schemas/class/Test/PERL_WSDL_TEST">
   <xsd:element name="DebuggingInfo">
    <xsd:complexType>
     <xsd:sequence>
      <xsd:element name="debugLog" type="xsd:string"/>
     </xsd:sequence>
    </xsd:complexType>
   </xsd:element>
   <xsd:simpleType name="ID">
    <xsd:restriction base="xsd:string">
     <xsd:length value="18"/>
     <xsd:pattern value="[a-zA-Z0-9]{18}"/>
    </xsd:restriction>
   </xsd:simpleType>
   <xsd:simpleType name="LogCategory">
    <xsd:restriction base="xsd:string">
     <xsd:enumeration value="Db"/>
     <xsd:enumeration value="Workflow"/>
     <xsd:enumeration value="Validation"/>
     <xsd:enumeration value="Callout"/>
     <xsd:enumeration value="Apex_code"/>
     <xsd:enumeration value="Apex_profiling"/>
     <xsd:enumeration value="All"/>
    </xsd:restriction>
   </xsd:simpleType>
   <xsd:simpleType name="LogCategoryLevel">
    <xsd:restriction base="xsd:string">
     <xsd:enumeration value="Internal"/>
     <xsd:enumeration value="Finest"/>
     <xsd:enumeration value="Finer"/>
     <xsd:enumeration value="Fine"/>
     <xsd:enumeration value="Debug"/>
     <xsd:enumeration value="Info"/>
     <xsd:enumeration value="Warn"/>
     <xsd:enumeration value="Error"/>
    </xsd:restriction>
   </xsd:simpleType>
   <xsd:complexType name="LogInfo">
    <xsd:sequence>
     <xsd:element name="category" type="tns:LogCategory"/>
     <xsd:element name="level" type="tns:LogCategoryLevel"/>
    </xsd:sequence>
   </xsd:complexType>
   <xsd:simpleType name="LogType">
    <xsd:restriction base="xsd:string">
     <xsd:enumeration value="None"/>
     <xsd:enumeration value="Debugonly"/>
     <xsd:enumeration value="Db"/>
     <xsd:enumeration value="Profiling"/>
     <xsd:enumeration value="Callout"/>
     <xsd:enumeration value="Detail"/>
    </xsd:restriction>
   </xsd:simpleType>
   <xsd:element name="DebuggingHeader">
    <xsd:complexType>
     <xsd:sequence>
      <xsd:element name="categories" minOccurs="0" maxOccurs="unbounded" type="tns:LogInfo"/>
      <xsd:element name="debugLevel" type="tns:LogType"/>
     </xsd:sequence>
    </xsd:complexType>
   </xsd:element>
   <xsd:element name="CallOptions">
    <xsd:complexType>
     <xsd:sequence>
      <xsd:element name="client" type="xsd:string"/>
     </xsd:sequence>
    </xsd:complexType>
   </xsd:element>
   <xsd:element name="SessionHeader">
    <xsd:complexType>
     <xsd:sequence>
      <xsd:element name="sessionId" type="xsd:string"/>
     </xsd:sequence>
    </xsd:complexType>
   </xsd:element>
   <xsd:element name="AllowFieldTruncationHeader">
    <xsd:complexType>
     <xsd:sequence>
      <xsd:element name="allowFieldTruncation" type="xsd:boolean"/>
     </xsd:sequence>
    </xsd:complexType>
   </xsd:element>
  </xsd:schema>
 </types>
 <!-- Operation Messages -->
 <portType name="PERL_WSDL_TESTPortType"/>
 <binding name="PERL_WSDL_TESTBinding" type="tns:PERL_WSDL_TESTPortType">
  <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
 </binding>
 <service name="PERL_WSDL_TESTService">
  <documentation></documentation>
  <port binding="tns:PERL_WSDL_TESTBinding" name="PERL_WSDL_TEST">
   <soap:address location="https://na6-api.salesforce.com/services/Soap/class/Test/PERL_WSDL_TEST"/>
  </port>
 </service>
</definitions>

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

Step 3. As per the http://www.cgi101.com/learn/connect/winxp.html link created wsdlTest.pl file under My Website folder
I used the documentation available at the above link to configure my Apache




                                             *********** wsdlTest.pl  - BEGIN*********
 #!perl -w

  use SOAP::Lite
   
  service => 'C:/WebServiceTest/PERL_WSDL_TEST.wsdl';
   
 
                                             *********** wsdlTest.pl  - END*********



On hitting  http://localhost/~MyUsername/ I can see the perl file along with other test CGI files. After clicking the test CGI file I can see the correct output. But clicking the perl file I get 500 Internal Server Error ..........

What should I need to do to make this perl code workable.




Sorry I was incomplete in my explanation - also how to invoke the updateAccountData method & test the over all process?
your wsdl is doc/lit and wont work with soap lite.

look at this module: http://search.cpan.org/dist/SOAP-WSDL/

specifically, look here: http://search.cpan.org/dist/SOAP-WSDL/lib/SOAP/WSDL/Client.pm
Thank you kawas,

Will you please be more clear - I could not understand you. I was just trying to create a test WSDL to test the client side call from Perl.
I don't know much about WSDL types. I have only used  SALESFORCE based WSDL from .Net. That is why I was trying to use the similar WSDL as a test.
What considerations should be taken based on the WSDL platform (.Net based WSDL,salesforce based WSDL, .......). I was thinking WSDL is just WSDL.



install SOAP::WSDL

then follow the 5 steps here: http://search.cpan.org/~mkutter/SOAP-WSDL/lib/SOAP/WSDL/Manual.pod#Quick_walk-through_for_the_unpatient

The only difference that I found is that when running the command: perl wsdl2perl.pl -b base_dir URL, I omitted the 'perl' part so it looked like: wsdl2perl.pl -b base_dir URL
After installing  SOAP::WSDL I tried to execute:
C:\SoapWsdl>wsdl2perl.pl -b base_dir URL

and the result is:
URL must be absolute at "C:/Perl/site/lib/SOAP/WSDL/Expat/Base.pm" line 67.

I don't understand what does it mean.


You need to specify *base_dir* which is where you want the stuff it generates put
and the *URL* which is the URL to your wsdl (i.e. http://foo.bar/myservice.wsdl)
Still no success.  I have saved the WSDL locally at "C:\Documents and Settings\testUser\My Documents\My Website\PERL_WSDL_TEST.wsdl"

1. Using URL as "C:\Documents and Settings\testUser\My Documents\My Website\PERL_WSDL_TEST.wsdl"

C:\>wsdl2perl.pl -b "C:\Documents and Settings\testUser\My Documents\My Website"
"C:\Documents and Settings\testUser\My Documents\My Website\PERL_WSDL_TEST.wsdl"

Protocol scheme 'c' is not supported at C:/Perl/site/lib/SOAP/WSDL/Expat/Base.pm
 line 67.


2. Using URL as "http://localhost/~testUser/PERL_WSDL_TEST.wsdl"

C:\>wsdl2perl.pl -b "C:\Documents and Settings\testUser\My Documents\My Website"   "http://localhost/~testUser/PERL_WSDL_TEST.wsdl"


Can't locate Class/Std/Fast/Storable.pm in @INC (@INC contains: C:/Perl/site/lib
 C:/Perl/lib .) at C:/Perl/site/lib/SOAP/WSDL/Definitions.pm line 9.
BEGIN failed--compilation aborted at C:/Perl/site/lib/SOAP/WSDL/Definitions.pm line 9.
Compilation failed in require at (eval 25) line 3.
 at C:/Perl/lib/XML/Parser/Expat.pm line 474
 at line 5 at C:/Perl/site/lib/SOAP/WSDL/Expat/Base.pm line 76


I installed the  SOAP::WSDL using SOAP-WSDL-2.00.04.tar.gz downloaded from http://webscripts.softpedia.com/script/Development-Scripts-js/SOAP-WSDL-45463.html#


you are on windows, right? from the run menu, type 'cmd' without the quotes. then type 'ppm' and wait for the dialog to pop up. then install SOAP-WSDL from that gui. It will install all missing dependencies. If it doesnt show any, then install that missing module, 'class-std-fast-storable' (you may have to type a substring of that name to find the module in ppm)
kawas thanks for your great help!

I played around with the Perl Packaging Manager, got the same problem. I then tried to re-install the SOAP::WSDL

and found the cause of the problem:

*****-----********
C:\SoapWsdl>perl build.pl
Checking whether your kit is complete...
Looks good

Checking prerequisites...
 - ERROR: Class::Std::Fast is not installed
 - ERROR: Template is not installed
 - ERROR: Date::Format is not installed
 - ERROR: Date::Parse is not installed
 - ERROR: Class::Std::Fast is not installed
 - ERROR: Template is not installed
 - ERROR: Date::Format is not installed
 - ERROR: Date::Parse is not installed

ERRORS/WARNINGS FOUND IN PREREQUISITES.  You may wish to install the versions
of the modules indicated above before proceeding with this installation

Deleting Build
Removed previous script 'Build'

Creating new 'Build' script for 'SOAP-WSDL' version '2.00.04'

C:\SoapWsdl>

*****-----********

I was trying to follow the instructions available on README file

********
 
INSTALLING
 ----------
 
 Use the following mantra:
 
  perl Build.PL
  perl Build
  perl Build test
  perl Build install
 
 If you don't have Module::Build installed, you may also use
 
  perl Makefile.PL
  make
  make test
  make install
 
 Note that Module::Build is the recommended installer - make will not run
 all tests provided with SOAP-WSDL.  
*********

How can I fulfill the prerequisites mentioned above.

use ppm, or download them from cpan

usually, google'ing the module takes you to cpan where you can obtain it.
Thank you very .... much. Actually thats what I am doing now.
I could fix Class::Std::Fast related problem. As I couldn't see through PPM  making 'Class'  as search keyword, I downloaded  and installed the class using Build commands(instructions in README). Now the problem is related to template,

*********BEGIN*************

C:\SoapWsdl>wsdl2perl.pl -b "C:\Documents and Settings\testUser\My Documents\My Website"   "http://localhost/~TestUser/PERL_WSDL_TEST.wsdl"

Cannot load generator SOAP::WSDL::Generator::Template::XSDCan't locate Template.pm in @INC (@INC contains: C:/Perl/site/lib C:/Perl/lib .) at C:/Perl/site/lib/SOAP/WSDL/Generator/Template/XSD.pm line 3.BEGIN failed--compilation aborted at C:/Perl/site/lib/SOAP/WSDL/Generator/Template/XSD.pm line 3.Compilation failed in require at (eval 1295) line 3.


*********END**************

Third line of the C:/Perl/site/lib/SOAP/WSDL/Generator/Template/XSD.pm file is: Use Template;

I am wondering why I can't see template in the PPM. If I do 'template' search I can only see HTML Template.

Alternately, I tried  downloading the template tool kit (Template-Toolkit-2.21) but unable to install through command prompt. I can see Makefile.PL and Install - I did try with -

perl Install   ---> (it doesn't work - may be it only works in UNIX...& not in windows)


ASKER CERTIFIED SOLUTION
Avatar of kawas
kawas
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
C:\PerlStdFastClass\Template-Toolkit-2.21.tar\Template-Toolkit-2.21\Template-Too
lkit-2.21>perl Makefile.Pl

                    Template Toolkit Version 2.21
                    =============================

Using Win32 defaults.
Run 'perl Makefile.PL TT_HELP' for a summary of options.

The Template Toolkit requires that the AppConfig module (version 1.56
or later) first be installed.  This is used by
the 'ttree' program for reading command line options and configuration
files.  It is available from CPAN:

    http://www.cpan.org/authors/Andy_Wardley/



Template::Stash::XS
-------------------

The Template::Stash module is a core part of the Template Toolkit,
implementing the magic for accessing data using the dot notation.

There is a high speed version, Template::Stash::XS, written in C.
This makes the Template Toolkit run about twice as fast as when using
the regular Template::Stash written in Perl.  If you've got a C
compiler on your system then you can elect to have the XS Stash built.
You can also specify that you want to use the XS Stash by default.

Note that as of version 2.15 the XS Stash now supports access to tied
hashes and arrays.

See 'perldoc Template::Config' for further details.

Do you want to build the XS Stash module? [y]
Do you want to use the XS Stash by default? [y]

Checking if your kit is complete...
Looks good
Warning: prerequisite AppConfig 1.56 not found.
Checking if your kit is complete...
Looks good
Writing Makefile for Template::Stash::XS
Writing Makefile for Template

Configuration complete. You should now run 'nmake', 'nmake test' andthen 'nmake install'.   See the README file for further information.

But following doesn't work,

C:\PerlStdFastClass\Template-Toolkit-2.21.tar\Template-Toolkit-2.21\Template-Too
lkit-2.21>nmake
'nmake' is not recognized as an internal or external command,operable program or batch file.

C:\PerlStdFastClass\Template-Toolkit-2.21.tar\Template-Toolkit-2.21\Template-Too
lkit-2.21>perl nmake
Can't open perl script "nmake": No such file or directory
Thank you kawas, i am now able to install the soap::wsdl & soap::lite through PPM