package com.rayo.storage; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.Arrays; import java.util.HashSet; import java.util.List; import org.junit.Test; import com.rayo.server.storage.ApplicationNotFoundException; import com.rayo.server.storage.DefaultGatewayStorageService; import com.rayo.server.storage.RayoNodeNotFoundException; import com.rayo.server.storage.model.Application; import com.rayo.server.storage.model.RayoNode; import com.rayo.storage.lb.RoundRobinLoadBalancer; import com.rayo.storage.util.JIDImpl; import com.voxeo.moho.util.ParticipantIDParser; import com.voxeo.servlet.xmpp.JID; public abstract class BaseGatewayStorageServiceTest { protected DefaultGatewayStorageService storageService; protected RoundRobinLoadBalancer loadBalancer; @Test public void testRegisterRayoNode() throws Exception { String[] platforms = new String[]{"staging"}; RayoNode node1 = buildRayoNode("node1",platforms); assertEquals(0, storageService.getRayoNodes("staging").size()); storageService.registerRayoNode(node1); assertEquals(1, storageService.getRayoNodes("staging").size()); platforms = new String[]{"production", "test"}; RayoNode node2 = buildRayoNode("node2",platforms); storageService.registerRayoNode(node2); RayoNode node3 = buildRayoNode("node3",platforms); storageService.registerRayoNode(node3); assertEquals(2, storageService.getRayoNodes("test").size()); storageService.unregisterRayoNode(node3.getHostname()); assertEquals(1, storageService.getRayoNodes("test").size()); storageService.unregisterRayoNode(node1.getHostname()); assertEquals(0, storageService.getRayoNodes("staging").size()); } @Test public void testUpdateRayoNode() throws Exception { String[] platforms = new String[]{"staging"}; RayoNode node = buildRayoNode("node1", platforms); node.setIpAddress("127.0.0.1"); node.setWeight(30); node.setPriority(1); RayoNode stored = storageService.registerRayoNode(node); assertEquals(stored.toString(), node.toString()); RayoNode newnode = buildRayoNode("node1", platforms); node.setIpAddress("127.0.0.1"); node.setWeight(30); node.setPriority(1); stored = storageService.updateRayoNode(newnode); assertEquals(stored.toString(), newnode.toString()); assertFalse(stored.toString().equals(node.toString())); } @Test public void testGetRayoNodes() throws Exception { String[] platforms = new String[]{"staging"}; RayoNode node1 = buildRayoNode("node1",platforms); storageService.registerRayoNode(node1); List<RayoNode> nodes = storageService.getRayoNodes("staging"); assertEquals(nodes.size(),1); assertEquals(nodes.get(0).getHostname(), "node1"); } @Test public void testRegisterRayoNodeTwiceHasNoEffect() throws Exception { String[] platforms = new String[]{"staging"}; RayoNode node1 = buildRayoNode("node1",platforms); RayoNode node2 = buildRayoNode("node1",platforms); assertEquals(0, storageService.getRayoNodes("staging").size()); storageService.registerRayoNode(node1); storageService.registerRayoNode(node2); assertEquals(1, storageService.getRayoNodes("staging").size()); } @Test(expected=RayoNodeNotFoundException.class) public void testUnregisterUnexistentRayoNode() throws Exception { String[] platforms = new String[]{"staging"}; RayoNode node1 = buildRayoNode("node1",platforms); storageService.unregisterRayoNode(node1.getHostname()); } @Test public void testMultipleRegisterAndUnregister() throws Exception { String[] platforms = new String[]{"staging"}; RayoNode node1 = buildRayoNode("node1",platforms); storageService.registerRayoNode(node1); assertEquals(1, storageService.getRayoNodes("staging").size()); storageService.unregisterRayoNode(node1.getHostname()); assertEquals(0, storageService.getRayoNodes("staging").size()); storageService.registerRayoNode(node1); List<RayoNode> nodes = storageService.getRayoNodes("staging"); assertEquals(nodes.size(),1); assertEquals(nodes.get(0).getHostname(), "node1"); } @Test public void testBindClient() throws Exception { Application application = buildApplication("voxeo"); storageService.registerApplication(application); JID clientJid = new JIDImpl("client@jabber.org/a"); assertNull(storageService.getPlatformForClient(clientJid)); storageService.registerClient(clientJid); assertEquals("staging", storageService.getPlatformForClient(clientJid)); storageService.unregisterClient(clientJid); assertNull(storageService.getPlatformForClient(clientJid)); storageService.registerClient(clientJid); assertEquals("staging", storageService.getPlatformForClient(clientJid)); } @Test(expected=ApplicationNotFoundException.class) public void testBindClientWithoutApplication() throws Exception { JID clientJid = new JIDImpl("test@jabber.org/a"); assertNull(storageService.getPlatformForClient(clientJid)); storageService.registerClient(clientJid); } @Test public void testRegisterCalls() throws Exception { JID clientJid = new JIDImpl("test@jabber.org"); assertEquals(0, storageService.getCallsForClient(clientJid.toString()).size()); String[] platforms = new String[]{"staging"}; RayoNode node = buildRayoNode("node",platforms); storageService.registerRayoNode(node); // moho://ip:port/<type>/<callid> String uid = String.valueOf(Math.abs(new com.eaio.uuid.UUID().getTime())); String callId = ParticipantIDParser.encode("moho://127.0.0.1:5060/1/" + uid); storageService.registerCall(callId, clientJid.toString()); assertEquals(1, storageService.getCallsForClient(clientJid.toString()).size()); storageService.unregistercall(callId); assertEquals(0, storageService.getCallsForClient(clientJid.toString()).size()); } @Test public void testRegisterMixers() throws Exception { String[] platforms = new String[]{"staging"}; RayoNode node = buildRayoNode("node",platforms); storageService.registerRayoNode(node); assertNull(storageService.getMixer("1234")); storageService.registerMixer("1234", node.getHostname()); assertNotNull(storageService.getMixer("1234")); assertEquals(storageService.getMixer("1234").getNodeJid(),node.getHostname()); storageService.unregisterMixer("1234"); assertNull(storageService.getMixer("1234")); } @Test public void testAddAndRemoveCallsFromMixers() throws Exception { String[] platforms = new String[]{"staging"}; RayoNode node = buildRayoNode("node",platforms); storageService.registerRayoNode(node); storageService.registerMixer("1234", node.getHostname()); assertNotNull(storageService.getMixer("1234")); assertTrue(storageService.getMixer("1234").getParticipants().isEmpty()); storageService.addCallToMixer("a", "1234"); assertEquals(storageService.getMixer("1234").getParticipants().size(), 1); storageService.addCallToMixer("b", "1234"); assertEquals(storageService.getMixer("1234").getParticipants().size(), 2); storageService.removeCallFromMixer("a", "1234"); assertEquals(storageService.getMixer("1234").getParticipants().size(), 1); storageService.removeCallFromMixer("b", "1234"); assertTrue(storageService.getMixer("1234").getParticipants().isEmpty()); } @Test public void testAddAndRemoveVerbsFromMixers() throws Exception { String[] platforms = new String[]{"staging"}; RayoNode node = buildRayoNode("node",platforms); storageService.registerRayoNode(node); storageService.registerMixer("1234", node.getHostname()); assertNotNull(storageService.getMixer("1234")); assertTrue(storageService.getVerbs("1234").isEmpty()); storageService.addVerbToMixer("verb1", "app1@jid.com", "1234"); assertEquals(storageService.getVerbs("1234").size(), 1); storageService.addVerbToMixer("verb2", "app2@jid.com", "1234"); assertEquals(storageService.getVerbs("1234").size(), 2); storageService.removeVerbFromMixer("verb1", "1234"); assertEquals(storageService.getVerbs("1234").size(), 1); storageService.removeVerbFromMixer("verb2", "1234"); assertTrue(storageService.getVerbs("1234").isEmpty()); } @Test public void testFindVerbsOnMixer() throws Exception { String[] platforms = new String[]{"staging"}; RayoNode node = buildRayoNode("node",platforms); storageService.registerRayoNode(node); storageService.registerMixer("1234", node.getHostname()); storageService.addVerbToMixer("verb1", "app1@jid.com", "1234"); storageService.addVerbToMixer("verb2", "app2@jid.com", "1234"); assertNotNull(storageService.getVerb("1234", "verb1")); assertNotNull(storageService.getVerb("1234", "verb2")); assertNull(storageService.getVerb("1234", "abcd")); assertNull(storageService.getVerb("lalala", "abcd")); storageService.removeVerbFromMixer("verb1", "1234"); assertNull(storageService.getVerb("1234", "verb1")); } @Test public void testFindCallsForRayoNode() throws Exception { JID clientJid = new JIDImpl("test@jabber.org"); String[] platforms = new String[]{"staging"}; RayoNode node = buildRayoNode("node",platforms); assertEquals(0, storageService.getCallsForNode(node.getHostname()).size()); storageService.registerRayoNode(node); // moho://ip:port/<type>/<callid> String uid = String.valueOf(Math.abs(new com.eaio.uuid.UUID().getTime())); String callId = ParticipantIDParser.encode("moho://127.0.0.1:5060/1/" + uid); storageService.registerCall(callId, clientJid.toString()); assertEquals(1, storageService.getCallsForNode(node.getHostname()).size()); storageService.unregistercall(callId); assertEquals(0, storageService.getCallsForNode(node.getHostname()).size()); } @Test public void testFindNodeForCall() throws Exception { JID clientJid = new JIDImpl("test@jabber.org"); assertEquals(0, storageService.getCallsForClient(clientJid.toString()).size()); String[] platforms = new String[]{"staging"}; RayoNode node = buildRayoNode("node",platforms); storageService.registerRayoNode(node); // moho://ip:port/<type>/<callid> String uid = String.valueOf(Math.abs(new com.eaio.uuid.UUID().getTime())); String callId = ParticipantIDParser.encode("moho://127.0.0.1:5060/1/" + uid); storageService.registerCall(callId, clientJid.toString()); assertEquals(storageService.getRayoNode(callId), "node"); storageService.unregistercall(callId); assertNull(storageService.getRayoNode(callId)); } @Test public void testFindClientJidForCall() throws Exception { JID clientJid = new JIDImpl("test@jabber.org"); assertEquals(0, storageService.getCallsForClient(clientJid.toString()).size()); String[] platforms = new String[]{"staging"}; RayoNode node = buildRayoNode("node",platforms); storageService.registerRayoNode(node); // moho://ip:port/<type>/<callid> String uid = String.valueOf(Math.abs(new com.eaio.uuid.UUID().getTime())); String callId = ParticipantIDParser.encode("moho://127.0.0.1:5060/1/" + uid); storageService.registerCall(callId, clientJid.toString()); assertEquals(storageService.getclientJID(callId), clientJid.toString()); storageService.unregistercall(callId); assertNull(storageService.getclientJID(callId)); } @Test public void testClientResources() throws Exception { Application application = buildApplication("voxeo"); storageService.registerApplication(application); JID clientJid1 = new JIDImpl("client@jabber.org/a"); assertEquals(0, storageService.getResourcesForClient(clientJid1.getBareJID().toString()).size()); storageService.registerClient(clientJid1); assertEquals(1, storageService.getResourcesForClient(clientJid1.getBareJID().toString()).size()); assertEquals(storageService.getResourcesForClient(clientJid1.getBareJID().toString()).iterator().next(),"a"); JID clientJid2 = new JIDImpl("client@jabber.org/b"); storageService.registerClient(clientJid2); assertEquals(2, storageService.getResourcesForClient(clientJid1.getBareJID().toString()).size()); assertEquals(storageService.getResourcesForClient(clientJid1.getBareJID().toString()).toString(),"[a, b]"); storageService.unregisterClient(clientJid2); assertEquals(1, storageService.getResourcesForClient(clientJid1.getBareJID().toString()).size()); assertEquals(storageService.getResourcesForClient(clientJid1.getBareJID().toString()).iterator().next(),"a"); storageService.unregisterClient(clientJid1); assertEquals(0, storageService.getResourcesForClient(clientJid1.getBareJID().toString()).size()); } @Test public void testGetClientResources() throws Exception { Application application = buildApplication("voxeo"); storageService.registerApplication(application); Application application2 = buildApplication("test", "test@jabber.org"); storageService.registerApplication(application2); assertEquals(storageService.getClients().size(),0); JID clientJid1 = new JIDImpl("client@jabber.org/a"); storageService.registerClient(clientJid1); JID clientJid2 = new JIDImpl("client@jabber.org/b"); storageService.registerClient(clientJid2); JID clientJid3 = new JIDImpl("test@jabber.org/a"); storageService.registerClient(clientJid3); List<String> resources = storageService.getClients(); assertEquals(2, resources.size()); assertTrue(resources.contains("client@jabber.org")); assertTrue(resources.contains("test@jabber.org")); storageService.unregisterClient(clientJid1); storageService.unregisterClient(clientJid2); storageService.unregisterClient(clientJid3); assertEquals(storageService.getClients().size(),0); } @Test public void testRayoNodesLoadBalancing() throws Exception { assertNull(loadBalancer.pickRayoNode("staging")); String[] platforms = new String[]{"staging"}; RayoNode node1 = buildRayoNode("node1",platforms); storageService.registerRayoNode(node1); RayoNode node2 = buildRayoNode("node2",platforms); storageService.registerRayoNode(node2); RayoNode node3 = buildRayoNode("node3",platforms); storageService.registerRayoNode(node3); assertEquals(loadBalancer.pickRayoNode("staging"), node1); assertEquals(loadBalancer.pickRayoNode("staging"), node2); assertEquals(loadBalancer.pickRayoNode("staging"), node3); assertEquals(loadBalancer.pickRayoNode("staging"), node1); assertEquals(loadBalancer.pickRayoNode("staging"), node2); assertEquals(loadBalancer.pickRayoNode("staging"), node3); storageService.unregisterRayoNode(node2.getHostname()); assertEquals(loadBalancer.pickRayoNode("staging"), node1); assertEquals(loadBalancer.pickRayoNode("staging"), node3); assertEquals(loadBalancer.pickRayoNode("staging"), node1); assertEquals(loadBalancer.pickRayoNode("staging"), node3); } @Test public void testClientResourcesLoadBalancing() throws Exception{ Application application = buildApplication("voxeo"); storageService.registerApplication(application); JID clientJid = new JIDImpl("client@jabber.org/a"); assertNull(loadBalancer.pickClientResource(clientJid.getBareJID().toString())); storageService.registerClient(clientJid); JID clientJid2 = new JIDImpl("client@jabber.org/b"); storageService.registerClient(clientJid2); JID clientJid3 = new JIDImpl("client@jabber.org/c"); storageService.registerClient(clientJid3); assertEquals(loadBalancer.pickClientResource(clientJid.getBareJID().toString()),"a"); assertEquals(loadBalancer.pickClientResource(clientJid.getBareJID().toString()),"b"); assertEquals(loadBalancer.pickClientResource(clientJid.getBareJID().toString()),"c"); assertEquals(loadBalancer.pickClientResource(clientJid.getBareJID().toString()),"a"); assertEquals(loadBalancer.pickClientResource(clientJid.getBareJID().toString()),"b"); assertEquals(loadBalancer.pickClientResource(clientJid.getBareJID().toString()),"c"); storageService.unregisterClient(clientJid2); assertEquals(loadBalancer.pickClientResource(clientJid.getBareJID().toString()),"a"); assertEquals(loadBalancer.pickClientResource(clientJid.getBareJID().toString()),"c"); assertEquals(loadBalancer.pickClientResource(clientJid.getBareJID().toString()),"a"); assertEquals(loadBalancer.pickClientResource(clientJid.getBareJID().toString()),"c"); } @Test public void testFindPlatforms() throws Exception { String[] platforms = new String[]{"staging", "production"}; RayoNode node1 = buildRayoNode("node1",platforms); storageService.registerRayoNode(node1); assertEquals(storageService.getRegisteredPlatforms().size(), 2); assertTrue(storageService.getRegisteredPlatforms().contains("staging")); assertTrue(storageService.getRegisteredPlatforms().contains("production")); storageService.unregisterRayoNode(node1.getHostname()); // Platforms are not removed once added assertEquals(storageService.getRegisteredPlatforms().size(), 2); } @Test public void testNoPlatformsRegistered() throws Exception { assertEquals(storageService.getRegisteredPlatforms().size(), 0); } private RayoNode buildRayoNode(String hostname,String[] platforms) { List<String> list = Arrays.asList(platforms); return new RayoNode(hostname, "127.0.0.1", new HashSet<String>(list)); } private Application buildApplication(String appId) { return buildApplication(appId, "client@jabber.org"); } private Application buildApplication(String appId, String jid) { return buildApplication(appId, jid, "staging"); } private Application buildApplication(String appId, String jid, String platform) { Application application = new Application(appId, jid, platform); application.setName("test"); application.setAccountId("zytr"); application.setPermissions("read,write"); return application; } }