From bcffed6bdf0fceb352fac2bfe9393e6370542112 Mon Sep 17 00:00:00 2001 From: Pedro Gordo Date: Sat, 4 Apr 2026 15:16:40 +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 | 19 +++++++++++++ .../cassandra/fql/FullQueryLoggerTest.java | 20 +++++++++++++ .../service/StorageServiceServerTest.java | 28 +++++++++++++++++++ 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 593235d5771e..2cb84ae1167f 100644 --- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java +++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java @@ -2546,6 +2546,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 d3dab125e4d9..de702488b2bd 100644 --- a/src/java/org/apache/cassandra/service/StorageService.java +++ b/src/java/org/apache/cassandra/service/StorageService.java @@ -5597,10 +5597,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 { @@ -6077,6 +6081,9 @@ public void clearConnectionHistory() public void disableAuditLog() { AuditLogManager.instance.disableAuditLog(); + AuditLogOptions disabledOptions = new AuditLogOptions(); + disabledOptions.enabled = false; + DatabaseDescriptor.setAuditLoggingOptions(disabledOptions); logger.info("Auditlog is disabled"); } @@ -6105,6 +6112,7 @@ public void enableAuditLog(String loggerName, Map parameters, St auditLogOptions.excluded_users = excludedUsers != null ? excludedUsers : DatabaseDescriptor.getAuditLoggingOptions().excluded_users; AuditLogManager.instance.enable(auditLogOptions); + DatabaseDescriptor.setAuditLoggingOptions(auditLogOptions); logger.info("AuditLog is enabled with logger: [{}], included_keyspaces: [{}], excluded_keyspaces: [{}], " + "included_categories: [{}], excluded_categories: [{}], included_users: [{}], " @@ -6209,6 +6217,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(Paths.get(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 712f0496e0dc..14b44a4163a4 100644 --- a/test/unit/org/apache/cassandra/fql/FullQueryLoggerTest.java +++ b/test/unit/org/apache/cassandra/fql/FullQueryLoggerTest.java @@ -18,7 +18,9 @@ package org.apache.cassandra.fql; import java.io.File; +import java.io.IOException; import java.nio.ByteBuffer; +import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; @@ -673,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() { diff --git a/test/unit/org/apache/cassandra/service/StorageServiceServerTest.java b/test/unit/org/apache/cassandra/service/StorageServiceServerTest.java index 60bed4c64d1f..205275423021 100644 --- a/test/unit/org/apache/cassandra/service/StorageServiceServerTest.java +++ b/test/unit/org/apache/cassandra/service/StorageServiceServerTest.java @@ -36,6 +36,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.WindowsFailedSnapshotTracker; @@ -728,4 +729,31 @@ public void isReplacingSameHostAddressAndHostIdTest() throws UnknownHostExceptio System.clearProperty("cassandra.replace_address"); } } + + @Test + public void testAuditLogJmxUpdatesConfig() throws Exception + { + AuditLogOptions baseOptions = new AuditLogOptions(); + baseOptions.enabled = false; + 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