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:
local machine (directly to backend server without involving frontend, i.e. originating from the same address space and using http://localhost:8080 or https://localhost:8443 as Parallels Business Automation - Standard XML API Gate proxy URL).remote machines (using frontend for proxying requests to backend).Safe packages and methods:
local requests: all packages are considered safe and all their methods are publicAuthentication and sessions handling:
local requests: authentication by password is possible, but not required, authentication is possible by account number only,remote requests: authentication by password is required.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:
HSPC::API:: prefix and have its version set:our $VERSION = 1.0;
$ENV{session} is valid only for requests including session ID returned by session_open() call, i.e. could be valid for local and always valid for remote requests;$ENV{security_obj} is valid only for requests including session ID and contains valid account and user IDs identified by call to session_open();die with error message to immediately return it in SOAP fault envelope with message as description, using the call like this:## 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}"); ?>