Package com.hazelcast.client.map

Source Code of com.hazelcast.client.map.ClientMapStoreTest$ClientThread

package com.hazelcast.client.map;

import com.hazelcast.client.HazelcastClient;
import com.hazelcast.client.map.helpers.AMapStore;
import com.hazelcast.config.Config;
import com.hazelcast.config.MapConfig;
import com.hazelcast.config.MapStoreConfig;
import com.hazelcast.config.XmlConfigBuilder;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
import com.hazelcast.core.MapLoader;
import com.hazelcast.core.MapStore;
import com.hazelcast.map.impl.mapstore.writebehind.ReachedMaxSizeException;
import com.hazelcast.test.AssertTask;
import com.hazelcast.test.HazelcastSerialClassRunner;
import com.hazelcast.test.HazelcastTestSupport;
import com.hazelcast.test.annotation.SlowTest;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;

import java.io.ByteArrayInputStream;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import static junit.framework.Assert.assertEquals;

@RunWith(HazelcastSerialClassRunner.class)
@Category(SlowTest.class)
public class ClientMapStoreTest extends HazelcastTestSupport {

    static final String MAP_NAME = "clientMapStoreLoad";
    Config nodeConfig;

    @Before
    public void setup() {
        nodeConfig = new Config();
        MapConfig mapConfig = new MapConfig();
        MapStoreConfig mapStoreConfig = new MapStoreConfig();
        mapStoreConfig.setEnabled(true);
        mapStoreConfig.setImplementation(new SimpleMapStore());
        mapStoreConfig.setInitialLoadMode(MapStoreConfig.InitialLoadMode.EAGER);
        mapConfig.setName(MAP_NAME);
        mapConfig.setMapStoreConfig(mapStoreConfig);
        nodeConfig.addMapConfig(mapConfig);
    }

    @After
    public void tearDown() {
        HazelcastClient.shutdownAll();
        Hazelcast.shutdownAll();
    }

    @Test
    public void testOneClient_KickOffMapStoreLoad() throws InterruptedException {
        Hazelcast.newHazelcastInstance(nodeConfig);

        ClientThread client1 = new ClientThread();
        client1.start();

        HazelcastTestSupport.assertJoinable(client1);
        assertSizeEventually(SimpleMapStore.MAX_KEYS, client1.map);
    }

    @Test
    public void testTwoClient_KickOffMapStoreLoad() throws InterruptedException {
        Hazelcast.newHazelcastInstance(nodeConfig);
        ClientThread[] clientThreads = new ClientThread[2];
        for (int i = 0; i < clientThreads.length; i++) {
            ClientThread client1 = new ClientThread();
            client1.start();
            clientThreads[i] = client1;
        }

        HazelcastTestSupport.assertJoinable(clientThreads);

        for (ClientThread c : clientThreads) {
            assertSizeEventually(SimpleMapStore.MAX_KEYS, c.map);
        }
    }

    @Test
    public void testOneClientKickOffMapStoreLoad_ThenNodeJoins() {
        Hazelcast.newHazelcastInstance(nodeConfig);

        ClientThread client1 = new ClientThread();
        client1.start();

        Hazelcast.newHazelcastInstance(nodeConfig);

        HazelcastTestSupport.assertJoinable(client1);

        assertSizeEventually(SimpleMapStore.MAX_KEYS, client1.map);
    }

    @Test
    public void testForIssue2112() {
        Hazelcast.newHazelcastInstance(nodeConfig);
        IMap<String, String> map = HazelcastClient.newHazelcastClient().getMap(ClientMapStoreTest.MAP_NAME);
        assertSizeEventually(SimpleMapStore.MAX_KEYS, map);
        Hazelcast.newHazelcastInstance(nodeConfig);
        map = HazelcastClient.newHazelcastClient().getMap(ClientMapStoreTest.MAP_NAME);
        assertSizeEventually(SimpleMapStore.MAX_KEYS, map);
    }

    // Default impl. of write-behind-queue has no capacity it is bounded by number of elements in a map.
    // we can open this test, when we have a configuration parameter for write-coalescing.
    // for now this test should be ignored since default mode is write-coalescing.
    // please see https://github.com/hazelcast/hazelcast/issues/3056 for additional details
    @Test
    @Ignore
    public void mapSize_After_MapStore_OperationQueue_OverFlow_Test() throws Exception {
        Config config = new Config();
        MapConfig mapConfig = new MapConfig();
        MapStoreConfig mapStoreConfig = new MapStoreConfig();

        final MapStoreBackup store = new MapStoreBackup();
        final int delaySeconds = 4;
        mapStoreConfig.setEnabled(true);
        mapStoreConfig.setImplementation(store);
        mapStoreConfig.setWriteDelaySeconds(delaySeconds);

        mapConfig.setName(MAP_NAME);

        mapConfig.setMapStoreConfig(mapStoreConfig);
        config.addMapConfig(mapConfig);

        HazelcastInstance server = Hazelcast.newHazelcastInstance(config);
        HazelcastInstance client = HazelcastClient.newHazelcastClient();
        final IMap map = client.getMap(MAP_NAME);


        final int max = getMaxCapacity(server) + 1;
        for (int i = 0; i < max; i++) {
            map.putAsync(i, i);
        }

        Thread.sleep(1000 * (delaySeconds + 1));
        assertEquals(max - 1, map.size());
    }

    // Default impl. of write-behind-queue has no capacity it is bounded by number of elements in a map.
    // we can open this test, when we have a configuration parameter for write-coalescing.
    // for now this test should be ignored since default mode is write-coalescing.
    @Test(expected = ReachedMaxSizeException.class)
    @Ignore
    public void mapStore_OperationQueue_AtMaxCapacity_Test() throws Exception {
        Config config = new Config();
        MapConfig mapConfig = new MapConfig();
        MapStoreConfig mapStoreConfig = new MapStoreConfig();

        final MapStoreBackup store = new MapStoreBackup();
        final int longDelaySec = 60;
        mapStoreConfig.setEnabled(true);
        mapStoreConfig.setImplementation(store);
        mapStoreConfig.setWriteDelaySeconds(longDelaySec);

        mapConfig.setName(MAP_NAME);

        mapConfig.setMapStoreConfig(mapStoreConfig);
        config.addMapConfig(mapConfig);

        HazelcastInstance server = Hazelcast.newHazelcastInstance(config);
        HazelcastInstance client = HazelcastClient.newHazelcastClient();

        final IMap map = client.getMap(MAP_NAME);

        final int mapStoreQ_MaxCapacity = getMaxCapacity(server) + 1;
        for (int i = 0; i < mapStoreQ_MaxCapacity; i++) {
            map.put(i, i);
        }
    }


    @Test
    public void destroyMap_configedWith_MapStore() throws Exception {
        Config config = new Config();
        MapConfig mapConfig = new MapConfig();
        MapStoreConfig mapStoreConfig = new MapStoreConfig();

        final MapStoreBackup store = new MapStoreBackup();
        final int delaySeconds = 4;
        mapStoreConfig.setEnabled(true);
        mapStoreConfig.setImplementation(store);
        mapStoreConfig.setWriteDelaySeconds(delaySeconds);

        mapConfig.setName(MAP_NAME);

        mapConfig.setMapStoreConfig(mapStoreConfig);
        config.addMapConfig(mapConfig);

        HazelcastInstance server = Hazelcast.newHazelcastInstance(config);
        HazelcastInstance client = HazelcastClient.newHazelcastClient();

        IMap map = client.getMap(MAP_NAME);

        for (int i = 0; i < 1; i++) {
            map.putAsync(i, i);
        }

        map.destroy();
    }


    static class SimpleMapStore implements MapStore<String, String>, MapLoader<String, String> {

        public static final int MAX_KEYS = 30;
        public static final int DELAY_SECONDS_PER_KEY = 1;

        @Override
        public String load(String key) {
            sleepSeconds(DELAY_SECONDS_PER_KEY);
            return key + "value";
        }

        @Override
        public Map<String, String> loadAll(Collection<String> keys) {
            Map<String, String> map = new HashMap<String, String>();
            for (String key : keys) {
                map.put(key, load(key));
            }
            return map;
        }

        @Override
        public Set<String> loadAllKeys() {
            Set<String> keys = new HashSet<String>();

            for (int k = 0; k < MAX_KEYS; k++) {
                keys.add("key" + k);
            }

            return keys;
        }

        @Override
        public void delete(String key) {
            sleepSeconds(DELAY_SECONDS_PER_KEY);
        }

        @Override
        public void deleteAll(Collection<String> keys) {
            for (String key : keys) {
                delete(key);
            }
        }

        @Override
        public void store(String key, String value) {
            sleepSeconds(DELAY_SECONDS_PER_KEY);
        }

        @Override
        public void storeAll(Map<String, String> entries) {
            for (Map.Entry<String, String> e : entries.entrySet()) {
                store(e.getKey(), e.getValue());
            }
        }
    }

    private class ClientThread extends Thread {

        IMap<String, String> map;

        public void run() {
            HazelcastInstance client = HazelcastClient.newHazelcastClient();
            map = client.getMap(ClientMapStoreTest.MAP_NAME);
            map.size();
        }
    }

    public class MapStoreBackup implements MapStore<Object, Object> {

        public final Map store = new ConcurrentHashMap();

        @Override
        public void store(Object key, Object value) {
            store.put(key, value);
        }

        @Override
        public void storeAll(Map<Object, Object> map) {
            for (Map.Entry<Object, Object> kvp : map.entrySet()) {
                store.put(kvp.getKey(), kvp.getValue());
            }
        }

        @Override
        public void delete(Object key) {
            store.remove(key);
        }

        @Override
        public void deleteAll(Collection<Object> keys) {
            for (Object key : keys) {
                store.remove(key);
            }
        }

        @Override
        public Object load(Object key) {
            return store.get(key);
        }

        @Override
        public Map<Object, Object> loadAll(Collection<Object> keys) {
            Map result = new HashMap();
            for (Object key : keys) {
                final Object v = store.get(key);
                if (v != null) {
                    result.put(key, v);
                }
            }
            return result;
        }

        @Override
        public Set<Object> loadAllKeys() {
            return store.keySet();
        }
    }

    private int getMaxCapacity(HazelcastInstance node) {
        return getNode(node).getNodeEngine().getGroupProperties().MAP_WRITE_BEHIND_QUEUE_CAPACITY.getInteger();
    }


    @Test
    public void testIssue3023_testWithSubStringMapNames() throws Exception {
        String mapNameWithStore = "MapStore*";
        String mapNameWithStoreAndSize = "MapStoreMaxSize*";

        String xml = "<hazelcast xsi:schemaLocation=\"http://www.hazelcast.com/schema/config\n" +
                "                             http://www.hazelcast.com/schema/config/hazelcast-config-3.2.xsd\"\n" +
                "                             xmlns=\"http://www.hazelcast.com/schema/config\"\n" +
                "                             xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" +
                "\n" +
                "    <map name=\"" + mapNameWithStore + "\">\n" +
                "        <map-store enabled=\"true\">\n" +
                "            <class-name>com.will.cause.problem.if.used</class-name>\n" +
                "            <write-delay-seconds>5</write-delay-seconds>\n" +
                "        </map-store>\n" +
                "    </map>\n" +
                "\n" +
                "    <map name=\"" + mapNameWithStoreAndSize + "\">\n" +
                "        <in-memory-format>BINARY</in-memory-format>\n" +
                "        <backup-count>1</backup-count>\n" +
                "        <async-backup-count>0</async-backup-count>\n" +
                "        <max-idle-seconds>0</max-idle-seconds>\n" +
                "        <eviction-policy>LRU</eviction-policy>\n" +
                "        <max-size policy=\"PER_NODE\">10</max-size>\n" +
                "        <eviction-percentage>50</eviction-percentage>\n" +
                "\n" +
                "        <merge-policy>com.hazelcast.map.merge.PassThroughMergePolicy</merge-policy>\n" +
                "\n" +
                "        <map-store enabled=\"true\">\n" +
                "            <class-name>com.hazelcast.client.map.helpers.AMapStore</class-name>\n" +
                "            <write-delay-seconds>5</write-delay-seconds>\n" +
                "        </map-store>\n" +
                "    </map>\n" +
                "\n" +
                "</hazelcast>";

        Config config = buildConfig(xml);
        HazelcastInstance hz = Hazelcast.newHazelcastInstance(config);
        HazelcastInstance client = HazelcastClient.newHazelcastClient();

        IMap map = client.getMap(mapNameWithStoreAndSize + "1");
        map.put(1, 1);

        final AMapStore store = (AMapStore) (hz.getConfig().getMapConfig(mapNameWithStoreAndSize + "1").getMapStoreConfig().getImplementation());

        assertTrueEventually(new AssertTask() {
            @Override
            public void run() throws Exception {
                assertEquals(1, store.store.get(1));
            }
        });
    }

    private Config buildConfig(String xml) {
        ByteArrayInputStream bis = new ByteArrayInputStream(xml.getBytes());
        XmlConfigBuilder configBuilder = new XmlConfigBuilder(bis);
        return configBuilder.build();
    }
}
TOP

Related Classes of com.hazelcast.client.map.ClientMapStoreTest$ClientThread

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.