Search code examples
perlsoaplite

Pull value from hash reference


I am using Perl and SOAP::Lite to pull ticket information from a system called OTRS.

At the moment we have a web service set up on OTRS called GetTicket.

We've managed to get SOAP:Lite to connect to the web service and pull the ticket information. The ticket information comes back as hash reference.

I am not creating a hash reference inside of the code, that is just what is being returned. How do I pull apart that hash reference if I haven't created it?

At this point we are trying to loop through the hash reference using foreach. I will post my progress as I go through it, but as usual, any advice is appreciated.

Perl Script

#!perl -w

use SOAP::Lite;
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;

use Data::Dumper;
print Dumper(SOAP::Lite
    -> proxy('https://ost-otrstest.ostusa.com/otrs/nph-genericinterface.pl/Webservice/Test/GetTicket')
    -> GetTicket()
    -> result);

Output

$VAR1 = {
         'ErrorCode' => 'TicketGet.AuthFail'
         'ErrorMessage' => 'TicketGet: Authorization failing!'
        };
Press any key to continue...

EDIT: Added dumper and received an authorization error. We do have a user name and password, at this point I'm just not sure where to put that.


Solution

  • SOAP::Lite relies on LWP::UserAgent for a lot of its http functionality, including the behaviour when authorization is requested.

    The documentation for LWP::UserAgent says this

    [get_basic_credentials] should return a username and password. It should return an empty list to abort the authentication resolution attempt. Subclasses can override this method to prompt the user for the information.

    So you need to overload LWP::UserAgent::get_basic_credentials by writing a new SOAP::Transport::HTTP::Client::get_basic_credentials.

    Overloading this method is described in the SOAP::Transport documentation. You need to write this

    BEGIN {
      sub SOAP::Transport::HTTP::Client::get_basic_credentials {
        return ('username', 'password');
      }
    }
    

    anywhere in your program. At the top is probably tidiest. (The BEGIN block forces the new method definition to be implemented before execution starts, regardless of its position in the program.)

    I hope there is a better solution as I'm not very happy with this solution: it is an ugly piece of Perl programming. You may be better off subclassing SOAP::Lite altogether to make the interface a little tidier.