package io.urmia.naming.service; /** * * Copyright 2014 by Amin Abbaspour * * This file is part of Urmia.io * * Urmia.io is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Urmia.io is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Urmia.io. If not, see <http://www.gnu.org/licenses/>. */ import com.google.common.base.Optional; import com.google.common.base.Predicates; import com.google.common.collect.Lists; import com.google.common.collect.Ordering; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.retry.ExponentialBackoffRetry; import org.apache.curator.utils.CloseableUtils; import org.apache.curator.x.discovery.ServiceInstance; import org.apache.curator.x.discovery.ServiceType; import org.apache.zookeeper.server.NIOServerCnxnFactory; import org.apache.zookeeper.server.ServerCnxnFactory; import org.apache.zookeeper.server.ZooKeeperServer; import org.junit.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.urmia.naming.model.NodeType; import java.io.File; import java.net.InetSocketAddress; import java.util.List; import java.util.UUID; import static org.junit.Assert.*; import static io.urmia.naming.model.NodeType.*; public class ZkNamingServiceTest { private static final Logger log = LoggerFactory.getLogger(ZkNamingServiceTest.class); private static final int ZK_PORT = 21818; private static final String ZK_SERVER = "localhost:" + ZK_PORT; private static ServerCnxnFactory standaloneServerFactory; static CuratorFramework client; static ZooKeeperServer server; static NamingService ns; @BeforeClass public static void startZooKeeperServer() throws Exception { log.info("startZooKeeperServer on: {}", ZK_SERVER); int clientPort = ZK_PORT; // none-standard int numConnections = 5; int tickTime = 2000; //String dataDirectory = System.getProperty("java.io.tmpdir"); String dataDirectory = "/tmp/ZkNamingServiceTest"; log.info("dataDirectory: {}", dataDirectory); File dir = new File(dataDirectory, "zookeeper").getAbsoluteFile(); server = new ZooKeeperServer(dir, dir, tickTime); standaloneServerFactory = NIOServerCnxnFactory.createFactory(new InetSocketAddress(clientPort), numConnections); standaloneServerFactory.startup(server); // start the server. log.info("temp zk server is up..."); client = CuratorFrameworkFactory.newClient(ZK_SERVER, new ExponentialBackoffRetry(1000, 3)); client.start(); ns = new ZkNamingServiceImpl(client, 1); Thread.sleep(1000); List<NodeType> types = ns.queryTypes(); for(NodeType t : types) deleteAll(t); } @AfterClass public static void stopZooKeeperServer() { CloseableUtils.closeQuietly(client); server.shutdown(); log.info("stopZooKeeperServer..."); try { standaloneServerFactory.shutdown(); }catch (Exception e) { log.info("e: ", e.getMessage()); } log.info("stopZooKeeperServer stopped"); } @Test public void testSimpleAddFindSingleNode2() throws Exception { String id = UUID.randomUUID().toString(); ServiceInstance<NodeType> si = ServiceInstance.<NodeType>builder() .address("localhost") .name(NodeType.JRS.name()) .id(id) .port(NodeType.JRS.defaultPort) .payload(NodeType.JRS) .serviceType(ServiceType.PERMANENT) .build(); ns.add(si); log.debug("added node: {}", si); Thread.sleep(100); ServiceInstance<NodeType> hostNode = ns.get(NodeType.JRS, id); log.info("nodes: {}", hostNode); assertNotNull(hostNode); assertEquals(NodeType.JRS, hostNode.getPayload()); assertEquals(NodeType.JRS.name(), hostNode.getName()); assertEquals("localhost", hostNode.getAddress()); assertEquals(id, hostNode.getId()); } private static void deleteAll(NodeType t) throws Exception { for(ServiceInstance<NodeType> si : ns.list(t, Predicates.<ServiceInstance<NodeType>>alwaysTrue())) { log.info("removing: {}", si); ns.remove(si); } } @Test public void testWhoAmI_1instance() throws Exception { deleteAll(ODS); ServiceInstance<NodeType> b = ns.builder(ODS, ServiceType.STATIC).build(); ns.add(b); Optional<ServiceInstance<NodeType>> opt = ns.whoAmI(ODS, false); assertTrue(opt.isPresent()); ServiceInstance<NodeType> si = opt.get(); assertEquals(ODS, si.getPayload()); assertEquals(b.getName(), si.getName()); assertEquals(b.getId(), si.getId()); } @Test public void testWhoAmI_2instance_sort_Port() throws Exception { deleteAll(ODS); ServiceInstance<NodeType> b1 = ns.builder(ODS, ServiceType.STATIC).id("testWhoAmI_2instance_sort_Port-id1").build(); ns.add(b1); ServiceInstance<NodeType> b2 = ns.builder(ODS, ServiceType.STATIC).id("testWhoAmI_2instance_sort_Port-id2").build(); ns.add(b2); Optional<ServiceInstance<NodeType>> opt = ns.whoAmI(ODS, false); assertTrue(opt.isPresent()); ServiceInstance<NodeType> si = opt.get(); assertEquals(ODS, si.getPayload()); assertEquals(b1.getName(), si.getName()); assertEquals(b1.getId(), si.getId()); assertEquals(ODS.defaultPort, si.getPort().intValue()); } @Test public void testWhoAmI_2instance_1running() throws Exception { deleteAll(ODS); ServiceInstance<NodeType> b1 = ns.builder(ODS, ServiceType.STATIC).id("testWhoAmI_2instance_1running-id1").build(); ns.add(b1); ServiceInstance<NodeType> b2 = ns.builder(ODS, ServiceType.STATIC).id("testWhoAmI_2instance_1running-id2").build(); ns.add(b2); ns.register(b1); Optional<ServiceInstance<NodeType>> opt = ns.whoAmI(ODS, false); assertTrue(opt.isPresent()); ServiceInstance<NodeType> si = opt.get(); assertEquals(ODS, si.getPayload()); assertEquals(b2.getName(), si.getName()); assertEquals(b2.getId(), si.getId()); assertEquals(b2.getPort().intValue(), ODS.defaultPort + 1); ns.deregister(b1); } private ServiceInstance<NodeType> buildSI(NodeType type, String host, int port) throws Exception { return buildSI(type, UUID.randomUUID().toString(), host, port); } private ServiceInstance<NodeType> buildSI(NodeType type, String id, String host, int port) throws Exception { return ServiceInstance.<NodeType>builder() .id(id) .name(type.name()) .address(host) .payload(type) .port(port) .build(); } @Test public void testNodeTypeComparatorTest_port() throws Exception { ServiceInstance<NodeType> i1_8080 = buildSI(ODS, "localhost", 8080); ServiceInstance<NodeType> i2_8081 = buildSI(ODS, "localhost", 8081); int c = ZkNamingServiceImpl.nodeTypeComparator.compare(i1_8080, i2_8081); assertTrue(c < 0); } @Test public void testNodeTypeComparatorTest_list() throws Exception { ServiceInstance<NodeType> i1_8080 = buildSI(ODS, "localhost", 8080); ServiceInstance<NodeType> i2_8081 = buildSI(ODS, "localhost", 8081); List<ServiceInstance<NodeType>> l1 = Lists.newArrayList(i1_8080, i2_8081); List<ServiceInstance<NodeType>> l2 = Lists.newArrayList(i2_8081, i1_8080); List<ServiceInstance<NodeType>> s1 = Ordering.from(ZkNamingServiceImpl.nodeTypeComparator).immutableSortedCopy(l1); List<ServiceInstance<NodeType>> s2 = Ordering.from(ZkNamingServiceImpl.nodeTypeComparator).immutableSortedCopy(l2); assertFalse(s1.isEmpty()); assertFalse(s2.isEmpty()); assertEquals(2, s1.size()); assertEquals(2, s2.size()); assertEquals(i1_8080, s1.get(0)); assertEquals(i1_8080, s2.get(0)); assertEquals(i2_8081, s1.get(1)); assertEquals(i2_8081, s2.get(1)); } }