NAME

XML::Compile::SOAP::Daemon - SOAP accepting server

INHERITANCE

XML::Compile::SOAP::Daemon is extended by
  XML::Compile::SOAP::HTTPDaemon

SYNOPSIS

#### have a look in the examples directory!
use XML::Compile::SOAP::HTTPDaemon;
use XML::Compile::SOAP11;

# Be warned that the daemon will be Net::Server based, which consumes
# command-line arguments!
my $daemon  = XML::Compile::SOAP::HTTPDaemon->new;

# daemon definitions from WSDL
my $wsdl    = XML::Compile::WSDL11->new(...);
$wsdl->importDefinitions(...); # more schemas
$daemon->operationsFromWSDL($wsdl, callbacks => ...);

# daemon definitions added manually
my $soap11  = XML::Compile::SOAP11::Server->new(schemas => $wsdl->schemas);
my $handler = $soap11->compileHandler(...);
$daemon->addHandler('getInfo', $soap11, $handler);

# see what is defined:
$daemon->printIndex;

# finally, run the server.  This never returns.
$daemon->run(...daemon options...);

DESCRIPTION

This base class implements the common needs between various types of SOAP daemons. As daemon type, you can use any kind of Net::Server implementation.

The following extensions are implemented on the moment: (other are not yet planned to get implemented)

.

XML::Compile::SOAP::HTTPDaemon, for transport over HTTP.

The daemon can handle various kinds of SOAP protocols at the same time, when possible hidden from the user of this module.

If you have a WSDL describing your procedures, then the only thing you have to worry about is adding callbacks for each of the defined ports. Without WSDL, you will need to do more manually, but it is still relatively simple to achieve.

Do not forget to take a look at the extensive example, enclosed in the XML::Compile::SOAP::Daemon distribution package. It is really worth the time.

METHODS

Constructors

XML::Compile::SOAP::Daemon->new(OPTIONS)

    Create the server handler, which extends some class which implements a Net::Server.

    Any daemon configuration parameter should be passed with run(). This is a little tricky. Read below in the "Configuration options" section.

    Option        --Default
    based_on        <internal Net::Server::PreFork>
    output_charset  'UTF-8'

    . based_on => Net::Server OBJECT|CLASS

      You may pass your own Net::Server compatible daemon, if you feel a need to initialize it or prefer an other one. Preferrably, pass configuration settings to run(). You may also specify any Net::Server compatible CLASS name.

    . output_charset => STRING

      The character-set to be used for the output XML document.

Attributes

$obj->outputCharset

    The character-set to be used for output documents.

Running the server

$obj->process(CLIENT, XMLIN, REQUEST, ACTION)

    The XMLIN SOAP-structured message (an XML::LibXML::Element, XML::LibXML::Document, or XML as string), was received from the CLIENT (some extension specific object).

    The full REQUEST is passed in, however its format depends on the kind of server. The ACTION parameter relates to the soapAction header field which may be available in some form.

    Returned is an XML document as answer or a protocol specific ready response object (usually an error object).

$obj->run(OPTIONS)

    See Net::Server subroutine run, but the OPTIONS are passed as list, not as HASH.

Preparations

$obj->addHandler(NAME, SOAP, CODE)

    The SOAP value is SOAP11, SOAP12, or a SOAP server object or and SOAP Operation object. The CODE reference is called with the incoming document (an XML::LibXML::Document) of the received input message.

    In case the handler does not understand the message, it should return undef. Otherwise, it must return a correct answer message as XML::LibXML::Document.

$obj->operationsFromWSDL(WSDL, OPTIONS)

    Compile the operations found in the WSDL object (an XML::Compile::WSDL11). You can add the operations from many different WSDLs into one server, simply by calling this method repeatedly.

    Option          --Default
    callbacks         {}
    default_callback  <produces fault reply>

    . callbacks => HASH

      The keys are the port names, as defined in the WSDL. The values are CODE references which are called in case a message is received which seems to be addressing the port (this is a guess). See "Operation handlers"

    . default_callback => CODE

      When a message arrives which has no explicit handler attached to it, this handler will be called. By default, an "not implemented" fault will be returned. See "Operation handlers"

Helpers

$obj->faultInvalidXML(ERROR)

$obj->faultNotSoapMessage(NODETYPE)

$obj->faultUnsupportedSoapVersion(ENV_NS)

    Produces a text message, because we do not know how to produce an error in a SOAP which we do not understand.

$obj->handlers(('SOAP11'|'SOAP12'|SOAP))

    Returns all the handler names for a certain soap version.

    example:

    foreach my $version (sort $server->soapVersions)
    {   foreach my $action (sort $server->handlers($version))
        {  print "$version $action\n";
        }
    }

$obj->printIndex([FILEHANDLE])

    Print a table which shows the messages that the server can handle, by default to STDOUT.

$obj->soapVersions

DETAILS

Configuration options

This module will wrap any kind of Net::Server, for instance a Net::Server::PreFork. It depends on the type of Net::Server you specify (see new(based_on)) which conifguration options are available on the command-line, in a configuration file, or with run(). Each daemon extension implementation will add some configuration options as well.

Any XML::Compile::SOAP::Daemon object will have the following additional configuration options:

Key          Value                            Default
# there will be some, I am sure of it.

Some general configuration options of Net::Server have a different default. See also the next section about logging.

Key          Value                            New default
setsid       boolean                          true
background   boolean                          true

logging

An attempt is made to merge XML::Compile's Log::Report and Net::Server log configuration. By hijacking the log() method, all Net::Server internal errors are dispatched over the Log::Report framework. Log levels are translated into report reasons: 0=ERROR, 1=WARNING, 2=NOTICE, 3=INFO, 4=TRACE.

When you specify Sys::Syslog or a filename, default dispatchers of type SYSLOG resp FILE are created for you. When the log_file type is set to Log::Report, you have much more control over the process, but all log related configuration options will get ignored. In that case, you must have initialized the dispatcher framework the way Log::Report is doing it: before the daemon is initiated. See Log::Report subroutine dispatcher.

Key          Value                            Default
log_file     filename|Sys::Syslog|Log::Report Log::Report
log_level    0..4 | REASON                    2 (NOTICE)

Operation handlers

Per operation, you define a callback which handles the request. There can also be a default callback for all your operations. Besides, when an operation does not have a handler defined, one is created for you.

sub my_callback($$)
{   my ($soap, $data_in) = @_;

    return $data_out;
}

The $data_out is a nested HASH which will be translated in the right XML structure. This could be a Fault, like shown in the next section.

Please take a look at the scripts in the example directory within the distribution.

Returning general errors

To have a handler return an error, leave the callback with something like this:

use XML::Compile::Util        qw/pack_type/;

sub my_callback($$)
{   my ($soap, $data) = @_;

    my $code = pack_type $my_err_ns, 'error-code';

    return
     +{ Fault =>
         { faultcode   => $code
         , faultstring => 'something is wrong'
         , faultactor  => $soap->role
         }
      , _RETURN_CODE => 404
      , _RETURN_TEXT => 'sorry, not found'
      };
}

Fault codes are "prefix:error-name", XML::Compile finds the right prefix based on the URI. If your error namespace is not mentioned in the WSDL or other loaded schemas, you should use XML::Compile::WSDL11 subroutine prefixes first.

SOAP uses error codes in the SOAPENV namespace. It shows whether errors are client or server side. This is produced like:

use XML::Compile::SOAP::Util 'SOAP11ENV';
$code = pack_type SOAP11ENV, 'Server.validationFailed';

[release 2.02] Fields _RETURN_CODE and _RETURN_TEXT can be used to change the HTTP response (and maybe other protocol headers in the future). These can also be used with valid answers, not limited to errors. There is no clear definition how SOAP faults and HTTP return codes should work together for user errors.

Returning private errors

In a WSDL, we can specify own fault types. These defined elements descripe the detail component of the message.

To return such an error, you have to figure-out how the fault part is named. Often, the name simply is fault. Then, your handle has to return a Fault structure where the detail refers to a HASH with data matching the need for the fault. Example:

return
+{ fault =>   # the name of the fault part, often "fault"
     { faultcode   => pack_type(SOAP11ENV, 'Server')
     , faultstring => 'any-ns.WentWrong'
     , faultactor  => $soap->role
     , detail      => { message => 'Hello, World!' }
     }
 };

SEE ALSO

This module is part of XML-Compile-SOAP-Daemon distribution version 2.03, built on September 30, 2010. Website: http://perl.overmeer.net/xml-compile/

All modules in this suite: XML::Compile, XML::Compile::SOAP, XML::Compile::SOAP12, XML::Compile::SOAP::Daemon, XML::Compile::SOAP::WSA, XML::Compile::Tester, XML::Compile::Cache, XML::Compile::Dumper, XML::Compile::RPC, and XML::Rewrite, XML::eXistDB, XML::LibXML::Simple.

Please post questions or ideas to the mailinglist at http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/xml-compile For life contact with other developers, visit the #xml-compile channel on irc.perl.org.

LICENSE

Copyrights 2007-2010 by Mark Overmeer. For other contributors see ChangeLog.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html