Недавно я подумал о создании процесса, с помощью которого я мог бы синхронизировать два экземпляра
WordPress . Я хотел посмотреть, смогу ли я сделать это с Мулом. Я придумал следующее решение:
- Получите RSS-канал о новом сообщении в Mule flow
- Используйте содержимое RSS-канала для публикации в другом экземпляре WordPress с помощью XML-RPC.
- Запустите его на CloudHub, чтобы мне не пришлось настраивать свой собственный Muleserver
Итак, давайте начнем новый проект CloudHub . Поскольку я большой поклонник Netbeans, я использую подход, основанный на Maven (должен признать, что я пытался использовать MuleStudio для этого, но это не принесло мне повышения производительности, на которое я надеялся).
Я создал проект Mule с:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns:rss="http://www.mulesoft.org/schema/mule/rss"
xmlns:spring="http://www.springframework.org/schema/beans"
xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/3.1/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/3.1/mule-http.xsd
http://www.mulesoft.org/schema/mule/rss http://www.mulesoft.org/schema/mule/rss/3.1/mule-rss.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<spring:bean name="xmlRpcHelper" class="net.pascalalma.rss.XmlRpcHelper">
<spring:constructor-arg value="http://www.pragmatic-integrators.com/xmlrpc.php" type="java.lang.String"/>
<spring:constructor-arg value="UserName" type="java.lang.String"/>
<spring:constructor-arg value="Password" type="java.lang.String"/>
</spring:bean>
<spring:bean name="entryReceiver" class="net.pascalalma.rss.EntryReceiver">
<spring:constructor-arg ref="xmlRpcHelper"/>
</spring:bean>
<flow name="poll-and-post">
<poll frequency="36000000">
<http:outbound-endpoint address="http://www.redstream.nl/feed/" />
</poll>
<rss:feed-splitter />
<component>
<spring-object bean="entryReceiver"/>
</component>
</flow>
</mule>
Как видите, я опрашиваю сайт «www.redstream.nl» один раз каждые 10 часов. RSS-канал, который я получаю, разделяется и отправляется в мой пользовательский компонент entryReceiver. Было бы хорошо , чтобы использовать XML-RPC конечной точки здесь , но это не будет создан еще (и на самом деле я не чувствую , как это ни). EntryReceiver выглядит так:
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)) {
xmlRpcHelper.post(entry);
} else {
// Skip this post
}
}
}
Отказ от ответственности: просто хотел посмотреть, работает ли он, я не пытался создать надежное решение, которое должно было бы работать для каждого сайта WordPress, так что вы предупреждены!
И боб, где сделана грязная работа:
package net.pascalalma.rss;
import java.net.MalformedURLException;
import java.net.URL;
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
e.printStackTrace();
}
client.setConfig(config);
}
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) {
content.append(syndContent.getValue());
}
content.append("</content>");
try {
client.execute("blogger.newPost", new Object[]{"bla", 1,
userName, password, content.toString(), true});
} catch (XmlRpcException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
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
e.printStackTrace();
// 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,
content.indexOf("</title>"));
}
return title;
}
}
Некоторое время я был занят тем, что первая строка в массиве объектов, поставляемая с вызовом XmlRpc, может содержать что угодно, если только она содержит что-то. Пустая строка «» игнорируется в вызове и приведет к неверному сообщению имени пользователя / пароля.
Если все это есть, вы можете собрать проект с помощью: ‘mvn clean install’. Это создаст zip-файл в целевой директории. Этот zip-файл может быть загружен с вашей приборной панели в ваш экземпляр CloudHub и все! Как вы можете видеть, два сайта «www.redstream.nl» и «www.pragmatic-integrators.com» синхронизированы (с максимальным разрывом в 10 часов). Конечно, скопированный пост не является точным клоном оригинала (я теряю информацию об авторе, категориях и т. Д., И изображения упоминаются в исходном местоположении), но он показывает, что основная идея работает!