ibessonov commented on code in PR #2684:
URL: https://github.com/apache/ignite-3/pull/2684#discussion_r1361669639
##########
modules/configuration/src/main/java/org/apache/ignite/internal/configuration/SuperRoot.java:
##########
@@ -84,6 +90,34 @@ public void addRoot(RootKey<?, ?> rootKey, InnerNode root) {
roots.put(rootKey.key(), new RootInnerNode(rootKey, root));
}
+ /**
+ * Convert configuration subtree into a user-defined representation.
+ *
+ * @param path Path to configuration subtree. Can be empty, can't be
{@code null}.
+ * @param visitor Visitor that will be applied to the subtree and build
the representation.
+ * @param <T> Type of the representation.
+ * @return User-defined representation constructed by {@code visitor}.
+ * @throws IllegalArgumentException If {@code path} is not found in
current configuration.
+ */
+
+ public <T> T represent(List<String> path, ConfigurationVisitor<T> visitor)
throws IllegalArgumentException {
Review Comment:
What was the reason of moving this code into SuperRoot? It doesn't belong
here.
In order to reuse the code, I'd recommend creating utility method somewhere
else instead.
##########
modules/configuration/src/main/java/org/apache/ignite/internal/configuration/ConfigurationDefaultsPatcherImpl.java:
##########
@@ -0,0 +1,85 @@
+/*
+ * 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
+ *
+ * http://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.ignite.internal.configuration;
+
+import com.typesafe.config.Config;
+import com.typesafe.config.ConfigFactory;
+import com.typesafe.config.ConfigRenderOptions;
+import java.util.List;
+import org.apache.ignite.configuration.ConfigurationDefaultsPatcher;
+import org.apache.ignite.configuration.ConfigurationModule;
+import org.apache.ignite.configuration.SuperRootChange;
+import
org.apache.ignite.configuration.validation.ConfigurationValidationException;
+import org.apache.ignite.internal.configuration.hocon.HoconConverter;
+import org.apache.ignite.internal.configuration.tree.ConfigurationSource;
+import org.apache.ignite.internal.configuration.tree.ConverterToMapVisitor;
+
+/**
+ * Implementation of {@link ConfigurationDefaultsPatcher}.
+ */
+public class ConfigurationDefaultsPatcherImpl implements
ConfigurationDefaultsPatcher {
+ /**
+ * Configuration module.
+ */
+ private final ConfigurationModule configurationModule;
+
+ /**
+ * Configuration tree generator.
+ */
+ private final ConfigurationTreeGenerator generator;
+
+
Review Comment:
Do we use two empty lines in a row anywhere in the code? I don't think that
this is allowed by the code style guidelines
##########
modules/configuration/src/main/java/org/apache/ignite/internal/configuration/hocon/HoconConverter.java:
##########
@@ -42,29 +43,31 @@ public static ConfigValue represent(
ConfigurationRegistry registry,
List<String> path
) throws IllegalArgumentException {
- ConverterToMapVisitor visitor = ConverterToMapVisitor.builder()
- .includeInternal(false)
- .maskSecretValues(true)
- .build();
- return represent(registry, path, visitor);
+ Object res = registry.represent(
+ path,
+ ConverterToMapVisitor.builder()
+ .includeInternal(false)
+ .maskSecretValues(true)
+ .build());
+
+ return ConfigImpl.fromAnyRef(res, null);
}
/**
* Converts configuration subtree to a HOCON {@link ConfigValue} instance.
*
- * @param registry Configuration registry instance.
- * @param path Path to the configuration subtree. Can be empty, can't
be {@code null}.
- * @param visitor Visitor that will be used to convert configuration
subtree.
+ * @param superRoot Super root instance.
+ * @param path Path to the configuration subtree. Can be empty, can't be
{@code null}.
+ * @param visitor Visitor that will be used to convert configuration
subtree.
* @return {@link ConfigValue} instance that represents configuration
subtree.
* @throws IllegalArgumentException If {@code path} is not found in
current configuration.
*/
public static ConfigValue represent(
Review Comment:
What does this method have to do with HOCON? Should it even be here?
Changing registry to superRoot looks out-of-place, API symmetry is broken.
What was the reason? Maybe first method shouldn't use registry either, this way
it would call current method with a specific visitor, right?
##########
modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterInitializer.java:
##########
@@ -264,18 +254,16 @@ private static List<ClusterNode>
resolveNodes(ClusterService clusterService, Col
}
- private CompletableFuture<String>
setDefaultsToClusterConfiguration(@Nullable String hocon) {
- return configurationDefaultsSetter.setDefaults(hocon == null ? "" :
hocon);
+ private String patchClusterConfigurationWithDefaults(@Nullable String
hocon) {
+ return configurationDefaultsPatcher.patchWithDefaults(hocon == null ?
"" : hocon);
Review Comment:
How many times do we convert string to a tree and back? I wonder.
Anyway, the real question - what's the meaning behind converting null into
an empty string? Can't `patchWithDefaults` handle null?
##########
modules/configuration/src/main/java/org/apache/ignite/internal/configuration/SuperRootChangeImpl.java:
##########
@@ -0,0 +1,54 @@
+/*
+ * 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
+ *
+ * http://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.ignite.internal.configuration;
+
+import java.util.Objects;
+import org.apache.ignite.configuration.ConfigurationTree;
+import org.apache.ignite.configuration.RootKey;
+import org.apache.ignite.configuration.SuperRootChange;
+import org.apache.ignite.internal.configuration.util.ConfigurationUtil;
+
+/**
+ * Implementation of {@link SuperRootChange}.
+ */
+public class SuperRootChangeImpl implements SuperRootChange {
Review Comment:
Can it become package-private?
##########
modules/security/src/test/java/org/apache/ignite/internal/security/authentication/SecurityConfigurationModuleTest.java:
##########
@@ -24,24 +24,57 @@
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.jupiter.api.Assertions.assertAll;
+import org.apache.ignite.configuration.SuperRootChange;
+import org.apache.ignite.internal.configuration.ConfigurationTreeGenerator;
+import org.apache.ignite.internal.configuration.SuperRoot;
+import org.apache.ignite.internal.configuration.SuperRootChangeImpl;
+import
org.apache.ignite.internal.security.authentication.basic.BasicAuthenticationProviderChange;
import
org.apache.ignite.internal.security.authentication.basic.BasicAuthenticationProviderConfigurationSchema;
+import
org.apache.ignite.internal.security.authentication.basic.BasicAuthenticationProviderView;
import
org.apache.ignite.internal.security.authentication.configuration.validator.AuthenticationProvidersValidatorImpl;
import org.apache.ignite.internal.security.configuration.SecurityConfiguration;
-import org.hamcrest.Matchers;
+import org.apache.ignite.internal.security.configuration.SecurityView;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class SecurityConfigurationModuleTest {
+ private ConfigurationTreeGenerator generator;
+
+ private SuperRootChange rootChange;
+
private final SecurityConfigurationModule module = new
SecurityConfigurationModule();
+ @BeforeEach
+ void setUp() {
+ generator = new ConfigurationTreeGenerator(
+ module.rootKeys(),
+ module.schemaExtensions(),
+ module.polymorphicSchemaExtensions()
+ );
+
+ SuperRoot superRoot = generator.createSuperRoot();
+
+ rootChange = new SuperRootChangeImpl(superRoot);
+ }
+
+ @AfterEach
+ void tearDown() {
+ generator.close();
+ generator = null;
Review Comment:
This is not necessary, but I'm OK with it
##########
modules/cli/src/integrationTest/java/org/apache/ignite/internal/rest/ItGeneratedRestClientTest.java:
##########
@@ -287,25 +287,14 @@ void updateClusterConfigurationWithInvalidParam() throws
JsonProcessingException
ApiException thrown = assertThrows(
ApiException.class,
() -> clusterConfigurationApi.updateClusterConfiguration("{\n"
- + " \"security\": {\n"
- + " \"authentication\": {\n"
- + " \"enabled\": true,\n"
- + " \"providers\": [\n"
- + " {\n"
- + " \"name\": \"basic\",\n"
- + " \"type\": \"basic\",\n"
- + " \"username\": \"\",\n"
- + " \"password\": \"\"\n"
- + " }\n"
- + " ]\n"
- + " }\n"
- + " }\n"
+ + " security.enabled:true, \n"
+ + " security.authentication.providers:null\n"
+ "}")
);
Problem problem = objectMapper.readValue(thrown.getResponseBody(),
Problem.class);
assertThat(problem.getStatus(), equalTo(400));
- assertThat(problem.getInvalidParams(), hasSize(2));
+ assertThat(problem.getInvalidParams(), hasSize(1));
Review Comment:
Should we also check the message just in case?
##########
modules/configuration/src/test/java/org/apache/ignite/internal/configuration/ConfigurationDefaultsPatcherImplTest.java:
##########
@@ -0,0 +1,58 @@
+/*
+ * 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
+ *
+ * http://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.ignite.internal.configuration;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+class ConfigurationDefaultsPatcherImplTest {
+ private static final TestConfigurationModule MODULE = new
TestConfigurationModule();
+
+ private static ConfigurationTreeGenerator generator;
+
+ private static ConfigurationDefaultsPatcherImpl patcher;
+
+ @BeforeAll
+ static void beforeAll() {
+ generator = new ConfigurationTreeGenerator(
+ MODULE.rootKeys(),
+ MODULE.schemaExtensions(),
+ MODULE.polymorphicSchemaExtensions()
+ );
+ patcher = new ConfigurationDefaultsPatcherImpl(
+ MODULE,
+ generator
+ );
+ }
+
+ @AfterAll
+ static void afterAll() {
+ generator.close();
+ generator = null;
+ }
+
+ @Test
+ void patchedHoconDoesNotContainNullValues() {
+ String patchedHocon = patcher.patchWithDefaults("");
+ assertThat(patchedHocon,
equalTo("{\"testRoot\":{\"testSubConfiguration\":{\"testInt\":42,\"testSecret\":\"secret\"}}}"));
Review Comment:
Another question - why do we render our HOCON configuration as JSON? Is this
intentional?
I don't get it
--
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]