mirror of https://github.com/apache/cassandra
Fix JMX initialization problem in injvm-dtest framework
Patch by Francisco Guerrerro, Doug Rohrer; reviewed by TBD for CASSANDRA-20539 Co-authored-by: Doug Rohrer <jeetkundoug@apache.org>
This commit is contained in:
parent
8404d2fd5c
commit
d3658f0491
|
|
@ -645,9 +645,14 @@ public class Instance extends IsolatedExecutor implements IInvokableInstance
|
|||
initialized = true;
|
||||
}
|
||||
|
||||
private synchronized void startJmx()
|
||||
private synchronized void setupMbeanWrapper()
|
||||
{
|
||||
this.isolatedJmx = new IsolatedJmx(this, inInstancelogger);
|
||||
this.isolatedJmx.setupMBeanWrapper();
|
||||
}
|
||||
|
||||
private synchronized void startJmx()
|
||||
{
|
||||
isolatedJmx.startJmx();
|
||||
}
|
||||
|
||||
|
|
@ -707,6 +712,8 @@ public class Instance extends IsolatedExecutor implements IInvokableInstance
|
|||
assert config.networkTopology().contains(config.broadcastAddress()) : String.format("Network topology %s doesn't contain the address %s",
|
||||
config.networkTopology(), config.broadcastAddress());
|
||||
DistributedTestInitialLocationProvider.assign(config.networkTopology());
|
||||
if (config.has(JMX))
|
||||
setupMbeanWrapper();
|
||||
DatabaseDescriptor.daemonInitialization();
|
||||
if (config.has(JMX))
|
||||
startJmx();
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import java.util.HashMap;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.management.remote.JMXConnector;
|
||||
import javax.management.remote.JMXConnectorServer;
|
||||
|
|
@ -76,6 +77,8 @@ public class IsolatedJmx
|
|||
{
|
||||
try
|
||||
{
|
||||
Objects.requireNonNull(wrapper, "Must call setupMBeanWrapper before use");
|
||||
|
||||
// Several RMI threads hold references to in-jvm dtest objects, and are, by default, kept
|
||||
// alive for long enough (minutes) to keep classloaders from being collected.
|
||||
// Set these two system properties to a low value to allow cleanup to occur fast enough
|
||||
|
|
@ -88,8 +91,6 @@ public class IsolatedJmx
|
|||
int jmxPort = config.jmxPort();
|
||||
|
||||
String hostname = addr.getHostAddress();
|
||||
wrapper = new MBeanWrapper.InstanceMBeanWrapper(hostname + ":" + jmxPort);
|
||||
((MBeanWrapper.DelegatingMbeanWrapper) MBeanWrapper.instance).setDelegate(wrapper);
|
||||
|
||||
// CASSANDRA-18508: Sensitive JMX SSL configuration options can be easily exposed
|
||||
Map<String, Object> jmxServerOptionsMap = (Map<String, Object>) config.getParams().get("jmx_server_options");
|
||||
|
|
@ -158,6 +159,15 @@ public class IsolatedJmx
|
|||
}
|
||||
}
|
||||
|
||||
public void setupMBeanWrapper()
|
||||
{
|
||||
InetAddress addr = config.broadcastAddress().getAddress();
|
||||
int jmxPort = config.jmxPort();
|
||||
String hostname = addr.getHostAddress();
|
||||
wrapper = new MBeanWrapper.InstanceMBeanWrapper(hostname + ':' + jmxPort);
|
||||
((MBeanWrapper.DelegatingMbeanWrapper) MBeanWrapper.instance).setDelegate(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds {@code EncryptionOptions} from the map based SSL configuration properties.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package org.apache.cassandra.distributed.test.jmx;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
|
@ -66,6 +67,15 @@ public class JMXTestsUtil
|
|||
"org.apache.cassandra.db:type=CIDRGroupsMappingManager:loadCidrGroupsCache", // AllowAllCIDRAuthorizer doesn't support this operation, as feature is disabled by default
|
||||
"org.apache.cassandra.db:type=StorageService:forceRemoveCompletion" // deprecated (TCM)
|
||||
);
|
||||
// This set of mbeans are registered early enough during the startup of a
|
||||
// Cassandra instance for in-jvm dtests to avoid missing registration of mbeans.
|
||||
// We ignore both "org.apache.cassandra.diag:type=DiagnosticEventService" and
|
||||
// "org.apache.cassandra.diag:type=LastEventIdBroadcaster" because they are being intialized
|
||||
// outside the scope of the in-jvm Instance initialization.
|
||||
private static final Set<String> EXPECTED_MBEANS_TO_BE_REGISTERED = Set.of(
|
||||
"org.apache.cassandra.db:type=EndpointSnitchInfo",
|
||||
"org.apache.cassandra.db:type=LocationInfo"
|
||||
);
|
||||
|
||||
/**
|
||||
* Tests JMX getters and operations and allows passing JMX Env used for the client JMX connection.
|
||||
|
|
@ -75,6 +85,7 @@ public class JMXTestsUtil
|
|||
*/
|
||||
public static void testAllValidGetters(Cluster cluster, Map<String, ?> jmxEnv) throws Exception
|
||||
{
|
||||
Set<String> missingExpectedMbeans = new HashSet<>(EXPECTED_MBEANS_TO_BE_REGISTERED);
|
||||
for (IInvokableInstance instance : cluster)
|
||||
{
|
||||
if (instance.isShutdown())
|
||||
|
|
@ -91,6 +102,7 @@ public class JMXTestsUtil
|
|||
{
|
||||
if (!name.getDomain().startsWith("org.apache.cassandra"))
|
||||
continue;
|
||||
missingExpectedMbeans.remove(name.getCanonicalName());
|
||||
MBeanInfo info = mbsc.getMBeanInfo(name);
|
||||
for (MBeanAttributeInfo a : info.getAttributes())
|
||||
{
|
||||
|
|
@ -123,7 +135,7 @@ public class JMXTestsUtil
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!errors.isEmpty())
|
||||
if (!errors.isEmpty() || !missingExpectedMbeans.isEmpty())
|
||||
{
|
||||
AssertionError root = new AssertionError();
|
||||
for (Named error : errors)
|
||||
|
|
@ -132,6 +144,13 @@ public class JMXTestsUtil
|
|||
logger.error("Error {}", error.getMessage());
|
||||
root.addSuppressed(error);
|
||||
}
|
||||
for (String missingMbean : missingExpectedMbeans)
|
||||
{
|
||||
// The Named object's message has the cause also so this only logs the message
|
||||
String errorMessage = String.format("Expected mbean %s was not found", missingMbean);
|
||||
logger.error(errorMessage);
|
||||
root.addSuppressed(new RuntimeException(errorMessage));
|
||||
}
|
||||
throw root;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue