Use Mule to sync WordPress sites

I recently thought about to create a process with which I could keep two instances of WordPress in sync. I wanted to see if I could do this with Mule. I came up with the following solution:

  • Receive the RSS feed of a new post in Mule flow
  • Use the content of the RSS feed to post to the other wordpress instance by using XML-RPC
  • Have it running on Mule iON so I don’t have to setup my own Muleserver

So lets start a new Mule iON project. Since I am a big fan of Netbeans I use the Maven based approach (I must admit I have tried to use MuleStudio for this but it didn’t bring me the productivityboost I hoped for).
I created the Mule project with:

mvn -DartifactId=wordpress-copy-service -DgroupId=net.pascalalma.mule-ion -Dinteractive=false -Dmodules=rss -DmuleVersion=3.1.1

The Mule config looks like:

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns=""
    <spring:bean name="xmlRpcHelper" class="net.pascalalma.rss.XmlRpcHelper">
        <spring:constructor-arg value="" type="java.lang.String"/>
        <spring:constructor-arg value="UserName" type="java.lang.String"/>
        <spring:constructor-arg value="Password" type="java.lang.String"/>
    <spring:bean name="entryReceiver" class="net.pascalalma.rss.EntryReceiver">
        <spring:constructor-arg ref="xmlRpcHelper"/>
    <flow name="poll-and-post">
        <poll frequency="36000000">
            <http:outbound-endpoint address="" />
        <rss:feed-splitter />
            <spring-object bean="entryReceiver"/>

As you can see I poll the website ‘’ once each 10 hours. The RSS feed I receive is split and sent to my custom made component ‘entryReceiver’. It would be nice to use a XML-RPC endpoint here but this isn’t created yet (and actually I don’t feel like it neither).

The EntryReceiver looks like:

package net.pascalalma.rss;

import org.mule.api.annotations.param.Payload;
import com.sun.syndication.feed.synd.SyndEntry;

public class EntryReceiver {

    XmlRpcHelper xmlRpcHelper = null;

    public EntryReceiver(XmlRpcHelper helper) {
        xmlRpcHelper = helper;
    public void readEntry(@Payload SyndEntry entry) throws Exception {

        // Get the title
        String title = entry.getTitle();

        // Check if title exist in current blogs on the new blogsite
       if (!xmlRpcHelper.titleExists(title)) {

        } else {
            // Skip this post

Disclaimer: just wanted to see if it worked, I did not try to build a robust solution that had to work for every WordPress site, so you are warned!

And the bean where the dirty work is done:

package net.pascalalma.rss;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

import com.sun.syndication.feed.synd.SyndContentImpl;
import com.sun.syndication.feed.synd.SyndEntry;

public class XmlRpcHelper {

    private String url;
    private String userName;
    private String password;
    XmlRpcClient client = new XmlRpcClient();

    public XmlRpcHelper(String url, String u, String p) {
        this.url = url;
        this.userName = u;
        this.password = p;

        XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
        try {
            config.setServerURL(new URL(url));
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block

    public boolean titleExists(String title) {
        return getRecentTitles().contains(title);

    public void post(SyndEntry entry) {
        StringBuilder content = new StringBuilder("<content><title>").append(entry.getTitle()).append("</title>");
        List<SyndContentImpl> contents = entry.getContents();

        for (SyndContentImpl syndContent : contents) {
        try {
            client.execute("blogger.newPost", new Object[]{"bla", 1,
                        userName, password, content.toString(), true});
        } catch (XmlRpcException e) {
            // TODO Auto-generated catch block

    private List<String> getRecentTitles() {
        List<String> titles = new ArrayList<String>();
        try {
            Object token = client.execute("blogger.getRecentPosts", new Object[]{"bla", 1,
                        userName, password, 10});

            Object[] result = (Object[]) token;
            for (int i = 0; i < result.length; i++) {
                titles.add(getTitle((HashMap<String, Object>) result[i]));
        } catch (XmlRpcException e) {
            // TODO Auto-generated catch block
            // return null;
        return titles;

    private static String getTitle(Map response) {
        String title = null;
        String content = (String) response.get("content");

        if (content != null) {
            title = content.substring(content.indexOf("<title>") + 7,
        return title;

One thing that kept me busy for a while was that the first String in the Object array that is supplied with the XmlRpc call may contain anything as long as it contains something. An empty String “” is ignored in the call and will lead to an invalid Username/Password message.

If all this is in place you can build the project with: ‘mvn clean install’. This will create a zip file in the target directory. This zip file can then be uploaded with your dashboard to your Mule iON instance and that’s it! As you can see the two sites ‘’ and ‘’ are know kept in sync (with a max. gap of 10 hrs). Of course the copied post is not an exact clone of the original (I am loosing info about the Author, Categories, etc. and images are referred to at the original location) but it shows that the main idea works!

About Pascal Alma

Pascal is a senior JEE Developer and Architect. Pascal has been designing and building J2EE applications since 2001. He is particularly interested in Open Source toolstack (Mule, Spring Framework, JBoss) and technologies like Web Services, SOA and Cloud technologies. Specialties: JEE AWS XML/XSD/XSLT SOAP/Web Services/SOA Mule ESB Maven Cloud Technology
This entry was posted in Mule iON, Mule3 and tagged , . Bookmark the permalink.