package org.buddycloud.channelserver.queue; import java.util.ArrayList; import junit.framework.Assert; import org.buddycloud.channelserver.Configuration; import org.buddycloud.channelserver.channel.ChannelManager; import org.buddycloud.channelserver.channel.ChannelsEngineMock; import org.buddycloud.channelserver.packetHandler.iq.IQTestHandler; import org.buddycloud.channelserver.packetprocessor.iq.namespace.pubsub.JabberPubsub; import org.dom4j.Element; import org.dom4j.tree.DefaultElement; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import org.xmpp.packet.IQ; import org.xmpp.packet.JID; import org.xmpp.packet.Message; import org.xmpp.packet.Packet; import org.xmpp.packet.PacketError; public class FederatedQueueManagerTest extends IQTestHandler { private FederatedQueueManager queueManager; private ChannelsEngineMock channelsEngine; private String localServer = "channels.shakespeare.lit"; private Configuration configuration; @Before public void setUp() throws Exception { channelsEngine = new ChannelsEngineMock(); Mockito.mock(ChannelManager.class); configuration = Mockito.mock(Configuration.class); Mockito.when(configuration.getProperty(Configuration.CONFIGURATION_SERVER_CHANNELS_DOMAIN)).thenReturn(localServer); Mockito.when(configuration.getProperty(Configuration.DISCOVERY_USE_DNS)).thenReturn("true"); queueManager = new FederatedQueueManager(channelsEngine, configuration); } @Test(expected = UnknownFederatedPacketException.class) public void testAttemptingToForwardNonExistantFederatedPacketThrowsException() throws Exception { IQ packet = new IQ(); packet.setID("1"); queueManager.passResponseToRequester(packet); } @Test public void testUnDiscoveredServerSpawnsDiscoItemsRequest() throws Exception { IQ packet = new IQ(); packet.setID("1"); packet.setFrom(new JID("romeo@montague.lit/street")); packet.setTo(new JID("capulet.lit")); packet.setType(IQ.Type.get); queueManager.process(packet); Assert.assertEquals(1, channelsEngine.size()); Packet outgoingPacket = channelsEngine.poll(); Assert.assertEquals(localServer, outgoingPacket.getElement().attributeValue("from")); Assert.assertEquals(JabberPubsub.NS_DISCO_ITEMS, outgoingPacket.getElement().element("query").getNamespace().getStringValue()); } @Test public void testResponseToDiscoItemsRequestResultsInDiscoInfoRequests() throws Exception { Element item = new DefaultElement("item"); item.addAttribute("jid", "channels.capulet.lit"); ArrayList<Element> items = new ArrayList<Element>(); items.add(item); queueManager.processDiscoItemsResponse(new JID("capulet.lit"), items); Assert.assertEquals(1, channelsEngine.size()); Packet discoInfoRequest = channelsEngine.poll(); Assert.assertEquals(localServer, discoInfoRequest.getElement().attributeValue("from")); Assert.assertEquals("channels.capulet.lit", discoInfoRequest.getElement().attributeValue("to")); Assert.assertEquals(JabberPubsub.NS_DISCO_INFO, discoInfoRequest.getElement().element("query").getNamespace().getStringValue()); } @Test public void testNotProvidingChannelServerInItemsResponseResultsInErrorStanazaReturn() throws Exception { // Attempt to send stanza IQ packet = new IQ(); packet.setID("1:some-request"); packet.setFrom(new JID("romeo@montague.lit/street")); packet.setTo(new JID("capulet.lit")); packet.setType(IQ.Type.get); queueManager.process(packet); // Disco#items fired, passing in items list Element item = new DefaultElement("item"); item.addAttribute("jid", "channels.capulet.lit"); ArrayList<Element> items = new ArrayList<Element>(); items.add(item); queueManager.processDiscoItemsResponse(new JID("capulet.lit"), items); channelsEngine.poll(); // Response to disco#info with no identities queueManager.processDiscoInfoResponse(new JID("channels.capulter.lit"), channelsEngine.poll().getID(), new ArrayList<Element>()); // Expect error response to original packet IQ errorResponse = (IQ) channelsEngine.poll(); Assert.assertEquals(packet.getID(), errorResponse.getID()); Assert.assertEquals(IQ.Type.error, errorResponse.getType()); Assert.assertEquals(localServer, errorResponse.getFrom().toString()); Assert.assertEquals(PacketError.Type.cancel.toXMPP(), errorResponse.getElement().element("error").attributeValue("type")); Assert.assertEquals(PacketError.Condition.item_not_found.toXMPP(), errorResponse.getElement().element("error").element("item-not-found").getName()); Assert.assertEquals("No pubsub channel service discovered for capulet.lit", errorResponse.getElement().element("error").elementText("text")); } @Test public void testPassingChannelServerIdentifierViaItemsResultsInQueuedPacketSending() throws Exception { // Attempt to send stanza IQ packet = new IQ(); packet.setID("1:some-request"); packet.setFrom(new JID("romeo@montague.lit/street")); packet.setTo(new JID("topics.capulet.lit")); packet.setType(IQ.Type.get); queueManager.process(packet); channelsEngine.poll(); // Pass in items with name="buddycloud-server" Element item = new DefaultElement("item"); item.addAttribute("jid", "channels.capulet.lit"); item.addAttribute("name", "buddycloud-server"); ArrayList<Element> items = new ArrayList<Element>(); items.add(item); queueManager.processDiscoItemsResponse(new JID("topics.capulet.lit"), items); // Note original packet now sent with remote channel server tag Packet originalPacketRedirected = channelsEngine.poll(); Packet expectedForwaredPacket = packet.createCopy(); expectedForwaredPacket.setFrom(new JID(localServer)); expectedForwaredPacket.setTo(new JID("channels.capulet.lit")); Assert.assertEquals(expectedForwaredPacket.toXML(), originalPacketRedirected.toXML()); } @Test public void testOutgoingFederatedPacketsAreRoutedBackToOriginalSender() throws Exception { channelsEngine.clear(); IQ packet = new IQ(); packet.setID("1:some-request"); packet.setFrom(new JID("romeo@montague.lit/street")); packet.setTo(new JID("topics.capulet.lit")); packet.setType(IQ.Type.get); packet.getElement().addAttribute("remote-server-discover", "false"); queueManager.process(packet.createCopy()); IQ originalPacketRedirected = (IQ) channelsEngine.poll(); IQ response = IQ.createResultIQ(originalPacketRedirected); queueManager.passResponseToRequester(response); Assert.assertEquals(1, channelsEngine.size()); Packet redirected = channelsEngine.poll(); Assert.assertEquals(packet.getFrom(), redirected.getTo()); } @Test public void testOutgoingFederatedPacketsFromDifferentClientsUsingSameIdAreRoutedBackToOriginalSender() throws Exception { channelsEngine.clear(); IQ clientOnePacket = new IQ(); clientOnePacket.setID("1:some-request"); clientOnePacket.setFrom(new JID("romeo@montague.lit/street")); clientOnePacket.setTo(new JID("topics.capulet.lit")); clientOnePacket.setType(IQ.Type.get); clientOnePacket.getElement().addAttribute("remote-server-discover", "false"); IQ clientTwoPacket = new IQ(); clientTwoPacket.setID("1:some-request"); clientTwoPacket.setFrom(new JID("juliet@montague.lit/street")); clientTwoPacket.setTo(new JID("topics.capulet.lit")); clientTwoPacket.setType(IQ.Type.get); clientTwoPacket.getElement().addAttribute("remote-server-discover", "false"); queueManager.addChannelMap(new JID("topics.capulet.lit")); queueManager.process(clientOnePacket.createCopy()); queueManager.process(clientTwoPacket.createCopy()); IQ clientOneOriginalPacketRedirected = (IQ) channelsEngine.poll(); IQ clientTwoOriginalPacketRedirected = (IQ) channelsEngine.poll(); IQ clientOneResponse = IQ.createResultIQ(clientOneOriginalPacketRedirected); queueManager.passResponseToRequester(clientOneResponse); IQ clientTwoResponse = IQ.createResultIQ(clientTwoOriginalPacketRedirected); queueManager.passResponseToRequester(clientTwoResponse); Assert.assertEquals(2, channelsEngine.size()); Packet clientOneRedirected = channelsEngine.poll(); Packet clientTwoRedirected = channelsEngine.poll(); Assert.assertEquals(clientOnePacket.getFrom(), clientOneRedirected.getTo()); Assert.assertEquals(clientTwoPacket.getFrom(), clientTwoRedirected.getTo()); } @Test public void testOutgoingIqPacketsGetIdMapped() throws Exception { channelsEngine.clear(); String originalId = "id:12345"; IQ packet = new IQ(); packet.setFrom(new JID("romeo@montague.lit/street")); packet.setTo(new JID("topics.capulet.lit")); packet.setType(IQ.Type.get); packet.setID(originalId); packet.getElement().addAttribute("remote-server-discover", "false"); queueManager.addChannelMap(new JID("topics.capulet.lit")); queueManager.process(packet.createCopy()); IQ packetExternal = (IQ) channelsEngine.poll(); Assert.assertFalse(originalId.equals(packetExternal.getID())); IQ response = IQ.createResultIQ(packetExternal); queueManager.passResponseToRequester(response); IQ packetInternal = (IQ) channelsEngine.poll(); Assert.assertTrue(originalId.equals(packetInternal.getID())); } @Test public void testNonIqPacketsDoNotGetIdMapped() throws Exception { channelsEngine.clear(); String originalId = "id:12345"; Message packet = new Message(); packet.setFrom(new JID("romeo@montague.lit/street")); packet.setTo(new JID("topics.capulet.lit")); packet.getElement().addAttribute("remote-server-discover", "false"); packet.setID(originalId); queueManager.addChannelMap(new JID("topics.capulet.lit")); queueManager.process(packet.createCopy()); Message packetExternal = (Message) channelsEngine.poll(); Assert.assertTrue(originalId.equals(packetExternal.getID())); } @Test public void testIqResultPacketsDontGetIdMapped() throws Exception { channelsEngine.clear(); String originalId = "id:12345"; IQ packet = new IQ(); packet.setFrom(new JID("romeo@montague.lit/street")); packet.setTo(new JID("topics.capulet.lit")); packet.setType(IQ.Type.result); packet.setID(originalId); packet.getElement().addAttribute("remote-server-discover", "false"); queueManager.addChannelMap(new JID("topics.capulet.lit")); queueManager.process(packet.createCopy()); IQ packetExternal = (IQ) channelsEngine.poll(); Assert.assertTrue(originalId.equals(packetExternal.getID())); } @Test public void testIqErrorPacketsDontGetIdMapped() throws Exception { channelsEngine.clear(); String originalId = "id:12345"; IQ packet = new IQ(); packet.setFrom(new JID("romeo@montague.lit/street")); packet.setTo(new JID("topics.capulet.lit")); packet.setType(IQ.Type.error); packet.setID(originalId); packet.getElement().addAttribute("remote-server-discover", "false"); queueManager.addChannelMap(new JID("topics.capulet.lit")); queueManager.process(packet.createCopy()); IQ packetExternal = (IQ) channelsEngine.poll(); Assert.assertTrue(originalId.equals(packetExternal.getID())); } }