/*
* 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.ignite.internal.processors.cache.distributed.replicated.preloader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import javax.cache.configuration.CacheEntryListenerConfiguration;
import javax.cache.configuration.Factory;
import javax.cache.configuration.MutableCacheEntryListenerConfiguration;
import javax.cache.event.CacheEntryEventFilter;
import javax.cache.event.CacheEntryListener;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteMessaging;
import org.apache.ignite.binary.BinaryObject;
import org.apache.ignite.cache.CacheEntryEventSerializableFilter;
import org.apache.ignite.cache.CachePeekMode;
import org.apache.ignite.cache.CacheRebalanceMode;
import org.apache.ignite.cache.affinity.AffinityFunction;
import org.apache.ignite.cache.affinity.AffinityFunctionContext;
import org.apache.ignite.cache.affinity.AffinityKeyMapper;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.events.Event;
import org.apache.ignite.internal.IgniteKernal;
import org.apache.ignite.internal.binary.BinaryEnumObjectImpl;
import org.apache.ignite.internal.binary.BinaryMarshaller;
import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.P2;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgnitePredicate;
import org.apache.ignite.plugin.CachePluginConfiguration;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
import org.apache.ignite.spi.eventstorage.memory.MemoryEventStorageSpi;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import static org.apache.ignite.cache.CacheMode.REPLICATED;
import static org.apache.ignite.cache.CacheRebalanceMode.ASYNC;
import static org.apache.ignite.cache.CacheRebalanceMode.SYNC;
import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
import static org.apache.ignite.configuration.DeploymentMode.CONTINUOUS;
import static org.apache.ignite.events.EventType.EVTS_ALL;
import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_PUT;
import static org.apache.ignite.events.EventType.EVT_CACHE_REBALANCE_STARTED;
import static org.apache.ignite.events.EventType.EVT_CACHE_REBALANCE_STOPPED;
/**
* Tests for replicated cache preloader.
*/
@SuppressWarnings("unchecked")
public class GridCacheReplicatedPreloadSelfTest extends GridCommonAbstractTest {
/** */
private CacheRebalanceMode preloadMode = ASYNC;
/** */
private int batchSize = 4096;
/** */
private int poolSize = 2;
/** */
private volatile boolean extClassloadingAtCfg = false;
/** */
private volatile boolean isClient = false;
/** */
private volatile boolean useExtClassLoader = false;
/** Disable p2p. */
private volatile boolean disableP2p = false;
/** */
private TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true);
/** */
private static volatile CountDownLatch latch;
/** */
private static boolean cutromEvt = false;
/** {@inheritDoc} */
@Override protected void afterTest() throws Exception {
super.afterTest();
stopAllGrids();
}
/** {@inheritDoc} */
@Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
TcpDiscoverySpi disco = new TcpDiscoverySpi();
disco.setIpFinder(ipFinder);
cfg.setDiscoverySpi(disco);
cfg.setCacheConfiguration(cacheConfiguration(igniteInstanceName));
cfg.setDeploymentMode(CONTINUOUS);
cfg.setUserAttributes(F.asMap("EVEN", !igniteInstanceName.endsWith("0") && !igniteInstanceName.endsWith("2")));
MemoryEventStorageSpi spi = new MemoryEventStorageSpi();
spi.setExpireCount(50_000);
cfg.setEventStorageSpi(spi);
if (disableP2p)
cfg.setPeerClassLoadingEnabled(false);
if (getTestIgniteInstanceName(1).equals(igniteInstanceName) || useExtClassLoader ||
cfg.getMarshaller() instanceof BinaryMarshaller)
cfg.setClassLoader(getExternalClassLoader());
if (isClient)
cfg.setClientMode(true);
if (cutromEvt) {
int[] evts = new int[EVTS_ALL.length + 1];
evts[0] = Integer.MAX_VALUE - 1;
System.arraycopy(EVTS_ALL, 0, evts, 1, EVTS_ALL.length);
cfg.setIncludeEventTypes(evts);
}
return cfg;
}
/**
* Gets cache configuration for grid with specified name.
*
* @param igniteInstanceName Ignite instance name.
* @return Cache configuration.
*/
CacheConfiguration cacheConfiguration(String igniteInstanceName) {
CacheConfiguration cacheCfg = defaultCacheConfiguration();
cacheCfg.setCacheMode(REPLICATED);
cacheCfg.setWriteSynchronizationMode(FULL_SYNC);
cacheCfg.setRebalanceMode(preloadMode);
cacheCfg.setRebalanceBatchSize(batchSize);
cacheCfg.setRebalanceThreadPoolSize(poolSize);
if (extClassloadingAtCfg)
loadExternalClassesToCfg(cacheCfg);
return cacheCfg;
}
/**
*
* @param cacheCfg Configuration.
*/
private void loadExternalClassesToCfg(CacheConfiguration cacheCfg) {
try {
Object sf = getExternalClassLoader().
loadClass("org.apache.ignite.tests.p2p.CacheDeploymentTestStoreFactory").newInstance();
cacheCfg.setCacheStoreFactory((Factory)sf);
Object sslf = getExternalClassLoader().
loadClass("org.apache.ignite.tests.p2p.CacheDeploymentStoreSessionListenerFactory").newInstance();
cacheCfg.setCacheStoreSessionListenerFactories((Factory)sslf);
Object cpc = getExternalClassLoader().
loadClass("org.apache.ignite.tests.p2p.CacheDeploymentCachePluginConfiguration").newInstance();
cacheCfg.setPluginConfigurations((CachePluginConfiguration)cpc);
Object akm = getExternalClassLoader().
loadClass("org.apache.ignite.tests.p2p.CacheDeploymentAffinityKeyMapper").newInstance();
cacheCfg.setAffinityMapper((AffinityKeyMapper)akm);
Object pred = getExternalClassLoader().
loadClass("org.apache.ignite.tests.p2p.CacheDeploymentAlwaysTruePredicate2").newInstance();
cacheCfg.setNodeFilter((IgnitePredicate)pred);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @throws Exception If failed.
*/
public void testSingleNode() throws Exception {
preloadMode = SYNC;
try {
startGrid(1);
}
finally {
stopAllGrids();
}
}
/**
* @throws Exception If test failed.
*/
public void testIntegrity() throws Exception {
preloadMode = SYNC;
try {
Ignite g1 = startGrid(1);
GridCacheAdapter<Integer, String> cache1 = ((IgniteKernal)g1).internalCache(DEFAULT_CACHE_NAME);
cache1.getAndPut(1, "val1");
cache1.getAndPut(2, "val2");
GridCacheEntryEx e1 = cache1.entryEx(1);
assertNotNull(e1);
e1.unswap();
Ignite g2 = startGrid(2);
Collection<Event> evts = null;
for (int i = 0; i < 3; i++) {
evts = g2.events().localQuery(F.<Event>alwaysTrue(),
EVT_CACHE_REBALANCE_STARTED, EVT_CACHE_REBALANCE_STOPPED);
if (evts.size() != 2) {
info("Wrong events collection size (will retry in 1000 ms): " + evts.size());
Thread.sleep(1000);
}
else
break;
}
assert evts != null && evts.size() == 2 : "Wrong events received: " + evts;
Iterator<Event> iter = evts.iterator();
assertEquals(EVT_CACHE_REBALANCE_STARTED, iter.next().type());
assertEquals(EVT_CACHE_REBALANCE_STOPPED, iter.next().type());
IgniteCache<Integer, String> cache2 = g2.cache(DEFAULT_CACHE_NAME);
assertEquals("val1", cache2.localPeek(1));
assertEquals("val2", cache2.localPeek(2));
GridCacheAdapter<Integer, String> cacheAdapter2 = ((IgniteKernal)g2).internalCache(DEFAULT_CACHE_NAME);
GridCacheEntryEx e2 = cacheAdapter2.entryEx(1);
assertNotNull(e2);
assertNotSame(e2, e1);
e2.unswap();
assertNotNull(e2.version());
assertEquals(e1.version(), e2.version());
}
finally {
stopAllGrids();
}
}
/**
* @throws Exception If test failed.
*/
public void testDeployment() throws Exception {
// TODO GG-11141.
if (true)
return;
preloadMode = SYNC;
try {
Ignite g1 = startGrid(1);
Ignite g2 = startGrid(2);
IgniteCache<Integer, Object> cache1 = g1.cache(DEFAULT_CACHE_NAME);
IgniteCache<Integer, Object> cache2 = g2.cache(DEFAULT_CACHE_NAME);
ClassLoader ldr = grid(1).configuration().getClassLoader();
Object v1 = ldr.loadClass("org.apache.ignite.tests.p2p.CacheDeploymentTestValue3").newInstance();
cache1.put(1, v1);
info("Stored value in cache1 [v=" + v1 + ", ldr=" + v1.getClass().getClassLoader() + ']');
Object v2 = cache2.get(1);
info("Read value from cache2 [v=" + v2 + ", ldr=" + v2.getClass().getClassLoader() + ']');
assert v2 != null;
assert v2.toString().equals(v1.toString());
assert !v2.getClass().getClassLoader().equals(getClass().getClassLoader());
assert v2.getClass().getClassLoader().getClass().getName().contains("GridDeploymentClassLoader") ||
grid(2).configuration().getMarshaller() instanceof BinaryMarshaller;
Object e1 = ldr.loadClass("org.apache.ignite.tests.p2p.CacheDeploymentTestEnumValue").getEnumConstants()[0];
cache1.put(2, e1);
Object e2 = cache2.get(2);
if (g1.configuration().getMarshaller() instanceof BinaryMarshaller) {
BinaryObject enumObj = (BinaryObject)cache2.withKeepBinary().get(2);
assertEquals(0, enumObj.enumOrdinal());
assertTrue(enumObj.type().isEnum());
assertTrue(enumObj instanceof BinaryEnumObjectImpl);
}
assert e2 != null;
assert e2.toString().equals(e1.toString());
assert !e2.getClass().getClassLoader().equals(getClass().getClassLoader());
assert e2.getClass().getClassLoader().getClass().getName().contains("GridDeploymentClassLoader") ||
grid(2).configuration().getMarshaller() instanceof BinaryMarshaller;
stopGrid(1);
Ignite g3 = startGrid(3);
IgniteCache<Integer, Object> cache3 = g3.cache(DEFAULT_CACHE_NAME);
Object v3 = cache3.localPeek(1, CachePeekMode.ONHEAP);
assert v3 != null;
info("Read value from cache3 [v=" + v3 + ", ldr=" + v3.getClass().getClassLoader() + ']');
assert v3 != null;
assert v3.toString().equals(v1.toString());
assert !v3.getClass().getClassLoader().equals(getClass().getClassLoader());
assert v3.getClass().getClassLoader().getClass().getName().contains("GridDeploymentClassLoader") ||
grid(3).configuration().getMarshaller() instanceof BinaryMarshaller;
}
finally {
stopAllGrids();
}
}
/**
* @throws Exception If test failed.
*/
public void testExternalClassesAtConfiguration() throws Exception {
try {
extClassloadingAtCfg = true;
useExtClassLoader = true;
Ignite g1 = startGrid(1);
Ignite g2 = startGrid(2); // Checks deserialization at node join.
isClient = true;
Ignite g3 = startGrid(3);
IgniteCache<Integer, Object> cache1 = g1.cache(DEFAULT_CACHE_NAME);
IgniteCache<Integer, Object> cache2 = g2.cache(DEFAULT_CACHE_NAME);
IgniteCache<Integer, Object> cache3 = g3.cache(DEFAULT_CACHE_NAME);
final Class<CacheEntryListener> cls1 = (Class<CacheEntryListener>) getExternalClassLoader().
loadClass("org.apache.ignite.tests.p2p.CacheDeploymentCacheEntryListener");
final Class<CacheEntryEventSerializableFilter> cls2 = (Class<CacheEntryEventSerializableFilter>) getExternalClassLoader().
loadClass("org.apache.ignite.tests.p2p.CacheDeploymentCacheEntryEventSerializableFilter");
CacheEntryListenerConfiguration<Integer, Object> lsnrCfg = new MutableCacheEntryListenerConfiguration<>(
new Factory<CacheEntryListener<Integer, Object>>() {
@Override public CacheEntryListener<Integer, Object> create() {
try {
return cls1.newInstance();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
},
new ClassFilterFactory(cls2),
true,
true
);
cache1.registerCacheEntryListener(lsnrCfg);
cache1.put(1, 1);
assertEquals(1, cache2.get(1));
assertEquals(1, cache3.get(1));
}
finally {
extClassloadingAtCfg = false;
isClient = false;
useExtClassLoader = false;
}
}
/**
* @throws Exception If test failed.
*/
public void testExternalClassesAtConfigurationDynamicStart() throws Exception {
try {
extClassloadingAtCfg = false;
useExtClassLoader = true;
Ignite g1 = startGrid(1);
Ignite g2 = startGrid(2);
isClient = true;
Ignite g3 = startGrid(3);
CacheConfiguration cfg = defaultCacheConfiguration();
loadExternalClassesToCfg(cfg);
cfg.setName("customStore");
IgniteCache<Integer, Object> cache1 = g1.createCache(cfg);
IgniteCache<Integer, Object> cache2 = g2.getOrCreateCache(cfg); // Checks deserialization at cache creation.
IgniteCache<Integer, Object> cache3 = g3.getOrCreateCache(cfg); // Checks deserialization at cache creation.
cache1.put(1, 1);
assertEquals(1, cache2.get(1));
assertEquals(1, cache3.get(1));
}
finally {
extClassloadingAtCfg = false;
isClient = false;
useExtClassLoader = false;
}
}
/**
* @throws Exception If test failed.
*/
public void testExternalClassesAtConfigurationDynamicStart2() throws Exception {
try {
extClassloadingAtCfg = false;
useExtClassLoader = true;
Ignite g1 = startGrid(1);
Ignite g2 = startGrid(2);
isClient = true;
Ignite g3 = startGrid(3);
CacheConfiguration cfg = defaultCacheConfiguration();
loadExternalClassesToCfg(cfg);
cfg.setName("customStore");
IgniteCache<Integer, Object> cache1 = g1.getOrCreateCache(cfg);
IgniteCache<Integer, Object> cache2 = g2.getOrCreateCache("customStore"); // Checks deserialization at cache creation.
IgniteCache<Integer, Object> cache3 = g3.getOrCreateCache("customStore"); // Checks deserialization at cache creation.
cache1.put(1, 1);
assertEquals(1, cache2.get(1));
assertEquals(1, cache3.get(1));
}
finally {
extClassloadingAtCfg = false;
isClient = false;
useExtClassLoader = false;
}
}
/**
* @throws Exception If test failed.
*/
public void testExternalClassesAtMessage() throws Exception {
try {
useExtClassLoader = true;
disableP2p = true;
final Class cls = (Class)getExternalClassLoader().
loadClass("org.apache.ignite.tests.p2p.CacheDeploymentExternalizableTestValue");
Ignite g1 = startGrid(1);
startGrid(2);
IgniteMessaging rmtMsg = g1.message();
latch = new CountDownLatch(2);
rmtMsg.remoteListen("MyOrderedTopic", new MessageListener());
Object o = cls.newInstance();
o.toString();
rmtMsg.send("MyOrderedTopic", o);
rmtMsg.sendOrdered("MyOrderedTopic", o, 0);
latch.await();
// Custom topic.
final Class cls2 = (Class)getExternalClassLoader().
loadClass("org.apache.ignite.tests.p2p.CacheDeploymentTestEnumValue");
Object topic = cls2.getEnumConstants()[0];
latch = new CountDownLatch(2);
rmtMsg.remoteListen(topic, new MessageListener());
rmtMsg.send(topic, topic);
rmtMsg.sendOrdered(topic, topic, 0);
latch.await();
}
finally {
useExtClassLoader = false;
disableP2p = false;
}
}
/**
* @throws Exception If test failed.
*/
public void testExternalClassesAtEventP2pDisabled() throws Exception {
testExternalClassesAtEvent0(true);
}
/**
* @throws Exception If test failed.
*/
public void testExternalClassesAtEvent() throws Exception {
testExternalClassesAtEvent0(false);
}
/**
* @throws Exception If test failed.
*/
private void testExternalClassesAtEvent0(boolean p2p) throws Exception {
try {
useExtClassLoader = true;
cutromEvt = true;
if (p2p)
disableP2p = true;
final Class cls = (Class)getExternalClassLoader().
loadClass("org.apache.ignite.tests.p2p.CacheDeploymentExternalizableTestValue");
final Class cls2 = (Class)getExternalClassLoader().
loadClass("org.apache.ignite.tests.p2p.GridEventConsumeFilter");
Ignite g1 = startGrid(1);
startGrid(2);
latch = new CountDownLatch(3);
g1.events().localListen((IgnitePredicate)cls2.newInstance(), EVT_CACHE_OBJECT_PUT);
g1.events().localListen(new EventListener(), EVT_CACHE_OBJECT_PUT);
g1.events().remoteListen(null, (IgnitePredicate)cls2.newInstance(), EVT_CACHE_OBJECT_PUT);
g1.events().remoteListen(null, new EventListener(), EVT_CACHE_OBJECT_PUT);
g1.cache(DEFAULT_CACHE_NAME).put("1", cls.newInstance());
latch.await();
}
finally {
useExtClassLoader = false;
cutromEvt = false;
if (p2p)
disableP2p = false;
}
}
/**
* @throws Exception If test failed.
*/
public void testSync() throws Exception {
preloadMode = SYNC;
batchSize = 512;
try {
IgniteCache<Integer, String> cache1 = startGrid(1).cache(DEFAULT_CACHE_NAME);
int keyCnt = 1000;
for (int i = 0; i < keyCnt; i++)
cache1.put(i, "val" + i);
IgniteCache<Integer, String> cache2 = startGrid(2).cache(DEFAULT_CACHE_NAME);
assertEquals(keyCnt, cache2.localSize(CachePeekMode.ALL));
}
finally {
stopAllGrids();
}
}
/**
* @throws Exception If test failed.
*/
public void testAsync() throws Exception {
preloadMode = ASYNC;
batchSize = 256;
try {
IgniteCache<Integer, String> cache1 = startGrid(1).cache(DEFAULT_CACHE_NAME);
int keyCnt = 2000;
for (int i = 0; i < keyCnt; i++)
cache1.put(i, "val" + i);
IgniteCache<Integer, String> cache2 = startGrid(2).cache(DEFAULT_CACHE_NAME);
int size = cache2.localSize(CachePeekMode.ALL);
info("Size of cache2: " + size);
assert waitCacheSize(cache2, keyCnt, getTestTimeout()) :
"Actual cache size: " + cache2.localSize(CachePeekMode.ALL);
}
finally {
stopAllGrids();
}
}
/**
* @param cache Cache.
* @param expSize Lower bound of expected size.
* @param timeout Timeout.
* @return {@code true} if success.
* @throws InterruptedException If thread was interrupted.
*/
@SuppressWarnings({"BusyWait"})
private boolean waitCacheSize(IgniteCache<Integer, String> cache, int expSize, long timeout)
throws InterruptedException {
assert cache != null;
assert expSize > 0;
assert timeout >= 0;
long end = System.currentTimeMillis() + timeout;
while (cache.localSize(CachePeekMode.ALL) < expSize) {
Thread.sleep(50);
if (end - System.currentTimeMillis() <= 0)
break;
}
return cache.localSize(CachePeekMode.ALL) >= expSize;
}
/**
* @throws Exception If test failed.
*/
public void testBatchSize1() throws Exception {
preloadMode = SYNC;
batchSize = 1; // 1 byte but one entry should be in batch anyway.
try {
IgniteCache<Integer, String> cache1 = startGrid(1).cache(DEFAULT_CACHE_NAME);
int cnt = 100;
for (int i = 0; i < cnt; i++)
cache1.put(i, "val" + i);
IgniteCache<Integer, String> cache2 = startGrid(2).cache(DEFAULT_CACHE_NAME);
assertEquals(cnt, cache2.localSize(CachePeekMode.ALL));
}
finally {
stopAllGrids();
}
}
/**
* @throws Exception If test failed.
*/
public void testBatchSize1000() throws Exception {
preloadMode = SYNC;
batchSize = 1000; // 1000 bytes.
try {
IgniteCache<Integer, String> cache1 = startGrid(1).cache(DEFAULT_CACHE_NAME);
int cnt = 100;
for (int i = 0; i < cnt; i++)
cache1.put(i, "val" + i);
IgniteCache<Integer, String> cache2 = startGrid(2).cache(DEFAULT_CACHE_NAME);
assertEquals(cnt, cache2.localSize(CachePeekMode.ALL));
}
finally {
stopAllGrids();
}
}
/**
* @throws Exception If test failed.
*/
public void testBatchSize10000() throws Exception {
preloadMode = SYNC;
batchSize = 10000; // 10000 bytes.
try {
IgniteCache<Integer, String> cache1 = startGrid(1).cache(DEFAULT_CACHE_NAME);
int cnt = 100;
for (int i = 0; i < cnt; i++)
cache1.put(i, "val" + i);
IgniteCache<Integer, String> cache2 = startGrid(2).cache(DEFAULT_CACHE_NAME);
assertEquals(cnt, cache2.localSize(CachePeekMode.ALL));
}
finally {
stopGrid(1);
stopGrid(2);
}
}
/**
* @throws Exception If test failed.
*/
public void testMultipleNodes() throws Exception {
preloadMode = ASYNC;
batchSize = 256;
try {
int gridCnt = 4;
startGridsMultiThreaded(gridCnt);
info("Beginning data population...");
int cnt = 2500;
Map<Integer, String> map = null;
for (int i = 0; i < cnt; i++) {
if (i % 100 == 0) {
if (map != null && !map.isEmpty()) {
grid(0).cache(DEFAULT_CACHE_NAME).putAll(map);
info("Put entries count: " + i);
}
map = new HashMap<>();
}
map.put(i, "val" + i);
}
if (map != null && !map.isEmpty())
grid(0).cache(DEFAULT_CACHE_NAME).putAll(map);
for (int gridIdx = 0; gridIdx < gridCnt; gridIdx++) {
assert grid(gridIdx).cache(DEFAULT_CACHE_NAME).localSize(CachePeekMode.ALL) == cnt :
"Actual size: " + grid(gridIdx).cache(DEFAULT_CACHE_NAME).localSize(CachePeekMode.ALL);
info("Cache size is OK for grid index: " + gridIdx);
}
IgniteCache<Integer, String> lastCache = startGrid(gridCnt).cache(DEFAULT_CACHE_NAME);
// Let preloading start.
Thread.sleep(1000);
// Stop random initial node while preloading is in progress.
int idx = new Random().nextInt(gridCnt);
info("Stopping node with index: " + idx);
stopGrid(idx);
assert waitCacheSize(lastCache, cnt, 20 * 1000) :
"Actual cache size: " + lastCache.localSize(CachePeekMode.ALL);
}
finally {
stopAllGrids();
}
}
/**
* @throws Exception If test failed.
*/
public void testConcurrentStartSync() throws Exception {
preloadMode = SYNC;
batchSize = 10000;
try {
startGridsMultiThreaded(4);
}
finally {
stopAllGrids();
}
}
/**
* @throws Exception If test failed.
*/
public void testConcurrentStartAsync() throws Exception {
preloadMode = ASYNC;
batchSize = 10000;
try {
startGridsMultiThreaded(4);
}
finally {
stopAllGrids();
}
}
/**
* Test affinity.
*/
@SuppressWarnings({"PublicInnerClass"})
private static class TestAffinityFunction implements AffinityFunction {
/** {@inheritDoc} */
@Override public int partitions() {
return 2;
}
/** {@inheritDoc} */
@Override public int partition(Object key) {
if (key instanceof Number)
return ((Number)key).intValue() % 2;
return key == null ? 0 : U.safeAbs(key.hashCode() % 2);
}
/** {@inheritDoc} */
@Override public List<List<ClusterNode>> assignPartitions(AffinityFunctionContext affCtx) {
List<List<ClusterNode>> res = new ArrayList<>(partitions());
for (int part = 0; part < partitions(); part++)
res.add(nodes(part, affCtx.currentTopologySnapshot()));
return res;
}
/** {@inheritDoc} */
@SuppressWarnings({"RedundantTypeArguments"})
public List<ClusterNode> nodes(int part, Collection<ClusterNode> nodes) {
Collection<ClusterNode> col = new HashSet<>(nodes);
if (col.size() <= 1)
return new ArrayList<>(col);
for (Iterator<ClusterNode> iter = col.iterator(); iter.hasNext(); ) {
ClusterNode node = iter.next();
boolean even = node.<Boolean>attribute("EVEN");
if ((even && part != 0) || (!even && part != 1))
iter.remove();
}
return new ArrayList<>(col);
}
/** {@inheritDoc} */
@Override public void reset() {
// No-op.
}
/** {@inheritDoc} */
@Override public void removeNode(UUID nodeId) {
// No-op.
}
}
/**
*
*/
private static class MessageListener implements P2<UUID, Object> {
/**
* @param nodeId
* @param msg
* @return
*/
@Override public boolean apply(UUID nodeId, Object msg) {
System.out.println("Received message [msg=" + msg + ", from=" + nodeId + ']');
latch.countDown();
return true; // Return true to continue listening.
}
}
private static class EventListener implements IgnitePredicate<Event> {
@Override public boolean apply(Event evt) {
System.out.println("Cache event: " + evt);
latch.countDown();
return true;
}
}
/**
*
*/
private static class ClassFilterFactory implements Factory<CacheEntryEventFilter<Integer, Object>> {
/** */
private Class<CacheEntryEventSerializableFilter> cls;
/**
* @param cls Class.
*/
public ClassFilterFactory(Class<CacheEntryEventSerializableFilter> cls) {
this.cls = cls;
}
/** {@inheritDoc} */
@Override public CacheEntryEventSerializableFilter<Integer, Object> create() {
try {
return cls.newInstance();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}