From 80eee39db1e834180876cb0b002e692dd1a70f53 Mon Sep 17 00:00:00 2001 From: Lloyd Watkin Date: Thu, 28 Nov 2013 16:51:30 +0000 Subject: [PATCH 1/4] Add datastore methods to check whether node config is cached --- .../org/buddycloud/channelserver/db/NodeStore.java | 8 ++++++++ .../channelserver/db/jdbc/JDBCNodeStore.java | 5 +++++ .../channelserver/db/jdbc/JDBCNodeStoreTest.java | 11 +++++++++++ 3 files changed, 24 insertions(+) diff --git a/src/main/java/org/buddycloud/channelserver/db/NodeStore.java b/src/main/java/org/buddycloud/channelserver/db/NodeStore.java index 8129f140..2f4b5b1e 100644 --- a/src/main/java/org/buddycloud/channelserver/db/NodeStore.java +++ b/src/main/java/org/buddycloud/channelserver/db/NodeStore.java @@ -536,6 +536,14 @@ void deleteNodeItemById(String nodeId, String nodeItemId) */ boolean isCachedJID(JID jid) throws NodeStoreException; + /** + * Return whether node config is cached locally + * + * @param nodeId + * @return + * @throws NodeStoreException + */ + boolean isCachedNodeConfig(String nodeId) throws NodeStoreException; /** * Allows the server to determine if the requested (subscriptions) node diff --git a/src/main/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStore.java b/src/main/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStore.java index 47d593e2..b38ca35f 100644 --- a/src/main/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStore.java +++ b/src/main/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStore.java @@ -1643,6 +1643,11 @@ public ArrayList getNodeList() throws NodeStoreException { public boolean isCachedNode(String nodeId) throws NodeStoreException { return (this.countNodeItems(nodeId) > 0); } + + @Override + public boolean isCachedNodeConfig(String nodeId) throws NodeStoreException { + return (this.getNodeConf(nodeId).size() > 0); + } @Override public boolean isCachedJID(JID jid) throws NodeStoreException { diff --git a/src/test/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStoreTest.java b/src/test/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStoreTest.java index 8c7e5a7f..ad3e9954 100644 --- a/src/test/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStoreTest.java +++ b/src/test/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStoreTest.java @@ -489,6 +489,17 @@ public void testGetNodeConf() throws Exception { entry.getValue(), result.get(entry.getKey())); } } + + @Test + public void testNodeWithConfigSaysConfigIsCached() throws Exception { + dbTester.loadData("node_1"); + Assert.assertTrue(store.isCachedNodeConfig(TEST_SERVER1_NODE1_ID)); + } + + @Test + public void testNodeWithoutConfigSaysConfigNotCached() throws Exception { + Assert.assertFalse(store.isCachedNodeConfig(TEST_SERVER1_NODE1_ID)); + } @Test public void testAddUserSubscriptionNewSubscription() throws Exception { From 3ca3af45a2dbc5382d76e7784122f04e3c9a6fa1 Mon Sep 17 00:00:00 2001 From: Lloyd Watkin Date: Thu, 28 Nov 2013 16:51:57 +0000 Subject: [PATCH 2/4] Use local cache if we have it --- .../iq/namespace/pubsub/get/NodeConfigureGet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/get/NodeConfigureGet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/get/NodeConfigureGet.java index 1aec738f..219bf48a 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/get/NodeConfigureGet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/get/NodeConfigureGet.java @@ -51,7 +51,7 @@ public void process(Element elm, JID actorJID, IQ reqIQ, Element rsm) return; } - if (!channelManager.isLocalNode(node)) { + if (!channelManager.isLocalNode(node) && !channelManager.isCachedNodeConfig(node)) { makeRemoteRequest(); return; } From be752ef50545b638813b1a6c42fb32ac186f6607 Mon Sep 17 00:00:00 2001 From: Lloyd Watkin Date: Thu, 28 Nov 2013 17:06:02 +0000 Subject: [PATCH 3/4] Add skeleton of node configuration result parser --- .../channel/ChannelManagerImpl.java | 6 +++ .../iq/namespace/pubsub/PubSubResult.java | 2 + .../pubsub/result/Configuration.java | 46 ++++++++++++++++ .../pubsub/result/ConfigurationTest.java | 53 +++++++++++++++++++ 4 files changed, 107 insertions(+) create mode 100644 src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/result/Configuration.java create mode 100644 src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/result/ConfigurationTest.java diff --git a/src/main/java/org/buddycloud/channelserver/channel/ChannelManagerImpl.java b/src/main/java/org/buddycloud/channelserver/channel/ChannelManagerImpl.java index 55853c6d..ffb34f0f 100644 --- a/src/main/java/org/buddycloud/channelserver/channel/ChannelManagerImpl.java +++ b/src/main/java/org/buddycloud/channelserver/channel/ChannelManagerImpl.java @@ -83,6 +83,12 @@ public Map getNodeConf(String nodeId) throws NodeStoreException { return nodeStore.getNodeConf(nodeId); } + + + @Override + public boolean isCachedNodeConfig(String nodeId) throws NodeStoreException { + return nodeStore.isCachedNodeConfig(nodeId); + } @Override public boolean nodeExists(String nodeId) throws NodeStoreException { diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/PubSubResult.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/PubSubResult.java index 8896ae77..c606459f 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/PubSubResult.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/PubSubResult.java @@ -7,6 +7,7 @@ import org.buddycloud.channelserver.channel.ChannelManager; import org.buddycloud.channelserver.packetprocessor.PacketProcessor; import org.buddycloud.channelserver.packetprocessor.iq.namespace.pubsub.result.AffiliationsResult; +import org.buddycloud.channelserver.packetprocessor.iq.namespace.pubsub.result.Configuration; import org.buddycloud.channelserver.packetprocessor.iq.namespace.pubsub.result.ItemsResult; import org.buddycloud.channelserver.packetprocessor.iq.namespace.pubsub.result.SubscriptionsResult; import org.buddycloud.channelserver.queue.FederatedQueueManager; @@ -42,6 +43,7 @@ private void initElementProcessors() { elementProcessors.add(new SubscriptionsResult(channelManager)); elementProcessors.add(new AffiliationsResult(channelManager)); elementProcessors.add(new ItemsResult(channelManager)); + elementProcessors.add(new Configuration(channelManager)); } @Override diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/result/Configuration.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/result/Configuration.java new file mode 100644 index 00000000..40d4be0a --- /dev/null +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/result/Configuration.java @@ -0,0 +1,46 @@ +package org.buddycloud.channelserver.packetprocessor.iq.namespace.pubsub.result; + +import java.util.List; + +import org.apache.log4j.Logger; +import org.buddycloud.channelserver.channel.ChannelManager; +import org.buddycloud.channelserver.db.exception.NodeStoreException; +import org.buddycloud.channelserver.packetprocessor.iq.namespace.pubsub.PubSubElementProcessorAbstract; +import org.buddycloud.channelserver.pubsub.model.NodeSubscription; +import org.buddycloud.channelserver.pubsub.model.impl.NodeSubscriptionImpl; +import org.buddycloud.channelserver.pubsub.subscription.Subscriptions; +import org.dom4j.Element; +import org.xmpp.packet.IQ; +import org.xmpp.packet.JID; + +public class Configuration extends PubSubElementProcessorAbstract { + + private IQ request; + private boolean ownerRequest; + private String lastNode = ""; + + private static final Logger logger = Logger + .getLogger(Configuration.class); + + public Configuration(ChannelManager channelManager) { + this.channelManager = channelManager; + } + + @Override + public void process(Element elm, JID actorJID, IQ reqIQ, Element rsm) + throws Exception { + this.request = reqIQ; + + if (-1 != request.getFrom().toString().indexOf("@")) { + logger.debug("Ignoring result packet, only interested in stanzas " + + "from other buddycloud servers"); + return; + } + + } + + @Override + public boolean accept(Element elm) { + return elm.getName().equals("configure"); + } +} \ No newline at end of file diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/result/ConfigurationTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/result/ConfigurationTest.java new file mode 100644 index 00000000..e65c680e --- /dev/null +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/result/ConfigurationTest.java @@ -0,0 +1,53 @@ +package org.buddycloud.channelserver.packetprocessor.iq.namespace.pubsub.result; + +import junit.framework.Assert; + +import org.buddycloud.channelserver.channel.ChannelManager; +import org.buddycloud.channelserver.packetHandler.iq.IQTestHandler; +import org.buddycloud.channelserver.pubsub.affiliation.Affiliations; +import org.buddycloud.channelserver.pubsub.model.NodeSubscription; +import org.dom4j.Element; +import org.dom4j.tree.BaseElement; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.xmpp.packet.IQ; +import org.xmpp.packet.JID; + +public class ConfigurationTest extends IQTestHandler { + + private IQ resultWithNode; + private IQ resultNoNode; + private Configuration confResult; + private Element element; + + private String node = "/user/pamela@denmark.lit/posts"; + private JID jid = new JID("juliet@shakespeare.lit"); + private ChannelManager channelManager; + + @Before + public void setUp() throws Exception { + + channelManager = Mockito.mock(ChannelManager.class); + + confResult = new Configuration(channelManager); + resultWithNode = readStanzaAsIq("/iq/pubsub/subscriptions/reply-with-node.stanza"); + resultNoNode = readStanzaAsIq("/iq/pubsub/subscriptions/reply-no-node.stanza"); + + element = new BaseElement("configure"); + element.addAttribute("node", node); + + confResult.setChannelManager(channelManager); + } + + @Test + public void testPassingConfigureAsElementNameReturnsTrue() { + Assert.assertTrue(confResult.accept(element)); + } + + @Test + public void testPassingNotConfigureAsElementNameReturnsFalse() { + Element element = new BaseElement("not-configure"); + Assert.assertFalse(confResult.accept(element)); + } +} \ No newline at end of file From 742b9929205d1bffe674a358ee7d885a7f41f4bb Mon Sep 17 00:00:00 2001 From: Lloyd Watkin Date: Thu, 28 Nov 2013 17:23:49 +0000 Subject: [PATCH 4/4] Finish node config result parsing code --- .../pubsub/result/Configuration.java | 32 +++++++++++++- .../pubsub/result/ConfigurationTest.java | 43 +++++++++++++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/result/Configuration.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/result/Configuration.java index 40d4be0a..d9fda7bf 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/result/Configuration.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/result/Configuration.java @@ -1,9 +1,12 @@ package org.buddycloud.channelserver.packetprocessor.iq.namespace.pubsub.result; +import java.util.HashMap; import java.util.List; import org.apache.log4j.Logger; import org.buddycloud.channelserver.channel.ChannelManager; +import org.buddycloud.channelserver.channel.node.configuration.NodeConfigurationException; +import org.buddycloud.channelserver.channel.node.configuration.field.Owner; import org.buddycloud.channelserver.db.exception.NodeStoreException; import org.buddycloud.channelserver.packetprocessor.iq.namespace.pubsub.PubSubElementProcessorAbstract; import org.buddycloud.channelserver.pubsub.model.NodeSubscription; @@ -12,12 +15,12 @@ import org.dom4j.Element; import org.xmpp.packet.IQ; import org.xmpp.packet.JID; +import org.xmpp.packet.PacketError; public class Configuration extends PubSubElementProcessorAbstract { private IQ request; - private boolean ownerRequest; - private String lastNode = ""; + Element configure; private static final Logger logger = Logger .getLogger(Configuration.class); @@ -36,7 +39,32 @@ public void process(Element elm, JID actorJID, IQ reqIQ, Element rsm) + "from other buddycloud servers"); return; } + + configure = request.getChildElement().element("configure"); + node = configure.attributeValue("node"); + if (0 == node.length()) return; + + if (false == channelManager.nodeExists(node)) { + channelManager.addRemoteNode(node); + } + setNodeConfiguration(); + } + + private void setNodeConfiguration() throws Exception { + try { + getNodeConfigurationHelper().parse(request); + updateNodeConfiguration(getNodeConfigurationHelper() + .getValues()); + } catch (NodeConfigurationException e) { + logger.error("Node configuration exception", e); + } catch (NodeStoreException e) { + logger.error("Data Store Exception", e); + } + } + private void updateNodeConfiguration(HashMap configuration) + throws Exception { + channelManager.setNodeConf(node, configuration); } @Override diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/result/ConfigurationTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/result/ConfigurationTest.java index e65c680e..ae164fcb 100644 --- a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/result/ConfigurationTest.java +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/pubsub/result/ConfigurationTest.java @@ -50,4 +50,47 @@ public void testPassingNotConfigureAsElementNameReturnsFalse() { Element element = new BaseElement("not-configure"); Assert.assertFalse(confResult.accept(element)); } + + @Test(expected = NullPointerException.class) + public void testInvalidStanzaThrowsException() throws Exception { + + IQ result = toIq("" + + "" + + ""); + + confResult.process(element, jid, result, null); + } + + @Test + public void testEmptyNodeValueCausesNoAction() throws Exception { + IQ result = toIq("" + + "" + + "" + "" + ""); + + confResult.process(element, jid, result, null); + + Mockito.verify(channelManager, Mockito.times(0)).nodeExists( + Mockito.anyString()); + } + + @Test + public void testIfNodeIsUnknownThenItIsAddedToDatabase() throws Exception { + IQ result = toIq("" + + "" + + "" + "" + ""); + + confResult.process(element, jid, result, null); + + Mockito.when(channelManager.nodeExists(Mockito.anyString())).thenReturn(false); + Mockito.verify(channelManager, Mockito.times(1)).nodeExists( + Mockito.anyString()); + Mockito.verify(channelManager, Mockito.times(1)).addRemoteNode( + Mockito.anyString()); + } } \ No newline at end of file