/* * 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; import javax.cache.Cache; import javax.cache.configuration.Factory; import javax.cache.integration.CacheWriterException; import javax.cache.processor.MutableEntry; import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCache; import org.apache.ignite.cache.CacheAtomicityMode; import org.apache.ignite.cache.CacheEntryProcessor; import org.apache.ignite.cache.CacheMode; import org.apache.ignite.cache.CachePeekMode; import org.apache.ignite.cache.CacheWriteSynchronizationMode; import org.apache.ignite.cache.store.CacheStore; import org.apache.ignite.cache.store.CacheStoreAdapter; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.configuration.MemoryConfiguration; import org.apache.ignite.configuration.NearCacheConfiguration; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.lang.IgniteBiInClosure; import org.apache.ignite.resources.IgniteInstanceResource; 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.testframework.junits.common.GridCommonAbstractTest; import static org.apache.ignite.IgniteSystemProperties.IGNITE_SKIP_CONFIGURATION_CONSISTENCY_CHECK; /** * Tests for cache client with and without store. */ public class CacheClientStoreSelfTest extends GridCommonAbstractTest { /** */ private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true); /** */ private static final String CACHE_NAME = "test-cache"; /** */ private volatile boolean nearEnabled; /** */ private volatile Factory<CacheStore> factory; /** */ private volatile CacheMode cacheMode; /** */ private static volatile boolean loadedFromClient; /** {@inheritDoc} */ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); boolean client = igniteInstanceName != null && igniteInstanceName.startsWith("client"); cfg.setClientMode(client); if (client) cfg.setMemoryConfiguration(new MemoryConfiguration()); CacheConfiguration cc = new CacheConfiguration(DEFAULT_CACHE_NAME); cc.setName(CACHE_NAME); cc.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL); cc.setCacheMode(cacheMode); cc.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC); cc.setBackups(1); cc.setCacheStoreFactory(factory); if (factory instanceof Factory3) cc.setReadThrough(true); if (client && nearEnabled) cc.setNearConfiguration(new NearCacheConfiguration()); cfg.setCacheConfiguration(cc); TcpDiscoverySpi disco = new TcpDiscoverySpi(); disco.setIpFinder(IP_FINDER); cfg.setDiscoverySpi(disco); return cfg; } /** {@inheritDoc} */ @Override protected void afterTest() throws Exception { stopAllGrids(); loadedFromClient = false; } /** * @throws Exception If failed. */ public void testCorrectStore() throws Exception { nearEnabled = false; cacheMode = CacheMode.PARTITIONED; factory = new Factory1(); startGrids(2); Ignite ignite = startGrid("client-1"); IgniteCache<Object, Object> cache = ignite.cache(CACHE_NAME); cache.get(0); cache.getAll(F.asSet(0, 1)); cache.getAndPut(0, 0); cache.getAndPutIfAbsent(0, 0); cache.getAndRemove(0); cache.getAndReplace(0, 0); cache.put(0, 0); cache.putAll(F.asMap(0, 0, 1, 1)); cache.putIfAbsent(0, 0); cache.remove(0); cache.remove(0, 0); cache.removeAll(F.asSet(0, 1)); cache.removeAll(); cache.invoke(0, new EP()); cache.invokeAll(F.asSet(0, 1), new EP()); } /** * @throws Exception If failed. */ public void testInvalidStore() throws Exception { nearEnabled = false; cacheMode = CacheMode.PARTITIONED; factory = new Factory1(); startGrids(2); factory = new Factory2(); startGrid("client-1"); } /** * @throws Exception If failed. */ public void testDisabledConsistencyCheck() throws Exception { nearEnabled = false; cacheMode = CacheMode.PARTITIONED; factory = new Factory1(); startGrids(2); factory = new Factory2(); System.setProperty(IGNITE_SKIP_CONFIGURATION_CONSISTENCY_CHECK, "true"); startGrid("client-1"); factory = new Factory1(); System.clearProperty(IGNITE_SKIP_CONFIGURATION_CONSISTENCY_CHECK); startGrid("client-2"); } /** * @throws Exception If failed. */ public void testNoStoreNearDisabled() throws Exception { nearEnabled = false; cacheMode = CacheMode.PARTITIONED; factory = new Factory1(); startGrids(2); doTestNoStore(); } /** * @throws Exception If failed. */ public void testNoStoreNearEnabled() throws Exception { nearEnabled = true; cacheMode = CacheMode.PARTITIONED; factory = new Factory1(); startGrids(2); doTestNoStore(); } /** * @throws Exception If failed. */ private void doTestNoStore() throws Exception { factory = null; Ignite ignite = startGrid("client-1"); IgniteCache<Object, Object> cache = ignite.cache(CACHE_NAME); cache.get(0); cache.getAll(F.asSet(0, 1)); cache.getAndPut(0, 0); cache.getAndPutIfAbsent(0, 0); cache.getAndRemove(0); cache.getAndReplace(0, 0); cache.put(0, 0); cache.putAll(F.asMap(0, 0, 1, 1)); cache.putIfAbsent(0, 0); cache.remove(0); cache.remove(0, 0); cache.removeAll(F.asSet(0, 1)); cache.removeAll(); cache.invoke(0, new EP()); cache.invokeAll(F.asSet(0, 1), new EP()); } /** * Load cache created on client as LOCAL and see if it only loaded on client * * @throws Exception If failed. */ public void testLocalLoadClient() throws Exception { cacheMode = CacheMode.LOCAL; factory = new Factory3(); startGrids(2); Ignite client = startGrid("client-1"); IgniteCache<Object, Object> cache = client.cache(CACHE_NAME); cache.loadCache(null); assertEquals(10, cache.localSize(CachePeekMode.ALL)); assertEquals(0, grid(0).cache(CACHE_NAME).localSize(CachePeekMode.ALL)); assertEquals(0, grid(1).cache(CACHE_NAME).localSize(CachePeekMode.ALL)); assert loadedFromClient; } /** * Load cache from server that created on client as LOCAL and see if it only loaded on server * * @throws Exception If failed. */ public void testLocalLoadServer() throws Exception { cacheMode = CacheMode.LOCAL; factory = new Factory3(); startGrids(2); Ignite client = startGrid("client-1"); IgniteCache cache = grid(0).cache(CACHE_NAME); cache.loadCache(null); assertEquals(10, cache.localSize(CachePeekMode.ALL)); assertEquals(0, grid(1).cache(CACHE_NAME).localSize(CachePeekMode.ALL)); assertEquals(0, client.cache(CACHE_NAME).localSize(CachePeekMode.ALL)); assert !loadedFromClient : "Loaded data from client!"; } /** * Load cache created on client as REPLICATED and see if it only loaded on servers */ public void testReplicatedLoadFromClient() throws Exception { cacheMode = CacheMode.REPLICATED; factory = new Factory3(); startGrids(2); Ignite client = startGrid("client-1"); IgniteCache cache = client.cache(CACHE_NAME); cache.loadCache(null); assertEquals(0, cache.localSize(CachePeekMode.ALL)); assertEquals(10, grid(0).cache(CACHE_NAME).localSize(CachePeekMode.ALL)); assertEquals(10, grid(1).cache(CACHE_NAME).localSize(CachePeekMode.ALL)); assert !loadedFromClient : "Loaded data from client!"; } /** * Load cache created on client as REPLICATED and see if it only loaded on servers */ public void testPartitionedLoadFromClient() throws Exception { cacheMode = CacheMode.PARTITIONED; factory = new Factory3(); startGrids(2); Ignite client = startGrid("client-1"); IgniteCache cache = client.cache(CACHE_NAME); cache.loadCache(null); assertEquals(0, cache.localSize(CachePeekMode.ALL)); assertEquals(10, grid(0).cache(CACHE_NAME).localSize(CachePeekMode.ALL)); assertEquals(10, grid(1).cache(CACHE_NAME).localSize(CachePeekMode.ALL)); assert !loadedFromClient : "Loaded data from client!"; } /** */ private static class Factory1 implements Factory<CacheStore> { /** {@inheritDoc} */ @Override public CacheStore create() { return null; } } /** */ private static class Factory2 implements Factory<CacheStore> { /** {@inheritDoc} */ @Override public CacheStore create() { return null; } } /** */ private static class Factory3 implements Factory<CacheStore> { /** {@inheritDoc} */ @Override public CacheStore create() { return new TestStore(); } } /** */ private static class EP implements CacheEntryProcessor { /** {@inheritDoc} */ @Override public Object process(MutableEntry entry, Object... arguments) { return null; } } /** * Test store that loads 10 item */ public static class TestStore extends CacheStoreAdapter<Object, Object> { /** */ @IgniteInstanceResource private Ignite ignite; /** {@inheritDoc} */ @Override public Integer load(Object key) { return null; } /** {@inheritDoc} */ @Override public void write(Cache.Entry<?, ?> entry) { // No-op. } /** {@inheritDoc} */ @Override public void delete(Object key) throws CacheWriterException { // No-op. } /** {@inheritDoc} */ @Override public void loadCache(IgniteBiInClosure<Object, Object> clo, Object... args) { if (ignite.cluster().localNode().isClient()) loadedFromClient = true; for (int i = 0; i < 10; i++) clo.apply(i, i); } } }