Loading ...
Sorry, an error occurred while loading the content.

WebService client with SOAP::Lite and ComplexType

Expand Messages
  • afafcruz
    Hello all. I m having a similar problem to [id://548716|this]. Unfortunately, I couldn t figure out the solution from the thread. I m calling a Web Service
    Message 1 of 1 , Jul 5, 2006
    View Source
    • 0 Attachment
      Hello all.

      I'm having a similar problem to [id://548716|this]. Unfortunately, I
      couldn't figure out the solution from the thread.

      I'm calling a Web Service method which takes a sole ComplexType argument.

      The output I get is:

      ./complex.pl
      document/literal support is EXPERIMENTAL in SOAP::Lite at
      /usr/local/share/perl/5.8.7/SOAP/Lite.pm line 2818.
      Type 'PublishRequest' can't be found in a schema class 'SOAP::Serializer'

      I'm using SOAP::Data::ComplexType to build the argument.

      Here is the WSDL:
      <?xml version="1.0" encoding="UTF-8"?>
      <definitions
      name="SapoBroker"
      targetNamespace="http://services.mydomain.org/broker"
      xmlns="http://schemas.xmlsoap.org/wsdl/"
      xmlns:typens="http://services.mydomain.org/broker"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema"
      xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

      <types>
      <schema xmlns="http://www.w3.org/2001/XMLSchema"
      targetNamespace="http://services.mydomain.org/broker">

      <complexType name="BrokerMessage">
      <sequence>
      <element name="deliveryMode" type="int" />
      <element name="priority" type="int" />
      <element name="messageId" nillable="true" type="string" />
      <element name="correlationId" nillable="true" type="string" />
      <element name="timestamp" nillable="true" type="string" />
      <element name="expiration" nillable="true" type="string" />
      <element name="destinationName" nillable="true" type="string" />
      <element name="textPayload" nillable="true" type="string" />
      </sequence>
      </complexType>

      <complexType name="EnqueueRequest">
      <sequence>
      <element name="brokerMessage" type="typens:BrokerMessage" />
      </sequence>
      </complexType>


      <complexType name="PublishRequest">
      <sequence>
      <element name="brokerMessage" type="typens:BrokerMessage" />
      </sequence>
      </complexType>


      <element name="EnqueueRequestMessage" type="typens:EnqueueRequest" />
      <element name="PublishRequestMessage" type="typens:PublishRequest" />

      </schema>
      </types>

      <message name="enqueueMessageRequest">
      <part element="typens:EnqueueRequestMessage"
      name="EnqueueRequestMessage" />
      </message>

      <message name="publishMessageRequest">
      <part element="typens:PublishRequestMessage"
      name="PublishRequestMessage" />
      </message>

      <message name="BrokerOut" />

      <portType name="BrokerApi">

      <operation name="enqueue">
      <input message="typens:enqueueMessageRequest"
      name="enqueueMessageRequest" />
      <output message="typens:BrokerOut" name="enqueueOutput" />
      </operation>

      <operation name="publish">
      <input message="typens:publishMessageRequest"
      name="publishMessageRequest" />
      <output message="typens:BrokerOut" name="publishOutput" />
      </operation>

      </portType>

      <binding name="BrokerSoapBinding" type="typens:BrokerApi">
      <soap:binding style="document"
      transport="http://schemas.xmlsoap.org/soap/http" />

      <operation name="enqueue">
      <soap:operation
      soapAction="http://services.mydomain.org/broker/enqueue" />
      <input name="enqueueMessageRequest">
      <soap:body use="literal" />
      </input>
      <output name="enqueueOutput">
      <soap:body use="literal" />
      </output>
      </operation>

      <operation name="publish">
      <soap:operation
      soapAction="http://services.mydomain.org/broker/publish" />
      <input name="publishMessageRequest">
      <soap:body use="literal" />
      </input>
      <output name="publishOutput">
      <soap:body use="literal" />
      </output>
      </operation>

      </binding>

      <service name="BrokerApiService">
      <port binding="typens:BrokerSoapBinding" name="Broker">
      <soap:address location="http://localhost:8000/broker/producer" />
      </port>
      </service>

      </definitions>

      Here are the modules I created to represent a PublishRequest:

      package PublishRequestType;
      use strict;
      use warnings;
      use SOAP::Data::ComplexType;
      use vars qw(@ISA);
      @ISA = qw(SOAP::Data::ComplexType);

      use constant OBJ_URI => 'http://services.mydomain.org/broker';
      use constant OBJ_TYPE => 'ns1:PublishRequest';
      use constant OBJ_FIELDS => {
      PublishRequest => [[ BrokerMessageType_inner::OBJ_TYPE,
      BrokerMessageType_inner::OBJ_FIELDS ],
      BrokerMessageType_inner::OBJ_URI,
      undef ]
      };


      sub new {
      my $proto = shift;
      my $class = ref($proto) || $proto;
      my $data = shift;
      my $obj_fields = shift;
      $obj_fields = defined $obj_fields && ref($obj_fields) eq 'HASH' ?
      {%{$obj_fields}, %{+OBJ_FIELDS}} : OBJ_FIELDS;
      my $self = $class->SUPER::new($data, $obj_fields);
      return bless($self, $class);
      }
      package BrokerMessageType_inner;
      use strict;
      use warnings;
      use SOAP::Data::ComplexType;
      use vars qw(@ISA);
      @ISA = qw(SOAP::Data::ComplexType);

      use constant OBJ_URI => 'http://services.mydomain.org/broker';
      use constant OBJ_TYPE => 'ns1:PublishRequest';
      use constant OBJ_FIELDS => {
      BrokerMessage => [[ BrokerMessageType::OBJ_TYPE,
      BrokerMessageType::OBJ_FIELDS ],
      BrokerMessageType::OBJ_URI,
      undef ]
      };

      sub new {
      my $proto = shift;
      my $class = ref($proto) || $proto;
      my $data = shift;
      my $obj_fields = shift;
      $obj_fields = defined $obj_fields && ref($obj_fields) eq 'HASH' ?
      {%{$obj_fields}, %{+OBJ_FIELDS}} : OBJ_FIELDS;
      my $self = $class->SUPER::new($data, $obj_fields);
      return bless($self, $class);
      }

      package BrokerMessageType;
      use strict;
      use warnings;
      use SOAP::Data::ComplexType;
      use vars qw(@ISA);
      @ISA = qw(SOAP::Data::ComplexType);

      use constant OBJ_URI => 'http://services.mydomain.org/broker';
      use constant OBJ_TYPE => 'ns1:BrokerMessage';
      use constant OBJ_FIELDS => {
      deliveryMode => ['int', undef, undef],
      priority => ['int', undef, undef],
      messageId => ['string', undef, undef],
      correlationId => ['string', undef, undef],
      timestamp => ['string', undef, undef],
      expiration => ['string', undef, undef],
      destinationName => ['string', undef, undef],
      textPayload => ['string', undef, undef],
      };

      sub new {
      my $proto = shift;
      my $class = ref($proto) || $proto;
      my $data = shift;
      my $obj_fields = shift;
      $obj_fields = defined $obj_fields && ref($obj_fields) eq 'HASH' ?
      {%{$obj_fields}, %{+OBJ_FIELDS}} : OBJ_FIELDS;
      my $self = $class->SUPER::new($data, $obj_fields);
      return bless($self, $class);
      }

      And here is the client code I use:

      #!/usr/bin/perl -w

      package main;

      use strict;
      use Data::Dumper;
      use SOAP::Lite +trace => qw( debug );
      use SOAP::Data::ComplexType;
      use BrokerMessageType;
      use BrokerMessageType_inner;
      use PublishRequestType;

      my $WSDL = 'file:///tmp/broker.wsdl';

      my $soap = SOAP::Lite
      -> uri('http://services.mydomain.org/broker')
      -> service($WSDL);

      my $request_obj = PublishRequestType->new
      ({
      PublishRequest => { BrokerMessage => { destinationName => 'blogs',
      textPayload =>
      'TEST' }}
      });

      $soap->publish($request_obj->as_soap_data);

      By the way, $request_obj->as_xml_data prints this:

      <?xml version="1.0" encoding="UTF-8"?>
      <SOAP:ENV
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema"
      xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
      <namesp1:PublishRequest
      xmlns:namesp1="http://services.mydomain.org/broker"
      xsi:type="ns1:PublishRequest">
      <namesp2:BrokerMessage xsi:type="ns1:BrokerMessage"
      xmlns:namesp2="http://services.mydomain.org/broker">
      <destinationName xsi:type="xsd:string">blogs</destinationName>

      <textPayload xsi:type="xsd:string">TEST</textPayload>
      </namesp2:BrokerMessage>
      </namesp1:PublishRequest>
      </SOAP:ENV>
      </code>

      SOAP::Lite::VERSION = 0.67
      SOAP::Data::ComplexType::VERSION = 0.041

      I'm sorry for the long post, but I wanted to give all the needed
      information.

      Thanks for the help.
    Your message has been successfully submitted and would be delivered to recipients shortly.