This is an automated email from the ASF dual-hosted git repository.

keith-turner pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/accumulo.git


The following commit(s) were added to refs/heads/main by this push:
     new cb9bc5db07 Fixes PluginEnvironment.Configuration.isSet (#6597)
cb9bc5db07 is described below

commit cb9bc5db078b52a93421341e13d246b42d63b55c
Author: Keith Turner <[email protected]>
AuthorDate: Thu Oct 22 13:44:54 2026 -0400

    Fixes PluginEnvironment.Configuration.isSet (#6597)
    
    When creating a PluginEnvironment.Configuration object using
    PluginEnvironment.Configuration.from() the isSet method would not work
    properly.  It should work now.
---
 .../accumulo/core/client/PluginEnvironment.java    |  9 ++-
 .../accumulo/core/conf/LayeredConfiguration.java   | 69 +++++++++++++++++
 .../core/conf/LayeredConfigurationTest.java        | 90 ++++++++++++++++++++++
 3 files changed, 165 insertions(+), 3 deletions(-)

diff --git 
a/core/src/main/java/org/apache/accumulo/core/client/PluginEnvironment.java 
b/core/src/main/java/org/apache/accumulo/core/client/PluginEnvironment.java
index 1d590110b5..9b62c5d135 100644
--- a/core/src/main/java/org/apache/accumulo/core/client/PluginEnvironment.java
+++ b/core/src/main/java/org/apache/accumulo/core/client/PluginEnvironment.java
@@ -24,8 +24,10 @@ import java.util.Map.Entry;
 import java.util.function.Function;
 import java.util.function.Supplier;
 
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
 import org.apache.accumulo.core.conf.ConfigurationCopy;
 import org.apache.accumulo.core.conf.DefaultConfiguration;
+import org.apache.accumulo.core.conf.LayeredConfiguration;
 import org.apache.accumulo.core.data.TableId;
 import org.apache.accumulo.core.util.ConfigurationImpl;
 
@@ -143,9 +145,10 @@ public interface PluginEnvironment {
      * @since 4.0.0
      */
     static Configuration from(Map<String,String> properties, boolean 
includeDefaults) {
-      ConfigurationCopy config = includeDefaults
-          ? new ConfigurationCopy(DefaultConfiguration.getInstance()) : new 
ConfigurationCopy();
-      properties.forEach(config::set);
+      AccumuloConfiguration config = new ConfigurationCopy(properties);
+      if (includeDefaults) {
+        config = new LayeredConfiguration(DefaultConfiguration.getInstance(), 
config);
+      }
       return new ConfigurationImpl(config);
     }
   }
diff --git 
a/core/src/main/java/org/apache/accumulo/core/conf/LayeredConfiguration.java 
b/core/src/main/java/org/apache/accumulo/core/conf/LayeredConfiguration.java
new file mode 100644
index 0000000000..7cd215a709
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/conf/LayeredConfiguration.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.accumulo.core.conf;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Predicate;
+
+/**
+ * Layers one accumulo configuration on top of another. When getting 
properties will look in the
+ * outer layer first and if not present will fall back to the inner layer.
+ */
+public class LayeredConfiguration extends AccumuloConfiguration {
+
+  private final AccumuloConfiguration inner;
+  private final AccumuloConfiguration outer;
+
+  public LayeredConfiguration(AccumuloConfiguration inner, 
AccumuloConfiguration outer) {
+    this.inner = Objects.requireNonNull(inner);
+    this.outer = Objects.requireNonNull(outer);
+  }
+
+  @Override
+  public String get(Property property) {
+    String value = outer.get(property);
+    if (value == null) {
+      value = inner.get(property);
+    }
+    return value;
+  }
+
+  @Override
+  public void getProperties(Map<String,String> props, Predicate<String> 
filter) {
+    inner.getProperties(props, filter);
+    outer.getProperties(props, filter);
+  }
+
+  @Override
+  public boolean isPropertySet(Property prop) {
+    return outer.isPropertySet(prop) || inner.isPropertySet(prop);
+  }
+
+  @Override
+  public long getUpdateCount() {
+    return outer.getUpdateCount() + inner.getUpdateCount();
+  }
+
+  @Override
+  public void invalidateCache() {
+    outer.invalidateCache();
+    inner.invalidateCache();
+  }
+}
diff --git 
a/core/src/test/java/org/apache/accumulo/core/conf/LayeredConfigurationTest.java
 
b/core/src/test/java/org/apache/accumulo/core/conf/LayeredConfigurationTest.java
new file mode 100644
index 0000000000..47ccb64d07
--- /dev/null
+++ 
b/core/src/test/java/org/apache/accumulo/core/conf/LayeredConfigurationTest.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.accumulo.core.conf;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+public class LayeredConfigurationTest {
+
+  private AccumuloConfiguration config;
+  private ConfigurationCopy copyConfig1;
+  private ConfigurationCopy copyConfig2;
+
+  @BeforeEach
+  public void setup() {
+    copyConfig1 = new 
ConfigurationCopy(Map.of(Property.COMPACTOR_CLIENTPORT.getKey(), "1234",
+        Property.TABLE_DURABILITY.getKey(), "flush"));
+    copyConfig2 = new 
ConfigurationCopy(Map.of(Property.COMPACTOR_CLIENTPORT.getKey(), "1235",
+        Property.SPLIT_MAXOPEN.getKey(), "200"));
+    config = new LayeredConfiguration(
+        new LayeredConfiguration(DefaultConfiguration.getInstance(), 
copyConfig1), copyConfig2);
+    assertNotEquals("1234", 
DefaultConfiguration.getInstance().get(Property.COMPACTOR_CLIENTPORT));
+    assertNotEquals("1235", 
DefaultConfiguration.getInstance().get(Property.COMPACTOR_CLIENTPORT));
+    assertNotEquals("flush", 
DefaultConfiguration.getInstance().get(Property.TABLE_DURABILITY));
+    assertNotEquals("200", 
DefaultConfiguration.getInstance().get(Property.SPLIT_MAXOPEN));
+  }
+
+  @Test
+  public void testUpdateCount() {
+    assertEquals(0, config.getUpdateCount());
+    copyConfig1.set(Property.TABLE_DURABILITY.getKey(), "sync");
+    assertEquals(1, config.getUpdateCount());
+    copyConfig2.set(Property.TABLE_DURABILITY.getKey(), "flush");
+    assertEquals(2, config.getUpdateCount());
+  }
+
+  @Test
+  public void testGet() {
+    assertEquals("1235", config.get(Property.COMPACTOR_CLIENTPORT));
+    assertEquals("200", config.get(Property.SPLIT_MAXOPEN));
+    assertEquals("flush", config.get(Property.TABLE_DURABILITY));
+    
assertEquals(DefaultConfiguration.getInstance().get(Property.GC_CYCLE_DELAY),
+        config.get(Property.GC_CYCLE_DELAY));
+  }
+
+  @Test
+  public void testIsPropSet() {
+    assertTrue(config.isPropertySet(Property.COMPACTOR_CLIENTPORT));
+    assertTrue(config.isPropertySet(Property.SPLIT_MAXOPEN));
+    assertTrue(config.isPropertySet(Property.TABLE_DURABILITY));
+    assertFalse(config.isPropertySet(Property.GC_CYCLE_DELAY));
+  }
+
+  @Test
+  public void testGetProps() {
+    var props = new HashMap<String,String>();
+    config.getProperties(props, p -> true);
+
+    var props2 = new HashMap<String,String>();
+    DefaultConfiguration.getInstance().forEach(e -> props2.put(e.getKey(), 
e.getValue()));
+    copyConfig1.forEach(e -> props2.put(e.getKey(), e.getValue()));
+    copyConfig2.forEach(e -> props2.put(e.getKey(), e.getValue()));
+
+    assertEquals(props2, props);
+  }
+}

Reply via email to