blob: c50f0119dc0138ea06ec6867436ffedb1edf054f [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.lang.management.ManagementFactory;
import java.util.Arrays;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicInteger;
import javax.cache.CacheManager;
import javax.cache.Caching;
import javax.management.MBeanServer;
import javax.management.MBeanServerInvocationHandler;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.CacheMetrics;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.DataRegionConfiguration;
import org.apache.ignite.configuration.DataStorageConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.configuration.WALMode;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.IgniteInterruptedCheckedException;
import org.apache.ignite.internal.util.lang.GridAbsPredicate;
import org.apache.ignite.internal.util.typedef.G;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.mxbean.CacheMetricsMXBean;
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.GridTestUtils;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
/**
*
*/
public class CacheMetricsEnableRuntimeTest extends GridCommonAbstractTest {
/** */
private static final TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true);
/** */
private static final String CACHE1 = "cache1";
/** */
private static final String CACHE2 = "cache2";
/** */
private static final String GROUP = "group1";
/** Wait condition timeout. */
private static final long WAIT_CONDITION_TIMEOUT = 3_000L;
/** Persistence. */
private boolean persistence = false;
/**
* @throws Exception If failed.
*/
public void testJmxNoPdsStatisticsEnable() throws Exception {
testJmxStatisticsEnable(false);
}
/**
* @throws Exception If failed.
*/
public void testJmxPdsStatisticsEnable() throws Exception {
testJmxStatisticsEnable(true);
}
/**
* @throws Exception If failed.
*/
public void testCacheManagerStatisticsEnable() throws Exception {
final CacheManager mgr1 = Caching.getCachingProvider().getCacheManager();
final CacheManager mgr2 = Caching.getCachingProvider().getCacheManager();
CacheConfiguration cfg1 = new CacheConfiguration()
.setName(CACHE1)
.setGroupName(GROUP)
.setCacheMode(CacheMode.PARTITIONED)
.setAtomicityMode(CacheAtomicityMode.ATOMIC);
mgr1.createCache(CACHE1, cfg1);
CacheConfiguration cfg2 = new CacheConfiguration(cfg1)
.setName(CACHE2)
.setStatisticsEnabled(true);
mgr1.createCache(CACHE2, cfg2);
assertTrue(GridTestUtils.waitForCondition(new GridAbsPredicate() {
@Override public boolean apply() {
return !isStatisticsEnabled(mgr1, CACHE1) && !isStatisticsEnabled(mgr2, CACHE1)
&& isStatisticsEnabled(mgr1, CACHE2) && isStatisticsEnabled(mgr2, CACHE2);
}
}, WAIT_CONDITION_TIMEOUT));
mgr1.enableStatistics(CACHE1, true);
mgr2.enableStatistics(CACHE2, false);
assertTrue(GridTestUtils.waitForCondition(new GridAbsPredicate() {
@Override public boolean apply() {
return isStatisticsEnabled(mgr1, CACHE1) && isStatisticsEnabled(mgr2, CACHE1)
&& !isStatisticsEnabled(mgr1, CACHE2) && !isStatisticsEnabled(mgr2, CACHE2);
}
}, WAIT_CONDITION_TIMEOUT));
}
/**
*
*/
public void testPublicApiStatisticsEnable() throws Exception {
Ignite ig1 = startGrid(1);
startGrid(2);
IgniteCache<?, ?> cache1 = ig1.cache(CACHE1);
CacheConfiguration cacheCfg2 = new CacheConfiguration(cache1.getConfiguration(CacheConfiguration.class));
cacheCfg2.setName(CACHE2);
cacheCfg2.setStatisticsEnabled(true);
ig1.getOrCreateCache(cacheCfg2);
assertCachesStatisticsMode(false, true);
cache1.enableStatistics(true);
assertCachesStatisticsMode(true, true);
ig1.cluster().enableStatistics(Arrays.asList(CACHE1, CACHE2), false);
assertCachesStatisticsMode(false, false);
}
/**
*
*/
public void testMultiThreadStatisticsEnable() throws Exception {
startGrids(5);
IgniteCache<?, ?> cache1 = grid(0).cache(CACHE1);
CacheConfiguration cacheCfg2 = new CacheConfiguration(cache1.getConfiguration(CacheConfiguration.class));
cacheCfg2.setName(CACHE2);
grid(0).getOrCreateCache(cacheCfg2);
final CyclicBarrier barrier = new CyclicBarrier(10);
final AtomicInteger gridIdx = new AtomicInteger(-1);
IgniteInternalFuture<?> fut = multithreadedAsync(new Runnable() {
@Override public void run() {
try {
Ignite ignite = grid(gridIdx.incrementAndGet() % 5);
barrier.await();
ignite.cluster().enableStatistics(Arrays.asList(CACHE1, CACHE2), true);
assertCachesStatisticsMode(true, true);
barrier.await();
ignite.cluster().enableStatistics(Arrays.asList(CACHE1, CACHE2), false);
assertCachesStatisticsMode(false, false);
barrier.await();
ignite.cluster().enableStatistics(Arrays.asList(CACHE1), true);
assertCachesStatisticsMode(true, false);
}
catch (InterruptedException | BrokenBarrierException | IgniteCheckedException e) {
fail("Unexpected exception: " + e);
}
}
}, 10);
fut.get();
startGrid(5);
assertCachesStatisticsMode(true, false);
}
/** {@inheritDoc} */
@Override protected void afterTest() throws Exception {
super.afterTest();
stopAllGrids();
persistence = false;
}
/**
* @param persistence Persistence.
*/
private void testJmxStatisticsEnable(boolean persistence) throws Exception {
this.persistence = persistence;
Ignite ig1 = startGrid(1);
Ignite ig2 = startGrid(2);
ig1.active(true);
CacheConfiguration ccfg = ig1.cache(CACHE1).getConfiguration(CacheConfiguration.class);
CacheConfiguration cacheCfg2 = new CacheConfiguration(ccfg);
cacheCfg2.setName(CACHE2);
cacheCfg2.setStatisticsEnabled(true);
ig2.getOrCreateCache(cacheCfg2);
CacheMetricsMXBean mxBeanCache1 = mxBean(2, CACHE1, CacheClusterMetricsMXBeanImpl.class);
CacheMetricsMXBean mxBeanCache2 = mxBean(2, CACHE2, CacheClusterMetricsMXBeanImpl.class);
CacheMetricsMXBean mxBeanCache1loc = mxBean(2, CACHE1, CacheLocalMetricsMXBeanImpl.class);
mxBeanCache1.enableStatistics();
mxBeanCache2.disableStatistics();
assertCachesStatisticsMode(true, false);
stopGrid(1);
startGrid(3);
assertCachesStatisticsMode(true, false);
mxBeanCache1loc.disableStatistics();
assertCachesStatisticsMode(false, false);
mxBeanCache1.enableStatistics();
mxBeanCache2.enableStatistics();
// Start node 1 again.
startGrid(1);
assertCachesStatisticsMode(true, true);
int gridIdx = 0;
for (Ignite ignite : G.allGrids()) {
gridIdx++;
ignite.cache(CACHE1).put(gridIdx, gridIdx);
ignite.cache(CACHE2).put(gridIdx, gridIdx);
ignite.cache(CACHE1).get(gridIdx);
ignite.cache(CACHE2).get(gridIdx);
}
assertTrue(GridTestUtils.waitForCondition(new GridAbsPredicate() {
@Override public boolean apply() {
int cnt = G.allGrids().size();
for (Ignite ignite : G.allGrids()) {
CacheMetrics metrics1 = ignite.cache(CACHE1).metrics();
CacheMetrics metrics2 = ignite.cache(CACHE2).metrics();
if (metrics1.getCacheGets() < cnt || metrics2.getCacheGets() < cnt
|| metrics1.getCachePuts() < cnt || metrics2.getCachePuts() < cnt)
return false;
}
return true;
}
}, 10_000L));
stopAllGrids();
ig1 = startGrid(1);
ig1.active(true);
ig1.getOrCreateCache(cacheCfg2.setStatisticsEnabled(false));
if (persistence)
// cache1 - from local configuration, cache2 - restored from pds
assertCachesStatisticsMode(false, true);
else
assertCachesStatisticsMode(false, false);
mxBeanCache1 = mxBean(1, CACHE1, CacheLocalMetricsMXBeanImpl.class);
mxBeanCache2 = mxBean(1, CACHE2, CacheLocalMetricsMXBeanImpl.class);
mxBeanCache1.enableStatistics();
mxBeanCache2.disableStatistics();
startGrid(2);
assertCachesStatisticsMode(true, false);
}
/**
* Gets CacheGroupMetricsMXBean for given node and group name.
*
* @param nodeIdx Node index.
* @param cacheName Cache name.
* @return MBean instance.
*/
private CacheMetricsMXBean mxBean(int nodeIdx, String cacheName, Class<? extends CacheMetricsMXBean> clazz)
throws MalformedObjectNameException {
ObjectName mbeanName = U.makeMBeanName(getTestIgniteInstanceName(nodeIdx), cacheName,
clazz.getName());
MBeanServer mbeanSrv = ManagementFactory.getPlatformMBeanServer();
if (!mbeanSrv.isRegistered(mbeanName))
fail("MBean is not registered: " + mbeanName.getCanonicalName());
return MBeanServerInvocationHandler.newProxyInstance(mbeanSrv, mbeanName, CacheMetricsMXBean.class,
true);
}
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
((TcpDiscoverySpi)cfg.getDiscoverySpi()).setIpFinder(ipFinder);
CacheConfiguration cacheCfg = new CacheConfiguration()
.setName(CACHE1)
.setGroupName(GROUP)
.setCacheMode(CacheMode.PARTITIONED)
.setAtomicityMode(CacheAtomicityMode.ATOMIC);
cfg.setCacheConfiguration(cacheCfg);
if (persistence)
cfg.setDataStorageConfiguration(new DataStorageConfiguration()
.setDefaultDataRegionConfiguration(new DataRegionConfiguration().setPersistenceEnabled(true))
.setWalMode(WALMode.LOG_ONLY)
);
return cfg;
}
/**
* Check cache statistics enabled/disabled flag for all nodes
*
* @param cacheName Cache name.
* @param enabled Enabled.
*/
private boolean checkStatisticsMode(String cacheName, boolean enabled) {
for (Ignite ignite : G.allGrids())
if (ignite.cache(cacheName).metrics().isStatisticsEnabled() != enabled) {
log.warning("Wrong cache statistics mode [grid=" + ignite.name() + ", cache=" + cacheName
+ ", expected=" + enabled);
return false;
}
return true;
}
/**
* @param enabled1 Statistics enabled for cache 1.
* @param enabled2 Statistics enabled for cache 2.
*/
private void assertCachesStatisticsMode(final boolean enabled1, final boolean enabled2) throws IgniteInterruptedCheckedException {
assertTrue(GridTestUtils.waitForCondition(new GridAbsPredicate() {
@Override public boolean apply() {
return checkStatisticsMode(CACHE1, enabled1) && checkStatisticsMode(CACHE2, enabled2);
}
}, WAIT_CONDITION_TIMEOUT));
}
/**
* @param cacheMgr Cache manager.
* @param cacheName Cache name.
*/
private boolean isStatisticsEnabled(CacheManager cacheMgr, String cacheName) {
return ((IgniteCache)cacheMgr.getCache(cacheName)).metrics().isStatisticsEnabled();
}
}