Package com.hazelcast.topic

Source Code of com.hazelcast.topic.TopicTest

/*
* Copyright (c) 2008-2013, Hazelcast, Inc. All Rights Reserved.
*
* 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.hazelcast.topic;

import com.hazelcast.config.Config;
import com.hazelcast.config.ListenerConfig;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.ITopic;
import com.hazelcast.core.Member;
import com.hazelcast.core.Message;
import com.hazelcast.core.MessageListener;
import com.hazelcast.instance.MemberImpl;
import com.hazelcast.monitor.impl.LocalTopicStatsImpl;
import com.hazelcast.nio.ObjectDataInput;
import com.hazelcast.nio.ObjectDataOutput;
import com.hazelcast.nio.serialization.DataSerializable;
import com.hazelcast.test.AssertTask;
import com.hazelcast.test.HazelcastParallelClassRunner;
import com.hazelcast.test.HazelcastTestSupport;
import com.hazelcast.test.TestHazelcastInstanceFactory;
import com.hazelcast.test.annotation.QuickTest;
import com.hazelcast.topic.impl.TopicService;
import com.hazelcast.util.UuidUtil;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;

import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import static org.junit.Assert.*;


@RunWith(HazelcastParallelClassRunner.class)
@Category(QuickTest.class)
public class TopicTest extends HazelcastTestSupport {

    @Test
    public void testDestroyTopicRemovesStatistics() {
        HazelcastInstance instance = createHazelcastInstance();
        final ITopic topic = instance.getTopic("foo");
        topic.publish("foobar");

        //we need to give the message the chance to be processed, else the topic statistics are recreated.
        //so in theory the destroy for the topic is broken.
        sleepSeconds(1);

        topic.destroy();

        final TopicService topicService = getNode(instance).nodeEngine.getService(TopicService.SERVICE_NAME);

        assertTrueEventually(new AssertTask() {
            @Override
            public void run() {
                boolean containsStats = topicService.getStatsMap().containsKey(topic.getName());
                assertFalse(containsStats);
            }
        });
    }

    @Test
    public void testTopicPublishingMember() {
        final Config config = new Config();
        config.getTopicConfig("default").setGlobalOrderingEnabled(true);
        final int k = 3;
        TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(k);
        final HazelcastInstance[] instances = factory.newInstances(config);

        final CountDownLatch mainLatch = new CountDownLatch(k);
        final AtomicInteger count = new AtomicInteger(0);
        final AtomicInteger count1 = new AtomicInteger(0);
        final AtomicInteger count2 = new AtomicInteger(0);
        final String name = "testTopicPublishingMember";

        for (int i = 0; i < k; i++) {
            final HazelcastInstance instance = instances[i];
            new Thread(new Runnable() {
                public void run() {
                    ITopic<Long> topic = instance.getTopic(name);
                    topic.addMessageListener(new MessageListener<Long>() {
                        public void onMessage(Message<Long> message) {
                            Member publishingMember = message.getPublishingMember();
                            if (publishingMember.equals(instance.getCluster().getLocalMember()))
                                count.incrementAndGet();
                            if (publishingMember.equals(message.getMessageObject()))
                                count1.incrementAndGet();
                            if (publishingMember.localMember())
                                count2.incrementAndGet();
                        }
                    });
                    mainLatch.countDown();
                }
            }).start();

        }
        try {
            mainLatch.await(1, TimeUnit.MINUTES);
        } catch (InterruptedException e) {
            fail();
        }

        for (int i = 0; i < k; i++) {
            HazelcastInstance instance = instances[i];
            instance.getTopic(name).publish(instance.getCluster().getLocalMember());
        }

        assertTrueEventually(new AssertTask() {
            @Override
            public void run() {
                assertEquals(k, count.get());
                assertEquals(k * k, count1.get());
                assertEquals(k, count2.get());
            }
        });
    }

    @Test
    public void testTopicLocalOrder() throws Exception {
        final int k = 5;
        final int count = 1000;
        final CountDownLatch startLatch = new CountDownLatch(k);
        final CountDownLatch messageLatch = new CountDownLatch(k * k * count);
        final CountDownLatch publishLatch = new CountDownLatch(k * count);
        final Config config = new Config();
        config.getTopicConfig("default").setGlobalOrderingEnabled(false);

        final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(k);
        final HazelcastInstance[] instances = factory.newInstances(config);
        final List<TestMessage>[] messageLists = new List[k];
        for (int i = 0; i < k; i++) {
            messageLists[i] = new CopyOnWriteArrayList<TestMessage>();
        }

        ExecutorService ex = Executors.newFixedThreadPool(k);
        for (int i = 0; i < k; i++) {
            final int finalI = i;
            ex.execute(new Runnable() {
                public void run() {
                    final List<TestMessage> messages = messageLists[finalI];
                    HazelcastInstance hz = instances[finalI];
                    ITopic<TestMessage> topic = hz.getTopic("default");
                    topic.addMessageListener(new MessageListener<TestMessage>() {
                        public void onMessage(Message<TestMessage> message) {
                            messages.add(message.getMessageObject());
                            messageLatch.countDown();
                        }
                    });

                    startLatch.countDown();
                    try {
                        startLatch.await(1, TimeUnit.MINUTES);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        return;
                    }

                    Member localMember = hz.getCluster().getLocalMember();
                    for (int j = 0; j < count; j++) {
                        topic.publish(new TestMessage(localMember, UuidUtil.buildRandomUuidString()));
                        publishLatch.countDown();
                    }
                }
            });
        }

        try {
            assertTrue(publishLatch.await(2, TimeUnit.MINUTES));
            assertTrue(messageLatch.await(5, TimeUnit.MINUTES));
            TestMessage[] ref = new TestMessage[messageLists[0].size()];
            messageLists[0].toArray(ref);

            Comparator<TestMessage> comparator = new Comparator<TestMessage>() {
                public int compare(TestMessage m1, TestMessage m2) {
                    // sort only publisher blocks. if publishers are the same, leave them as they are.
                    return m1.publisher.getUuid().compareTo(m2.publisher.getUuid());
                }
            };
            Arrays.sort(ref, comparator);

            for (int i = 1; i < k; i++) {
                TestMessage[] messages = new TestMessage[messageLists[i].size()];
                messageLists[i].toArray(messages);
                Arrays.sort(messages, comparator);
                assertArrayEquals(ref, messages);
            }
        } finally {
            ex.shutdownNow();
        }
    }

    @Test
    public void testTopicGlobalOrder() throws Exception {
        final int k = 5;
        final int count = 1000;
        final CountDownLatch startLatch = new CountDownLatch(k);
        final CountDownLatch messageLatch = new CountDownLatch(k * k * count);
        final CountDownLatch publishLatch = new CountDownLatch(k * count);
        final Config config = new Config();
        config.getTopicConfig("default").setGlobalOrderingEnabled(true);

        final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(k);
        final HazelcastInstance[] instances = factory.newInstances(config);
        final List<TestMessage>[] messageLists = new List[k];
        for (int i = 0; i < k; i++) {
            messageLists[i] = new CopyOnWriteArrayList<TestMessage>();
        }

        ExecutorService ex = Executors.newFixedThreadPool(k);
        for (int i = 0; i < k; i++) {
            final int finalI = i;
            ex.execute(new Runnable() {
                public void run() {
                    final List<TestMessage> messages = messageLists[finalI];
                    HazelcastInstance hz = instances[finalI];
                    ITopic<TestMessage> topic = hz.getTopic("default");
                    topic.addMessageListener(new MessageListener<TestMessage>() {
                        public void onMessage(Message<TestMessage> message) {
                            messages.add(message.getMessageObject());
                            messageLatch.countDown();
                        }
                    });

                    startLatch.countDown();
                    try {
                        startLatch.await(1, TimeUnit.MINUTES);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        return;
                    }

                    Member localMember = hz.getCluster().getLocalMember();
                    for (int j = 0; j < count; j++) {
                        topic.publish(new TestMessage(localMember, UUID.randomUUID().toString()));
                        publishLatch.countDown();
                    }
                }
            });
        }

        try {
            assertTrue(publishLatch.await(2, TimeUnit.MINUTES));
            assertTrue(messageLatch.await(5, TimeUnit.MINUTES));
            TestMessage[] ref = new TestMessage[messageLists[0].size()];
            messageLists[0].toArray(ref);

            for (int i = 1; i < k; i++) {
                TestMessage[] messages = new TestMessage[messageLists[i].size()];
                messageLists[i].toArray(messages);

                assertArrayEquals(ref, messages);
            }
        } finally {
            ex.shutdownNow();
        }
    }

    static class TestMessage implements DataSerializable {
        Member publisher;
        String data;

        TestMessage() {
        }

        TestMessage(Member publisher, String data) {
            this.publisher = publisher;
            this.data = data;
        }

        public void writeData(ObjectDataOutput out) throws IOException {
            publisher.writeData(out);
            out.writeUTF(data);
        }

        public void readData(ObjectDataInput in) throws IOException {
            publisher = new MemberImpl();
            publisher.readData(in);
            data = in.readUTF();
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            TestMessage that = (TestMessage) o;

            if (data != null ? !data.equals(that.data) : that.data != null) return false;
            if (publisher != null ? !publisher.equals(that.publisher) : that.publisher != null) return false;

            return true;
        }

        @Override
        public int hashCode() {
            int result = publisher != null ? publisher.hashCode() : 0;
            result = 31 * result + (data != null ? data.hashCode() : 0);
            return result;
        }

        @Override
        public String toString() {
            final StringBuilder sb = new StringBuilder("TestMessage{");
            sb.append("publisher=").append(publisher);
            sb.append(", data='").append(data).append('\'');
            sb.append('}');
            return sb.toString();
        }
    }

    @Test
    public void testName() {
        HazelcastInstance hClient = createHazelcastInstance();
        ITopic<?> topic = hClient.getTopic("testName");
        assertEquals("testName", topic.getName());
    }

    @Test
    public void addMessageListener() throws InterruptedException {
        HazelcastInstance hClient = createHazelcastInstance();
        ITopic<String> topic = hClient.getTopic("addMessageListener");
        final CountDownLatch latch = new CountDownLatch(1);
        final String message = "Hazelcast Rocks!";
        topic.addMessageListener(new MessageListener<String>() {
            public void onMessage(Message<String> msg) {
                if (msg.getMessageObject().equals(message)) {
                    latch.countDown();
                }
            }
        });
        topic.publish(message);
        assertTrue(latch.await(10000, TimeUnit.MILLISECONDS));
    }

    @Test
    public void testConfigListenerRegistration() throws InterruptedException {
        Config config = new Config();
        final String name = "default";
        final CountDownLatch latch = new CountDownLatch(1);
        config.getTopicConfig(name).addMessageListenerConfig(new ListenerConfig().setImplementation(new MessageListener() {
            public void onMessage(Message message) {
                latch.countDown();
            }
        }));
        final HazelcastInstance hz = createHazelcastInstance(config);
        hz.getTopic(name).publish(1);
        assertTrue(latch.await(10, TimeUnit.SECONDS));
    }

    @Test
    public void addTwoMessageListener() throws InterruptedException {
        HazelcastInstance hazelcastInstance = createHazelcastInstance();
        ITopic<String> topic = hazelcastInstance.getTopic("addTwoMessageListener");
        final CountDownLatch latch = new CountDownLatch(2);
        final String message = "Hazelcast Rocks!";
        topic.addMessageListener(new MessageListener<String>() {
            public void onMessage(Message<String> msg) {
                if (msg.getMessageObject().equals(message)) {
                    latch.countDown();
                }
            }
        });
        topic.addMessageListener(new MessageListener<String>() {
            public void onMessage(Message<String> msg) {
                if (msg.getMessageObject().equals(message)) {
                    latch.countDown();
                }
            }
        });
        topic.publish(message);
        assertTrue(latch.await(10000, TimeUnit.MILLISECONDS));
    }

    @Test
    public void removeMessageListener() throws InterruptedException {
        try {
            HazelcastInstance hazelcastInstance = createHazelcastInstance();
            ITopic<String> topic = hazelcastInstance.getTopic("removeMessageListener");
            final CountDownLatch latch = new CountDownLatch(2);
            final CountDownLatch cp = new CountDownLatch(1);

            MessageListener<String> messageListener = new MessageListener<String>() {
                public void onMessage(Message<String> msg) {
                    latch.countDown();
                    cp.countDown();

                }
            };
            final String message = "message_" + messageListener.hashCode() + "_";
            final String id = topic.addMessageListener(messageListener);
            topic.publish(message + "1");
            cp.await();
            topic.removeMessageListener(id);
            topic.publish(message + "2");

            assertTrueEventually(new AssertTask() {
                @Override
                public void run() {
                    assertEquals(1, latch.getCount());
                }
            });
        } finally {
            shutdownNodeFactory();
        }
    }

    @Test
    public void test10TimesRemoveMessageListener() throws InterruptedException {
        ExecutorService ex = Executors.newFixedThreadPool(1);
        final CountDownLatch latch = new CountDownLatch(10);
        try {
            ex.execute(new Runnable() {
                public void run() {
                    for (int i = 0; i < 10; i++) {
                        try {
                            removeMessageListener();
                            latch.countDown();
                        } catch (InterruptedException e) {
                            return;
                        }
                    }
                }
            });
            assertTrue(latch.await(30, TimeUnit.SECONDS));
        } finally {
            ex.shutdownNow();
        }
    }

    @Test
    public void testPerformance() throws InterruptedException {
        HazelcastInstance hazelcastInstance = createHazelcastInstance();
        int count = 10000;
        final ITopic topic = hazelcastInstance.getTopic("perf");
        ExecutorService ex = Executors.newFixedThreadPool(10);
        final CountDownLatch l = new CountDownLatch(count);
        for (int i = 0; i < count; i++) {
            ex.submit(new Runnable() {
                public void run() {
                    topic.publish("my object");
                    l.countDown();
                }
            });
        }
        assertTrue(l.await(20, TimeUnit.SECONDS));
    }

    @Test
    public void add2listenerAndRemoveOne() throws InterruptedException {
        HazelcastInstance hazelcastInstance = createHazelcastInstance();
        ITopic<String> topic = hazelcastInstance.getTopic("add2listenerAndRemoveOne");
        final CountDownLatch latch = new CountDownLatch(3);
        final CountDownLatch cp = new CountDownLatch(2);
        final AtomicInteger atomicInteger = new AtomicInteger();
        final String message = "Hazelcast Rocks!";
        MessageListener<String> messageListener1 = new MessageListener<String>() {
            public void onMessage(Message<String> msg) {
                atomicInteger.incrementAndGet();
                latch.countDown();
                cp.countDown();
            }
        };
        MessageListener<String> messageListener2 = new MessageListener<String>() {
            public void onMessage(Message<String> msg) {
                atomicInteger.incrementAndGet();
                latch.countDown();
                cp.countDown();
            }
        };
        final String id1 = topic.addMessageListener(messageListener1);
        topic.addMessageListener(messageListener2);
        topic.publish(message);
        assertOpenEventually(cp);
        topic.removeMessageListener(id1);
        topic.publish(message);

        assertOpenEventually(latch);
        assertEquals(3, atomicInteger.get());
    }

    /**
     * Testing if topic can properly listen messages
     * and if topic has any issue after a shutdown.
     */
    @Test
    public void testTopicCluster() throws InterruptedException {
        final Config cfg = new Config();
        TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2);
        HazelcastInstance[] instances = factory.newInstances(cfg);
        HazelcastInstance h1 = instances[0];
        HazelcastInstance h2 = instances[1];
        String topicName = "TestMessages";
        ITopic<String> topic1 = h1.getTopic(topicName);
        final CountDownLatch latch1 = new CountDownLatch(1);
        final String message = "Test1";
        topic1.addMessageListener(new MessageListener<String>() {
            public void onMessage(Message msg) {
                assertEquals(message, msg.getMessageObject());
                latch1.countDown();
            }
        });
        ITopic<String> topic2 = h2.getTopic(topicName);
        final CountDownLatch latch2 = new CountDownLatch(2);
        topic2.addMessageListener(new MessageListener<String>() {
            public void onMessage(Message msg) {
                assertEquals(message, msg.getMessageObject());
                latch2.countDown();
            }
        });

        topic1.publish(message);
        assertTrue(latch1.await(5, TimeUnit.SECONDS));

        h1.shutdown();
        topic2.publish(message);
        assertTrue(latch2.await(5, TimeUnit.SECONDS));
    }

    @Test
    public void testTopicStats() throws InterruptedException {
        HazelcastInstance hazelcastInstance = createHazelcastInstance();
        ITopic<String> topic = hazelcastInstance.getTopic("testTopicStats");

        final CountDownLatch latch1 = new CountDownLatch(1000);
        topic.addMessageListener(new MessageListener<String>() {
            public void onMessage(Message msg) {
                latch1.countDown();
            }
        });
        final CountDownLatch latch2 = new CountDownLatch(1000);
        topic.addMessageListener(new MessageListener<String>() {
            public void onMessage(Message msg) {
                latch2.countDown();
            }
        });

        for (int i = 0; i < 1000; i++) {
            topic.publish("sancar");
        }

        assertTrue(latch1.await(1, TimeUnit.MINUTES));
        assertTrue(latch2.await(1, TimeUnit.MINUTES));

        LocalTopicStatsImpl stats = (LocalTopicStatsImpl) topic.getLocalTopicStats();
        assertEquals(1000, stats.getPublishOperationCount());
        assertEquals(2000, stats.getReceiveOperationCount());
    }
}
TOP

Related Classes of com.hazelcast.topic.TopicTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.