XML-RPC Integration

Last modified by Thomas Mortagne on 2023/10/10 17:29

cogMakes XWiki accessible using the XML-RPC protocol
TypeOther
CategoryAPI
Developed by

XWiki Development Team

Rating
0 Votes
LicenseGNU Lesser General Public License 2.1
Compatibility

Starting with XWiki 7.3M1, the XML-RPC feature is no longer bundled by default in XWiki Enterprise.

Description

Note that XML-RPC API was deprecated in favour of The XWiki RESTful API, is not enabled by default since 6.4.7, 7.1.4 and 7.3M1, and it's not provided anymore in the default distribution since 7.4M1. It's now available on xwiki-contrib in Github.

For users of XWiki versions < 6.4.7, 7.1.4 and 7.3M1, we highly recommend upgrading or turning off the XML-RPC feature. This can be easily achieved by editing your WEB-INF/web.xml file and commenting the following lines:

...
 <!--filter-mapping>
    <filter-name>XWikiXmlRpcContextInitializationFilter</filter-name>
    <servlet-name>xmlrpc</servlet-name>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>FORWARD</dispatcher>
  </filter-mapping—>
...
  <!--servlet>
    <servlet-name>xmlrpc</servlet-name>
    <servlet-class>com.xpn.xwiki.xmlrpc.XWikiXmlRpcServlet</servlet-class>
    <init-param>
      <description>Sets, whether the servlet supports vendor extensions for XML-RPC.</description>
      <param-name>enabledForExtensions</param-name>
      <param-value>false</param-value>
    </init-param>
  </servlet—>
...
 <!--servlet-mapping>
    <servlet-name>xmlrpc</servlet-name>
    <url-pattern>/xmlrpc/*</url-pattern>
  </servlet-mapping-->

...

However if you still wish to use it, make sure that your wiki is not accessible from the outside world since this feature has an important security vulnerability.

XWiki instances can be accessed remotely using the XML-RPC protocol.

XML-RPC is a remote procedure call (RPC) protocol which uses XML to encode its calls and HTTP as a transport mechanism.
-Wikipedia

XML-RPC makes it easy to build your own 3rd party applications which can connect to your XWiki instances. For example this feature can be helpful to integrate XWiki with other existing Java applications. To be more precise, the XML-RPC feature could be used to provide XWiki functionality to other applications. In such a case, XWiki acts as your content repository accessible directly as well as through your 3rd party applications.

Features

XWiki implements the most important part of the Confluence XML-RPC API.

  • Authenticated and anonymous access
  • Spaces: retrieval, creation and removal
  • Pages: retrieval, rendering, creation, history, update, search and removal
  • Attachments: retrieval(download), creation(upload), moving/renaming, removal
  • Comments: retrieval, creation and removal

The list of functions from the Confluence API not yet supported by XWiki is given in the description of XWIKI-1559.

For more information about the Confluence XML-RPC API check out this documentation. In the future we plan to extend this API with XWiki-specific features - any extension will be documented here.

In addition, XWiki-specific extensions allow you to add, modify and remove objects via XML-RPC.

XML-RPC Clients

There are XML-RPC libraries for most programming languages.

Java Clients

Apache XML-RPC Client

For Java the most well-known one is Apache XML-RPC, which is also used in the implementation of XWiki (i.e. server-side). Here is an example which uses Apache XML-RPC directly in order to get the rendered content of a wiki page (for a much easier way to achieve the same result see the "Client-side Proxy for Java" section below).

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;

import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;

public class RawXmlRpc
{
   public static void main(String[] args)
       throws MalformedURLException, XmlRpcException
   {
        XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
        URL url = new URL("http://127.0.0.1:8080/xwiki/xmlrpc");
        config.setServerURL(url);
        XmlRpcClient client = new XmlRpcClient();
        client.setConfig(config);
       
        String token = (String)client.execute("confluence1.login",
           new Object[] {"Admin", "admin"});
       
        Map page = (Map)client.execute("confluence1.getPage",
           new Object[] {token, "Main", "WebHome"});
        String pageId = (String)page.get("id");
        String content = (String)page.get("content");
       
        String renderedContent = (String)client.execute(
           "confluence1.renderContent",
           new Object[] {token, "Main", pageId, content});
        System.out.print(renderedContent);
   }
}

In order for this to work you need to have commons-logging-1.1.1.jar, ws-commons-util-1.0.1.jar, xmlrpc-common-3.0.jar, and xmlrpc-client-3.0.jar in your classpath (version numbers are irrelevant).

Client-side Proxy for Java

Starting with XWiki 1.2 the Apache XML-RPC dynamic proxies are no longer supported.

You can build Java applications that use XWiki through the XML-RPC interface easier by using the client-side proxy that is part of XWiki. This proxy is based on Swizzle Confluence and eliminates most of the plumbing needed to use XML-RPC directly. For instance the example above is much simpler when rewritten to use the proxy.

import org.xwiki.xmlrpc.XWikiXmlRpcClient;
import org.xwiki.xmlrpc.model.XWikiPage;

public class ProxyXmlRpc
{
   public static void main(String[] args) throws XWikiClientException
   {
        String url = "http://127.0.0.1:8080/xwiki/xmlrpc/confluence";
        String user = "WikiUser";
        String pass = "password";
        XWikiXmlRpcClient rpc  = new XWikiXmlRpcClient(url);
        rpc.login(user, pass);
        XWikiPage page = rpc.getPage("Main.WebHome");
        String rendered = rpc.renderContent(
               page.getSpace(), page.getId(), page.getContent());
        System.out.print(rendered);
   }
}

In order for this to work you need to have commons-logging-1.1.1.jar, ws-commons-util-1.0.1.jar, xmlrpc-common-3.0.jar, xmlrpc-client-3.0.jar, xwiki-core-1.5.jar, and swizzle-confluence-1.2-20080419-xwiki.jar, xwiki-core-xmlrpc-client-1.5.jar, xwiki-core-xmlrpc-model-1.5.jar in your classpath (version numbers are for the most part irrelevant).

You can also try this Groovy script in an XWiki Page in your wiki (you need to add xwiki-core-xmlrpc-client-1.5.jar to yours WEB-INF/lib.

<%

import org.xwiki.xmlrpc.XWikiXmlRpcClient;
import org.xwiki.xmlrpc.model.XWikiPage;

String url = "http://localhost:8080/xwiki/xmlrpc/confluence";
String user = "WikiUser";
String pass = "password";
XWikiXmlRpcClient rpc  = new XWikiXmlRpcClient(url);
rpc.login(user, pass);
XWikiPage page = rpc.getPage("Main.WebHome");
println(page.getContent());
String rendered = rpc.renderContent(
page.getSpace(), page.getId(), page.getContent());
println(rendered);

%>

Manipulating Objects

The following non-Confluence APIs are provided for manipulating XWiki objects:

    /* Objects */
   public List/* List<XWikiObjectSummary> */getObjects(String token, String pageId) throws Exception;

   public Map/* XWikiObject */getObject(String token, String pageId, String className, Integer id) throws Exception;

   public Map/* XWikiObject */getObject(String token, String pageId, String guid) throws Exception;

   public Map/* XWikiObject */storeObject(String token, Map objectMap) throws Exception;

   public Map/* XWikiObject */storeObject(String token, Map objectMap, boolean checkVersion) throws Exception;

   public Boolean removeObject(String token, String pageId, String className, Integer id) throws Exception;

To update an object, you need to specify the className, id (number), and pageId in the objectMap, along with a propertyToValueMap which lists the fields you want to update.  For example, in perl:

    $xmlrpc->send_request('confluence1.storeObject', $token, {
       'className' => 'MySpace.Person',
       'id' => 1,
       'pageId' => 'MySpace.People',
       'propertyToValueMap' => RPC::XML::struct->new(
           'firstName' => 'Fred',
           'lastName' => 'Bloggs',
        ),
   });

To add a new object, do the same thing but with an id of -1.

Various Examples

Check the various XML-RPC examples in Java for more details.

Groovy Client

Simple Groovy sample:

import groovy.net.xmlrpc.*

def proxy = new XMLRPCServerProxy("http://www.xwiki.org/xwiki/xmlrpc/confluence")
def token = proxy.confluence1.login("username","password")
def pages = proxy.confluence1.getPages(token, "UserGuide")
print pages

Perl Client

Simple Perl sample using XML::RPC:

#!/usr/bin/perl
use XML::RPC;
use strict;

my ($result, $token);
my $xmlrpc = XML::RPC->new('http://www.xwiki.org/xwiki/xmlrpc/confluence');
$token = $xmlrpc->call( 'confluence1.login',
            ( 'username', 'password' ) );
$result = $xmlrpc->call( 'confluence1.getPages',
            ( $token, 'UserGuide' ) );
foreach my $elem (@{$result}) {
   foreach my $key (keys( %{$elem})) {
       printf "%s->%sn", $key, $elem->{$key};
    }
}

Python Client

Example of uploading an attachment using python:

import xmlrpclib
proxy = xmlrpclib.ServerProxy("http://localhost:8080/xwiki/xmlrpc/")
token = proxy.confluence1.login("Admin","admin")
page = proxy.confluence1.getPage(token, "Space.TargetPage")
attachment = {'fileName':'TargetFileName.gif','contentType':'image/gif','comment':'ignored','pageId':page.get('id')}
data = xmlrpclib.Binary(open("SomeImage.gif").read())
proxy.confluence1.addAttachment(token, 0, attachment, data)

Ruby Client

Example of connecting to the server and retrieving a page using ruby:

require 'xmlrpc/client'
server = XMLRPC::Client.new2("http://localhost:8080/xwiki/xmlrpc/confluence")
token = server.call("confluence1.login", "Admin", "admin")
server.call("confluence1.getPage", token, "Sandbox.WebHome")

Prerequisites & Installation Instructions

To enable XMLRPC in XWiki follow these steps:

  • Stop XWiki
  • Install the following JARs in WEB-INF/lib (Note that unfortunately the Extension Manager cannot be used since these need to be core Extensions as they're defined and used in web.xml):
    org.xwiki.platform:xwiki-platform-xmlrpc-oldcore:jar:7.3-milestone-1
    org.xwiki.platform:xwiki-platform-xmlrpc-model:jar:7.3-milestone-1
    org.codehaus.swizzle:swizzle-confluence:jar:xwiki:1.2-20080419:compile
    org.apache.xmlrpc:xmlrpc-client:jar:3.1
    org.apache.xmlrpc:xmlrpc-common:jar:3.1
    org.apache.ws.commons.util:ws-commons-util:jar:1.0.2
    org.apache.xmlrpc:xmlrpc-server:jar:3.1
  • Edit web.xml and add:
     <filter-mapping>
       <filter-name>XWikiXmlRpcContextInitializationFilter</filter-name>
       <servlet-name>xmlrpc</servlet-name>
       <dispatcher>REQUEST</dispatcher>
       <dispatcher>INCLUDE</dispatcher>
       <dispatcher>FORWARD</dispatcher>
     </filter-mapping>
    ...
     <servlet>
       <servlet-name>xmlrpc</servlet-name>
       <servlet-class>com.xpn.xwiki.xmlrpc.XWikiXmlRpcServlet</servlet-class>
       <init-param>
         <description>Sets, whether the servlet supports vendor extensions for XML-RPC.</description>
         <param-name>enabledForExtensions</param-name>
         <param-value>false</param-value>
       </init-param>
     </servlet>
    ...
    <servlet-mapping>
       <servlet-name>xmlrpc</servlet-name>
       <url-pattern>/xmlrpc/*</url-pattern>
     </servlet-mapping>
    ...
  • Restart XWiki
Tags:
    

Get Connected