This is an automated email from the ASF dual-hosted git repository. sergeychugunov 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 edc458e IGNITE-13718 IgniteRunner application integrating configuration module and using it to configure REST API edc458e is described below commit edc458ee886d40fb82d7ae3bce3adac92c8ef1da Author: Sergey Chugunov <sergey.chugu...@gmail.com> AuthorDate: Thu Dec 17 16:40:49 2020 +0300 IGNITE-13718 IgniteRunner application integrating configuration module and using it to configure REST API --- modules/ignite-runner/pom.xml | 86 +++++++++++ .../java/org/apache/ignite/app/IgniteRunner.java | 101 +++++++++++++ .../ignite/configuration/ConfigurationModule.java | 82 +++++++++++ .../extended/AutoAdjustConfigurationSchema.java | 36 +++++ .../extended/BaselineConfigurationSchema.java | 29 ++++ .../extended/DataStorageConfigurationSchema.java | 37 +++++ .../extended/LocalConfigurationSchema.java | 39 +++++ .../extended/RestConfigurationSchema.java | 33 +++++ .../presentation/FormatConverter.java | 35 +++++ .../presentation/json/JsonConverter.java | 63 ++++++++ .../java/org/apache/ignite/rest/ErrorResult.java | 33 +++++ .../java/org/apache/ignite/rest/RestModule.java | 160 +++++++++++++++++++++ .../org/apache/ignite/utils/IgniteProperties.java | 75 ++++++++++ .../src/main/resources/bootstrap-config.json | 1 + .../src/main/resources/ignite.properties | 18 +++ .../src/main/resources/simplelogger.properties | 19 +++ pom.xml | 1 + 17 files changed, 848 insertions(+) diff --git a/modules/ignite-runner/pom.xml b/modules/ignite-runner/pom.xml new file mode 100644 index 0000000..b357f90 --- /dev/null +++ b/modules/ignite-runner/pom.xml @@ -0,0 +1,86 @@ +<?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. +--> + +<!-- + 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> + + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-runner</artifactId> + <version>3.0-SNAPSHOT</version> + <url>http://ignite.apache.org</url> + + <properties> + <maven.compiler.source>1.8</maven.compiler.source> + <maven.compiler.target>1.8</maven.compiler.target> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-configuration</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + <version>2.8.6</version> + </dependency> + + <dependency> + <groupId>io.javalin</groupId> + <artifactId>javalin</artifactId> + <version>3.12.0</version> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-simple</artifactId> + <version>1.7.30</version> + </dependency> + + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-configuration-annotation-processor</artifactId> + <version>${project.version}</version> + <scope>compile</scope> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + </resource> + </resources> + + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.8.1</version> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/modules/ignite-runner/src/main/java/org/apache/ignite/app/IgniteRunner.java b/modules/ignite-runner/src/main/java/org/apache/ignite/app/IgniteRunner.java new file mode 100644 index 0000000..ef197c1 --- /dev/null +++ b/modules/ignite-runner/src/main/java/org/apache/ignite/app/IgniteRunner.java @@ -0,0 +1,101 @@ +/* + * 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.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +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 CONF_PARAM_NAME = "--config"; + + /** */ + private static final String DFLT_CONF_FILE_NAME = "bootstrap-config.json"; + + /** */ + private static final String VER_KEY = "version"; + + /** */ + private final static 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 { + ackVersion(); + + ConfigurationModule confModule = new ConfigurationModule(); + + Reader 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 FileReader(args[i + 1]); + + break; + } + } + } + + if (confReader == null) { + confReader = new InputStreamReader( + IgniteRunner.class.getClassLoader().getResourceAsStream(DFLT_CONF_FILE_NAME)); + } + + confModule.bootstrap(confReader); + } + finally { + if (confReader != null) + confReader.close(); + } + + RestModule rest = new RestModule(confModule, log); + + rest.start(); + + ackSuccessStart(); + } + + /** */ + private static void ackSuccessStart() { + log.info("Ignite application started successfully"); + } + + /** */ + private static void ackVersion() { + String ver = IgniteProperties.get(VER_KEY); + + log.info("Starting Ignite of version " + ver); + } +} diff --git a/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/ConfigurationModule.java b/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/ConfigurationModule.java new file mode 100644 index 0000000..c04f5bf --- /dev/null +++ b/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/ConfigurationModule.java @@ -0,0 +1,82 @@ +/* + * 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 java.io.Reader; +import java.io.Serializable; +import java.util.function.Consumer; + +import org.apache.ignite.configuration.extended.InitLocal; +import org.apache.ignite.configuration.extended.LocalConfigurationImpl; +import org.apache.ignite.configuration.extended.Selectors; +import org.apache.ignite.configuration.presentation.FormatConverter; +import org.apache.ignite.configuration.presentation.json.JsonConverter; +import org.apache.ignite.configuration.storage.ConfigurationStorage; + +/** + * Module is responsible for preparing configuration when module is started. + * + * Preparing configuration includes reading it from configuration file, parsing it and initializing + * {@link Configurator} object. + */ +public class ConfigurationModule { + static { + try { + Selectors.LOCAL_BASELINE_AUTO_ADJUST_ENABLED.select(null); + } + catch (Throwable ignored) { + // No-op. + } + } + + /** */ + private final ConfigurationStorage storage = new ConfigurationStorage() { + /** {@inheritDoc} */ + @Override public <T extends Serializable> void save(String propertyName, T object) { + + } + + /** {@inheritDoc} */ + @Override public <T extends Serializable> T get(String propertyName) { + return null; + } + + /** {@inheritDoc} */ + @Override public <T extends Serializable> void listen(String key, Consumer<T> listener) { + + } + }; + + /** */ + private Configurator<LocalConfigurationImpl> localConfigurator; + + /** */ + public void bootstrap(Reader confReader) { + FormatConverter converter = new JsonConverter(); + + Configurator<LocalConfigurationImpl> configurator = + Configurator.create(storage, LocalConfigurationImpl::new, converter.convertFrom(confReader, "local", InitLocal.class)); + + localConfigurator = configurator; + } + + /** */ + public Configurator<LocalConfigurationImpl> localConfigurator() { + return localConfigurator; + } +} diff --git a/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/extended/AutoAdjustConfigurationSchema.java b/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/extended/AutoAdjustConfigurationSchema.java new file mode 100644 index 0000000..c0bfaca --- /dev/null +++ b/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/extended/AutoAdjustConfigurationSchema.java @@ -0,0 +1,36 @@ +/* + * 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.extended; + + +import javax.validation.constraints.Min; +import org.apache.ignite.configuration.annotation.Config; +import org.apache.ignite.configuration.annotation.Value; + +/** */ +@Config(value = "auto_adjust") +public class AutoAdjustConfigurationSchema { + /** */ + @Value + private boolean enabled; + + /** */ + @Value + @Min(value = 0, message = "Minimum value is 0") + private int timeout; +} diff --git a/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/extended/BaselineConfigurationSchema.java b/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/extended/BaselineConfigurationSchema.java new file mode 100644 index 0000000..930c67b --- /dev/null +++ b/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/extended/BaselineConfigurationSchema.java @@ -0,0 +1,29 @@ +/* + * 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.extended; + +import org.apache.ignite.configuration.annotation.Config; +import org.apache.ignite.configuration.annotation.ConfigValue; + +/** */ +@Config +public class BaselineConfigurationSchema { + /** */ + @ConfigValue + private AutoAdjustConfigurationSchema autoAdjust; +} diff --git a/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/extended/DataStorageConfigurationSchema.java b/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/extended/DataStorageConfigurationSchema.java new file mode 100644 index 0000000..b2a3a9a --- /dev/null +++ b/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/extended/DataStorageConfigurationSchema.java @@ -0,0 +1,37 @@ +/* + * 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.extended; + +import org.apache.ignite.configuration.annotation.Config; +import org.apache.ignite.configuration.annotation.Value; + +/** */ +@Config +public class DataStorageConfigurationSchema { + /** */ + @Value + private int pageSize; + + /** */ + @Value + private String storagePath; + + /** */ + @Value + private String walPath; +} diff --git a/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/extended/LocalConfigurationSchema.java b/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/extended/LocalConfigurationSchema.java new file mode 100644 index 0000000..60a1a9f --- /dev/null +++ b/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/extended/LocalConfigurationSchema.java @@ -0,0 +1,39 @@ +/* + * 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.extended; + +import org.apache.ignite.configuration.annotation.Config; +import org.apache.ignite.configuration.annotation.ConfigValue; + +/** + * + */ +@Config(value = "local", root = true) +public class LocalConfigurationSchema { + /** */ + @ConfigValue + private RestConfigurationSchema rest; + + /** */ + @ConfigValue + private BaselineConfigurationSchema baseline; + + /** */ + @ConfigValue + private DataStorageConfigurationSchema dataStorage; +} diff --git a/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/extended/RestConfigurationSchema.java b/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/extended/RestConfigurationSchema.java new file mode 100644 index 0000000..d25c61c --- /dev/null +++ b/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/extended/RestConfigurationSchema.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.configuration.extended; + +import org.apache.ignite.configuration.annotation.Config; +import org.apache.ignite.configuration.annotation.Value; + +/** */ +@Config +public class RestConfigurationSchema { + /** */ + @Value + private int port; + + /** */ + @Value + private int portRange; +} diff --git a/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/presentation/FormatConverter.java b/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/presentation/FormatConverter.java new file mode 100644 index 0000000..6bba4cf --- /dev/null +++ b/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/presentation/FormatConverter.java @@ -0,0 +1,35 @@ +/* + * 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.presentation; + +import java.io.Reader; + +/** */ +public interface FormatConverter { + /** */ + String convertTo(Object obj); + + /** */ + String convertTo(String rootName, Object obj); + + /** */ + <T> T convertFrom(String source, String rootName, Class<T> clazz); + + /** */ + <T> T convertFrom(Reader source, String rootName, Class<T> clazz); +} diff --git a/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/presentation/json/JsonConverter.java b/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/presentation/json/JsonConverter.java new file mode 100644 index 0000000..5622e2f --- /dev/null +++ b/modules/ignite-runner/src/main/java/org/apache/ignite/configuration/presentation/json/JsonConverter.java @@ -0,0 +1,63 @@ +/* + * 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.presentation.json; + +import java.io.Reader; + +import com.google.gson.Gson; +import java.util.HashMap; +import java.util.Map; +import org.apache.ignite.configuration.presentation.FormatConverter; + +/** */ +public class JsonConverter implements FormatConverter { + /** */ + private final Gson gson = new Gson(); + + /** {@inheritDoc} */ + @Override public String convertTo(Object obj) { + return gson.toJson(obj); + } + + /** {@inheritDoc} */ + @Override public String convertTo(String rootName, Object src) { + Map<String, Object> res = new HashMap<>(); + + res.put(rootName, src); + + return gson.toJson(res); + } + + /** {@inheritDoc} */ + @Override public <T> T convertFrom(String source, String rootName, Class<T> clazz) { + Map map = gson.fromJson(source, Map.class); + + String root = gson.toJson(map.get(rootName)); + + return gson.fromJson(root, clazz); + } + + /** {@inheritDoc} */ + @Override public <T> T convertFrom(Reader source, String rootName, Class<T> clazz) { + Map map = gson.fromJson(source, Map.class); + + String root = gson.toJson(map.get(rootName)); + + return gson.fromJson(root, clazz); + } +} diff --git a/modules/ignite-runner/src/main/java/org/apache/ignite/rest/ErrorResult.java b/modules/ignite-runner/src/main/java/org/apache/ignite/rest/ErrorResult.java new file mode 100644 index 0000000..431f3d1 --- /dev/null +++ b/modules/ignite-runner/src/main/java/org/apache/ignite/rest/ErrorResult.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.rest; + +/** */ +public class ErrorResult { + /** */ + private final String type; + + /** */ + private final String message; + + /** */ + public ErrorResult(String type, String message) { + this.type = type; + this.message = message; + } +} diff --git a/modules/ignite-runner/src/main/java/org/apache/ignite/rest/RestModule.java b/modules/ignite-runner/src/main/java/org/apache/ignite/rest/RestModule.java new file mode 100644 index 0000000..4ce35ed --- /dev/null +++ b/modules/ignite-runner/src/main/java/org/apache/ignite/rest/RestModule.java @@ -0,0 +1,160 @@ +/* + * 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.rest; + +import com.google.gson.JsonSyntaxException; +import io.javalin.Javalin; +import org.apache.ignite.configuration.ConfigurationModule; +import org.apache.ignite.configuration.Configurator; +import org.apache.ignite.configuration.extended.ChangeLocal; +import org.apache.ignite.configuration.extended.Local; +import org.apache.ignite.configuration.extended.LocalConfigurationImpl; +import org.apache.ignite.configuration.extended.Selectors; +import org.apache.ignite.configuration.internal.selector.SelectorNotFoundException; +import org.apache.ignite.configuration.presentation.FormatConverter; +import org.apache.ignite.configuration.presentation.json.JsonConverter; +import org.apache.ignite.configuration.validation.ConfigurationValidationException; +import org.slf4j.Logger; + +/** + * Rest module is responsible for starting a REST endpoints for accessing and managing configuration. + * + * It is started on port 8080 by default but it is possible to change this in configuration itself. + * Refer to default config file in resources for the example. + */ +public class RestModule { + /** */ + private static final int DFLT_PORT = 8080; + + /** */ + private static final String CONF_URL = "/management/v1/configuration/"; + + /** */ + private static final String PATH_PARAM = "selector"; + + /** */ + private final ConfigurationModule confModule; + + /** */ + private final Logger log; + + /** */ + public RestModule(ConfigurationModule confModule, Logger log) { + this.confModule = confModule; + this.log = log; + } + + /** */ + public void start() { + Configurator<LocalConfigurationImpl> configurator = confModule.localConfigurator(); + + Integer port = configurator.getPublic(Selectors.LOCAL_REST_PORT); + Integer portRange = configurator.getPublic(Selectors.LOCAL_REST_PORT_RANGE); + Javalin app = null; + + if (portRange == null || portRange == 0) { + try { + app = Javalin.create().start(port != null ? port : DFLT_PORT); + } + catch (RuntimeException e) { + log.warn("Failed to start REST endpoint: ", e); + + throw e; + } + } + else { + int startPort = port; + + for (int portCandidate = startPort; portCandidate < startPort + portRange; portCandidate++) { + try { + app = Javalin.create().start(portCandidate); + } + catch (RuntimeException ignored) { + // No-op. + } + + if (app != null) + break; + } + + if (app == null) { + String msg = "Cannot start REST endpoint. " + + "All ports in range [" + startPort + ", " + (startPort + portRange) + ") are in use."; + + log.warn(msg); + + throw new RuntimeException(msg); + } + } + + log.info("REST protocol started successfully on port " + app.port()); + + FormatConverter converter = new JsonConverter(); + + app.get(CONF_URL, ctx -> { + Local local = configurator.getRoot().value(); + + ctx.result(converter.convertTo("local", local)); + }); + + app.get(CONF_URL + ":" + PATH_PARAM, ctx -> { + try { + Object subTree = configurator.getPublic(Selectors.find(ctx.pathParam(PATH_PARAM))); + + String res = converter.convertTo(subTree); + + ctx.result(res); + } + catch (SelectorNotFoundException selectorE) { + ErrorResult eRes = new ErrorResult("CONFIG_PATH_UNRECOGNIZED", selectorE.getMessage()); + + ctx.status(400).result(converter.convertTo("error", eRes)); + } + }); + + app.post(CONF_URL, ctx -> { + try { + ChangeLocal local = converter.convertFrom(ctx.body(), "local", ChangeLocal.class); + + configurator.set(Selectors.LOCAL, local); + } + catch (SelectorNotFoundException selectorE) { + ErrorResult eRes = new ErrorResult("CONFIG_PATH_UNRECOGNIZED", selectorE.getMessage()); + + ctx.status(400).result(converter.convertTo("error", eRes)); + } + catch (ConfigurationValidationException validationE) { + ErrorResult eRes = new ErrorResult("APPLICATION_EXCEPTION", validationE.getMessage()); + + ctx.status(400).result(converter.convertTo("error", eRes)); + } + catch (JsonSyntaxException e) { + String msg = e.getCause() != null ? e.getCause().getMessage() : e.getMessage(); + + ErrorResult eRes = new ErrorResult("VALIDATION_EXCEPTION", msg); + + ctx.status(400).result(converter.convertTo("error", eRes)); + } + catch (Exception e) { + ErrorResult eRes = new ErrorResult("VALIDATION_EXCEPTION", e.getMessage()); + + ctx.status(400).result(converter.convertTo("error", eRes)); + } + }); + } +} diff --git a/modules/ignite-runner/src/main/java/org/apache/ignite/utils/IgniteProperties.java b/modules/ignite-runner/src/main/java/org/apache/ignite/utils/IgniteProperties.java new file mode 100644 index 0000000..4f6766c --- /dev/null +++ b/modules/ignite-runner/src/main/java/org/apache/ignite/utils/IgniteProperties.java @@ -0,0 +1,75 @@ +/* + * 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.utils; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +/** + * Utility class to read Ignite properties from properties file. + */ +public class IgniteProperties { + /** Properties file path. */ + private static final String FILE_PATH = "ignite.properties"; + + /** Properties. */ + private static final Properties PROPS; + + /** */ + static { + PROPS = new Properties(); + + readProperties(FILE_PATH, PROPS, true); + } + + /** + * @param path Path. + * @param props Properties. + * @param throwExc Flag indicating whether to throw an exception or not. + */ + public static void readProperties(String path, Properties props, boolean throwExc) { + try (InputStream is = IgniteProperties.class.getClassLoader().getResourceAsStream(path)) { + if (is == null) { + if (throwExc) + throw new RuntimeException("Failed to find properties file: " + path); + else + return; + } + + props.load(is); + } + catch (IOException e) { + throw new RuntimeException("Failed to read properties file: " + path, e); + } + } + + /** + * Returns property value for a given key or {@code null} if nothing was found. + * + * @return Value or {@code null}. + */ + public static String get(String key) { + return PROPS.getProperty(key, ""); + } + + /** */ + private IgniteProperties() { + // No-op. + } +} diff --git a/modules/ignite-runner/src/main/resources/bootstrap-config.json b/modules/ignite-runner/src/main/resources/bootstrap-config.json new file mode 100644 index 0000000..3b29984 --- /dev/null +++ b/modules/ignite-runner/src/main/resources/bootstrap-config.json @@ -0,0 +1 @@ +{"local":{"rest":{"port":8080,"portRange":100},"baseline":{"autoAdjust":{"timeout":10000,"enabled":true}},"dataStorage": {"pageSize":4096,"storagePath":"db/data","walPath":"db/wal"}}} \ No newline at end of file diff --git a/modules/ignite-runner/src/main/resources/ignite.properties b/modules/ignite-runner/src/main/resources/ignite.properties new file mode 100644 index 0000000..4fe61e2 --- /dev/null +++ b/modules/ignite-runner/src/main/resources/ignite.properties @@ -0,0 +1,18 @@ +# +# 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. +# + +version=${pom.version} \ No newline at end of file diff --git a/modules/ignite-runner/src/main/resources/simplelogger.properties b/modules/ignite-runner/src/main/resources/simplelogger.properties new file mode 100644 index 0000000..4d52a62 --- /dev/null +++ b/modules/ignite-runner/src/main/resources/simplelogger.properties @@ -0,0 +1,19 @@ +# +# 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. +# + +org.slf4j.simpleLogger.defaultLogLevel=off +org.slf4j.simpleLogger.log.org.apache.ignite.app.IgniteRunner=info \ No newline at end of file diff --git a/pom.xml b/pom.xml index a27e525..64f2265 100644 --- a/pom.xml +++ b/pom.xml @@ -40,5 +40,6 @@ <modules> <module>modules/configuration</module> <module>modules/configuration-annotation-processor</module> + <module>modules/ignite-runner</module> </modules> </project>