org.apache.hedwig.server.netty.TestPubSubServer.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hedwig.server.netty.TestPubSubServer.java

Source

/**
 * 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.
 */
package org.apache.hedwig.server.netty;

import java.io.IOException;
import java.lang.Thread.UncaughtExceptionHandler;
import java.net.InetSocketAddress;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.SynchronousQueue;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.junit.Test;

import org.apache.bookkeeper.test.PortManager;
import com.google.protobuf.ByteString;
import org.apache.hedwig.client.conf.ClientConfiguration;
import org.apache.hedwig.client.HedwigClient;
import org.apache.hedwig.client.api.Publisher;
import org.apache.hedwig.exceptions.PubSubException;
import org.apache.hedwig.protocol.PubSubProtocol.Message;
import org.apache.hedwig.server.PubSubServerStandAloneTestBase;
import org.apache.hedwig.server.common.ServerConfiguration;
import org.apache.hedwig.server.topics.AbstractTopicManager;
import org.apache.hedwig.server.topics.TopicManager;
import org.apache.hedwig.server.LoggingExceptionHandler;
import org.apache.hedwig.util.Callback;
import org.apache.hedwig.util.HedwigSocketAddress;
import org.apache.hedwig.zookeeper.SafeAsyncZKCallback;

import static org.junit.Assert.*;

public class TestPubSubServer extends PubSubServerStandAloneTestBase {

    @Test(timeout = 60000)
    public void testSecondServer() throws Exception {
        PubSubServer server1 = new PubSubServer(new StandAloneServerConfiguration() {
            @Override
            public int getServerPort() {
                return super.getServerPort() + 1;
            }
        }, new ClientConfiguration(), new LoggingExceptionHandler());
        server1.start();
        server1.shutdown();
    }

    class RecordingUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
        SynchronousQueue<Throwable> queue;

        public RecordingUncaughtExceptionHandler(SynchronousQueue<Throwable> queue) {
            this.queue = queue;
        }

        @Override
        public void uncaughtException(Thread t, Throwable e) {
            queue.add(e);
        }

    }

    private interface TopicManagerInstantiator {
        public TopicManager instantiateTopicManager() throws IOException;
    }

    PubSubServer startServer(final UncaughtExceptionHandler uncaughtExceptionHandler, final int port,
            final TopicManagerInstantiator instantiator) throws Exception {
        PubSubServer server = new PubSubServer(new StandAloneServerConfiguration() {
            @Override
            public int getServerPort() {
                return port;
            }

        }, new ClientConfiguration(), uncaughtExceptionHandler) {

            @Override
            protected TopicManager instantiateTopicManager() throws IOException {
                return instantiator.instantiateTopicManager();
            }
        };
        server.start();
        return server;

    }

    public void runPublishRequest(final int port) throws Exception {
        Publisher publisher = new HedwigClient(new ClientConfiguration() {
            @Override
            public InetSocketAddress getDefaultServerHost() {
                return new InetSocketAddress("localhost", port);
            }
        }).getPublisher();

        publisher.asyncPublish(ByteString.copyFromUtf8("blah"),
                Message.newBuilder().setBody(ByteString.copyFromUtf8("blah")).build(), new Callback<Void>() {
                    @Override
                    public void operationFailed(Object ctx, PubSubException exception) {
                        assertTrue(false);
                    }

                    @Override
                    public void operationFinished(Object ctx, Void resultOfOperation) {
                        assertTrue(false);
                    }

                }, null);
    }

    @Test(timeout = 60000)
    public void testUncaughtExceptionInNettyThread() throws Exception {

        SynchronousQueue<Throwable> queue = new SynchronousQueue<Throwable>();
        RecordingUncaughtExceptionHandler uncaughtExceptionHandler = new RecordingUncaughtExceptionHandler(queue);
        final int port = PortManager.nextFreePort();

        PubSubServer server = startServer(uncaughtExceptionHandler, port, new TopicManagerInstantiator() {

            @Override
            public TopicManager instantiateTopicManager() throws IOException {
                return new AbstractTopicManager(new ServerConfiguration(),
                        Executors.newSingleThreadScheduledExecutor()) {
                    @Override
                    protected void realGetOwner(ByteString topic, boolean shouldClaim,
                            Callback<HedwigSocketAddress> cb, Object ctx) {
                        throw new RuntimeException("this exception should be uncaught");
                    }

                    @Override
                    protected void postReleaseCleanup(ByteString topic, Callback<Void> cb, Object ctx) {
                    }
                };
            }
        });

        runPublishRequest(port);
        assertEquals(RuntimeException.class, queue.take().getClass());
        server.shutdown();
    }

    @Test(timeout = 60000)
    public void testUncaughtExceptionInZKThread() throws Exception {

        SynchronousQueue<Throwable> queue = new SynchronousQueue<Throwable>();
        RecordingUncaughtExceptionHandler uncaughtExceptionHandler = new RecordingUncaughtExceptionHandler(queue);
        final int port = PortManager.nextFreePort();
        final String hostPort = "127.0.0.1:" + PortManager.nextFreePort();

        PubSubServer server = startServer(uncaughtExceptionHandler, port, new TopicManagerInstantiator() {

            @Override
            public TopicManager instantiateTopicManager() throws IOException {
                return new AbstractTopicManager(new ServerConfiguration(),
                        Executors.newSingleThreadScheduledExecutor()) {

                    @Override
                    protected void realGetOwner(ByteString topic, boolean shouldClaim,
                            Callback<HedwigSocketAddress> cb, Object ctx) {
                        ZooKeeper zookeeper;
                        try {
                            zookeeper = new ZooKeeper(hostPort, 60000, new Watcher() {
                                @Override
                                public void process(WatchedEvent event) {
                                    // TODO Auto-generated method stub

                                }
                            });
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }

                        zookeeper.getData("/fake", false, new SafeAsyncZKCallback.DataCallback() {
                            @Override
                            public void safeProcessResult(int rc, String path, Object ctx, byte[] data,
                                    org.apache.zookeeper.data.Stat stat) {
                                throw new RuntimeException("This should go to the uncaught exception handler");
                            }

                        }, null);
                    }

                    @Override
                    protected void postReleaseCleanup(ByteString topic, Callback<Void> cb, Object ctx) {
                    }
                };
            }
        });

        runPublishRequest(port);
        assertEquals(RuntimeException.class, queue.take().getClass());
        server.shutdown();
    }

    @Test(timeout = 60000)
    public void testInvalidServerConfiguration() throws Exception {
        boolean success = false;
        ServerConfiguration conf = new ServerConfiguration() {
            @Override
            public boolean isInterRegionSSLEnabled() {
                return conf.getBoolean(INTER_REGION_SSL_ENABLED, true);
            }

            @Override
            public List<String> getRegions() {
                List<String> regionsList = new LinkedList<String>();
                regionsList.add("regionHost1:4080:9876");
                regionsList.add("regionHost2:4080");
                regionsList.add("regionHost3:4080:9876");
                return regionsList;
            }
        };
        try {
            conf.validate();
        } catch (ConfigurationException e) {
            logger.error("Invalid configuration: ", e);
            success = true;
        }
        assertTrue(success);
    }

    @Test(timeout = 60000)
    public void testValidServerConfiguration() throws Exception {
        boolean success = true;
        ServerConfiguration conf = new ServerConfiguration() {
            @Override
            public boolean isInterRegionSSLEnabled() {
                return conf.getBoolean(INTER_REGION_SSL_ENABLED, true);
            }

            @Override
            public List<String> getRegions() {
                List<String> regionsList = new LinkedList<String>();
                regionsList.add("regionHost1:4080:9876");
                regionsList.add("regionHost2:4080:2938");
                regionsList.add("regionHost3:4080:9876");
                return regionsList;
            }
        };
        try {
            conf.validate();
        } catch (ConfigurationException e) {
            logger.error("Invalid configuration: ", e);
            success = false;
        }
        assertTrue(success);
    }

}