XML-RPC Gateway Interface

ISIS-NBP has a XML-RPC server implementation to the basic database operations (CRUD).

The server supports introspection to provide metadata to the client. The client does so by invoking the special methods "system.listMethods" and "system.methodHelp".

URL: http://127.0.0.1:8080/web/xmlrpc/

Sample XML Functions

Create new database
<?xml version='1.0'?>
 <methodCall>
  <methodName>createDB</methodName>
   <params>
    <param>
     <value>
      <struct>
       <member>
        <name>collection</name>
        <value><string>sample</string></value>
       </member>
       <member>
        <name>database</name>
        <value><string>dbtest</string></value>
       </member>
      </struct>
    </value>
   </param>
  </params>
</methodCall>

Create new record
<?xml version='1.0'?>
 <methodCall>
  <methodName>createRecord</methodName>
   <params>
    <param>
     <value>
      <struct>
       <member>
        <name>collection</name>
        <value><string>sample</string></value>
       </member>
       <member>
        <name>database</name>
        <value><string>dbtest</string></value>
       </member>
       <member>
        <name>26</name>
        <value><string>^aParis^bUnesco^c-1965</string></value>
       </member>
       <member>
        <name>30</name>
        <value><string>^ap. 211-224^billus.</string></value>
       </member>
       <member>
        <name>50</name>
        <value><string>Incl. bibl.</string></value>
       </member>
      </struct>
    </value>
   </param>
  </params>
 </methodCall>

Delete database
<?xml version='1.0'?>
 <methodCall>
  <methodName>deleteDB</methodName>
   <params>
    <param>
     <value>
      <struct>
       <member>
        <name>collection</name>
        <value><string>sample</string></value>
       </member>
       <member>
        <name>database</name>
        <value><string>dbtest</string></value>
       </member>
      </struct>
     </value>
    </param>
  </params>
 </methodCall>

Delete record
<?xml version='1.0'?>
 <methodCall>
  <methodName>deleteRecord</methodName>
   <params>
    <param>
     <value>
      <struct>
       <member>
        <name>collection</name>
        <value><string>sample</string></value>
       </member>
       <member>
        <name>database</name>
        <value><string>dbtest</string></value>
       </member>
       <member>
        <name>mfn</name>
        <value><int>2</int></value>
       </member>
      </struct>
     </value>
    </param>
   </params>
 </methodCall>

Read record
<?xml version='1.0'?>
 <methodCall>
  <methodName>readRecord</methodName>
   <params>
    <param>
     <value>
      <struct>
       <member>
        <name>collection</name>
        <value><string>sample</string></value>
       </member>
       <member>
        <name>database</name>
        <value><string>dbtest</string></value>
       </member>
       <member>
        <name>from</name>
        <value><string>1</string></value>
       </member>
       <member>
        <name>to</name>
        <value><string>2</string></value>
       </member>
       <member>
        <name>count</name>
        <value><string>2</string></value>
       </member>
       <member>
        <name>gizmo</name>
        <value><string>gunima</string></value>
       </member>
       <member>
        <name>reverse</name>
        <value><string>on</string></value>
       </member>
      </struct>
     </value>
    </param>
   </params>
  </methodCall>

Update record
<?xml version='1.0'?>
 <methodCall>
  <methodName>updateRecord</methodName>
   <params>
    <param>
     <value>
      <struct>
       <member>
        <name>collection</name>
        <value><string>sample</string></value>
       </member>
       <member>
        <name>database</name>
        <value><string>dbtest</string></value>
       </member>
       <member>
        <name>mfn</name>
        <value><int>1</int></value>
       </member>
       <member>
        <name>26</name>
        <value><string>^aParis^bUnesco^c-1965</string></value>
       </member>
       <member>
        <name>30</name>
        <value><string>^ap. 211-224^billus.</string></value>
       </member>
       <member>
        <name>50</name>
        <value><string>Incl. bibl.</string></value>
       </member>
      </struct>
    </value>
   </param>
  </params>
 </methodCall>

Below there are some client implementations in JAVA, PHP and Python.
Java client with basic CRUD operations using Apache XML-RPC implementation.

package br.com.gpr.javaclient;

import java.util.HashMap;
import java.net.URL;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
import org.apache.xmlrpc.*;

public class JavaClient {

    private final static String server_url =
        "http://127.0.0.1:8000/web/xmlrpc/";
    
    static String result;
    
    public static void main (String [] args) {
        try {
        	
            XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
            config.setServerURL(new URL(server_url));
            XmlRpcClient client = new XmlRpcClient();
            client.setConfig(config);
            
            HashMap<String, String> params = new HashMap<String, String>();
            params.put("collection", "sample");
            params.put("database", "dbtest");
            
            Object[] params1 = new Object[]{params};
            result = (String) client.execute("deleteDB", params1);
            System.out.println("deleteDB >>: " + result);

            result = (String) client.execute("createDB", params1);            
            System.out.println("createDB >>: " + result);

            createRecord(client);
            updateRecord(client);
            deleteRecord(client);
            readRecord(client);

            
        } catch (XmlRpcException exception) {
            System.err.println("JavaClient: XML-RPC Fault #" +
                               Integer.toString(exception.code) + ": " +
                               exception.toString());
        } catch (Exception exception) {
            System.err.println("JavaClient: " + exception.toString());
        }
    }
    
    public static void createRecord(XmlRpcClient client){

    	try{
    		
	        HashMap<String, String> params = new HashMap<String, String>();
	        params.put("collection", "sample");
	        params.put("database", "dbtest");
	        params.put("24","Techniques for the measurement of transpiration of individual plants");
	        params.put("26","^aParis^bUnesco^c-1965");
	        params.put("30","^ap. 211-224^billus.");
	        params.put("44","Methodology of plant eco-physiology: proceedings of the Montpellier Symposium");
	        params.put("50","Incl. bibl.");
	        params.put("69","Paper on: <plant physiology><plant transpiration><measurement and instruments>");
	        params.put("70","Magalhaes, A.C. Franco, C.M.");
	        
	        Object[] params1 = new Object[]{params};
	        result = (String) client.execute("createRecord", params1);
	        System.out.println("createRecord >>: " + result);
 
    	} catch (XmlRpcException exception) {
    		System.err.println("JavaClient: XML-RPC Fault #" +
                           		Integer.toString(exception.code) + ": " +
                           		exception.toString());
    	} catch (Exception exception) {
    		System.err.println("JavaClient: " + exception.toString());
    	}
        
    }

    public static void updateRecord(XmlRpcClient client){

    	try{
    		
	        HashMap<String, String> params = new HashMap<String, String>();
	        params.put("collection", "sample");
	        params.put("database", "dbtest");
	        params.put("24","XXXTechniques for the measurement of transpiration of individual plants");
	        params.put("26","^aXXXParis^bXXXUnesco^cXXX-1965");
	        params.put("30","^aXXXp. 211-224^bXXXillus.");
	        params.put("44","XXXMethodology of plant eco-physiology: proceedings of the Montpellier Symposium");
	        params.put("50","XXXIncl. bibl.");
	        params.put("69","XXXPaper on: <plant physiology><plant transpiration><measurement and instruments>");
	        params.put("70","XXXMagalhaes, A.C. Franco, C.M.");
	        params.put("mfn","1");
	        	        
	        Object[] params1 = new Object[]{params};
	        result = (String) client.execute("updateRecord", params1);
	        System.out.println("updateRecord >>: " + result);
 
    	} catch (XmlRpcException exception) {
    		System.err.println("JavaClient: XML-RPC Fault #" +
                           		Integer.toString(exception.code) + ": " +
                           		exception.toString());
    	} catch (Exception exception) {
    		System.err.println("JavaClient: " + exception.toString());
    	}
        
    }

    public static void deleteRecord(XmlRpcClient client){

    	try{
    		
	        HashMap<String, String> params = new HashMap<String, String>();
	        params.put("collection", "sample");
	        params.put("database", "dbtest");
	        params.put("mfn","1");
	        
	        Object[] params1 = new Object[]{params};
	        result = (String) client.execute("deleteRecord", params1);
	        System.out.println("deleteRecord >>: " + result);
 
    	} catch (XmlRpcException exception) {
    		System.err.println("JavaClient: XML-RPC Fault #" +
                           		Integer.toString(exception.code) + ": " +
                           		exception.toString());
    	} catch (Exception exception) {
    		System.err.println("JavaClient: " + exception.toString());
    	}
    }    
    
    public static void readRecord(XmlRpcClient client){

    	try{
    		
	        HashMap<String, String> params = new HashMap<String, String>();
	        params.put("collection", "sample");
	        params.put("database", "dbtest");
	        params.put("mfn","1");
	        
	        Object[] params1 = new Object[]{params};
	        result = (String) client.execute("readRecord", params1);
	        System.out.println("readRecord >>: " + result);
 
    	} catch (XmlRpcException exception) {
    		System.err.println("JavaClient: XML-RPC Fault #" +
                           		Integer.toString(exception.code) + ": " +
                           		exception.toString());
    	} catch (Exception exception) {
    		System.err.println("JavaClient: " + exception.toString());
    	}
    }    
    
    
}

Source: http://reddes.bvsaude.org/projects/isisnbp/browser/isisnbp-poc/trunk/pyisis/pyisis/web/client/xmlrpc/java/src/br/com/gpr/javaclient/JavaClient.java.

This sample for PHP 5 uses library XML-RPC for PHP.

<html>
<head><title>xmlrpc</title></head>
<body>
<h1>XMLRPC Client PHP-5</h1>
<h2>CRUD Operations - ISIS-NBP</h2>

<?php
    include("xmlrpc.inc");

    function prtsend($func){
 	print "<pre>Sending the following request:\n\n" . htmlentities($func->serialize()) . "\n\nDebug info of server data follows...\n\n";
    }

    function prtresult($result) {

	if(!$result->faultCode()) {
		$v=$result->value();
		print "</pre><br/><< ". htmlspecialchars($v->scalarval()) . "<br/>";
	} else {
		print "Error! Code: " . htmlspecialchars($r->faultCode())
			. " Reason: '" . htmlspecialchars($r->faultString()) . "'</pre><br/>";
	}
    }

    if(!isset($HTTP_POST_VARS) && isset($_POST)) {
		$HTTP_POST_VARS = $_POST;
    }

    $c=new xmlrpc_client("/web/xmlrpc/", "192.168.0.21", 8000);
    $c->setDebug(0);
	
    $database = new xmlrpcval(
       array (
	'collection' => new xmlrpcval('sample','string'),
	'database'  => new xmlrpcval('phpdb','string')
       ),'struct'); 

    //Delete Database
    $f=new xmlrpcmsg('deleteDB',array(php_xmlrpc_encode($database)));
    prtsend($f);
    $r=&$c->send($f);
    prtresult($r);
	
    //Create Database
    $f=new xmlrpcmsg('createDB',array(php_xmlrpc_encode($database)));
    prtsend($f);
    $r=&$c->send($f);
    prtresult($r);

    $database = new xmlrpcval(
       array (
	'collection' => new xmlrpcval('sample','string'),
	'database' => new xmlrpcval('phpdb','string'),
	'24' => new xmlrpcval('Techniques for the measurement of transpiration of individual plants','string'),
	'26' => new xmlrpcval('^aParis^bUnesco^c-1965','string'),
	'30' => new xmlrpcval('^ap. 211-224^billus.','string'),
	'44' => new xmlrpcval('Methodology of plant eco-physiology: proceedings of the Montpellier Symposium','string'),
	'50' => new xmlrpcval('Incl. bibl.','string'),
	'69' => new xmlrpcval('Paper on: <plant physiology><plant transpiration><measurement and instruments>','string'),
	//subfiled
	'70' => new xmlrpcval(
			array (
			        new xmlrpcval('Magalhaes, A.C','string'),
			        new xmlrpcval('Franco, C.M.','string')
			), 'array'),
       ),'struct'); 


    //Create Record
    $f=new xmlrpcmsg('createRecord',array(php_xmlrpc_encode($database)));
    prtsend($f);
    $r=&$c->send($f);
    prtresult($r);


    $database = new xmlrpcval(
       array (
	'collection' => new xmlrpcval('sample','string'),
	'database' => new xmlrpcval('phpdb','string'),
	'24' => new xmlrpcval('XXX Techniques for the measurement of transpiration of individual plants','string'),
	'26' => new xmlrpcval('^aXXX Paris^bXXX Unesco^cXXX -1965','string'),
	'30' => new xmlrpcval('^aXXX p. 211-224^b XXXillus.','string'),
	'44' => new xmlrpcval('XXX Methodology of plant eco-physiology: proceedings of the Montpellier Symposium','string'),
	'50' => new xmlrpcval('XXX Incl. bibl.','string'),
	'69' => new xmlrpcval('XXX Paper on: <plant physiology><plant transpiration><measurement and instruments>','string'),
	//subfield
	'70' => new xmlrpcval(
			array (
			        new xmlrpcval('XXX Magalhaes, A.C','string'),
			        new xmlrpcval('XXX Franco, C.M.','string')
			), 'array'),
	'mfn' => new xmlrpcval(1,'int')
       ),'struct'); 

    //Update Record
    $f=new xmlrpcmsg('updateRecord',array(php_xmlrpc_encode($database)));
    prtsend($f);
    $r=&$c->send($f);
    prtresult($r);


    $database = new xmlrpcval(
       array (
	'collection' => new xmlrpcval('sample','string'),
	'database' => new xmlrpcval('phpdb','string'),
	'mfn' => new xmlrpcval(1,'int')
       ),'struct'); 

    //Delete Record
    $f=new xmlrpcmsg('deleteRecord',array(php_xmlrpc_encode($database)));
    prtsend($f);
    $r=&$c->send($f);
    prtresult($r);


    $database = new xmlrpcval(
       array (
	'collection' => new xmlrpcval('sample','string'),
	'database' => new xmlrpcval('phpdb','string'),
	'from' => new xmlrpcval(1,'int'),
	'to' => new xmlrpcval(1,'int'),
	'count' => new xmlrpcval(1,'int'),
	'reverse' => new xmlrpcval('off','string'),
	'gizmo' => new xmlrpcval('gunima','string')
       ),'struct'); 

    //Read Record
    $f=new xmlrpcmsg('readRecord',array(php_xmlrpc_encode($database)));
    prtsend($f);
    $r=&$c->send($f);
    prtresult($r);

?>
<hr/>
</body>
</html>

Source: http://reddes.bvsaude.org/projects/isisnbp/browser/isisnbp-poc/trunk/pyisis/pyisis/web/client/xmlrpc/php/xmlrpc-client.php.

And simple Python implementation

# -*- coding: utf-8 -*-
"""
This module implements tests to XML-RPC.
"""
__created__ = "2008-08-28"
__author__  = "Joao Chaves <joaochaves@gpr.com.br>"

import sys
import xmlrpclib

IPADDR= 'localhost'
PORT  = 8000

dbname = sys.argv[1]

rpc_srv = xmlrpclib.ServerProxy("http://%s:%d/web/xmlrpc/"%(IPADDR,PORT),verbose=False)

params = {'collection':'sample','database':dbname}
print '\n'+'-'*10,' DELETE DB ','-'*10;print rpc_srv.deleteDB(params)
print '\n'+'-'*10,' CREATE DB ','-'*10;print rpc_srv.createDB(params)

params['24'] = 'Techniques for the measurement of transpiration of individual plants'
params['26'] = '^aParis^bUnesco^c-1965'
params['30'] = '^ap. 211-224^billus.'
params['44'] = 'Methodology of plant eco-physiology: proceedings of the Montpellier Symposium'
params['50'] = 'Incl. bibl.'
params['69'] = 'Paper on: <plant physiology><plant transpiration><measurement and instruments>'
params['70'] = ('Magalhaes, A.C.','Franco, C.M.')
print '\n'+'-'*10,' CREATE RECORD 1 ','-'*10;print rpc_srv.createRecord(params)
print '\n'+'-'*10,' CREATE RECORD 2 ','-'*10;print rpc_srv.createRecord(params)

params['24'] = 'xxxTechniques for the measurement of transpiration of individual plants'
params['26'] = 'xxx^aParis^bUnesco^c-1965'
params['30'] = 'xxx^ap. 211-224^billus.'
params['44'] = 'xxxMethodology of plant eco-physiology: proceedings of the Montpellier Symposium'
params['50'] = 'xxxIncl. bibl.'
params['69'] = 'xxxPaper on: <plant physiology><plant transpiration><measurement and instruments>'
params['70'] = 'xxxMagalhaes, A.C.'
params['mfn'] = 1
print '\n'+'-'*10,' UPDATE RECORD 1 ','-'*10;print rpc_srv.updateRecord(params)

params = {'collection': 'sample','database': dbname,'mfn': 2}
print '\n'+'-'*10,' DELETE RECORD 2 ','-'*10;print rpc_srv.deleteRecord(params)

params = {'collection': 'sample'}
for k,v in [('database',dbname),('from','1'),('to','1'),('count','2'),
            ('gizmo','gunima'),('reverse','on')]:
    params[k] = v
    print '\n'+'-'*10,' READ RECORD %s,%s'%(k,v),'-'*10;
    print rpc_srv.readRecord(params)
    print

print '\nIntrospection'
print "-"*40
methods = rpc_srv.system.listMethods()
#print methods
for method in methods:
    if method.startswith('system'): continue
    print rpc_srv.system.methodHelp(method)+'\n'

Note: Use the system.listMethods and system.methodHelp to introspection.

Source: http://reddes.bvsaude.org/projects/isisnbp/browser/isisnbp-poc/trunk/pyisis/pyisis/web/client/xmlrpc/python/xmlrpc_test.py.

Server Source: http://reddes.bvsaude.org/projects/isisnbp/browser/isisnbp-poc/trunk/pyisis/pyisis/web/isis/xmlrpc.py

References:
http://www.xmlrpc.com/spec
http://ws.apache.org/xmlrpc/
http://phpxmlrpc.sourceforge.net/