Introduction to Parallels Business Automation - Standard XML API

Parallels Business Automation - Standard XML API Gate is based on SOAP protocol, currently maintained by World Wide Web Consortium at http://www.w3c.org and supported by most of modern programming languages as framework for messages exchange and remote method calls.

Parallels Business Automation - Standard XML API Gate is implemented as mod_perl handler and inherits from SOAP::Transport::HTTP::Apache, i.e. is based on the functionality provided by SOAP::Lite module available from CPAN. Please, refer to SOAP::Lite documentation for general information and this section provides implementation details and examples.

Module namespaces are package names with '::' included are replaced with '/' - see examples below.

Security

There are two different strategies used by Parallels Business Automation - Standard XML API Gate in defining security requirements:

Safe packages and methods:

Authentication and sessions handling:

Authentication is done with call to session_open() interface in HSPC/API namespace and relies on functionality provided by Security Manager.

Interfaces in HSPC/API namespace:

session_open()

Parameters: account_no, e-mail, password

Performs authentication with given parameters (required for remote requests and optional for local, except account_no or server_name) and initialize session.

If account_no is set to 0, first account which user has roles in is chosen automatically, but in this case e-mail and password must be set as well.

If server_name is passed and account_no is empty or missing, account_no is located by vendor's server name located in server_name parameter.

Returns either unique value to be used as HSPC-SID in next requests (see examples of clients) or SOAP fault envelope with error message.

session_close()

Performs cleanup of session identified by HSPC-SID header.

Returns undef or SOAP fault envelope with error message.

Configuration

Parallels Business Automation - Standard XML API Gate intended for requests from both local and remote machines is pre-configured at /hspc/xml-api location.

backend

/etc/hspcd/conf/hspc_xml-api.conf

<Location /hspc/xml-api>
     SetHandler perl-script
     PerlHandler HSPC::XMLAPI
     Order Allow,Deny
     Allow from all
 </Location>

frontend

/etc/httpd/conf/hspc_frontend.conf:

 <VirtualHost _default_:443>
     ...
     SSLEngine on
     ...
     <Location /hspc/xml-api>
         Order Deny,Allow
         Allow from all
 </VirtualHost>

 <Location /hspc/xml-api>
    Order Deny,Allow
    Deny from all
 </Location>

Security limitation is set by explicitly allowing /hspc/xml-api location for HTTPS connections and denying for HTTP connections, so that plain text SOAP envelopes couldn't be read by intruders.

Parallels Business Automation - Standard XML API Gate could be opened at another locations as well by configuring backend and frontend server in the same way as described above, i.e. by adding more Location blocks to backend and frontend servers' configurations.

Servers

Exported methods of packages providing API through Parallels Business Automation - Standard XML API Gate should rely on the following rules:

our $VERSION = 1.0;
 ## return fault with:
 ## - error code 'ErrorCode'
 ## - error message
 die HSPC::API->fault('ErrorCode', 'Error description.');

Notes for HSPstore:

If error code starts with the User prefix, its description is shown to PHP Store visitor, so it must be localized:

 die HSPC::API->fault('UserPassword', string('passwords_do_not_match'));

If error code does not start with the User prefix, its description is not shown to PHP Store visitor and is only logged to vendor's local log file, so it must not be localized:

 die HSPC::API->fault('AuthenRequired', 'Authentication required.');

feel free to return any data structures that you can theoretically serialize to XML - and do not expect an object to arrive at remote side by just returning its blessed reference (guess why it's just ridiculous).

Examples

HSPC/Test.pm (local requests):

 package HSPC::Test;
 use strict;
 use Data::Dumper;
 ## returns dump of parameters list, including class name
 sub method {
     return Dumper(\@_);
 }
 1;

HSPC/API/Test.pm (remote requests):

 package HSPC::API::Test;
 use strict;
our $VERSION = 1.0;
 ## gets/sets parameter with key passed as a parameter
 sub param {
     my (undef, $key, $value) = @_;
     return defined $value
         ? $ENV{session}->{$key} = $value
         : $ENV{session}->{$key};
 }
 1;

Clients

In order to initialize stable communication with Parallels Business Automation - Standard XML API Gate, first call session_open() in HSPC/API namespace to receive HSPC-SID value and then add HSPC-SID to either HTTP or SOAP headers to each request before sending SOAP envelope.

Examples

local.pl:

 use SOAP::Lite;
 use strict;
 my $result = SOAP::Lite
     ->proxy('http://127.0.0.1:8080/hspc/xml-api') ## Gate URL
     ->ns('HSPC/Test') ## package namespace
     ->method ## method name
         ('param1', {param2 => 'test', param3 => [1, 2, 3]}, 0); ## parameters
 print $result->fault
     ? 'Fault: ' . $result->faultstring
     : 'Result: ' . $result->result;

local.php:

 <?
 require_once('nusoap.php');
 $client = new soap_client('http://127.0.0.1:8080/hspc/xml-api'); // Gate URL
 $result = $client->call(
     'method', // method name
     array ("param1", array ("param2" => "test", "param3" => array (1, 2, 3)), 0), // parameters
     'HSPC/Test' // package namespace
 );
 if ($client->fault)
     die("Fault: {$client->faultstring}");
 echo $result;
 ?>

remote.pl:

 use strict;
 use SOAP::Lite;
 my $client = SOAP::Lite
	 ->proxy('https://192.168.0.100/hspc/xml-api')
	 ->on_fault(sub {die 'Fault: ' . $_[1]->faultstring});
 ## pass authentication and receive session ID 
 my $sid = $client->ns('HSPC/API/1.0')->session_open({
	   email => 'email@provider.com', password => 'password'
 })->result->{session_id};
 ## put session ID to outgoing requests' HTTP headers
 $client->transport->http_request->header('HSPC-SID' => $sid);
 ## make session-dependent calls
 $client->ns('HSPC/API/Test/1.0');
 $client->param('key' => 'value');
 print $client->param('key')->result;
 $client->ns('HSPC/API/1.0')->session_close;

remote.php

<? require_once('nusoap.php');
 $client = new soap_client('https://192.168.0.100/hspc/xml-api'); // Gate URL
 ## pass authentication and receive session ID
 $sid_result = $client->call('session_open', array (
	array ('email' => 'root@provider.com', 'password' => '1q2w3e')
 ), 'HSPC/API/1.0');
 $sid = $sid_result['session_id'];
 if ($client->fault)
	 die("Fault: {$client->faultstring}");
 ## put session ID to outgoing requests' SOAP headers $client->setHeaders("<HSPC-SID>$sid</HSPC-SID>");
 ## make session-dependent calls
 $client->call('param', array ('key', 'value'), 'HSPC/API/Test/1.0');
 if ($client->fault)
	 die("Fault: {$client->faultstring}");
 echo $client->call('param', array ('key'), 'HSPC/API/Test/1.0') . "\n";
 if ($client->fault)
	 die("Fault: {$client->faultstring}");
 $client->call('session_close', undef, 'HSPC/API/1.0');
 if ($client->fault)
	 die("Fault: {$client->faultstring}"); ?>