[Catalyst-commits] r7546 - in Catalyst-Controller-SOAP/1.0/trunk: . lib/Catalyst/Action/SOAP lib/Catalyst/Controller lib/Catalyst/Controller/SOAP t t/PostApp/lib/PostApp/Controller

ruoso at dev.catalyst.perl.org ruoso at dev.catalyst.perl.org
Wed Apr 2 12:23:39 BST 2008


Author: ruoso
Date: 2008-04-02 12:23:38 +0100 (Wed, 02 Apr 2008)
New Revision: 7546

Added:
   Catalyst-Controller-SOAP/1.0/trunk/t/PostApp/lib/PostApp/Controller/WithWSDL2.pm
   Catalyst-Controller-SOAP/1.0/trunk/t/hello2.wsdl
Modified:
   Catalyst-Controller-SOAP/1.0/trunk/MANIFEST
   Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Action/SOAP/DocumentLiteral.pm
   Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Action/SOAP/RPCEndpoint.pm
   Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Controller/SOAP.pm
   Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Controller/SOAP/RPC.pm
   Catalyst-Controller-SOAP/1.0/trunk/t/PostApp.t
   Catalyst-Controller-SOAP/1.0/trunk/t/PostApp/lib/PostApp/Controller/WS.pm
Log:
[C-C-SOAP] Better support for RPC messages, tests including an example of a RPC-Literal service, exception catching generating a SOAP Fault.

Modified: Catalyst-Controller-SOAP/1.0/trunk/MANIFEST
===================================================================
--- Catalyst-Controller-SOAP/1.0/trunk/MANIFEST	2008-04-01 17:22:29 UTC (rev 7545)
+++ Catalyst-Controller-SOAP/1.0/trunk/MANIFEST	2008-04-02 11:23:38 UTC (rev 7546)
@@ -5,6 +5,7 @@
 README
 t/Catalyst-Controller-SOAP.t
 t/hello.wsdl
+t/hello2.wsdl
 t/PostApp.t
 t/lib/TestApp/Controller/WS.pm
 t/lib/TestApp/Controller/Root.pm
@@ -14,6 +15,7 @@
 t/PostApp/script/post.pl
 t/PostApp/script/postapp_server.pl
 t/PostApp/lib/PostApp/Controller/WithWSDL.pm
+t/PostApp/lib/PostApp/Controller/WithWSDL2.pm
 t/PostApp/lib/PostApp/Controller/WS.pm
 t/PostApp/lib/PostApp/Controller/Root.pm
 t/PostApp/lib/PostApp/Controller/WS2.pm

Modified: Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Action/SOAP/DocumentLiteral.pm
===================================================================
--- Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Action/SOAP/DocumentLiteral.pm	2008-04-01 17:22:29 UTC (rev 7545)
+++ Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Action/SOAP/DocumentLiteral.pm	2008-04-02 11:23:38 UTC (rev 7546)
@@ -14,11 +14,20 @@
           my ($body) = $envelope->getElementsByTagNameNS($namespace, 'Body');
           my $operation = $self->name;
           $c->stash->{soap}->operation_name($operation);
-          if ($controller->wsdlobj) {
-              $body = $c->stash->{soap}->arguments
-                ($controller->decoders->{$operation}->($body));
+          eval {
+              if ($controller->wsdlobj) {
+                  $body = $c->stash->{soap}->arguments
+                    ($controller->decoders->{$operation}->($body));
+              }
+          };
+          if ($@) {
+              $c->stash->{soap}->fault
+                ({ code => [ 'env:Sender' => 'env:Body' ],
+                   reason => 'Bad Body', detail =>
+                   'Schema validation on the body failed.'});
+          } else {
+              $self->NEXT::execute($controller, $c, $body);
           }
-          $self->NEXT::execute($controller, $c, $body);
       }
   }
 };

Modified: Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Action/SOAP/RPCEndpoint.pm
===================================================================
--- Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Action/SOAP/RPCEndpoint.pm	2008-04-01 17:22:29 UTC (rev 7545)
+++ Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Action/SOAP/RPCEndpoint.pm	2008-04-02 11:23:38 UTC (rev 7546)
@@ -1,7 +1,9 @@
 { package Catalyst::Action::SOAP::RPCEndpoint;
 
+  use strict;
   use base qw/Catalyst::Action::SOAP/;
   use constant NS_SOAP_ENV => "http://schemas.xmlsoap.org/soap/envelope/";
+  use UNIVERSAL;
 
   sub execute {
       my $self = shift;
@@ -13,34 +15,50 @@
           my $envelope = $c->stash->{soap}->parsed_envelope;
           my $namespace = $c->stash->{soap}->namespace || NS_SOAP_ENV;
           my ($body) = $envelope->getElementsByTagNameNS($namespace,'Body',0);
-          my @children = $body->getChildNodes();
+          my @children = grep { UNIVERSAL::isa( $_, 'XML::LibXML::Element') } $body->getChildNodes();
           if (scalar @children != 1) {
               $c->stash->{soap}->fault
-                ({ code => { 'env:Sender' => 'env:Body' },
+                ({ code => [ 'env:Sender' => 'env:Body' ],
                    reason => 'Bad Body', detail =>
                    'RPC messages should contain only one element inside body'})
             } else {
-                my ($smthing, $operation) = split /:/, $children[0]->nodeName();
+                my $rpc_element = $children[0];
+                my ($smthing, $operation) = split /:/, $rpc_element->nodeName();
                 $operation ||= $smthing; # if there's no ns prefix,
                                          # operation is the first
                                          # part.
                 $c->stash->{soap}->operation_name($operation);
-                if ($controller->wsdlobj) {
-                    $c->stash->{soap}->arguments
-                      ($controller->decoders->{$operation}->($children[0]));
-                } else {
-                    my $arguments = $children[0]->getChildNodes();
-                    $c->stash->{soap}->arguments($arguments);
-                }
-                if (!grep { /RPC(Encoded|Literal)/ } @{$controller->action_for($operation)->attributes->{ActionClass}}) {
+
+                eval {
+                    if ($controller->wsdlobj) {
+                        my $decoder = $controller->decoders->{$operation};
+                        my ($args) = $decoder->($rpc_element);
+                        $c->stash->{soap}->arguments($args);
+                    } else {
+                        my $arguments = $rpc_element->getChildNodes();
+                        $c->stash->{soap}->arguments($arguments);
+                    }
+                };
+                if ($@) {
                     $c->stash->{soap}->fault
-                      ({ code => { 'env:Sender' => 'env:Body' },
-                         reason => 'Bad Operation', detail =>
-                         'Invalid Operation'})
+                      ({ code => [ 'env:Sender' => 'env:Body' ],
+                         reason => 'Bad Body', detail =>
+                         'Malformed parts on the message body'});
                 } else {
-                    # this is our RPC action
-                    $c->forward($operation);
+                    my $action = $controller->action_for($operation);
+
+                    if (!$action ||
+                        !grep { /RPC(Encoded|Literal)/ } @{$action->attributes->{ActionClass}}) {
+                        $c->stash->{soap}->fault
+                          ({ code => [ 'env:Sender' => 'env:Body' ],
+                             reason => 'Bad Operation', detail =>
+                             'Invalid Operation'});
+                    } else {
+                        # this is our RPC action
+                        $c->forward($operation);
+                    }
                 }
+
             }
       }
   }

Modified: Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Controller/SOAP/RPC.pm
===================================================================
--- Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Controller/SOAP/RPC.pm	2008-04-01 17:22:29 UTC (rev 7545)
+++ Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Controller/SOAP/RPC.pm	2008-04-02 11:23:38 UTC (rev 7546)
@@ -1,7 +1,7 @@
 { package Catalyst::Controller::SOAP::RPC;
   use strict;
   use base qw(Catalyst::Controller::SOAP);
-  sub rpc_endpoint :Path('') :SOAP('RPCEndpoint') { };
+  sub rpc_endpoint :Path('') :ActionClass('SOAP::RPCEndpoint') { };
 };
 
 1;

Modified: Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Controller/SOAP.pm
===================================================================
--- Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Controller/SOAP.pm	2008-04-01 17:22:29 UTC (rev 7545)
+++ Catalyst-Controller-SOAP/1.0/trunk/lib/Catalyst/Controller/SOAP.pm	2008-04-02 11:23:38 UTC (rev 7546)
@@ -8,7 +8,7 @@
 
     use constant NS_SOAP_ENV => "http://schemas.xmlsoap.org/soap/envelope/";
 
-    our $VERSION = '0.3';
+    our $VERSION = '0.4';
 
     __PACKAGE__->mk_accessors qw(wsdlobj decoders encoders);
 
@@ -74,6 +74,14 @@
 
         return $self->NEXT::end($c, @_) unless $soap;
 
+        if (scalar @{$c->error}) {
+            $c->stash->{soap}->fault
+              ({ code => [ 'env:Sender' ],
+                 reason => 'Unexpected Error', detail =>
+                 'Unexpected error in the application: '.(join "\n", @{$c->error} ).'!'});
+            $c->error(0);
+        }
+
         my $namespace = $soap->namespace || NS_SOAP_ENV;
         my $response = XML::LibXML->createDocument();
 
@@ -160,7 +168,7 @@
             $codenode->appendChild($subcode);
             $self->_generate_Fault_Code($document, $subcode, $codeValue->[1], $namespace);
         } else {
-            $value->appendText($codeValue);
+            $value->appendText($codeValue) if $codeValue;
             $codenode->appendChild($value);
         }
     }

Modified: Catalyst-Controller-SOAP/1.0/trunk/t/PostApp/lib/PostApp/Controller/WS.pm
===================================================================
--- Catalyst-Controller-SOAP/1.0/trunk/t/PostApp/lib/PostApp/Controller/WS.pm	2008-04-01 17:22:29 UTC (rev 7545)
+++ Catalyst-Controller-SOAP/1.0/trunk/t/PostApp/lib/PostApp/Controller/WS.pm	2008-04-02 11:23:38 UTC (rev 7546)
@@ -25,4 +25,8 @@
     $c->stash->{soap}->literal_return($foo);
 }
 
+sub bar : Local SOAP('DocumentLiteral') {
+    die 'exception leaked by an action';
+}
+
 1;

Added: Catalyst-Controller-SOAP/1.0/trunk/t/PostApp/lib/PostApp/Controller/WithWSDL2.pm
===================================================================
--- Catalyst-Controller-SOAP/1.0/trunk/t/PostApp/lib/PostApp/Controller/WithWSDL2.pm	                        (rev 0)
+++ Catalyst-Controller-SOAP/1.0/trunk/t/PostApp/lib/PostApp/Controller/WithWSDL2.pm	2008-04-02 11:23:38 UTC (rev 7546)
@@ -0,0 +1,16 @@
+package PostApp::Controller::WithWSDL2;
+
+use strict;
+use warnings;
+use base 'Catalyst::Controller::SOAP::RPC';
+
+__PACKAGE__->config->{wsdl} = 't/hello2.wsdl';
+
+sub Greet : SOAP('RPCLiteral') {
+    my ( $self, $c, $args ) = @_;
+    my $who = $args->{who};
+    my $grt = $args->{greeting};
+    $c->stash->{soap}->compile_return({ greeting => $grt.' '.$who.'!' });
+}
+
+1;

Modified: Catalyst-Controller-SOAP/1.0/trunk/t/PostApp.t
===================================================================
--- Catalyst-Controller-SOAP/1.0/trunk/t/PostApp.t	2008-04-01 17:22:29 UTC (rev 7545)
+++ Catalyst-Controller-SOAP/1.0/trunk/t/PostApp.t	2008-04-02 11:23:38 UTC (rev 7546)
@@ -1,4 +1,4 @@
-use Test::More tests => 4;
+use Test::More tests => 8;
 use File::Spec::Functions;
 use HTTP::Response;
 use IPC::Open3;
@@ -31,6 +31,46 @@
   );
 ok($response->content =~ /greeting\>Hello World\!\<\//, 'Literal response: '.$response->content);
 
+$response = soap_xml_post
+  ('/withwsdl2/Greet','
+    <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
+         <Body>
+            <Greet>
+               <who>World</who>
+               <greeting>Hello</greeting>
+            </Greet>
+         </Body>
+    </Envelope>
+  ');
+ok($response->content =~ /greeting[^>]+\>Hello World\!\<\//, 'Literal response: '.$response->content);
+
+$response = soap_xml_post
+  ('/withwsdl2/Greet','
+    <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
+         <Body>
+               <GreetingSpecifier>
+                   <who><Big>W</Big><Small>orld</Small></who>
+                   <greeting>Hello</greeting>
+               </GreetingSpecifier>
+         </Body>
+    </Envelope>
+  ');
+ok($response->content =~ /Fault/, 'Fault on malformed body for RPC-Literal: '.$response->content);
+
+$response = soap_xml_post
+  ('/withwsdl/Greet',
+   '<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"><Body><GreetingSpecifier><name>World</name><greeting>Hello</greeting></GreetingSpecifier></Body></Envelope>'
+  );
+ok($response->content =~ /Fault/, 'Fault on malformed body for Document-Literal: '.$response->content);
+
+$response = soap_xml_post
+  ('/ws/bar',
+   '<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"><Body>World</Body></Envelope>'
+  );
+ok($response->content =~ /Fault/, 'Fault for uncaugh exception: '.$response->content);
+
+
+
 sub soap_xml_post {
     my $path = shift;
     my $content = shift;

Added: Catalyst-Controller-SOAP/1.0/trunk/t/hello2.wsdl
===================================================================
--- Catalyst-Controller-SOAP/1.0/trunk/t/hello2.wsdl	                        (rev 0)
+++ Catalyst-Controller-SOAP/1.0/trunk/t/hello2.wsdl	2008-04-02 11:23:38 UTC (rev 7546)
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions
+    xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
+    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+    xmlns:s="http://www.w3.org/2001/XMLSchema"
+    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+    xmlns:hello="http://example.com/hello"
+    xmlns="http://example.com/hello"
+    targetNamespace="http://example.com/hello">
+
+  <wsdl:types>
+    <s:schema elementFormDefault="qualified" targetNamespace="http://example.com/hello">
+      <s:element minOccurs="0" maxOccurs="1" name="who" type="s:string"/>
+      <s:element minOccurs="0" maxOccurs="1" name="greeting" type="s:string"/>
+    </s:schema>
+  </wsdl:types>
+  <wsdl:message name="AskGreeting">
+    <wsdl:part name="who" element="hello:who"/>
+    <wsdl:part name="greeting" element="hello:greeting"/>
+  </wsdl:message>
+  <wsdl:message name="GiveGreeting">
+    <wsdl:part name="greeting" element="hello:greeting"/>
+  </wsdl:message>
+  <wsdl:portType name="GreetingPort">
+    <wsdl:operation name="Greet">
+      <wsdl:input message="hello:AskGreeting"/>
+      <wsdl:output message="hello:GiveGreeting"/>
+    </wsdl:operation>
+  </wsdl:portType>
+  <wsdl:binding name="GreetingBind" type="hello:GreetingPort">
+    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
+    <wsdl:operation name="Greet">
+      <soap:operation soapAction="http://example.com/" />
+      <wsdl:input>
+        <soap:body use="literal"/>
+      </wsdl:input>
+      <wsdl:output>
+        <soap:body use="literal"/>
+      </wsdl:output>
+    </wsdl:operation>
+  </wsdl:binding>
+  <wsdl:service name="GreetService">
+    <wsdl:port name="GreetPort" binding="hello:GreetingBind">
+      <soap:address location="http://localhost:3000/hello"/>
+    </wsdl:port>
+  </wsdl:service>
+</wsdl:definitions>
\ No newline at end of file




More information about the Catalyst-commits mailing list