=head1 NAME

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

=head1 INHERITANCE

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

=head1 SYNOPSIS

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

 # 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...);

=head1 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)

=over 4

=item .

L<XML::Compile::SOAP::HTTPDaemon|XML::Compile::SOAP::HTTPDaemon>, for transport over HTTP.

=back

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
L<XML::Compile::SOAP::Daemon|XML::Compile::SOAP::Daemon> distribution package.  It is really worth
the time.

=head1 METHODS

=head2 Constructors

XML::Compile::SOAP::Daemon-E<gt>B<new>(OPTIONS)

=over 4

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

Any daemon configuration parameter should be passed with L<run()|XML::Compile::SOAP::Daemon/"Running the server">.  This
is a little tricky.  Read below in the L</Configuration options> section.

 Option            --Default
 accept_slow_select  <true>
 based_on            <internal Net::Server::PreFork>
 output_charset      'UTF-8'
 soap_action_input   {}
 wsa_action_input    {}
 wsa_action_output   {}

. accept_slow_select => BOOLEAN

=over 4

Traditional SOAP does not have a simple way to find-out which operation
is being called. The only way to figure-out which operation is needed,
is by trying all defined operations... until one matches.

Later, people started to use soapAction (which was officially only
for proxies) and then the WSA header extension. Both of them make
it easy to find the right handler one on one.

Disabling C<accept_slow_select> will protect you againts various
forms of DoS-attacks, however is often not possible.

=back

. based_on => Net::Server OBJECT|CLASS

=over 4

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 L<run()|XML::Compile::SOAP::Daemon/"Running the server">.  You may also specify any Net::Server compatible
CLASS name.

=back

. output_charset => STRING

=over 4

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

=back

. soap_action_input => HASH|ARRAY

=over 4

The keys are port names, with as value the related SOAPAction header
field content (without quotes). Often, these SOAPAction fields originate
from the WSDL.

=back

. wsa_action_input => HASH|ARRAY

=over 4

The keys are port names, the values are strings which are used by
clients to indicate which server operation they want to use. Often,
an WSDL contains this information in C<wsaw:Action> attributes; that
info is added to this HASH automatically.

=back

. wsa_action_output => HASH|ARRAY

=over 4

The keys are port names, the values are strings which the server will
add to replies to the client. Often, an WSDL contains this information
in C<wsaw:Action> attributes.

=back

=back

=head2 Attributes

$obj-E<gt>B<addSoapAction>(HASH|PAIRS)

=over 4

Map SOAPAction headers only operations. You do not need to map
explicitly when the info can be derived from the WSDL.

=back

$obj-E<gt>B<addWsaTable>(('INPUT'|'OUTPUT'), [HASH|PAIRS])

=over 4

Map operation name onto respectively server-input or server-output
messages, used for C<wsa:Action> fields in the header. Usually, these
values are automatically taken from the WSDL (but only if the WSA
extension is loaded).

=back

$obj-E<gt>B<outputCharset>

=over 4

The character-set to be used for output documents.

=back

=head2 Running the server

$obj-E<gt>B<process>(CLIENT, XMLIN, REQUEST, ACTION)

=over 4

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).

=back

$obj-E<gt>B<run>(OPTIONS)

=over 4

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

=back

=head2 Preparations

$obj-E<gt>B<addHandler>(NAME, SOAP, CODE)

=over 4

The SOAP value is C<SOAP11>, C<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.

=back

$obj-E<gt>B<operationsFromWSDL>(WSDL, OPTIONS)

=over 4

Compile the operations found in the WSDL object (an
L<XML::Compile::WSDL11|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

=over 4

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 is
addressing the port (this is a guess). See L</Operation handlers>

=back

. default_callback => CODE

=over 4

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 L</Operation handlers>

=back

=back

=head2 Helpers

$obj-E<gt>B<faultInvalidXML>(ERROR)

=over 4

=back

$obj-E<gt>B<faultNotSoapMessage>(NODETYPE)

=over 4

=back

$obj-E<gt>B<faultUnsupportedSoapVersion>(ENV_NS)

=over 4

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

=back

$obj-E<gt>B<handlers>(('SOAP11'|'SOAP12'|SOAP))

=over 4

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";
     }
 }

=back

$obj-E<gt>B<printIndex>([FILEHANDLE])

=over 4

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

=back

$obj-E<gt>B<soapVersions>

=over 4

=back

=head1 DETAILS

=head2 Configuration options

This module will wrap any kind of Net::Server, for instance a
Net::Server::PreFork.  It depends on the type of C<Net::Server>
you specify (see L<new(based_on)|XML::Compile::SOAP::Daemon/"Constructors">) which conifguration options are
available on the command-line, in a configuration file, or with L<run()|XML::Compile::SOAP::Daemon/"Running the server">.
Each daemon extension implementation will add some configuration options
as well.

Any C<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

=head3 logging

An attempt is made to merge XML::Compile's Log::Report and Net::Server
log configuration.  By hijacking the C<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 C<Sys::Syslog> or a filename, default dispatchers of type
SYSLOG resp FILE are created for you.  When the C<log_file> type is set to
C<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)

=head3 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 C<$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.

=head3 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 C<_RETURN_CODE> and C<_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.

=head3 Returning private errors

In a WSDL, we can specify own fault types. These defined elements descripe
the C<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 C<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!' }
       }
   };

=head1 SEE ALSO

This module is part of XML-Compile-SOAP-Daemon distribution version 2.04,
built on November 01, 2010. Website: F<http://perl.overmeer.net/xml-compile/>

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

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

=head1 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 F<http://www.perl.com/perl/misc/Artistic.html>

