Author: bpoussin Date: 2010-11-17 19:11:44 +0100 (Wed, 17 Nov 2010) New Revision: 479 Url: http://nuiton.org/repositories/revision/wikitty/479 Log: add WikittyServiceSlave and WikittyServiceHessianClient that can be used as WikittyService Added: trunk/wikitty-hessian-client/src/main/java/org/nuiton/ trunk/wikitty-hessian-client/src/main/java/org/nuiton/wikitty/ trunk/wikitty-hessian-client/src/main/java/org/nuiton/wikitty/services/ trunk/wikitty-hessian-client/src/main/java/org/nuiton/wikitty/services/WikittyServiceHessianClient.java trunk/wikitty-hessian-client/src/main/java/org/nuiton/wikitty/services/WikittyServiceSlave.java Added: trunk/wikitty-hessian-client/src/main/java/org/nuiton/wikitty/services/WikittyServiceHessianClient.java =================================================================== --- trunk/wikitty-hessian-client/src/main/java/org/nuiton/wikitty/services/WikittyServiceHessianClient.java (rev 0) +++ trunk/wikitty-hessian-client/src/main/java/org/nuiton/wikitty/services/WikittyServiceHessianClient.java 2010-11-17 18:11:44 UTC (rev 479) @@ -0,0 +1,31 @@ +package org.nuiton.wikitty.services; + + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.util.ApplicationConfig; +import org.nuiton.wikitty.WikittyConfig; +import org.nuiton.wikitty.WikittyService; +import org.wikitty.hessian.WikittyHessianFactory; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyServiceHessianClient extends WikittyServiceDelegator { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittyServiceHessianClient.class); + + public WikittyServiceHessianClient(ApplicationConfig config) { + String url = config.getOption(WikittyConfig.Option. + WIKITTY_SERVER_URL.getKey()); + WikittyService ws = WikittyHessianFactory.getWikittyService(url); + setDelegate(ws); + } + +} Added: trunk/wikitty-hessian-client/src/main/java/org/nuiton/wikitty/services/WikittyServiceSlave.java =================================================================== --- trunk/wikitty-hessian-client/src/main/java/org/nuiton/wikitty/services/WikittyServiceSlave.java (rev 0) +++ trunk/wikitty-hessian-client/src/main/java/org/nuiton/wikitty/services/WikittyServiceSlave.java 2010-11-17 18:11:44 UTC (rev 479) @@ -0,0 +1,197 @@ +package org.nuiton.wikitty.services; + + +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.jivesoftware.smack.PacketListener; +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.packet.Packet; +import org.jivesoftware.smackx.muc.DiscussionHistory; +import org.jivesoftware.smackx.muc.MultiUserChat; +import org.nuiton.util.ApplicationConfig; +import org.nuiton.wikitty.WikittyConfig; +import org.nuiton.wikitty.WikittyException; +import org.nuiton.wikitty.WikittyProxy; +import org.nuiton.wikitty.WikittyService; +import org.nuiton.wikitty.WikittyUtil; +import org.nuiton.wikitty.entities.Wikitty; +import org.nuiton.wikitty.entities.WikittyExtension; +import org.nuiton.wikitty.services.WikittyEvent; +import org.nuiton.wikitty.services.WikittyServiceDelegator; +import org.nuiton.wikitty.services.XMPPNotifierTransporter; +import org.wikitty.hessian.WikittyHessianFactory; + +/** + * This classe override all modification method (store, delete, clear) to send + * modification to master. All read method are directly done localy. + * + * Slave is listener of master event and synchronize local data when event are + * received + * + * Configuration: + * <li> slave login + * <li> slave passwd + * <li> master service url + * <li> master service xmpp room + * <li> async store + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class WikittyServiceSlave + extends WikittyServiceDelegator implements PacketListener { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(WikittyServiceSlave.class); + + // Keep room addresse and pseudo to verify that messages event are not send by us + protected String room; + protected String pseudo; + + protected WikittyService master; + protected ApplicationConfig config; + protected boolean useAsync = false; + + public WikittyServiceSlave(ApplicationConfig config, WikittyService ws) { + super(ws); + this.config = config; + + useAsync = config.getOptionAsBoolean(WikittyConfig.Option. + WIKITTY_SLAVE_ASYNC_STORE.getKey()); + + String masterURL = config.getOption(WikittyConfig.Option. + WIKITTY_SLAVE_MASTER_URL.getKey()); + + // creation du WikittyService master + master = WikittyHessianFactory.getWikittyService(masterURL); + + // enregistrement en tant que listener sur le master + initXMPP(config); + } + + /** + * FIXME poussin 20101117 reutilise le transporter plutot que de dupliquer le code. + * Le probleme est de passer de la meilleur facon possible le xmpp server et la room + * qui ne sont pas donnes par les memes cles de config. Il y a aussi l'historique + * qu'il faut recuperer ici alors que dans le transporter qui est utilise pour les + * client, il n'y a pas besoin d'historique. Le but est de pouvoir creer facilement + * de nouveau transporter sans devoir modifier cette classe. + * + * Si persistent est vrai alors il faut toujours utilise le meme user id + * + * @param props + */ + protected void initXMPP(ApplicationConfig config) { + String server = config.getOption(WikittyConfig.Option. + WIKITTY_SLAVE_MASTER_XMPP_SERVER.getKey()); + + // Keep them to verify that is not us notifications + room = config.getOption(WikittyConfig.Option. + WIKITTY_SLAVE_MASTER_XMPP_ROOM.getKey()); + pseudo = WikittyUtil.getUniqueLoginName(); + try { + if (log.isInfoEnabled()) { + log.info("Try to connect to xmpp serveur " + server + + " with pseudo " + pseudo + " in room " + room); + } + XMPPConnection connection = new XMPPConnection(server); + connection.connect(); + connection.loginAnonymously(); + + DiscussionHistory history = new DiscussionHistory(); + // FIXME poussin 20101113 compute amount of log history to retrieve + // MUC must be archived + Date date = new Date(); + history.setSince(date); + + // connection to the volatile room + MultiUserChat muc = new MultiUserChat(connection, room); + muc.join(pseudo, "", history, 4000); + muc.addMessageListener(this); + } catch (Exception eee) { + throw new WikittyException("Can't connect to xmpp serveur", eee); + } + } + /** + * used for MUC message + * @param packet + */ + @Override + public void processPacket(Packet packet) { + + // Dont listen own events + String name = room + "/" + pseudo; + if (!name.equals(packet.getFrom())) { + + Object event = packet.getProperty(XMPPNotifierTransporter.PROPERTY_EVENT_NAME); + + if (log.isDebugEnabled()) { + log.debug("Receive message : " + event); + } + + if (event instanceof WikittyEvent) { + processRemoteEvent((WikittyEvent)event); + } + } + } + + protected void processRemoteEvent(WikittyEvent event) { + // rejoue l'event en local + replay(null, Collections.singletonList(event)); + + // FIXME poussin 20101117 marquer cet event comme etant le dernier recu et rejouer + } + + ////////////////////////////////////////////////////// + // + // W I K I T T Y S E R V I C E M E T H O D S + // + ////////////////////////////////////////////////////// + + @Override + public String login(String login, String password) { + return master.login(login, password); + } + + @Override + public void logout(String securityToken) { + master.logout(securityToken); + } + + @Override + public WikittyEvent store(String securityToken, Collection<Wikitty> wikitties, boolean force) { + return master.store(securityToken, wikitties, force); + } + + @Override + public WikittyEvent storeExtension(String securityToken, Collection<WikittyExtension> exts) { + return master.storeExtension(securityToken, exts); + } + + @Override + public WikittyEvent delete(String securityToken, Collection<String> ids) { + return master.delete(securityToken, ids); + } + + @Override + public WikittyEvent deleteExtension(String securityToken, Collection<String> extNames) { + return master.deleteExtension(securityToken, extNames); + } + + @Override + public WikittyEvent deleteTree(String securityToken, String wikittyId) { + return master.deleteTree(securityToken, wikittyId); + } + + @Override + public WikittyEvent clear(String securityToken) { + return master.clear(securityToken); + } + +}