pauloricardomg commented on code in PR #369:
URL: https://github.com/apache/cassandra-sidecar/pull/369#discussion_r3561398733


##########
server/src/main/java/org/apache/cassandra/sidecar/configmanagement/ConfigurationManager.java:
##########
@@ -84,4 +86,94 @@ private ConfigurationOverlaySnapshot getBaseSnapshot()
         cachedBaseSnapshot = snapshot;
         return snapshot;
     }
+
+    /**
+     * Patches the effective configuration for the given instance using RFC 
6902-inspired JSON Patch
+     * operations. Validates the caller's expected hash against the current 
effective configuration,
+     * validates and applies the patch operations to the overlay, persists via 
the
+     * {@link ConfigurationProvider}, and returns the new effective 
configuration.
+     *
+     * <p>Paths reference the effective configuration structure, but mutations 
target the overlay.
+     * For nested paths within a top-level {@code cassandraYaml} key,
+     * the entire top-level key value is copied from the effective config into 
the overlay before
+     * applying the leaf change (copy-siblings strategy). This ensures the 
overlay is always
+     * self-contained at the top-level key granularity.
+     *
+     * <p>All operations are validated atomically: either all succeed or none 
are applied.
+     *
+     * @param instance     the Cassandra instance metadata
+     * @param expectedHash the hash of the effective configuration as last 
seen by the caller
+     * @param operations   the patch operations to apply
+     * @return a snapshot of the new effective configuration with its SHA-256 
hash and last modified timestamp
+     * @throws ConfigurationConflictException if the expectedHash does not 
match the current effective hash
+     * @throws ConfigurationPatchException    if any patch operation fails 
validation or application
+     * @throws ConfigurationManagerException  if the provider fails during the 
operation
+     */
+    @NotNull
+    public ConfigurationOverlaySnapshot patchConfiguration(@NotNull 
InstanceMetadata instance,
+                                                           @NotNull String 
expectedHash,
+                                                           @NotNull 
List<ConfigurationPatchOperation> operations)
+    {
+        Objects.requireNonNull(instance, "instance must not be null");
+        Objects.requireNonNull(expectedHash, "expectedHash must not be null");
+        Objects.requireNonNull(operations, "operations must not be null");
+
+        try
+        {
+            // 1. Validate operations structure (path format, value presence, 
duplicates)
+            List<ConfigurationPatchValidator.ParsedPatchOperation> parsedOps =
+                    ConfigurationPatchValidator.validate(operations);
+
+            // 2. Read current state and validate the caller's hash matches
+            ConfigurationOverlaySnapshot baseSnapshot = getBaseSnapshot();
+            ConfigurationOverlaySnapshot currentOverlay = 
provider.getOverlay(instance);
+
+            ConfigurationOverlaySnapshot effectiveConfig = currentOverlay != 
null
+                                                           ? 
baseSnapshot.overlay(currentOverlay, instance.id())
+                                                           : baseSnapshot;
+
+            if (!expectedHash.equals(effectiveConfig.hash()))
+            {
+                throw new ConfigurationConflictException(expectedHash, 
effectiveConfig.hash());
+            }
+
+            // 3. Apply patch operations to the overlay (precondition checks + 
mutations)
+            CassandraConfigurationOverlay currentOverlayConfig = 
currentOverlay != null
+                                                                 ? 
currentOverlay.configuration()
+                                                                 : new 
CassandraConfigurationOverlay(null, null);
+            CassandraConfigurationOverlay updatedOverlay =
+                    ConfigurationPatchApplier.apply(parsedOps, 
effectiveConfig.configuration(), currentOverlayConfig);

Review Comment:
   Addressed in 17fb8896.
   apply() now checks boolean JVM opt conflicts against the effective config 
(base + overlay), not just the overlay, and rejects the patch before 
storeOverlay is called. Stored and returned configs no longer diverge, and the 
warn-and-drop path in baseSnapshot.overlay() is no longer hit.
   
   Tests: ConfigurationManagerTest.testPatchConflictingBooleanJvmOptRejected 
(rejected, nothing stored) and testPatchReturnedConfigMatchesStoredConfig 
(returned == re-read).
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to