This is an automated email from the ASF dual-hosted git repository. frankgh pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/cassandra.git
The following commit(s) were added to refs/heads/trunk by this push: new d3658f0491 Fix JMX initialization problem in injvm-dtest framework d3658f0491 is described below commit d3658f0491a7c01490be49270d468f5602c3baf7 Author: Francisco Guerrero <fran...@apache.org> AuthorDate: Tue Apr 8 14:19:56 2025 -0700 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 <jeetkund...@apache.org> --- .../apache/cassandra/distributed/impl/Instance.java | 9 ++++++++- .../cassandra/distributed/impl/IsolatedJmx.java | 14 ++++++++++++-- .../distributed/test/jmx/JMXTestsUtil.java | 21 ++++++++++++++++++++- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/test/distributed/org/apache/cassandra/distributed/impl/Instance.java b/test/distributed/org/apache/cassandra/distributed/impl/Instance.java index a7cb238119..06258b6145 100644 --- a/test/distributed/org/apache/cassandra/distributed/impl/Instance.java +++ b/test/distributed/org/apache/cassandra/distributed/impl/Instance.java @@ -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(); diff --git a/test/distributed/org/apache/cassandra/distributed/impl/IsolatedJmx.java b/test/distributed/org/apache/cassandra/distributed/impl/IsolatedJmx.java index 18eaeb85c5..59e9e8ca04 100644 --- a/test/distributed/org/apache/cassandra/distributed/impl/IsolatedJmx.java +++ b/test/distributed/org/apache/cassandra/distributed/impl/IsolatedJmx.java @@ -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. * diff --git a/test/distributed/org/apache/cassandra/distributed/test/jmx/JMXTestsUtil.java b/test/distributed/org/apache/cassandra/distributed/test/jmx/JMXTestsUtil.java index 5726c242d9..ad9fd21a48 100644 --- a/test/distributed/org/apache/cassandra/distributed/test/jmx/JMXTestsUtil.java +++ b/test/distributed/org/apache/cassandra/distributed/test/jmx/JMXTestsUtil.java @@ -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; } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org