com.navercorp.pinpoint.web.cluster.ClusterTest.java Source code

Java tutorial

Introduction

Here is the source code for com.navercorp.pinpoint.web.cluster.ClusterTest.java

Source

/*
 * Copyright 2014 NAVER Corp.
 *
 * Licensed 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.
 */

package com.navercorp.pinpoint.web.cluster;

import com.navercorp.pinpoint.common.util.NetUtils;
import com.navercorp.pinpoint.rpc.client.PinpointClient;
import com.navercorp.pinpoint.rpc.client.PinpointClientFactory;
import com.navercorp.pinpoint.rpc.client.SimpleMessageListener;
import com.navercorp.pinpoint.web.cluster.connection.ClusterConnectionManager;
import com.navercorp.pinpoint.web.cluster.zookeeper.ZookeeperClusterDataManager;
import com.navercorp.pinpoint.web.config.WebConfig;
import com.navercorp.pinpoint.web.TestAwaitTaskUtils;
import com.navercorp.pinpoint.web.TestAwaitUtils;
import com.navercorp.pinpoint.web.util.PinpointWebTestUtils;
import org.apache.curator.test.TestingServer;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.SocketUtils;

import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.List;

/**
 * @author Taejin Koo
 */
public class ClusterTest {

    private static final Logger LOGGER = LoggerFactory.getLogger(ClusterTest.class);

    private static final Charset UTF_8_CHARSET = Charset.forName("UTF-8");

    // some tests may fail when executed in local environment
    // when failures happen, you have to copy pinpoint-web.properties of resource-test to resource-local. Tests will succeed.

    private static TestAwaitUtils awaitUtils = new TestAwaitUtils(100, 10000);

    private static final String DEFAULT_IP = PinpointWebTestUtils.getRepresentationLocalV4Ip();
    static ClusterConnectionManager clusterConnectionManager;
    static ZookeeperClusterDataManager clusterDataManager;
    private static String CLUSTER_NODE_PATH;
    private static int acceptorPort;
    private static int zookeeperPort;
    private static String acceptorAddress;
    private static String zookeeperAddress;
    private static TestingServer ts = null;

    @BeforeClass
    public static void setUp() throws Exception {
        acceptorPort = SocketUtils.findAvailableTcpPort(28000);
        acceptorAddress = DEFAULT_IP + ":" + acceptorPort;

        zookeeperPort = SocketUtils.findAvailableTcpPort(acceptorPort + 1);
        zookeeperAddress = DEFAULT_IP + ":" + zookeeperPort;

        ts = createZookeeperServer(zookeeperPort);

        CLUSTER_NODE_PATH = "/pinpoint-cluster/web/" + acceptorAddress;
        LOGGER.info("CLUSTER_NODE_PATH:{}", CLUSTER_NODE_PATH);

        WebConfig config = mock(WebConfig.class);

        when(config.isClusterEnable()).thenReturn(true);
        when(config.getClusterTcpPort()).thenReturn(acceptorPort);
        when(config.getClusterZookeeperAddress()).thenReturn(zookeeperAddress);
        when(config.getClusterZookeeperRetryInterval()).thenReturn(60000);
        when(config.getClusterZookeeperSessionTimeout()).thenReturn(3000);

        clusterConnectionManager = new ClusterConnectionManager(config);
        clusterConnectionManager.start();

        clusterDataManager = new ZookeeperClusterDataManager(config);
        clusterDataManager.start();

        List<String> localV4IpList = NetUtils.getLocalV4IpList();
        clusterDataManager.registerWebCluster(acceptorAddress, convertIpListToBytes(localV4IpList, "\r\n"));
    }

    @AfterClass
    public static void tearDown() throws Exception {
        closeZookeeperServer(ts);

        try {
            clusterDataManager.stop();
        } catch (Exception ignore) {
        }

        try {
            clusterConnectionManager.stop();
        } catch (Exception ignore) {
        }
    }

    private static TestingServer createZookeeperServer(int port) throws Exception {
        TestingServer mockZookeeperServer = new TestingServer(port);
        mockZookeeperServer.start();

        return mockZookeeperServer;
    }

    private static void closeZookeeperServer(TestingServer mockZookeeperServer) throws Exception {
        try {
            if (mockZookeeperServer != null) {
                mockZookeeperServer.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static byte[] convertIpListToBytes(List<String> ipList, String delimiter) {
        StringBuilder stringBuilder = new StringBuilder();

        Iterator<String> ipIterator = ipList.iterator();
        while (ipIterator.hasNext()) {
            String eachIp = ipIterator.next();
            stringBuilder.append(eachIp);

            if (ipIterator.hasNext()) {
                stringBuilder.append(delimiter);
            }
        }

        return stringBuilder.toString().getBytes(UTF_8_CHARSET);
    }

    @After
    public void after() throws Exception {
        ts.restart();
    }

    @Test
    public void clusterTest1() throws Exception {
        ZooKeeper zookeeper = new ZooKeeper(zookeeperAddress, 5000, null);
        awaitZookeeperConnected(zookeeper);

        if (zookeeper != null) {
            zookeeper.close();
        }
    }

    @Test
    public void clusterTest2() throws Exception {
        ZooKeeper zookeeper = new ZooKeeper(zookeeperAddress, 5000, null);
        awaitZookeeperConnected(zookeeper);

        ts.stop();

        awaitZookeeperDisconnected(zookeeper);
        try {
            zookeeper.getData(CLUSTER_NODE_PATH, null, null);
            Assert.fail();
        } catch (KeeperException e) {
            Assert.assertEquals(KeeperException.Code.CONNECTIONLOSS, e.code());
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        ts.restart();
        getNodeAndCompareContents(zookeeper);

        if (zookeeper != null) {
            zookeeper.close();
        }
    }

    @Test
    public void clusterTest3() throws Exception {
        PinpointClientFactory clientFactory = null;
        PinpointClient client = null;

        ZooKeeper zookeeper = null;
        try {
            zookeeper = new ZooKeeper(zookeeperAddress, 5000, null);
            awaitZookeeperConnected(zookeeper);

            Assert.assertEquals(0, clusterConnectionManager.getClusterList().size());

            clientFactory = new PinpointClientFactory();
            clientFactory.setMessageListener(SimpleMessageListener.INSTANCE);

            client = clientFactory.connect(DEFAULT_IP, acceptorPort);
            awaitPinpointClientConnected(clusterConnectionManager);

            Assert.assertEquals(1, clusterConnectionManager.getClusterList().size());

        } finally {
            closePinpointSocket(clientFactory, client);

            if (zookeeper != null) {
                zookeeper.close();
            }
        }
    }

    private void awaitZookeeperConnected(final ZooKeeper zookeeper) {
        boolean pass = awaitUtils.await(new TestAwaitTaskUtils() {
            @Override
            public boolean checkCompleted() {
                return getNodeAndCompareContents0(zookeeper);
            }
        });
        Assert.assertTrue(pass);
    }

    private void awaitZookeeperDisconnected(final ZooKeeper zookeeper) {
        boolean pass = awaitUtils.await(new TestAwaitTaskUtils() {
            @Override
            public boolean checkCompleted() {
                return !getNodeAndCompareContents0(zookeeper);
            }
        });
        Assert.assertTrue(pass);
    }

    private void awaitPinpointClientConnected(final ClusterConnectionManager connectionManager) {
        boolean pass = awaitUtils.await(new TestAwaitTaskUtils() {
            @Override
            public boolean checkCompleted() {
                return !connectionManager.getClusterList().isEmpty();
            }
        });
        Assert.assertTrue(pass);
    }

    private void getNodeAndCompareContents(ZooKeeper zookeeper) throws KeeperException, InterruptedException {
        LOGGER.info("getNodeAndCompareContents() {}", CLUSTER_NODE_PATH);

        byte[] contents = zookeeper.getData(CLUSTER_NODE_PATH, null, null);

        String[] registeredIplist = new String(contents).split("\r\n");

        List<String> ipList = NetUtils.getLocalV4IpList();

        Assert.assertEquals(registeredIplist.length, ipList.size());

        for (String ip : registeredIplist) {
            Assert.assertTrue(ipList.contains(ip));
        }
    }

    private boolean getNodeAndCompareContents0(ZooKeeper zookeeper) {
        try {
            LOGGER.info("getNodeAndCompareContents() {}", CLUSTER_NODE_PATH);

            byte[] contents = zookeeper.getData(CLUSTER_NODE_PATH, null, null);
            if (contents == null) {
                contents = new byte[0];
            }

            String[] registeredIplist = new String(contents).split("\r\n");

            List<String> ipList = NetUtils.getLocalV4IpList();

            if (registeredIplist.length != ipList.size()) {
                return false;
            }

            for (String ip : registeredIplist) {
                if (!ipList.contains(ip)) {
                    return false;
                }
            }
            return true;
        } catch (Exception e) {
            LOGGER.warn(e.getMessage(), e);
        }
        return false;
    }

    private void closePinpointSocket(PinpointClientFactory clientFactory, PinpointClient client) {
        if (client != null) {
            client.close();
        }

        if (clientFactory != null) {
            clientFactory.release();
        }
    }

}