Недавно я подумал о создании процесса, с помощью которого я мог бы синхронизировать два экземпляра
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 часов). Конечно, скопированный пост не является точным клоном оригинала (я теряю информацию об авторе, категориях и т. Д., И изображения упоминаются в исходном местоположении), но он показывает, что основная идея работает!