blob: 8784dd9e65c1b9572cade35a4b4d8bdfe3d524c1 [file] [log] [blame]
/*
* 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 java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.cache.Cache;
import javax.cache.integration.CacheLoaderException;
import org.apache.ignite.Ignite;
import org.apache.ignite.cache.CacheInterceptor;
import org.apache.ignite.cache.CacheMode;
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.cache.eviction.EvictableEntry;
import org.apache.ignite.cache.eviction.EvictionFilter;
import org.apache.ignite.cache.eviction.EvictionPolicy;
import org.apache.ignite.cache.store.CacheStore;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.configuration.NearCacheConfiguration;
import org.apache.ignite.configuration.TopologyValidator;
import org.apache.ignite.lang.IgniteBiInClosure;
import org.apache.ignite.lang.IgniteBiTuple;
import org.apache.ignite.lifecycle.LifecycleAware;
import org.apache.ignite.resources.CacheNameResource;
import org.apache.ignite.resources.IgniteInstanceResource;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.testframework.junits.common.GridAbstractLifecycleAwareSelfTest;
import org.jetbrains.annotations.Nullable;
import org.junit.Test;
import static org.apache.ignite.cache.CacheMode.PARTITIONED;
/**
* Test for {@link LifecycleAware} support in {@link CacheConfiguration}.
*/
public class GridCacheLifecycleAwareSelfTest extends GridAbstractLifecycleAwareSelfTest {
/** */
private static final String CACHE_NAME = "cache";
/** */
private boolean near;
/** */
private boolean writeBehind;
/**
*/
private static class TestStore implements CacheStore, LifecycleAware {
/** */
private final TestLifecycleAware lifecycleAware = new TestLifecycleAware(CACHE_NAME);
/** {@inheritDoc} */
@Override public void start() {
lifecycleAware.start();
}
/** {@inheritDoc} */
@Override public void stop() {
lifecycleAware.stop();
}
/**
* @param cacheName Cache name.
*/
@CacheNameResource
public void setCacheName(String cacheName) {
lifecycleAware.cacheName(cacheName);
}
/** {@inheritDoc} */
@Nullable @Override public Object load(Object key) {
return null;
}
/** {@inheritDoc} */
@Override public void loadCache(IgniteBiInClosure clo, @Nullable Object... args) {
// No-op.
}
/** {@inheritDoc} */
@Override public Map loadAll(Iterable keys) throws CacheLoaderException {
return Collections.emptyMap();
}
/** {@inheritDoc} */
@Override public void write(Cache.Entry entry) {
// No-op.
}
/** {@inheritDoc} */
@Override public void writeAll(Collection col) {
// No-op.
}
/** {@inheritDoc} */
@Override public void delete(Object key) {
// No-op.
}
/** {@inheritDoc} */
@Override public void deleteAll(Collection keys) {
// No-op.
}
/** {@inheritDoc} */
@Override public void sessionEnd(boolean commit) {
// No-op.
}
}
/**
*/
public static class TestAffinityFunction extends TestLifecycleAware implements AffinityFunction {
/**
*/
public TestAffinityFunction() {
super(CACHE_NAME);
}
/** {@inheritDoc} */
@Override public void reset() {
// No-op.
}
/** {@inheritDoc} */
@Override public int partitions() {
return 1;
}
/** {@inheritDoc} */
@Override public int partition(Object key) {
return 0;
}
/** {@inheritDoc} */
@Override public List<List<ClusterNode>> assignPartitions(AffinityFunctionContext affCtx) {
List<List<ClusterNode>> res = new ArrayList<>();
res.add(nodes(0, affCtx.currentTopologySnapshot()));
return res;
}
/** */
public List<ClusterNode> nodes(int part, Collection<ClusterNode> nodes) {
return new ArrayList<>(nodes);
}
/** {@inheritDoc} */
@Override public void removeNode(UUID nodeId) {
// No-op.
}
}
/**
*/
public static class TestEvictionPolicy extends TestLifecycleAware implements EvictionPolicy, Serializable {
/**
*/
public TestEvictionPolicy() {
super(CACHE_NAME);
}
/** {@inheritDoc} */
@Override public void onEntryAccessed(boolean rmv, EvictableEntry entry) {
// No-op.
}
}
/**
*/
private static class TestEvictionFilter extends TestLifecycleAware implements EvictionFilter {
/**
*/
TestEvictionFilter() {
super(CACHE_NAME);
}
/** {@inheritDoc} */
@Override public boolean evictAllowed(Cache.Entry entry) {
return false;
}
}
/**
*/
private static class TestAffinityKeyMapper extends TestLifecycleAware implements AffinityKeyMapper {
/**
*/
TestAffinityKeyMapper() {
super(CACHE_NAME);
}
/** {@inheritDoc} */
@Override public Object affinityKey(Object key) {
return key;
}
/** {@inheritDoc} */
@Override public void reset() {
// No-op.
}
}
/**
*/
private static class TestInterceptor extends TestLifecycleAware implements CacheInterceptor {
/**
*/
private TestInterceptor() {
super(CACHE_NAME);
}
/** {@inheritDoc} */
@Nullable @Override public Object onGet(Object key, @Nullable Object val) {
return val;
}
/** {@inheritDoc} */
@Nullable @Override public Object onBeforePut(Cache.Entry entry, Object newVal) {
return newVal;
}
/** {@inheritDoc} */
@Override public void onAfterPut(Cache.Entry entry) {
// No-op.
}
/** {@inheritDoc} */
@SuppressWarnings("unchecked") @Nullable @Override public IgniteBiTuple onBeforeRemove(Cache.Entry entry) {
return new IgniteBiTuple(false, entry.getValue());
}
/** {@inheritDoc} */
@Override public void onAfterRemove(Cache.Entry entry) {
// No-op.
}
}
/**
*/
private static class TestTopologyValidator extends TestLifecycleAware implements TopologyValidator {
/** */
@IgniteInstanceResource
private Ignite ignite;
/**
*/
public TestTopologyValidator() {
super(CACHE_NAME);
}
/** {@inheritDoc} */
@Override public boolean validate(Collection<ClusterNode> nodes) {
return false;
}
/** {@inheritDoc} */
@Override public void start() {
super.start();
assertNotNull(ignite);
}
}
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override protected final IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
cfg.setDiscoverySpi(new TcpDiscoverySpi());
CacheConfiguration ccfg = defaultCacheConfiguration();
ccfg.setCacheMode(PARTITIONED);
ccfg.setWriteBehindEnabled(writeBehind);
ccfg.setCacheMode(CacheMode.PARTITIONED);
ccfg.setName(CACHE_NAME);
TestStore store = new TestStore();
ccfg.setCacheStoreFactory(singletonFactory(store));
ccfg.setReadThrough(true);
ccfg.setWriteThrough(true);
ccfg.setLoadPreviousValue(true);
lifecycleAwares.add(store.lifecycleAware);
TestAffinityFunction affinity = new TestAffinityFunction();
ccfg.setAffinity(affinity);
lifecycleAwares.add(affinity);
TestEvictionPolicy evictionPlc = new TestEvictionPolicy();
ccfg.setEvictionPolicy(evictionPlc);
ccfg.setOnheapCacheEnabled(true);
lifecycleAwares.add(evictionPlc);
if (near) {
TestEvictionPolicy nearEvictionPlc = new TestEvictionPolicy();
NearCacheConfiguration nearCfg = new NearCacheConfiguration();
nearCfg.setNearEvictionPolicy(nearEvictionPlc);
ccfg.setNearConfiguration(nearCfg);
lifecycleAwares.add(nearEvictionPlc);
}
TestEvictionFilter evictionFilter = new TestEvictionFilter();
ccfg.setEvictionFilter(evictionFilter);
lifecycleAwares.add(evictionFilter);
TestAffinityKeyMapper mapper = new TestAffinityKeyMapper();
ccfg.setAffinityMapper(mapper);
lifecycleAwares.add(mapper);
TestInterceptor interceptor = new TestInterceptor();
lifecycleAwares.add(interceptor);
ccfg.setInterceptor(interceptor);
TestTopologyValidator topValidator = new TestTopologyValidator();
lifecycleAwares.add(topValidator);
ccfg.setTopologyValidator(topValidator);
cfg.setCacheConfiguration(ccfg);
return cfg;
}
/** {@inheritDoc} */
@SuppressWarnings("ErrorNotRethrown")
@Test
@Override public void testLifecycleAware() throws Exception {
for (boolean nearEnabled : new boolean[] {true, false}) {
near = nearEnabled;
writeBehind = false;
try {
super.testLifecycleAware();
}
catch (AssertionError e) {
throw new AssertionError("Failed for [near=" + near + ", writeBehind=" + writeBehind + ']',
e);
}
writeBehind = true;
try {
super.testLifecycleAware();
}
catch (AssertionError e) {
throw new AssertionError("Failed for [near=" + near + ", writeBehind=" + writeBehind + ']',
e);
}
}
}
}