Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Who is scrambling my SOAP (Moose) object?

by sam_bakki (Pilgrim)
on Oct 15, 2012 at 05:17 UTC ( [id://999011]=perlquestion: print w/replies, xml ) Need Help??

sam_bakki has asked for the wisdom of the Perl Monks concerning the following question:

Dear Perl Monks

Please help me to solve a SOAP::Lite + Moose object problem.

I am trying to create a SOAP server which serves a Moose object as a Web service. Both my server & client is in perl. When I get the perl object from client side, Only first call to any instance method works after that object (which I got from SOAP server) scrambles. So subsequent instance method calls fails.

Please have a look at my example code to reproduce the problem.

soap-ser.pl

#!perl package DemoService; use strict; use warnings; use Moose; use namespace::autoclean; has 'size',is=>'rw',default=>20; #Do it for all classes so Moose will create fast object creation, so a +pplication runs faster __PACKAGE__->meta->make_immutable(); 1; package main; use strict; use warnings; use SOAP::Transport::HTTP; use Compress::Zlib; use FindBin qw($RealBin); use lib "$RealBin"; $|=1; my $httpSoapDaemon = SOAP::Transport::HTTP::Daemon->new(LocalAddr => ' +localhost',Reuse => 1,LocalPort => 8081); #Will be encrypted if message > 100 $httpSoapDaemon->options({compress_threshold => 500}); #Dispatch calls to particular class #$httpSoapDaemon-> objects_by_reference(qw(DemoService)); $httpSoapDaemon->dispatch_to(qw(DemoService)); print "\n Server started. URL: ", $httpSoapDaemon->url(); #Daemon started here $httpSoapDaemon->handle();

soap-cli.pl

#!perl use strict; use warnings; use SOAP::Lite; use Data::Dumper; my $result; my $soapService = SOAP::Lite->new(); #Specify which class should be called for the service, i.e namespace $soapService->uri('DemoService'); #specify service provider location, Initial timeout should be very min +imal $soapService->transport()->proxy('http://127.0.0.1:8081/',timeout=>600 +,keep_alive =>1); #No need to have HTTP proxy #transport returns underlaying LWP::UserAgent object $soapService->transport()->no_proxy('127.0.0.1','localhost'); #Get Object, To call constructor use explicit call function, DO not us +e autodispatch. my $obj = $soapService->call('new'=>())->result(); #Modify the Obj to Hash ref $obj = SOAP::Data->value($obj); print "\n OBJ-State:",Dumper($obj); print "\n"; #Call instance methods #Pass the obj as first argument so it will go as $self $result = $soapService->call(size=>($obj,45)); unless ($result->fault) { print "\n Size is ::",$result->result(); # Method result print "\n New-OBJ-State:",Dumper($obj); } #So far it is good. Call the size again to set another value #This call fails because 'New-OBJ-State' is scrambled :( #Got following error # ERROR: soap:Server, Can't use string ("DemoService") as a HASH ref w +hile "strict refs" in use at accessor DemoService::size (defined at s +oap-ser.pl line 8) line 3. $result = $soapService->call(size=>($obj,20)); unless ($result->fault) { print "\n Size is ::",$result->result(); # Method result print "\n OBJ-State:",Dumper($obj); } else { print "\n ERROR: ", join ', ', $result->faultcode, $result->faultstring, $result->faultdetail; }

First we need to start SOAP server by running perl soap-ser.pl
Then start the client by running perl soap-cli.pl

I get following output & error from soap-cli.pl

E:\temp>perl soap-cli.pl OBJ-State:$VAR1 = bless( { '_signature' => [], '_value' => [ bless( { 'size' => '20' }, 'DemoService' ) ], '_attr' => {} }, 'SOAP::Data' ); Size is ::45 New-OBJ-State:$VAR1 = bless( { '_name' => undef, '_signature' => [ 'DemoService∟DemoService' ], '_value' => [ \bless( { '_signature' => [], '_value' => [ bless( { '_nam +e' => 'size', '_sig +nature' => [], '_val +ue' => [ + '45' + ], '_pre +fix' => '', '_att +r' => { + 'xsi:type' => 'xsd:int', + '{http://www.w3.org/2001/XMLSchema-instance}type' => '{http:/ +/ www.w3.org/2001/XMLSchema}int' + } }, 'SOA +P::Data' ) ], '_attr' => {} }, 'SOAP::Data' ) ], '_attr' => {} }, 'SOAP::Data' ); ERROR: soap:Server, Can't use string ("DemoService") as a HASH ref wh +ile "strict refs" in use at accessor DemoService::size (defined at so +a p-ser.pl line 8) line 3. E:\temp>

I am using ActivePerl 5.14 (x86), SOAP::Lite 0.715

What am I doing wrong?

Thanks & Regards,
Bakkiaraj M
My Perl Gtk2 technology demo project - http://code.google.com/p/saaral-soft-search-spider/ , contributions are welcome.

Replies are listed 'Best First'.
Re: Who is scrambling my SOAP (Moose) object?
by thomas895 (Deacon) on Oct 15, 2012 at 05:35 UTC

    A quick skimming of the docs for SOAP::Lite reveal that ->uri() is deprecated, yet oddly the authour uses it anyways. Perhaps you should try the alternative suggested, by using ->ns() or ->default_ns()?
    Also, judging by the reviews, this module is not one of the best. Of course, you shouldn't use that as your only deciding factor, but you might want to consider it when choosing a module for a purpose.

    I apologise if that does not work, I know next to nothing about SOAP.

    ~Thomas~
    confess( "I offer no guarantees on my code." );

      Hi Thomas

      Thanks for the information. Can you please suggest some other SOAP modules which works better with Moose? As far my studies with CPAN, I could see SOAP::Lite is the easy & better documented. (http://cookbook.soaplite.com/).

      As you suggested, I tried with changing uri() with ns() but that did not solve the issue. Looks like I am doing some more mistakes.

      Thanks & Regards,
      Bakkiaraj M
      My Perl Gtk2 technology demo project - http://code.google.com/p/saaral-soft-search-spider/ , contributions are welcome.

Re: Who is scrambling my SOAP (Moose) object?
by tobyink (Canon) on Oct 15, 2012 at 08:06 UTC

    The server end appears to be interpreting the size call as:

    DemoService->size($object, 20)

    instead of:

    $object->size(20)

    How to fix it, I'm not sure. Most of my SOAP experience has been at the client end.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: Who is scrambling my SOAP (Moose) object?
by Anonymous Monk on Oct 15, 2012 at 14:51 UTC
    Your service should not be a Moose object (not isa) it should have-a Moose object

      Hi

      Thanks. I got the idea. I have to create a wrapper simple module, which will create moose objects and return them.So I don't need to worry about OO interface with SOAP. Correct?

      Thanks & Regards,
      Bakkiaraj M
      My Perl Gtk2 technology demo project - http://code.google.com/p/saaral-soft-search-spider/ , contributions are welcome.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (2)
As of 2024-04-19 18:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found