Search in sources :

Example 1 with ClusterInfoSession

use of com.nokia.dempsy.cluster.ClusterInfoSession in project Dempsy by Dempsy.

the class TestDempsy method testExpandingAndContractingKeySpace.

@Test
public void testExpandingAndContractingKeySpace() throws Throwable {
    Checker checker = new Checker() {

        @Override
        public void check(ApplicationContext context) throws Throwable {
            ClusterInfoSession session = null;
            try {
                // start things and verify that the init method was called
                Dempsy dempsy = (Dempsy) context.getBean("dempsy");
                TestMp mp = (TestMp) getMp(dempsy, "test-app", "test-cluster1");
                final ClusterId clusterId = new ClusterId("test-app", "test-cluster1");
                // verify we haven't called it again, not that there's really
                // a way to given the code
                assertEquals(1, mp.startCalls.get());
                // make sure that there are no Mps
                MetricGetters statsCollector = (MetricGetters) dempsy.getCluster(new ClusterId("test-app", "test-cluster1")).getNodes().get(0).getStatsCollector();
                // This will wait until the keySpace is up to the maxcount which is set (in the setup, below) to 100000
                assertTrue(poll(baseTimeoutMillis, statsCollector, new Condition<MetricGetters>() {

                    @Override
                    public boolean conditionMet(MetricGetters sc) {
                        return 100000 == sc.getMessageProcessorCount();
                    }
                }));
                // now push the cluster into backup node.
                ClusterInfoSession originalSession = dempsy.getCluster(new ClusterId("test-app", "test-cluster1")).getNodes().get(0).retouRteg().getClusterSession();
                ClusterInfoSessionFactory factory = dempsy.getClusterSessionFactory();
                session = TestUtils.stealShard(originalSession, factory, clusterId.asPath() + "/" + String.valueOf(0), baseTimeoutMillis);
                // If we got here then the MpContainer is on standby and the number of Mps should
                // drop to zero.
                assertTrue(poll(baseTimeoutMillis, statsCollector, new Condition<MetricGetters>() {

                    @Override
                    public boolean conditionMet(MetricGetters sc) {
                        return 0 == sc.getMessageProcessorCount();
                    }
                }));
                Thread.sleep(10);
                assertEquals(0, statsCollector.getMessageProcessorCount());
                // this should give control back over to the original session.
                session.stop();
                session = null;
                // If we got here then the MpContainer is no longer on standby and the number of Mps should
                // go back to the original amount.
                assertTrue(poll(baseTimeoutMillis, statsCollector, new Condition<MetricGetters>() {

                    @Override
                    public boolean conditionMet(MetricGetters sc) {
                        return 100000 == sc.getMessageProcessorCount();
                    }
                }));
                Thread.sleep(10);
                assertEquals(100000, statsCollector.getMessageProcessorCount());
            } finally {
                if (session != null)
                    session.stop();
            }
        }

        public String toString() {
            return "testExpandingAndContractingKeySpace";
        }

        public void setup() {
            KeySourceImpl.maxcount = 100000;
            System.setProperty("min_nodes_for_cluster", "1");
            System.setProperty("total_slots_for_cluster", "1");
        }
    };
    runAllCombinations("SinglestageWithKeyStoreAndExecutorApplicationActx.xml", checker);
}
Also used : Condition(com.nokia.dempsy.TestUtils.Condition) ClassPathXmlApplicationContext(org.springframework.context.support.ClassPathXmlApplicationContext) ApplicationContext(org.springframework.context.ApplicationContext) ClusterInfoSessionFactory(com.nokia.dempsy.cluster.ClusterInfoSessionFactory) ClusterId(com.nokia.dempsy.config.ClusterId) ClusterInfoSession(com.nokia.dempsy.cluster.ClusterInfoSession) MetricGetters(com.nokia.dempsy.monitoring.coda.MetricGetters) Test(org.junit.Test)

Example 2 with ClusterInfoSession

use of com.nokia.dempsy.cluster.ClusterInfoSession in project Dempsy by Dempsy.

the class TestUtils method stealShard.

/**
    * This method will grab the slot requested. It requires that it is already held by 
    * the session provided and that the entry there contains a valid DefaultRouterSlotInfo
    * which it will extract, modify and use to replace.
    * 
    * This will be accomplished by disrupting the session and trying to grab the slot
    * at the same time. It will try this over and over until it gets it, or until the
    * number of tries is exceeded.
    * 
    * @param originalSession is the session that will be disrupted in order to grab the shard.
    * @param factory is the {@link ClusterInfoSessionFactory} that will be used to create a new 
    * session that can be used to grab the slot.
    * @param shardPath is the path all the way to the directory containing the shard that you
    * want stolen.
    * 
    * @throws Assert when one of the test condition fails or grabbing the slot fails.
    */
public static ClusterInfoSession stealShard(final ClusterInfoSession originalSession, final ClusterInfoSessionFactory factory, final String shardPath, final long timeoutmillis) throws InterruptedException, ClusterInfoException {
    // get the current slot data to use as a template
    final DefaultRouterSlotInfo newSlot = (DefaultRouterSlotInfo) originalSession.getData(shardPath, null);
    final AtomicBoolean stillRunning = new AtomicBoolean(true);
    final AtomicBoolean failed = new AtomicBoolean(false);
    final ClusterInfoSession session = factory.createSession();
    Runnable slotGrabber = new Runnable() {

        @Override
        public void run() {
            try {
                Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
                boolean haveSlot = false;
                while (!haveSlot && stillRunning.get()) {
                    newSlot.setDestination(new JunkDestination());
                    if (session.mkdir(shardPath, newSlot, DirMode.EPHEMERAL) != null)
                        haveSlot = true;
                    Thread.yield();
                }
            } catch (ClusterInfoException e) {
                failed.set(true);
            } catch (RuntimeException re) {
                re.printStackTrace();
                failed.set(true);
            } finally {
                stillRunning.set(false);
            }
        }
    };
    try {
        new Thread(slotGrabber).start();
        boolean onStandby = false;
        long startTime = System.currentTimeMillis();
        while (!onStandby && timeoutmillis >= (System.currentTimeMillis() - startTime)) {
            ((DisruptibleSession) originalSession).disrupt();
            Thread.sleep(100);
            if (!stillRunning.get())
                onStandby = true;
        }
        assertTrue(onStandby);
        assertFalse(failed.get());
    } catch (InterruptedException ie) {
        session.stop();
        throw ie;
    } catch (Error cie) {
        session.stop();
        throw cie;
    } finally {
        stillRunning.set(false);
    }
    return session;
}
Also used : ClusterInfoException(com.nokia.dempsy.cluster.ClusterInfoException) DisruptibleSession(com.nokia.dempsy.cluster.DisruptibleSession) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ClusterInfoSession(com.nokia.dempsy.cluster.ClusterInfoSession) DefaultRouterSlotInfo(com.nokia.dempsy.router.DecentralizedRoutingStrategy.DefaultRouterSlotInfo)

Example 3 with ClusterInfoSession

use of com.nokia.dempsy.cluster.ClusterInfoSession in project Dempsy by Dempsy.

the class TestZookeeperClusterResilience method testSessionExpiredWithFullApp.

@Test
public void testSessionExpiredWithFullApp() throws Throwable {
    // now lets startup the server.
    ZookeeperTestServer server = null;
    final AtomicReference<ZookeeperSession> sessionRef = new AtomicReference<ZookeeperSession>();
    ZookeeperSession session = null;
    final AtomicLong processCount = new AtomicLong(0);
    Dempsy[] dempsy = new Dempsy[3];
    try {
        server = new ZookeeperTestServer();
        server.start();
        session = new ZookeeperSession("127.0.0.1:" + port, 5000) {

            @Override
            public WatcherProxy makeWatcherProxy(ClusterInfoWatcher w) {
                processCount.incrementAndGet();
                return super.makeWatcherProxy(w);
            }

            ;
        };
        sessionRef.set(session);
        final FullApplication app = new FullApplication();
        ApplicationDefinition ad = app.getTopology();
        // no calls yet
        assertEquals(0, processCount.intValue());
        dempsy[0] = getDempsyFor(new ClusterId(FullApplication.class.getSimpleName(), FullApplication.MyAdaptor.class.getSimpleName()), ad);
        dempsy[0].setClusterSessionFactory(new ZookeeperSessionFactory("127.0.0.1:" + port, 5000));
        dempsy[1] = getDempsyFor(new ClusterId(FullApplication.class.getSimpleName(), FullApplication.MyMp.class.getSimpleName()), ad);
        dempsy[1].setClusterSessionFactory(new ZookeeperSessionFactory("127.0.0.1:" + port, 5000));
        dempsy[2] = getDempsyFor(new ClusterId(FullApplication.class.getSimpleName(), FullApplication.MyRankMp.class.getSimpleName()), ad);
        //         dempsy[2].setClusterSessionFactory(new ZookeeperSessionFactory<ClusterInformation, SlotInformation>("127.0.0.1:" + port,5000));
        dempsy[2].setClusterSessionFactory(new ClusterInfoSessionFactory() {

            @Override
            public ClusterInfoSession createSession() throws ClusterInfoException {
                return sessionRef.get();
            }
        });
        // start everything in reverse order
        for (int i = 2; i >= 0; i--) dempsy[i].start();
        // make sure the final count is incrementing
        long curCount = app.finalMessageCount.get();
        assertTrue(poll(30000, curCount, new Condition<Long>() {

            @Override
            public boolean conditionMet(Long o) {
                return app.finalMessageCount.get() > (o + 100L);
            }
        }));
        logger.trace("Killing zookeeper");
        ZooKeeper origZk = session.zkref.get();
        ZookeeperTestServer.forceSessionExpiration(origZk);
        logger.trace("Killed zookeeper");
        // wait for the current session to go invalid
        assertTrue(poll(baseTimeoutMillis, origZk, new Condition<ZooKeeper>() {

            @Override
            public boolean conditionMet(ZooKeeper o) {
                return !o.getState().isAlive();
            }
        }));
        // make sure the final count is STILL incrementing
        curCount = app.finalMessageCount.get();
        assertTrue(poll(30000, curCount, new Condition<Long>() {

            @Override
            public boolean conditionMet(Long o) {
                return app.finalMessageCount.get() > (o + 100L);
            }
        }));
    } finally {
        if (server != null)
            server.shutdown();
        if (session != null)
            session.stop();
        for (int i = 0; i < dempsy.length; i++) if (dempsy[i] != null)
            dempsy[i].stop();
        for (int i = 0; i < dempsy.length; i++) if (dempsy[i] != null)
            assertTrue(dempsy[i].waitToBeStopped(baseTimeoutMillis));
    }
}
Also used : ClusterInfoException(com.nokia.dempsy.cluster.ClusterInfoException) ClusterInfoWatcher(com.nokia.dempsy.cluster.ClusterInfoWatcher) ClusterInfoSession(com.nokia.dempsy.cluster.ClusterInfoSession) Condition(com.nokia.dempsy.TestUtils.Condition) ClusterInfoSessionFactory(com.nokia.dempsy.cluster.ClusterInfoSessionFactory) ClusterId(com.nokia.dempsy.config.ClusterId) Dempsy(com.nokia.dempsy.Dempsy) AtomicReference(java.util.concurrent.atomic.AtomicReference) AtomicLong(java.util.concurrent.atomic.AtomicLong) ZooKeeper(org.apache.zookeeper.ZooKeeper) ApplicationDefinition(com.nokia.dempsy.config.ApplicationDefinition) AtomicLong(java.util.concurrent.atomic.AtomicLong) Test(org.junit.Test)

Example 4 with ClusterInfoSession

use of com.nokia.dempsy.cluster.ClusterInfoSession in project Dempsy by Dempsy.

the class TestDempsy method testFailedClusterManagerDuringKeyStoreCalls.

@Test
public void testFailedClusterManagerDuringKeyStoreCalls() throws Throwable {
    Checker checker = new Checker() {

        @Override
        public void check(ApplicationContext context) throws Throwable {
            ClusterInfoSession session = null;
            try {
                // start things and verify that the init method was called
                Dempsy dempsy = (Dempsy) context.getBean("dempsy");
                TestMp mp = (TestMp) getMp(dempsy, "test-app", "test-cluster1");
                final ClusterId clusterId = new ClusterId("test-app", "test-cluster1");
                // verify we haven't called it again, not that there's really
                // a way to given the code
                assertEquals(1, mp.startCalls.get());
                // make sure that there are no Mps
                MetricGetters statsCollector = (MetricGetters) dempsy.getCluster(new ClusterId("test-app", "test-cluster1")).getNodes().get(0).getStatsCollector();
                assertTrue(poll(baseTimeoutMillis, statsCollector, new Condition<MetricGetters>() {

                    @Override
                    public boolean conditionMet(MetricGetters sc) {
                        return 100000 == sc.getMessageProcessorCount();
                    }
                }));
                // now there's 100000 mps in the container created from the KeySource. So we steal the 
                // shard and force if offline but continuously disrupt it while it tries to come
                // back up.
                // now push the cluster into backup node.
                ClusterInfoSession originalSession = dempsy.getCluster(new ClusterId("test-app", "test-cluster1")).getNodes().get(0).retouRteg().getClusterSession();
                ClusterInfoSessionFactory factory = dempsy.getClusterSessionFactory();
                String path = clusterId.asPath() + "/" + String.valueOf(0);
                session = TestUtils.stealShard(originalSession, factory, path, baseTimeoutMillis);
                DefaultRouterSlotInfo si = (DefaultRouterSlotInfo) session.getData(path, null);
                // checks to see who actually has the slot.
                assertTrue(si.getDestination() instanceof JunkDestination);
                // we will keep disrupting the session but we should still end up with zero mps.
                for (int i = 0; i < 100; i++) {
                    ((DisruptibleSession) originalSession).disrupt();
                    Thread.sleep(1);
                }
                // now wait until we get to zero.
                assertTrue(poll(baseTimeoutMillis, statsCollector, new Condition<MetricGetters>() {

                    @Override
                    public boolean conditionMet(MetricGetters sc) {
                        return 0 == sc.getMessageProcessorCount();
                    }
                }));
                Thread.sleep(10);
                assertEquals(0, statsCollector.getMessageProcessorCount());
                // ok. Now we will close the session that's holding the shard and allow the container
                // to re-establish control of that shard. During the KeyStore reinstantiation of the 
                // MPs we will be disrupting the session.
                session.stop();
                for (int i = 0; i < 100; i++) {
                    ((DisruptibleSession) originalSession).disrupt();
                    Thread.sleep(1);
                }
                // Now we should get back to 100000 Mps.
                poll(baseTimeoutMillis, statsCollector, new Condition<MetricGetters>() {

                    @Override
                    public boolean conditionMet(MetricGetters sc) {
                        return 100000 == sc.getMessageProcessorCount();
                    }
                });
                assertEquals(100000, statsCollector.getMessageProcessorCount());
            } finally {
                if (session != null)
                    session.stop();
            }
        }

        public String toString() {
            return "testFailedClusterManagerDuringKeyStoreCalls";
        }

        public void setup() {
            KeySourceImpl.maxcount = 100000;
            System.setProperty("min_nodes_for_cluster", "1");
            System.setProperty("total_slots_for_cluster", "1");
        }
    };
    runAllCombinations("SinglestageWithKeyStoreAndExecutorApplicationActx.xml", checker);
}
Also used : Condition(com.nokia.dempsy.TestUtils.Condition) JunkDestination(com.nokia.dempsy.TestUtils.JunkDestination) ClusterInfoSessionFactory(com.nokia.dempsy.cluster.ClusterInfoSessionFactory) ClusterId(com.nokia.dempsy.config.ClusterId) DisruptibleSession(com.nokia.dempsy.cluster.DisruptibleSession) ClassPathXmlApplicationContext(org.springframework.context.support.ClassPathXmlApplicationContext) ApplicationContext(org.springframework.context.ApplicationContext) ClusterInfoSession(com.nokia.dempsy.cluster.ClusterInfoSession) DefaultRouterSlotInfo(com.nokia.dempsy.router.DecentralizedRoutingStrategy.DefaultRouterSlotInfo) MetricGetters(com.nokia.dempsy.monitoring.coda.MetricGetters) Test(org.junit.Test)

Example 5 with ClusterInfoSession

use of com.nokia.dempsy.cluster.ClusterInfoSession in project Dempsy by Dempsy.

the class TestFullApp method testStartForceMpDisconnectStop.

@Test
public void testStartForceMpDisconnectStop() throws Throwable {
    ClassPathXmlApplicationContext actx = null;
    Dempsy dempsy = null;
    try {
        logger.debug("Starting up the appliction context ...");
        actx = new ClassPathXmlApplicationContext(ctx);
        actx.registerShutdownHook();
        final FullApplication app = (FullApplication) actx.getBean("app");
        dempsy = (Dempsy) actx.getBean("dempsy");
        // Override the cluster session factory to keep track of the sessions asked for.
        // This is so that I can grab the ZookeeperSession that's being instantiated by
        // the MyMp cluster.
        zookeeperCluster = null;
        dempsy.setClusterSessionFactory(new ZookeeperSessionFactory(System.getProperty("zk_connect"), 5000) {

            int sessionCount = 0;

            @Override
            public synchronized ClusterInfoSession createSession() throws ClusterInfoException {
                sessionCount++;
                ClusterInfoSession ret = super.createSession();
                if (sessionCount == 2)
                    zookeeperCluster = (ZookeeperSession) ret;
                return ret;
            }
        });
        dempsy.start();
        Dempsy.Application.Cluster cluster = dempsy.getCluster(new ClusterId(FullApplication.class.getSimpleName(), MyAdaptor.class.getSimpleName()));
        Dempsy.Application.Cluster.Node node = cluster.getNodes().get(0);
        final StatsCollector collector = node.getStatsCollector();
        // this checks that the throughput works.
        assertTrue(poll(baseTimeoutMillis * 5, app, new Condition<Object>() {

            @Override
            public boolean conditionMet(Object o) {
                return app.finalMessageCount.get() > 10;
            }
        }));
        assertNotNull(zookeeperCluster);
        assertEquals(0, ((MetricGetters) collector).getDiscardedMessageCount());
        assertEquals(0, ((MetricGetters) collector).getMessageFailedCount());
        // ok ... so now we have stuff going all the way through. let's kick
        // the middle Mp's zookeeper cluster and see what happens.
        ZooKeeper origZk = zookeeperCluster.zkref.get();
        long sessionid = origZk.getSessionId();
        ZooKeeper killer = new ZooKeeper(System.getProperty("zk_connect"), 5000, new Watcher() {

            @Override
            public void process(WatchedEvent arg0) {
            }
        }, sessionid, null);
        // tricks the server into expiring the other session
        killer.close();
        //         // we should be getting failures now ... 
        //         // but it's possible that it can reconnect prior to actually seeing an error so if this 
        //         //   fails frequently we need to remove this test.
        //         assertTrue(poll(baseTimeoutMillis, app, new Condition()
        //         {
        //            @Override
        //            public boolean conditionMet(Object o)
        //            {
        //               return collector.getMessageFailedCount() > 1;
        //            }
        //         }));
        //... and then recover.
        // get the MyMp prototype
        cluster = dempsy.getCluster(new ClusterId(FullApplication.class.getSimpleName(), MyMp.class.getSimpleName()));
        node = cluster.getNodes().get(0);
        final MyMp prototype = (MyMp) node.getMpContainer().getPrototype();
        // so let's see where we are
        final long interimMessageCount = prototype.myMpReceived.get();
        // and now we should eventually get more as the session recovers.
        assertTrue(poll(baseTimeoutMillis * 5, app, new Condition<Object>() {

            @Override
            public boolean conditionMet(Object o) {
                return prototype.myMpReceived.get() > interimMessageCount + 100;
            }
        }));
    } finally {
        if (dempsy != null)
            dempsy.stop();
        if (actx != null)
            actx.close();
        if (dempsy != null)
            assertTrue(dempsy.waitToBeStopped(baseTimeoutMillis));
    }
}
Also used : Condition(com.nokia.dempsy.TestUtils.Condition) ClusterId(com.nokia.dempsy.config.ClusterId) StatsCollector(com.nokia.dempsy.monitoring.StatsCollector) Dempsy(com.nokia.dempsy.Dempsy) ClusterInfoException(com.nokia.dempsy.cluster.ClusterInfoException) Watcher(org.apache.zookeeper.Watcher) MyMp(com.nokia.dempsy.cluster.zookeeper.FullApplication.MyMp) WatchedEvent(org.apache.zookeeper.WatchedEvent) ZooKeeper(org.apache.zookeeper.ZooKeeper) ClassPathXmlApplicationContext(org.springframework.context.support.ClassPathXmlApplicationContext) ClusterInfoSession(com.nokia.dempsy.cluster.ClusterInfoSession) Test(org.junit.Test)

Aggregations

ClusterInfoSession (com.nokia.dempsy.cluster.ClusterInfoSession)8 ClusterId (com.nokia.dempsy.config.ClusterId)7 Test (org.junit.Test)6 Dempsy (com.nokia.dempsy.Dempsy)5 Condition (com.nokia.dempsy.TestUtils.Condition)5 ClassPathXmlApplicationContext (org.springframework.context.support.ClassPathXmlApplicationContext)5 ClusterInfoException (com.nokia.dempsy.cluster.ClusterInfoException)4 ClusterInfoSessionFactory (com.nokia.dempsy.cluster.ClusterInfoSessionFactory)4 ZooKeeper (org.apache.zookeeper.ZooKeeper)3 DisruptibleSession (com.nokia.dempsy.cluster.DisruptibleSession)2 MyMp (com.nokia.dempsy.cluster.zookeeper.FullApplication.MyMp)2 ApplicationDefinition (com.nokia.dempsy.config.ApplicationDefinition)2 StatsCollector (com.nokia.dempsy.monitoring.StatsCollector)2 MetricGetters (com.nokia.dempsy.monitoring.coda.MetricGetters)2 DefaultRouterSlotInfo (com.nokia.dempsy.router.DecentralizedRoutingStrategy.DefaultRouterSlotInfo)2 ApplicationContext (org.springframework.context.ApplicationContext)2 JunkDestination (com.nokia.dempsy.TestUtils.JunkDestination)1 ClusterInfoWatcher (com.nokia.dempsy.cluster.ClusterInfoWatcher)1 LocalClusterSessionFactory (com.nokia.dempsy.cluster.invm.LocalClusterSessionFactory)1 ClusterDefinition (com.nokia.dempsy.config.ClusterDefinition)1