blob: 789cab1bc89dad1a4423f76e355324f8cc076ea6 [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.geode.distributed.internal;
import static org.apache.geode.distributed.ConfigurationProperties.STATISTIC_SAMPLING_ENABLED;
import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
import static org.apache.geode.test.dunit.LogWriterUtils.getLogWriter;
import static org.assertj.core.api.Assertions.assertThat;
import java.net.InetAddress;
import java.util.Set;
import org.apache.logging.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.apache.geode.cache.AttributesFactory;
import org.apache.geode.cache.CacheException;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionAttributes;
import org.apache.geode.cache.Scope;
import org.apache.geode.distributed.DistributedLockService;
import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
import org.apache.geode.internal.Config;
import org.apache.geode.internal.admin.Alert;
import org.apache.geode.internal.admin.AlertListener;
import org.apache.geode.internal.admin.ApplicationVM;
import org.apache.geode.internal.admin.DLockInfo;
import org.apache.geode.internal.admin.EntryValueNode;
import org.apache.geode.internal.admin.GemFireVM;
import org.apache.geode.internal.admin.GfManagerAgent;
import org.apache.geode.internal.admin.GfManagerAgentConfig;
import org.apache.geode.internal.admin.GfManagerAgentFactory;
import org.apache.geode.internal.admin.StatResource;
import org.apache.geode.internal.admin.remote.RemoteTransportConfig;
import org.apache.geode.internal.logging.LogService;
import org.apache.geode.test.dunit.Host;
import org.apache.geode.test.dunit.IgnoredException;
import org.apache.geode.test.dunit.VM;
import org.apache.geode.test.dunit.cache.CacheTestCase;
/**
* This class tests the functionality of the {@linkplain org.apache.geode.internal.admin internal
* admin} API.
*/
public class ClusterDistributionManagerForAdminDUnitTest extends CacheTestCase
implements AlertListener {
private static Logger logger = LogService.getLogger();
private transient GfManagerAgent agent;
@Before
public void setUp() throws Exception {
IgnoredException.addIgnoredException("Error occurred while reading system log");
ClusterDistributionManager.setIsDedicatedAdminVM(true);
populateCache();
boolean created = !isConnectedToDS();
InternalDistributedSystem ds = getSystem();
RemoteTransportConfig transport =
new RemoteTransportConfig(ds.getConfig(), ClusterDistributionManager.ADMIN_ONLY_DM_TYPE);
if (created) {
disconnectFromDS();
}
// create a GfManagerAgent in the master vm.
this.agent = GfManagerAgentFactory.getManagerAgent(
new GfManagerAgentConfig(null, transport, getLogWriter(), Alert.SEVERE, this, null));
await().untilAsserted(() -> assertThat(agent.isConnected()).isTrue());
}
@Override
@After
public void preTearDownCacheTestCase() throws Exception {
try {
if (this.agent != null) {
this.agent.disconnect();
}
disconnectFromDS();
} finally {
ClusterDistributionManager.setIsDedicatedAdminVM(false);
}
}
@Test
public void testGetDistributionVMType() {
DistributionManager dm = this.agent.getDM();
assertThat(dm.getId().getVmKind()).isEqualTo(ClusterDistributionManager.ADMIN_ONLY_DM_TYPE);
}
@Test
public void testAgent() {
assertThat(agent.listPeers()).hasSize(0);
assertThat(agent.isConnected()).isTrue();
agent.disconnect();
assertThat(agent.isConnected()).isFalse();
}
@Test
public void testApplications() throws Exception {
await()
.untilAsserted(() -> assertThat(agent.listApplications().length).isGreaterThanOrEqualTo(4));
ApplicationVM[] applications = agent.listApplications();
for (int whichApplication = 0; whichApplication < applications.length; whichApplication++) {
InetAddress host = applications[whichApplication].getHost();
String appHostName = host.getHostName();
assertThat(host).isEqualTo(InetAddress.getByName(appHostName));
StatResource[] stats = applications[whichApplication].getStats(null);
assertThat(stats.length).isGreaterThan(0);
Config config = applications[whichApplication].getConfig();
String[] attributeNames = config.getAttributeNames();
boolean foundStatisticSamplingEnabled = false;
for (String attributeName : attributeNames) {
if (attributeName.equals(STATISTIC_SAMPLING_ENABLED)) {
foundStatisticSamplingEnabled = true;
assertThat(config.getAttribute(attributeName)).isEqualTo("true");
break;
}
}
assertThat(foundStatisticSamplingEnabled).isTrue();
String[] logs = applications[whichApplication].getSystemLogs();
assertThat(logs.length).isGreaterThan(0);
VM vm = findVMForAdminObject(applications[whichApplication]);
assertThat(vm).isNotNull();
String lockName = "cdm_testlock" + whichApplication;
assertThat(acquireDistributedLock(vm, lockName)).isTrue();
DLockInfo[] locks = applications[whichApplication].getDistributedLockInfo();
assertThat(locks.length).isGreaterThan(0);
boolean foundLock = false;
for (DLockInfo lock : locks) {
if (lock.getLockName().equals(lockName)) {
foundLock = true;
assertThat(lock.isAcquired()).isTrue();
}
}
assertThat(foundLock).isTrue();
Region[] roots = applications[whichApplication].getRootRegions();
assertThat(roots.length).isGreaterThan(0);
Region root = roots[0];
assertThat(root).isNotNull();
assertThat(root.getName()).isEqualTo("root");
assertThat(root.getFullPath()).isEqualTo("/root");
RegionAttributes attributes = root.getAttributes();
assertThat(attributes).isNotNull();
if (attributes.getStatisticsEnabled()) {
assertThat(root.getStatistics()).isNotNull();
}
Set subregions = root.subregions(false);
assertThat(subregions).hasSize(3);
assertThat(root.keySet()).hasSize(2);
Region.Entry entry = root.getEntry("cacheObj1");
assertThat(entry).isNotNull();
if (attributes.getStatisticsEnabled()) {
assertThat(entry.getStatistics()).isNotNull();
}
assertThat(entry.getValue()).isEqualTo("null");
/// test lightweight inspection;
entry = root.getEntry("cacheObj2");
assertThat(entry).isNotNull();
Object val = entry.getValue();
assertThat(val).isInstanceOf(String.class);
assertThat(((String) val)).contains("java.lang.StringBuffer");
/// test physical inspection
applications[whichApplication].setCacheInspectionMode(GemFireVM.PHYSICAL_CACHE_VALUE);
entry = root.getEntry("cacheObj2");
assertThat(entry).isNotNull();
val = entry.getValue();
assertThat(val).isInstanceOf(EntryValueNode.class);
EntryValueNode node = (EntryValueNode) val;
String type = node.getType();
assertThat(type).contains("java.lang.StringBuffer");
assertThat(node.isPrimitiveOrString()).isFalse();
EntryValueNode[] fields = node.getChildren();
assertThat(fields).isNotNull();
getLogWriter().warning(
"The tests use StringBuffers for values which might be implemented differently in jdk 1.5");
/// test destruction in the last valid app
int lastApplication = applications.length - 1;
if (whichApplication == lastApplication) {
int expectedSize = subregions.size() - 1;
Region subRegion = (Region) subregions.iterator().next();
Region rootRegion = root;
subRegion.destroyRegion();
await()
.untilAsserted(
() -> assertThat(rootRegion.subregions(false).size()).isEqualTo(expectedSize));
}
}
}
@Override
public void alert(Alert alert) {
getLogWriter().info("DEBUG: alert=" + alert);
}
private void populateCache() {
AttributesFactory attributesFactory = new AttributesFactory();
attributesFactory.setScope(Scope.DISTRIBUTED_NO_ACK);
RegionAttributes regionAttributes = attributesFactory.create();
for (int i = 0; i < Host.getHostCount(); i++) {
Host host = Host.getHost(i);
for (int j = 0; j < host.getVMCount(); j++) {
VM vm = host.getVM(j);
vm.invoke(() -> {
createRegion("cdm-testSubRegion1", regionAttributes);
createRegion("cdm-testSubRegion2", regionAttributes);
createRegion("cdm-testSubRegion3", regionAttributes);
remoteCreateEntry("", "cacheObj1", null);
StringBuffer val = new StringBuffer("userDefValue1");
remoteCreateEntry("", "cacheObj2", val);
});
}
}
}
/**
* Puts (or creates) a value in a region named <code>regionName</code> named
* <code>entryName</code>.
*/
private void remoteCreateEntry(String regionName, String entryName, Object value)
throws CacheException {
Region root = getRootRegion();
Region region = root.getSubregion(regionName);
region.create(entryName, value);
logger.info("Put value " + value + " in entry " + entryName + " in region '"
+ region.getFullPath() + "'");
}
private boolean acquireDistributedLock(VM vm, String lockName) {
return vm.invoke(() -> remoteAcquireDistLock(lockName));
}
private boolean remoteAcquireDistLock(String lockName) {
String serviceName = "cdmtest_service";
DistributedLockService service = DistributedLockService.getServiceNamed(serviceName);
if (service == null) {
service =
DistributedLockService.create(serviceName, InternalDistributedSystem.getAnyInstance());
}
assertThat(service).isNotNull();
return service.lock(lockName, 1000, 3000);
}
private VM findVMForAdminObject(GemFireVM gemFireVM) {
for (int i = 0; i < Host.getHostCount(); i++) {
Host host = Host.getHost(i);
for (int j = 0; j < host.getVMCount(); j++) {
VM vm = host.getVM(j);
InternalDistributedMember member = getJavaGroupsIdForVM(vm);
if (gemFireVM.getId().equals(member)) {
return vm;
}
}
}
return null;
}
private InternalDistributedMember getJavaGroupsIdForVM(VM vm) {
return vm.invoke(() -> remoteGetJavaGroupsIdForVM());
}
private InternalDistributedMember remoteGetJavaGroupsIdForVM() {
InternalDistributedSystem system = InternalDistributedSystem.getAnyInstance();
return system.getDistributionManager().getDistributionManagerId();
}
}