This is an automated email from the ASF dual-hosted git repository. sk0x50 pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push: new 3565c9d IGNITE-14411 Defined minimal set of cluster components and their lifecycle. Fixes #96 3565c9d is described below commit 3565c9d0ab61af1dcc44ad3060e1facae4d7461c Author: Alexander Lapin <lapin1...@gmail.com> AuthorDate: Wed Apr 21 15:29:21 2021 +0300 IGNITE-14411 Defined minimal set of cluster components and their lifecycle. Fixes #96 Signed-off-by: Slava Koptilin <slava.kopti...@gmail.com> --- modules/{table => affinity}/pom.xml | 43 ++- .../ignite/internal/affinity/AffinityManager.java | 60 ++++ modules/api/pom.xml | 6 + .../main/java/org/apache/ignite/app/Ignite.java} | 15 +- .../main/java/org/apache/ignite/app/Ignition.java} | 17 +- .../org/apache/ignite/app/IgnitionManager.java | 62 ++++ .../network/NetworkConfigurationSchema.java} | 15 +- .../schemas/rest}/RestConfigurationSchema.java | 6 +- .../runner/ClusterConfigurationSchema.java} | 25 +- .../apache/ignite/table/manager/TableManager.java} | 7 +- modules/baseline/pom.xml | 54 ++++ .../ignite/internal/baseline/BaselineManager.java | 58 ++++ .../notifications/ConfigurationListenerTest.java | 16 +- .../ignite/configuration/sample/UsageTest.java | 21 +- modules/configuration/pom.xml | 5 + .../ignite/configuration/ConfigurationChanger.java | 7 + .../configuration/ConfigurationRegistry.java | 34 +- .../internal/ConfigurationManager.java | 92 ++++++ .../internal/rest/FormatConverter.java} | 25 +- .../configuration/internal/rest/JsonConverter.java | 356 +++++++++++++++++++++ .../ignite/configuration/validation/Validator.java | 2 - modules/metastorage/pom.xml | 60 ++++ .../internal/metastorage/MetaStorageManager.java | 112 +++++++ .../network/MetaStorageMessageTypes.java} | 30 +- .../org/apache/ignite/internal/raft/Loza.java} | 21 +- modules/rest/pom.xml | 6 + .../java/org/apache/ignite/rest/RestModule.java | 5 +- .../rest/presentation/json/JsonConverterTest.java | 12 +- modules/runner/pom.xml | 61 +++- .../ignite/internal/runner/app/IgnitionTest.java | 81 +++++ .../java/org/apache/ignite/app/IgniteRunner.java | 113 +------ .../ignite/configuration/ConfigurationModule.java | 67 ---- .../apache/ignite/internal/app/IgniteImpl.java} | 29 +- .../apache/ignite/internal/app/IgnitionImpl.java | 181 +++++++++++ .../storage/DistributedConfigurationStorage.java | 104 ++++++ .../storage/LocalConfigurationStorage.java | 104 ++++++ .../services/org.apache.ignite.app.Ignition | 1 + .../ignite/internal/schema/SchemaManager.java} | 21 +- modules/table/pom.xml | 31 ++ .../table/distributed/TableManagerImpl.java | 69 ++++ modules/{api => vault}/pom.xml | 15 +- .../ignite/internal/vault/VaultManager.java} | 17 +- parent/pom.xml | 1 + pom.xml | 4 + 44 files changed, 1766 insertions(+), 305 deletions(-) diff --git a/modules/table/pom.xml b/modules/affinity/pom.xml similarity index 55% copy from modules/table/pom.xml copy to modules/affinity/pom.xml index 1f58901..42c02af 100644 --- a/modules/table/pom.xml +++ b/modules/affinity/pom.xml @@ -1,25 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - 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 + 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 + 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. ---> + 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. + --> -<!-- - POM file. ---> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> @@ -32,38 +29,38 @@ <relativePath>../../parent/pom.xml</relativePath> </parent> - <artifactId>ignite-table</artifactId> + <artifactId>ignite-affinity</artifactId> <version>3.0.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.apache.ignite</groupId> - <artifactId>ignite-api</artifactId> + <artifactId>ignite-configuration</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.apache.ignite</groupId> - <artifactId>ignite-schema</artifactId> + <artifactId>ignite-metastorage</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.apache.ignite</groupId> - <artifactId>ignite-core</artifactId> + <artifactId>ignite-baseline</artifactId> <version>${project.version}</version> </dependency> - <!-- Test dependencies --> + <!-- Test dependencies. --> <dependency> <groupId>org.junit.jupiter</groupId> - <artifactId>junit-jupiter-engine</artifactId> + <artifactId>junit-jupiter-api</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> - <artifactId>junit-jupiter-params</artifactId> + <artifactId>junit-jupiter-engine</artifactId> <scope>test</scope> </dependency> </dependencies> diff --git a/modules/affinity/src/main/java/org/apache/ignite/internal/affinity/AffinityManager.java b/modules/affinity/src/main/java/org/apache/ignite/internal/affinity/AffinityManager.java new file mode 100644 index 0000000..7e28308 --- /dev/null +++ b/modules/affinity/src/main/java/org/apache/ignite/internal/affinity/AffinityManager.java @@ -0,0 +1,60 @@ +/* + * 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.affinity; + +import org.apache.ignite.internal.baseline.BaselineManager; +import org.apache.ignite.configuration.internal.ConfigurationManager; +import org.apache.ignite.internal.metastorage.MetaStorageManager; + +/** + * Affinity manager is responsible for affinity function related logic including calculating affinity assignments. + */ +// TODO: IGNITE-14586 Remove @SuppressWarnings when implementation provided. +@SuppressWarnings({"FieldCanBeLocal", "unused"}) public class AffinityManager { + /** + * MetaStorage manager in order to watch private distributed affinity specific configuration, + * cause ConfigurationManger handles only public configuration. + */ + private final MetaStorageManager metaStorageMgr; + + /** Configuration manager in order to handle and listen affinity specific configuration.*/ + private final ConfigurationManager configurationMgr; + + /** Baseline manager. */ + private final BaselineManager baselineMgr; + + /** + * The constructor. + * + * @param configurationMgr Configuration manager. + * @param metaStorageMgr Meta storage manager. + */ + public AffinityManager( + ConfigurationManager configurationMgr, + MetaStorageManager metaStorageMgr, + BaselineManager baselineMgr + ) { + this.configurationMgr = configurationMgr; + this.metaStorageMgr = metaStorageMgr; + this.baselineMgr = baselineMgr; + } + + // TODO: IGNITE-14237 Affinity function. + // TODO: IGNITE-14238 Creating and destroying caches. + // TODO: IGNITE-14235 Provide a minimal cache/table configuration. +} diff --git a/modules/api/pom.xml b/modules/api/pom.xml index 2ca3c60..c0e395b 100644 --- a/modules/api/pom.xml +++ b/modules/api/pom.xml @@ -37,5 +37,11 @@ <groupId>org.jetbrains</groupId> <artifactId>annotations</artifactId> </dependency> + + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-configuration-annotation-processor</artifactId> + <version>${project.version}</version> + </dependency> </dependencies> </project> diff --git a/modules/core/src/test/java/org/apache/ignite/internal/testframework/package-info.java b/modules/api/src/main/java/org/apache/ignite/app/Ignite.java similarity index 71% rename from modules/core/src/test/java/org/apache/ignite/internal/testframework/package-info.java rename to modules/api/src/main/java/org/apache/ignite/app/Ignite.java index 23ab2d4..c9613dd 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/testframework/package-info.java +++ b/modules/api/src/main/java/org/apache/ignite/app/Ignite.java @@ -15,7 +15,18 @@ * limitations under the License. */ +package org.apache.ignite.app; + +import org.apache.ignite.table.manager.TableManager; + /** - * Contains internal tests or test related classes and interfaces. + * Ignite node interface. Main entry-point for all Ignite APIs. */ -package org.apache.ignite.internal.testframework; +public interface Ignite extends AutoCloseable { + /** + * Gets a manager for tables. + * + * @return Table manager. + */ + TableManager tableManager(); +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java b/modules/api/src/main/java/org/apache/ignite/app/Ignition.java similarity index 60% copy from modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java copy to modules/api/src/main/java/org/apache/ignite/app/Ignition.java index 9cc76fb..9904f4c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java +++ b/modules/api/src/main/java/org/apache/ignite/app/Ignition.java @@ -15,7 +15,20 @@ * limitations under the License. */ +package org.apache.ignite.app; + +import org.jetbrains.annotations.Nullable; + /** - * Common utility classes for strings. + * Entry point for handling grid lifecycle. */ -package org.apache.ignite.internal.tostring; +@SuppressWarnings("UnnecessaryInterfaceModifier") +public interface Ignition { + /** + * Starts Ignite node with optional bootstrap configuration in json format. + * @param jsonStrBootstrapCfg Node configuration in json format. + * @return Started Ignite node. + */ + // TODO: IGNITE-14599 Add generic way to bootstrap configuration. + public Ignite start(@Nullable String jsonStrBootstrapCfg); +} diff --git a/modules/api/src/main/java/org/apache/ignite/app/IgnitionManager.java b/modules/api/src/main/java/org/apache/ignite/app/IgnitionManager.java new file mode 100644 index 0000000..1d66c30 --- /dev/null +++ b/modules/api/src/main/java/org/apache/ignite/app/IgnitionManager.java @@ -0,0 +1,62 @@ +/* + * 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.app; + +import java.util.ServiceLoader; +import org.jetbrains.annotations.Nullable; + +/** + * Service loader based implementation of an entry point for handling grid lifecycle. + */ +public class IgnitionManager { + /** Loaded Ignition instance. */ + private static Ignition ignition; + + /** + * Starts Ignite node with optional bootstrap configuration in json format. + * @param jsonStrBootstrapCfg Node configuration in json format. + * @return Started Ignite node. + */ + // TODO IGNITE-14580 Add exception handling logic to IgnitionProcessor. + public static synchronized Ignite start(@Nullable String jsonStrBootstrapCfg) { + if (ignition == null) { + ServiceLoader<Ignition> ldr = ServiceLoader.load(Ignition.class); + ignition = ldr.iterator().next(); + } + + return ignition.start(jsonStrBootstrapCfg); + } + + /** + * Starts Ignite node with optional bootstrap configuration in json format. + * @param jsonStrBootstrapCfg Node configuration in json format. + * @param clsLdr The class loader to be used to load provider-configuration files + * and provider classes, or {@code null} if the system class + * loader (or, failing that, the bootstrap class loader) is to be used + * @return Started Ignite node. + */ + // TODO IGNITE-14580 Add exception handling logic to IgnitionProcessor. + public static synchronized Ignite start(@Nullable String jsonStrBootstrapCfg, @Nullable ClassLoader clsLdr) { + if (ignition == null) { + ServiceLoader<Ignition> ldr = ServiceLoader.load(Ignition.class, clsLdr); + ignition = ldr.iterator().next(); + } + + return ignition.start(jsonStrBootstrapCfg); + } +} diff --git a/modules/rest/src/main/java/org/apache/ignite/rest/configuration/RestConfigurationSchema.java b/modules/api/src/main/java/org/apache/ignite/configuration/schemas/network/NetworkConfigurationSchema.java similarity index 77% copy from modules/rest/src/main/java/org/apache/ignite/rest/configuration/RestConfigurationSchema.java copy to modules/api/src/main/java/org/apache/ignite/configuration/schemas/network/NetworkConfigurationSchema.java index 66eaa51..1a1b51f 100644 --- a/modules/rest/src/main/java/org/apache/ignite/rest/configuration/RestConfigurationSchema.java +++ b/modules/api/src/main/java/org/apache/ignite/configuration/schemas/network/NetworkConfigurationSchema.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.ignite.rest.configuration; +package org.apache.ignite.configuration.schemas.network; import javax.validation.constraints.Max; import javax.validation.constraints.Min; @@ -23,21 +23,18 @@ import org.apache.ignite.configuration.annotation.ConfigurationRoot; import org.apache.ignite.configuration.annotation.Value; import org.apache.ignite.configuration.storage.ConfigurationType; -import static org.apache.ignite.rest.RestModule.DFLT_PORT; - /** - * Configuration schema for REST endpoint subtree. + * Configuration schema for network endpoint subtree. */ -@ConfigurationRoot(rootName = "rest", type = ConfigurationType.LOCAL) -public class RestConfigurationSchema { +@ConfigurationRoot(rootName = "network", type = ConfigurationType.LOCAL) +public class NetworkConfigurationSchema { /** */ @Min(1024) @Max(0xFFFF) @Value(hasDefault = true) - public final int port = DFLT_PORT; + public final int port = 3040; /** */ - @Min(0) @Value(hasDefault = true) - public final int portRange = 0; + public String[] netClusterNodes = {"localhost:" + port}; } diff --git a/modules/rest/src/main/java/org/apache/ignite/rest/configuration/RestConfigurationSchema.java b/modules/api/src/main/java/org/apache/ignite/configuration/schemas/rest/RestConfigurationSchema.java similarity index 90% copy from modules/rest/src/main/java/org/apache/ignite/rest/configuration/RestConfigurationSchema.java copy to modules/api/src/main/java/org/apache/ignite/configuration/schemas/rest/RestConfigurationSchema.java index 66eaa51..d65360f 100644 --- a/modules/rest/src/main/java/org/apache/ignite/rest/configuration/RestConfigurationSchema.java +++ b/modules/api/src/main/java/org/apache/ignite/configuration/schemas/rest/RestConfigurationSchema.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.ignite.rest.configuration; +package org.apache.ignite.configuration.schemas.rest; import javax.validation.constraints.Max; import javax.validation.constraints.Min; @@ -23,8 +23,6 @@ import org.apache.ignite.configuration.annotation.ConfigurationRoot; import org.apache.ignite.configuration.annotation.Value; import org.apache.ignite.configuration.storage.ConfigurationType; -import static org.apache.ignite.rest.RestModule.DFLT_PORT; - /** * Configuration schema for REST endpoint subtree. */ @@ -34,7 +32,7 @@ public class RestConfigurationSchema { @Min(1024) @Max(0xFFFF) @Value(hasDefault = true) - public final int port = DFLT_PORT; + public final int port = 10300; /** */ @Min(0) diff --git a/modules/rest/src/main/java/org/apache/ignite/rest/configuration/RestConfigurationSchema.java b/modules/api/src/main/java/org/apache/ignite/configuration/schemas/runner/ClusterConfigurationSchema.java similarity index 64% rename from modules/rest/src/main/java/org/apache/ignite/rest/configuration/RestConfigurationSchema.java rename to modules/api/src/main/java/org/apache/ignite/configuration/schemas/runner/ClusterConfigurationSchema.java index 66eaa51..63278e3 100644 --- a/modules/rest/src/main/java/org/apache/ignite/rest/configuration/RestConfigurationSchema.java +++ b/modules/api/src/main/java/org/apache/ignite/configuration/schemas/runner/ClusterConfigurationSchema.java @@ -15,29 +15,18 @@ * limitations under the License. */ -package org.apache.ignite.rest.configuration; +package org.apache.ignite.configuration.schemas.runner; -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; import org.apache.ignite.configuration.annotation.ConfigurationRoot; import org.apache.ignite.configuration.annotation.Value; import org.apache.ignite.configuration.storage.ConfigurationType; -import static org.apache.ignite.rest.RestModule.DFLT_PORT; - /** - * Configuration schema for REST endpoint subtree. + * Configuration schema for cluster endpoint subtree. */ -@ConfigurationRoot(rootName = "rest", type = ConfigurationType.LOCAL) -public class RestConfigurationSchema { - /** */ - @Min(1024) - @Max(0xFFFF) - @Value(hasDefault = true) - public final int port = DFLT_PORT; - - /** */ - @Min(0) - @Value(hasDefault = true) - public final int portRange = 0; +@ConfigurationRoot(rootName = "cluster", type = ConfigurationType.DISTRIBUTED) +public class ClusterConfigurationSchema { + /** List of unique names of those cluster nodes that will host distributed metastorage instances. */ + @Value + String[] metastorageClusterNodeNames; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java b/modules/api/src/main/java/org/apache/ignite/table/manager/TableManager.java similarity index 86% copy from modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java copy to modules/api/src/main/java/org/apache/ignite/table/manager/TableManager.java index 9cc76fb..f7fcf50 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java +++ b/modules/api/src/main/java/org/apache/ignite/table/manager/TableManager.java @@ -15,7 +15,10 @@ * limitations under the License. */ +package org.apache.ignite.table.manager; + /** - * Common utility classes for strings. + * Interface that provides methods for managing tables. */ -package org.apache.ignite.internal.tostring; +public interface TableManager { +} diff --git a/modules/baseline/pom.xml b/modules/baseline/pom.xml new file mode 100644 index 0000000..ef01290 --- /dev/null +++ b/modules/baseline/pom.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + 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. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-parent</artifactId> + <version>1</version> + <relativePath>../../parent/pom.xml</relativePath> + </parent> + + <artifactId>ignite-baseline</artifactId> + <version>3.0.0-SNAPSHOT</version> + + <dependencies> + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-network</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-configuration</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-metastorage</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> +</project> diff --git a/modules/baseline/src/main/java/org/apache/ignite/internal/baseline/BaselineManager.java b/modules/baseline/src/main/java/org/apache/ignite/internal/baseline/BaselineManager.java new file mode 100644 index 0000000..e2b78d8 --- /dev/null +++ b/modules/baseline/src/main/java/org/apache/ignite/internal/baseline/BaselineManager.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.baseline; + +import org.apache.ignite.configuration.internal.ConfigurationManager; +import org.apache.ignite.internal.metastorage.MetaStorageManager; +import org.apache.ignite.network.ClusterService; + +/** + * Baseline manager is responsible for handling baseline related logic. + */ +// TODO: IGNITE-14586 Remove @SuppressWarnings when implementation provided. +@SuppressWarnings({"FieldCanBeLocal", "unused"}) public class BaselineManager { + /** Configuration manager in order to handle and listen baseline specific configuration.*/ + private final ConfigurationManager configurationMgr; + + /** + * MetaStorage manager in order to watch private distributed baseline specific configuration, + * cause ConfigurationManger handles only public configuration. + */ + private final MetaStorageManager metastorageMgr; + + /** Cluster network service in order to retrieve information about current cluster nodes. */ + private final ClusterService clusterSvc; + + /** + * The constructor. + * + * @param configurationMgr Configuration manager. + * @param metastorageMgr MetaStorage manager. + * @param clusterSvc Cluster network service. + */ + public BaselineManager( + ConfigurationManager configurationMgr, + MetaStorageManager metastorageMgr, + ClusterService clusterSvc + ) { + this.configurationMgr = configurationMgr; + this.metastorageMgr = metastorageMgr; + this.clusterSvc = clusterSvc; + } +} + diff --git a/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/configuration/notifications/ConfigurationListenerTest.java b/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/configuration/notifications/ConfigurationListenerTest.java index c3dd2b2..3d1c308 100644 --- a/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/configuration/notifications/ConfigurationListenerTest.java +++ b/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/configuration/notifications/ConfigurationListenerTest.java @@ -18,6 +18,7 @@ package org.apache.ignite.configuration.notifications; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; import org.apache.ignite.configuration.ConfigurationRegistry; @@ -26,6 +27,7 @@ import org.apache.ignite.configuration.annotation.ConfigValue; import org.apache.ignite.configuration.annotation.ConfigurationRoot; import org.apache.ignite.configuration.annotation.NamedConfigValue; import org.apache.ignite.configuration.annotation.Value; +import org.apache.ignite.configuration.storage.ConfigurationStorage; import org.apache.ignite.configuration.storage.ConfigurationType; import org.apache.ignite.configuration.storage.TestConfigurationStorage; import org.junit.jupiter.api.AfterEach; @@ -61,7 +63,7 @@ public class ConfigurationListenerTest { } /** */ - private final ConfigurationRegistry registry = new ConfigurationRegistry(); + private ConfigurationRegistry registry; /** */ private ParentConfiguration configuration; @@ -69,13 +71,15 @@ public class ConfigurationListenerTest { /** */ @BeforeEach public void before() { - registry.registerRootKey(ParentConfiguration.KEY); + ConfigurationStorage testConfigurationStorage = new TestConfigurationStorage(); - TestConfigurationStorage storage = new TestConfigurationStorage(); + registry = new ConfigurationRegistry( + Collections.singletonList(ParentConfiguration.KEY), + Collections.emptyMap(), + Collections.singletonList(testConfigurationStorage) + ); - registry.registerStorage(storage); - - registry.startStorageConfigurations(storage.type()); + registry.startStorageConfigurations(testConfigurationStorage.type()); configuration = registry.getConfiguration(ParentConfiguration.KEY); } diff --git a/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/configuration/sample/UsageTest.java b/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/configuration/sample/UsageTest.java index 41f14d9..21416ab 100644 --- a/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/configuration/sample/UsageTest.java +++ b/modules/configuration-annotation-processor/src/test/java/org/apache/ignite/configuration/sample/UsageTest.java @@ -17,6 +17,8 @@ package org.apache.ignite.configuration.sample; +import java.util.Arrays; +import java.util.Collections; import org.apache.ignite.configuration.ConfigurationRegistry; import org.apache.ignite.configuration.storage.TestConfigurationStorage; import org.junit.jupiter.api.AfterEach; @@ -33,7 +35,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; */ public class UsageTest { /** */ - private final ConfigurationRegistry registry = new ConfigurationRegistry(); + private ConfigurationRegistry registry; /** */ @AfterEach @@ -46,9 +48,11 @@ public class UsageTest { */ @Test public void test() throws Exception { - registry.registerRootKey(LocalConfiguration.KEY); - - registry.registerStorage(new TestConfigurationStorage()); + registry = new ConfigurationRegistry( + Collections.singletonList(LocalConfiguration.KEY), + Collections.emptyMap(), + Collections.singletonList(new TestConfigurationStorage()) + ); LocalConfiguration root = registry.getConfiguration(LocalConfiguration.KEY); @@ -100,10 +104,11 @@ public class UsageTest { long autoAdjustTimeout = 30_000L; - registry.registerRootKey(NetworkConfiguration.KEY); - registry.registerRootKey(LocalConfiguration.KEY); - - registry.registerStorage(new TestConfigurationStorage()); + registry = new ConfigurationRegistry( + Arrays.asList(NetworkConfiguration.KEY, LocalConfiguration.KEY), + Collections.emptyMap(), + Collections.singletonList(new TestConfigurationStorage()) + ); registry.getConfiguration(LocalConfiguration.KEY).change(local -> local.changeBaseline(baseline -> diff --git a/modules/configuration/pom.xml b/modules/configuration/pom.xml index 02e54de..e2c86ca 100644 --- a/modules/configuration/pom.xml +++ b/modules/configuration/pom.xml @@ -51,5 +51,10 @@ <groupId>org.jetbrains</groupId> <artifactId>annotations</artifactId> </dependency> + + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + </dependency> </dependencies> </project> diff --git a/modules/configuration/src/main/java/org/apache/ignite/configuration/ConfigurationChanger.java b/modules/configuration/src/main/java/org/apache/ignite/configuration/ConfigurationChanger.java index 8e628f3..0eb3465 100644 --- a/modules/configuration/src/main/java/org/apache/ignite/configuration/ConfigurationChanger.java +++ b/modules/configuration/src/main/java/org/apache/ignite/configuration/ConfigurationChanger.java @@ -127,6 +127,13 @@ public final class ConfigurationChanger { } /** */ + public <A extends Annotation> void addValidators(Class<A> annotationType, Set<Validator<A, ?>> validators) { + this.validators + .computeIfAbsent(annotationType, a -> new HashSet<>()) + .addAll(validators); + } + + /** */ public void addRootKey(RootKey<?, ?> rootKey) { assert !storageInstances.containsKey(rootKey.type()); diff --git a/modules/configuration/src/main/java/org/apache/ignite/configuration/ConfigurationRegistry.java b/modules/configuration/src/main/java/org/apache/ignite/configuration/ConfigurationRegistry.java index e30f396..766714e 100644 --- a/modules/configuration/src/main/java/org/apache/ignite/configuration/ConfigurationRegistry.java +++ b/modules/configuration/src/main/java/org/apache/ignite/configuration/ConfigurationRegistry.java @@ -20,9 +20,11 @@ package org.apache.ignite.configuration; import java.io.Serializable; import java.lang.annotation.Annotation; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.function.BiFunction; import java.util.function.Function; @@ -67,21 +69,27 @@ public class ConfigurationRegistry { changer.addValidator(Max.class, new MaxValidator()); } - /** */ - public void registerRootKey(RootKey<?, ?> rootKey) { - changer.addRootKey(rootKey); - - configs.put(rootKey.key(), (DynamicConfiguration<?, ?, ?>)rootKey.createPublicRoot(changer)); - } + /** + * Constructor. + * + * @param rootKeys Configuration root keys. + * @param validators Validators. + * @param configurationStorages Configuration Storages. + */ + public <A extends Annotation> ConfigurationRegistry( + Collection<RootKey<?, ?>> rootKeys, + Map<Class<A>, Set<Validator<A, ?>>> validators, + Collection<ConfigurationStorage> configurationStorages + ) { + rootKeys.forEach(rootKey -> + { + changer.addRootKey(rootKey); + configs.put(rootKey.key(), (DynamicConfiguration<?, ?, ?>)rootKey.createPublicRoot(changer)); + }); - /** */ - public <A extends Annotation> void registerValidator(Class<A> annotationType, Validator<A, ?> validator) { - changer.addValidator(annotationType, validator); - } + validators.forEach(changer::addValidators); - /** */ - public void registerStorage(ConfigurationStorage configurationStorage) { - changer.register(configurationStorage); + configurationStorages.forEach(changer::register); } /** */ diff --git a/modules/configuration/src/main/java/org/apache/ignite/configuration/internal/ConfigurationManager.java b/modules/configuration/src/main/java/org/apache/ignite/configuration/internal/ConfigurationManager.java new file mode 100644 index 0000000..46e3b17 --- /dev/null +++ b/modules/configuration/src/main/java/org/apache/ignite/configuration/internal/ConfigurationManager.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.configuration.internal; + +import java.lang.annotation.Annotation; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ExecutionException; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import org.apache.ignite.configuration.ConfigurationRegistry; +import org.apache.ignite.configuration.RootKey; +import org.apache.ignite.configuration.internal.rest.JsonConverter; +import org.apache.ignite.configuration.storage.ConfigurationStorage; +import org.apache.ignite.configuration.validation.Validator; + +/** + * Configuration manager is responsible for handling configuration lifecycle and provides configuration API. + */ +// TODO: IGNITE-14586 Remove @SuppressWarnings when implementation provided. +@SuppressWarnings("WeakerAccess") public class ConfigurationManager { + /** Configuration registry. */ + private final ConfigurationRegistry confRegistry; + + /** Set of configuration storages. */ + private final Set<ConfigurationStorage> configurationStorages; + + /** + * The constructor. + * + * @param rootKeys Configuration root keys. + * @param validators Validators. + * @param configurationStorages Configuration storages. + */ + public <A extends Annotation> ConfigurationManager( + Collection<RootKey<?, ?>> rootKeys, + Map<Class<A>, Set<Validator<A, ?>>> validators, + Collection<ConfigurationStorage> configurationStorages + ) { + this.configurationStorages = Set.copyOf(configurationStorages); + + confRegistry = new ConfigurationRegistry(rootKeys, validators, configurationStorages); + } + + /** + * Constructor. + * + * @param rootKeys Configuration root keys. + * @param configurationStorages Configuration storages. + */ + public ConfigurationManager( + Collection<RootKey<?, ?>> rootKeys, + Collection<ConfigurationStorage> configurationStorages + ) { + this(rootKeys, Collections.emptyMap(), configurationStorages); + } + + /** + * Bootstrap configuration manager with customer user cfg. + * @param jsonStr Customer configuration in json format. + */ + public void bootstrap(String jsonStr) throws InterruptedException, ExecutionException { + JsonObject jsonCfg = JsonParser.parseString(jsonStr).getAsJsonObject(); + + for (ConfigurationStorage configurationStorage : configurationStorages) + confRegistry.change(JsonConverter.jsonSource(jsonCfg), configurationStorage).get(); + } + + /** + * @return Configuration registry. + */ + public ConfigurationRegistry configurationRegistry() { + return confRegistry; + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java b/modules/configuration/src/main/java/org/apache/ignite/configuration/internal/rest/FormatConverter.java similarity index 64% copy from modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java copy to modules/configuration/src/main/java/org/apache/ignite/configuration/internal/rest/FormatConverter.java index 9cc76fb..d39d01b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java +++ b/modules/configuration/src/main/java/org/apache/ignite/configuration/internal/rest/FormatConverter.java @@ -15,7 +15,24 @@ * limitations under the License. */ -/** - * Common utility classes for strings. - */ -package org.apache.ignite.internal.tostring; +package org.apache.ignite.configuration.internal.rest; + +import java.io.Reader; + +/** */ +public interface FormatConverter { + /** */ + String convertTo(Object obj); + + /** */ + String convertTo(String rootName, Object obj); + + /** */ + String rootName(String source); + + /** */ + Object convertFrom(String source, String rootName, Class<?> clazz); + + /** */ + <T> T convertFrom(Reader source, String rootName, Class<T> clazz); +} diff --git a/modules/configuration/src/main/java/org/apache/ignite/configuration/internal/rest/JsonConverter.java b/modules/configuration/src/main/java/org/apache/ignite/configuration/internal/rest/JsonConverter.java new file mode 100644 index 0000000..83d6571 --- /dev/null +++ b/modules/configuration/src/main/java/org/apache/ignite/configuration/internal/rest/JsonConverter.java @@ -0,0 +1,356 @@ +/* + * 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.configuration.internal.rest; + +import java.io.Serializable; +import java.lang.reflect.Array; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonNull; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import org.apache.ignite.configuration.tree.ConfigurationSource; +import org.apache.ignite.configuration.tree.ConfigurationVisitor; +import org.apache.ignite.configuration.tree.ConstructableTreeNode; +import org.apache.ignite.configuration.tree.InnerNode; +import org.apache.ignite.configuration.tree.NamedListNode; +import org.jetbrains.annotations.NotNull; + +import static org.apache.ignite.configuration.internal.util.ConfigurationUtil.join; + +public class JsonConverter { + /** */ + public static ConfigurationVisitor<JsonElement> jsonVisitor() { + return new ConfigurationVisitor<JsonElement>() { + /** */ + private final Deque<JsonObject> jsonObjectsStack = new ArrayDeque<>(); + + /** {@inheritDoc} */ + @Override public JsonElement visitLeafNode(String key, Serializable val) { + JsonElement jsonLeaf = toJsonLeaf(val); + + addToParent(key, jsonLeaf); + + return jsonLeaf; + } + + /** {@inheritDoc} */ + @Override public JsonElement visitInnerNode(String key, InnerNode node) { + JsonObject innerJsonNode = new JsonObject(); + + jsonObjectsStack.push(innerJsonNode); + + node.traverseChildren(this); + + jsonObjectsStack.pop(); + + addToParent(key, innerJsonNode); + + return innerJsonNode; + } + + /** {@inheritDoc} */ + @Override public <N extends InnerNode> JsonElement visitNamedListNode(String key, NamedListNode<N> node) { + JsonObject namedListJsonNode = new JsonObject(); + + jsonObjectsStack.push(namedListJsonNode); + + for (String subkey : node.namedListKeys()) + node.get(subkey).accept(subkey, this); + + jsonObjectsStack.pop(); + + addToParent(key, namedListJsonNode); + + return namedListJsonNode; + } + + /** */ + @NotNull private JsonElement toJsonLeaf(Serializable val) { + if (val == null) + return JsonNull.INSTANCE; + + Class<? extends Serializable> valClass = val.getClass(); + + if (!valClass.isArray()) + return toJsonPrimitive(val); + + int size = Array.getLength(val); + + JsonArray jsonArray = new JsonArray(size); + + for (int idx = 0; idx < size; idx++) + jsonArray.add(toJsonPrimitive(Array.get(val, idx))); + + return jsonArray; + } + + /** */ + @NotNull private JsonElement toJsonPrimitive(Object val) { + if (val == null) + return JsonNull.INSTANCE; + + if (val instanceof Boolean) + return new JsonPrimitive((Boolean)val); + + if (val instanceof String) + return new JsonPrimitive((String)val); + + assert val instanceof Number : val.getClass(); + + return new JsonPrimitive((Number)val); + } + + /** + * Add subelement to the paretn JSON object if it exists. + * + * @param key Key for the passed JSON element. + * @param jsonElement JSON element to add to the parent. + */ + private void addToParent(String key, JsonElement jsonElement) { + if (!jsonObjectsStack.isEmpty()) + jsonObjectsStack.peek().add(key, jsonElement); + } + }; + } + + /** + * @param jsonElement JSON that has to be converted to the configuration source. + * @return JSON-based configuration source. + */ + public static ConfigurationSource jsonSource(JsonElement jsonElement) { + if (!jsonElement.isJsonObject()) + throw new IllegalArgumentException("JSON object is expected as a configuration source"); + + return new JsonObjectConfigurationSource(new ArrayList<>(), jsonElement.getAsJsonObject()); + } + + private static class JsonObjectConfigurationSource implements ConfigurationSource { + /** */ + private final List<String> path; + + /** */ + private final JsonObject jsonObject; + + private JsonObjectConfigurationSource(List<String> path, JsonObject jsonObject) { + this.path = path; + this.jsonObject = jsonObject; + } + + /** {@inheritDoc} */ + @Override public <T> T unwrap(Class<T> clazz) { + throw new IllegalArgumentException( + "'" + clazz.getSimpleName() + "' is expected as a type for '" + + join(path) + "' configuration value" + ); + } + + /** {@inheritDoc} */ + @Override public void descend(ConstructableTreeNode node) { + for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) { + String key = entry.getKey(); + + JsonElement jsonElement = entry.getValue(); + + try { + if (jsonElement.isJsonArray() || jsonElement.isJsonPrimitive()) { + List<String> path = new ArrayList<>(this.path.size() + 1); + path.addAll(this.path); + path.add(key); + + node.construct(key, new JsonPrimitiveConfigurationSource(path, jsonElement)); + } + else if (jsonElement.isJsonNull()) { + node.construct(key, null); + } + else { + assert jsonElement.isJsonObject(); + + List<String> path = new ArrayList<>(this.path.size() + 1); + path.addAll(this.path); + path.add(key); + + node.construct(key, new JsonObjectConfigurationSource(path, jsonElement.getAsJsonObject())); + } + } + catch (NoSuchElementException e) { + if (path.isEmpty()) { + throw new IllegalArgumentException( + "'" + key + "' configuration root doesn't exist" + ); + } + else { + throw new IllegalArgumentException( + "'" + join(path) + "' configuration doesn't have '" + key + "' subconfiguration" + ); + } + } + } + } + } + + private static class JsonPrimitiveConfigurationSource implements ConfigurationSource { + private final List<String> path; + + private final JsonElement jsonLeaf; + + private JsonPrimitiveConfigurationSource(List<String> path, JsonElement jsonLeaf) { + assert !path.isEmpty(); + + this.path = path; + this.jsonLeaf = jsonLeaf; + } + + /** {@inheritDoc} */ + @Override public <T> T unwrap(Class<T> clazz) { + if (clazz.isArray()) { + if (!jsonLeaf.isJsonArray()) + throw wrongTypeException(clazz, -1); + + JsonArray jsonArray = jsonLeaf.getAsJsonArray(); + int size = jsonArray.size(); + + Class<?> componentType = clazz.getComponentType(); + Class<?> boxedComponentType = box(componentType); + + Object resArray = Array.newInstance(componentType, size); + + for (int idx = 0; idx < size; idx++) { + JsonElement element = jsonArray.get(idx); + + if (!element.isJsonPrimitive()) + throw wrongTypeException(boxedComponentType, idx); + + Array.set(resArray, idx, unwrap(element.getAsJsonPrimitive(), boxedComponentType, idx)); + } + + return (T)resArray; + } + else { + if (jsonLeaf.isJsonArray()) + throw wrongTypeException(clazz, -1); + + return unwrap(jsonLeaf.getAsJsonPrimitive(), clazz, -1); + } + } + + /** {@inheritDoc} */ + @Override public void descend(ConstructableTreeNode node) { + throw new IllegalArgumentException( + "'" + join(path) + "' is expected to be a composite configuration node, not a single value" + ); + } + + @NotNull private <T> IllegalArgumentException wrongTypeException(Class<T> clazz, int idx) { + return new IllegalArgumentException( + "'" + unbox(clazz).getSimpleName() + "' is expected as a type for '" + + join(path) + (idx == -1 ? "" : ("[" + idx + "]")) + "' configuration value" + ); + } + + /** + * @param clazz Class object. + * @return Same object of it doesn't represent primitive class, boxed version otherwise. + */ + private static Class<?> box(Class<?> clazz) { + if (!clazz.isPrimitive()) + return clazz; + + switch (clazz.getName()) { + case "boolean": + return Boolean.class; + + case "int": + return Integer.class; + + case "long": + return Long.class; + + default: + assert clazz == double.class; + + return Double.class; + } + } + + private static Class<?> unbox(Class<?> clazz) { + assert !clazz.isPrimitive(); + + if (clazz == Boolean.class) + return boolean.class; + else if (clazz == Integer.class) + return int.class; + else if (clazz == Long.class) + return long.class; + else if (clazz == Double.class) + return double.class; + else + return clazz; + } + + private <T> T unwrap(JsonPrimitive jsonPrimitive, Class<T> clazz, int idx) { + assert !clazz.isArray(); + assert !clazz.isPrimitive(); + + if (clazz == String.class) { + if (!jsonPrimitive.isString()) + throw wrongTypeException(clazz, idx); + + return clazz.cast(jsonPrimitive.getAsString()); + } + + if (Number.class.isAssignableFrom(clazz)) { + if (!jsonPrimitive.isNumber()) + throw wrongTypeException(clazz, idx); + + if (clazz == Double.class) + return clazz.cast(jsonPrimitive.getAsDouble()); + + if (clazz == Long.class) + return clazz.cast(jsonPrimitive.getAsLong()); + + assert clazz == Integer.class; + + long longValue = jsonPrimitive.getAsLong(); + + if (longValue < Integer.MIN_VALUE || longValue > Integer.MAX_VALUE) { + throw new IllegalArgumentException( + "'" + join(path) + "' has integer type" + + " and the value " + longValue + " is out of bounds" + ); + } + + return clazz.cast((int)longValue); + } + + assert clazz == Boolean.class; + + if (!jsonPrimitive.isBoolean()) + throw wrongTypeException(clazz, idx); + + return clazz.cast(jsonPrimitive.getAsBoolean()); + } + } +} + diff --git a/modules/configuration/src/main/java/org/apache/ignite/configuration/validation/Validator.java b/modules/configuration/src/main/java/org/apache/ignite/configuration/validation/Validator.java index 47b57ab..d9e422a 100644 --- a/modules/configuration/src/main/java/org/apache/ignite/configuration/validation/Validator.java +++ b/modules/configuration/src/main/java/org/apache/ignite/configuration/validation/Validator.java @@ -18,7 +18,6 @@ package org.apache.ignite.configuration.validation; import java.lang.annotation.Annotation; -import org.apache.ignite.configuration.ConfigurationRegistry; /** * Interface for all configuration validators. Recommended to be a stateless class. @@ -27,7 +26,6 @@ import org.apache.ignite.configuration.ConfigurationRegistry; * * @param <A> Type of the annotation that puts current validator to the field. * @param <VIEW> Upper bound for field types that can be validated with this validator. - * @see ConfigurationRegistry#registerValidator(Class, Validator) */ public interface Validator<A extends Annotation, VIEW> { /** diff --git a/modules/metastorage/pom.xml b/modules/metastorage/pom.xml new file mode 100644 index 0000000..d85d192 --- /dev/null +++ b/modules/metastorage/pom.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + 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. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-parent</artifactId> + <version>1</version> + <relativePath>../../parent/pom.xml</relativePath> + </parent> + + <artifactId>ignite-metastorage</artifactId> + <version>3.0.0-SNAPSHOT</version> + + <dependencies> + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-network</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-raft</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-vault</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>metastorage-client</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> +</project> diff --git a/modules/metastorage/src/main/java/org/apache/ignite/internal/metastorage/MetaStorageManager.java b/modules/metastorage/src/main/java/org/apache/ignite/internal/metastorage/MetaStorageManager.java new file mode 100644 index 0000000..d613b3e --- /dev/null +++ b/modules/metastorage/src/main/java/org/apache/ignite/internal/metastorage/MetaStorageManager.java @@ -0,0 +1,112 @@ +/* + * 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.metastorage; + +import java.util.concurrent.CompletableFuture; + +import org.apache.ignite.internal.vault.VaultManager; +import org.apache.ignite.metastorage.client.MetaStorageService; +import org.apache.ignite.metastorage.common.Key; +import org.apache.ignite.metastorage.common.WatchListener; +import org.apache.ignite.network.ClusterService; +import org.apache.ignite.internal.raft.Loza; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * MetaStorage manager is responsible for: + * <ul> + * <li>Handling cluster init message.</li> + * <li>Managing meta storage lifecycle including instantiation meta storage raft group.</li> + * <li>Providing corresponding meta storage service proxy interface</li> + * </ul> + */ +// TODO: IGNITE-14586 Remove @SuppressWarnings when implementation provided. +@SuppressWarnings({"FieldCanBeLocal", "unused", "WeakerAccess"}) public class MetaStorageManager { + /** Vault manager in order to commit processed watches with corresponding applied revision. */ + private final VaultManager vaultMgr; + + /** Cluster network service that is used in order to handle cluster init message. */ + private final ClusterService clusterNetSvc; + + /** Raft manager that is used for metastorage raft group handling. */ + private final Loza raftMgr; + + /** Meta storage service. */ + private MetaStorageService metaStorageSvc; + + /** + * The constructor. + * + * @param vaultMgr Vault manager. + * @param clusterNetSvc Cluster network service. + * @param raftMgr Raft manager. + */ + public MetaStorageManager( + VaultManager vaultMgr, + ClusterService clusterNetSvc, + Loza raftMgr + ) { + this.vaultMgr = vaultMgr; + this.clusterNetSvc = clusterNetSvc; + this.raftMgr = raftMgr; + + // TODO: IGNITE-14088: Uncomment and use real serializer factory +// Arrays.stream(MetaStorageMessageTypes.values()).forEach( +// msgTypeInstance -> net.registerMessageMapper( +// msgTypeInstance.msgType(), +// new DefaultMessageMapperProvider() +// ) +// ); + + clusterNetSvc.messagingService().addMessageHandler((message, sender, correlationId) -> { + // TODO: IGNITE-14414 Cluster initialization flow. + }); + } + + /** + * Register subscription on meta storage updates for further deployment when DMS is ready. + * + * @param key The target key. Couldn't be {@code null}. + * @param lsnr Listener which will be notified for each update. + * @return Subscription identifier. Could be used in {@link #unregisterWatch} method in order to cancel + * subscription. + */ + public synchronized CompletableFuture<Long> registerWatch(@Nullable Key key, @NotNull WatchListener lsnr) { + // TODO: IGNITE-14446 Implement DMS manager with watch registry. + return null; + } + + /** + * Unregister subscription for the given identifier. + * + * @param id Subscription identifier. + * @return Completed future in case of operation success. Couldn't be {@code null}. + */ + public synchronized CompletableFuture<Void> unregisterWatch(long id) { + // TODO: IGNITE-14446 Implement DMS manager with watch registry. + return null; + } + + /** + * Deploy all registered watches through{@code MetaStorageService.watch()}. + */ + public synchronized void deployWatches() { + // TODO: IGNITE-14446 Implement DMS manager with watch registry. + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java b/modules/metastorage/src/main/java/org/apache/ignite/internal/metastorage/network/MetaStorageMessageTypes.java similarity index 57% copy from modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java copy to modules/metastorage/src/main/java/org/apache/ignite/internal/metastorage/network/MetaStorageMessageTypes.java index 9cc76fb..6113fa0 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java +++ b/modules/metastorage/src/main/java/org/apache/ignite/internal/metastorage/network/MetaStorageMessageTypes.java @@ -15,7 +15,33 @@ * limitations under the License. */ +package org.apache.ignite.internal.metastorage.network; + /** - * Common utility classes for strings. + * Metastorage message types */ -package org.apache.ignite.internal.tostring; +// TODO: IGNITE-14088: Uncomment and use real serializer factory +//@DirectlyMarshallableTypes(moduleType = 11) +public enum MetaStorageMessageTypes { + /** */ + CLUSTER_INIT_REQUEST((short)1100); + + /** */ + private short msgType; + + /** + * Constructor. + * + * @param msgType Message type. + */ + MetaStorageMessageTypes(short msgType) { + this.msgType = msgType; + } + + /** + * @return Message type. + */ + public short msgType() { + return msgType; + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java b/modules/raft/src/main/java/org/apache/ignite/internal/raft/Loza.java similarity index 59% copy from modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java copy to modules/raft/src/main/java/org/apache/ignite/internal/raft/Loza.java index 9cc76fb..e91ff2d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java +++ b/modules/raft/src/main/java/org/apache/ignite/internal/raft/Loza.java @@ -15,7 +15,24 @@ * limitations under the License. */ +package org.apache.ignite.internal.raft; + +import org.apache.ignite.network.ClusterService; + /** - * Common utility classes for strings. + * Best raft manager ever since 1982. */ -package org.apache.ignite.internal.tostring; +// TODO: IGNITE-14586 Remove @SuppressWarnings when implementation provided. +@SuppressWarnings({"FieldCanBeLocal", "unused"}) public class Loza { + /** Cluster network service. */ + private final ClusterService clusterNetSvc; + + /** + * Constructor. + * + * @param clusterNetSvc Cluster network service. + */ + public Loza(ClusterService clusterNetSvc) { + this.clusterNetSvc = clusterNetSvc; + } +} diff --git a/modules/rest/pom.xml b/modules/rest/pom.xml index 45c6b5d..ad4a082 100644 --- a/modules/rest/pom.xml +++ b/modules/rest/pom.xml @@ -42,6 +42,12 @@ </dependency> <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-api</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </dependency> diff --git a/modules/rest/src/main/java/org/apache/ignite/rest/RestModule.java b/modules/rest/src/main/java/org/apache/ignite/rest/RestModule.java index 867bbac..91cce7f 100644 --- a/modules/rest/src/main/java/org/apache/ignite/rest/RestModule.java +++ b/modules/rest/src/main/java/org/apache/ignite/rest/RestModule.java @@ -33,9 +33,9 @@ import java.net.BindException; import java.nio.charset.StandardCharsets; import java.util.Map; import org.apache.ignite.configuration.ConfigurationRegistry; +import org.apache.ignite.configuration.schemas.rest.RestConfiguration; +import org.apache.ignite.configuration.schemas.rest.RestView; import org.apache.ignite.configuration.validation.ConfigurationValidationException; -import org.apache.ignite.rest.configuration.RestConfiguration; -import org.apache.ignite.rest.configuration.RestView; import org.apache.ignite.rest.netty.RestApiInitializer; import org.apache.ignite.rest.presentation.ConfigurationPresentation; import org.apache.ignite.rest.presentation.json.JsonPresentation; @@ -81,7 +81,6 @@ public class RestModule { */ public void prepareStart(ConfigurationRegistry sysCfg) { sysConf = sysCfg; - sysCfg.registerRootKey(RestConfiguration.KEY); presentation = new JsonPresentation(sysCfg); } diff --git a/modules/rest/src/test/java/org/apache/ignite/rest/presentation/json/JsonConverterTest.java b/modules/rest/src/test/java/org/apache/ignite/rest/presentation/json/JsonConverterTest.java index 7a60a5a..23f6bbf 100644 --- a/modules/rest/src/test/java/org/apache/ignite/rest/presentation/json/JsonConverterTest.java +++ b/modules/rest/src/test/java/org/apache/ignite/rest/presentation/json/JsonConverterTest.java @@ -18,6 +18,8 @@ package org.apache.ignite.rest.presentation.json; import com.google.gson.JsonNull; + +import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutionException; import org.apache.ignite.configuration.ConfigurationRegistry; @@ -105,7 +107,7 @@ public class JsonConverterTest { } /** */ - private final ConfigurationRegistry registry = new ConfigurationRegistry(); + private ConfigurationRegistry registry; /** */ private JsonRootConfiguration configuration; @@ -113,9 +115,11 @@ public class JsonConverterTest { /** */ @BeforeEach public void before() { - registry.registerRootKey(JsonRootConfiguration.KEY); - - registry.registerStorage(new TestConfigurationStorage()); + registry = new ConfigurationRegistry( + Collections.singletonList(JsonRootConfiguration.KEY), + Collections.emptyMap(), + Collections.singletonList(new TestConfigurationStorage()) + ); configuration = registry.getConfiguration(JsonRootConfiguration.KEY); } diff --git a/modules/runner/pom.xml b/modules/runner/pom.xml index d8c680a..cfb8626 100644 --- a/modules/runner/pom.xml +++ b/modules/runner/pom.xml @@ -43,28 +43,77 @@ <dependency> <groupId>org.apache.ignite</groupId> - <artifactId>ignite-configuration-annotation-processor</artifactId> + <artifactId>ignite-rest</artifactId> <version>${project.version}</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.ignite</groupId> - <artifactId>ignite-rest</artifactId> + <artifactId>ignite-api</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-vault</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-network</artifactId> <version>${project.version}</version> - <scope>compile</scope> </dependency> - <!-- 3rd party dependencies. --> <dependency> - <groupId>com.google.code.gson</groupId> - <artifactId>gson</artifactId> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-raft</artifactId> + <version>${project.version}</version> </dependency> <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-metastorage</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-baseline</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-affinity</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-table</artifactId> + <version>${project.version}</version> + </dependency> + + <!-- 3rd party dependencies. --> + <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> </dependency> + + <!-- Test dependencies. --> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-api</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-engine</artifactId> + <scope>test</scope> + </dependency> </dependencies> <build> diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/IgnitionTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/IgnitionTest.java new file mode 100644 index 0000000..12f4f4a --- /dev/null +++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/IgnitionTest.java @@ -0,0 +1,81 @@ +/* + * 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.runner.app; + +import java.util.ArrayList; +import java.util.List; +import org.apache.ignite.app.Ignite; +import org.apache.ignite.app.IgnitionManager; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * Ignition interface tests. + */ +class IgnitionTest { + + /** Nodes bootstrap configuration. */ + private final String[] nodesBootstrapCfg = + { + "{\n" + + " \"network\": {\n" + + " \"port\":3344,\n" + + " \"netClusterNodes\":[ \"localhost:3344\", \"localhost:3345\", \"localhost:3346\" ]\n" + + " }\n" + + "}", + + "{\n" + + " \"network\": {\n" + + " \"port\":3345,\n" + + " \"netClusterNodes\":[ \"localhost:3344\", \"localhost:3345\", \"localhost:3346\" ]\n" + + " }\n" + + "}", + + "{\n" + + " \"network\": {\n" + + " \"port\":3346,\n" + + " \"netClusterNodes\":[ \"localhost:3344\", \"localhost:3345\", \"localhost:3346\" ]\n" + + " }\n" + + "}", + }; + + /** + * Check that Ignition.start() with bootstrap configuration returns Ignite instance. + */ + @Test + void testNodesStartWithBootstrapConfiguration() { + List<Ignite> startedNodes = new ArrayList<>(); + + for (String nodeBootstrapCfg : nodesBootstrapCfg) + startedNodes.add(IgnitionManager.start(nodeBootstrapCfg)); + + Assertions.assertEquals(3, startedNodes.size()); + + startedNodes.forEach(Assertions::assertNotNull); + } + + /** + * Check that Ignition.start() with bootstrap configuration returns Ignite instance. + */ + @Test + void testNodeStartWithoutBootstrapConfiguartion() { + Ignite ignite = IgnitionManager.start(null); + + Assertions.assertNotNull(ignite); + } +} diff --git a/modules/runner/src/main/java/org/apache/ignite/app/IgniteRunner.java b/modules/runner/src/main/java/org/apache/ignite/app/IgniteRunner.java index d741fb7..61c5f9c 100644 --- a/modules/runner/src/main/java/org/apache/ignite/app/IgniteRunner.java +++ b/modules/runner/src/main/java/org/apache/ignite/app/IgniteRunner.java @@ -17,120 +17,9 @@ package org.apache.ignite.app; -import io.netty.channel.ChannelFuture; -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.Arrays; -import java.util.stream.Collectors; -import org.apache.ignite.configuration.ConfigurationModule; -import org.apache.ignite.rest.RestModule; -import org.apache.ignite.utils.IgniteProperties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** * Sample application integrating new configuration module and providing standard REST API to access and modify it. */ public class IgniteRunner { - /** */ - private static final String[] BANNER = new String[] { - "", - " # ___ __", - " ### / | ____ ____ _ _____ / /_ ___", - " # ##### / /| | / __ \\ / __ `// ___// __ \\ / _ \\", - " ### ###### / ___ | / /_/ // /_/ // /__ / / / // ___/", - " ##### ####### /_/ |_|/ .___/ \\__,_/ \\___//_/ /_/ \\___/", - " ####### ###### /_/", - " ######## #### ____ _ __ _____", - " # ######## ## / _/____ _ ____ (_)/ /_ ___ |__ /", - " #### ####### # / / / __ `// __ \\ / // __// _ \\ /_ <", - " ##### ##### _/ / / /_/ // / / // // /_ / ___/ ___/ /", - " #### ## /___/ \\__, //_/ /_//_/ \\__/ \\___/ /____/", - " ## /____/\n" - }; - - /** */ - private static final String CONF_PARAM_NAME = "--config"; - - /** */ - private static final String DFLT_CONF_FILE_NAME = "bootstrap-config.json"; - - /** */ - private static final String VER_KEY = "version"; - - /** */ - private static final Logger log = LoggerFactory.getLogger(IgniteRunner.class); - - /** - * It is possible to start application with a custom configuration in form of json file other than that in resources. - * - * To make application pick up custom configuration file its full path should be passed to arguments after key "--config". - * - * @param args Empty or providing path to custom configuration file after marker parameter "--config". - */ - public static void main(String[] args) throws IOException, InterruptedException { - ackBanner(); - - ConfigurationModule confModule = new ConfigurationModule(); - - RestModule restModule = new RestModule(log); - - BufferedReader confReader = null; - - try { - if (args != null) { - for (int i = 0; i < args.length; i++) { - if (CONF_PARAM_NAME.equals(args[i]) && i + 1 < args.length) { - confReader = new BufferedReader(new FileReader(args[i + 1])); - - break; - } - } - } - - if (confReader == null) { - confReader = new BufferedReader(new InputStreamReader( - IgniteRunner.class.getClassLoader().getResourceAsStream(DFLT_CONF_FILE_NAME))); - } - - StringBuilder bldr = new StringBuilder(); - - String str; - - while ((str = confReader.readLine()) != null) - bldr.append(str); - - restModule.prepareStart(confModule.configurationRegistry()); - - confModule.bootstrap(bldr.toString()); - } - finally { - if (confReader != null) - confReader.close(); - } - - ChannelFuture restChFut = restModule.start(); - - ackSuccessStart(); - - restChFut.sync(); - } - - /** */ - private static void ackSuccessStart() { - log.info("Apache Ignite started successfully!"); - } - - /** */ - private static void ackBanner() { - String ver = IgniteProperties.get(VER_KEY); - - String banner = Arrays - .stream(BANNER) - .collect(Collectors.joining("\n")); - - log.info(banner + '\n' + " ".repeat(22) + "Apache Ignite ver. " + ver + '\n'); - } + // TODO: IGNITE-14413 Start of Ignite node should be supported by ignite-ctl tool } diff --git a/modules/runner/src/main/java/org/apache/ignite/configuration/ConfigurationModule.java b/modules/runner/src/main/java/org/apache/ignite/configuration/ConfigurationModule.java deleted file mode 100644 index e738974..0000000 --- a/modules/runner/src/main/java/org/apache/ignite/configuration/ConfigurationModule.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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.configuration; - -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import java.util.concurrent.ExecutionException; -import org.apache.ignite.configuration.extended.LocalConfiguration; -import org.apache.ignite.rest.configuration.InMemoryConfigurationStorage; -import org.apache.ignite.rest.presentation.json.JsonConverter; - -/** - * Module is responsible for preparing configuration when module is started. - * - * Preparing configuration includes reading it from configuration file, parsing it and initializing - * {@link ConfigurationRegistry} object. - */ -@SuppressWarnings("PMD.UnusedPrivateField") -public class ConfigurationModule { - /** */ - private LocalConfiguration localConfigurator; - - /** */ - private final ConfigurationRegistry confRegistry = new ConfigurationRegistry(); - - /** - * @param jsonStr - */ - public void bootstrap(String jsonStr) throws InterruptedException { - confRegistry.registerRootKey(LocalConfiguration.KEY); - - InMemoryConfigurationStorage storage = new InMemoryConfigurationStorage(); - - confRegistry.registerStorage(storage); - - JsonObject jsonCfg = JsonParser.parseString(jsonStr).getAsJsonObject(); - - try { - confRegistry.change(JsonConverter.jsonSource(jsonCfg), storage).get(); - } - catch (ExecutionException e) { - throw new RuntimeException(e.getCause()); - } - - localConfigurator = confRegistry.getConfiguration(LocalConfiguration.KEY); - } - - /** */ - public ConfigurationRegistry configurationRegistry() { - return confRegistry; - } -} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java similarity index 54% copy from modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java copy to modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java index 9cc76fb..c60026c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java +++ b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java @@ -15,7 +15,32 @@ * limitations under the License. */ +package org.apache.ignite.internal.app; + +import org.apache.ignite.app.Ignite; +import org.apache.ignite.table.manager.TableManager; + /** - * Common utility classes for strings. + * Ignite internal implementation. */ -package org.apache.ignite.internal.tostring; +public class IgniteImpl implements Ignite { + /** Distributed table manager. */ + private final TableManager distributedTblMgr; + + /** + * @param TblMgr Table manager. + */ + IgniteImpl(TableManager TblMgr) { + this.distributedTblMgr = TblMgr; + } + + /** {@inheritDoc} */ + @Override public TableManager tableManager() { + return distributedTblMgr; + } + + /** {@inheritDoc} */ + @Override public void close() { + // TODO IGNITE-14581 Implement IgniteImpl close method. + } +} diff --git a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgnitionImpl.java b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgnitionImpl.java new file mode 100644 index 0000000..b6b2622 --- /dev/null +++ b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgnitionImpl.java @@ -0,0 +1,181 @@ +/* + * 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.app; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import org.apache.ignite.app.Ignite; +import org.apache.ignite.app.Ignition; +import org.apache.ignite.internal.baseline.BaselineManager; +import org.apache.ignite.configuration.RootKey; +import org.apache.ignite.configuration.internal.ConfigurationManager; +import org.apache.ignite.configuration.storage.ConfigurationType; +import org.apache.ignite.configuration.schemas.network.NetworkConfiguration; +import org.apache.ignite.configuration.schemas.network.NetworkView; +import org.apache.ignite.internal.affinity.AffinityManager; +import org.apache.ignite.configuration.storage.ConfigurationStorage; +import org.apache.ignite.internal.table.distributed.TableManagerImpl; +import org.apache.ignite.internal.vault.VaultManager; +import org.apache.ignite.internal.metastorage.MetaStorageManager; +import org.apache.ignite.lang.IgniteLogger; +import org.apache.ignite.network.ClusterLocalConfiguration; +import org.apache.ignite.network.ClusterService; +import org.apache.ignite.network.message.MessageSerializationRegistry; +import org.apache.ignite.network.scalecube.ScaleCubeClusterServiceFactory; +import org.apache.ignite.internal.raft.Loza; +import org.apache.ignite.internal.storage.DistributedConfigurationStorage; +import org.apache.ignite.internal.storage.LocalConfigurationStorage; +import org.apache.ignite.internal.schema.SchemaManager; +import org.apache.ignite.table.manager.TableManager; +import org.apache.ignite.utils.IgniteProperties; + +/** + * Implementation of an entry point for handling grid lifecycle. + */ +public class IgnitionImpl implements Ignition { + /** */ + private static final String[] BANNER = new String[] { + "", + " # ___ __", + " ### / | ____ ____ _ _____ / /_ ___", + " # ##### / /| | / __ \\ / __ `// ___// __ \\ / _ \\", + " ### ###### / ___ | / /_/ // /_/ // /__ / / / // ___/", + " ##### ####### /_/ |_|/ .___/ \\__,_/ \\___//_/ /_/ \\___/", + " ####### ###### /_/", + " ######## #### ____ _ __ _____", + " # ######## ## / _/____ _ ____ (_)/ /_ ___ |__ /", + " #### ####### # / / / __ `// __ \\ / // __// _ \\ /_ <", + " ##### ##### _/ / / /_/ // / / // // /_ / ___/ ___/ /", + " #### ## /___/ \\__, //_/ /_//_/ \\__/ \\___/ /____/", + " ## /____/\n" + }; + + /** */ + private static final String VER_KEY = "version"; + + /** */ + private static final IgniteLogger LOG = IgniteLogger.forClass(IgnitionImpl.class); + + /** {@inheritDoc} */ + @Override public synchronized Ignite start(String jsonStrBootstrapCfg) { + ackBanner(); + + // Vault Component startup. + VaultManager vaultMgr = new VaultManager(); + + boolean cfgBootstrappedFromPds = vaultMgr.bootstrapped(); + + List<RootKey<?, ?>> rootKeys = new ArrayList<>(Collections.singletonList(NetworkConfiguration.KEY)); + + List<ConfigurationStorage> configurationStorages = + new ArrayList<>(Collections.singletonList(new LocalConfigurationStorage(vaultMgr))); + + // Bootstrap local configuration manager. + ConfigurationManager locConfigurationMgr = new ConfigurationManager(rootKeys, configurationStorages); + + if (!cfgBootstrappedFromPds && jsonStrBootstrapCfg != null) + try { + locConfigurationMgr.bootstrap(jsonStrBootstrapCfg); + } + catch (Exception e) { + LOG.warn("Unable to parse user specific configuration, default configuration will be used", e); + } + else if (jsonStrBootstrapCfg != null) + LOG.warn("User specific configuration will be ignored, cause vault was bootstrapped with pds configuration"); + else + locConfigurationMgr.configurationRegistry().startStorageConfigurations(ConfigurationType.LOCAL); + + NetworkView netConfigurationView = + locConfigurationMgr.configurationRegistry().getConfiguration(NetworkConfiguration.KEY).value(); + + var serializationRegistry = new MessageSerializationRegistry(); + + // Network startup. + ClusterService clusterNetSvc = new ScaleCubeClusterServiceFactory().createClusterService( + new ClusterLocalConfiguration( + "Node" + netConfigurationView.port(), + netConfigurationView.port(), + Arrays.asList(netConfigurationView.netClusterNodes()), + serializationRegistry + ) + ); + + // Raft Component startup. + Loza raftMgr = new Loza(clusterNetSvc); + + // MetaStorage Component startup. + MetaStorageManager metaStorageMgr = new MetaStorageManager( + vaultMgr, + clusterNetSvc, + raftMgr + ); + + // TODO IGNITE-14578 Bootstrap configuration manager with distributed configuration. + configurationStorages.add(new DistributedConfigurationStorage(metaStorageMgr)); + + // Start configuration manager. + ConfigurationManager configurationMgr = new ConfigurationManager(rootKeys, configurationStorages); + + // Baseline manager startup. + BaselineManager baselineMgr = new BaselineManager(configurationMgr, metaStorageMgr, clusterNetSvc); + + // Affinity manager startup. + new AffinityManager(configurationMgr, metaStorageMgr, baselineMgr); + + SchemaManager schemaMgr = new SchemaManager(configurationMgr); + + // Distributed table manager startup. + TableManager distributedTblMgr = new TableManagerImpl( + configurationMgr, + clusterNetSvc, + metaStorageMgr, + schemaMgr, + raftMgr + ); + + // TODO IGNITE-14579 Start rest manager. + + // Deploy all resisted watches cause all components are ready and have registered their listeners. + metaStorageMgr.deployWatches(); + + clusterNetSvc.start(); + + ackSuccessStart(); + + return new IgniteImpl(distributedTblMgr); + } + + /** */ + private static void ackSuccessStart() { + LOG.info("Apache Ignite started successfully!"); + } + + /** */ + private static void ackBanner() { + String ver = IgniteProperties.get(VER_KEY); + + String banner = Arrays + .stream(BANNER) + .collect(Collectors.joining("\n")); + + LOG.info(banner + '\n' + " ".repeat(22) + "Apache Ignite ver. " + ver + '\n'); + } +} diff --git a/modules/runner/src/main/java/org/apache/ignite/internal/storage/DistributedConfigurationStorage.java b/modules/runner/src/main/java/org/apache/ignite/internal/storage/DistributedConfigurationStorage.java new file mode 100644 index 0000000..9d53731 --- /dev/null +++ b/modules/runner/src/main/java/org/apache/ignite/internal/storage/DistributedConfigurationStorage.java @@ -0,0 +1,104 @@ +/* + * 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.storage; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.AtomicLong; +import org.apache.ignite.configuration.storage.ConfigurationStorage; +import org.apache.ignite.configuration.storage.ConfigurationStorageListener; +import org.apache.ignite.configuration.storage.ConfigurationType; +import org.apache.ignite.configuration.storage.Data; +import org.apache.ignite.configuration.storage.StorageException; +import org.apache.ignite.internal.metastorage.MetaStorageManager; + +/** + * Distributed configuration storage. + */ +// TODO: IGNITE-14586 Remove @SuppressWarnings when implementation provided. +@SuppressWarnings({"FieldCanBeLocal", "unused"}) public class DistributedConfigurationStorage implements ConfigurationStorage { + /** MetaStorage manager */ + private final MetaStorageManager metaStorageMgr; + + /** + * Constructor. + * + * @param metaStorageMgr MetaStorage Manager. + */ + public DistributedConfigurationStorage(MetaStorageManager metaStorageMgr) { + this.metaStorageMgr = metaStorageMgr; + } + + /** Map to store values. */ + private Map<String, Serializable> map = new ConcurrentHashMap<>(); + + /** Change listeners. */ + private List<ConfigurationStorageListener> listeners = new CopyOnWriteArrayList<>(); + + /** Storage version. */ + private AtomicLong version = new AtomicLong(0); + + /** {@inheritDoc} */ + @Override public synchronized Data readAll() throws StorageException { + return new Data(new HashMap<>(map), version.get(), 0); + } + + /** {@inheritDoc} */ + @Override public synchronized CompletableFuture<Boolean> write(Map<String, Serializable> newValues, long version) { + if (version != this.version.get()) + return CompletableFuture.completedFuture(false); + + for (Map.Entry<String, Serializable> entry : newValues.entrySet()) { + if (entry.getValue() != null) + map.put(entry.getKey(), entry.getValue()); + else + map.remove(entry.getKey()); + } + + this.version.incrementAndGet(); + + listeners.forEach(listener -> listener.onEntriesChanged(new Data(newValues, this.version.get(), 0))); + + return CompletableFuture.completedFuture(true); + } + + /** {@inheritDoc} */ + @Override public void addListener(ConfigurationStorageListener listener) { + listeners.add(listener); + } + + /** {@inheritDoc} */ + @Override public void removeListener(ConfigurationStorageListener listener) { + listeners.remove(listener); + } + + /** {@inheritDoc} */ + @Override public void notifyApplied(long storageRevision) { + // No-op. + } + + /** {@inheritDoc} */ + @Override public ConfigurationType type() { + return ConfigurationType.DISTRIBUTED; + } +} diff --git a/modules/runner/src/main/java/org/apache/ignite/internal/storage/LocalConfigurationStorage.java b/modules/runner/src/main/java/org/apache/ignite/internal/storage/LocalConfigurationStorage.java new file mode 100644 index 0000000..eb99781 --- /dev/null +++ b/modules/runner/src/main/java/org/apache/ignite/internal/storage/LocalConfigurationStorage.java @@ -0,0 +1,104 @@ +/* + * 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.storage; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.AtomicLong; +import org.apache.ignite.configuration.storage.ConfigurationStorage; +import org.apache.ignite.configuration.storage.ConfigurationStorageListener; +import org.apache.ignite.configuration.storage.ConfigurationType; +import org.apache.ignite.configuration.storage.Data; +import org.apache.ignite.configuration.storage.StorageException; +import org.apache.ignite.internal.vault.VaultManager; + +/** + * Local configuration storage. + */ +// TODO: IGNITE-14586 Remove @SuppressWarnings when implementation provided. +@SuppressWarnings({"FieldCanBeLocal", "unused"}) public class LocalConfigurationStorage implements ConfigurationStorage { + /** Vault manager. */ + private final VaultManager vaultMgr; + + /** + * Constructor. + * + * @param vaultMgr Vault manager. + */ + public LocalConfigurationStorage(VaultManager vaultMgr) { + this.vaultMgr = vaultMgr; + } + + /** Map to store values. */ + private Map<String, Serializable> map = new ConcurrentHashMap<>(); + + /** Change listeners. */ + private List<ConfigurationStorageListener> listeners = new CopyOnWriteArrayList<>(); + + /** Storage version. */ + private AtomicLong version = new AtomicLong(0); + + /** {@inheritDoc} */ + @Override public synchronized Data readAll() throws StorageException { + return new Data(new HashMap<>(map), version.get(), 0); + } + + /** {@inheritDoc} */ + @Override public synchronized CompletableFuture<Boolean> write(Map<String, Serializable> newValues, long version) { + if (version != this.version.get()) + return CompletableFuture.completedFuture(false); + + for (Map.Entry<String, Serializable> entry : newValues.entrySet()) { + if (entry.getValue() != null) + map.put(entry.getKey(), entry.getValue()); + else + map.remove(entry.getKey()); + } + + this.version.incrementAndGet(); + + listeners.forEach(listener -> listener.onEntriesChanged(new Data(newValues, this.version.get(), 0))); + + return CompletableFuture.completedFuture(true); + } + + /** {@inheritDoc} */ + @Override public void addListener(ConfigurationStorageListener listener) { + listeners.add(listener); + } + + /** {@inheritDoc} */ + @Override public void removeListener(ConfigurationStorageListener listener) { + listeners.remove(listener); + } + + /** {@inheritDoc} */ + @Override public void notifyApplied(long storageRevision) { + // No-op. + } + + /** {@inheritDoc} */ + @Override public ConfigurationType type() { + return ConfigurationType.LOCAL; + } +} diff --git a/modules/runner/src/main/resources/META-INF/services/org.apache.ignite.app.Ignition b/modules/runner/src/main/resources/META-INF/services/org.apache.ignite.app.Ignition new file mode 100644 index 0000000..d54df30 --- /dev/null +++ b/modules/runner/src/main/resources/META-INF/services/org.apache.ignite.app.Ignition @@ -0,0 +1 @@ +org.apache.ignite.internal.app.IgnitionImpl \ No newline at end of file diff --git a/modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java b/modules/schema/src/main/java/org/apache/ignite/internal/schema/SchemaManager.java similarity index 54% copy from modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java copy to modules/schema/src/main/java/org/apache/ignite/internal/schema/SchemaManager.java index 9cc76fb..f5831c4 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java +++ b/modules/schema/src/main/java/org/apache/ignite/internal/schema/SchemaManager.java @@ -15,7 +15,24 @@ * limitations under the License. */ +package org.apache.ignite.internal.schema; + +import org.apache.ignite.configuration.internal.ConfigurationManager; + /** - * Common utility classes for strings. + * Schema Manager. */ -package org.apache.ignite.internal.tostring; +// TODO: IGNITE-14586 Remove @SuppressWarnings when implementation provided. +@SuppressWarnings({"FieldCanBeLocal", "unused"}) public class SchemaManager { + /** Configuration manager in order to handle and listen schema specific configuration.*/ + private final ConfigurationManager configurationMgr; + + /** + * The constructor. + * + * @param configurationMgr Configuration manager. + */ + public SchemaManager(ConfigurationManager configurationMgr) { + this.configurationMgr = configurationMgr; + } +} diff --git a/modules/table/pom.xml b/modules/table/pom.xml index 1f58901..553d2b1 100644 --- a/modules/table/pom.xml +++ b/modules/table/pom.xml @@ -54,6 +54,37 @@ <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-metastorage</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-baseline</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-network</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-schema</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-raft</artifactId> + <version>${project.version}</version> + </dependency> + + <!-- Test dependencies --> <dependency> <groupId>org.junit.jupiter</groupId> diff --git a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManagerImpl.java b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManagerImpl.java new file mode 100644 index 0000000..5932ea1 --- /dev/null +++ b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/TableManagerImpl.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 + * + * 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.table.distributed; + +import org.apache.ignite.configuration.internal.ConfigurationManager; +import org.apache.ignite.internal.metastorage.MetaStorageManager; +import org.apache.ignite.network.ClusterService; +import org.apache.ignite.internal.schema.SchemaManager; +import org.apache.ignite.internal.raft.Loza; +import org.apache.ignite.table.manager.TableManager; + +/** + * Table Manager that handles inner table lifecycle and provide corresponding API methods. + */ +// TODO: IGNITE-14586 Remove @SuppressWarnings when implementation provided. +@SuppressWarnings({"FieldCanBeLocal", "unused"}) public class TableManagerImpl implements TableManager { + /** Meta storage service. */ + private final MetaStorageManager metaStorageMgr; + + /** Network cluster. */ + private final ClusterService clusterNetSvc; + + /** Schema manager. */ + private final SchemaManager schemaMgr; + + /** Configuration manager. */ + private final ConfigurationManager configurationMgr; + + /** Raft manager. */ + private final Loza raftMgr; + + /** + * The constructor. + * + * @param configurationMgr Configuration table. + * @param clusterNetSvc Cluster network service. + * @param metaStorageMgr MetaStorage manager. + * @param schemaMgr Schema manager. + * @param raftMgr Raft manager. + */ + public TableManagerImpl( + ConfigurationManager configurationMgr, + ClusterService clusterNetSvc, + MetaStorageManager metaStorageMgr, + SchemaManager schemaMgr, + Loza raftMgr + ) { + this.configurationMgr = configurationMgr; + this.clusterNetSvc = clusterNetSvc; + this.metaStorageMgr = metaStorageMgr; + this.schemaMgr = schemaMgr; + this.raftMgr = raftMgr; + } +} diff --git a/modules/api/pom.xml b/modules/vault/pom.xml similarity index 78% copy from modules/api/pom.xml copy to modules/vault/pom.xml index 2ca3c60..48ab776 100644 --- a/modules/api/pom.xml +++ b/modules/vault/pom.xml @@ -17,8 +17,10 @@ limitations under the License. --> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +<!-- + POM file. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> @@ -29,13 +31,6 @@ <relativePath>../../parent/pom.xml</relativePath> </parent> - <artifactId>ignite-api</artifactId> + <artifactId>ignite-vault</artifactId> <version>3.0.0-SNAPSHOT</version> - - <dependencies> - <dependency> - <groupId>org.jetbrains</groupId> - <artifactId>annotations</artifactId> - </dependency> - </dependencies> </project> diff --git a/modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java b/modules/vault/src/main/java/org/apache/ignite/internal/vault/VaultManager.java similarity index 61% rename from modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java rename to modules/vault/src/main/java/org/apache/ignite/internal/vault/VaultManager.java index 9cc76fb..f3d7f48 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/tostring/package-info.java +++ b/modules/vault/src/main/java/org/apache/ignite/internal/vault/VaultManager.java @@ -15,7 +15,20 @@ * limitations under the License. */ +package org.apache.ignite.internal.vault; + /** - * Common utility classes for strings. + * VaultManager is responsible for handling VaultService lifecycle and providing interface for managing local keys. */ -package org.apache.ignite.internal.tostring; +public class VaultManager { + + /** + * @return {@code true} if VaultService beneath given VaultManager was bootstrapped with data + * either from PDS or from user initial bootstrap configuration. + */ + public boolean bootstrapped() { + return false; + } + + // TODO: IGNITE-14405 Local persistent key-value storage (Vault). +} diff --git a/parent/pom.xml b/parent/pom.xml index d0cd6ea..aa2f3d5 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -634,6 +634,7 @@ <exclude>**/*.iml</exclude> <!-- IntelliJ IDEA project files --> <exclude>modules/bytecode/src/main/java/com/facebook/presto/bytecode/ClassInfo.java</exclude> <!-- MIT license. --> <exclude>modules/bytecode/src/main/java/com/facebook/presto/bytecode/ClassInfoLoader.java</exclude> <!-- MIT license. --> + <exclude>**/META-INF/services/**</exclude> <!-- Interface mappings: cannot be changed --> </excludes> </configuration> </plugin> diff --git a/pom.xml b/pom.xml index 9612a10..4aee2ca 100644 --- a/pom.xml +++ b/pom.xml @@ -41,6 +41,7 @@ <module>modules/configuration</module> <module>modules/configuration-annotation-processor</module> <module>modules/core</module> + <module>modules/metastorage</module> <module>modules/metastorage-client</module> <module>modules/metastorage-common</module> <module>modules/network</module> @@ -50,6 +51,9 @@ <module>modules/runner</module> <module>modules/schema</module> <module>modules/table</module> + <module>modules/vault</module> + <module>modules/baseline</module> + <module>modules/affinity</module> </modules> <build>