org.apache.solr.cloud.ZkSolrClientTest.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.solr.cloud.ZkSolrClientTest.java

Source

package org.apache.solr.cloud;

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with this
 * work for additional information regarding copyright ownership. The ASF
 * licenses this file to You under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

import java.io.File;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

import junit.framework.Assert;

import org.apache.solr.common.cloud.SolrZkClient;
import org.apache.solr.util.AbstractSolrTestCase;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.junit.AfterClass;
import org.junit.BeforeClass;

public class ZkSolrClientTest extends AbstractSolrTestCase {
    private static final boolean DEBUG = false;

    @BeforeClass
    public static void beforeClass() throws Exception {
        initCore("solrconfig.xml", "schema.xml");
    }

    public void testConnect() throws Exception {
        String zkDir = dataDir.getAbsolutePath() + File.separator + "zookeeper/server1/data";
        ZkTestServer server = null;

        server = new ZkTestServer(zkDir);
        server.run();
        AbstractZkTestCase.tryCleanSolrZkNode(server.getZkHost());
        SolrZkClient zkClient = new SolrZkClient(server.getZkAddress(), AbstractZkTestCase.TIMEOUT);

        zkClient.close();
        server.shutdown();
    }

    public void testMakeRootNode() throws Exception {
        String zkDir = dataDir.getAbsolutePath() + File.separator + "zookeeper/server1/data";
        ZkTestServer server = null;

        server = new ZkTestServer(zkDir);
        server.run();
        AbstractZkTestCase.tryCleanSolrZkNode(server.getZkHost());
        AbstractZkTestCase.makeSolrZkNode(server.getZkHost());

        SolrZkClient zkClient = new SolrZkClient(server.getZkHost(), AbstractZkTestCase.TIMEOUT);

        assertTrue(zkClient.exists("/solr", true));

        zkClient.close();
        server.shutdown();
    }

    public void testClean() throws Exception {
        String zkDir = dataDir.getAbsolutePath() + File.separator + "zookeeper/server1/data";
        ZkTestServer server = null;

        server = new ZkTestServer(zkDir);
        server.run();
        AbstractZkTestCase.tryCleanSolrZkNode(server.getZkHost());

        SolrZkClient zkClient = new SolrZkClient(server.getZkHost(), AbstractZkTestCase.TIMEOUT);

        zkClient.makePath("/test/path/here", true);

        zkClient.makePath("/zz/path/here", true);

        zkClient.clean("/");

        assertFalse(zkClient.exists("/test", true));
        assertFalse(zkClient.exists("/zz", true));

        zkClient.close();
        server.shutdown();
    }

    public void testReconnect() throws Exception {
        String zkDir = dataDir.getAbsolutePath() + File.separator + "zookeeper/server1/data";
        ZkTestServer server = null;
        SolrZkClient zkClient = null;
        try {
            server = new ZkTestServer(zkDir);
            server.run();
            AbstractZkTestCase.tryCleanSolrZkNode(server.getZkHost());
            AbstractZkTestCase.makeSolrZkNode(server.getZkHost());

            zkClient = new SolrZkClient(server.getZkAddress(), AbstractZkTestCase.TIMEOUT);
            String shardsPath = "/collections/collection1/shards";
            zkClient.makePath(shardsPath, false, true);

            zkClient.makePath("collections/collection1", false, true);
            int zkServerPort = server.getPort();
            // this tests disconnect state
            server.shutdown();

            Thread.sleep(80);

            try {
                zkClient.makePath("collections/collection2", false);
                Assert.fail("Server should be down here");
            } catch (KeeperException.ConnectionLossException e) {

            }

            // bring server back up
            server = new ZkTestServer(zkDir, zkServerPort);
            server.run();

            // TODO: can we do better?
            // wait for reconnect
            Thread.sleep(600);

            try {
                zkClient.makePath("collections/collection3", true);
            } catch (KeeperException.ConnectionLossException e) {
                Thread.sleep(5000); // try again in a bit
                zkClient.makePath("collections/collection3", true);
            }

            if (DEBUG) {
                zkClient.printLayoutToStdOut();
            }

            assertNotNull(zkClient.exists("/collections/collection3", null, true));
            assertNotNull(zkClient.exists("/collections/collection1", null, true));

            // simulate session expiration

            // one option
            long sessionId = zkClient.getSolrZooKeeper().getSessionId();
            server.expire(sessionId);

            // another option
            //zkClient.getSolrZooKeeper().getConnection().disconnect();

            // this tests expired state

            Thread.sleep(1000); // pause for reconnect

            for (int i = 0; i < 8; i++) {
                try {
                    zkClient.makePath("collections/collection4", true);
                    break;
                } catch (KeeperException.SessionExpiredException e) {

                } catch (KeeperException.ConnectionLossException e) {

                }
                Thread.sleep(1000 * i);
            }

            if (DEBUG) {
                zkClient.printLayoutToStdOut();
            }

            assertNotNull("Node does not exist, but it should",
                    zkClient.exists("/collections/collection4", null, true));

        } finally {

            if (zkClient != null) {
                zkClient.close();
            }
            if (server != null) {
                server.shutdown();
            }
        }
    }

    public void testWatchChildren() throws Exception {
        String zkDir = dataDir.getAbsolutePath() + File.separator + "zookeeper/server1/data";

        final AtomicInteger cnt = new AtomicInteger();
        ZkTestServer server = new ZkTestServer(zkDir);
        server.run();
        AbstractZkTestCase.tryCleanSolrZkNode(server.getZkHost());
        Thread.sleep(400);
        AbstractZkTestCase.makeSolrZkNode(server.getZkHost());
        final SolrZkClient zkClient = new SolrZkClient(server.getZkAddress(), AbstractZkTestCase.TIMEOUT);
        try {
            final CountDownLatch latch = new CountDownLatch(1);
            zkClient.makePath("/collections", true);

            zkClient.getChildren("/collections", new Watcher() {

                @Override
                public void process(WatchedEvent event) {
                    if (DEBUG) {
                        System.out.println("children changed");
                    }
                    cnt.incrementAndGet();
                    // remake watch
                    try {
                        zkClient.getChildren("/collections", this, true);
                        latch.countDown();
                    } catch (KeeperException e) {
                        throw new RuntimeException(e);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }, true);

            zkClient.makePath("/collections/collection99/shards", true);
            latch.await(); //wait until watch has been re-created

            zkClient.makePath("collections/collection99/config=collection1", true);

            zkClient.makePath("collections/collection99/config=collection3", true);

            zkClient.makePath("/collections/collection97/shards", true);

            if (DEBUG) {
                zkClient.printLayoutToStdOut();
            }

            // pause for the watches to fire
            Thread.sleep(700);

            if (cnt.intValue() < 2) {
                Thread.sleep(4000); // wait a bit more
            }

            if (cnt.intValue() < 2) {
                Thread.sleep(4000); // wait a bit more
            }

            assertEquals(2, cnt.intValue());

        } finally {

            if (zkClient != null) {
                zkClient.close();
            }
            if (server != null) {
                server.shutdown();
            }
        }
    }

    @Override
    public void tearDown() throws Exception {
        super.tearDown();
    }

    @AfterClass
    public static void afterClass() throws InterruptedException {
        // wait just a bit for any zk client threads to outlast timeout
        Thread.sleep(2000);
    }
}