Search code examples
xml-rpcconfluencexwiki

How to make confluence2 calls via XWikiXmlRpcClient?


Using a version of this code. (The code is modified to use pages relevant to my confluence set up, apart from that it's identical to this):

import java.net.MalformedURLException;
import org.apache.xmlrpc.XmlRpcException;
import org.codehaus.swizzle.confluence.Page;
import org.xwiki.xmlrpc.XWikiXmlRpcClient;


public class UpdatePage {

   public static void main(String[] args) throws MalformedURLException, XmlRpcException {

   //URL of the xwiki instance
   String url = "http://localhost:8080/xwiki/xmlrpc/confluence";

   //Replace user & pass with desired xwiki username & password
   String user = "Admin";
    String pass = "admin";


    XWikiXmlRpcClient rpc = new XWikiXmlRpcClient(url);
   try {

       //Perform Login & Authentication
       rpc.login(user, pass);

       //Create a Page object to hold our Document information
       Page page = new Page();
       //Fetch the required page. In our example, the page is in Space "demo code"
       //and the Page is "Update Page"
       page=rpc.getPage("demo code.Update Page");
       //Fetch the content of the page & store it in a string for temporary storage
       //This is the present content of the Page
       String presentContent=page.getContent();
       //Create a string that will hold the new content that is to be added to the Page
       String newContent="\\\\Some new content added";
       //Set the content of the page as: present content + new content
       //However, this page is not yet stored to XWiki. It only resides in your application
       page.setContent(presentContent+newContent);
       //Finally, store the "updated" Page to XWiki
       rpc.storePage(page);

       //Just to make sure everything saved all right, fetch the content again for the Page
       System.out.println(page.getContent());

   } catch (XmlRpcException e) {
        System.out.println("invalid username/password was specified or communication problem or ");
        System.out.println(e);
   } finally {
        rpc.logout();
   }
   }
}

taken from http://extensions.xwiki.org/xwiki/bin/view/Extension/XML-RPC+Integration+Java+Examples

When it tries to retrieve that page from Confluence:

page=rpc.getPage("demo code.Update Page");

I get this error when using the code above:

   org.apache.xmlrpc.XmlRpcException: java.lang.Exception:   com.atlassian.confluence.rpc.RemoteException: You must supply a valid number as the page ID.

Then if I get the page id from the page, and use that:

page = rpc.getPage("39201714");

I get this exception:

org.apache.xmlrpc.XmlRpcException: java.lang.Exception:   com.atlassian.confluence.rpc.RemoteException: Unsupported operation: Wiki formatted content can no longer be retrieved from this API. Please use the version 2 API. The version 2 WSDL is available at: http://confluence:8080/rpc/soap-axis/confluenceservice-v2?wsdl. XML-RPC requests should prefixed with "confluence2.".

Do I change the confluence URL to access confluence2 api? Not sure how to change what XWikiXmlRpcClient uses..


Solution

  • If you look at the source code for XWikiXmlRpcClient, the constructor shows that it is using confluence1:

        /**
     * Constructor.
     * 
     * @param endpoint The endpoint for the XMLRPC servlet.
     * @throws MalformedURLException
     */
    public XWikiXmlRpcClient(String endpoint) throws MalformedURLException
    {
        this(endpoint, "confluence1");
    }
    

    This calls the internal constructor using 'confluence1' as the RPC Handler.

    The class has two constructors though, so it should be possible to call the same thing directly from outside the class:

     XWikiXmlRpcClient rpc = new XWikiXmlRpcClient(CONFLUENCE_URI, "confluence2");
    

    Later when it invokes the rpc, confluence2 (this.rpcHandler) gets prepended onto the string:

        private synchronized Object invokeRpc(String methodName, Object... args) throws XmlRpcException
    {
        return this.xmlRpcClient.execute(String.format("%s.%s", this.rpcHandler, methodName), args);
    }
    

    You need to use both the confluence1 and confluence2 versions of the object to update the page:

     XWikiXmlRpcClient rpcConfluence1 = new    XWikiXmlRpcClient(CONFLUENCE_URI);
        XWikiXmlRpcClient rpcConfluence2 = new XWikiXmlRpcClient(CONFLUENCE_URI, "confluence2");
        try {
            rpcConfluence1.login(USER_NAME, PASSWORD);
            rpcConfluence2.login(USER_NAME, PASSWORD);
            Page page = new Page();     
            page = rpcConfluence2.getPage(PAGEID);
    
            List<String> lines = Files.readAllLines(Paths.get("summary.markup"), Charset.defaultCharset());
            StringBuilder b = new StringBuilder();
            for(int i=0; i < lines.size(); i++) {
                    b.append(String.format("%s%s", lines.get(i), "\r\n"));
            }              
            page.setContent(b.toString());
    
            rpcConfluence1.storePage(page);
            } catch (XmlRpcException e) {
                e.printStackTrace();
            }
    
    
    
    }