From 008abd86b0204600bc985bf42f46644b3186a7fd Mon Sep 17 00:00:00 2001 From: Pedro Gordo Date: Sat, 4 Apr 2026 15:20:53 +0100 Subject: [PATCH] Update Config when properties are changed via JMX When endpoint_snitch, dynamic_snitch, audit_logging_options, or full_query_logging_options are modified via JMX, update the corresponding Config fields so the Settings Virtual Table reflects the current runtime values. Patch by Pedro Gordo; reviewed by for CASSANDRA-17736 --- .../cassandra/config/DatabaseDescriptor.java | 15 ++++++++++ .../cassandra/service/StorageService.java | 20 +++++++++++++ .../cassandra/fql/FullQueryLoggerTest.java | 18 ++++++++++++ .../service/StorageServiceServerTest.java | 29 +++++++++++++++++++ 4 files changed, 82 insertions(+) diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java index f102c3f7293f..0c8879bc22cf 100644 --- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java +++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java @@ -3201,6 +3201,21 @@ public static void setDynamicBadnessThreshold(double dynamicBadnessThreshold) conf.dynamic_snitch_badness_threshold = dynamicBadnessThreshold; } + public static boolean isDynamicSnitch() + { + return conf.dynamic_snitch; + } + + public static void setDynamicSnitch(boolean enabled) + { + conf.dynamic_snitch = enabled; + } + + public static void setEndpointSnitchClassName(String endpointSnitch) + { + conf.endpoint_snitch = endpointSnitch; + } + public static EncryptionOptions.ServerEncryptionOptions getInternodeMessagingEncyptionOptions() { return conf.server_encryption_options; diff --git a/src/java/org/apache/cassandra/service/StorageService.java b/src/java/org/apache/cassandra/service/StorageService.java index 8d494fc4d6dd..64748d8c998b 100644 --- a/src/java/org/apache/cassandra/service/StorageService.java +++ b/src/java/org/apache/cassandra/service/StorageService.java @@ -5963,10 +5963,14 @@ public void updateSnitch(String epSnitchClassName, Boolean dynamic, Integer dyna // point snitch references to the new instance DatabaseDescriptor.setEndpointSnitch(newSnitch); + DatabaseDescriptor.setEndpointSnitchClassName(epSnitchClassName); for (String ks : Schema.instance.getKeyspaces()) { Keyspace.open(ks).getReplicationStrategy().snitch = newSnitch; } + + if (dynamic != null) + DatabaseDescriptor.setDynamicSnitch(dynamic); } else { @@ -6458,6 +6462,10 @@ public void clearConnectionHistory() public void disableAuditLog() { AuditLogManager.instance.disableAuditLog(); + AuditLogOptions disabledOptions = new AuditLogOptions.Builder(DatabaseDescriptor.getAuditLoggingOptions()) + .withEnabled(false) + .build(); + DatabaseDescriptor.setAuditLoggingOptions(disabledOptions); logger.info("Auditlog is disabled"); } @@ -6511,6 +6519,7 @@ public void enableAuditLog(String loggerName, Map parameters, St .build(); AuditLogManager.instance.enable(options); + DatabaseDescriptor.setAuditLoggingOptions(options); logger.info("AuditLog is enabled with configuration: {}", options); } @@ -6633,6 +6642,17 @@ public void enableFullQueryLogger(String path, String rollCycle, Boolean blockin Preconditions.checkNotNull(path, "cassandra.yaml did not set log_dir and not set as parameter"); FullQueryLogger.instance.enableWithoutClean(File.getPath(path), rollCycle, blocking, maxQueueWeight, maxLogSize, archiveCommand, maxArchiveRetries); + + FullQueryLoggerOptions updatedOptions = new FullQueryLoggerOptions(); + updatedOptions.log_dir = path; + updatedOptions.roll_cycle = rollCycle; + updatedOptions.block = blocking; + updatedOptions.max_queue_weight = maxQueueWeight; + updatedOptions.max_log_size = maxLogSize; + updatedOptions.archive_command = archiveCommand; + updatedOptions.max_archive_retries = maxArchiveRetries; + updatedOptions.allow_nodetool_archive_command = fqlOptions.allow_nodetool_archive_command; + DatabaseDescriptor.setFullQueryLogOptions(updatedOptions); } @Override diff --git a/test/unit/org/apache/cassandra/fql/FullQueryLoggerTest.java b/test/unit/org/apache/cassandra/fql/FullQueryLoggerTest.java index 51f7fb89dd4a..26cfb3b43677 100644 --- a/test/unit/org/apache/cassandra/fql/FullQueryLoggerTest.java +++ b/test/unit/org/apache/cassandra/fql/FullQueryLoggerTest.java @@ -675,6 +675,24 @@ public void testLogQueryNegativeTime() throws Exception logQuery("", QueryOptions.DEFAULT, queryState(), -1); } + @Test + public void testEnableFullQueryLoggerUpdatesConfig() throws IOException + { + FullQueryLoggerOptions options = new FullQueryLoggerOptions(); + Path tmpDir = Files.createTempDirectory("FullQueryLoggerTest"); + options.log_dir = tmpDir.toString(); + DatabaseDescriptor.setFullQueryLogOptions(options); + + StorageService.instance.enableFullQueryLogger(options.log_dir, "TEST_SECONDLY", true, 5000, 50000, null, 0); + + FullQueryLoggerOptions updated = DatabaseDescriptor.getFullQueryLogOptions(); + assertEquals("TEST_SECONDLY", updated.roll_cycle); + assertTrue(updated.block); + assertEquals(5000, updated.max_queue_weight); + + FullQueryLogger.instance.stop(); + } + @Test public void testJMXArchiveCommand() throws IOException { diff --git a/test/unit/org/apache/cassandra/service/StorageServiceServerTest.java b/test/unit/org/apache/cassandra/service/StorageServiceServerTest.java index 119b8104d4a9..1e59b451e5c3 100644 --- a/test/unit/org/apache/cassandra/service/StorageServiceServerTest.java +++ b/test/unit/org/apache/cassandra/service/StorageServiceServerTest.java @@ -33,6 +33,7 @@ import org.junit.Test; import org.apache.cassandra.audit.AuditLogManager; +import org.apache.cassandra.audit.AuditLogOptions; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.db.Keyspace; import org.apache.cassandra.db.commitlog.CommitLog; @@ -659,4 +660,32 @@ public void isReplacingSameHostAddressAndHostIdTest() throws UnknownHostExceptio System.clearProperty("cassandra.replace_address"); } } + + @Test + public void testAuditLogJmxUpdatesConfig() throws Exception + { + AuditLogOptions baseOptions = new AuditLogOptions.Builder(DatabaseDescriptor.getAuditLoggingOptions()) + .withEnabled(false) + .build(); + DatabaseDescriptor.setAuditLoggingOptions(baseOptions); + + StorageService.instance.enableAuditLog(null, null, null, null, null, null, null); + Assert.assertTrue(DatabaseDescriptor.getAuditLoggingOptions().enabled); + + StorageService.instance.disableAuditLog(); + Assert.assertFalse(DatabaseDescriptor.getAuditLoggingOptions().enabled); + } + + @Test + public void testSnitchSettersUpdateConfig() + { + DatabaseDescriptor.setDynamicSnitch(false); + Assert.assertFalse(DatabaseDescriptor.isDynamicSnitch()); + DatabaseDescriptor.setDynamicSnitch(true); + Assert.assertTrue(DatabaseDescriptor.isDynamicSnitch()); + + DatabaseDescriptor.setEndpointSnitchClassName("org.apache.cassandra.locator.SimpleSnitch"); + Assert.assertEquals("org.apache.cassandra.locator.SimpleSnitch", + DatabaseDescriptor.getRawConfig().endpoint_snitch); + } } \ No newline at end of file