sashapolo commented on a change in pull request #460:
URL: https://github.com/apache/ignite-3/pull/460#discussion_r755995347



##########
File path: 
modules/runner/src/main/java/org/apache/ignite/internal/configuration/CompoundModule.java
##########
@@ -0,0 +1,92 @@
+/*
+ * 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 java.util.stream.Collectors.toUnmodifiableList;
+
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+import org.apache.ignite.configuration.RootKey;
+import org.apache.ignite.configuration.annotation.ConfigurationType;
+import org.apache.ignite.configuration.validation.Validator;
+
+/**
+ * {@link ConfigurationModule} that merges a few {@code ConfigurationModule}s.
+ */
+public class CompoundModule implements ConfigurationModule {
+    private final ConfigurationType type;
+    private final List<ConfigurationModule> modules;
+
+    public CompoundModule(ConfigurationType type, 
Collection<ConfigurationModule> modules) {
+        this.type = type;
+        this.modules = List.copyOf(modules);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public ConfigurationType type() {
+        return type;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Collection<RootKey<?, ?>> rootKeys() {
+        return unionFromModulesExtractedWith(ConfigurationModule::rootKeys);
+    }
+
+    private <T> List<T> unionFromModulesExtractedWith(
+            Function<? super ConfigurationModule, ? extends Collection<T>> 
extractor) {
+        return modules.stream()
+                .flatMap(module -> extractor.apply(module).stream())
+                .collect(toUnmodifiableList());
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Map<Class<? extends Annotation>, Set<Validator<? extends 
Annotation, ?>>> validators() {
+        Map<Class<? extends Annotation>, Set<Validator<? extends Annotation, 
?>>> result = new HashMap<>();
+
+        var validatorsMaps = 
modules.stream().map(ConfigurationModule::validators);

Review comment:
       We have an agreement that such `var` usages are illegal

##########
File path: 
modules/configuration-api/src/main/java/org/apache/ignite/configuration/annotation/ConfigurationRoot.java
##########
@@ -25,8 +25,34 @@
 import java.lang.annotation.Target;
 
 /**
- * Annotation that marks underlying class as a root configuration schema. Has 
basically the same properties as {@link Config} + adds extra
- * properties.
+ * This annotation, if applied to a class, marks it as a configuration schema 
root. Annotation processor generates
+ * several classes for each configuration schema:
+ * <ul>
+ * <li>Config - Represents configuration itself, provides API to init, change 
and view it.

Review comment:
       ```suggestion
    * <li>Config - Represents the configuration, provides API to init, change 
and view it.
   ```

##########
File path: 
modules/runner/src/main/java/org/apache/ignite/internal/configuration/CompoundModule.java
##########
@@ -0,0 +1,92 @@
+/*
+ * 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 java.util.stream.Collectors.toUnmodifiableList;
+
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+import org.apache.ignite.configuration.RootKey;
+import org.apache.ignite.configuration.annotation.ConfigurationType;
+import org.apache.ignite.configuration.validation.Validator;
+
+/**
+ * {@link ConfigurationModule} that merges a few {@code ConfigurationModule}s.
+ */
+public class CompoundModule implements ConfigurationModule {
+    private final ConfigurationType type;
+    private final List<ConfigurationModule> modules;
+
+    public CompoundModule(ConfigurationType type, 
Collection<ConfigurationModule> modules) {
+        this.type = type;
+        this.modules = List.copyOf(modules);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public ConfigurationType type() {
+        return type;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Collection<RootKey<?, ?>> rootKeys() {
+        return unionFromModulesExtractedWith(ConfigurationModule::rootKeys);
+    }
+
+    private <T> List<T> unionFromModulesExtractedWith(
+            Function<? super ConfigurationModule, ? extends Collection<T>> 
extractor) {
+        return modules.stream()
+                .flatMap(module -> extractor.apply(module).stream())
+                .collect(toUnmodifiableList());
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Map<Class<? extends Annotation>, Set<Validator<? extends 
Annotation, ?>>> validators() {
+        Map<Class<? extends Annotation>, Set<Validator<? extends Annotation, 
?>>> result = new HashMap<>();

Review comment:
       This method can be written in a much shorter way:
   ```
   return modules.stream()
           .flatMap(module -> module.validators().entrySet().stream())
           .collect(groupingBy(
                   Map.Entry::getKey,
                   flatMapping(e -> e.getValue().stream(), toSet())
           ));
   ```        

##########
File path: 
modules/runner/src/main/java/org/apache/ignite/internal/configuration/ServiceLoaderModulesProvider.java
##########
@@ -0,0 +1,33 @@
+/*
+ * 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.ServiceLoader;
+import java.util.stream.Stream;
+
+/**
+ * Provides {@link ConfigurationModule}s using {@link ServiceLoader} mechanism.
+ * Uses {@link ConfigurationModule} interface to query the ServiceLoader.
+ *
+ * @see ConfigurationModule
+ */
+public class ServiceLoaderModulesProvider {
+    public Stream<ConfigurationModule> modules() {

Review comment:
       I would suggest to use a simple List as the return type, it makes a more 
clear interface

##########
File path: 
modules/configuration-api/src/main/java/org/apache/ignite/configuration/annotation/ConfigurationRoot.java
##########
@@ -25,8 +25,34 @@
 import java.lang.annotation.Target;
 
 /**
- * Annotation that marks underlying class as a root configuration schema. Has 
basically the same properties as {@link Config} + adds extra
- * properties.
+ * This annotation, if applied to a class, marks it as a configuration schema 
root. Annotation processor generates
+ * several classes for each configuration schema:
+ * <ul>
+ * <li>Config - Represents configuration itself, provides API to init, change 
and view it.
+ * Extends {@code DynamicConfiguration}</li>
+ * <li>Change - changes config tree</li>

Review comment:
       ```suggestion
    * <li>Change - changes the config tree</li>
   ```

##########
File path: 
modules/runner/src/main/java/org/apache/ignite/internal/configuration/ConfigurationModules.java
##########
@@ -0,0 +1,65 @@
+/*
+ * 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 java.util.stream.Collectors.toUnmodifiableList;
+
+import java.util.List;
+import org.apache.ignite.configuration.annotation.ConfigurationType;
+
+/**
+ * An ensemble of {@link ConfigurationModule}s used to easily pick node-local 
and cluster-wide configuration
+ * and merge modules for convenience.
+ */
+public class ConfigurationModules {
+    private final List<ConfigurationModule> modules;
+
+    /**
+     * Creates a new instance of {@link ConfigurationModules} wrapping modules 
passed to it.
+     *
+     * @param modules modules to wrap; they may be of different types
+     */
+    public ConfigurationModules(List<ConfigurationModule> modules) {
+        this.modules = List.copyOf(modules);
+    }
+
+    /**
+     * Return a module representing the result of merge of modules of type 
{@link ConfigurationType#LOCAL}.
+     *
+     * @return node-local configuration merge result
+     */
+    public ConfigurationModule local() {
+        return compoundOfType(ConfigurationType.LOCAL);
+    }
+
+    /**
+     * Return a module representing the result of merge of modules of type 
{@link ConfigurationType#DISTRIBUTED}.
+     *
+     * @return cluster-wide configuration merge result
+     */
+    public ConfigurationModule distributed() {
+        return compoundOfType(ConfigurationType.DISTRIBUTED);
+    }
+
+    private CompoundModule compoundOfType(ConfigurationType type) {

Review comment:
       Will it make sense to group the modules by type in the constructor 
instead of evaluating them on each call?

##########
File path: 
modules/runner/src/test/java/org/apache/ignite/internal/configuration/CompoundModuleTest.java
##########
@@ -0,0 +1,126 @@
+/*
+ * 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 java.util.Collections.emptyList;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.when;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ignite.configuration.RootKey;
+import org.apache.ignite.configuration.annotation.ConfigurationType;
+import org.apache.ignite.configuration.validation.Validator;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+class CompoundModuleTest {
+    @Mock
+    private RootKey<?, ?> rootKeyA;
+    @Mock
+    private RootKey<?, ?> rootKeyB;
+
+    @Mock
+    private Validator<AnnotationA, ?> validatorA;
+    @Mock
+    private Validator<AnnotationB, ?> validatorB;
+
+    @Mock
+    private ConfigurationModule moduleA;
+    @Mock
+    private ConfigurationModule moduleB;
+
+    private ConfigurationModule compound;
+
+    @BeforeEach
+    void createCompoundModule() {
+        compound = new CompoundModule(ConfigurationType.LOCAL, 
List.of(moduleA, moduleB));
+    }
+
+    @Test
+    void returnsTypePassedViaConstructor() {
+        var compound = new CompoundModule(ConfigurationType.LOCAL, 
emptyList());
+
+        assertThat(compound.type(), is(ConfigurationType.LOCAL));
+    }
+
+    @Test
+    void returnsUnionOfRootKeysOfItsModules() {
+        when(moduleA.rootKeys()).thenReturn(Set.of(rootKeyA));
+        when(moduleB.rootKeys()).thenReturn(Set.of(rootKeyB));
+
+        assertThat(compound.rootKeys(), containsInAnyOrder(rootKeyA, 
rootKeyB));
+    }
+
+    @Test
+    void providesUnionOfValidatorsMapsOfItsModulesPerKey() {
+        when(moduleA.validators()).thenReturn(Map.of(AnnotationA.class, 
Set.of(validatorA)));
+        when(moduleB.validators()).thenReturn(Map.of(AnnotationB.class, 
Set.of(validatorB)));
+
+        var validators = compound.validators();

Review comment:
       same stuff about using `var`

##########
File path: 
modules/configuration-api/src/main/java/org/apache/ignite/configuration/annotation/ConfigurationRoot.java
##########
@@ -25,8 +25,34 @@
 import java.lang.annotation.Target;
 
 /**
- * Annotation that marks underlying class as a root configuration schema. Has 
basically the same properties as {@link Config} + adds extra
- * properties.
+ * This annotation, if applied to a class, marks it as a configuration schema 
root. Annotation processor generates
+ * several classes for each configuration schema:
+ * <ul>
+ * <li>Config - Represents configuration itself, provides API to init, change 
and view it.
+ * Extends {@code DynamicConfiguration}</li>
+ * <li>Change - changes config tree</li>
+ * <li>View - immutable object to view config tree</li>

Review comment:
       ```suggestion
    * <li>View - an immutable object to view the config tree</li>
   ```




-- 
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]


Reply via email to