From 73ed7417437faca6776208a21df1c79840c8643e Mon Sep 17 00:00:00 2001 From: Artem Labazin Date: Mon, 1 Oct 2018 20:17:40 +0300 Subject: [PATCH 01/20] Rewrite encon-config --- CHANGELOG.md | 7 + README.md | 4 +- benchmark/pom.xml | 2 +- .../benchmark/Encon_Node2NodeBenchmarks.java | 4 +- .../benchmark/Encon_SimpleBenchmarks.java | 4 +- encon-common/pom.xml | 2 +- encon-config/README.md | 4 +- encon-config/pom.xml | 19 +- .../appulse/encon/config/AbstractConfig.java | 116 +++ .../encon/config/CompressionConfig.java | 90 -- .../java/io/appulse/encon/config/Config.java | 981 ++++++++++++++++-- .../encon/config/ConfigNodeMapping.java | 190 ++++ .../io/appulse/encon/config/ConfigTree.java | 285 +++++ .../config/ConfigurationProgrammatical.java | 194 ++++ .../encon/config/ConfigurationYaml.java | 119 +++ .../io/appulse/encon/config/Defaults.java | 261 ----- .../appulse/encon/config/FieldProperty.java | 39 + .../io/appulse/encon/config/FieldUtils.java | 88 ++ .../appulse/encon/config/MailboxConfig.java | 75 -- .../io/appulse/encon/config/NodeConfig.java | 233 ----- .../io/appulse/encon/config/ServerConfig.java | 101 -- .../exception/ConfigDumpingException.java | 43 + .../exception/ConfigLoadingException.java | 43 + .../ConfigLoadingFileNotFoundException.java | 43 + .../ConfigLoadingFileParsingException.java | 43 + ...nfigLoadingMalformedFilePathException.java | 43 + ...nfigMappingEnumValueNotFoundException.java | 45 + .../exception/ConfigMappingException.java | 43 + ...nfigMappingNoMappingFunctionException.java | 48 + ...ConfigMappingUnsupportedTypeException.java | 51 + .../NoSuchMailboxHandlerException.java | 51 - encon-config/src/main/java/lombok.config | 1 + .../io/appulse/encon/config/ConfigTest.java | 662 ------------ .../io/appulse/encon/config/DumpTest.java | 122 +++ .../appulse/encon/config/GetBooleanTest.java | 66 ++ .../io/appulse/encon/config/GetByteTest.java | 55 + .../io/appulse/encon/config/GetCharTest.java} | 37 +- .../appulse/encon/config/GetDoubleTest.java | 51 + .../io/appulse/encon/config/GetFloatTest.java | 51 + .../appulse/encon/config/GetIntegerTest.java | 55 + .../io/appulse/encon/config/GetLongTest.java | 55 + .../appulse/encon/config/GetObjectTest.java | 62 ++ .../io/appulse/encon/config/GetPojoTest.java | 239 +++++ .../io/appulse/encon/config/GetShortTest.java | 55 + .../appulse/encon/config/GetStringTest.java | 44 + .../io/appulse/encon/config/LoadTest.java | 189 ++++ encon-config/src/test/resources/boolean.yml | 15 + encon-config/src/test/resources/byte.yml | 6 + encon-config/src/test/resources/char.yml | 3 + encon-config/src/test/resources/connector.yml | 48 - encon-config/src/test/resources/double.yml | 5 + .../test/resources/dump/back-file.properties | 5 + encon-config/src/test/resources/dump/file.yml | 12 + encon-config/src/test/resources/float.yml | 5 + encon-config/src/test/resources/int.yml | 6 + .../src/test/resources/load/file.properties | 10 + encon-config/src/test/resources/load/file.xml | 12 + .../src/test/resources/load/file.yaml | 12 + encon-config/src/test/resources/load/file.yml | 12 + encon-config/src/test/resources/long.yml | 6 + encon-config/src/test/resources/object.yml | 11 + encon-config/src/test/resources/pojo.yml | 25 + encon-config/src/test/resources/short.yml | 6 + encon-config/src/test/resources/string.yml | 3 + encon-databind/README.md | 8 +- encon-databind/pom.xml | 2 +- encon-handler/README.md | 4 +- encon-handler/pom.xml | 2 +- encon-spring/pom.xml | 2 +- .../encon/spring/EnconAutoConfiguration.java | 3 + .../appulse/encon/spring/EnconProperties.java | 20 +- encon-terms/pom.xml | 2 +- encon/README.md | 4 +- encon/pom.xml | 2 +- .../src/main/java/io/appulse/encon/Node.java | 50 +- .../src/main/java/io/appulse/encon/Nodes.java | 41 +- .../java/io/appulse/encon/NodesConfig.java | 284 +++++ .../test/java/io/appulse/encon/NodeTest.java | 26 +- .../test/java/io/appulse/encon/NodesTest.java | 27 +- examples/custom-queue/pom.xml | 2 +- .../encon/examples/custom/queue/Main.java | 2 +- examples/databind/pom.xml | 2 +- examples/echo-server-spring/pom.xml | 2 +- .../src/main/resources/application.yml | 8 +- .../examples/echo/server/spring/MainTest.java | 1 + examples/echo-server/pom.xml | 2 +- .../examples/echo/server/EchoClientNode.java | 2 +- .../examples/echo/server/EchoServerNode.java | 2 +- examples/handler-advanced/pom.xml | 2 +- examples/handler-basic/pom.xml | 2 +- examples/load-config-spring/pom.xml | 2 +- .../src/main/resources/application.yml | 41 +- .../examples/load/config/spring/MainTest.java | 10 +- examples/load-config/pom.xml | 2 +- .../load-config/src/main/resources/nodes.yml | 41 +- .../encon/examples/load/config/MainTest.java | 4 +- examples/pom.xml | 2 +- examples/simple/pom.xml | 2 +- .../appulse/encon/examples/simple/Main.java | 2 +- pom.xml | 10 +- 100 files changed, 4002 insertions(+), 1835 deletions(-) create mode 100644 encon-config/src/main/java/io/appulse/encon/config/AbstractConfig.java delete mode 100644 encon-config/src/main/java/io/appulse/encon/config/CompressionConfig.java create mode 100644 encon-config/src/main/java/io/appulse/encon/config/ConfigNodeMapping.java create mode 100644 encon-config/src/main/java/io/appulse/encon/config/ConfigTree.java create mode 100644 encon-config/src/main/java/io/appulse/encon/config/ConfigurationProgrammatical.java create mode 100644 encon-config/src/main/java/io/appulse/encon/config/ConfigurationYaml.java delete mode 100644 encon-config/src/main/java/io/appulse/encon/config/Defaults.java create mode 100644 encon-config/src/main/java/io/appulse/encon/config/FieldProperty.java create mode 100644 encon-config/src/main/java/io/appulse/encon/config/FieldUtils.java delete mode 100644 encon-config/src/main/java/io/appulse/encon/config/MailboxConfig.java delete mode 100644 encon-config/src/main/java/io/appulse/encon/config/NodeConfig.java delete mode 100644 encon-config/src/main/java/io/appulse/encon/config/ServerConfig.java create mode 100644 encon-config/src/main/java/io/appulse/encon/config/exception/ConfigDumpingException.java create mode 100644 encon-config/src/main/java/io/appulse/encon/config/exception/ConfigLoadingException.java create mode 100644 encon-config/src/main/java/io/appulse/encon/config/exception/ConfigLoadingFileNotFoundException.java create mode 100644 encon-config/src/main/java/io/appulse/encon/config/exception/ConfigLoadingFileParsingException.java create mode 100644 encon-config/src/main/java/io/appulse/encon/config/exception/ConfigLoadingMalformedFilePathException.java create mode 100644 encon-config/src/main/java/io/appulse/encon/config/exception/ConfigMappingEnumValueNotFoundException.java create mode 100644 encon-config/src/main/java/io/appulse/encon/config/exception/ConfigMappingException.java create mode 100644 encon-config/src/main/java/io/appulse/encon/config/exception/ConfigMappingNoMappingFunctionException.java create mode 100644 encon-config/src/main/java/io/appulse/encon/config/exception/ConfigMappingUnsupportedTypeException.java delete mode 100644 encon-config/src/main/java/io/appulse/encon/config/exception/NoSuchMailboxHandlerException.java create mode 100644 encon-config/src/main/java/lombok.config delete mode 100644 encon-config/src/test/java/io/appulse/encon/config/ConfigTest.java create mode 100644 encon-config/src/test/java/io/appulse/encon/config/DumpTest.java create mode 100644 encon-config/src/test/java/io/appulse/encon/config/GetBooleanTest.java create mode 100644 encon-config/src/test/java/io/appulse/encon/config/GetByteTest.java rename encon-config/src/{main/java/io/appulse/encon/config/ServerPortGenerator.java => test/java/io/appulse/encon/config/GetCharTest.java} (56%) create mode 100644 encon-config/src/test/java/io/appulse/encon/config/GetDoubleTest.java create mode 100644 encon-config/src/test/java/io/appulse/encon/config/GetFloatTest.java create mode 100644 encon-config/src/test/java/io/appulse/encon/config/GetIntegerTest.java create mode 100644 encon-config/src/test/java/io/appulse/encon/config/GetLongTest.java create mode 100644 encon-config/src/test/java/io/appulse/encon/config/GetObjectTest.java create mode 100644 encon-config/src/test/java/io/appulse/encon/config/GetPojoTest.java create mode 100644 encon-config/src/test/java/io/appulse/encon/config/GetShortTest.java create mode 100644 encon-config/src/test/java/io/appulse/encon/config/GetStringTest.java create mode 100644 encon-config/src/test/java/io/appulse/encon/config/LoadTest.java create mode 100644 encon-config/src/test/resources/boolean.yml create mode 100644 encon-config/src/test/resources/byte.yml create mode 100644 encon-config/src/test/resources/char.yml delete mode 100644 encon-config/src/test/resources/connector.yml create mode 100644 encon-config/src/test/resources/double.yml create mode 100644 encon-config/src/test/resources/dump/back-file.properties create mode 100644 encon-config/src/test/resources/dump/file.yml create mode 100644 encon-config/src/test/resources/float.yml create mode 100644 encon-config/src/test/resources/int.yml create mode 100644 encon-config/src/test/resources/load/file.properties create mode 100644 encon-config/src/test/resources/load/file.xml create mode 100644 encon-config/src/test/resources/load/file.yaml create mode 100644 encon-config/src/test/resources/load/file.yml create mode 100644 encon-config/src/test/resources/long.yml create mode 100644 encon-config/src/test/resources/object.yml create mode 100644 encon-config/src/test/resources/pojo.yml create mode 100644 encon-config/src/test/resources/short.yml create mode 100644 encon-config/src/test/resources/string.yml create mode 100644 encon/src/main/java/io/appulse/encon/NodesConfig.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f60d13..d49052e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Turn on checkstyle JavaDocs module. - Add updates to the protocol, like new `ControlMessage`. +## [2.0.0](https://github.com/appulse-projects/encon-java/releases/tag/2.0.0) - 2018-10-14 + +### Changed + +- Module `encon-config` now is a configuration framework for laoding, dumping and mapping different configurations and a fancy and flexible way; +- According to the new `encon-config` implementation, all configurations were moved to the appropriate modules. + ## [1.6.5](https://github.com/appulse-projects/encon-java/releases/tag/1.6.5) - 2018-09-28 ### Changed diff --git a/README.md b/README.md index 5c1c775..680b8fa 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ $> mvn clean compile [INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary: [INFO] -[INFO] encon 1.6.5 ........................................ SUCCESS [ 1.210 s] +[INFO] encon 2.0.0 ........................................ SUCCESS [ 1.210 s] [INFO] encon-common ....................................... SUCCESS [ 25.693 s] [INFO] encon-terms ........................................ SUCCESS [ 27.517 s] [INFO] encon-config ....................................... SUCCESS [ 18.707 s] @@ -64,7 +64,7 @@ $> mvn clean compile [INFO] handler-advanced ................................... SUCCESS [ 11.289 s] [INFO] load-config ........................................ SUCCESS [ 3.725 s] [INFO] load-config-spring ................................. SUCCESS [ 6.420 s] -[INFO] benchmark 1.6.5 .................................... SUCCESS [ 5.594 s] +[INFO] benchmark 2.0.0 .................................... SUCCESS [ 5.594 s] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ diff --git a/benchmark/pom.xml b/benchmark/pom.xml index 2066446..c907d95 100644 --- a/benchmark/pom.xml +++ b/benchmark/pom.xml @@ -25,7 +25,7 @@ limitations under the License. io.appulse.encon encon-parent - 1.6.5 + 2.0.0 benchmark diff --git a/benchmark/src/main/java/io/appulse/encon/benchmark/Encon_Node2NodeBenchmarks.java b/benchmark/src/main/java/io/appulse/encon/benchmark/Encon_Node2NodeBenchmarks.java index 374dbe9..0ed7a3c 100644 --- a/benchmark/src/main/java/io/appulse/encon/benchmark/Encon_Node2NodeBenchmarks.java +++ b/benchmark/src/main/java/io/appulse/encon/benchmark/Encon_Node2NodeBenchmarks.java @@ -27,8 +27,8 @@ import io.appulse.encon.Node; import io.appulse.encon.Nodes; -import io.appulse.encon.config.NodeConfig; -import io.appulse.encon.config.ServerConfig; +import io.appulse.encon.NodesConfig.NodeConfig; +import io.appulse.encon.NodesConfig.NodeConfig.ServerConfig; import io.appulse.encon.mailbox.Mailbox; import io.appulse.encon.terms.ErlangTerm; import io.appulse.encon.terms.type.ErlangPid; diff --git a/benchmark/src/main/java/io/appulse/encon/benchmark/Encon_SimpleBenchmarks.java b/benchmark/src/main/java/io/appulse/encon/benchmark/Encon_SimpleBenchmarks.java index f5072ee..c249cdb 100644 --- a/benchmark/src/main/java/io/appulse/encon/benchmark/Encon_SimpleBenchmarks.java +++ b/benchmark/src/main/java/io/appulse/encon/benchmark/Encon_SimpleBenchmarks.java @@ -25,8 +25,8 @@ import io.appulse.encon.Node; import io.appulse.encon.Nodes; -import io.appulse.encon.config.NodeConfig; -import io.appulse.encon.config.ServerConfig; +import io.appulse.encon.NodesConfig.NodeConfig; +import io.appulse.encon.NodesConfig.NodeConfig.ServerConfig; import io.appulse.encon.connection.regular.Message; import io.appulse.encon.mailbox.Mailbox; import io.appulse.encon.terms.ErlangTerm; diff --git a/encon-common/pom.xml b/encon-common/pom.xml index b41a7b9..6d3c51c 100644 --- a/encon-common/pom.xml +++ b/encon-common/pom.xml @@ -25,7 +25,7 @@ limitations under the License. io.appulse.encon encon-parent - 1.6.5 + 2.0.0 encon-common diff --git a/encon-config/README.md b/encon-config/README.md index 0e2c281..68d501a 100644 --- a/encon-config/README.md +++ b/encon-config/README.md @@ -14,7 +14,7 @@ First of all, add config's dependency: io.appulse.encon encon-config - 1.6.5 + 2.0.0 ... @@ -23,7 +23,7 @@ First of all, add config's dependency: **Gradle**: ```groovy -compile 'io.appulse.encon:encon-config:1.6.5' +compile 'io.appulse.encon:encon-config:2.0.0' ``` ### File based configuration diff --git a/encon-config/pom.xml b/encon-config/pom.xml index 71aa168..9817561 100644 --- a/encon-config/pom.xml +++ b/encon-config/pom.xml @@ -25,7 +25,7 @@ limitations under the License. io.appulse.encon encon-parent - 1.6.5 + 2.0.0 encon-config @@ -38,19 +38,10 @@ limitations under the License. provided - - io.appulse.epmd.java - client - - - ${project.groupId} - encon-common - ${project.version} - org.yaml snakeyaml - 1.21 + 1.23 @@ -64,6 +55,12 @@ limitations under the License. provided + + io.appulse + utils-java + test + + junit junit diff --git a/encon-config/src/main/java/io/appulse/encon/config/AbstractConfig.java b/encon-config/src/main/java/io/appulse/encon/config/AbstractConfig.java new file mode 100644 index 0000000..60a47de --- /dev/null +++ b/encon-config/src/main/java/io/appulse/encon/config/AbstractConfig.java @@ -0,0 +1,116 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config; + +import static io.appulse.encon.config.ConfigTree.NodeType.LIST; +import static java.nio.file.StandardOpenOption.CREATE; +import static java.util.Locale.US; +import static java.util.Optional.empty; +import static java.util.Optional.ofNullable; + +import java.io.OutputStream; +import java.io.Writer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Properties; + +import io.appulse.encon.config.ConfigTree.ConfigNode; +import io.appulse.encon.config.ConfigTree.ConfigNodeList; +import io.appulse.encon.config.ConfigTree.ConfigNodeMap; + +import lombok.Cleanup; +import lombok.NonNull; +import lombok.SneakyThrows; +import org.yaml.snakeyaml.Yaml; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +abstract class AbstractConfig implements Config { + + @Override + @SneakyThrows + public void dumpTo (@NonNull Path path) { + if (Files.notExists(path)) { + Files.createFile(path); + } + + Map map = getConfigTree().toMap(); + @Cleanup Writer writer = Files.newBufferedWriter(path, CREATE); + + String fileName = path.toString().toLowerCase(US); + if (fileName.endsWith(".yml") || fileName.endsWith(".yaml")) { + Yaml yaml = new Yaml(); + yaml.dump(map, writer); + return; + } + + Properties properties = new Properties(); + properties.putAll(map); + + if (fileName.endsWith(".properties")) { + properties.store(writer, fileName); + } else if (fileName.endsWith(".xml")) { + @Cleanup OutputStream outputStream = Files.newOutputStream(path); + properties.storeToXML(outputStream, fileName, fileName); + } else { + throw new UnsupportedOperationException("Unsupported file extension " + fileName); + } + } + + @Override + public boolean containsKey (@NonNull String key) { + return getConfigTree().containsKey(key); + } + + @Override + public Optional get (String key, @NonNull Class type) { + ConfigNode node = getConfigTree().get(key); + if (node == null) { + return empty(); + } + T result = ConfigNodeMapping.map(node, type); + return ofNullable(result); + } + + @Override + public Optional> getList (@NonNull String key, @NonNull Class type) { + ConfigNode node = getConfigTree().get(key); + if (node == null || node.getType() != LIST) { + return empty(); + } + List result = ConfigNodeMapping.toGenericList((ConfigNodeList) node, type); + return ofNullable(result); + } + + @Override + public Optional> getMap (@NonNull String key, @NonNull Class type) { + ConfigNode node = getConfigTree().get(key); + if (node == null) { + return empty(); + } + Map result = ConfigNodeMapping.toGenericMap((ConfigNodeMap) node, type); + return ofNullable(result); + } + + abstract ConfigTree getConfigTree (); +} diff --git a/encon-config/src/main/java/io/appulse/encon/config/CompressionConfig.java b/encon-config/src/main/java/io/appulse/encon/config/CompressionConfig.java deleted file mode 100644 index 8b0dee6..0000000 --- a/encon-config/src/main/java/io/appulse/encon/config/CompressionConfig.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2018 the original author or authors. - * - * Licensed 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 io.appulse.encon.config; - -import static java.util.Optional.ofNullable; -import static lombok.AccessLevel.PRIVATE; - -import java.util.Map; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import lombok.experimental.FieldDefaults; - -/** - * Protocol compression settings. - * - * @since 1.0.0 - * @author Artem Labazin - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@FieldDefaults(level = PRIVATE) -public class CompressionConfig { - - static CompressionConfig newInstance (@NonNull Map map) { - CompressionConfigBuilder builder = CompressionConfig.builder(); - - ofNullable(map.get("enabled")) - .map(Object::toString) - .map(Boolean::parseBoolean) - .ifPresent(builder::enabled); - - ofNullable(map.get("level")) - .map(Object::toString) - .map(Integer::parseInt) - .ifPresent(builder::level); - - return builder.build(); - } - - Boolean enabled; - - Integer level; - - /** - * Copy constructor. - * - * @param compressionConfig config to copy - */ - public CompressionConfig (CompressionConfig compressionConfig) { - enabled = compressionConfig.getEnabled(); - level = compressionConfig.getLevel(); - } - - /** - * Method for setting up the default values. - * - * @param defaults CompressionConfig with default values for compression - * - * @return reference to this object (for chain calls) - */ - CompressionConfig withDefaultsFrom (@NonNull CompressionConfig defaults) { - enabled = ofNullable(enabled) - .orElse(defaults.getEnabled()); - - level = ofNullable(level) - .orElse(defaults.getLevel()); - - return this; - } -} diff --git a/encon-config/src/main/java/io/appulse/encon/config/Config.java b/encon-config/src/main/java/io/appulse/encon/config/Config.java index a4a846d..1ea1c13 100644 --- a/encon-config/src/main/java/io/appulse/encon/config/Config.java +++ b/encon-config/src/main/java/io/appulse/encon/config/Config.java @@ -16,133 +16,948 @@ package io.appulse.encon.config; -import static java.util.Optional.ofNullable; +import static java.util.Locale.US; import static java.util.stream.Collectors.toMap; import java.io.File; -import java.nio.file.Files; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; import java.nio.file.Path; -import java.util.AbstractMap.SimpleEntry; +import java.nio.file.Paths; +import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Objects; +import java.util.Optional; +import java.util.Properties; + +import io.appulse.encon.config.ConfigurationProgrammatical.ConfigurationProgrammaticalBuilder; +import io.appulse.encon.config.exception.ConfigDumpingException; +import io.appulse.encon.config.exception.ConfigLoadingException; +import io.appulse.encon.config.exception.ConfigLoadingFileNotFoundException; +import io.appulse.encon.config.exception.ConfigLoadingFileParsingException; +import io.appulse.encon.config.exception.ConfigLoadingMalformedFilePathException; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; import lombok.NonNull; -import lombok.Singular; -import lombok.SneakyThrows; import lombok.val; import org.yaml.snakeyaml.Yaml; /** - * Main nodes conigs aggregator. * - * @since 1.0.0 * @author Artem Labazin + * @since 2.0.0 */ -@Data -@NoArgsConstructor -@SuppressFBWarnings("UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR") -public final class Config { +public interface Config { /** - * Loads configuration YAML file byt its path. + * Loads configuration and parses it into {@link Config} instance. + *

+ * Configuration could be present in two forms: + *

    + *
  • - YAML files. Extensions: .yml and .yaml;
  • + *
  • - property files. Extensions: .properties and .xml.
  • + *
* - * @param fileName configuration file path + * @param fileName configuration resource location. * - * @return parsed {@link Config} instance + * @return parsed {@link Config} instance. + * + * @throws ConfigLoadingFileNotFoundException if configuration resource + * is not accessible. + * + * @throws ConfigLoadingFileParsingException in case of any error + * during parsing user's map. + * + * @throws ConfigLoadingException if any error occurs + * during the resource loading. + */ + static Config load (@NonNull String fileName) { + Path path; + try { + path = Paths.get(fileName); + } catch (Exception ex) { + throw new ConfigLoadingMalformedFilePathException(ex); + } + return load(path); + } + + /** + * Loads configuration and parses it into {@link Config} instance. + *

+ * Configuration could be present in two forms: + *

    + *
  • - YAML files. Extensions: .yml and .yaml;
  • + *
  • - property files. Extensions: .properties and .xml.
  • + *
+ * + * @param file configuration resource location. + * + * @return parsed {@link Config} instance. + * + * @throws ConfigLoadingFileNotFoundException if configuration resource + * is not accessible. + * + * @throws ConfigLoadingFileParsingException in case of any error + * during parsing user's map. + * + * @throws ConfigLoadingException if any error occurs + * during the resource loading. + */ + static Config load (@NonNull File file) { + Path path; + try { + path = file.toPath(); + } catch (Exception ex) { + throw new ConfigLoadingMalformedFilePathException(ex); + } + return load(path); + } + + /** + * Loads configuration and parses it into {@link Config} instance. + *

+ * Configuration could be present in two forms: + *

    + *
  • - YAML files. Extensions: .yml and .yaml;
  • + *
  • - property files. Extensions: .properties and .xml.
  • + *
+ * + * @param path configuration resource location. + * + * @return parsed {@link Config} instance. + * + * @throws ConfigLoadingFileNotFoundException if configuration resource + * is not accessible. + * + * @throws ConfigLoadingFileParsingException in case of any error + * during parsing user's map. + * + * @throws ConfigLoadingException if any error occurs + * during the resource loading. + */ + static Config load (@NonNull Path path) { + URI uri; + try { + uri = path.toUri(); + } catch (Exception ex) { + throw new ConfigLoadingMalformedFilePathException(ex); + } + return load(uri); + } + + /** + * Loads configuration and parses it into {@link Config} instance. + *

+ * Configuration could be present in two forms: + *

    + *
  • - YAML files. Extensions: .yml and .yaml;
  • + *
  • - property files. Extensions: .properties and .xml.
  • + *
+ * + * @param uri remote or local configuration resource location. + * + * @return parsed {@link Config} instance. + * + * @throws ConfigLoadingFileNotFoundException if configuration resource + * is not accessible. + * + * @throws ConfigLoadingFileParsingException in case of any error + * during parsing user's map. + * + * @throws ConfigLoadingException if any error occurs + * during the resource loading. + */ + static Config load (@NonNull URI uri) { + URL url; + try { + url = uri.toURL(); + } catch (MalformedURLException ex) { + throw new ConfigLoadingMalformedFilePathException(ex); + } + return load(url); + } + + /** + * Loads configuration and parses it into {@link Config} instance. + *

+ * Configuration could be present in two forms: + *

    + *
  • - YAML files. Extensions: .yml and .yaml;
  • + *
  • - property files. Extensions: .properties and .xml.
  • + *
+ * + * @param url remote or local configuration resource location. + * + * @return parsed {@link Config} instance. + * + * @throws ConfigLoadingFileNotFoundException if configuration resource + * is not accessible. + * + * @throws ConfigLoadingFileParsingException in case of any error + * during parsing user's map. + * + * @throws ConfigLoadingException if any error occurs + * during the resource loading. */ - public static Config load (@NonNull String fileName) { - val file = new File(fileName); - return load(file); + static Config load (@NonNull URL url) { + InputStream inputStream; + try { + inputStream = url.openStream(); + } catch (IOException ex) { + throw new ConfigLoadingFileNotFoundException(ex); + } + + String path = url.getPath().toLowerCase(US); + try { + if (path.endsWith(".yml") || path.endsWith(".yaml")) { + Yaml yaml = new Yaml(); + Map map = yaml.load(inputStream); + return load(map); + } + + Properties properties = new Properties(); + if (path.endsWith(".properties")) { + properties.load(inputStream); + } else if (path.endsWith(".xml")) { + properties.loadFromXML(inputStream); + } else { + throw new UnsupportedOperationException("Unsupported file extension " + path); + } + return load(properties); + } catch (ConfigLoadingException ex) { + throw ex; + } catch (Exception ex) { + throw new ConfigLoadingException(ex); + } } /** - * Loads configuration YAML file byt its path. + * Parses properties {@link Map} into {@link Config} instance. * - * @param path configuration file path + * @param properties user's defined properties for parsing into + * {@link Config} instance. * * @return parsed {@link Config} instance + * + * @throws ConfigLoadingFileParsingException in case of any error + * during parsing user's map. */ - public static Config load (@NonNull Path path) { - val file = path.toFile(); - return load(file); + static Config load (@NonNull Properties properties) { + Map map = properties.entrySet() + .stream() + .collect(toMap(it -> it.getKey().toString(), Entry::getValue)); + + return load(map); } /** - * Loads configuration YAML file. + * Parses properties {@link Map} into {@link Config} instance. * - * @param file configuration file + * @param map user's defined properties for parsing into + * {@link Config} instance. * * @return parsed {@link Config} instance + * + * @throws ConfigLoadingFileParsingException in case of any error + * during parsing user's map. */ - @SuppressWarnings("unchecked") - public static Config load (@NonNull File file) { - val map = parseYaml(file); - - ConfigBuilder builder = Config.builder(); - - ofNullable(map) - .map(it -> it.get("defaults")) - .filter(Objects::nonNull) - .map(Defaults::newInstance) - .ifPresent(builder::defaults); - - ofNullable(map) - .map(it -> it.get("nodes")) - .filter(Objects::nonNull) - .map(subMap -> subMap.entrySet() - .stream() - .filter(it -> it.getValue() instanceof Map) - .collect(toMap(Entry::getKey, it -> NodeConfig.newInstance((Map) it.getValue()))) - ) - .ifPresent(builder::nodes); - - return builder.build(); - } - - @SneakyThrows - @SuppressWarnings("unchecked") - private static Map> parseYaml (@NonNull File file) { - val yaml = new Yaml(); - try (val inputStream = Files.newInputStream(file.toPath())) { - return (Map>) yaml.load(inputStream); + static Config load (@NonNull Map map) { + try { + return new ConfigurationYaml(map); + } catch (Exception ex) { + throw new ConfigLoadingFileParsingException(ex); } } - Defaults defaults; + static ConfigurationProgrammaticalBuilder builder () { + return ConfigurationProgrammatical.builder(); + } - Map nodes; + /** + * Saves {@link Config} instance state to a file. If file doesn't exist, it will be created. + * + * @param fileName destination file name. + * + * @throws ConfigDumpingException in case of IO errors. + */ + default void dumpTo (@NonNull String fileName) { + val path = Paths.get(fileName); + dumpTo(path); + } /** - * Copy constructor. + * Saves {@link Config} instance state to a file. If file doesn't exist, it will be created. * - * @param config config to copy + * @param file destination file. + * + * @throws ConfigDumpingException in case of IO errors. */ - public Config (Config config) { - defaults = ofNullable(config.getDefaults()) - .map(Defaults::new) - .orElse(null); - nodes = ofNullable(config.getNodes()) - .map(it -> it.entrySet() - .stream() - .map(entry -> new SimpleEntry<>(entry.getKey(), new NodeConfig(entry.getValue()))) - .collect(toMap(Entry::getKey, Entry::getValue)) - ) - .orElse(null); + default void dumpTo (@NonNull File file) { + val path = file.toPath(); + dumpTo(path); } - @Builder - private Config (Defaults defaults, @Singular Map nodes) { - this.defaults = ofNullable(defaults) - .orElse(Defaults.INSTANCE); + /** + * Saves {@link Config} instance state to a file. If file doesn't exist, it will be created. + * + * @param path destination path. + * + * @throws ConfigDumpingException in case of IO errors. + */ + void dumpTo (Path path) throws ConfigDumpingException; - this.nodes = nodes.entrySet() - .stream() - .peek(it -> it.getValue().withDefaultsFrom(this.defaults)) - .collect(toMap(Entry::getKey, Entry::getValue)); + /** + * Tells if specific key exists or not in {@link Config} instance. + * + * @param key option's identifier. + * + * @return {@code tru} if exists and {@code false} otherwise. + */ + boolean containsKey (String key); + + /** + * Returns parsed value of specific type from specific prefix. + * + * @param return value type. + * + * @param prefix configuration key offset. + * + * @param type return value type class. + * + * @return parsed value of specific type if key exists, empty value if not. + * + * @throws ConfigMappingUnsupportedTypeException couldn't map specified type. + * + * @throws ConfigMappingNoMappingFunctionException there is no mapping function for type. + * + * @throws ConfigMappingEnumValueNotFoundException in case of errors with {@code enum} types. + * + * @throws ConfigMappingException common mapping error. + */ + Optional get (String prefix, Class type); + + /** + * Returns parsed value of specific type from specific prefix. + * + * @param return value type. + * + * @param prefix configuration key offset. + * + * @param type return value type class. + * + * @param defaultValue default value + * + * @return parsed value of specific type if key exists, default value if not. + * + * @throws ConfigMappingUnsupportedTypeException couldn't map specified type. + * + * @throws ConfigMappingNoMappingFunctionException there is no mapping function for type. + * + * @throws ConfigMappingEnumValueNotFoundException in case of errors with {@code enum} types. + * + * @throws ConfigMappingException common mapping error. + */ + default T get (String prefix, @NonNull Class type, T defaultValue) { + return get(prefix, type).orElse(defaultValue); + } + + /** + * Returns parsed value of specific type from the root of {@link Config} tree. + * + * @param return value type. + * + * @param type return value type class. + * + * @return parsed value of specific type if exists, empty value if not. + * + * @throws ConfigMappingUnsupportedTypeException couldn't map specified type. + * + * @throws ConfigMappingNoMappingFunctionException there is no mapping function for type. + * + * @throws ConfigMappingEnumValueNotFoundException in case of errors with {@code enum} types. + * + * @throws ConfigMappingException common mapping error. + */ + default Optional get (@NonNull Class type) { + return get("", type); + } + + /** + * Returns parsed value of specific type from the root of {@link Config} tree. + * + * @param return value type. + * + * @param type return value type class. + * + * @param defaultValue default value. + * + * @return parsed value of specific type if exists, default value if not. + * + * @throws ConfigMappingUnsupportedTypeException couldn't map specified type. + * + * @throws ConfigMappingNoMappingFunctionException there is no mapping function for type. + * + * @throws ConfigMappingEnumValueNotFoundException in case of errors with {@code enum} types. + * + * @throws ConfigMappingException common mapping error. + */ + default T get (@NonNull Class type, T defaultValue) { + return get(type).orElse(defaultValue); + } + + /** + * Returns non-parsed value at specific key. + * + * @param key option's key. + * + * @return value at specific key if exists, or empty value. + * + * @throws ConfigMappingException common mapping error. + */ + default Optional get (@NonNull String key) { + return get(key, Object.class); + } + + /** + * Returns non-parsed value at specific key. + * + * @param key option's key. + * + * @param defaultValue default value. + * + * @return value at specific key if exists, or default value. + * + * @throws ConfigMappingException common mapping error. + */ + default Object get (@NonNull String key, Object defaultValue) { + return get(key).orElse(defaultValue); + } + + /** + * Returns {@link String} value at specific key. + * + * @param key option's key. + * + * @return value at specific key if exists, or empty. + * + * @throws ConfigMappingException common mapping error. + */ + default Optional getString (@NonNull String key) { + return get(key, String.class); + } + + /** + * Returns {@link String} value at specific key. + * + * @param key option's key. + * + * @param defaultValue default value. + * + * @return value at specific key if exists, or default value. + * + * @throws ConfigMappingException common mapping error. + */ + default String getString (@NonNull String key, String defaultValue) { + return getString(key).orElse(defaultValue); + } + + /** + * Returns {@link Character} value at specific key. + * + * @param key option's key. + * + * @return value at specific key if exists, or empty. + * + * @throws ConfigMappingException common mapping error. + */ + default Optional getChar (@NonNull String key) { + return get(key, Character.class); + } + + /** + * Returns {@link Character} value at specific key. + * + * @param key option's key. + * + * @param defaultValue default value. + * + * @return value at specific key if exists, or default value. + * + * @throws ConfigMappingException common mapping error. + */ + default Character getChar (@NonNull String key, Character defaultValue) { + return getChar(key).orElse(defaultValue); + } + + /** + * Returns {@link Byte} value at specific key. + * + * @param key option's key. + * + * @return value at specific key if exists, or empty. + * + * @throws ConfigMappingException common mapping error. + */ + default Optional getByte (@NonNull String key) { + return get(key, Byte.class); + } + + /** + * Returns {@link Byte} value at specific key. + * + * @param key option's key. + * + * @param defaultValue default value. + * + * @return value at specific key if exists, or default value. + * + * @throws ConfigMappingException common mapping error. + */ + default Byte getByte (@NonNull String key, Byte defaultValue) { + return getByte(key).orElse(defaultValue); + } + + /** + * Returns {@link Short} value at specific key. + * + * @param key option's key. + * + * @return value at specific key if exists, or empty. + * + * @throws ConfigMappingException common mapping error. + */ + default Optional getShort (@NonNull String key) { + return get(key, Short.class); + } + + /** + * Returns {@link Short} value at specific key. + * + * @param key option's key. + * + * @param defaultValue default value. + * + * @return value at specific key if exists, or default value. + * + * @throws ConfigMappingException common mapping error. + */ + default Short getShort (@NonNull String key, Short defaultValue) { + return getShort(key).orElse(defaultValue); + } + + /** + * Returns {@link Integer} value at specific key. + * + * @param key option's key. + * + * @return value at specific key if exists, or empty. + * + * @throws ConfigMappingException common mapping error. + */ + default Optional getInteger (@NonNull String key) { + return get(key, Integer.class); + } + + /** + * Returns {@link Integer} value at specific key. + * + * @param key option's key. + * + * @param defaultValue default value. + * + * @return value at specific key if exists, or default value. + * + * @throws ConfigMappingException common mapping error. + */ + default Integer getInteger (@NonNull String key, Integer defaultValue) { + return getInteger(key).orElse(defaultValue); + } + + /** + * Returns {@link Long} value at specific key. + * + * @param key option's key. + * + * @return value at specific key if exists, or empty. + * + * @throws ConfigMappingException common mapping error. + */ + default Optional getLong (@NonNull String key) { + return get(key, Long.class); + } + + /** + * Returns {@link Long} value at specific key. + * + * @param key option's key. + * + * @param defaultValue default value. + * + * @return value at specific key if exists, or default value. + * + * @throws ConfigMappingException common mapping error. + */ + default Long getLong (@NonNull String key, Long defaultValue) { + return getLong(key).orElse(defaultValue); + } + + /** + * Returns {@link BigInteger} value at specific key. + * + * @param key option's key. + * + * @return value at specific key if exists, or empty. + * + * @throws ConfigMappingException common mapping error. + */ + default Optional getBigInteger (@NonNull String key) { + return get(key, BigInteger.class); + } + + /** + * Returns {@link BigInteger} value at specific key. + * + * @param key option's key. + * + * @param defaultValue default value. + * + * @return value at specific key if exists, or default value. + * + * @throws ConfigMappingException common mapping error. + */ + default BigInteger getBigInteger (@NonNull String key, BigInteger defaultValue) { + return getBigInteger(key).orElse(defaultValue); + } + + /** + * Returns {@link Float} value at specific key. + * + * @param key option's key. + * + * @return value at specific key if exists, or empty. + * + * @throws ConfigMappingException common mapping error. + */ + default Optional getFloat (@NonNull String key) { + return get(key, Float.class); + } + + /** + * Returns {@link Float} value at specific key. + * + * @param key option's key. + * + * @param defaultValue default value. + * + * @return value at specific key if exists, or default value. + * + * @throws ConfigMappingException common mapping error. + */ + default Float getFloat (@NonNull String key, Float defaultValue) { + return getFloat(key).orElse(defaultValue); + } + + /** + * Returns {@link Double} value at specific key. + * + * @param key option's key. + * + * @return value at specific key if exists, or empty. + * + * @throws ConfigMappingException common mapping error. + */ + default Optional getDouble (@NonNull String key) { + return get(key, Double.class); + } + + /** + * Returns {@link Double} value at specific key. + * + * @param key option's key. + * + * @param defaultValue default value. + * + * @return value at specific key if exists, or default value. + * + * @throws ConfigMappingException common mapping error. + */ + default Double getDouble (@NonNull String key, Double defaultValue) { + return getDouble(key).orElse(defaultValue); + } + + /** + * Returns {@link BigDecimal} value at specific key. + * + * @param key option's key. + * + * @return value at specific key if exists, or empty. + * + * @throws ConfigMappingException common mapping error. + */ + default Optional getBigDecimal (@NonNull String key) { + return get(key, BigDecimal.class); + } + + /** + * Returns {@link BigDecimal} value at specific key. + * + * @param key option's key. + * + * @param defaultValue default value. + * + * @return value at specific key if exists, or default value. + * + * @throws ConfigMappingException common mapping error. + */ + default BigDecimal getBigDecimal (@NonNull String key, BigDecimal defaultValue) { + return getBigDecimal(key).orElse(defaultValue); + } + + /** + * Returns {@link Boolean} value at specific key. + * + * @param key option's key. + * + * @return value at specific key if exists, or empty. + * + * @throws ConfigMappingException common mapping error. + */ + default Optional getBoolean (@NonNull String key) { + return get(key, Boolean.class); + } + + /** + * Returns {@link Boolean} value at specific key. + * + * @param key option's key. + * + * @param defaultValue default value. + * + * @return value at specific key if exists, or default value. + * + * @throws ConfigMappingException common mapping error. + */ + default Boolean getBoolean (@NonNull String key, Boolean defaultValue) { + return getBoolean(key).orElse(defaultValue); + } + + /** + * Returns {@link List} value at specific key. + * + * @param key option's key. + * + * @return value at specific key if exists, or empty. + * + * @throws ConfigMappingException common mapping error. + */ + default Optional> getList (@NonNull String key) { + return getList(key, Object.class); + } + + /** + * Returns {@link List} value at specific key. + * + * @param key option's key. + * + * @param defaultValue default value. + * + * @return value at specific key if exists, or default value. + * + * @throws ConfigMappingException common mapping error. + */ + default List getList (@NonNull String key, List defaultValue) { + return getList(key).orElse(defaultValue); + } + + /** + * Returns {@link List} value at specific key. + * + * @param return value type. + * + * @param key option's key. + * + * @param type value's type. + * + * @return value at specific key if exists, or empty. + * + * @throws ConfigMappingUnsupportedTypeException couldn't map specified type. + * + * @throws ConfigMappingNoMappingFunctionException there is no mapping function for type. + * + * @throws ConfigMappingEnumValueNotFoundException in case of errors with {@code enum} types. + * + * @throws ConfigMappingException common mapping error. + */ + Optional> getList (@NonNull String key, @NonNull Class type); + + /** + * Returns {@link List} value at specific key. + * + * @param return value type. + * + * @param key option's key. + * + * @param type value's type. + * + * @param defaultValue default value. + * + * @return value at specific key if exists, or default value. + * + * @throws ConfigMappingUnsupportedTypeException couldn't map specified type. + * + * @throws ConfigMappingNoMappingFunctionException there is no mapping function for type. + * + * @throws ConfigMappingEnumValueNotFoundException in case of errors with {@code enum} types. + * + * @throws ConfigMappingException common mapping error. + */ + default List getList (@NonNull String key, @NonNull Class type, List defaultValue) { + return getList(key, type).orElse(defaultValue); + } + + /** + * Returns configuration root {@link Map} instance. + * + * @return value at specific key if exists, or empty. + * + * @throws ConfigMappingException common mapping error. + */ + default Optional> getRootMap () { + return getMap(""); + } + + /** + * Returns configuration root {@link Map} instance. + * + * @param defaultValue default value. + * + * @return value at specific key if exists, or default value. + * + * @throws ConfigMappingException common mapping error. + */ + default Map getRootMap (Map defaultValue) { + return getRootMap().orElse(defaultValue); + } + + /** + * Returns configuration root {@link Map} instance parsed with specific value. + * + * @param return value type. + * + * @param type value's type. + * + * @return value at specific key if exists, or empty. + * + * @throws ConfigMappingUnsupportedTypeException couldn't map specified type. + * + * @throws ConfigMappingNoMappingFunctionException there is no mapping function for type. + * + * @throws ConfigMappingEnumValueNotFoundException in case of errors with {@code enum} types. + * + * @throws ConfigMappingException common mapping error. + */ + default Optional> geRootMap (@NonNull Class type) { + return getMap("", type); + } + + /** + * Returns configuration root {@link Map} instance parsed with specific value. + * + * @param return value type. + * + * @param type value's type. + * + * @param defaultValue default value. + * + * @return value at specific key if exists, or default value. + * + * @throws ConfigMappingUnsupportedTypeException couldn't map specified type. + * + * @throws ConfigMappingNoMappingFunctionException there is no mapping function for type. + * + * @throws ConfigMappingEnumValueNotFoundException in case of errors with {@code enum} types. + * + * @throws ConfigMappingException common mapping error. + */ + default Map getRootMap (@NonNull Class type, Map defaultValue) { + return geRootMap(type).orElse(defaultValue); + } + + /** + * Returns {@link Map} value at specific key. + * + * @param key option's key. + * + * @return value at specific key if exists, or empty. + * + * @throws ConfigMappingException common mapping error. + */ + default Optional> getMap (@NonNull String key) { + return getMap(key, Object.class); + } + + /** + * Returns {@link Map} value at specific key. + * + * @param key option's key. + * + * @param defaultValue default value. + * + * @return value at specific key if exists, or default value. + * + * @throws ConfigMappingException common mapping error. + */ + default Map getMap (@NonNull String key, Map defaultValue) { + return getMap(key).orElse(defaultValue); + } + + /** + * Returns {@link Map} value at specific key. + * + * @param return value type. + * + * @param key option's key. + * + * @param type value's type. + * + * @return value at specific key if exists, or empty. + * + * @throws ConfigMappingUnsupportedTypeException couldn't map specified type. + * + * @throws ConfigMappingNoMappingFunctionException there is no mapping function for type. + * + * @throws ConfigMappingEnumValueNotFoundException in case of errors with {@code enum} types. + * + * @throws ConfigMappingException common mapping error. + */ + Optional> getMap (@NonNull String key, @NonNull Class type); + + /** + * Returns {@link Map} value at specific key. + * + * @param return value type. + * + * @param key option's key. + * + * @param type value's type. + * + * @param defaultValue default value. + * + * @return value at specific key if exists, or default value. + * + * @throws ConfigMappingUnsupportedTypeException couldn't map specified type. + * + * @throws ConfigMappingNoMappingFunctionException there is no mapping function for type. + * + * @throws ConfigMappingEnumValueNotFoundException in case of errors with {@code enum} types. + * + * @throws ConfigMappingException common mapping error. + */ + default Map getMap (@NonNull String key, @NonNull Class type, Map defaultValue) { + return getMap(key, type).orElse(defaultValue); } } diff --git a/encon-config/src/main/java/io/appulse/encon/config/ConfigNodeMapping.java b/encon-config/src/main/java/io/appulse/encon/config/ConfigNodeMapping.java new file mode 100644 index 0000000..8c03146 --- /dev/null +++ b/encon-config/src/main/java/io/appulse/encon/config/ConfigNodeMapping.java @@ -0,0 +1,190 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config; + +import static io.appulse.encon.config.ConfigTree.NodeType.LIST; +import static io.appulse.encon.config.ConfigTree.NodeType.MAP; +import static io.appulse.encon.config.ConfigTree.NodeType.VALUE; +import static java.util.Optional.ofNullable; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toSet; + +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +import io.appulse.encon.config.ConfigTree.ConfigNode; +import io.appulse.encon.config.ConfigTree.ConfigNodeList; +import io.appulse.encon.config.ConfigTree.ConfigNodeMap; +import io.appulse.encon.config.ConfigTree.ConfigNodeValue; +import io.appulse.encon.config.exception.ConfigMappingEnumValueNotFoundException; +import io.appulse.encon.config.exception.ConfigMappingException; +import io.appulse.encon.config.exception.ConfigMappingNoMappingFunctionException; +import io.appulse.encon.config.exception.ConfigMappingUnsupportedTypeException; + +import lombok.NonNull; +import lombok.SneakyThrows; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +@SuppressWarnings("unchecked") +final class ConfigNodeMapping { + + static T map (@NonNull ConfigNode node, @NonNull Class type) { + if (type == Object.class) { + return (T) node.toObject(); + } else if (type.isEnum()) { + return toEnum(node, type); + } else if (node.getType() == VALUE) { + return toSimpleType((ConfigNodeValue) node, type); + } else if (node.getType() == LIST && Collection.class.isAssignableFrom(type)) { + return toCollection(node, type); + } else if (node.getType() == MAP) { + return toMap(node, type); + } + throw new ConfigMappingUnsupportedTypeException(type); + } + + static Map toGenericMap (ConfigNodeMap node, Class valueType) { + return node.getNodes() + .entrySet() + .stream() + .collect(Collectors.toMap(Entry::getKey, it -> map(it.getValue(), valueType))); + } + + static List toGenericList (ConfigNodeList node, Class valueType) { + return node.getNodes() + .stream() + .map(it -> map(it, valueType)) + .collect(toList()); + } + + static Set toGenericSet (ConfigNodeList node, Class valueType) { + return node.getNodes() + .stream() + .map(it -> map(it, valueType)) + .collect(toSet()); + } + + private static Object fromString (ConfigNode node, Function parser) { + return ofNullable(node.toObject()) + .map(Object::toString) + .map(parser) + .orElseThrow(ConfigMappingException::new); + } + + private static T toSimpleType (@NonNull ConfigNodeValue node, @NonNull Class type) { + if (type == Object.class) { + return (T) node.toObject(); + } else if (type == Character.class || type == Character.TYPE) { + return (T) fromString(node, it -> it.toCharArray()[0]); + } else if (type == Byte.class || type == Byte.TYPE) { + return (T) fromString(node, Byte::parseByte); + } else if (type == Short.class || type == Short.TYPE) { + return (T) fromString(node, Short::parseShort); + } else if (type == Integer.class || type == Integer.TYPE) { + return (T) fromString(node, Integer::parseInt); + } else if (type == Long.class || type == Long.TYPE) { + return (T) fromString(node, Long::parseLong); + } else if (type == Float.class || type == Float.TYPE) { + return (T) fromString(node, Float::parseFloat); + } else if (type == Double.class || type == Double.TYPE) { + return (T) fromString(node, Double::parseDouble); + } else if (type == Boolean.class || type == Boolean.TYPE) { + return (T) fromString(node, it -> "yes".equalsIgnoreCase(it) || + "1".equalsIgnoreCase(it) || + Boolean.parseBoolean(it)); + } else if (type == BigInteger.class) { + return (T) fromString(node, BigInteger::new); + } else if (type == BigDecimal.class) { + return (T) fromString(node, BigDecimal::new); + } else if (type == String.class || type == CharSequence.class) { + return (T) fromString(node, it -> it); + } + throw new ConfigMappingNoMappingFunctionException(type, node.toObject().toString()); + } + + private static T toCollection (ConfigNode node, Class type) { + List list = (List) node.toObject(); + return Set.class.isAssignableFrom(type) + ? (T) list.stream().collect(toSet()) + : (T) list; + } + + @SneakyThrows + private static T toMap (ConfigNode node, Class type) { + if (Map.class.isAssignableFrom(type)) { + return (T) node.toObject(); + } + + T result = type.getConstructor().newInstance(); + Map nodes = ((ConfigNodeMap) node).getNodes(); + for (Field field : type.getDeclaredFields()) { + if (FieldUtils.isIgnored(field)) { + continue; + } + + String key = FieldUtils.getName(field); + ConfigNode leaf = nodes.get(key); + if (leaf == null) { + continue; + } + + Class fieldType = field.getType(); + Object value; + if (Map.class.isAssignableFrom(fieldType)) { + value = toGenericMap((ConfigNodeMap) leaf, FieldUtils.getGenericType(field, 1)); + } else if (Set.class.isAssignableFrom(fieldType)) { + value = toGenericSet((ConfigNodeList) leaf, FieldUtils.getGenericType(field, 0)); + } else if (Collection.class.isAssignableFrom(fieldType)) { + value = toGenericList((ConfigNodeList) leaf, FieldUtils.getGenericType(field, 0)); + } else { + value = map(leaf, fieldType); + } + + FieldUtils.setValue(result, field, value); + } + return result; + } + + private static T toEnum (ConfigNode node, Class type) { + String nodeAsString = node.toObject().toString(); + + for (Object enumObject : type.getEnumConstants()) { + Enum enumItem = (Enum) enumObject; + String name = enumItem.name(); + String toString = enumItem.toString(); + if (nodeAsString.equalsIgnoreCase(name) || nodeAsString.equalsIgnoreCase(toString)) { + return (T) enumItem; + } + } + throw new ConfigMappingEnumValueNotFoundException(type, nodeAsString); + } + + private ConfigNodeMapping () { + } +} diff --git a/encon-config/src/main/java/io/appulse/encon/config/ConfigTree.java b/encon-config/src/main/java/io/appulse/encon/config/ConfigTree.java new file mode 100644 index 0000000..af5d1c6 --- /dev/null +++ b/encon-config/src/main/java/io/appulse/encon/config/ConfigTree.java @@ -0,0 +1,285 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config; + +import static io.appulse.encon.config.ConfigTree.NodeType.LIST; +import static io.appulse.encon.config.ConfigTree.NodeType.MAP; +import static io.appulse.encon.config.ConfigTree.NodeType.UNDEFINED; +import static io.appulse.encon.config.ConfigTree.NodeType.VALUE; +import static java.util.Optional.ofNullable; +import static java.util.stream.Collectors.toList; +import static lombok.AccessLevel.PRIVATE; + +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.Deque; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.NonNull; +import lombok.Singular; +import lombok.ToString; +import lombok.Value; +import lombok.experimental.FieldDefaults; +import lombok.val; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +@ToString +@EqualsAndHashCode +@AllArgsConstructor(access = PRIVATE) +@FieldDefaults(level = PRIVATE, makeFinal = true) +class ConfigTree { + + static ConfigTree from (Map map) { + ConfigNodeMap root = processMap(map); + return new ConfigTree(root); + } + + private static ConfigNodeMap processMap (Map map) { + ConfigNodeMap.ConfigNodeMapBuilder builder = ConfigNodeMap.builder(); + map.entrySet() + .stream() + .forEach(it -> { + ConfigNode value = processValue(it.getValue()); + builder.node(it.getKey(), value); + }); + return builder.build(); + } + + private static ConfigNodeList processList (List list) { + ConfigNodeList.ConfigNodeListBuilder builder = ConfigNodeList.builder(); + list.stream() + .map(ConfigTree::processValue) + .forEach(builder::node); + + return builder.build(); + } + + @SuppressWarnings("unchecked") + private static ConfigNode processValue (Object object) { + if (object instanceof Map) { + return processMap((Map) object); + } else if (object instanceof List) { + return processList((List) object); + } + return new ConfigNodeValue(object); + } + + private static Optional> toKey (String key) { + return ofNullable(key) + .map(String::trim) + .filter(it -> !it.isEmpty()) + .map(it -> it.split("\\.")) + .map(it -> Stream.of(it) + .map(String::trim) + .filter(token -> !token.isEmpty()) + .collect(toList()) + ) + .filter(it -> !it.isEmpty()) + .map(ArrayDeque::new); + } + + @NonNull + ConfigNodeMap root; + + @SuppressWarnings("unchecked") + Map toMap () { + return (Map) root.toObject(); + } + + boolean containsKey (@NonNull String key) { + return toKey(key) + .map(root::containsKey) + .orElse(false); + } + + ConfigNode get (String key) { + return toKey(key) + .map(root::get) + .orElse(root); + } + + enum NodeType { + + VALUE, + MAP, + LIST, + UNDEFINED; + + static NodeType of (Object object) { + if (object == null) { + return UNDEFINED; + } else if (object instanceof Map) { + return MAP; + } else if (object instanceof Collection) { + return LIST; + } + return UNDEFINED; + } + } + + interface ConfigNode { + + boolean containsKey (@NonNull Deque key); + + ConfigNode get (@NonNull Deque key); + + Object toObject (); + + default NodeType getType () { + return UNDEFINED; + } + } + + @Value + static class ConfigNodeValue implements ConfigNode { + + @NonNull + Object value; + + @Override + public ConfigNode get (Deque key) { + throw new UnsupportedOperationException(""); + } + + @Override + public boolean containsKey (Deque key) { + throw new UnsupportedOperationException(""); + } + + @Override + public Object toObject () { + return value; + } + + @Override + public NodeType getType () { + return VALUE; + } + } + + @Value + @Builder + static class ConfigNodeMap implements ConfigNode { + + @Singular + Map nodes; + + @Override + public ConfigNode get (Deque key) { + val token = key.pop(); + val node = nodes.get(token); + if (node == null) { + return null; + } + return key.isEmpty() + ? node + : node.get(key); + } + + @Override + public boolean containsKey (Deque key) { + val token = key.pop(); + val node = nodes.get(token); + if (node == null) { + return false; + } + return key.isEmpty() || node.containsKey(key); + } + + @Override + public Object toObject () { + return nodes + .entrySet() + .stream() + .collect(Collectors.toMap(Entry::getKey, it -> it.getValue().toObject())); + } + + @Override + public NodeType getType () { + return MAP; + } + } + + @Value + @Builder + static class ConfigNodeList implements ConfigNode { + + private static int parseIndex (String token) { + val indexString = token.charAt(0) == '[' && token.endsWith("]") + ? token.substring(1, token.length() - 1) + : token; + try { + return Integer.parseInt(indexString); + } catch (NumberFormatException ex) { + return -1; + } + } + + @Singular + List nodes; + + @Override + public ConfigNode get (Deque key) { + val token = key.pop(); + val index = parseIndex(token); + if (index < 0 || index >= nodes.size()) { + return null; + } + + val node = nodes.get (index); + return key.isEmpty() + ? node + : node.get(key); + } + + @Override + public boolean containsKey (Deque key) { + val token = key.pop(); + val index = parseIndex(token); + if (index < 0 || index >= nodes.size()) { + return false; + } + + val node = nodes.get(index); + return key.isEmpty() || node.containsKey(key); + } + + @Override + public Object toObject () { + return nodes.stream() + .map(ConfigNode::toObject) + .collect(toList()); + } + + @Override + public NodeType getType () { + return LIST; + } + } +} diff --git a/encon-config/src/main/java/io/appulse/encon/config/ConfigurationProgrammatical.java b/encon-config/src/main/java/io/appulse/encon/config/ConfigurationProgrammatical.java new file mode 100644 index 0000000..06a8f61 --- /dev/null +++ b/encon-config/src/main/java/io/appulse/encon/config/ConfigurationProgrammatical.java @@ -0,0 +1,194 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config; + +import static java.util.stream.Collectors.toList; +import static lombok.AccessLevel.PRIVATE; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Singular; +import lombok.SneakyThrows; +import lombok.ToString; +import lombok.experimental.FieldDefaults; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +@ToString +@EqualsAndHashCode(callSuper = false) +@FieldDefaults(level = PRIVATE, makeFinal = true) +final class ConfigurationProgrammatical extends AbstractConfig { + + ConfigTree tree; + + private static boolean isClientPojo (Object object) { + Class type = object.getClass(); + String packageName = type.getPackage().getName(); + return !packageName.startsWith("java."); + } + + @AllArgsConstructor(staticName = "of") + private static class Tuple { + + Map map; + + String key; + + void put (Object value) { + map.put(key, value); + } + } + + @SuppressWarnings({ "unchecked", "PMD.AvoidInstantiatingObjectsInLoops"}) + private static Tuple unfoldKey (Map map, String key) { + Map current = map; + String currentKey = key; + + if (!currentKey.contains(".")) { + return Tuple.of(current, currentKey); + } + + String[] tokens = currentKey.split("\\."); + int lastIndex = tokens.length - 1; + for (int index = 0; index < lastIndex; index++) { + Map temporary = (Map) current.get(tokens[index]); + if (temporary == null) { + temporary = new HashMap<>(2, 1.F); + current.put(tokens[index], temporary); + } + current = temporary; + } + currentKey = tokens[lastIndex]; + return Tuple.of(current, currentKey); + } + + @SneakyThrows + private static Map processObject (Object object) { + Map result = new HashMap<>(); + Class type = object.getClass(); + for (Field field : type.getDeclaredFields()) { + if (FieldUtils.isIgnored(field)) { + continue; + } + + field.setAccessible(true); + Object value = field.get(object); + if (value == null) { + continue; + } + + result.put(FieldUtils.getName(field), processValue(value)); + } + return result; + } + + private static Map processMap (Map map) { + Map result = new HashMap<>(); + for (Entry entry : map.entrySet()) { + Tuple currentMap = unfoldKey(result, entry.getKey()); + Object value = processValue(entry.getValue()); + currentMap.put(value); + } + return result; + } + + private static List processList (Collection list) { + return list.stream() + .map(ConfigurationProgrammatical::processValue) + .collect(toList()); + } + + @SuppressWarnings("unchecked") + private static Object processValue (Object object) { + if (object instanceof Map) { + return processMap((Map) object); + } else if (object instanceof Collection) { + return processList((Collection) object); + } else if (object instanceof Enum) { + return object.toString(); + } else if (isClientPojo(object)) { + return processObject(object); + } + return object; + } + + @SuppressWarnings("unchecked") + private static Object merge (Object left, Object right) { + if (left == null) { + return right; + } + if (right == null) { + return right; + } + + if ((left instanceof List) && (right instanceof List)) { + List list = new ArrayList(); + list.addAll((List) left); + list.addAll((List) right); + return list; + } + + if ((left instanceof Map) && (right instanceof Map)) { + Map leftMap = (Map) left; + Map rightMap = (Map) right; + return merge(leftMap, rightMap); + } + + throw new IllegalArgumentException(new StringBuilder() + .append("Couldnt merge ") + .append(left.toString()) + .append(" and ") + .append(right.toString()) + .toString()); + } + + private static Map merge (Map left, Map right) { + Map result = new HashMap<>(left); + right.forEach((key, value) -> { + result.merge(key, value, ConfigurationProgrammatical::merge); + }); + return result; + } + + @Builder + private ConfigurationProgrammatical (@Singular List configs) { + super(); + + Map properties = configs.stream() + .map(ConfigurationProgrammatical::processObject) + .reduce(new HashMap<>(), ConfigurationProgrammatical::merge); + + tree = ConfigTree.from(properties); + } + + @Override + ConfigTree getConfigTree () { + return tree; + } +} diff --git a/encon-config/src/main/java/io/appulse/encon/config/ConfigurationYaml.java b/encon-config/src/main/java/io/appulse/encon/config/ConfigurationYaml.java new file mode 100644 index 0000000..ea1dba5 --- /dev/null +++ b/encon-config/src/main/java/io/appulse/encon/config/ConfigurationYaml.java @@ -0,0 +1,119 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config; + +import static java.util.stream.Collectors.toList; +import static lombok.AccessLevel.PRIVATE; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.NonNull; +import lombok.ToString; +import lombok.experimental.FieldDefaults; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +@ToString +@EqualsAndHashCode(callSuper = false) +@FieldDefaults(level = PRIVATE, makeFinal = true) +final class ConfigurationYaml extends AbstractConfig { + + @AllArgsConstructor(staticName = "of") + private static class Tuple { + + Map map; + + String key; + + void put (Object value) { + map.put(key, value); + } + } + + @SuppressWarnings({ "unchecked", "PMD.AvoidInstantiatingObjectsInLoops"}) + private static Tuple unfoldKey (Map map, String key) { + Map current = map; + String currentKey = key; + + if (!currentKey.contains(".")) { + return Tuple.of(current, currentKey); + } + + String[] tokens = currentKey.split("\\."); + int lastIndex = tokens.length - 1; + for (int index = 0; index < lastIndex; index++) { + Map temporary = (Map) current.get(tokens[index]); + if (temporary == null) { + temporary = new HashMap<>(2, 1.F); + current.put(tokens[index], temporary); + } + current = temporary; + } + currentKey = tokens[lastIndex]; + return Tuple.of(current, currentKey); + } + + private static Map processMap (Map map) { + Map result = new HashMap<>(); + for (Entry entry : map.entrySet()) { + Tuple currentMap = unfoldKey(result, entry.getKey()); + Object value = processValue(entry.getValue()); + currentMap.put(value); + } + return result; + } + + private static List processList (Collection list) { + return list.stream() + .map(ConfigurationYaml::processValue) + .collect(toList()); + } + + @SuppressWarnings("unchecked") + private static Object processValue (Object object) { + if (object instanceof Map) { + return processMap((Map) object); + } else if (object instanceof Collection) { + return processList((Collection) object); + } else if (object instanceof Enum) { + return object.toString(); + } + return object; + } + + ConfigTree tree; + + ConfigurationYaml (@NonNull Map properties) { + super(); + Map unfoldedProperties = processMap(properties); + tree = ConfigTree.from(unfoldedProperties); + } + + @Override + ConfigTree getConfigTree () { + return tree; + } +} diff --git a/encon-config/src/main/java/io/appulse/encon/config/Defaults.java b/encon-config/src/main/java/io/appulse/encon/config/Defaults.java deleted file mode 100644 index 346ebbf..0000000 --- a/encon-config/src/main/java/io/appulse/encon/config/Defaults.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright 2018 the original author or authors. - * - * Licensed 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 io.appulse.encon.config; - -import static io.appulse.encon.common.DistributionFlag.BIG_CREATION; -import static io.appulse.encon.common.DistributionFlag.BIT_BINARIES; -import static io.appulse.encon.common.DistributionFlag.EXTENDED_PIDS_PORTS; -import static io.appulse.encon.common.DistributionFlag.EXTENDED_REFERENCES; -import static io.appulse.encon.common.DistributionFlag.FUN_TAGS; -import static io.appulse.encon.common.DistributionFlag.MAP_TAG; -import static io.appulse.encon.common.DistributionFlag.NEW_FLOATS; -import static io.appulse.encon.common.DistributionFlag.NEW_FUN_TAGS; -import static io.appulse.encon.common.DistributionFlag.UTF8_ATOMS; -import static io.appulse.epmd.java.core.model.NodeType.R6_ERLANG; -import static io.appulse.epmd.java.core.model.Protocol.TCP; -import static io.appulse.epmd.java.core.model.Version.R6; -import static java.lang.Boolean.FALSE; -import static java.util.Arrays.asList; -import static java.util.Locale.ENGLISH; -import static java.util.Optional.ofNullable; -import static java.util.stream.Collectors.toSet; -import static lombok.AccessLevel.PRIVATE; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -import io.appulse.encon.common.DistributionFlag; -import io.appulse.epmd.java.client.EpmdClient; -import io.appulse.epmd.java.core.model.NodeType; -import io.appulse.epmd.java.core.model.Protocol; -import io.appulse.epmd.java.core.model.Version; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import lombok.experimental.FieldDefaults; -import lombok.val; - -/** - * Set of defaults for configuration settings. - * - * @since 1.0.0 - * @author Artem Labazin - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@FieldDefaults(level = PRIVATE) -public class Defaults { - - /** - * Cached defaults instance. - */ - public static final Defaults INSTANCE = Defaults.builder().build(); - - /** - * Returns default cookie. It could be an empty string or content of ~/.erlang.cookie file. - * - * @return default cookie value - */ - public static String getDefaultCookie () { - val cookieFile = Paths.get(getHomeDir(), ".erlang.cookie"); - if (!Files.exists(cookieFile)) { - return ""; - } - - try { - return Files.lines(cookieFile) - .filter(Objects::nonNull) - .map(String::trim) - .filter(it -> !it.isEmpty()) - .findFirst() - .orElse(""); - } catch (IOException ex) { - return ""; - } - } - - /** - * Returns user's home directory. - * - * @return user's home directory - */ - public static String getHomeDir () { - val home = System.getProperty("user.home"); - if (!System.getProperty("os.name").toLowerCase(ENGLISH).contains("windows")) { - return home; - } - - val drive = System.getenv("HOMEDRIVE"); - val path = System.getenv("HOMEPATH"); - return drive == null || path == null - ? home - : drive + path; - } - - @SuppressWarnings("unchecked") - static Defaults newInstance (@NonNull Map map) { - DefaultsBuilder builder = Defaults.builder(); - - ofNullable(map.get("epmd-port")) - .map(Object::toString) - .map(Integer::parseInt) - .ifPresent(builder::epmdPort); - - ofNullable(map.get("type")) - .map(Object::toString) - .map(NodeType::valueOf) - .ifPresent(builder::type); - - ofNullable(map.get("short-name")) - .map(Object::toString) - .map(Boolean::valueOf) - .ifPresent(builder::shortName); - - ofNullable(map.get("cookie")) - .map(Object::toString) - .ifPresent(builder::cookie); - - ofNullable(map.get("protocol")) - .map(Object::toString) - .map(Protocol::valueOf) - .ifPresent(builder::protocol); - - ofNullable(map.get("low-version")) - .map(Object::toString) - .map(Version::valueOf) - .ifPresent(builder::lowVersion); - - ofNullable(map.get("high-version")) - .map(Object::toString) - .map(Version::valueOf) - .ifPresent(builder::highVersion); - - ofNullable(map.get("distribution-flags")) - .filter(it -> it instanceof List) - .map(it -> (List) it) - .map(it -> it.stream().map(DistributionFlag::valueOf).collect(toSet())) - .ifPresent(builder::distributionFlags); - - ofNullable(map.get("mailbox")) - .filter(it -> it instanceof Map) - .map(it -> (Map) it) - .map(MailboxConfig::newInstance) - .ifPresent(builder::mailbox); - - ofNullable(map.get("server")) - .filter(it -> it instanceof Map) - .map(it -> (Map) it) - .map(ServerConfig::newInstance) - .ifPresent(builder::server); - - ofNullable(map.get("compression")) - .filter(it -> it instanceof Map) - .map(it -> (Map) it) - .map(CompressionConfig::newInstance) - .ifPresent(builder::compression); - - return builder.build(); - } - - @Builder.Default - int epmdPort = EpmdClient.Default.PORT; - - @Builder.Default - NodeType type = R6_ERLANG; - - @Builder.Default - Boolean shortName = FALSE; - - @Builder.Default - String cookie = getDefaultCookie(); - - @Builder.Default - Protocol protocol = TCP; - - @Builder.Default - Version lowVersion = R6; - - @Builder.Default - Version highVersion = R6; - - @Builder.Default - Set distributionFlags = new HashSet<>(asList( - EXTENDED_REFERENCES, - EXTENDED_PIDS_PORTS, - BIT_BINARIES, - NEW_FLOATS, - FUN_TAGS, - NEW_FUN_TAGS, - UTF8_ATOMS, - MAP_TAG, - BIG_CREATION - )); - - @Builder.Default - MailboxConfig mailbox = MailboxConfig.builder() - .build(); - - @Builder.Default - ServerConfig server = ServerConfig.builder() - .bossThreads(1) - .workerThreads(2) - .build(); - - @Builder.Default - CompressionConfig compression = CompressionConfig.builder() - .enabled(FALSE) - .level(-1) - .build(); - - /** - * Copy constructor. - * - * @param defaults config to copy - */ - public Defaults (Defaults defaults) { - epmdPort = defaults.getEpmdPort(); - type = defaults.getType(); - shortName = defaults.getShortName(); - cookie = defaults.getCookie(); - protocol = defaults.getProtocol(); - lowVersion = defaults.getLowVersion(); - highVersion = defaults.getHighVersion(); - distributionFlags = ofNullable(defaults.getDistributionFlags()) - .map(HashSet::new) - .orElse(null); - mailbox = ofNullable(defaults.getMailbox()) - .map(MailboxConfig::new) - .orElse(null); - server = ofNullable(defaults.getServer()) - .map(ServerConfig::new) - .orElse(null); - compression = ofNullable(defaults.getCompression()) - .map(CompressionConfig::new) - .orElse(null); - } -} diff --git a/encon-config/src/main/java/io/appulse/encon/config/FieldProperty.java b/encon-config/src/main/java/io/appulse/encon/config/FieldProperty.java new file mode 100644 index 0000000..1edd9f8 --- /dev/null +++ b/encon-config/src/main/java/io/appulse/encon/config/FieldProperty.java @@ -0,0 +1,39 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +@Target(TYPE) +@Retention(RUNTIME) +public @interface FieldProperty { + + String value () default ""; + + String name () default ""; + + boolean ignore () default false; +} diff --git a/encon-config/src/main/java/io/appulse/encon/config/FieldUtils.java b/encon-config/src/main/java/io/appulse/encon/config/FieldUtils.java new file mode 100644 index 0000000..8c7b584 --- /dev/null +++ b/encon-config/src/main/java/io/appulse/encon/config/FieldUtils.java @@ -0,0 +1,88 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config; + +import static java.util.Optional.ofNullable; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.stream.Stream; + +import lombok.SneakyThrows; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +final class FieldUtils { + + static boolean isIgnored (Field field) { + int modifiers = field.getModifiers(); + if (Modifier.isFinal(modifiers) || Modifier.isStatic(modifiers)) { + return true; + } + FieldProperty fieldProperty = field.getAnnotation(FieldProperty.class); + return fieldProperty != null && fieldProperty.ignore(); + } + + static String getName (Field field) { + FieldProperty fieldProperty = field.getAnnotation(FieldProperty.class); + return ofNullable(fieldProperty) + .flatMap(prop -> Stream.of(prop.value(), prop.name()) + .filter(it -> !it.isEmpty()) + .findFirst() + ) + .orElseGet(() -> field.getName()); + } + + static Class getGenericType (Field field, int index) { + Type genericType = field.getGenericType(); + ParameterizedType parameterizedType = (ParameterizedType) genericType; + Type[] types = parameterizedType.getActualTypeArguments(); + return (Class) types[index]; + } + + @SneakyThrows + static void setValue (Object object, Field field, Object value) { + String fieldName = field.getName(); + String setter = new StringBuilder() + .append("set") + .append(Character.toUpperCase(fieldName.charAt(0))) + .append(fieldName.substring(1)) + .toString(); + + try { + object.getClass() + .getDeclaredMethod(setter) + .invoke(object, value); + } catch (NoSuchMethodException ex) { + AccessController.doPrivileged((PrivilegedAction) () -> { + field.setAccessible(true); + return null; + }); + field.set(object, value); + } + } + + private FieldUtils () { + } +} diff --git a/encon-config/src/main/java/io/appulse/encon/config/MailboxConfig.java b/encon-config/src/main/java/io/appulse/encon/config/MailboxConfig.java deleted file mode 100644 index 77ee25c..0000000 --- a/encon-config/src/main/java/io/appulse/encon/config/MailboxConfig.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2018 the original author or authors. - * - * Licensed 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 io.appulse.encon.config; - -import static java.util.Optional.ofNullable; -import static lombok.AccessLevel.PRIVATE; - -import java.util.Map; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import lombok.experimental.FieldDefaults; - -/** - * Set of mailbox settings. - * - * @since 1.0.0 - * @author Artem Labazin - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@FieldDefaults(level = PRIVATE) -public class MailboxConfig { - - static MailboxConfig newInstance (@NonNull Map map) { - MailboxConfigBuilder builder = MailboxConfig.builder(); - - ofNullable(map.get("name")) - .map(Object::toString) - .ifPresent(builder::name); - - return builder.build(); - } - - String name; - - /** - * Copy constructor. - * - * @param mailboxConfig config for copying - */ - public MailboxConfig (MailboxConfig mailboxConfig) { - name = mailboxConfig.getName(); - } - - /** - * Method for setting up the default values. - * - * @param defaults MailboxConfig with default values for node - * - * @return reference to this object (for chain calls) - */ - public MailboxConfig withDefaultsFrom (@NonNull MailboxConfig defaults) { - return this; - } -} diff --git a/encon-config/src/main/java/io/appulse/encon/config/NodeConfig.java b/encon-config/src/main/java/io/appulse/encon/config/NodeConfig.java deleted file mode 100644 index 4796e90..0000000 --- a/encon-config/src/main/java/io/appulse/encon/config/NodeConfig.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright 2018 the original author or authors. - * - * Licensed 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 io.appulse.encon.config; - -import static java.util.Collections.emptyList; -import static java.util.Optional.ofNullable; -import static java.util.stream.Collectors.toList; -import static java.util.stream.Collectors.toSet; -import static lombok.AccessLevel.PRIVATE; - -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import io.appulse.encon.common.DistributionFlag; -import io.appulse.epmd.java.core.model.NodeType; -import io.appulse.epmd.java.core.model.Protocol; -import io.appulse.epmd.java.core.model.Version; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import lombok.Singular; -import lombok.experimental.FieldDefaults; - -/** - * Node configuration settings. - * - * @since 1.0.0 - * @author Artem Labazin - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@FieldDefaults(level = PRIVATE) -public class NodeConfig { - - /** - * Cached empty {@link NodeConfig} instance. - */ - public static final NodeConfig DEFAULT = NodeConfig.builder().build(); - - @SuppressWarnings("unchecked") - static NodeConfig newInstance (@NonNull Map map) { - NodeConfigBuilder builder = NodeConfig.builder(); - - ofNullable(map.get("epmd-port")) - .map(Object::toString) - .map(Integer::parseInt) - .ifPresent(builder::epmdPort); - - ofNullable(map.get("type")) - .map(Object::toString) - .map(NodeType::valueOf) - .ifPresent(builder::type); - - ofNullable(map.get("short-name")) - .map(Object::toString) - .map(Boolean::valueOf) - .ifPresent(builder::shortName); - - ofNullable(map.get("cookie")) - .map(Object::toString) - .ifPresent(builder::cookie); - - ofNullable(map.get("protocol")) - .map(Object::toString) - .map(Protocol::valueOf) - .ifPresent(builder::protocol); - - ofNullable(map.get("low-version")) - .map(Object::toString) - .map(Version::valueOf) - .ifPresent(builder::lowVersion); - - ofNullable(map.get("high-version")) - .map(Object::toString) - .map(Version::valueOf) - .ifPresent(builder::highVersion); - - ofNullable(map.get("distribution-flags")) - .filter(it -> it instanceof List) - .map(it -> (List) it) - .map(it -> it.stream().map(DistributionFlag::valueOf).collect(toSet())) - .ifPresent(builder::distributionFlags); - - ofNullable(map.get("mailboxes")) - .filter(it -> it instanceof List) - .map(it -> (List>) it) - .map(it -> it.stream() - .map(sub -> MailboxConfig.newInstance(sub)) - .collect(toList()) - ) - .ifPresent(builder::mailboxes); - - ofNullable(map.get("server")) - .filter(it -> it instanceof Map) - .map(it -> (Map) it) - .map(ServerConfig::newInstance) - .ifPresent(builder::server); - - ofNullable(map.get("compression")) - .filter(it -> it instanceof Map) - .map(it -> (Map) it) - .map(CompressionConfig::newInstance) - .ifPresent(builder::compression); - - return builder.build(); - } - - Integer epmdPort; - - NodeType type; - - Boolean shortName; - - String cookie; - - Protocol protocol; - - Version lowVersion; - - Version highVersion; - - @Singular - Set distributionFlags; - - @Singular - List mailboxes; - - ServerConfig server; - - CompressionConfig compression; - - /** - * Copy constructor. - * - * @param nodeConfig config to copy - */ - public NodeConfig (NodeConfig nodeConfig) { - epmdPort = nodeConfig.getEpmdPort(); - type = nodeConfig.getType(); - shortName = nodeConfig.getShortName(); - cookie = nodeConfig.getCookie(); - protocol = nodeConfig.getProtocol(); - lowVersion = nodeConfig.getLowVersion(); - highVersion = nodeConfig.getHighVersion(); - distributionFlags = ofNullable(nodeConfig.getDistributionFlags()) - .map(HashSet::new) - .orElse(null); - mailboxes = ofNullable(nodeConfig.getMailboxes()) - .map(it -> it.stream() - .map(MailboxConfig::new) - .collect(toList()) - ) - .orElse(null); - server = ofNullable(nodeConfig.getServer()) - .map(ServerConfig::new) - .orElse(null); - compression = ofNullable(nodeConfig.getCompression()) - .map(CompressionConfig::new) - .orElse(null); - } - - /** - * Method for setting up the default values. - * - * @param defaults Defaults with default values for node - * - * @return reference to this object (for chain calls) - */ - public NodeConfig withDefaultsFrom (@NonNull Defaults defaults) { - epmdPort = ofNullable(epmdPort) - .orElse(defaults.getEpmdPort()); - - type = ofNullable(type) - .orElse(defaults.getType()); - - shortName = ofNullable(shortName) - .orElse(defaults.getShortName()); - - cookie = ofNullable(cookie) - .orElse(defaults.getCookie()); - - protocol = ofNullable(protocol) - .orElse(defaults.getProtocol()); - - lowVersion = ofNullable(lowVersion) - .orElse(defaults.getLowVersion()); - - highVersion = ofNullable(highVersion) - .orElse(defaults.getHighVersion()); - - distributionFlags = ofNullable(distributionFlags) - .filter(it -> !it.isEmpty()) - .orElse(defaults.getDistributionFlags()); - - mailboxes = ofNullable(mailboxes) - .map(it -> it.stream() - .map(mailbox -> mailbox.withDefaultsFrom(defaults.getMailbox())) - .collect(toList()) - ) - .orElse(emptyList()); - - server = ofNullable(server) - .orElse(ServerConfig.builder().build()) - .withDefaultsFrom(defaults.getServer()); - - compression = ofNullable(compression) - .orElse(CompressionConfig.builder().build()) - .withDefaultsFrom(defaults.getCompression()); - - return this; - } -} diff --git a/encon-config/src/main/java/io/appulse/encon/config/ServerConfig.java b/encon-config/src/main/java/io/appulse/encon/config/ServerConfig.java deleted file mode 100644 index 3512585..0000000 --- a/encon-config/src/main/java/io/appulse/encon/config/ServerConfig.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2018 the original author or authors. - * - * Licensed 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 io.appulse.encon.config; - -import static java.util.Optional.ofNullable; -import static lombok.AccessLevel.PRIVATE; - -import java.util.Map; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import lombok.experimental.FieldDefaults; - -/** - * Server's configuration. - * - * @since 1.0.0 - * @author Artem Labazin - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@FieldDefaults(level = PRIVATE) -public class ServerConfig { - - static ServerConfig newInstance (@NonNull Map map) { - ServerConfigBuilder builder = ServerConfig.builder(); - - ofNullable(map.get("port")) - .map(Object::toString) - .map(Integer::parseInt) - .ifPresent(builder::port); - - ofNullable(map.get("boss-threads")) - .map(Object::toString) - .map(Integer::parseInt) - .ifPresent(builder::bossThreads); - - ofNullable(map.get("worker-threads")) - .map(Object::toString) - .map(Integer::parseInt) - .ifPresent(builder::workerThreads); - - return builder.build(); - } - - Integer port; - - Integer bossThreads; - - Integer workerThreads; - - /** - * Copy constructor. - * - * @param serverConfig config to copy - */ - public ServerConfig (ServerConfig serverConfig) { - port = serverConfig.getPort(); - bossThreads = serverConfig.getBossThreads(); - workerThreads = serverConfig.getWorkerThreads(); - } - - /** - * Method for setting up the default values. - * - * @param defaults ServerConfig with default values for server - * - * @return reference to this object (for chain calls) - */ - ServerConfig withDefaultsFrom (@NonNull ServerConfig defaults) { - port = ofNullable(port) - .orElse(ServerPortGenerator.nextPort()); - - bossThreads = ofNullable(bossThreads) - .orElse(defaults.getBossThreads()); - - workerThreads = ofNullable(workerThreads) - .orElse(defaults.getWorkerThreads()); - - return this; - } -} diff --git a/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigDumpingException.java b/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigDumpingException.java new file mode 100644 index 0000000..3b534fd --- /dev/null +++ b/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigDumpingException.java @@ -0,0 +1,43 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config.exception; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +public class ConfigDumpingException extends RuntimeException { + + private static final long serialVersionUID = -2037687366820497432L; + + public ConfigDumpingException () { + super(); + } + + public ConfigDumpingException (String message) { + super(message); + } + + public ConfigDumpingException (String message, Throwable cause) { + super(message, cause); + } + + public ConfigDumpingException (Throwable cause) { + super(cause); + } +} diff --git a/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigLoadingException.java b/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigLoadingException.java new file mode 100644 index 0000000..5862a2b --- /dev/null +++ b/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigLoadingException.java @@ -0,0 +1,43 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config.exception; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +public class ConfigLoadingException extends RuntimeException { + + private static final long serialVersionUID = -6331216493731022355L; + + public ConfigLoadingException () { + super(); + } + + public ConfigLoadingException (String message) { + super(message); + } + + public ConfigLoadingException (String message, Throwable cause) { + super(message, cause); + } + + public ConfigLoadingException (Throwable cause) { + super(cause); + } +} diff --git a/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigLoadingFileNotFoundException.java b/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigLoadingFileNotFoundException.java new file mode 100644 index 0000000..c620064 --- /dev/null +++ b/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigLoadingFileNotFoundException.java @@ -0,0 +1,43 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config.exception; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +public class ConfigLoadingFileNotFoundException extends ConfigLoadingException { + + private static final long serialVersionUID = 5257226653126248314L; + + public ConfigLoadingFileNotFoundException () { + super(); + } + + public ConfigLoadingFileNotFoundException (String message) { + super(message); + } + + public ConfigLoadingFileNotFoundException (String message, Throwable cause) { + super(message, cause); + } + + public ConfigLoadingFileNotFoundException (Throwable cause) { + super(cause); + } +} diff --git a/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigLoadingFileParsingException.java b/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigLoadingFileParsingException.java new file mode 100644 index 0000000..f7c54a6 --- /dev/null +++ b/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigLoadingFileParsingException.java @@ -0,0 +1,43 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config.exception; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +public class ConfigLoadingFileParsingException extends ConfigLoadingException { + + private static final long serialVersionUID = 2722656115265976050L; + + public ConfigLoadingFileParsingException () { + super(); + } + + public ConfigLoadingFileParsingException (String message) { + super(message); + } + + public ConfigLoadingFileParsingException (String message, Throwable cause) { + super(message, cause); + } + + public ConfigLoadingFileParsingException (Throwable cause) { + super(cause); + } +} diff --git a/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigLoadingMalformedFilePathException.java b/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigLoadingMalformedFilePathException.java new file mode 100644 index 0000000..3dacf21 --- /dev/null +++ b/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigLoadingMalformedFilePathException.java @@ -0,0 +1,43 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config.exception; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +public class ConfigLoadingMalformedFilePathException extends ConfigLoadingException { + + private static final long serialVersionUID = -6755810629678253064L; + + public ConfigLoadingMalformedFilePathException () { + super(); + } + + public ConfigLoadingMalformedFilePathException (String message) { + super(message); + } + + public ConfigLoadingMalformedFilePathException (String message, Throwable cause) { + super(message, cause); + } + + public ConfigLoadingMalformedFilePathException (Throwable cause) { + super(cause); + } +} diff --git a/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigMappingEnumValueNotFoundException.java b/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigMappingEnumValueNotFoundException.java new file mode 100644 index 0000000..437eb06 --- /dev/null +++ b/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigMappingEnumValueNotFoundException.java @@ -0,0 +1,45 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config.exception; + +import lombok.EqualsAndHashCode; +import lombok.Value; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +@Value +@EqualsAndHashCode(callSuper = true) +public class ConfigMappingEnumValueNotFoundException extends ConfigMappingUnsupportedTypeException { + + String nodeAsString; + + public ConfigMappingEnumValueNotFoundException (Class type, String nodeAsString) { + super(type); + this.nodeAsString = nodeAsString; + } + + @Override + public String getMessage () { + return new StringBuilder() + .append("Enum class ").append(getType().getName()) + .append(" couldn't be instantiated from string ").append(nodeAsString) + .toString(); + } +} diff --git a/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigMappingException.java b/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigMappingException.java new file mode 100644 index 0000000..daa4536 --- /dev/null +++ b/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigMappingException.java @@ -0,0 +1,43 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config.exception; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +public class ConfigMappingException extends RuntimeException { + + private static final long serialVersionUID = -6274584960099563788L; + + public ConfigMappingException () { + super(); + } + + public ConfigMappingException (String message) { + super(message); + } + + public ConfigMappingException (String message, Throwable cause) { + super(message, cause); + } + + public ConfigMappingException (Throwable cause) { + super(cause); + } +} diff --git a/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigMappingNoMappingFunctionException.java b/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigMappingNoMappingFunctionException.java new file mode 100644 index 0000000..af340db --- /dev/null +++ b/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigMappingNoMappingFunctionException.java @@ -0,0 +1,48 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config.exception; + +import lombok.EqualsAndHashCode; +import lombok.Value; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +@Value +@EqualsAndHashCode(callSuper = true) +public class ConfigMappingNoMappingFunctionException extends ConfigMappingUnsupportedTypeException { + + private static final long serialVersionUID = -8570254024009936472L; + + String nodeAsString; + + public ConfigMappingNoMappingFunctionException (Class type, String nodeAsString) { + super(type); + this.nodeAsString = nodeAsString; + } + + @Override + public String getMessage () { + return new StringBuilder() + .append("There is no any way for mapping the type ") + .append(getType().getClass().getName()).append(" into ") + .append(nodeAsString) + .toString(); + } +} diff --git a/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigMappingUnsupportedTypeException.java b/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigMappingUnsupportedTypeException.java new file mode 100644 index 0000000..61123d2 --- /dev/null +++ b/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigMappingUnsupportedTypeException.java @@ -0,0 +1,51 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config.exception; + +import static lombok.AccessLevel.PRIVATE; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.experimental.FieldDefaults; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +@Getter +@EqualsAndHashCode(callSuper = true) +@FieldDefaults(level = PRIVATE, makeFinal = true) +public class ConfigMappingUnsupportedTypeException extends ConfigMappingException { + + private static final long serialVersionUID = -6947696128448927769L; + + Class type; + + public ConfigMappingUnsupportedTypeException (Class type) { + super(); + this.type = type; + } + + @Override + public String getMessage () { + return new StringBuilder() + .append("Unsupported mapping type ") + .append(type.getClass().getName()) + .toString(); + } +} diff --git a/encon-config/src/main/java/io/appulse/encon/config/exception/NoSuchMailboxHandlerException.java b/encon-config/src/main/java/io/appulse/encon/config/exception/NoSuchMailboxHandlerException.java deleted file mode 100644 index 12cda3b..0000000 --- a/encon-config/src/main/java/io/appulse/encon/config/exception/NoSuchMailboxHandlerException.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2018 the original author or authors. - * - * Licensed 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 io.appulse.encon.config.exception; - -import lombok.EqualsAndHashCode; -import lombok.Value; - -/** - * The exception indicates what mailbox handler class is unreachable. - * - * @since 1.0.0 - * @author Artem Labazin - */ -@Value -@EqualsAndHashCode(callSuper = false) -public class NoSuchMailboxHandlerException extends RuntimeException { - - private static final long serialVersionUID = 9031562526640890127L; - - String classPath; - - /** - * Constructs a new runtime exception with the specified cause and a detail message - * of (cause==null ? null : cause.toString()) (which typically contains the class and detail message of cause). - *

- * This constructor is useful for runtime exceptions that are little more than wrappers for other throwables. - * - * @param cause the cause (which is saved for later retrieval by the Throwable.getCause() method). - * (A null value is permitted, and indicates that the cause is nonexistent or unknown.) - * - * @param classPath handler class path - */ - public NoSuchMailboxHandlerException (Throwable cause, String classPath) { - super(cause); - this.classPath = classPath; - } -} diff --git a/encon-config/src/main/java/lombok.config b/encon-config/src/main/java/lombok.config new file mode 100644 index 0000000..a0f6168 --- /dev/null +++ b/encon-config/src/main/java/lombok.config @@ -0,0 +1 @@ +lombok.extern.findbugs.addSuppressFBWarnings = true diff --git a/encon-config/src/test/java/io/appulse/encon/config/ConfigTest.java b/encon-config/src/test/java/io/appulse/encon/config/ConfigTest.java deleted file mode 100644 index b63b84c..0000000 --- a/encon-config/src/test/java/io/appulse/encon/config/ConfigTest.java +++ /dev/null @@ -1,662 +0,0 @@ -/* - * Copyright 2018 the original author or authors. - * - * Licensed 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 io.appulse.encon.config; - -import static io.appulse.encon.common.DistributionFlag.BIG_CREATION; -import static io.appulse.encon.common.DistributionFlag.BIT_BINARIES; -import static io.appulse.encon.common.DistributionFlag.EXTENDED_PIDS_PORTS; -import static io.appulse.encon.common.DistributionFlag.EXTENDED_REFERENCES; -import static io.appulse.encon.common.DistributionFlag.FUN_TAGS; -import static io.appulse.encon.common.DistributionFlag.MAP_TAG; -import static io.appulse.encon.common.DistributionFlag.NEW_FLOATS; -import static io.appulse.encon.common.DistributionFlag.NEW_FUN_TAGS; -import static io.appulse.encon.common.DistributionFlag.UTF8_ATOMS; -import static io.appulse.epmd.java.core.model.NodeType.R3_ERLANG; -import static io.appulse.epmd.java.core.model.NodeType.R3_HIDDEN; -import static io.appulse.epmd.java.core.model.NodeType.R6_ERLANG; -import static io.appulse.epmd.java.core.model.Protocol.SCTP; -import static io.appulse.epmd.java.core.model.Protocol.TCP; -import static io.appulse.epmd.java.core.model.Protocol.UDP; -import static io.appulse.epmd.java.core.model.Version.R3; -import static io.appulse.epmd.java.core.model.Version.R4; -import static io.appulse.epmd.java.core.model.Version.R5C; -import static io.appulse.epmd.java.core.model.Version.R6; -import static java.util.Arrays.asList; -import static org.assertj.core.api.Assertions.assertThat; - -import java.io.File; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import io.appulse.encon.common.DistributionFlag; -import io.appulse.epmd.java.client.EpmdClient; -import io.appulse.epmd.java.core.model.NodeType; -import io.appulse.epmd.java.core.model.Protocol; -import io.appulse.epmd.java.core.model.Version; -import io.appulse.utils.test.TestMethodNamePrinter; - -import org.assertj.core.api.SoftAssertions; -import org.junit.Rule; -import org.junit.rules.TestRule; -import org.junit.Test; - -/** - * - * @author Artem Labazin - * @since 1.0.0 - */ -public class ConfigTest { - - @Rule - public TestRule watcher = new TestMethodNamePrinter(); - - @Test - public void defaultDefaults () { - Config config = Config.builder() - .build(); - - Defaults defaults = config.getDefaults(); - assertThat(defaults) - .isNotNull(); - - assertThat(config.getNodes()) - .isEmpty(); - - SoftAssertions.assertSoftly(softly -> { - softly.assertThat(defaults.getEpmdPort()) - .isEqualTo(EpmdClient.Default.PORT); - - softly.assertThat(defaults.getType()) - .isEqualTo(R6_ERLANG); - - softly.assertThat(defaults.getShortName()) - .isFalse(); - - softly.assertThat(defaults.getProtocol()) - .isEqualTo(TCP); - - softly.assertThat(defaults.getLowVersion()) - .isEqualTo(R6); - - softly.assertThat(defaults.getHighVersion()) - .isEqualTo(R6); - - softly.assertThat(defaults.getDistributionFlags()) - .isNotEmpty(); - - softly.assertThat(defaults.getMailbox()) - .isNotNull(); - - softly.assertThat(defaults.getServer()) - .isNotNull(); - - softly.assertThat(defaults.getServer().getPort()) - .isNull(); - - softly.assertThat(defaults.getServer().getBossThreads()) - .isEqualTo(1); - - softly.assertThat(defaults.getServer().getWorkerThreads()) - .isEqualTo(2); - }); - } - - @Test - public void nonDefaultDefaults () { - int epmdPort = 4321; - NodeType type = R3_HIDDEN; - Protocol protocol = UDP; - Version low = R3; - Version high = R5C; - Set distributionFlags = new HashSet<>(asList( - UTF8_ATOMS - )); - int bossThreads = 7; - int workerThreads = 14; - - Config config = Config.builder() - .defaults(Defaults.builder() - .epmdPort(epmdPort) - .type(type) - .protocol(protocol) - .lowVersion(low) - .highVersion(high) - .distributionFlags(distributionFlags) - .mailbox(MailboxConfig.builder() - .build()) - .server(ServerConfig.builder() - .bossThreads(bossThreads) - .workerThreads(workerThreads) - .build()) - .build()) - .build(); - - Defaults defaults = config.getDefaults(); - assertThat(defaults).isNotNull(); - - assertThat(config.getNodes()) - .isEmpty(); - - SoftAssertions.assertSoftly(softly -> { - softly.assertThat(defaults.getEpmdPort()) - .isEqualTo(epmdPort); - - softly.assertThat(defaults.getType()) - .isEqualTo(type); - - softly.assertThat(defaults.getShortName()) - .isFalse(); - - softly.assertThat(defaults.getProtocol()) - .isEqualTo(protocol); - - softly.assertThat(defaults.getLowVersion()) - .isEqualTo(low); - - softly.assertThat(defaults.getHighVersion()) - .isEqualTo(high); - - softly.assertThat(defaults.getDistributionFlags()) - .isEqualTo(distributionFlags); - - softly.assertThat(defaults.getMailbox()) - .isNotNull(); - - softly.assertThat(defaults.getServer()) - .isNotNull(); - - softly.assertThat(defaults.getServer().getPort()) - .isNull(); - - softly.assertThat(defaults.getServer().getBossThreads()) - .isEqualTo(bossThreads); - - softly.assertThat(defaults.getServer().getWorkerThreads()) - .isEqualTo(workerThreads); - }); - } - - @Test - public void nodeWithDefaults () { - Config config = Config.builder() - .node("popa", NodeConfig.builder().build()) - .build(); - - NodeConfig nodeConfig = config.getNodes().get("popa"); - assertThat(nodeConfig).isNotNull(); - - SoftAssertions.assertSoftly(softly -> { - softly.assertThat(nodeConfig.getEpmdPort()) - .isEqualTo(EpmdClient.Default.PORT); - - softly.assertThat(nodeConfig.getType()) - .isEqualTo(R6_ERLANG); - - softly.assertThat(nodeConfig.getShortName()) - .isFalse(); - - softly.assertThat(nodeConfig.getProtocol()) - .isEqualTo(TCP); - - softly.assertThat(nodeConfig.getLowVersion()) - .isEqualTo(R6); - - softly.assertThat(nodeConfig.getHighVersion()) - .isEqualTo(R6); - - softly.assertThat(nodeConfig.getDistributionFlags()) - .isNotEmpty(); - - softly.assertThat(nodeConfig.getMailboxes()) - .isEmpty(); - - softly.assertThat(nodeConfig.getServer()) - .isNotNull(); - - softly.assertThat(nodeConfig.getServer().getPort()) - .isNotNull(); - - softly.assertThat(nodeConfig.getServer().getBossThreads()) - .isEqualTo(1); - - softly.assertThat(nodeConfig.getServer().getWorkerThreads()) - .isEqualTo(2); - }); - } - - @Test - public void load () { - ClassLoader classLoader = getClass().getClassLoader(); - File file = new File(classLoader.getResource("connector.yml").getFile()); - - Config config = Config.load(file); - - Defaults defaults = config.getDefaults(); - assertThat(defaults) - .isNotNull(); - - SoftAssertions.assertSoftly(softly -> { - softly.assertThat(defaults.getEpmdPort()) - .isEqualTo(8888); - - softly.assertThat(defaults.getType()) - .isEqualTo(R3_ERLANG); - - softly.assertThat(defaults.getShortName()) - .isTrue(); - - softly.assertThat(defaults.getCookie()) - .isEqualTo("secret"); - - softly.assertThat(defaults.getProtocol()) - .isEqualTo(UDP); - - softly.assertThat(defaults.getLowVersion()) - .isEqualTo(R4); - - softly.assertThat(defaults.getHighVersion()) - .isEqualTo(R6); - - softly.assertThat(defaults.getDistributionFlags()) - .contains(MAP_TAG, BIG_CREATION); - - softly.assertThat(defaults.getServer()) - .isNotNull(); - - softly.assertThat(defaults.getServer().getPort()) - .isNull(); - - softly.assertThat(defaults.getServer().getBossThreads()) - .isEqualTo(2); - - softly.assertThat(defaults.getServer().getWorkerThreads()) - .isEqualTo(4); - }); - - Map nodes = config.getNodes(); - assertThat(nodes).isNotNull(); - - NodeConfig node1 = nodes.get("node-1"); - assertThat(node1).isNotNull(); - - SoftAssertions.assertSoftly(softly -> { - softly.assertThat(node1.getEpmdPort()) - .isEqualTo(7373); - - softly.assertThat(node1.getType()) - .isEqualTo(R3_HIDDEN); - - softly.assertThat(node1.getShortName()) - .isTrue(); - - softly.assertThat(node1.getCookie()) - .isEqualTo("non-secret"); - - softly.assertThat(node1.getProtocol()) - .isEqualTo(SCTP); - - softly.assertThat(node1.getLowVersion()) - .isEqualTo(R5C); - - softly.assertThat(node1.getHighVersion()) - .isEqualTo(R6); - - softly.assertThat(node1.getDistributionFlags()).contains( - EXTENDED_REFERENCES, - EXTENDED_PIDS_PORTS, - BIT_BINARIES, - NEW_FLOATS, - FUN_TAGS, - NEW_FUN_TAGS, - UTF8_ATOMS, - MAP_TAG, - BIG_CREATION - ); - - softly.assertThat(node1.getMailboxes()) - .isNotEmpty(); - - MailboxConfig mailbox1 = node1.getMailboxes() - .stream() - .filter(it -> "net_kernel".equals(it.getName())) - .findFirst() - .orElse(null); - assertThat(mailbox1).isNotNull(); - - MailboxConfig mailbox2 = node1.getMailboxes() - .stream() - .filter(it -> "another".equals(it.getName())) - .findFirst() - .orElse(null); - assertThat(mailbox2).isNotNull(); - - MailboxConfig mailbox3 = node1.getMailboxes() - .stream() - .filter(it -> "another_one".equals(it.getName())) - .findFirst() - .orElse(null); - assertThat(mailbox3).isNotNull(); - - softly.assertThat(node1.getServer()) - .isNotNull(); - - softly.assertThat(node1.getServer().getPort()) - .isEqualTo(8971); - - softly.assertThat(node1.getServer().getBossThreads()) - .isEqualTo(1); - - softly.assertThat(node1.getServer().getWorkerThreads()) - .isEqualTo(2); - }); - - NodeConfig node2 = nodes.get("node-2"); - assertThat(node2).isNotNull(); - - SoftAssertions.assertSoftly(softly -> { - softly.assertThat(node2.getEpmdPort()) - .isEqualTo(8888); - - softly.assertThat(node2.getType()) - .isEqualTo(R3_ERLANG); - - softly.assertThat(node2.getShortName()) - .isFalse(); - - softly.assertThat(node2.getCookie()) - .isEqualTo("popa"); - - softly.assertThat(node2.getProtocol()) - .isEqualTo(UDP); - - softly.assertThat(node2.getLowVersion()) - .isEqualTo(R4); - - softly.assertThat(node2.getHighVersion()) - .isEqualTo(R6); - - softly.assertThat(node2.getDistributionFlags()).contains( - MAP_TAG, - BIG_CREATION - ); - - softly.assertThat(node2.getMailboxes()) - .isNotEmpty(); - - MailboxConfig mailbox1 = node2.getMailboxes() - .stream() - .filter(it -> "net_kernel".equals(it.getName())) - .findFirst() - .orElse(null); - assertThat(mailbox1).isNotNull(); - - softly.assertThat(node2.getServer()) - .isNotNull(); - - softly.assertThat(node2.getServer().getPort()) - .isNotNull(); - - softly.assertThat(node2.getServer().getBossThreads()) - .isEqualTo(2); - - softly.assertThat(node2.getServer().getWorkerThreads()) - .isEqualTo(4); - }); - } - - @Test - public void manual () { - Config config = Config.builder() - .defaults(Defaults.builder() - .epmdPort(8888) - .type(R3_ERLANG) - .shortName(true) - .cookie("secret") - .protocol(UDP) - .lowVersion(R4) - .highVersion(R6) - .distributionFlags(new HashSet<>(asList( - MAP_TAG, - BIG_CREATION - ))) - .mailbox(MailboxConfig.builder() - .build()) - .server(ServerConfig.builder() - .bossThreads(2) - .workerThreads(4) - .build()) - .build() - ) - .node("node-1", NodeConfig.builder() - .epmdPort(7373) - .type(R3_HIDDEN) - .shortName(false) - .cookie("non-secret") - .protocol(SCTP) - .lowVersion(R5C) - .highVersion(R6) - .distributionFlag(EXTENDED_REFERENCES) - .distributionFlag(EXTENDED_PIDS_PORTS) - .distributionFlag(BIT_BINARIES) - .distributionFlag(NEW_FLOATS) - .distributionFlag(FUN_TAGS) - .distributionFlag(NEW_FUN_TAGS) - .distributionFlag(UTF8_ATOMS) - .distributionFlag(MAP_TAG) - .distributionFlag(BIG_CREATION) - .mailbox(MailboxConfig.builder() - .name("net_kernel") - .build()) - .mailbox(MailboxConfig.builder() - .build()) - .mailbox(MailboxConfig.builder() - .name("another") - .build()) - .server(ServerConfig.builder() - .port(8971) - .bossThreads(1) - .workerThreads(2) - .build()) - .build() - ) - .node("node-2", NodeConfig.builder() - .cookie("popa") - .mailbox(MailboxConfig.builder() - .name("net_kernel") - .build()) - .build() - ) - .build(); - - - Defaults defaults = config.getDefaults(); - assertThat(defaults) - .isNotNull(); - - SoftAssertions.assertSoftly(softly -> { - softly.assertThat(defaults.getEpmdPort()) - .isEqualTo(8888); - - softly.assertThat(defaults.getType()) - .isEqualTo(R3_ERLANG); - - softly.assertThat(defaults.getShortName()) - .isTrue(); - - softly.assertThat(defaults.getCookie()) - .isEqualTo("secret"); - - softly.assertThat(defaults.getProtocol()) - .isEqualTo(UDP); - - softly.assertThat(defaults.getLowVersion()) - .isEqualTo(R4); - - softly.assertThat(defaults.getHighVersion()) - .isEqualTo(R6); - - softly.assertThat(defaults.getDistributionFlags()) - .contains(MAP_TAG, BIG_CREATION); - - softly.assertThat(defaults.getMailbox()) - .isNotNull(); - - softly.assertThat(defaults.getServer()) - .isNotNull(); - - softly.assertThat(defaults.getServer().getPort()) - .isNull(); - - softly.assertThat(defaults.getServer().getBossThreads()) - .isEqualTo(2); - - softly.assertThat(defaults.getServer().getWorkerThreads()) - .isEqualTo(4); - }); - - Map nodes = config.getNodes(); - assertThat(nodes).isNotNull(); - - NodeConfig node1 = nodes.get("node-1"); - assertThat(node1).isNotNull(); - - SoftAssertions.assertSoftly(softly -> { - softly.assertThat(node1.getEpmdPort()) - .isEqualTo(7373); - - softly.assertThat(node1.getType()) - .isEqualTo(R3_HIDDEN); - - softly.assertThat(node1.getShortName()) - .isFalse(); - - softly.assertThat(node1.getCookie()) - .isEqualTo("non-secret"); - - softly.assertThat(node1.getProtocol()) - .isEqualTo(SCTP); - - softly.assertThat(node1.getLowVersion()) - .isEqualTo(R5C); - - softly.assertThat(node1.getHighVersion()) - .isEqualTo(R6); - - softly.assertThat(node1.getDistributionFlags()).contains( - EXTENDED_REFERENCES, - EXTENDED_PIDS_PORTS, - BIT_BINARIES, - NEW_FLOATS, - FUN_TAGS, - NEW_FUN_TAGS, - UTF8_ATOMS, - MAP_TAG, - BIG_CREATION - ); - - softly.assertThat(node1.getMailboxes()) - .isNotEmpty(); - - MailboxConfig mailbox1 = node1.getMailboxes() - .stream() - .filter(it -> "net_kernel".equals(it.getName())) - .findFirst() - .orElse(null); - assertThat(mailbox1).isNotNull(); - - MailboxConfig mailbox2 = node1.getMailboxes() - .stream() - .filter(it -> it.getName() == null) - .findFirst() - .orElse(null); - assertThat(mailbox2).isNotNull(); - - MailboxConfig mailbox3 = node1.getMailboxes() - .stream() - .filter(it -> "another".equals(it.getName())) - .findFirst() - .orElse(null); - assertThat(mailbox3).isNotNull(); - - softly.assertThat(node1.getServer()) - .isNotNull(); - - softly.assertThat(node1.getServer().getPort()) - .isEqualTo(8971); - - softly.assertThat(node1.getServer().getBossThreads()) - .isEqualTo(1); - - softly.assertThat(node1.getServer().getWorkerThreads()) - .isEqualTo(2); - }); - - NodeConfig node2 = nodes.get("node-2"); - assertThat(node2).isNotNull(); - - SoftAssertions.assertSoftly(softly -> { - softly.assertThat(node2.getEpmdPort()) - .isEqualTo(8888); - - softly.assertThat(node2.getType()) - .isEqualTo(R3_ERLANG); - - softly.assertThat(node2.getShortName()) - .isTrue(); - - softly.assertThat(node2.getCookie()) - .isEqualTo("popa"); - - softly.assertThat(node2.getProtocol()) - .isEqualTo(UDP); - - softly.assertThat(node2.getLowVersion()) - .isEqualTo(R4); - - softly.assertThat(node2.getHighVersion()) - .isEqualTo(R6); - - softly.assertThat(node2.getDistributionFlags()).contains( - MAP_TAG, - BIG_CREATION - ); - - softly.assertThat(node2.getMailboxes()) - .isNotEmpty(); - - MailboxConfig mailbox1 = node2.getMailboxes() - .stream() - .filter(it -> "net_kernel".equals(it.getName())) - .findFirst() - .orElse(null); - assertThat(mailbox1).isNotNull(); - - softly.assertThat(node2.getServer()) - .isNotNull(); - - softly.assertThat(node2.getServer().getPort()) - .isNotNull(); - - softly.assertThat(node2.getServer().getBossThreads()) - .isEqualTo(2); - - softly.assertThat(node2.getServer().getWorkerThreads()) - .isEqualTo(4); - }); - } -} diff --git a/encon-config/src/test/java/io/appulse/encon/config/DumpTest.java b/encon-config/src/test/java/io/appulse/encon/config/DumpTest.java new file mode 100644 index 0000000..d1e6c2f --- /dev/null +++ b/encon-config/src/test/java/io/appulse/encon/config/DumpTest.java @@ -0,0 +1,122 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config; + +import static java.util.Comparator.reverseOrder; +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import io.appulse.utils.ResourceUtils; + +import lombok.SneakyThrows; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +public class DumpTest { + + static Path FOLDER; + + @BeforeClass + @SneakyThrows + public static void beforeClass () { + FOLDER = Paths.get("dump_test_folder"); + + if (Files.exists(FOLDER)) { + Files.walk(FOLDER) + .map(Path::toFile) + .sorted(reverseOrder()) + .forEach(File::delete); + } + Files.createDirectories(FOLDER); + } + + @AfterClass + @SneakyThrows + public static void afterClass () { + FOLDER = Paths.get("dump_test_folder"); + + if (Files.exists(FOLDER)) { + Files.walk(FOLDER) + .map(Path::toFile) + .sorted(reverseOrder()) + .forEach(File::delete); + } + Files.deleteIfExists(FOLDER); + } + + @Test + public void dumpFileName () { + ResourceUtils.getResourceUrls("dump", "file.*").forEach(url -> { + Config config1 = Config.load(url); + + String name = url.getPath().endsWith(".yml") + ? "file_name-dump.yml" + : "file_name-dump.properties"; + + Path dumpPath = FOLDER.resolve(name); + config1.dumpTo(dumpPath.toString()); + + Config config2 = Config.load(dumpPath); + assertThat(config2).isEqualTo(config1); + }); + } + + @Test + public void dumpFile () { + ResourceUtils.getResourceUrls("dump", "file.*").forEach(url -> { + Config config1 = Config.load(url); + + String name = url.getPath().endsWith(".yml") + ? "file-dump.yml" + : "file-dump.properties"; + + Path dumpPath = FOLDER.resolve(name); + config1.dumpTo(dumpPath.toFile()); + + Config config2 = Config.load(dumpPath); + assertThat(config2).isEqualTo(config1); + }); + } + + @Test + public void dumpPath () { + ResourceUtils.getResourceUrls("dump", "file.*").forEach(url -> { + Config config1 = Config.load(url); + + String name = url.getPath().endsWith(".yml") + ? "path-dump.yml" + : "path-dump.properties"; + + Path dumpPath = FOLDER.resolve(name); + config1.dumpTo(dumpPath); + + Config config2 = Config.load(dumpPath); + assertThat(config2).isEqualTo(config1); + }); + } +} diff --git a/encon-config/src/test/java/io/appulse/encon/config/GetBooleanTest.java b/encon-config/src/test/java/io/appulse/encon/config/GetBooleanTest.java new file mode 100644 index 0000000..70470c2 --- /dev/null +++ b/encon-config/src/test/java/io/appulse/encon/config/GetBooleanTest.java @@ -0,0 +1,66 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config; + +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; +import static org.assertj.core.api.Assertions.assertThat; + +import java.net.URL; + +import io.appulse.utils.ResourceUtils; + +import org.junit.Test; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +public class GetBooleanTest { + + @Test + public void test () { + URL url = ResourceUtils.getResourceUrls("", "boolean.yml").get(0); + Config config = Config.load(url); + + assertThat(config.getBoolean("one")) + .isPresent().hasValue(TRUE); + assertThat(config.getBoolean("two")) + .isPresent().hasValue(FALSE); + + assertThat(config.getBoolean("three")) + .isPresent().hasValue(TRUE); + assertThat(config.getBoolean("four")) + .isPresent().hasValue(FALSE); + + assertThat(config.getBoolean("five")) + .isPresent().hasValue(TRUE); + assertThat(config.getBoolean("six")) + .isPresent().hasValue(FALSE); + + assertThat(config.getBoolean("seven")) + .isPresent().hasValue(TRUE); + assertThat(config.getBoolean("eight")) + .isPresent().hasValue(TRUE); + + assertThat(config.getBoolean("nine")) + .isPresent().hasValue(FALSE); + assertThat(config.getBoolean("ten")) + .isPresent().hasValue(FALSE); + } +} diff --git a/encon-config/src/test/java/io/appulse/encon/config/GetByteTest.java b/encon-config/src/test/java/io/appulse/encon/config/GetByteTest.java new file mode 100644 index 0000000..91ff7b8 --- /dev/null +++ b/encon-config/src/test/java/io/appulse/encon/config/GetByteTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.net.URL; + +import io.appulse.utils.ResourceUtils; + +import org.junit.Test; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +public class GetByteTest { + + @Test + public void test () { + URL url = ResourceUtils.getResourceUrls("", "byte.yml").get(0); + Config config = Config.load(url); + + assertThat(config.getByte("one")) + .isPresent().hasValue((byte) 0); + assertThat(config.getByte("two")) + .isPresent().hasValue((byte) -128); + assertThat(config.getByte("three")) + .isPresent().hasValue((byte) 127); + + assertThatThrownBy(() -> config.getByte("four")) + .isInstanceOf(NumberFormatException.class) + .hasMessage("Value out of range. Value:\"128\" Radix:10"); + + assertThatThrownBy(() -> config.getByte("five")) + .isInstanceOf(NumberFormatException.class) + .hasMessage("Value out of range. Value:\"-129\" Radix:10"); + } +} diff --git a/encon-config/src/main/java/io/appulse/encon/config/ServerPortGenerator.java b/encon-config/src/test/java/io/appulse/encon/config/GetCharTest.java similarity index 56% rename from encon-config/src/main/java/io/appulse/encon/config/ServerPortGenerator.java rename to encon-config/src/test/java/io/appulse/encon/config/GetCharTest.java index 91f6d90..55eaab8 100644 --- a/encon-config/src/main/java/io/appulse/encon/config/ServerPortGenerator.java +++ b/encon-config/src/test/java/io/appulse/encon/config/GetCharTest.java @@ -16,31 +16,32 @@ package io.appulse.encon.config; -import java.util.concurrent.atomic.AtomicInteger; +import static org.assertj.core.api.Assertions.assertThat; -import io.appulse.utils.SocketUtils; +import java.net.URL; -import lombok.val; +import io.appulse.utils.ResourceUtils; + +import org.junit.Test; /** * - * @since 1.0.0 * @author Artem Labazin + * @since 2.0.0 */ -final class ServerPortGenerator { - - private static final AtomicInteger UPPER_BOUND = new AtomicInteger(65535); - - static int nextPort () { - while (true) { - val currentValue = UPPER_BOUND.get(); - val port = SocketUtils.findFreePort(1024, currentValue - 1).get(); - if (UPPER_BOUND.compareAndSet(currentValue, port)) { - return port; - } - } - } +public class GetCharTest { + + @Test + public void test () { + URL url = ResourceUtils.getResourceUrls("", "char.yml").get(0); + Config config = Config.load(url); + + assertThat(config.getChar("one")) + .isPresent() + .hasValue('y'); - private ServerPortGenerator () { + assertThat(config.getChar("two")) + .isPresent() + .hasValue('p'); } } diff --git a/encon-config/src/test/java/io/appulse/encon/config/GetDoubleTest.java b/encon-config/src/test/java/io/appulse/encon/config/GetDoubleTest.java new file mode 100644 index 0000000..89e1455 --- /dev/null +++ b/encon-config/src/test/java/io/appulse/encon/config/GetDoubleTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.net.URL; + +import io.appulse.utils.ResourceUtils; + +import org.junit.Test; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +public class GetDoubleTest { + + @Test + public void test () { + URL url = ResourceUtils.getResourceUrls("", "double.yml").get(0); + Config config = Config.load(url); + + assertThat(config.getDouble("one")) + .isPresent().hasValue(0D); + assertThat(config.getDouble("two")) + .isPresent().hasValue(0x0.0000000000001P-1022); + assertThat(config.getDouble("three")) + .isPresent().hasValue(0x1.fffffffffffffP+1023); + + assertThatThrownBy(() -> config.getDouble("four")) + .isInstanceOf(NumberFormatException.class) + .hasMessage("For input string: \"popa\""); + } +} diff --git a/encon-config/src/test/java/io/appulse/encon/config/GetFloatTest.java b/encon-config/src/test/java/io/appulse/encon/config/GetFloatTest.java new file mode 100644 index 0000000..ff96625 --- /dev/null +++ b/encon-config/src/test/java/io/appulse/encon/config/GetFloatTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.net.URL; + +import io.appulse.utils.ResourceUtils; + +import org.junit.Test; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +public class GetFloatTest { + + @Test + public void test () { + URL url = ResourceUtils.getResourceUrls("", "float.yml").get(0); + Config config = Config.load(url); + + assertThat(config.getFloat("one")) + .isPresent().hasValue(0F); + assertThat(config.getFloat("two")) + .isPresent().hasValue(0x0.000002P-126F); + assertThat(config.getFloat("three")) + .isPresent().hasValue(0x1.fffffeP+127F); + + assertThatThrownBy(() -> config.getFloat("four")) + .isInstanceOf(NumberFormatException.class) + .hasMessage("For input string: \"popa\""); + } +} diff --git a/encon-config/src/test/java/io/appulse/encon/config/GetIntegerTest.java b/encon-config/src/test/java/io/appulse/encon/config/GetIntegerTest.java new file mode 100644 index 0000000..468137c --- /dev/null +++ b/encon-config/src/test/java/io/appulse/encon/config/GetIntegerTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.net.URL; + +import io.appulse.utils.ResourceUtils; + +import org.junit.Test; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +public class GetIntegerTest { + + @Test + public void test () { + URL url = ResourceUtils.getResourceUrls("", "int.yml").get(0); + Config config = Config.load(url); + + assertThat(config.getInteger("one")) + .isPresent().hasValue(0); + assertThat(config.getInteger("two")) + .isPresent().hasValue(-2147483648); + assertThat(config.getInteger("three")) + .isPresent().hasValue(2147483647); + + assertThatThrownBy(() -> config.getInteger("four")) + .isInstanceOf(NumberFormatException.class) + .hasMessage("For input string: \"2147483648\""); + + assertThatThrownBy(() -> config.getInteger("five")) + .isInstanceOf(NumberFormatException.class) + .hasMessage("For input string: \"-2147483649\""); + } +} diff --git a/encon-config/src/test/java/io/appulse/encon/config/GetLongTest.java b/encon-config/src/test/java/io/appulse/encon/config/GetLongTest.java new file mode 100644 index 0000000..2c9df1a --- /dev/null +++ b/encon-config/src/test/java/io/appulse/encon/config/GetLongTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.net.URL; + +import io.appulse.utils.ResourceUtils; + +import org.junit.Test; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +public class GetLongTest { + + @Test + public void test () { + URL url = ResourceUtils.getResourceUrls("", "long.yml").get(0); + Config config = Config.load(url); + + assertThat(config.getLong("one")) + .isPresent().hasValue(0L); + assertThat(config.getLong("two")) + .isPresent().hasValue(-9223372036854775808L); + assertThat(config.getLong("three")) + .isPresent().hasValue(9223372036854775807L); + + assertThatThrownBy(() -> config.getLong("four")) + .isInstanceOf(NumberFormatException.class) + .hasMessage("For input string: \"9223372036854775808\""); + + assertThatThrownBy(() -> config.getLong("five")) + .isInstanceOf(NumberFormatException.class) + .hasMessage("For input string: \"-9223372036854775809\""); + } +} diff --git a/encon-config/src/test/java/io/appulse/encon/config/GetObjectTest.java b/encon-config/src/test/java/io/appulse/encon/config/GetObjectTest.java new file mode 100644 index 0000000..245fb2b --- /dev/null +++ b/encon-config/src/test/java/io/appulse/encon/config/GetObjectTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.net.URL; +import java.util.List; +import java.util.Map; + +import io.appulse.utils.ResourceUtils; + +import org.junit.Test; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +public class GetObjectTest { + + @Test + public void test () { + URL url = ResourceUtils.getResourceUrls("", "object.yml").get(0); + Config config = Config.load(url); + + assertThat(config.get("one")) + .isPresent() + .get() + .isInstanceOf(Number.class); + assertThat(config.get("two")) + .isPresent() + .get() + .isInstanceOf(String.class); + assertThat(config.get("three")) + .isPresent() + .get() + .isInstanceOf(Boolean.class); + assertThat(config.get("four")) + .isPresent() + .get() + .isInstanceOf(List.class); + assertThat(config.get("five")) + .isPresent() + .get() + .isInstanceOf(Map.class); + } +} diff --git a/encon-config/src/test/java/io/appulse/encon/config/GetPojoTest.java b/encon-config/src/test/java/io/appulse/encon/config/GetPojoTest.java new file mode 100644 index 0000000..fc357f0 --- /dev/null +++ b/encon-config/src/test/java/io/appulse/encon/config/GetPojoTest.java @@ -0,0 +1,239 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config; + +import static java.lang.Boolean.FALSE; +import static lombok.AccessLevel.PRIVATE; +import static io.appulse.encon.config.GetPojoTest.Flag.ONE; +import static io.appulse.encon.config.GetPojoTest.Flag.TWO; +import static io.appulse.encon.config.GetPojoTest.Flag.THREE; +import static org.assertj.core.api.Assertions.assertThat; + +import java.net.URL; +import java.util.List; +import java.util.Map; + +import io.appulse.utils.ResourceUtils; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.Singular; +import lombok.experimental.FieldDefaults; +import lombok.extern.slf4j.Slf4j; + +import org.junit.Test; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +@Slf4j +public class GetPojoTest { + + static NodesConfig.NodeConfig.MailboxConfig NODE_1_MAILBOX = NodesConfig.NodeConfig.MailboxConfig.builder() + .name("popa") + .build(); + + static NodesConfig.NodeConfig NODE_CONFIG_1 = NodesConfig.NodeConfig.builder() + .shortName(Boolean.TRUE) + .cookie("secret") + .clearFlags().flag(ONE).flag(THREE) + .mailbox("mailbox-1", NodesConfig.NodeConfig.MailboxConfig.builder().build()) + .mailbox("mailbox-2", NODE_1_MAILBOX) + .build(); + + static NodesConfig.NodeConfig NODE_CONFIG_2 = NodesConfig.NodeConfig.builder() + .epmdPort(1234) + .clearFlags().flag(TWO) + .mailbox("mailbox-3", NodesConfig.NodeConfig.MailboxConfig.builder().build()) + .build(); + + static NodesConfig NODES_CONFIG = NodesConfig.builder() + .node("node-1", NODE_CONFIG_1) + .node("node-2", NODE_CONFIG_2) + .build(); + + static HandlersConfig.MailboxesConfig.MailboxConfig HANDLER_NODE_1_MAILBOX_1 = HandlersConfig.MailboxesConfig.MailboxConfig.builder() + .handler("handler-1") + .build(); + + static HandlersConfig.MailboxesConfig.MailboxConfig HANDLER_NODE_1_MAILBOX_2 = HandlersConfig.MailboxesConfig.MailboxConfig.builder() + .handler("handler-2") + .build(); + + static HandlersConfig.MailboxesConfig HANDLER_NODE_1 = HandlersConfig.MailboxesConfig.builder() + .mailbox("mailbox-1", HANDLER_NODE_1_MAILBOX_1) + .mailbox("mailbox-2", HANDLER_NODE_1_MAILBOX_2) + .build(); + + static HandlersConfig.MailboxesConfig.MailboxConfig HANDLER_NODE_2_MAILBOX_1 = HandlersConfig.MailboxesConfig.MailboxConfig.builder() + .handler("handler-3") + .build(); + + static HandlersConfig.MailboxesConfig HANDLER_NODE_2 = HandlersConfig.MailboxesConfig.builder() + .mailbox("mailbox-3", HANDLER_NODE_2_MAILBOX_1) + .build(); + + static HandlersConfig HANDLER = HandlersConfig.builder() + .node("node-1", HANDLER_NODE_1) + .node("node-2", HANDLER_NODE_2) + .build(); + + @Test + public void loadYamlTest () { + URL url = ResourceUtils.getResourceUrls("", "pojo.yml").get(0); + Config config = Config.load(url); + + validate(config); + } + + @Test + public void programmaticalTest () { + Config config = Config.builder() + .config(NODES_CONFIG) + .config(HANDLER) + .build(); + + validate(config); + } + + private void validate (Config config) { + try { + assertThat(config.get("nodes.node-1.mailboxes.mailbox-2", NodesConfig.NodeConfig.MailboxConfig.class)) + .hasValue(NODE_1_MAILBOX); + + assertThat(config.get("nodes.node-1", NodesConfig.NodeConfig.class)) + .hasValue(NODE_CONFIG_1); + + assertThat(config.get("nodes.node-2", NodesConfig.NodeConfig.class)) + .hasValue(NODE_CONFIG_2); + + assertThat(config.get(NodesConfig.class)) + .hasValue(NODES_CONFIG); + + + assertThat(config.get("nodes.node-1.mailboxes.mailbox-1", HandlersConfig.MailboxesConfig.MailboxConfig.class)) + .hasValue(HANDLER_NODE_1_MAILBOX_1); + + assertThat(config.get("nodes.node-1.mailboxes.mailbox-2", HandlersConfig.MailboxesConfig.MailboxConfig.class)) + .hasValue(HANDLER_NODE_1_MAILBOX_2); + + assertThat(config.get("nodes.node-2.mailboxes.mailbox-3", HandlersConfig.MailboxesConfig.MailboxConfig.class)) + .hasValue(HANDLER_NODE_2_MAILBOX_1); + + assertThat(config.get("nodes.node-1", HandlersConfig.MailboxesConfig.class)) + .hasValue(HANDLER_NODE_1); + + assertThat(config.get("nodes.node-2", HandlersConfig.MailboxesConfig.class)) + .hasValue(HANDLER_NODE_2); + + assertThat(config.get(HandlersConfig.class)) + .hasValue(HANDLER); + } catch (AssertionError ex) { + log.error("configuration\n{}", config); + throw ex; + } + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + @FieldDefaults(level = PRIVATE) + public static class HandlersConfig { + + @Singular + Map nodes; + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + @FieldDefaults(level = PRIVATE) + public static class MailboxesConfig { + + @Singular + Map mailboxes; + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + @FieldDefaults(level = PRIVATE) + public static class MailboxConfig { + + String handler; + } + } + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + @FieldDefaults(level = PRIVATE) + public static class NodesConfig { + + @Singular + Map nodes; + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + @FieldDefaults(level = PRIVATE) + public static class NodeConfig { + + @Builder.Default + Integer epmdPort = 6435; + + @Builder.Default + Boolean shortName = FALSE; + + @Builder.Default + String cookie = ""; + + @Singular + List flags; + + @Singular + Map mailboxes; + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + @FieldDefaults(level = PRIVATE) + public static class MailboxConfig { + + String name; + } + + + } + } + + public enum Flag { + + ONE, + TWO, + THREE; + } +} diff --git a/encon-config/src/test/java/io/appulse/encon/config/GetShortTest.java b/encon-config/src/test/java/io/appulse/encon/config/GetShortTest.java new file mode 100644 index 0000000..a61a6d6 --- /dev/null +++ b/encon-config/src/test/java/io/appulse/encon/config/GetShortTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.net.URL; + +import io.appulse.utils.ResourceUtils; + +import org.junit.Test; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +public class GetShortTest { + + @Test + public void test () { + URL url = ResourceUtils.getResourceUrls("", "short.yml").get(0); + Config config = Config.load(url); + + assertThat(config.getShort("one")) + .isPresent().hasValue((short) 0); + assertThat(config.getShort("two")) + .isPresent().hasValue((short) -32768); + assertThat(config.getShort("three")) + .isPresent().hasValue((short) 32767); + + assertThatThrownBy(() -> config.getShort("four")) + .isInstanceOf(NumberFormatException.class) + .hasMessage("Value out of range. Value:\"32768\" Radix:10"); + + assertThatThrownBy(() -> config.getShort("five")) + .isInstanceOf(NumberFormatException.class) + .hasMessage("Value out of range. Value:\"-32769\" Radix:10"); + } +} diff --git a/encon-config/src/test/java/io/appulse/encon/config/GetStringTest.java b/encon-config/src/test/java/io/appulse/encon/config/GetStringTest.java new file mode 100644 index 0000000..1c4e309 --- /dev/null +++ b/encon-config/src/test/java/io/appulse/encon/config/GetStringTest.java @@ -0,0 +1,44 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.net.URL; + +import io.appulse.utils.ResourceUtils; + +import org.junit.Test; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +public class GetStringTest { + + @Test + public void test () { + URL url = ResourceUtils.getResourceUrls("", "string.yml").get(0); + Config config = Config.load(url); + + assertThat(config.getString("one")) + .isPresent().hasValue("popa"); + assertThat(config.getString("two")) + .isPresent().hasValue("3"); + } +} diff --git a/encon-config/src/test/java/io/appulse/encon/config/LoadTest.java b/encon-config/src/test/java/io/appulse/encon/config/LoadTest.java new file mode 100644 index 0000000..bc28dfb --- /dev/null +++ b/encon-config/src/test/java/io/appulse/encon/config/LoadTest.java @@ -0,0 +1,189 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon.config; + +import static java.util.Arrays.asList; +import static java.util.stream.Collectors.toList; +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.net.URI; +import java.net.URL; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import io.appulse.encon.config.exception.ConfigLoadingFileNotFoundException; +import io.appulse.utils.ResourceUtils; + +import lombok.SneakyThrows; +import org.junit.Test; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +public class LoadTest { + + @Test(expected = ConfigLoadingFileNotFoundException.class) + public void loadNonexistentFile () { + Config.load("nonexistent.yml"); + } + + @Test + public void loadMap () { + Map subMap = new HashMap<>(); + subMap.put("name", "popa"); + subMap.put("my.age", 11); + + Map map = new HashMap<>(); + map.put("one.two.three.four", 4); + map.put("one.two.three.five.six", 6); + map.put("one.two.three.seven", asList(1, 2, 3, subMap)); + map.put("zero", 0); + + Config config = Config.load(map); + checkConfig(config, ""); + } + +// @Test + public void loadProperties () { + Properties properties = new Properties(); + properties.put("one.two.three.four", 4); + properties.put("one.two.three.five.six", 6); + properties.put("one.two.three.seven.[0]", 1); + properties.put("one.two.three.seven.1", 2); + properties.put("one.two.three.seven.[2]", 3); + properties.put("one.two.three.seven.3.name", "popa"); + properties.put("one.two.three.seven.[3].my.age", 11); + properties.put("zero", 0); + + Config config = Config.load(properties); + checkConfig(config, ""); + } + + @Test + public void loadUrl () { + getUrlFiles().forEach(url -> { + Config config = Config.load(url); + checkConfig(config, url.toString()); + }); + } + + @Test + public void loadUri () { + getUriFiles().forEach(uri -> { + Config config = Config.load(uri); + checkConfig(config, uri.toString()); + }); + } + + @Test + public void loadFile () { + getUriFiles().stream().map(File::new).forEach(file -> { + Config config = Config.load(file); + checkConfig(config, file.toString()); + }); + } + + @Test + public void loadPath () { + getUriFiles().stream().map(Paths::get).forEach(path -> { + Config config = Config.load(path); + checkConfig(config, path.toString()); + }); + } + + @Test + public void loadFileName () { + getUriFiles().stream().map(Paths::get).map(Path::toString).forEach(fileName -> { + Config config = Config.load(fileName); + checkConfig(config, fileName); + }); + } + + private void checkConfig (Config config, String file) { + assertThat(config).isNotNull(); + + assertThat(config.getString("one.two.three.four")) + .as("Key 'one.two.three.four' at file %s", file) + .isPresent() + .hasValue("4"); + + assertThat(config.getString("one.two.three.five.six")) + .as("Key 'one.two.three.five.six' at file %s", file) + .isPresent() + .hasValue("6"); + + assertThat(config.get("one.two.three.seven")) + .as("Key 'one.two.three.seven' at file %s", file) + .isPresent() + .get() + .isInstanceOf(List.class); + + assertThat(config.getString("one.two.three.seven.0")) + .as("Key 'one.two.three.seven.0' at file %s", file) + .isPresent() + .hasValue("1"); + + assertThat(config.getString("one.two.three.seven.[1]")) + .as("Key 'one.two.three.seven.[1]' at file %s", file) + .isPresent() + .hasValue("2"); + + assertThat(config.getString("one.two.three.seven.2")) + .as("Key 'one.two.three.seven.2' at file %s", file) + .isPresent() + .hasValue("3"); + + assertThat(config.getString("one.two.three.seven.[3].name")) + .as("Key 'one.two.three.seven.[3].name' at file %s", file) + .isPresent() + .hasValue("popa"); + + assertThat(config.getString("one.two.three.seven.3.my.age")) + .as("Key 'one.two.three.seven.3.my.age' at file %s", file) + .isPresent() + .hasValue("11"); + + assertThat(config.getString("zero")) + .as("Key 'zero' at file %s", file) + .isPresent() + .hasValue("0"); + } + + @SneakyThrows + private List getUriFiles () { + return getUrlFiles().stream() + .map(it -> { + try { + return it.toURI(); + } catch (Exception ex) { + return null; + } + }) + .collect(toList()); + } + + private List getUrlFiles () { + return ResourceUtils.getResourceUrls("load", "file.y*"); + } +} diff --git a/encon-config/src/test/resources/boolean.yml b/encon-config/src/test/resources/boolean.yml new file mode 100644 index 0000000..2d9f173 --- /dev/null +++ b/encon-config/src/test/resources/boolean.yml @@ -0,0 +1,15 @@ + +one: true +two: false + +three: yes +four: no + +five: 1 +six: 0 + +seven: tRuE +eight: YeS + +nine: 2 +ten: -1 \ No newline at end of file diff --git a/encon-config/src/test/resources/byte.yml b/encon-config/src/test/resources/byte.yml new file mode 100644 index 0000000..f567e4e --- /dev/null +++ b/encon-config/src/test/resources/byte.yml @@ -0,0 +1,6 @@ + +one: 0 +two: -128 +three: 127 +four: 128 +five: -129 \ No newline at end of file diff --git a/encon-config/src/test/resources/char.yml b/encon-config/src/test/resources/char.yml new file mode 100644 index 0000000..916354d --- /dev/null +++ b/encon-config/src/test/resources/char.yml @@ -0,0 +1,3 @@ + +one: y +two: popa \ No newline at end of file diff --git a/encon-config/src/test/resources/connector.yml b/encon-config/src/test/resources/connector.yml deleted file mode 100644 index 8437261..0000000 --- a/encon-config/src/test/resources/connector.yml +++ /dev/null @@ -1,48 +0,0 @@ - -defaults: - epmd-port: 8888 - type: R3_ERLANG - short-name: true - cookie: secret - protocol: UDP - low-version: R4 - high-version: R6 - distribution-flags: - - MAP_TAG - - BIG_CREATION - server: - boss-threads: 2 - worker-threads: 4 - -nodes: - node-1: - epmd-port: 7373 - type: R3_HIDDEN - cookie: non-secret - protocol: SCTP - low-version: R5C - high-version: R6 - distribution-flags: - - EXTENDED_REFERENCES - - EXTENDED_PIDS_PORTS - - BIT_BINARIES - - NEW_FLOATS - - FUN_TAGS - - NEW_FUN_TAGS - - UTF8_ATOMS - - MAP_TAG - - BIG_CREATION - mailboxes: - - name: net_kernel - - name: another - - name: another_one - server: - port: 8971 - boss-threads: 1 - worker-threads: 2 - - node-2: - short-name: false - cookie: popa - mailboxes: - - name: net_kernel diff --git a/encon-config/src/test/resources/double.yml b/encon-config/src/test/resources/double.yml new file mode 100644 index 0000000..92918bc --- /dev/null +++ b/encon-config/src/test/resources/double.yml @@ -0,0 +1,5 @@ + +one: 0 +two: 4.9E-324 +three: 1.7976931348623157E308 +four: popa \ No newline at end of file diff --git a/encon-config/src/test/resources/dump/back-file.properties b/encon-config/src/test/resources/dump/back-file.properties new file mode 100644 index 0000000..897c57b --- /dev/null +++ b/encon-config/src/test/resources/dump/back-file.properties @@ -0,0 +1,5 @@ + +one.two.three=3 + +zero=0 +popa=popa diff --git a/encon-config/src/test/resources/dump/file.yml b/encon-config/src/test/resources/dump/file.yml new file mode 100644 index 0000000..ae1a8a7 --- /dev/null +++ b/encon-config/src/test/resources/dump/file.yml @@ -0,0 +1,12 @@ + +one.two.three: + four: 4 + five.six: 6 + seven: + - 1 + - 2 + - 3 + - name: popa + my.age: 11 + +zero: 0 \ No newline at end of file diff --git a/encon-config/src/test/resources/float.yml b/encon-config/src/test/resources/float.yml new file mode 100644 index 0000000..4371bff --- /dev/null +++ b/encon-config/src/test/resources/float.yml @@ -0,0 +1,5 @@ + +one: 0 +two: 1.4E-45 +three: 3.4028235E38 +four: popa \ No newline at end of file diff --git a/encon-config/src/test/resources/int.yml b/encon-config/src/test/resources/int.yml new file mode 100644 index 0000000..b3ccf21 --- /dev/null +++ b/encon-config/src/test/resources/int.yml @@ -0,0 +1,6 @@ + +one: 0 +two: -2147483648 +three: 2147483647 +four: 2147483648 +five: -2147483649 \ No newline at end of file diff --git a/encon-config/src/test/resources/load/file.properties b/encon-config/src/test/resources/load/file.properties new file mode 100644 index 0000000..fb22127 --- /dev/null +++ b/encon-config/src/test/resources/load/file.properties @@ -0,0 +1,10 @@ + +one.two.three.four=4 +one.two.three.five.six=6 +one.two.three.seven.[0]=1 +one.two.three.seven.1=2 +one.two.three.seven.[2]=3 +one.two.three.seven.3.name=popa +one.two.three.seven.[3].my.age=11 + +zero=0 diff --git a/encon-config/src/test/resources/load/file.xml b/encon-config/src/test/resources/load/file.xml new file mode 100644 index 0000000..14dac07 --- /dev/null +++ b/encon-config/src/test/resources/load/file.xml @@ -0,0 +1,12 @@ + + + + 4 + 6 + 1 + 2 + 3 + popa + 11 + 0 + \ No newline at end of file diff --git a/encon-config/src/test/resources/load/file.yaml b/encon-config/src/test/resources/load/file.yaml new file mode 100644 index 0000000..ae1a8a7 --- /dev/null +++ b/encon-config/src/test/resources/load/file.yaml @@ -0,0 +1,12 @@ + +one.two.three: + four: 4 + five.six: 6 + seven: + - 1 + - 2 + - 3 + - name: popa + my.age: 11 + +zero: 0 \ No newline at end of file diff --git a/encon-config/src/test/resources/load/file.yml b/encon-config/src/test/resources/load/file.yml new file mode 100644 index 0000000..ae1a8a7 --- /dev/null +++ b/encon-config/src/test/resources/load/file.yml @@ -0,0 +1,12 @@ + +one.two.three: + four: 4 + five.six: 6 + seven: + - 1 + - 2 + - 3 + - name: popa + my.age: 11 + +zero: 0 \ No newline at end of file diff --git a/encon-config/src/test/resources/long.yml b/encon-config/src/test/resources/long.yml new file mode 100644 index 0000000..443e568 --- /dev/null +++ b/encon-config/src/test/resources/long.yml @@ -0,0 +1,6 @@ + +one: 0 +two: -9223372036854775808 +three: 9223372036854775807 +four: 9223372036854775808 +five: -9223372036854775809 \ No newline at end of file diff --git a/encon-config/src/test/resources/object.yml b/encon-config/src/test/resources/object.yml new file mode 100644 index 0000000..9bd653d --- /dev/null +++ b/encon-config/src/test/resources/object.yml @@ -0,0 +1,11 @@ + +one: 1 +two: hello +three: false +four: + - 1 + - 2 + - 3 +five: + age: 11 + name: popa \ No newline at end of file diff --git a/encon-config/src/test/resources/pojo.yml b/encon-config/src/test/resources/pojo.yml new file mode 100644 index 0000000..ffcae38 --- /dev/null +++ b/encon-config/src/test/resources/pojo.yml @@ -0,0 +1,25 @@ + +nodes: + node-1: + shortName: true + cookie: secret + flags: + - ONE + - THREE + + mailboxes: + + mailbox-1: + handler: handler-1 + + mailbox-2: + name: popa + handler: handler-2 + + node-2: + epmdPort: 1234 + flags: + - TWO + mailboxes: + mailbox-3: + handler: handler-3 diff --git a/encon-config/src/test/resources/short.yml b/encon-config/src/test/resources/short.yml new file mode 100644 index 0000000..8a53920 --- /dev/null +++ b/encon-config/src/test/resources/short.yml @@ -0,0 +1,6 @@ + +one: 0 +two: -32768 +three: 32767 +four: 32768 +five: -32769 \ No newline at end of file diff --git a/encon-config/src/test/resources/string.yml b/encon-config/src/test/resources/string.yml new file mode 100644 index 0000000..fae0d82 --- /dev/null +++ b/encon-config/src/test/resources/string.yml @@ -0,0 +1,3 @@ + +one: popa +two: 3 \ No newline at end of file diff --git a/encon-databind/README.md b/encon-databind/README.md index ca4b5c8..f54096f 100644 --- a/encon-databind/README.md +++ b/encon-databind/README.md @@ -14,12 +14,12 @@ First of all, add databind's dependency: io.appulse.encon encon - 1.6.5 + 2.0.0 io.appulse.encon encon-databind - 1.6.5 + 2.0.0 ... @@ -28,8 +28,8 @@ First of all, add databind's dependency: **Gradle**: ```groovy -compile 'io.appulse.encon:encon:1.6.5' -compile 'io.appulse.encon:encon-databind:1.6.5' +compile 'io.appulse.encon:encon:2.0.0' +compile 'io.appulse.encon:encon-databind:2.0.0' ``` Let's imagine, you have POJO like this: diff --git a/encon-databind/pom.xml b/encon-databind/pom.xml index 07463cd..308f588 100644 --- a/encon-databind/pom.xml +++ b/encon-databind/pom.xml @@ -25,7 +25,7 @@ limitations under the License. io.appulse.encon encon-parent - 1.6.5 + 2.0.0 encon-databind diff --git a/encon-handler/README.md b/encon-handler/README.md index c4ac5b4..decfbdf 100644 --- a/encon-handler/README.md +++ b/encon-handler/README.md @@ -14,7 +14,7 @@ First of all, add dependency: io.appulse.encon encon-handler - 1.6.5 + 2.0.0 ... @@ -23,7 +23,7 @@ First of all, add dependency: **Gradle**: ```groovy -compile 'io.appulse.encon:encon-handler:1.6.5' +compile 'io.appulse.encon:encon-handler:2.0.0' ``` ### Basics diff --git a/encon-handler/pom.xml b/encon-handler/pom.xml index fb82bb0..e7d3f77 100644 --- a/encon-handler/pom.xml +++ b/encon-handler/pom.xml @@ -25,7 +25,7 @@ limitations under the License. io.appulse.encon encon-parent - 1.6.5 + 2.0.0 encon-handler diff --git a/encon-spring/pom.xml b/encon-spring/pom.xml index 8cc8886..953f11b 100644 --- a/encon-spring/pom.xml +++ b/encon-spring/pom.xml @@ -25,7 +25,7 @@ limitations under the License. io.appulse.encon encon-parent - 1.6.5 + 2.0.0 encon-spring diff --git a/encon-spring/src/main/java/io/appulse/encon/spring/EnconAutoConfiguration.java b/encon-spring/src/main/java/io/appulse/encon/spring/EnconAutoConfiguration.java index 6a7f5d4..d1f25b2 100644 --- a/encon-spring/src/main/java/io/appulse/encon/spring/EnconAutoConfiguration.java +++ b/encon-spring/src/main/java/io/appulse/encon/spring/EnconAutoConfiguration.java @@ -33,6 +33,7 @@ import io.appulse.encon.spring.EnconAutoConfiguration.MailboxOperationsConfiguration; import lombok.experimental.FieldDefaults; +import lombok.extern.slf4j.Slf4j; import lombok.val; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; @@ -52,6 +53,7 @@ * @since 1.6.0 * @author Artem Labazin */ +@Slf4j @Configuration @ConditionalOnClass({ Node.class, @@ -84,6 +86,7 @@ public Config defaultConfig () { @ConditionalOnMissingBean @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") public Nodes defaultEnconNodes (Config config) { + log.debug("Configuration loaded\n{}", config); val nodes = Nodes.start(config); for (Node node : nodes) { val descriptor = node.getDescriptor(); diff --git a/encon-spring/src/main/java/io/appulse/encon/spring/EnconProperties.java b/encon-spring/src/main/java/io/appulse/encon/spring/EnconProperties.java index 1154c6e..2a9eaaf 100644 --- a/encon-spring/src/main/java/io/appulse/encon/spring/EnconProperties.java +++ b/encon-spring/src/main/java/io/appulse/encon/spring/EnconProperties.java @@ -20,18 +20,13 @@ import static lombok.AccessLevel.PACKAGE; import static lombok.AccessLevel.PRIVATE; -import java.util.LinkedHashMap; -import java.util.Map; - import javax.annotation.PostConstruct; +import io.appulse.encon.NodesConfig; import io.appulse.encon.config.Config; -import io.appulse.encon.config.Defaults; -import io.appulse.encon.config.NodeConfig; import lombok.Data; import lombok.Getter; -import lombok.NonNull; import lombok.experimental.FieldDefaults; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @@ -46,7 +41,7 @@ @Component @Validated @FieldDefaults(level = PRIVATE) -@ConfigurationProperties(prefix = "spring.encon") +@ConfigurationProperties(prefix = "spring") public class EnconProperties { @Getter(value = PACKAGE, lazy = true) @@ -54,10 +49,7 @@ public class EnconProperties { Boolean enabled; - Defaults defaults; - - @NonNull - Map nodes = new LinkedHashMap<>(); + NodesConfig encon; /** * Post construct. Initialize with default values the fields. @@ -67,15 +59,11 @@ public void postConstruct () { if (enabled == null) { enabled = TRUE; } - if (defaults == null) { - defaults = Defaults.INSTANCE; - } } private Config createConfig () { return Config.builder() - .defaults(defaults) - .nodes(nodes) + .config(encon) .build(); } } diff --git a/encon-terms/pom.xml b/encon-terms/pom.xml index d8a2387..4f77c05 100644 --- a/encon-terms/pom.xml +++ b/encon-terms/pom.xml @@ -25,7 +25,7 @@ limitations under the License. io.appulse.encon encon-parent - 1.6.5 + 2.0.0 encon-terms diff --git a/encon/README.md b/encon/README.md index e947af2..26fb39f 100644 --- a/encon/README.md +++ b/encon/README.md @@ -21,7 +21,7 @@ Adding encon's dependency to your `JVM` app: io.appulse.encon encon - 1.6.5 + 2.0.0 ... @@ -30,7 +30,7 @@ Adding encon's dependency to your `JVM` app: **Gradle**: ```groovy -compile 'io.appulse.encon:encon:1.6.5' +compile 'io.appulse.encon:encon:2.0.0' ``` ## Start the Node diff --git a/encon/pom.xml b/encon/pom.xml index 9380b1d..331126a 100644 --- a/encon/pom.xml +++ b/encon/pom.xml @@ -25,7 +25,7 @@ limitations under the License. io.appulse.encon encon-parent - 1.6.5 + 2.0.0 encon diff --git a/encon/src/main/java/io/appulse/encon/Node.java b/encon/src/main/java/io/appulse/encon/Node.java index 9cb2ce8..5f702f3 100644 --- a/encon/src/main/java/io/appulse/encon/Node.java +++ b/encon/src/main/java/io/appulse/encon/Node.java @@ -23,10 +23,10 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +import io.appulse.encon.NodesConfig.NodeConfig; import io.appulse.encon.common.Meta; import io.appulse.encon.common.NodeDescriptor; import io.appulse.encon.common.RemoteNode; -import io.appulse.encon.config.NodeConfig; import io.appulse.encon.connection.Connection; import io.appulse.encon.mailbox.Mailbox; import io.appulse.encon.mailbox.ModuleMailbox; @@ -41,7 +41,6 @@ import lombok.ToString; import lombok.experimental.FieldDefaults; import lombok.extern.slf4j.Slf4j; -import lombok.val; /** * Node's state holder and provider of all needed functions. @@ -59,23 +58,26 @@ @FieldDefaults(level = PACKAGE, makeFinal = true) public final class Node implements Closeable { - static Node newInstance (@NonNull String name, @NonNull NodeConfig config) { + // static Node newInstance (@NonNull String name, @NonNull Config config) { + // NodeConfig nodeConfig = config.get(NodeConfig.class, NodeConfig.DEFAULT); + static Node newInstance (@NonNull String name, @NonNull NodeConfig nodeConfig) { + NodeConfig configCopy = new NodeConfig(nodeConfig); - val descriptor = NodeDescriptor.from(name, config.getShortName()); - log.debug("Creating new Node '{}' with config:\n {}\n", descriptor.getFullName(), config); + NodeDescriptor descriptor = NodeDescriptor.from(name, configCopy.getShortName()); + log.debug("Creating new Node '{}' with config:\n {}\n", descriptor.getFullName(), configCopy); - val meta = Meta.builder() - .type(config.getType()) - .protocol(config.getProtocol()) - .low(config.getLowVersion()) - .high(config.getHighVersion()) - .flags(config.getDistributionFlags()) + Meta meta = Meta.builder() + .type(configCopy.getType()) + .protocol(configCopy.getProtocol()) + .low(configCopy.getLowVersion()) + .high(configCopy.getHighVersion()) + .flags(configCopy.getDistributionFlags()) .build(); - val epmd = new EpmdClient(config.getEpmdPort()); - val creation = epmd.register(Registration.builder() + EpmdClient epmd = new EpmdClient(configCopy.getEpmdPort()); + int creation = epmd.register(Registration.builder() .name(descriptor.getNodeName()) - .port(config.getServer().getPort()) + .port(configCopy.getServer().getOrFindAndSetPort()) .type(meta.getType()) .protocol(meta.getProtocol()) .high(meta.getHigh()) @@ -89,17 +91,11 @@ static Node newInstance (@NonNull String name, @NonNull NodeConfig config) { .meta(meta) .epmd(epmd) .creation(creation) - .config(config) + .config(configCopy) .build(); node.moduleMailbox.registerNetKernelMailbox(); - config.getMailboxes().forEach(it -> { - node.mailbox() - .name(it.getName()) - .build(); - }); - log.debug("Node '{}' was created", descriptor.getFullName()); return node; } @@ -144,12 +140,14 @@ private Node (@NonNull NodeDescriptor descriptor, int creation, @NonNull NodeConfig config ) { + NodeConfig configCopy = new NodeConfig(config); + this.descriptor = descriptor; this.meta = meta; this.epmd = epmd; - cookie = config.getCookie(); - port = config.getServer().getPort(); + cookie = configCopy.getCookie(); + port = configCopy.getServer().getOrFindAndSetPort(); generatorPid = new GeneratorPid(descriptor.getFullName(), creation); generatorPort = new GeneratorPort(descriptor.getFullName(), creation); @@ -159,11 +157,11 @@ private Node (@NonNull NodeDescriptor descriptor, moduleLookup = new ModuleLookup(epmd); moduleConnection = new ModuleConnection( descriptor.getNodeName(), - config.getServer().getBossThreads(), - config.getServer().getWorkerThreads() + configCopy.getServer().getBossThreads(), + configCopy.getServer().getWorkerThreads() ); moduleServer = new ModuleServer(this, moduleConnection, port); - moduleClient = new ModuleClient(this, moduleConnection, config.getShortName()); + moduleClient = new ModuleClient(this, moduleConnection, configCopy.getShortName()); moduleMailbox = new ModuleMailbox(this, () -> generatorPid.generate()); } diff --git a/encon/src/main/java/io/appulse/encon/Nodes.java b/encon/src/main/java/io/appulse/encon/Nodes.java index b29362e..d9102a0 100644 --- a/encon/src/main/java/io/appulse/encon/Nodes.java +++ b/encon/src/main/java/io/appulse/encon/Nodes.java @@ -26,16 +26,14 @@ import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; +import io.appulse.encon.NodesConfig.NodeConfig; import io.appulse.encon.common.NodeDescriptor; import io.appulse.encon.config.Config; -import io.appulse.encon.config.Defaults; -import io.appulse.encon.config.NodeConfig; import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.experimental.FieldDefaults; import lombok.extern.slf4j.Slf4j; -import lombok.val; /** * The set of different helper functions @@ -55,7 +53,9 @@ public final class Nodes implements Iterable, Closeable { * @return a new {@link Nodes} instance */ public static Nodes start () { - val config = Config.builder().build(); + Config config = Config.builder() + .build(); + return start(config); } @@ -67,13 +67,12 @@ public static Nodes start () { * @return a new {@link Nodes} instance */ public static Nodes start (@NonNull Config config) { - val copy = new Config(config); - log.debug("Creating ERTS instance with config {}", copy); + log.debug("Creating ERTS instance with config {}", config); - val erts = new Nodes(copy.getDefaults(), new ConcurrentHashMap<>()); - copy.getNodes() - .entrySet() - .forEach(it -> erts.newNode(it.getKey(), it.getValue())); + Nodes erts = new Nodes(config, new ConcurrentHashMap<>()); + config.get(NodesConfig.class).ifPresent(cfg -> { + cfg.getNodes().forEach((name, nodeConfig) -> erts.newNode(name, nodeConfig)); + }); return erts; } @@ -114,12 +113,10 @@ public static Node singleNode (@NonNull String name, boolean isShortNamed) { * @return new {@link Node} instance */ public static Node singleNode (@NonNull String name, @NonNull NodeConfig nodeConfig) { - val copy = new NodeConfig(nodeConfig); - copy.withDefaultsFrom(Defaults.INSTANCE); - return Node.newInstance(name, copy); + return Node.newInstance(name, nodeConfig); } - Defaults defaults; + Config config; Map nodes; @@ -131,7 +128,7 @@ public static Node singleNode (@NonNull String name, @NonNull NodeConfig nodeCon * @return new {@link Node} instance */ public Node newNode (@NonNull String name) { - val nodeConfig = NodeConfig.builder().build(); + NodeConfig nodeConfig = config.get("nodex." + name, NodeConfig.class, NodeConfig.DEFAULT); return newNode(name, nodeConfig); } @@ -145,9 +142,9 @@ public Node newNode (@NonNull String name) { * @return new {@link Node} instance */ public Node newNode (@NonNull String name, boolean isShortNamed) { - val nodeConfig = NodeConfig.builder() - .shortName(isShortNamed) - .build(); + NodeConfig nodeConfig = config.get("nodex." + name, NodeConfig.class, NodeConfig.DEFAULT) + .withShortName(isShortNamed); + return newNode(name, nodeConfig); } @@ -162,9 +159,7 @@ public Node newNode (@NonNull String name, boolean isShortNamed) { * @return new {@link Node} instance */ public Node newNode (@NonNull String name, @NonNull NodeConfig nodeConfig) { - val copy = new NodeConfig(nodeConfig); - copy.withDefaultsFrom(defaults); - val node = Node.newInstance(name, copy); + Node node = Node.newInstance(name, nodeConfig); nodes.put(node.getDescriptor(), node); return node; } @@ -177,7 +172,7 @@ public Node newNode (@NonNull String name, @NonNull NodeConfig nodeConfig) { * @return optional value, which could contains a searching node */ public Optional node (@NonNull String name) { - val descriptor = NodeDescriptor.from(name); + NodeDescriptor descriptor = NodeDescriptor.from(name); return node(descriptor); } @@ -209,7 +204,7 @@ public Collection nodes () { * @return the previous value associated with a name, or {@code null} if there was no mapping for name. */ public Node remove (@NonNull String name) { - val descriptor = NodeDescriptor.from(name); + NodeDescriptor descriptor = NodeDescriptor.from(name); return remove(descriptor); } diff --git a/encon/src/main/java/io/appulse/encon/NodesConfig.java b/encon/src/main/java/io/appulse/encon/NodesConfig.java new file mode 100644 index 0000000..3b7d202 --- /dev/null +++ b/encon/src/main/java/io/appulse/encon/NodesConfig.java @@ -0,0 +1,284 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon; + +import static io.appulse.encon.common.DistributionFlag.BIG_CREATION; +import static io.appulse.encon.common.DistributionFlag.BIT_BINARIES; +import static io.appulse.encon.common.DistributionFlag.EXTENDED_PIDS_PORTS; +import static io.appulse.encon.common.DistributionFlag.EXTENDED_REFERENCES; +import static io.appulse.encon.common.DistributionFlag.FUN_TAGS; +import static io.appulse.encon.common.DistributionFlag.MAP_TAG; +import static io.appulse.encon.common.DistributionFlag.NEW_FLOATS; +import static io.appulse.encon.common.DistributionFlag.NEW_FUN_TAGS; +import static io.appulse.encon.common.DistributionFlag.UTF8_ATOMS; +import static io.appulse.epmd.java.core.model.NodeType.R6_ERLANG; +import static io.appulse.epmd.java.core.model.Protocol.TCP; +import static io.appulse.epmd.java.core.model.Version.R6; +import static java.lang.Boolean.FALSE; +import static java.util.Arrays.asList; +import static java.util.Locale.ENGLISH; +import static java.util.Optional.ofNullable; +import static java.util.stream.Collectors.toMap; +import static lombok.AccessLevel.PRIVATE; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; + +import io.appulse.encon.common.DistributionFlag; +import io.appulse.epmd.java.client.EpmdClient; +import io.appulse.epmd.java.core.model.NodeType; +import io.appulse.epmd.java.core.model.Protocol; +import io.appulse.epmd.java.core.model.Version; +import io.appulse.utils.SocketUtils; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.Singular; +import lombok.experimental.FieldDefaults; +import lombok.experimental.Wither; + +/** + * + * @author Artem Labazin + * @since 2.0.0 + */ +@Data +@Wither +@NoArgsConstructor +@AllArgsConstructor +@Builder(toBuilder = true) +@FieldDefaults(level = PRIVATE) +public final class NodesConfig { + + @Singular + Map nodes; + + public NodesConfig (@NonNull NodesConfig other) { + this.nodes = other.getNodes() + .entrySet() + .stream() + .collect(toMap(Entry::getKey, it -> new NodeConfig(it.getValue()))); + } + + @Data + @Wither + @NoArgsConstructor + @AllArgsConstructor + @Builder(toBuilder = true) + @FieldDefaults(level = PRIVATE) + public static final class NodeConfig { + + private static final Set DEFAULT_DISTRIBUTION_FLAGS = new HashSet<>(asList( + EXTENDED_REFERENCES, + EXTENDED_PIDS_PORTS, + BIT_BINARIES, + NEW_FLOATS, + FUN_TAGS, + NEW_FUN_TAGS, + UTF8_ATOMS, + MAP_TAG, + BIG_CREATION + )); + + public static final NodeConfig DEFAULT = NodeConfig.builder().build(); + + /** + * Returns default cookie. It could be an empty string or content of ~/.erlang.cookie file. + * + * @return default cookie value + */ + public static String getDefaultCookie () { + Path cookieFile = Paths.get(getHomeDir(), ".erlang.cookie"); + if (!Files.exists(cookieFile)) { + return ""; + } + + try { + return Files.lines(cookieFile) + .filter(Objects::nonNull) + .map(String::trim) + .filter(it -> !it.isEmpty()) + .findFirst() + .orElse(""); + } catch (IOException ex) { + return ""; + } + } + + /** + * Returns user's home directory. + * + * @return user's home directory + */ + public static String getHomeDir () { + String home = System.getProperty("user.home"); + if (!System.getProperty("os.name").toLowerCase(ENGLISH).contains("windows")) { + return home; + } + + String drive = System.getenv("HOMEDRIVE"); + String path = System.getenv("HOMEPATH"); + return drive == null || path == null + ? home + : drive + path; + } + + public static NodeConfigBuilder builder () { + Set clone = new HashSet<>(DEFAULT_DISTRIBUTION_FLAGS); + return new NodeConfigBuilder().distributionFlags(clone); + } + + @Builder.Default + int epmdPort = EpmdClient.Default.PORT; + + @Builder.Default + NodeType type = R6_ERLANG; + + @Builder.Default + Boolean shortName = FALSE; + + @Builder.Default + String cookie = getDefaultCookie(); + + @Builder.Default + Protocol protocol = TCP; + + @Builder.Default + Version lowVersion = R6; + + @Builder.Default + Version highVersion = R6; + + @Singular + Set distributionFlags; + + @Builder.Default + ServerConfig server = ServerConfig.builder() + .bossThreads(1) + .workerThreads(2) + .build(); + + @Builder.Default + CompressionConfig compression = CompressionConfig.builder() + .enabled(FALSE) + .level(-1) + .build(); + + public NodeConfig (@NonNull NodeConfig other) { + epmdPort = other.getEpmdPort(); + type = other.getType(); + shortName = other.getShortName(); + cookie = other.getCookie(); + protocol = other.getProtocol(); + lowVersion = other.getLowVersion(); + highVersion = other.getHighVersion(); + + Set flags = ofNullable(other.getDistributionFlags()) + .orElse(DEFAULT_DISTRIBUTION_FLAGS); + + distributionFlags = new HashSet<>(flags); + + server = ofNullable(other.getServer()) + .map(ServerConfig::new) + .orElse(null); + + compression = ofNullable(other.getCompression()) + .map(CompressionConfig::new) + .orElse(null); + } + + @Data + @Wither + @NoArgsConstructor + @AllArgsConstructor + @Builder(toBuilder = true) + @FieldDefaults(level = PRIVATE) + public static final class ServerConfig { + + private static final AtomicInteger UPPER_BOUND = new AtomicInteger(65535); + + public static int findFreePort () { + while (true) { + int currentValue = UPPER_BOUND.get(); + Optional optional = SocketUtils.findFreePort(1024, currentValue); + if (!optional.isPresent()) { + UPPER_BOUND.set(65535); + continue; + } + + int port = optional.get(); + if (UPPER_BOUND.compareAndSet(currentValue, port - 1)) { + return port; + } + } + } + + Integer port; + + @Builder.Default + Integer bossThreads = 1; + + @Builder.Default + Integer workerThreads = 2; + + public ServerConfig (@NonNull ServerConfig other) { + port = other.getPort(); + bossThreads = other.getBossThreads(); + workerThreads = other.getWorkerThreads(); + } + + public int getOrFindAndSetPort () { + if (port == null) { + port = findFreePort(); + } + return port; + } + } + + @Data + @Wither + @NoArgsConstructor + @AllArgsConstructor + @Builder(toBuilder = true) + @FieldDefaults(level = PRIVATE) + public static final class CompressionConfig { + + @Builder.Default + Boolean enabled = FALSE; + + @Builder.Default + Integer level = -1; + + public CompressionConfig (@NonNull CompressionConfig other) { + enabled = other.getEnabled(); + level = other.getLevel(); + } + } + } +} diff --git a/encon/src/test/java/io/appulse/encon/NodeTest.java b/encon/src/test/java/io/appulse/encon/NodeTest.java index 27b5bbb..cc4fec4 100644 --- a/encon/src/test/java/io/appulse/encon/NodeTest.java +++ b/encon/src/test/java/io/appulse/encon/NodeTest.java @@ -33,11 +33,10 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import io.appulse.encon.config.MailboxConfig; -import io.appulse.encon.config.NodeConfig; -import io.appulse.encon.config.ServerConfig; import io.appulse.encon.connection.control.ControlMessage; import io.appulse.encon.connection.regular.Message; +import io.appulse.encon.NodesConfig.NodeConfig; +import io.appulse.encon.NodesConfig.NodeConfig.ServerConfig; import io.appulse.encon.mailbox.Mailbox; import io.appulse.encon.mailbox.exception.ReceivedExitException; import io.appulse.encon.terms.ErlangTerm; @@ -141,9 +140,9 @@ public void ping () throws Exception { val name1 = createName(); val name2 = createName(); node = Nodes.singleNode(name1, NodeConfig.builder() - .shortName(true) - .cookie("secret") - .build() + .shortName(true) + .cookie("secret") + .build() ); assertThat(node.ping(ELIXIR_ECHO_SERVER)) @@ -178,19 +177,10 @@ public void ping () throws Exception { public void instantiating () throws Exception { val name = createName(); node = Nodes.singleNode(name, NodeConfig.builder() - .shortName(true) - .mailbox(MailboxConfig.builder() - .name("one") - .build()) - .mailbox(MailboxConfig.builder() - .name("two") - .build()) - .build() + .shortName(true) + .build() ); - - assertThat(node.mailbox("one")).isNotNull(); - assertThat(node.mailbox("two")).isNotNull(); - assertThat(node.mailbox("three")).isNull(); + assertThat(node.mailbox("one")).isNull(); } @Test diff --git a/encon/src/test/java/io/appulse/encon/NodesTest.java b/encon/src/test/java/io/appulse/encon/NodesTest.java index d98404f..24c035c 100644 --- a/encon/src/test/java/io/appulse/encon/NodesTest.java +++ b/encon/src/test/java/io/appulse/encon/NodesTest.java @@ -23,15 +23,12 @@ import java.util.concurrent.Executors; import io.appulse.encon.config.Config; -import io.appulse.encon.config.Defaults; -import io.appulse.encon.config.MailboxConfig; -import io.appulse.encon.config.NodeConfig; -import io.appulse.encon.config.ServerConfig; import io.appulse.epmd.java.server.cli.CommonOptions; import io.appulse.epmd.java.server.command.server.ServerCommandExecutor; import io.appulse.epmd.java.server.command.server.ServerCommandOptions; import io.appulse.utils.SocketUtils; import io.appulse.utils.test.TestMethodNamePrinter; +import io.appulse.encon.NodesConfig.NodeConfig; import lombok.val; @@ -75,30 +72,18 @@ public static void afterClass () { @Test public void instantiating () { - val config = Config.builder() - .defaults(Defaults.builder() - .cookie("kojima-secret") - .server(ServerConfig.builder() - .bossThreads(1) - .workerThreads(1) - .build()) + Config config = Config.builder() + .config(NodesConfig.builder() + .node("kojima1", NodeConfig.DEFAULT) + .node("kojima2", NodeConfig.DEFAULT) .build()) - .node("kojima1", new NodeConfig()) - .node("kojima2", new NodeConfig()) - .node("ocelot", NodeConfig.builder() - .mailbox(MailboxConfig.builder() - .name("revolver") - .build()) - .build()) .build(); - try (val nodes = Nodes.start(config)) { + try (Nodes nodes = Nodes.start(config)) { assertThat(nodes.node("kojima1")) .isPresent(); assertThat(nodes.node("kojima2")) .isPresent(); - assertThat(nodes.node("ocelot")) - .isPresent(); assertThat(nodes.node("kojima3")) .isNotPresent(); } diff --git a/examples/custom-queue/pom.xml b/examples/custom-queue/pom.xml index 460e9ba..0b6e9d8 100644 --- a/examples/custom-queue/pom.xml +++ b/examples/custom-queue/pom.xml @@ -25,7 +25,7 @@ limitations under the License. io.appulse.encon examples - 1.6.5 + 2.0.0 io.appulse.encon.examples diff --git a/examples/custom-queue/src/main/java/io/appulse/encon/examples/custom/queue/Main.java b/examples/custom-queue/src/main/java/io/appulse/encon/examples/custom/queue/Main.java index 5b766a8..2010c3e 100644 --- a/examples/custom-queue/src/main/java/io/appulse/encon/examples/custom/queue/Main.java +++ b/examples/custom-queue/src/main/java/io/appulse/encon/examples/custom/queue/Main.java @@ -22,7 +22,7 @@ import io.appulse.encon.Node; import io.appulse.encon.Nodes; -import io.appulse.encon.config.NodeConfig; +import io.appulse.encon.NodesConfig.NodeConfig; import io.appulse.encon.mailbox.Mailbox; import io.appulse.encon.terms.ErlangTerm; import io.appulse.encon.terms.type.ErlangPid; diff --git a/examples/databind/pom.xml b/examples/databind/pom.xml index ac909af..734bd0b 100644 --- a/examples/databind/pom.xml +++ b/examples/databind/pom.xml @@ -25,7 +25,7 @@ limitations under the License. io.appulse.encon examples - 1.6.5 + 2.0.0 io.appulse.encon.examples diff --git a/examples/echo-server-spring/pom.xml b/examples/echo-server-spring/pom.xml index 2b24d4c..8e206d4 100644 --- a/examples/echo-server-spring/pom.xml +++ b/examples/echo-server-spring/pom.xml @@ -25,7 +25,7 @@ limitations under the License. io.appulse.encon examples - 1.6.5 + 2.0.0 diff --git a/examples/echo-server-spring/src/main/resources/application.yml b/examples/echo-server-spring/src/main/resources/application.yml index 59ec549..308c5af 100644 --- a/examples/echo-server-spring/src/main/resources/application.yml +++ b/examples/echo-server-spring/src/main/resources/application.yml @@ -1,4 +1,8 @@ spring.encon: - defaults: - cookie: secret + nodes: + echo-client: + shortName: true + echo-server: + shortName: true + diff --git a/examples/echo-server-spring/src/test/java/io/appulse/encon/examples/echo/server/spring/MainTest.java b/examples/echo-server-spring/src/test/java/io/appulse/encon/examples/echo/server/spring/MainTest.java index c656fbf..56ced74 100644 --- a/examples/echo-server-spring/src/test/java/io/appulse/encon/examples/echo/server/spring/MainTest.java +++ b/examples/echo-server-spring/src/test/java/io/appulse/encon/examples/echo/server/spring/MainTest.java @@ -36,6 +36,7 @@ import io.appulse.epmd.java.server.command.server.ServerCommandOptions; import io.appulse.utils.SocketUtils; import io.appulse.utils.test.TestMethodNamePrinter; + import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Rule; diff --git a/examples/echo-server/pom.xml b/examples/echo-server/pom.xml index a22adf3..a881751 100644 --- a/examples/echo-server/pom.xml +++ b/examples/echo-server/pom.xml @@ -25,7 +25,7 @@ limitations under the License. io.appulse.encon examples - 1.6.5 + 2.0.0 io.appulse.encon.examples diff --git a/examples/echo-server/src/main/java/io/appulse/encon/examples/echo/server/EchoClientNode.java b/examples/echo-server/src/main/java/io/appulse/encon/examples/echo/server/EchoClientNode.java index 7b50395..705d71a 100644 --- a/examples/echo-server/src/main/java/io/appulse/encon/examples/echo/server/EchoClientNode.java +++ b/examples/echo-server/src/main/java/io/appulse/encon/examples/echo/server/EchoClientNode.java @@ -22,7 +22,7 @@ import io.appulse.encon.Node; import io.appulse.encon.Nodes; -import io.appulse.encon.config.NodeConfig; +import io.appulse.encon.NodesConfig.NodeConfig; import io.appulse.encon.databind.TermMapper; import io.appulse.encon.mailbox.Mailbox; import io.appulse.encon.terms.ErlangTerm; diff --git a/examples/echo-server/src/main/java/io/appulse/encon/examples/echo/server/EchoServerNode.java b/examples/echo-server/src/main/java/io/appulse/encon/examples/echo/server/EchoServerNode.java index 927c7ff..04171ad 100644 --- a/examples/echo-server/src/main/java/io/appulse/encon/examples/echo/server/EchoServerNode.java +++ b/examples/echo-server/src/main/java/io/appulse/encon/examples/echo/server/EchoServerNode.java @@ -24,7 +24,7 @@ import io.appulse.encon.Node; import io.appulse.encon.Nodes; -import io.appulse.encon.config.NodeConfig; +import io.appulse.encon.NodesConfig.NodeConfig; import io.appulse.encon.connection.regular.Message; import io.appulse.encon.mailbox.Mailbox; import io.appulse.encon.terms.ErlangTerm; diff --git a/examples/handler-advanced/pom.xml b/examples/handler-advanced/pom.xml index 00830c9..18a625c 100644 --- a/examples/handler-advanced/pom.xml +++ b/examples/handler-advanced/pom.xml @@ -25,7 +25,7 @@ limitations under the License. io.appulse.encon examples - 1.6.5 + 2.0.0 io.appulse.encon.examples diff --git a/examples/handler-basic/pom.xml b/examples/handler-basic/pom.xml index 92d6d20..27dced7 100644 --- a/examples/handler-basic/pom.xml +++ b/examples/handler-basic/pom.xml @@ -25,7 +25,7 @@ limitations under the License. io.appulse.encon examples - 1.6.5 + 2.0.0 io.appulse.encon.examples diff --git a/examples/load-config-spring/pom.xml b/examples/load-config-spring/pom.xml index 310b821..5da4b84 100644 --- a/examples/load-config-spring/pom.xml +++ b/examples/load-config-spring/pom.xml @@ -25,7 +25,7 @@ limitations under the License. io.appulse.encon examples - 1.6.5 + 2.0.0 diff --git a/examples/load-config-spring/src/main/resources/application.yml b/examples/load-config-spring/src/main/resources/application.yml index 2bfd4c0..f688b6c 100644 --- a/examples/load-config-spring/src/main/resources/application.yml +++ b/examples/load-config-spring/src/main/resources/application.yml @@ -1,26 +1,14 @@ spring.encon: - defaults: - type: R3_ERLANG - short-name: true - cookie: secret - protocol: TCP - low-version: R4 - high-version: R6 - distribution-flags: - - MAP_TAG - - BIG_CREATION - server: - boss-threads: 2 - worker-threads: 4 - nodes: node-1: type: R3_HIDDEN + shortName: true cookie: non-secret - low-version: R5C - high-version: R6 - distribution-flags: + protocol: TCP + lowVersion: R5C + highVersion: R6 + distributionFlags: - EXTENDED_REFERENCES - EXTENDED_PIDS_PORTS - BIT_BINARIES @@ -30,14 +18,21 @@ spring.encon: - UTF8_ATOMS - MAP_TAG - BIG_CREATION - mailboxes: - - name: another - - name: another_one server: port: 8971 - boss-threads: 1 - worker-threads: 2 + bossThreads: 1 + workerThreads: 2 node-2: - short-name: false + type: R3_ERLANG + shortName: false cookie: popa + protocol: TCP + lowVersion: R4 + highVersion: R6 + distributionFlags: + - MAP_TAG + - BIG_CREATION + server: + bossThreads: 2 + workerThreads: 4 diff --git a/examples/load-config-spring/src/test/java/io/appulse/encon/examples/load/config/spring/MainTest.java b/examples/load-config-spring/src/test/java/io/appulse/encon/examples/load/config/spring/MainTest.java index 4c0a127..fcb04a5 100644 --- a/examples/load-config-spring/src/test/java/io/appulse/encon/examples/load/config/spring/MainTest.java +++ b/examples/load-config-spring/src/test/java/io/appulse/encon/examples/load/config/spring/MainTest.java @@ -68,8 +68,8 @@ public void test () { assertThat(context.containsBean("node-2")).isTrue(); assertThat(context.containsBean("node-1_net_kernelMailbox")).isFalse(); - assertThat(context.containsBean("node-1_anotherMailbox")).isTrue(); - assertThat(context.containsBean("node-1_another_oneMailbox")).isTrue(); + // assertThat(context.containsBean("node-1_anotherMailbox")).isTrue(); + // assertThat(context.containsBean("node-1_another_oneMailbox")).isTrue(); assertThat(context.containsBean("node-2_net_kernelMailbox")).isFalse(); } catch (Throwable ex) { @@ -122,9 +122,9 @@ private void checkNode1 (Node node) { assertThat(node.mailbox("net_kernel")).isNotNull(); - assertThat(node.mailbox("another")).isNotNull(); - assertThat(node.mailbox("another_one")).isNotNull(); - assertThat(node.mailboxes()).hasSize(3); + // assertThat(node.mailbox("another")).isNotNull(); + // assertThat(node.mailbox("another_one")).isNotNull(); + assertThat(node.mailboxes()).hasSize(1); } private void checkNode2 (Node node) { diff --git a/examples/load-config/pom.xml b/examples/load-config/pom.xml index 1bcfca9..f9bd914 100644 --- a/examples/load-config/pom.xml +++ b/examples/load-config/pom.xml @@ -25,7 +25,7 @@ limitations under the License. io.appulse.encon examples - 1.6.5 + 2.0.0 io.appulse.encon.examples diff --git a/examples/load-config/src/main/resources/nodes.yml b/examples/load-config/src/main/resources/nodes.yml index a7e13fe..a921efb 100644 --- a/examples/load-config/src/main/resources/nodes.yml +++ b/examples/load-config/src/main/resources/nodes.yml @@ -1,25 +1,13 @@ -defaults: - type: R3_ERLANG - short-name: true - cookie: secret - protocol: TCP - low-version: R4 - high-version: R6 - distribution-flags: - - MAP_TAG - - BIG_CREATION - server: - boss-threads: 2 - worker-threads: 4 - nodes: node-1: type: R3_HIDDEN + shortName: true cookie: non-secret - low-version: R5C - high-version: R6 - distribution-flags: + protocol: TCP + lowVersion: R5C + highVersion: R6 + distributionFlags: - EXTENDED_REFERENCES - EXTENDED_PIDS_PORTS - BIT_BINARIES @@ -29,14 +17,21 @@ nodes: - UTF8_ATOMS - MAP_TAG - BIG_CREATION - mailboxes: - - name: another - - name: another_one server: port: 8971 - boss-threads: 1 - worker-threads: 2 + bossThreads: 1 + workerThreads: 2 node-2: - short-name: false + type: R3_ERLANG + shortName: false cookie: popa + protocol: TCP + lowVersion: R4 + highVersion: R6 + distributionFlags: + - MAP_TAG + - BIG_CREATION + server: + bossThreads: 2 + workerThreads: 4 diff --git a/examples/load-config/src/test/java/io/appulse/encon/examples/load/config/MainTest.java b/examples/load-config/src/test/java/io/appulse/encon/examples/load/config/MainTest.java index 0ddc2d4..e8e6aec 100644 --- a/examples/load-config/src/test/java/io/appulse/encon/examples/load/config/MainTest.java +++ b/examples/load-config/src/test/java/io/appulse/encon/examples/load/config/MainTest.java @@ -100,9 +100,7 @@ private void checkNode1 (Server server) { assertThat(node.mailbox("net_kernel")).isNotNull(); - assertThat(node.mailbox("another")).isNotNull(); - assertThat(node.mailbox("another_one")).isNotNull(); - assertThat(node.mailboxes()).hasSize(3); + assertThat(node.mailboxes()).hasSize(1); } private void checkNode2 (Server server) { diff --git a/examples/pom.xml b/examples/pom.xml index f504ec0..cc374de 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -25,7 +25,7 @@ limitations under the License. io.appulse.encon encon-parent - 1.6.5 + 2.0.0 examples diff --git a/examples/simple/pom.xml b/examples/simple/pom.xml index 88e4a05..859160e 100644 --- a/examples/simple/pom.xml +++ b/examples/simple/pom.xml @@ -25,7 +25,7 @@ limitations under the License. io.appulse.encon examples - 1.6.5 + 2.0.0 io.appulse.encon.examples diff --git a/examples/simple/src/main/java/io/appulse/encon/examples/simple/Main.java b/examples/simple/src/main/java/io/appulse/encon/examples/simple/Main.java index 275d16e..3c79f75 100644 --- a/examples/simple/src/main/java/io/appulse/encon/examples/simple/Main.java +++ b/examples/simple/src/main/java/io/appulse/encon/examples/simple/Main.java @@ -20,7 +20,7 @@ import io.appulse.encon.Node; import io.appulse.encon.Nodes; -import io.appulse.encon.config.NodeConfig; +import io.appulse.encon.NodesConfig.NodeConfig; import io.appulse.encon.mailbox.Mailbox; import io.appulse.encon.terms.ErlangTerm; import io.appulse.encon.terms.type.ErlangPid; diff --git a/pom.xml b/pom.xml index a1413b2..5ae8738 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ limitations under the License. io.appulse.encon encon-parent - 1.6.5 + 2.0.0 pom @@ -74,7 +74,7 @@ limitations under the License. https://github.com/appulse-projects/encon-java scm:git:https://github.com/appulse-projects/encon-java.git scm:git:https://github.com/appulse-projects/encon-java.git - 1.6.5 + 2.0.0 @@ -244,7 +244,7 @@ limitations under the License. analyze-compile - compile + package check @@ -291,7 +291,7 @@ limitations under the License. validate - validate + package check @@ -375,7 +375,7 @@ limitations under the License. sign-artifacts - verify + install sign From 35132d0352ba1f6a2a651bb1a9b0fdc55bca63d9 Mon Sep 17 00:00:00 2001 From: Artem Labazin Date: Mon, 1 Oct 2018 20:23:38 +0300 Subject: [PATCH 02/20] Reduce @SupressWarnings amount at ConfigurationProgrammatical --- .../io/appulse/encon/config/ConfigurationProgrammatical.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/encon-config/src/main/java/io/appulse/encon/config/ConfigurationProgrammatical.java b/encon-config/src/main/java/io/appulse/encon/config/ConfigurationProgrammatical.java index 06a8f61..93a92b2 100644 --- a/encon-config/src/main/java/io/appulse/encon/config/ConfigurationProgrammatical.java +++ b/encon-config/src/main/java/io/appulse/encon/config/ConfigurationProgrammatical.java @@ -41,6 +41,7 @@ * @since 2.0.0 */ @ToString +@SuppressWarnings("unchecked") @EqualsAndHashCode(callSuper = false) @FieldDefaults(level = PRIVATE, makeFinal = true) final class ConfigurationProgrammatical extends AbstractConfig { @@ -65,7 +66,7 @@ void put (Object value) { } } - @SuppressWarnings({ "unchecked", "PMD.AvoidInstantiatingObjectsInLoops"}) + @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") private static Tuple unfoldKey (Map map, String key) { Map current = map; String currentKey = key; @@ -124,7 +125,6 @@ private static List processList (Collection list) { .collect(toList()); } - @SuppressWarnings("unchecked") private static Object processValue (Object object) { if (object instanceof Map) { return processMap((Map) object); @@ -138,7 +138,6 @@ private static Object processValue (Object object) { return object; } - @SuppressWarnings("unchecked") private static Object merge (Object left, Object right) { if (left == null) { return right; From 4a66c67221f9d66877ed5361ce00438cbc9b4f49 Mon Sep 17 00:00:00 2001 From: Artem Labazin Date: Tue, 2 Oct 2018 15:43:47 +0300 Subject: [PATCH 03/20] Change ErlangInteger cache behaviour --- .../io/appulse/encon/terms/ErlangTerm.java | 2 +- .../encon/terms/type/ErlangInteger.java | 125 ++++-------------- .../encon/terms/type/ErlangIntegerTest.java | 7 + 3 files changed, 34 insertions(+), 100 deletions(-) diff --git a/encon-terms/src/main/java/io/appulse/encon/terms/ErlangTerm.java b/encon-terms/src/main/java/io/appulse/encon/terms/ErlangTerm.java index e697902..1ca8da3 100644 --- a/encon-terms/src/main/java/io/appulse/encon/terms/ErlangTerm.java +++ b/encon-terms/src/main/java/io/appulse/encon/terms/ErlangTerm.java @@ -95,7 +95,7 @@ public static T newInstance (@NonNull ByteBuf buffer) { case INTEGER: case SMALL_BIG: case LARGE_BIG: - return (T) ErlangInteger.cached(type, buffer); + return (T) new ErlangInteger(type, buffer); case FLOAT: case NEW_FLOAT: return (T) new ErlangFloat(type, buffer); diff --git a/encon-terms/src/main/java/io/appulse/encon/terms/type/ErlangInteger.java b/encon-terms/src/main/java/io/appulse/encon/terms/type/ErlangInteger.java index 1158358..a8d9196 100644 --- a/encon-terms/src/main/java/io/appulse/encon/terms/type/ErlangInteger.java +++ b/encon-terms/src/main/java/io/appulse/encon/terms/type/ErlangInteger.java @@ -31,12 +31,9 @@ import io.appulse.encon.terms.TermType; import io.appulse.encon.terms.exception.ErlangTermDecodeException; import io.appulse.encon.terms.exception.IllegalErlangTermTypeException; -import io.appulse.utils.cache.LruCache; import io.netty.buffer.ByteBuf; -import io.netty.util.ByteProcessor; import lombok.EqualsAndHashCode; -import lombok.Getter; import lombok.NonNull; import lombok.ToString; import lombok.experimental.FieldDefaults; @@ -64,8 +61,6 @@ public class ErlangInteger extends ErlangTerm { private static final int MAX_SMALL_BIG_BYTES_LENGTH = 255; - private static final LruCache CACHE = new LruCache<>(1000); - /** * Creates cached {@link ErlangInteger} value. * @@ -74,15 +69,7 @@ public class ErlangInteger extends ErlangTerm { * @return new or cached {@link ErlangInteger} object */ public static ErlangInteger cached (byte value) { - int hashCode = 31 + value; - - ErlangInteger result = CACHE.get(hashCode); - if (result != null) { - return result; - } - result = new ErlangInteger(value); - CACHE.put(hashCode, result); - return result; + return ErlangIntegerCache.CACHE[value + (-ErlangIntegerCache.LOW)]; } /** @@ -93,16 +80,10 @@ public static ErlangInteger cached (byte value) { * @return new or cached {@link ErlangInteger} object */ public static ErlangInteger cached (char value) { - int hashCode = 31 + (byte) (value >> 8); - hashCode = 31 * hashCode + (byte) value; - - ErlangInteger result = CACHE.get(hashCode); - if (result != null) { - return result; + if (value <= ErlangIntegerCache.HIGH) { + return ErlangIntegerCache.CACHE[value + (-ErlangIntegerCache.LOW)]; } - result = new ErlangInteger(value); - CACHE.put(hashCode, result); - return result; + return new ErlangInteger(value); } /** @@ -113,16 +94,10 @@ public static ErlangInteger cached (char value) { * @return new or cached {@link ErlangInteger} object */ public static ErlangInteger cached (short value) { - int hashCode = 31 + (byte) (value >> 8); - hashCode = 31 * hashCode + (byte) value; - - ErlangInteger result = CACHE.get(hashCode); - if (result != null) { - return result; + if (value >= ErlangIntegerCache.LOW && value <= ErlangIntegerCache.HIGH) { + return ErlangIntegerCache.CACHE[value + (-ErlangIntegerCache.LOW)]; } - result = new ErlangInteger(value); - CACHE.put(hashCode, result); - return result; + return new ErlangInteger(value); } /** @@ -133,18 +108,10 @@ public static ErlangInteger cached (short value) { * @return new or cached {@link ErlangInteger} object */ public static ErlangInteger cached (int value) { - int hashCode = 31 + (byte) (value >> 24); - hashCode = 31 * hashCode + (byte) (value >> 16); - hashCode = 31 * hashCode + (byte) (value >> 8); - hashCode = 31 * hashCode + (byte) value; - - ErlangInteger result = CACHE.get(hashCode); - if (result != null) { - return result; + if (value >= ErlangIntegerCache.LOW && value <= ErlangIntegerCache.HIGH) { + return ErlangIntegerCache.CACHE[value + (-ErlangIntegerCache.LOW)]; } - result = new ErlangInteger(value); - CACHE.put(hashCode, result); - return result; + return new ErlangInteger(value); } /** @@ -155,22 +122,10 @@ public static ErlangInteger cached (int value) { * @return new or cached {@link ErlangInteger} object */ public static ErlangInteger cached (long value) { - int hashCode = 31 + (byte) (value >> 56); - hashCode = 31 * hashCode + (byte) (value >> 48); - hashCode = 31 * hashCode + (byte) (value >> 40); - hashCode = 31 * hashCode + (byte) (value >> 32); - hashCode = 31 * hashCode + (byte) (value >> 24); - hashCode = 31 * hashCode + (byte) (value >> 16); - hashCode = 31 * hashCode + (byte) (value >> 8); - hashCode = 31 * hashCode + (byte) value; - - ErlangInteger result = CACHE.get(hashCode); - if (result != null) { - return result; + if (value >= ErlangIntegerCache.LOW && value <= ErlangIntegerCache.HIGH) { + return ErlangIntegerCache.CACHE[(int) value + (-ErlangIntegerCache.LOW)]; } - result = new ErlangInteger(value); - CACHE.put(hashCode, result); - return result; + return new ErlangInteger(value); } /** @@ -187,39 +142,6 @@ public static ErlangInteger cached (BigInteger value) { return new ErlangInteger(value); } - public static ErlangInteger cached (TermType type, @NonNull ByteBuf buffer) { - int index = buffer.readerIndex(); - ByteArrayHashCode byteProcessor = new ByteArrayHashCode(); - - int length; - switch (type) { - case SMALL_INTEGER: - length = Byte.BYTES; - break; - case INTEGER: - length = Integer.BYTES; - break; - case SMALL_BIG: - length = buffer.readByte() + Byte.BYTES; - break; - case LARGE_BIG: - default: - length = buffer.readInt() + Byte.BYTES; - } - - buffer.forEachByte(buffer.readerIndex(), length, byteProcessor); - - return CACHE.compute(byteProcessor.getHashCode(), (key, value) -> { - if (value == null) { - buffer.readerIndex(index); - return new ErlangInteger(type, buffer); - } else { - buffer.skipBytes(length); - return value; - } - }); - } - BigInteger value; @NonFinal @@ -476,16 +398,21 @@ private void reverse (byte[] data) { } } - @Getter - @FieldDefaults(level = PRIVATE) - private static class ByteArrayHashCode implements ByteProcessor { + @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") + private static class ErlangIntegerCache { - int hashCode = 1; + private static final int LOW = -128; - @Override - public boolean process (byte value) throws Exception { - hashCode = 31 * hashCode + value; - return true; + private static final int HIGH = 127; + + private static final ErlangInteger[] CACHE; + + static { + CACHE = new ErlangInteger[(HIGH - LOW) + 1]; + int value = LOW; + for (int index = 0; index < CACHE.length; index++) { + CACHE[index] = new ErlangInteger(value++); + } } } } diff --git a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangIntegerTest.java b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangIntegerTest.java index 3110520..6cd6899 100644 --- a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangIntegerTest.java +++ b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangIntegerTest.java @@ -167,6 +167,13 @@ public void decode () throws Exception { } } + @Test + public void cached () { + ErlangInteger num1 = ErlangInteger.cached(1273); + ErlangInteger num2 = ErlangInteger.cached(117); + assertThat(num1).isNotEqualTo(num2); + } + @SneakyThrows private byte[] bytes (char value) { try (OtpOutputStream output = new OtpOutputStream()) { From a86d2dd6d4d25a0383f91e881c100a909c48289a Mon Sep 17 00:00:00 2001 From: Artem Labazin Date: Wed, 10 Oct 2018 10:16:05 +0300 Subject: [PATCH 04/20] Update readme headers --- README.md | 6 +++++- encon-common/README.md | 8 ++++++++ encon-config/README.md | 8 ++++++++ encon-databind/README.md | 8 ++++++++ encon-handler/README.md | 8 ++++++++ encon-spring/README.md | 8 ++++++++ encon-terms/README.md | 8 ++++++++ encon/README.md | 8 ++++++++ 8 files changed, 61 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 680b8fa..4b2c6fd 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,11 @@ # Overview [![build_status](https://travis-ci.org/appulse-projects/encon-java.svg?branch=master)](https://travis-ci.org/appulse-projects/encon-java) -[![maven_central](https://maven-badges.herokuapp.com/maven-central/io.appulse.encon/encon/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.appulse.encon/encon) +[![maven_central](https://maven-badges.herokuapp.com/maven-central/io.appulse.encon/encon/badge.svg)](https://search.maven.org/search?q=g:io.appulse.encon) +[![License](http://img.shields.io/:license-apache-brightgreen.svg)](http://www.apache.org/licenses/LICENSE-2.0.html) + + + Java implementation of **E**rlang **N**ode **CON**nector (using Eralng Distribution Protocol). For more information, visit the [site](https://appulse.io). diff --git a/encon-common/README.md b/encon-common/README.md index 780dbd7..72923eb 100644 --- a/encon-common/README.md +++ b/encon-common/README.md @@ -1,3 +1,11 @@ # Overview +[![build_status](https://travis-ci.org/appulse-projects/encon-java.svg?branch=master)](https://travis-ci.org/appulse-projects/encon-java) +[![maven_central](https://maven-badges.herokuapp.com/maven-central/io.appulse.encon/encon-common/badge.svg)](https://search.maven.org/search?q=a:encon-common) +[![License](http://img.shields.io/:license-apache-brightgreen.svg)](http://www.apache.org/licenses/LICENSE-2.0.html) +[![JavaDoc](http://www.javadoc.io/badge/io.appulse.encon/encon-common.svg)](http://www.javadoc.io/doc/io.appulse.encon/encon-common) + + + + Encon's common classes for all subprojects. diff --git a/encon-config/README.md b/encon-config/README.md index 68d501a..05e36d7 100644 --- a/encon-config/README.md +++ b/encon-config/README.md @@ -1,5 +1,13 @@ # Overview +[![build_status](https://travis-ci.org/appulse-projects/encon-java.svg?branch=master)](https://travis-ci.org/appulse-projects/encon-java) +[![maven_central](https://maven-badges.herokuapp.com/maven-central/io.appulse.encon/encon-config/badge.svg)](https://search.maven.org/search?q=a:encon-config) +[![License](http://img.shields.io/:license-apache-brightgreen.svg)](http://www.apache.org/licenses/LICENSE-2.0.html) +[![JavaDoc](http://www.javadoc.io/badge/io.appulse.encon/encon-config.svg)](http://www.javadoc.io/doc/io.appulse.encon/encon-config) + + + + Encon's configuration classes. ## Usage diff --git a/encon-databind/README.md b/encon-databind/README.md index f54096f..e3d21a5 100644 --- a/encon-databind/README.md +++ b/encon-databind/README.md @@ -1,5 +1,13 @@ # Overview +[![build_status](https://travis-ci.org/appulse-projects/encon-java.svg?branch=master)](https://travis-ci.org/appulse-projects/encon-java) +[![maven_central](https://maven-badges.herokuapp.com/maven-central/io.appulse.encon/encon-databind/badge.svg)](https://search.maven.org/search?q=a:encon-databind) +[![License](http://img.shields.io/:license-apache-brightgreen.svg)](http://www.apache.org/licenses/LICENSE-2.0.html) +[![JavaDoc](http://www.javadoc.io/badge/io.appulse.encon/encon-databind.svg)](http://www.javadoc.io/doc/io.appulse.encon/encon-databind) + + + + This is a Java library that can be used to convert Java Objects into their Erlang representation. ## Usage diff --git a/encon-handler/README.md b/encon-handler/README.md index decfbdf..38e7a5f 100644 --- a/encon-handler/README.md +++ b/encon-handler/README.md @@ -1,5 +1,13 @@ # Overview +[![build_status](https://travis-ci.org/appulse-projects/encon-java.svg?branch=master)](https://travis-ci.org/appulse-projects/encon-java) +[![maven_central](https://maven-badges.herokuapp.com/maven-central/io.appulse.encon/encon-handler/badge.svg)](https://search.maven.org/search?q=a:encon-handler) +[![License](http://img.shields.io/:license-apache-brightgreen.svg)](http://www.apache.org/licenses/LICENSE-2.0.html) +[![JavaDoc](http://www.javadoc.io/badge/io.appulse.encon/encon-handler.svg)](http://www.javadoc.io/doc/io.appulse.encon/encon-handler) + + + + Different classes for convenient mailbox handling. ## Usage diff --git a/encon-spring/README.md b/encon-spring/README.md index 9be038b..1029d17 100644 --- a/encon-spring/README.md +++ b/encon-spring/README.md @@ -1,5 +1,13 @@ # Overview +[![build_status](https://travis-ci.org/appulse-projects/encon-java.svg?branch=master)](https://travis-ci.org/appulse-projects/encon-java) +[![maven_central](https://maven-badges.herokuapp.com/maven-central/io.appulse.encon/encon-spring/badge.svg)](https://search.maven.org/search?q=a:encon-spring) +[![License](http://img.shields.io/:license-apache-brightgreen.svg)](http://www.apache.org/licenses/LICENSE-2.0.html) +[![JavaDoc](http://www.javadoc.io/badge/io.appulse.encon/encon-spring.svg)](http://www.javadoc.io/doc/io.appulse.encon/encon-spring) + + + + Package for Encon's Spring integration. Example: diff --git a/encon-terms/README.md b/encon-terms/README.md index 5f86cf5..ce03d25 100644 --- a/encon-terms/README.md +++ b/encon-terms/README.md @@ -1,3 +1,11 @@ # Overview +[![build_status](https://travis-ci.org/appulse-projects/encon-java.svg?branch=master)](https://travis-ci.org/appulse-projects/encon-java) +[![maven_central](https://maven-badges.herokuapp.com/maven-central/io.appulse.encon/encon-terms/badge.svg)](https://search.maven.org/search?q=a:encon-terms) +[![License](http://img.shields.io/:license-apache-brightgreen.svg)](http://www.apache.org/licenses/LICENSE-2.0.html) +[![JavaDoc](http://www.javadoc.io/badge/io.appulse.encon/encon-terms.svg)](http://www.javadoc.io/doc/io.appulse.encon/encon-terms) + + + + The set of Erlang's terms classes and different helpers. diff --git a/encon/README.md b/encon/README.md index 26fb39f..ebc4b31 100644 --- a/encon/README.md +++ b/encon/README.md @@ -1,5 +1,13 @@ # Overview +[![build_status](https://travis-ci.org/appulse-projects/encon-java.svg?branch=master)](https://travis-ci.org/appulse-projects/encon-java) +[![maven_central](https://maven-badges.herokuapp.com/maven-central/io.appulse.encon/encon/badge.svg)](https://search.maven.org/search?q=a:encon) +[![License](http://img.shields.io/:license-apache-brightgreen.svg)](http://www.apache.org/licenses/LICENSE-2.0.html) +[![JavaDoc](http://www.javadoc.io/badge/io.appulse.encon/encon.svg)](http://www.javadoc.io/doc/io.appulse.encon/encon) + + + + This project contains the general-purpose data-binding functionality. - [Add dependency](#add-dependency) From 7fdc167a1bf625e0995522c5c1a3300ede397f14 Mon Sep 17 00:00:00 2001 From: Artem Labazin Date: Thu, 11 Oct 2018 10:15:33 +0300 Subject: [PATCH 05/20] Remote procedure call functionality refactoring --- .../encon/ModuleRemoteProcedureCall.java | 404 ++++++++++++++++++ .../src/main/java/io/appulse/encon/Node.java | 14 + .../io/appulse/encon/mailbox/Mailbox.java | 278 ------------ .../test/java/io/appulse/encon/NodeTest.java | 37 +- 4 files changed, 429 insertions(+), 304 deletions(-) create mode 100644 encon/src/main/java/io/appulse/encon/ModuleRemoteProcedureCall.java diff --git a/encon/src/main/java/io/appulse/encon/ModuleRemoteProcedureCall.java b/encon/src/main/java/io/appulse/encon/ModuleRemoteProcedureCall.java new file mode 100644 index 0000000..74b6e30 --- /dev/null +++ b/encon/src/main/java/io/appulse/encon/ModuleRemoteProcedureCall.java @@ -0,0 +1,404 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.appulse.encon; + +import static io.appulse.encon.terms.Erlang.NIL; +import static io.appulse.encon.terms.Erlang.atom; +import static io.appulse.encon.terms.Erlang.list; +import static io.appulse.encon.terms.Erlang.tuple; +import static java.util.Optional.ofNullable; +import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static lombok.AccessLevel.PACKAGE; +import static lombok.AccessLevel.PRIVATE; + +import java.util.Optional; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +import io.appulse.encon.common.NodeDescriptor; +import io.appulse.encon.common.RemoteNode; +import io.appulse.encon.connection.regular.Message; +import io.appulse.encon.exception.NoSuchRemoteNodeException; +import io.appulse.encon.mailbox.Mailbox; +import io.appulse.encon.terms.ErlangTerm; +import io.appulse.encon.terms.type.ErlangAtom; + +import lombok.AllArgsConstructor; +import lombok.NonNull; +import lombok.experimental.FieldDefaults; +import lombok.val; + +/** + * Module with set of methods for remote procedure calls. + * + * @since 2.0.0 + * @author Artem Labazin + */ +@AllArgsConstructor(access = PACKAGE) +@FieldDefaults(level = PRIVATE, makeFinal = true) +public class ModuleRemoteProcedureCall { + + Node node; + + /** + * Send an RPC request to the remote Erlang node. This convenience function + * creates the following message and sends it to 'rex' on the remote node: + * + *
+   * { selfPid, { :call, :module_name, :function_name, [arguments], :user } }
+   * 
+ * + *

+ * Note that this method has unpredicatble results if the remote node is not + * an Erlang node. + *

+ * + *

+ * The response will be send back to this node in format: + *

+   * { :rex, response_body }
+   * 
+ *

+ * + * @param remoteNodeName remote node name + * + * @param module the name of the Erlang module containing the function to be called. + * + * @param function the name of the function to call. + * + * @param args a list of Erlang terms, to be used as arguments to the function. + * + * @return response holder, instance of {@link RpcResponse}. + */ + public RpcResponse call (@NonNull String remoteNodeName, @NonNull String module, @NonNull String function, ErlangTerm ...args) { + return call(remoteNodeName, atom(module), atom(function), args); + } + + /** + * Send an RPC request to the remote Erlang node. This convenience function + * creates the following message and sends it to 'rex' on the remote node: + * + *
+   * { selfPid, { :call, :module_name, :function_name, [arguments], :user } }
+   * 
+ * + *

+ * Note that this method has unpredicatble results if the remote node is not + * an Erlang node. + *

+ * + *

+ * The response will be send back to this node in format: + *

+   * { :rex, response_body }
+   * 
+ *

+ * + * @param descriptor remote node descriptor + * + * @param module the name of the Erlang module containing the function to be called. + * + * @param function the name of the function to call. + * + * @param args a list of Erlang terms, to be used as arguments to the function. + * + * @return response holder, instance of {@link RpcResponse}. + */ + public RpcResponse call (@NonNull NodeDescriptor descriptor, @NonNull String module, @NonNull String function, ErlangTerm ...args) { + return call(descriptor, atom(module), atom(function), args); + } + + /** + * Send an RPC request to the remote Erlang node. This convenience function + * creates the following message and sends it to 'rex' on the remote node: + * + *
+   * { selfPid, { :call, :module_name, :function_name, [arguments], :user } }
+   * 
+ * + *

+ * Note that this method has unpredicatble results if the remote node is not + * an Erlang node. + *

+ * + *

+ * The response will be send back to this node in format: + *

+   * { :rex, response_body }
+   * 
+ *

+ * + * @param remote remote node descriptor + * + * @param module the name of the Erlang module containing the function to be called. + * + * @param function the name of the function to call. + * + * @param args a list of Erlang terms, to be used as arguments to the function. + * + * @return response holder, instance of {@link RpcResponse}. + */ + public RpcResponse call (@NonNull RemoteNode remote, @NonNull String module, @NonNull String function, ErlangTerm ...args) { + return call(remote, atom(module), atom(function), args); + } + + /** + * Send an RPC request to the remote Erlang node. This convenience function + * creates the following message and sends it to 'rex' on the remote node: + * + *
+   * { selfPid, { :call, :module_name, :function_name, [arguments], :user } }
+   * 
+ * + *

+ * Note that this method has unpredicatble results if the remote node is not + * an Erlang node. + *

+ * + *

+ * The response will be send back to this node in format: + *

+   * { :rex, response_body }
+   * 
+ *

+ * + * @param remoteNodeName remote node name + * + * @param module the atom of the Erlang module containing the function to be called. + * + * @param function the atom of the function to call. + * + * @param args a list of Erlang terms, to be used as arguments to the function. + * + * @return response holder, instance of {@link RpcResponse}. + */ + public RpcResponse call (@NonNull String remoteNodeName, @NonNull ErlangAtom module, @NonNull ErlangAtom function, ErlangTerm ...args) { + val descriptor = NodeDescriptor.from(remoteNodeName); + return call(descriptor, module, function, args); + } + + /** + * Send an RPC request to the remote Erlang node. This convenience function + * creates the following message and sends it to 'rex' on the remote node: + * + *
+   * { selfPid, { :call, :module_name, :function_name, [arguments], :user } }
+   * 
+ * + *

+ * Note that this method has unpredicatble results if the remote node is not + * an Erlang node. + *

+ * + *

+ * The response will be send back to this node in format: + *

+   * { :rex, response_body }
+   * 
+ *

+ * + * @param descriptor remote node descriptor + * + * @param module the atom of the Erlang module containing the function to be called. + * + * @param function the atom of the function to call. + * + * @param args a list of Erlang terms, to be used as arguments to the function. + * + * @return response holder, instance of {@link RpcResponse}. + */ + public RpcResponse call (@NonNull NodeDescriptor descriptor, + @NonNull ErlangAtom module, + @NonNull ErlangAtom function, + ErlangTerm ...args + ) { + RemoteNode remote = node.lookup(descriptor); + if (remote == null) { + throw new NoSuchRemoteNodeException(descriptor); + } + return call(remote, module, function, args); + } + + /** + * Send an RPC request to the remote Erlang node. This convenience function + * creates the following message and sends it to 'rex' on the remote node: + * + *
+   * { selfPid, { :call, :module_name, :function_name, [arguments], :user } }
+   * 
+ * + *

+ * Note that this method has unpredicatble results if the remote node is not + * an Erlang node. + *

+ * + *

+ * The response will be send back to this node in format: + *

+   * { :rex, response_body }
+   * 
+ *

+ * + * @param remote remote node descriptor + * + * @param module the atom of the Erlang module containing the function to be called. + * + * @param function the atom of the function to call. + * + * @param args a list of Erlang terms, to be used as arguments to the function. + * + * @return response holder, instance of {@link RpcResponse}. + */ + @SuppressWarnings("PMD.AccessorClassGeneration") + public RpcResponse call (@NonNull RemoteNode remote, @NonNull ErlangAtom module, @NonNull ErlangAtom function, ErlangTerm ...args) { + ErlangTerm argumentsList; + if (args == null || args.length == 0) { + argumentsList = NIL; + } else if (args.length == 1 && args[0].isList()) { + argumentsList = args[0]; + } else { + argumentsList = list(args); + } + + Mailbox mailbox = node.mailbox().build(); + mailbox.send(remote, "rex", tuple( + mailbox.getPid(), + tuple( + atom("call"), + module, + function, + argumentsList, + atom("user") + ) + )); + return new RpcResponse(mailbox); + } + + /** + * Remote procedure call response holder. + */ + @FieldDefaults(level = PRIVATE) + public static final class RpcResponse { + + Mailbox mailbox; + + final AtomicReference response = new AtomicReference<>(null); + + private RpcResponse (Mailbox mailbox) { + this.mailbox = mailbox; + } + + /** + * Checks if a response was coming or not. + * + * @return {@code true} if this holder has a response, {@code false} otherwise. + */ + public boolean hasResponse () { + return response.get() != null || (mailbox != null && mailbox.size() == 0); + } + + /** + * Receive an RPC reply from the remote Erlang node in asynchronous manner. + * This convenience function receives a message from the remote node, and expects it to have + * the following format: + * + *
+     * { :rex, ErlangTerm }
+     * 
+ * + * @return the second element of the tuple if the received message is a + * two-tuple, otherwise empty. No further error checking is + * performed. + */ + public Optional getAsync () { + ErlangTerm result = response.get(); + if (result == null) { + result = getSync(1, NANOSECONDS); + } + return ofNullable(result); + } + + /** + * Receive an RPC reply from the remote Erlang node in synchronous manner. + * This convenience function receives a message from the remote node, and expects it to have + * the following format: + * + *
+     * { :rex, ErlangTerm }
+     * 
+ * + * @return the second element of the tuple if the received message is a + * two-tuple, otherwise null. No further error checking is + * performed. + */ + public ErlangTerm getSync () { + ErlangTerm result = response.get(); + if (result != null) { + return result; + } + return mailbox.receive() + .getBody() + .get(1) + .map(this::process) + .orElse(null); + } + + /** + * Receive an RPC reply from the remote Erlang node in synchronous manner. + * This convenience function receives a message from the remote node, and expects it to have + * the following format: + * + *
+     * { :rex, ErlangTerm }
+     * 
+ * + * @param timeout how long to wait before giving up, in units of + * {@code unit} + * @param unit a {@code TimeUnit} determining how to interpret the + * {@code timeout} parameter + * + * @return the second element of the tuple if the received message is a + * two-tuple, otherwise null. No further error checking is + * performed. It also could return {@ null} if the specified + * waiting time elapses before an element is available + */ + public ErlangTerm getSync (long timeout, TimeUnit unit) { + ErlangTerm result = response.get(); + if (result != null) { + return result; + } + Message message = mailbox.receive(timeout, unit); + if (message == null) { + return null; + } + return message.getBody() + .get(1) + .map(this::process) + .orElse(null); + } + + @SuppressWarnings("PMD.NullAssignment") + private ErlangTerm process (ErlangTerm term) { + if (!response.compareAndSet(null, term)) { + return null; + } + mailbox.close(); + mailbox = null; + return term; + } + } +} diff --git a/encon/src/main/java/io/appulse/encon/Node.java b/encon/src/main/java/io/appulse/encon/Node.java index 5f702f3..59e4997 100644 --- a/encon/src/main/java/io/appulse/encon/Node.java +++ b/encon/src/main/java/io/appulse/encon/Node.java @@ -133,6 +133,8 @@ static Node newInstance (@NonNull String name, @NonNull NodeConfig nodeConfig) { ModuleClient moduleClient; + ModuleRemoteProcedureCall moduleRemoteProcedureCall; + @Builder private Node (@NonNull NodeDescriptor descriptor, @NonNull Meta meta, @@ -163,6 +165,18 @@ private Node (@NonNull NodeDescriptor descriptor, moduleServer = new ModuleServer(this, moduleConnection, port); moduleClient = new ModuleClient(this, moduleConnection, configCopy.getShortName()); moduleMailbox = new ModuleMailbox(this, () -> generatorPid.generate()); + + moduleRemoteProcedureCall = new ModuleRemoteProcedureCall(this); + } + + /** + * Returns reference on {@link ModuleRemoteProcedureCall} instance + * for calling remote node's functions. + * + * @return {@link ModuleRemoteProcedureCall} instance. + */ + public ModuleRemoteProcedureCall rpc () { + return moduleRemoteProcedureCall; } /** diff --git a/encon/src/main/java/io/appulse/encon/mailbox/Mailbox.java b/encon/src/main/java/io/appulse/encon/mailbox/Mailbox.java index d8739c9..12b14da 100644 --- a/encon/src/main/java/io/appulse/encon/mailbox/Mailbox.java +++ b/encon/src/main/java/io/appulse/encon/mailbox/Mailbox.java @@ -16,10 +16,7 @@ package io.appulse.encon.mailbox; -import static io.appulse.encon.terms.Erlang.NIL; import static io.appulse.encon.terms.Erlang.atom; -import static io.appulse.encon.terms.Erlang.list; -import static io.appulse.encon.terms.Erlang.tuple; import static lombok.AccessLevel.PACKAGE; import static lombok.AccessLevel.PRIVATE; @@ -45,7 +42,6 @@ import io.appulse.encon.mailbox.exception.MailboxWithSuchPidDoesntExistException; import io.appulse.encon.mailbox.exception.ReceivedExitException; import io.appulse.encon.terms.ErlangTerm; -import io.appulse.encon.terms.type.ErlangAtom; import io.appulse.encon.terms.type.ErlangPid; import lombok.AllArgsConstructor; @@ -224,280 +220,6 @@ public void send (@NonNull RemoteNode remote, @NonNull String mailbox, @NonNull } } - /** - * Send an RPC request to the remote Erlang node. This convenience function - * creates the following message and sends it to 'rex' on the remote node: - * - *
-   * { selfPid, { :call, :module_name, :function_name, [arguments], :user } }
-   * 
- * - *

- * Note that this method has unpredicatble results if the remote node is not - * an Erlang node. - *

- * - *

- * The response will be send back to this node in format: - *

-   * { :rex, response_body }
-   * 
- *

- * - * @param remoteNodeName remote node name - * - * @param module the name of the Erlang module containing the function to be called. - * - * @param function the name of the function to call. - * - * @param args a list of Erlang terms, to be used as arguments to the function. - * - * @since 1.6.4 - */ - public void call (@NonNull String remoteNodeName, @NonNull String module, @NonNull String function, ErlangTerm ...args) { - call(remoteNodeName, atom(module), atom(function), args); - } - - /** - * Send an RPC request to the remote Erlang node. This convenience function - * creates the following message and sends it to 'rex' on the remote node: - * - *
-   * { selfPid, { :call, :module_name, :function_name, [arguments], :user } }
-   * 
- * - *

- * Note that this method has unpredicatble results if the remote node is not - * an Erlang node. - *

- * - *

- * The response will be send back to this node in format: - *

-   * { :rex, response_body }
-   * 
- *

- * - * @param descriptor remote node descriptor - * - * @param module the name of the Erlang module containing the function to be called. - * - * @param function the name of the function to call. - * - * @param args a list of Erlang terms, to be used as arguments to the function. - * - * @since 1.6.4 - */ - public void call (@NonNull NodeDescriptor descriptor, @NonNull String module, @NonNull String function, ErlangTerm ...args) { - call(descriptor, atom(module), atom(function), args); - } - - /** - * Send an RPC request to the remote Erlang node. This convenience function - * creates the following message and sends it to 'rex' on the remote node: - * - *
-   * { selfPid, { :call, :module_name, :function_name, [arguments], :user } }
-   * 
- * - *

- * Note that this method has unpredicatble results if the remote node is not - * an Erlang node. - *

- * - *

- * The response will be send back to this node in format: - *

-   * { :rex, response_body }
-   * 
- *

- * - * @param remote remote node descriptor - * - * @param module the name of the Erlang module containing the function to be called. - * - * @param function the name of the function to call. - * - * @param args a list of Erlang terms, to be used as arguments to the function. - * - * @since 1.6.4 - */ - public void call (@NonNull RemoteNode remote, @NonNull String module, @NonNull String function, ErlangTerm ...args) { - call(remote, atom(module), atom(function), args); - } - - /** - * Send an RPC request to the remote Erlang node. This convenience function - * creates the following message and sends it to 'rex' on the remote node: - * - *
-   * { selfPid, { :call, :module_name, :function_name, [arguments], :user } }
-   * 
- * - *

- * Note that this method has unpredicatble results if the remote node is not - * an Erlang node. - *

- * - *

- * The response will be send back to this node in format: - *

-   * { :rex, response_body }
-   * 
- *

- * - * @param remoteNodeName remote node name - * - * @param module the atom of the Erlang module containing the function to be called. - * - * @param function the atom of the function to call. - * - * @param args a list of Erlang terms, to be used as arguments to the function. - * - * @since 1.6.4 - */ - public void call (@NonNull String remoteNodeName, @NonNull ErlangAtom module, @NonNull ErlangAtom function, ErlangTerm ...args) { - val descriptor = NodeDescriptor.from(remoteNodeName); - call(descriptor, module, function, args); - } - - /** - * Send an RPC request to the remote Erlang node. This convenience function - * creates the following message and sends it to 'rex' on the remote node: - * - *
-   * { selfPid, { :call, :module_name, :function_name, [arguments], :user } }
-   * 
- * - *

- * Note that this method has unpredicatble results if the remote node is not - * an Erlang node. - *

- * - *

- * The response will be send back to this node in format: - *

-   * { :rex, response_body }
-   * 
- *

- * - * @param descriptor remote node descriptor - * - * @param module the atom of the Erlang module containing the function to be called. - * - * @param function the atom of the function to call. - * - * @param args a list of Erlang terms, to be used as arguments to the function. - * - * @since 1.6.4 - */ - public void call (@NonNull NodeDescriptor descriptor, @NonNull ErlangAtom module, @NonNull ErlangAtom function, ErlangTerm ...args) { - RemoteNode remote = node.lookup(descriptor); - if (remote == null) { - throw new NoSuchRemoteNodeException(descriptor); - } - call(remote, module, function, args); - } - - /** - * Send an RPC request to the remote Erlang node. This convenience function - * creates the following message and sends it to 'rex' on the remote node: - * - *
-   * { selfPid, { :call, :module_name, :function_name, [arguments], :user } }
-   * 
- * - *

- * Note that this method has unpredicatble results if the remote node is not - * an Erlang node. - *

- * - *

- * The response will be send back to this node in format: - *

-   * { :rex, response_body }
-   * 
- *

- * - * @param remote remote node descriptor - * - * @param module the atom of the Erlang module containing the function to be called. - * - * @param function the atom of the function to call. - * - * @param args a list of Erlang terms, to be used as arguments to the function. - * - * @since 1.6.4 - */ - public void call (@NonNull RemoteNode remote, @NonNull ErlangAtom module, @NonNull ErlangAtom function, ErlangTerm ...args) { - ErlangTerm argumentsList; - if (args == null || args.length == 0) { - argumentsList = NIL; - } else if (args.length == 1 && args[0].isList()) { - argumentsList = args[0]; - } else { - argumentsList = list(args); - } - - send(remote, "rex", tuple( - pid, - tuple( - atom("call"), - module, - function, - argumentsList, - atom("user") - ) - )); - } - - /** - * Receive an RPC reply from the remote Erlang node. This convenience - * function receives a message from the remote node, and expects it to have - * the following format: - * - *
-   * { :rex, ErlangTerm }
-   * 
- * - * @return the second element of the tuple if the received message is a - * two-tuple, otherwise null. No further error checking is - * performed. - */ - public ErlangTerm receiveRemoteProcedureResult () { - return receive().getBody() - .get(1) - .orElse(null); - } - - /** - * Receive an RPC reply from the remote Erlang node. This convenience - * function receives a message from the remote node, and expects it to have - * the following format: - * - *
-   * { :rex, ErlangTerm }
-   * 
- * - * @param timeout how long to wait before giving up, in units of - * {@code unit} - * @param unit a {@code TimeUnit} determining how to interpret the - * {@code timeout} parameter - * - * @return the second element of the tuple if the received message is a - * two-tuple, otherwise null. No further error checking is - * performed. It also could return {@ null} if the specified - * waiting time elapses before an element is available - */ - public ErlangTerm receiveRemoteProcedureResult (long timeout, TimeUnit unit) { - Message message = receive(timeout, unit); - if (message == null) { - return null; - } - return message.getBody() - .get(1) - .orElse(null); - } /** * Links the mailbox. diff --git a/encon/src/test/java/io/appulse/encon/NodeTest.java b/encon/src/test/java/io/appulse/encon/NodeTest.java index cc4fec4..2c31a9c 100644 --- a/encon/src/test/java/io/appulse/encon/NodeTest.java +++ b/encon/src/test/java/io/appulse/encon/NodeTest.java @@ -28,13 +28,12 @@ import static java.util.concurrent.TimeUnit.SECONDS; import static org.assertj.core.api.Assertions.assertThat; import static java.util.Optional.ofNullable; -import static io.appulse.encon.connection.control.ControlMessageTag.SEND; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import io.appulse.encon.connection.control.ControlMessage; import io.appulse.encon.connection.regular.Message; +import io.appulse.encon.ModuleRemoteProcedureCall.RpcResponse; import io.appulse.encon.NodesConfig.NodeConfig; import io.appulse.encon.NodesConfig.NodeConfig.ServerConfig; import io.appulse.encon.mailbox.Mailbox; @@ -379,33 +378,19 @@ public void remoteProcedureCall () throws Exception { .cookie("secret") .build()); - Mailbox mailbox = node.mailbox().build(); - mailbox.call(ELIXIR_ECHO_SERVER, "erlang", "date"); + RpcResponse response = node.rpc() + .call(ELIXIR_ECHO_SERVER, "erlang", "date"); - Message message = mailbox.receive(5, SECONDS); - assertThat(message.getHeader()) - .extracting(ControlMessage::getTag) - .isEqualTo(SEND); - - assertThat(message.getBody()) - .isNotNull(); - - ErlangTerm term = message.getBody(); - assertThat(term.isTuple()).isTrue(); - assertThat(term.size()).isEqualTo(2); - - assertThat(term.getUnsafe(0).asText()).isEqualTo("rex"); - assertThat(term.getUnsafe(1).isTuple()).isTrue(); - - ErlangTerm response1 = term.getUnsafe(1); - assertThat(response1.getUnsafe(0).isNumber()).isTrue(); - assertThat(response1.getUnsafe(1).isNumber()).isTrue(); - assertThat(response1.getUnsafe(2).isNumber()).isTrue(); + ErlangTerm payload = response.getSync(5, SECONDS); + assertThat(payload.getUnsafe(0).isNumber()).isTrue(); + assertThat(payload.getUnsafe(1).isNumber()).isTrue(); + assertThat(payload.getUnsafe(2).isNumber()).isTrue(); - mailbox.call(ELIXIR_ECHO_SERVER, "erlang", "date"); - ErlangTerm response2 = mailbox.receiveRemoteProcedureResult(5, SECONDS); - assertThat(response2).isEqualTo(response1); + assertThat(response.hasResponse()).isTrue(); + assertThat(response.getAsync().get()) + .isEqualTo(payload) + .isSameAs(payload); } private String createName () { From 8ea43260fb54253b1fdfc1d16693e86ff3165c2b Mon Sep 17 00:00:00 2001 From: Artem Labazin Date: Mon, 10 Dec 2018 01:23:19 +0300 Subject: [PATCH 06/20] Update POM files --- benchmark/pom.xml | 26 +--- encon-common/pom.xml | 33 +---- encon-config/pom.xml | 33 +---- encon-databind/pom.xml | 33 +---- encon-handler/pom.xml | 35 +---- encon-spring/pom.xml | 35 +---- encon-terms/pom.xml | 33 +---- encon/pom.xml | 39 +---- examples/custom-queue/pom.xml | 17 --- examples/databind/pom.xml | 24 +--- examples/echo-server-spring/pom.xml | 25 +--- examples/echo-server/pom.xml | 18 --- examples/handler-advanced/pom.xml | 24 ---- examples/handler-basic/pom.xml | 24 ---- examples/load-config-spring/pom.xml | 23 +-- examples/load-config/pom.xml | 25 ---- examples/simple/pom.xml | 19 +-- pom.xml | 214 +++++++++++++++++++--------- 18 files changed, 170 insertions(+), 510 deletions(-) diff --git a/benchmark/pom.xml b/benchmark/pom.xml index c907d95..350ba29 100644 --- a/benchmark/pom.xml +++ b/benchmark/pom.xml @@ -31,14 +31,6 @@ limitations under the License. benchmark jar - - UTF-8 - UTF-8 - - 1.8 - 1.8 - - io.appulse.epmd.java @@ -55,12 +47,6 @@ limitations under the License. jinterface - - org.projectlombok - lombok - provided - - org.openjdk.jmh jmh-core @@ -75,20 +61,10 @@ limitations under the License. - - org.apache.maven.plugins - maven-compiler-plugin - 3.1 - - ${maven.compiler.target} - ${maven.compiler.source} - ${maven.compiler.target} - - org.apache.maven.plugins maven-shade-plugin - 2.2 + 3.2.1 package diff --git a/encon-common/pom.xml b/encon-common/pom.xml index 6d3c51c..5b7888c 100644 --- a/encon-common/pom.xml +++ b/encon-common/pom.xml @@ -32,38 +32,10 @@ limitations under the License. jar - - org.projectlombok - lombok - provided - - io.appulse.epmd.java core - - - com.google.code.findbugs - annotations - provided - - - com.google.code.findbugs - jsr305 - provided - - - - junit - junit - test - - - org.assertj - assertj-core - test - @@ -78,14 +50,13 @@ limitations under the License. - org.codehaus.mojo - findbugs-maven-plugin + com.github.spotbugs + spotbugs-maven-plugin org.apache.maven.plugins maven-pmd-plugin - org.apache.maven.plugins maven-checkstyle-plugin diff --git a/encon-config/pom.xml b/encon-config/pom.xml index 9817561..89331e6 100644 --- a/encon-config/pom.xml +++ b/encon-config/pom.xml @@ -32,45 +32,17 @@ limitations under the License. jar - - org.projectlombok - lombok - provided - - org.yaml snakeyaml 1.23 - - com.google.code.findbugs - annotations - provided - - - com.google.code.findbugs - jsr305 - provided - - io.appulse utils-java test - - - junit - junit - test - - - org.assertj - assertj-core - test - @@ -85,14 +57,13 @@ limitations under the License. - org.codehaus.mojo - findbugs-maven-plugin + com.github.spotbugs + spotbugs-maven-plugin org.apache.maven.plugins maven-pmd-plugin - org.apache.maven.plugins maven-checkstyle-plugin diff --git a/encon-databind/pom.xml b/encon-databind/pom.xml index 308f588..51ae06f 100644 --- a/encon-databind/pom.xml +++ b/encon-databind/pom.xml @@ -32,12 +32,6 @@ limitations under the License. jar - - org.projectlombok - lombok - provided - - ${project.groupId} encon-terms @@ -52,28 +46,6 @@ limitations under the License. io.appulse utils-java - - - com.google.code.findbugs - annotations - provided - - - com.google.code.findbugs - jsr305 - provided - - - - junit - junit - test - - - org.assertj - assertj-core - test - @@ -88,14 +60,13 @@ limitations under the License. - org.codehaus.mojo - findbugs-maven-plugin + com.github.spotbugs + spotbugs-maven-plugin org.apache.maven.plugins maven-pmd-plugin - org.apache.maven.plugins maven-checkstyle-plugin diff --git a/encon-handler/pom.xml b/encon-handler/pom.xml index e7d3f77..2c837d5 100644 --- a/encon-handler/pom.xml +++ b/encon-handler/pom.xml @@ -32,12 +32,6 @@ limitations under the License. jar - - org.projectlombok - lombok - provided - - ${project.groupId} encon @@ -52,29 +46,7 @@ limitations under the License. cglib cglib - 3.2.7 - - - - com.google.code.findbugs - annotations - provided - - - com.google.code.findbugs - jsr305 - provided - - - - junit - junit - test - - - org.assertj - assertj-core - test + 3.2.9 @@ -90,14 +62,13 @@ limitations under the License. - org.codehaus.mojo - findbugs-maven-plugin + com.github.spotbugs + spotbugs-maven-plugin org.apache.maven.plugins maven-pmd-plugin - org.apache.maven.plugins maven-checkstyle-plugin diff --git a/encon-spring/pom.xml b/encon-spring/pom.xml index 953f11b..1ec3654 100644 --- a/encon-spring/pom.xml +++ b/encon-spring/pom.xml @@ -32,12 +32,6 @@ limitations under the License. jar - - org.projectlombok - lombok - provided - - ${project.groupId} encon @@ -57,29 +51,7 @@ limitations under the License. org.springframework.boot spring-boot-starter - 2.0.4.RELEASE - - - - com.google.code.findbugs - annotations - provided - - - com.google.code.findbugs - jsr305 - provided - - - - junit - junit - test - - - org.assertj - assertj-core - test + 2.1.1.RELEASE @@ -95,14 +67,13 @@ limitations under the License. - org.codehaus.mojo - findbugs-maven-plugin + com.github.spotbugs + spotbugs-maven-plugin org.apache.maven.plugins maven-pmd-plugin - org.apache.maven.plugins maven-checkstyle-plugin diff --git a/encon-terms/pom.xml b/encon-terms/pom.xml index 4f77c05..bca0826 100644 --- a/encon-terms/pom.xml +++ b/encon-terms/pom.xml @@ -32,45 +32,17 @@ limitations under the License. jar - - org.projectlombok - lombok - provided - - ${project.groupId} encon-common ${project.version} - - com.google.code.findbugs - annotations - provided - - - com.google.code.findbugs - jsr305 - provided - - io.netty netty-buffer - - - junit - junit - test - - - org.assertj - assertj-core - test - @@ -85,14 +57,13 @@ limitations under the License. - org.codehaus.mojo - findbugs-maven-plugin + com.github.spotbugs + spotbugs-maven-plugin org.apache.maven.plugins maven-pmd-plugin - org.apache.maven.plugins maven-checkstyle-plugin diff --git a/encon/pom.xml b/encon/pom.xml index 331126a..8fe814d 100644 --- a/encon/pom.xml +++ b/encon/pom.xml @@ -32,12 +32,6 @@ limitations under the License. jar - - org.projectlombok - lombok - provided - - ${project.groupId} encon-common @@ -67,21 +61,10 @@ limitations under the License. client - - com.google.code.findbugs - annotations - provided - - - com.google.code.findbugs - jsr305 - provided - - org.yaml snakeyaml - 1.21 + 1.23 @@ -99,21 +82,6 @@ limitations under the License. server test - - junit - junit - test - - - org.assertj - assertj-core - test - - - org.mockito - mockito-core - test - @@ -128,14 +96,13 @@ limitations under the License. - org.codehaus.mojo - findbugs-maven-plugin + com.github.spotbugs + spotbugs-maven-plugin org.apache.maven.plugins maven-pmd-plugin - org.apache.maven.plugins maven-checkstyle-plugin diff --git a/examples/custom-queue/pom.xml b/examples/custom-queue/pom.xml index 0b6e9d8..7992ea2 100644 --- a/examples/custom-queue/pom.xml +++ b/examples/custom-queue/pom.xml @@ -33,12 +33,6 @@ limitations under the License. jar - UTF-8 - UTF-8 - - 1.8 - 1.8 - io.appulse.encon.examples.custom.queue.Main @@ -48,17 +42,6 @@ limitations under the License. encon ${project.version} - - - junit - junit - test - - - org.assertj - assertj-core - test - diff --git a/examples/databind/pom.xml b/examples/databind/pom.xml index 734bd0b..405912e 100644 --- a/examples/databind/pom.xml +++ b/examples/databind/pom.xml @@ -33,21 +33,10 @@ limitations under the License. jar - UTF-8 - UTF-8 - - 1.8 - 1.8 - io.appulse.encon.examples.databind.Main - - org.projectlombok - lombok - - io.appulse.encon encon @@ -58,17 +47,6 @@ limitations under the License. encon-databind ${project.version} - - - junit - junit - test - - - org.assertj - assertj-core - test - @@ -76,7 +54,7 @@ limitations under the License. org.apache.maven.plugins maven-shade-plugin - 3.1.0 + 3.2.1 diff --git a/examples/echo-server-spring/pom.xml b/examples/echo-server-spring/pom.xml index 8e206d4..d33b3a9 100644 --- a/examples/echo-server-spring/pom.xml +++ b/examples/echo-server-spring/pom.xml @@ -33,7 +33,7 @@ limitations under the License. org.springframework.boot spring-boot-dependencies - 2.0.4.RELEASE + 2.1.1.RELEASE pom import @@ -44,23 +44,12 @@ limitations under the License. echo-server-spring jar - - UTF-8 - 1.8 - 1.8 - - org.springframework.boot spring-boot-starter - - org.projectlombok - lombok - - io.appulse.encon encon-spring @@ -77,16 +66,6 @@ limitations under the License. spring-boot-starter-test test - - junit - junit - test - - - org.assertj - assertj-core - test - @@ -94,7 +73,7 @@ limitations under the License. org.springframework.boot spring-boot-maven-plugin - 2.0.4.RELEASE + 2.1.1.RELEASE diff --git a/examples/echo-server/pom.xml b/examples/echo-server/pom.xml index a881751..a1512b3 100644 --- a/examples/echo-server/pom.xml +++ b/examples/echo-server/pom.xml @@ -32,19 +32,7 @@ limitations under the License. echo-server jar - - UTF-8 - UTF-8 - - 1.8 - 1.8 - - - - org.projectlombok - lombok - io.appulse.encon encon @@ -55,11 +43,5 @@ limitations under the License. encon-databind ${project.version} - - - junit - junit - test - diff --git a/examples/handler-advanced/pom.xml b/examples/handler-advanced/pom.xml index 18a625c..a443105 100644 --- a/examples/handler-advanced/pom.xml +++ b/examples/handler-advanced/pom.xml @@ -32,20 +32,7 @@ limitations under the License. handler-advanced jar - - UTF-8 - UTF-8 - - 1.8 - 1.8 - - - - org.projectlombok - lombok - - io.appulse.encon encon @@ -56,16 +43,5 @@ limitations under the License. encon-handler ${project.version} - - - junit - junit - test - - - org.assertj - assertj-core - test - diff --git a/examples/handler-basic/pom.xml b/examples/handler-basic/pom.xml index 27dced7..3754a6a 100644 --- a/examples/handler-basic/pom.xml +++ b/examples/handler-basic/pom.xml @@ -32,20 +32,7 @@ limitations under the License. handler-basic jar - - UTF-8 - UTF-8 - - 1.8 - 1.8 - - - - org.projectlombok - lombok - - io.appulse.encon encon @@ -56,16 +43,5 @@ limitations under the License. encon-handler ${project.version} - - - junit - junit - test - - - org.assertj - assertj-core - test - diff --git a/examples/load-config-spring/pom.xml b/examples/load-config-spring/pom.xml index 5da4b84..6b8bf3e 100644 --- a/examples/load-config-spring/pom.xml +++ b/examples/load-config-spring/pom.xml @@ -33,7 +33,7 @@ limitations under the License. org.springframework.boot spring-boot-dependencies - 2.0.4.RELEASE + 2.1.1.RELEASE pom import @@ -45,10 +45,6 @@ limitations under the License. jar - UTF-8 - 1.8 - 1.8 - io.appulse.encon.examples.load.config.spring.Main @@ -58,11 +54,6 @@ limitations under the License. spring-boot-starter - - org.projectlombok - lombok - - io.appulse.encon encon-spring @@ -79,16 +70,6 @@ limitations under the License. spring-boot-starter-test test - - junit - junit - test - - - org.assertj - assertj-core - test - @@ -96,7 +77,7 @@ limitations under the License. org.springframework.boot spring-boot-maven-plugin - 2.0.4.RELEASE + 2.1.1.RELEASE diff --git a/examples/load-config/pom.xml b/examples/load-config/pom.xml index f9bd914..69f9b56 100644 --- a/examples/load-config/pom.xml +++ b/examples/load-config/pom.xml @@ -32,36 +32,11 @@ limitations under the License. load-config jar - - UTF-8 - UTF-8 - - 1.8 - 1.8 - - - - org.projectlombok - lombok - provided - - io.appulse.encon encon ${project.version} - - - junit - junit - test - - - org.assertj - assertj-core - test - diff --git a/examples/simple/pom.xml b/examples/simple/pom.xml index 859160e..5946067 100644 --- a/examples/simple/pom.xml +++ b/examples/simple/pom.xml @@ -33,12 +33,6 @@ limitations under the License. jar - UTF-8 - UTF-8 - - 1.8 - 1.8 - io.appulse.encon.examples.simple.Main @@ -48,17 +42,6 @@ limitations under the License. encon ${project.version} - - - junit - junit - test - - - org.assertj - assertj-core - test - @@ -66,7 +49,7 @@ limitations under the License. org.apache.maven.plugins maven-shade-plugin - 3.1.0 + 3.2.1 diff --git a/pom.xml b/pom.xml index 5ae8738..d0a519c 100644 --- a/pom.xml +++ b/pom.xml @@ -31,11 +31,13 @@ limitations under the License. UTF-8 UTF-8 - 1.8 - 1.8 + 11 - 1.8 - 1.8 + ${java.version} + ${java.version} + + ${java.version} + ${java.version} @@ -104,26 +106,71 @@ limitations under the License. Artem Labazin xxlabaza@gmail.com - - ambivalence42 - Sokol Andrey - sokolandrey1993@mail.ru - - - isv - Stan Ignatev - i.v.stanislav@gmail.com - + + + org.projectlombok + lombok + 1.18.4 + provided + + + + net.jcip + jcip-annotations + 1.0 + provided + + + com.github.spotbugs + spotbugs-annotations + 3.1.9 + provided + + + com.google.code.findbugs + jsr305 + 3.0.2 + provided + + + + org.junit.jupiter + junit-jupiter-engine + 5.3.2 + test + + + org.junit.jupiter + junit-jupiter-params + 5.3.2 + test + + + + org.assertj + assertj-core + 3.11.1 + test + + + + org.mockito + mockito-core + 2.23.4 + test + + + org.mockito + mockito-junit-jupiter + 2.23.4 + test + + + - - org.projectlombok - lombok - 1.18.2 - - io.appulse logging-java @@ -156,31 +203,20 @@ limitations under the License. 1.6.1 - - com.google.code.findbugs - annotations - 3.0.1u2 - - - com.google.code.findbugs - jsr305 - 3.0.2 - - io.netty netty-buffer - 4.1.29.Final + 4.1.32.Final io.netty netty-handler - 4.1.29.Final + 4.1.32.Final io.netty netty-transport-native-epoll - 4.1.29.Final + 4.1.32.Final linux-x86_64 @@ -209,22 +245,6 @@ limitations under the License. jmh-generator-annprocess 1.21 - - - junit - junit - 4.12 - - - org.assertj - assertj-core - 3.11.1 - - - org.mockito - mockito-core - 2.22.0 - @@ -232,9 +252,9 @@ limitations under the License. - org.codehaus.mojo - findbugs-maven-plugin - 3.0.5 + com.github.spotbugs + spotbugs-maven-plugin + 3.1.8 Max Low @@ -243,22 +263,22 @@ limitations under the License. - analyze-compile - package + spotbugs-validation + verify check + org.apache.maven.plugins maven-pmd-plugin - 3.10.0 + 3.11.0 ${project.build.sourceEncoding} ${maven.compiler.source} - true true true true @@ -269,7 +289,8 @@ limitations under the License. - package + pmd-validation + verify check @@ -285,13 +306,13 @@ limitations under the License. com.puppycrawl.tools checkstyle - 8.12 + 8.15 - validate - package + checkstyle-validation + verify check @@ -310,7 +331,7 @@ limitations under the License. org.apache.maven.plugins maven-javadoc-plugin - 2.10.4 + 3.0.1 -Xdoclint:none -Xdoclint:none @@ -320,7 +341,7 @@ limitations under the License. UTF-8 true protected - 1.8 + ${java.version} true @@ -386,17 +407,68 @@ limitations under the License. + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + ${java.version} + ${maven.compiler.target} + ${maven.compiler.source} + ${maven.compiler.target} + + + + + pl.project13.maven + git-commit-id-plugin + 2.2.5 + + + git-infos + + revision + + + + + true + false + true + false + git + + ${project.build.outputDirectory}/git.properties + + yyyy-MM-dd'T'HH:mm:ssZ + ${project.basedir}/.git + + git.closest.tag.commit.count + git.closest.tag.name + + + + org.apache.maven.plugins maven-surefire-plugin - 2.21.0 + 2.22.1 + + --illegal-access=permit + false **/*Test.java + **/*Tests.java + **/Test*.java + **/it/** **/*IntegrationTest.java + **/*IntegrationTests.java + **/*IT.java + **/IT*.java @@ -404,14 +476,20 @@ limitations under the License. org.apache.maven.plugins maven-failsafe-plugin - 2.21.0 + 2.22.1 + + --illegal-access=permit + **/*IntegrationTest.java + **/*IntegrationTests.java + **/*IT.java + **/IT*.java + **/it/**/*Test.java + **/it/**/*Tests.java + **/it/**/Test*.java - - **/*Test.java - From 50a460fdf317b1c2d064c7b2118a6fa50268815e Mon Sep 17 00:00:00 2001 From: Artem Labazin Date: Mon, 10 Dec 2018 10:41:03 +0300 Subject: [PATCH 07/20] Add maven wrapper --- .mvn/wrapper/MavenWrapperDownloader.java | 110 +++++++++ .mvn/wrapper/maven-wrapper.properties | 1 + mvnw | 286 +++++++++++++++++++++++ mvnw.cmd | 161 +++++++++++++ 4 files changed, 558 insertions(+) create mode 100644 .mvn/wrapper/MavenWrapperDownloader.java create mode 100644 .mvn/wrapper/maven-wrapper.properties create mode 100755 mvnw create mode 100644 mvnw.cmd diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100644 index 0000000..fa4f7b4 --- /dev/null +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,110 @@ +/* +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. +*/ + +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = + "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if(mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if(mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: : " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if(!outputFile.getParentFile().exists()) { + if(!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..cd0d451 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip diff --git a/mvnw b/mvnw new file mode 100755 index 0000000..5551fde --- /dev/null +++ b/mvnw @@ -0,0 +1,286 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# 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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + wget "$jarUrl" -O "$wrapperJarPath" + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + curl -o "$wrapperJarPath" "$jarUrl" + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000..0e344f6 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,161 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" +FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + echo Found %WRAPPER_JAR% +) else ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" + echo Finished downloading %WRAPPER_JAR% +) +@REM End of extension + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% From afd95be260cbd4d503d4001860b83142a64df4f2 Mon Sep 17 00:00:00 2001 From: Artem Labazin Date: Mon, 10 Dec 2018 11:14:43 +0300 Subject: [PATCH 08/20] Update encon-common to Java 11 --- .../appulse/encon/common/NodeDescriptor.java | 2 ++ .../encon/common/DistributionFlagTest.java | 27 ++++++++++++------- .../encon/common/NodeDescriptorTest.java | 26 ++++++++++-------- 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/encon-common/src/main/java/io/appulse/encon/common/NodeDescriptor.java b/encon-common/src/main/java/io/appulse/encon/common/NodeDescriptor.java index 0ba31ed..e67de2e 100644 --- a/encon-common/src/main/java/io/appulse/encon/common/NodeDescriptor.java +++ b/encon-common/src/main/java/io/appulse/encon/common/NodeDescriptor.java @@ -26,6 +26,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Stream; +import edu.umd.cs.findbugs.annotations.SuppressWarnings; import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.NonNull; @@ -185,6 +186,7 @@ public static boolean removeFromCache (@NonNull NodeDescriptor descriptor) { private static NodeDescriptor getFromCacheOrCreateNew (@NonNull String node) { val atIndex = node.indexOf('@'); + @SuppressWarnings("PMD.LinguisticNaming") val isShortName = atIndex < 0 || node.indexOf('.', atIndex) < 0; return getFromCacheOrCreateNew(node, isShortName); } diff --git a/encon-common/src/test/java/io/appulse/encon/common/DistributionFlagTest.java b/encon-common/src/test/java/io/appulse/encon/common/DistributionFlagTest.java index 6b0ee46..0275a4b 100644 --- a/encon-common/src/test/java/io/appulse/encon/common/DistributionFlagTest.java +++ b/encon-common/src/test/java/io/appulse/encon/common/DistributionFlagTest.java @@ -23,38 +23,45 @@ import java.util.stream.Stream; -import io.appulse.utils.test.TestMethodNamePrinter; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 1.0.0 */ -public class DistributionFlagTest { +class DistributionFlagTest { - @Rule - public TestRule watcher = new TestMethodNamePrinter(); + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void parse () { + @DisplayName("Check if distribution flag's code could be converted to its enum value") + void couldConvert () { Stream.of(DistributionFlag.values()).forEach(it -> { assertThat(DistributionFlag.parse(it.getCode())) .hasSize(1) .first() .isEqualTo(it); }); + } + @Test + @DisplayName("Unfold integer to set of distribution flags") + void unfold () { assertThat(DistributionFlag.parse(262_147)) .hasSize(3) .contains(PUBLISHED, ATOM_CACHE, BIG_CREATION); } @Test - public void bitwiseOr () { + @DisplayName("Fold enum values to integer") + void fold () { assertThat(DistributionFlag.bitwiseOr(PUBLISHED, ATOM_CACHE, BIG_CREATION)) .isEqualTo(262_147); } diff --git a/encon-common/src/test/java/io/appulse/encon/common/NodeDescriptorTest.java b/encon-common/src/test/java/io/appulse/encon/common/NodeDescriptorTest.java index 8db6b81..d8490e9 100644 --- a/encon-common/src/test/java/io/appulse/encon/common/NodeDescriptorTest.java +++ b/encon-common/src/test/java/io/appulse/encon/common/NodeDescriptorTest.java @@ -20,25 +20,27 @@ import java.net.InetAddress; -import io.appulse.utils.test.TestMethodNamePrinter; - import org.assertj.core.api.SoftAssertions; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 1.0.0 */ -public class NodeDescriptorTest { +class NodeDescriptorTest { - @Rule - public TestRule watcher = new TestMethodNamePrinter(); + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void fullShortName () throws Exception { + @DisplayName("Parse short node's name with localhost host") + void fullShortName () throws Exception { InetAddress address = InetAddress.getByName("localhost"); String fullName = "popa@localhost"; NodeDescriptor.removeFromCache(fullName); @@ -72,7 +74,8 @@ public void fullShortName () throws Exception { } @Test - public void shortName () throws Exception { + @DisplayName("Parse short node's name without host") + void shortName () throws Exception { InetAddress address = InetAddress.getLoopbackAddress(); String tmp = InetAddress.getLocalHost().getHostName(); int dotIndex = tmp.indexOf('.'); @@ -112,7 +115,8 @@ public void shortName () throws Exception { } @Test - public void fullLongName () throws Exception { + @DisplayName("Parse full node's name with host") + void fullLongName () throws Exception { InetAddress address = InetAddress.getByName("localhost"); String fullName = "popa@localhost"; NodeDescriptor.removeFromCache(fullName); From ba65495f7a3f4912569e237f6c547158542374cb Mon Sep 17 00:00:00 2001 From: Artem Labazin Date: Mon, 10 Dec 2018 12:04:09 +0300 Subject: [PATCH 09/20] Update encon-terms for Java 11 --- .../encon/common/DistributionFlagTest.java | 7 ++-- .../encon/common/NodeDescriptorTest.java | 7 ++-- .../encon/terms/type/ErlangAtomTest.java | 33 +++++++++++-------- .../encon/terms/type/ErlangBinaryTest.java | 33 +++++++++++-------- .../encon/terms/type/ErlangBitStringTest.java | 33 +++++++++++-------- .../encon/terms/type/ErlangFloatTest.java | 25 +++++++++----- .../encon/terms/type/ErlangIntegerTest.java | 30 ++++++++++------- .../encon/terms/type/ErlangListTest.java | 27 ++++++++------- .../encon/terms/type/ErlangMapTest.java | 21 +++++++----- .../encon/terms/type/ErlangNilTest.java | 26 +++++++++------ .../encon/terms/type/ErlangPidTest.java | 31 ++++++++++------- .../encon/terms/type/ErlangPortTest.java | 29 +++++++++------- .../encon/terms/type/ErlangReferenceTest.java | 32 +++++++++++------- .../encon/terms/type/ErlangStringTest.java | 23 ++++++++----- .../encon/terms/type/ErlangTupleTest.java | 29 +++++++++------- 15 files changed, 236 insertions(+), 150 deletions(-) diff --git a/encon-common/src/test/java/io/appulse/encon/common/DistributionFlagTest.java b/encon-common/src/test/java/io/appulse/encon/common/DistributionFlagTest.java index 0275a4b..3975219 100644 --- a/encon-common/src/test/java/io/appulse/encon/common/DistributionFlagTest.java +++ b/encon-common/src/test/java/io/appulse/encon/common/DistributionFlagTest.java @@ -33,6 +33,7 @@ * @author Artem Labazin * @since 1.0.0 */ +@DisplayName("Check distribution flags enum") class DistributionFlagTest { @BeforeEach @@ -41,7 +42,7 @@ void beforeEach (TestInfo testInfo) { } @Test - @DisplayName("Check if distribution flag's code could be converted to its enum value") + @DisplayName("check if distribution flag's code could be converted to its enum value") void couldConvert () { Stream.of(DistributionFlag.values()).forEach(it -> { assertThat(DistributionFlag.parse(it.getCode())) @@ -52,7 +53,7 @@ void couldConvert () { } @Test - @DisplayName("Unfold integer to set of distribution flags") + @DisplayName("unfold integer to set of distribution flags") void unfold () { assertThat(DistributionFlag.parse(262_147)) .hasSize(3) @@ -60,7 +61,7 @@ void unfold () { } @Test - @DisplayName("Fold enum values to integer") + @DisplayName("fold enum values to integer") void fold () { assertThat(DistributionFlag.bitwiseOr(PUBLISHED, ATOM_CACHE, BIG_CREATION)) .isEqualTo(262_147); diff --git a/encon-common/src/test/java/io/appulse/encon/common/NodeDescriptorTest.java b/encon-common/src/test/java/io/appulse/encon/common/NodeDescriptorTest.java index d8490e9..eaa8586 100644 --- a/encon-common/src/test/java/io/appulse/encon/common/NodeDescriptorTest.java +++ b/encon-common/src/test/java/io/appulse/encon/common/NodeDescriptorTest.java @@ -31,6 +31,7 @@ * @author Artem Labazin * @since 1.0.0 */ +@DisplayName("Check node descriptor") class NodeDescriptorTest { @BeforeEach @@ -39,7 +40,7 @@ void beforeEach (TestInfo testInfo) { } @Test - @DisplayName("Parse short node's name with localhost host") + @DisplayName("parse short node's name with localhost host") void fullShortName () throws Exception { InetAddress address = InetAddress.getByName("localhost"); String fullName = "popa@localhost"; @@ -74,7 +75,7 @@ void fullShortName () throws Exception { } @Test - @DisplayName("Parse short node's name without host") + @DisplayName("parse short node's name without host") void shortName () throws Exception { InetAddress address = InetAddress.getLoopbackAddress(); String tmp = InetAddress.getLocalHost().getHostName(); @@ -115,7 +116,7 @@ void shortName () throws Exception { } @Test - @DisplayName("Parse full node's name with host") + @DisplayName("parse full node's name with host") void fullLongName () throws Exception { InetAddress address = InetAddress.getByName("localhost"); String fullName = "popa@localhost"; diff --git a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangAtomTest.java b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangAtomTest.java index 80a4db9..2176d5f 100644 --- a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangAtomTest.java +++ b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangAtomTest.java @@ -24,11 +24,9 @@ import java.util.stream.IntStream; - import io.appulse.encon.terms.Erlang; import io.appulse.encon.terms.ErlangTerm; import io.appulse.utils.Bytes; -import io.appulse.utils.test.TestMethodNamePrinter; import erlang.OtpInputStream; import erlang.OtpOutputStream; @@ -36,22 +34,27 @@ import lombok.SneakyThrows; import lombok.val; import org.assertj.core.api.SoftAssertions; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 1.0.0 */ -public class ErlangAtomTest { +@DisplayName("Check Erlang's Atom term type") +class ErlangAtomTest { - @Rule - public TestRule watcher = new TestMethodNamePrinter(); + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void instantiate () { + @DisplayName("create new instance by constructor") + void instantiate () { assertThat(new ErlangAtom("hello").getType()) .isEqualTo(SMALL_ATOM_UTF8); @@ -63,7 +66,8 @@ public void instantiate () { } @Test - public void newInstance () { + @DisplayName("create new instance from bytes") + void newInstance () { val value = "hello"; val bytes = Bytes.allocate() .put1B(SMALL_ATOM_UTF8.getCode()) @@ -87,7 +91,8 @@ public void newInstance () { } @Test - public void toBytes () { + @DisplayName("convert instance to byte array") + void toBytes () { val value = "hello"; val expected = Bytes.allocate() .put1B(SMALL_ATOM_UTF8.getCode()) @@ -100,7 +105,8 @@ public void toBytes () { } @Test - public void encode () { + @DisplayName("encode instance to byte array and compare with jinterface output") + void encode () { val smallValue = "popa"; val smallAtom = new ErlangAtom(smallValue); @@ -132,7 +138,8 @@ public void encode () { } @Test - public void decode () throws Exception { + @DisplayName("decode instance from byte array and compare with jinterface result") + void decode () throws Exception { val value1 = "hello"; val bytes1 = Bytes.allocate() .put1B(SMALL_ATOM_UTF8.getCode()) diff --git a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangBinaryTest.java b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangBinaryTest.java index e8c8346..5696b8f 100644 --- a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangBinaryTest.java +++ b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangBinaryTest.java @@ -20,11 +20,9 @@ import static io.netty.buffer.Unpooled.wrappedBuffer; import static org.assertj.core.api.Assertions.assertThat; - import io.appulse.encon.terms.Erlang; import io.appulse.encon.terms.ErlangTerm; import io.appulse.utils.Bytes; -import io.appulse.utils.test.TestMethodNamePrinter; import erlang.OtpErlangBinary; import erlang.OtpInputStream; @@ -32,22 +30,27 @@ import lombok.SneakyThrows; import lombok.val; import org.assertj.core.api.SoftAssertions; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 1.0.0 */ -public class ErlangBinaryTest { +@DisplayName("Check Erlang's Binary term type") +class ErlangBinaryTest { - @Rule - public TestRule watcher = new TestMethodNamePrinter(); + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void instantiate () { + @DisplayName("create new instance by constructor") + void instantiate () { val value = new byte[] { 1, 2, 3 }; assertThat(new ErlangBinary(value).asBinary()) @@ -55,7 +58,8 @@ public void instantiate () { } @Test - public void newInstance () { + @DisplayName("create new instance from bytes") + void newInstance () { val value = new byte[] { 1, 2, 3 }; val bytes = Bytes.allocate() @@ -77,7 +81,8 @@ public void newInstance () { } @Test - public void toBytes () { + @DisplayName("convert instance to byte array") + void toBytes () { val value = new byte[] { 1, 2, 3 }; val expected = Bytes.allocate() @@ -91,14 +96,16 @@ public void toBytes () { } @Test - public void encode () { + @DisplayName("encode instance to byte array and compare with jinterface output") + void encode () { val binary = new byte[] { 1, 2, 3, 4, 5 }; assertThat(Erlang.binary(binary).toBytes()) .isEqualTo(bytes(binary)); } @Test - public void decode () throws Exception { + @DisplayName("decode instance from byte array and compare with jinterface result") + void decode () throws Exception { val value = new byte[] { 1, 2, 3 }; val bytes = Bytes.allocate() diff --git a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangBitStringTest.java b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangBitStringTest.java index 2b654cf..3378166 100644 --- a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangBitStringTest.java +++ b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangBitStringTest.java @@ -21,12 +21,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; - import io.appulse.encon.terms.Erlang; import io.appulse.encon.terms.exception.ErlangTermValidationException; import io.appulse.encon.terms.ErlangTerm; import io.appulse.utils.Bytes; -import io.appulse.utils.test.TestMethodNamePrinter; import erlang.OtpErlangBitstr; import erlang.OtpInputStream; @@ -34,22 +32,27 @@ import lombok.SneakyThrows; import lombok.val; import org.assertj.core.api.SoftAssertions; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 1.0.0 */ -public class ErlangBitStringTest { +@DisplayName("Check Erlang's BitString term type") +class ErlangBitStringTest { - @Rule - public TestRule watcher = new TestMethodNamePrinter(); + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void erlangTermValidationException () { + @DisplayName("checks throwing exceptions in constructor") + void erlangTermValidationException () { assertThatThrownBy(() -> new ErlangBitString(new byte[] { 1 }, -1)) .isInstanceOf(ErlangTermValidationException.class) .hasMessage("Padding must be in range 0..7"); @@ -60,7 +63,8 @@ public void erlangTermValidationException () { } @Test - public void newInstance () { + @DisplayName("create new instance from bytes") + void newInstance () { val value = new byte[] { 1, 2, 3 }; val pad = 3; @@ -84,7 +88,8 @@ public void newInstance () { } @Test - public void toBytes () { + @DisplayName("convert instance to byte array") + void toBytes () { val bits = new byte[] { 1, 2, 3 }; val pad = 3; @@ -100,7 +105,8 @@ public void toBytes () { } @Test - public void encode () { + @DisplayName("encode instance to byte array and compare with jinterface output") + void encode () { val binary = new byte[] { 1, 2, 3 }; assertThat(Erlang.bitstr(binary, 1).toBytes()) @@ -114,7 +120,8 @@ public void encode () { } @Test - public void decode () throws Exception { + @DisplayName("decode instance from byte array and compare with jinterface result") + void decode () throws Exception { val bits = new byte[] { 1, 2, 3 }; val pad = 3; diff --git a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangFloatTest.java b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangFloatTest.java index 3053c49..d69eac2 100644 --- a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangFloatTest.java +++ b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangFloatTest.java @@ -26,28 +26,34 @@ import erlang.OtpErlangFloat; import erlang.OtpInputStream; import erlang.OtpOutputStream; + import io.appulse.encon.terms.Erlang; import io.appulse.encon.terms.ErlangTerm; import io.appulse.utils.Bytes; -import io.appulse.utils.test.TestMethodNamePrinter; + import lombok.SneakyThrows; import lombok.val; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 1.0.0 */ -public class ErlangFloatTest { +@DisplayName("Check Erlang's Float term type") +class ErlangFloatTest { - @Rule - public TestRule watcher = new TestMethodNamePrinter(); + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void encode () { + @DisplayName("encode instance to byte array and compare with jinterface output") + void encode () { assertThat(Erlang.number(Float.MIN_NORMAL).toBytes()) .isEqualTo(bytes(Float.MIN_NORMAL)); @@ -68,7 +74,8 @@ public void encode () { } @Test - public void decode () throws Exception { + @DisplayName("decode instance from byte array and compare with jinterface result") + void decode () throws Exception { val bytes1 = Bytes.allocate() .put1B(FLOAT.getCode()) .put(String.format("%031.20e", Float.MAX_VALUE).getBytes(ISO_8859_1)) diff --git a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangIntegerTest.java b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangIntegerTest.java index 6cd6899..2f79da9 100644 --- a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangIntegerTest.java +++ b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangIntegerTest.java @@ -27,32 +27,35 @@ import java.util.Arrays; import java.util.stream.IntStream; - import io.appulse.encon.terms.ErlangTerm; import io.appulse.utils.Bytes; -import io.appulse.utils.test.TestMethodNamePrinter; import erlang.OtpErlangLong; import erlang.OtpInputStream; import erlang.OtpOutputStream; import lombok.SneakyThrows; import lombok.val; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 1.0.0 */ -public class ErlangIntegerTest { +@DisplayName("Check Erlang's Integer term type") +class ErlangIntegerTest { - @Rule - public TestRule watcher = new TestMethodNamePrinter(); + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void instantiate () { + @DisplayName("create new instance by constructor") + void instantiate () { assertThat(new ErlangInteger(254).getType()) .isEqualTo(SMALL_INTEGER); @@ -73,7 +76,8 @@ public void instantiate () { } @Test - public void encode () { + @DisplayName("encode instance to byte array and compare with jinterface output") + void encode () { assertThat(new ErlangInteger(Character.MIN_VALUE).toBytes()) .isEqualTo(bytes(Character.MIN_VALUE)); @@ -119,7 +123,8 @@ public void encode () { } @Test - public void decode () throws Exception { + @DisplayName("decode instance from byte array and compare with jinterface result") + void decode () throws Exception { val bytes1 = Bytes.allocate() .put1B(SMALL_INTEGER.getCode()) .put1B(255) @@ -168,7 +173,8 @@ public void decode () throws Exception { } @Test - public void cached () { + @DisplayName("checks caching values") + void cached () { ErlangInteger num1 = ErlangInteger.cached(1273); ErlangInteger num2 = ErlangInteger.cached(117); assertThat(num1).isNotEqualTo(num2); diff --git a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangListTest.java b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangListTest.java index 356ffd8..875886a 100644 --- a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangListTest.java +++ b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangListTest.java @@ -22,10 +22,8 @@ import java.util.stream.Stream; - import io.appulse.encon.terms.ErlangTerm; import io.appulse.utils.Bytes; -import io.appulse.utils.test.TestMethodNamePrinter; import erlang.OtpErlangAtom; import erlang.OtpErlangList; @@ -33,22 +31,27 @@ import lombok.SneakyThrows; import lombok.val; import org.assertj.core.api.SoftAssertions; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 1.0.0 */ -public class ErlangListTest { +@DisplayName("Check Erlang's List term type") +class ErlangListTest { - @Rule - public TestRule watcher = new TestMethodNamePrinter(); + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void newInstance () { + @DisplayName("create new instance from bytes") + void newInstance () { val value = new ErlangNil(); val bytes = Bytes.allocate() .put1B(LIST.getCode()) @@ -80,7 +83,8 @@ public void newInstance () { } @Test - public void toBytes () { + @DisplayName("convert instance to byte array") + void toBytes () { val value = new ErlangNil(); val expected = Bytes.allocate() .put1B(LIST.getCode()) @@ -94,7 +98,8 @@ public void toBytes () { } @Test - public void encode () { + @DisplayName("encode instance to byte array and compare with jinterface output") + void encode () { String[] values = new String[] { "one", "two", diff --git a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangMapTest.java b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangMapTest.java index 4124052..044deea 100644 --- a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangMapTest.java +++ b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangMapTest.java @@ -22,31 +22,34 @@ import java.util.LinkedHashMap; import java.util.List; - import io.appulse.encon.terms.ErlangTerm; -import io.appulse.utils.test.TestMethodNamePrinter; import erlang.OtpErlangMap; import erlang.OtpErlangObject; import erlang.OtpErlangString; import erlang.OtpOutputStream; import lombok.SneakyThrows; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 1.0.0 */ -public class ErlangMapTest { +@DisplayName("Check Erlang's Map term type") +class ErlangMapTest { - @Rule - public TestRule watcher = new TestMethodNamePrinter(); + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void encode () { + @DisplayName("encode instance to byte array and compare with jinterface output") + void encode () { LinkedHashMap value = new LinkedHashMap<>(3); value.put("one", "1"); value.put("two", "2"); diff --git a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangNilTest.java b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangNilTest.java index 4aafb86..07109c9 100644 --- a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangNilTest.java +++ b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangNilTest.java @@ -22,27 +22,31 @@ import io.appulse.encon.terms.ErlangTerm; import io.appulse.utils.Bytes; -import io.appulse.utils.test.TestMethodNamePrinter; import erlang.OtpOutputStream; import lombok.SneakyThrows; import lombok.val; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 1.0.0 */ -public class ErlangNilTest { +@DisplayName("Check Erlang's NIL term type") +class ErlangNilTest { - @Rule - public TestRule watcher = new TestMethodNamePrinter(); + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void newInstance () { + @DisplayName("create new instance from bytes") + void newInstance () { val bytes = Bytes.allocate() .put1B(NIL.getCode()) .array(); @@ -54,7 +58,8 @@ public void newInstance () { } @Test - public void toBytes () { + @DisplayName("convert instance to byte array") + void toBytes () { val expected = Bytes.allocate() .put1B(NIL.getCode()) .array(); @@ -64,7 +69,8 @@ public void toBytes () { } @Test - public void encode () { + @DisplayName("encode instance to byte array and compare with jinterface output") + void encode () { assertThat(new ErlangNil().toBytes()) .isEqualTo(bytes()); } diff --git a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangPidTest.java b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangPidTest.java index 8951b8a..b382643 100644 --- a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangPidTest.java +++ b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangPidTest.java @@ -24,28 +24,34 @@ import erlang.OtpErlangPid; import erlang.OtpInputStream; import erlang.OtpOutputStream; + import io.appulse.encon.terms.ErlangTerm; import io.appulse.utils.Bytes; -import io.appulse.utils.test.TestMethodNamePrinter; + import lombok.SneakyThrows; import lombok.val; import org.assertj.core.api.SoftAssertions; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 1.0.0 */ -public class ErlangPidTest { +@DisplayName("Check Erlang's Pid term type") +class ErlangPidTest { - @Rule - public TestRule watcher = new TestMethodNamePrinter(); + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void newInstance () { + @DisplayName("create new instance from bytes") + void newInstance () { val node = "popa"; val id = 500; val serial = 10; @@ -78,7 +84,8 @@ public void newInstance () { } @Test - public void toBytes () { + @DisplayName("convert instance to byte array") + void toBytes () { val node = "popa"; val id = 500; val serial = 10; @@ -104,7 +111,8 @@ public void toBytes () { } @Test - public void encode () { + @DisplayName("encode instance to byte array and compare with jinterface output") + void encode () { assertThat(ErlangPid.builder() .node("popa@localhost") .id(1) @@ -128,7 +136,8 @@ public void encode () { } @Test - public void decode () throws Exception { + @DisplayName("decode instance from byte array and compare with jinterface result") + void decode () throws Exception { byte[] bytes1 = Bytes.allocate() .put1B(PID.getCode()) .put(new ErlangAtom("popa@localhost").toBytes()) diff --git a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangPortTest.java b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangPortTest.java index 0265952..c6f4c3b 100644 --- a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangPortTest.java +++ b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangPortTest.java @@ -23,7 +23,6 @@ import io.appulse.encon.terms.ErlangTerm; import io.appulse.utils.Bytes; -import io.appulse.utils.test.TestMethodNamePrinter; import erlang.OtpErlangPort; import erlang.OtpInputStream; @@ -31,22 +30,27 @@ import lombok.SneakyThrows; import lombok.val; import org.assertj.core.api.SoftAssertions; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 1.0.0 */ -public class ErlangPortTest { +@DisplayName("Check Erlang's Port term type") +class ErlangPortTest { - @Rule - public TestRule watcher = new TestMethodNamePrinter(); + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void newInstance () { + @DisplayName("create new instance from bytes") + void newInstance () { val node = "popa@localhost"; val id = 500; val creation = 42; @@ -74,7 +78,8 @@ public void newInstance () { } @Test - public void toBytes () { + @DisplayName("convert instance to byte array") + void toBytes () { val node = "popa@localhost"; val id = 500; val creation = 42; @@ -97,7 +102,8 @@ public void toBytes () { } @Test - public void encode () { + @DisplayName("encode instance to byte array and compare with jinterface output") + void encode () { assertThat(ErlangPort.builder() .node("popa@localhost") .id(1) @@ -119,7 +125,8 @@ public void encode () { } @Test - public void decode () throws Exception { + @DisplayName("decode instance from byte array and compare with jinterface result") + void decode () throws Exception { byte[] bytes1 = Bytes.allocate() .put1B(PORT.getCode()) .put(new ErlangAtom("popa@localhost").toBytes()) diff --git a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangReferenceTest.java b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangReferenceTest.java index 92ef439..cdcdc19 100644 --- a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangReferenceTest.java +++ b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangReferenceTest.java @@ -26,7 +26,6 @@ import io.appulse.encon.terms.ErlangTerm; import io.appulse.utils.Bytes; -import io.appulse.utils.test.TestMethodNamePrinter; import erlang.OtpErlangRef; import erlang.OtpInputStream; @@ -35,9 +34,10 @@ import lombok.extern.slf4j.Slf4j; import lombok.val; import org.assertj.core.api.SoftAssertions; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * @@ -45,13 +45,17 @@ * @since 1.0.0 */ @Slf4j -public class ErlangReferenceTest { +@DisplayName("Check Erlang's Reference term type") +class ErlangReferenceTest { - @Rule - public TestRule watcher = new TestMethodNamePrinter(); + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void instantiate () { + @DisplayName("create new instance by constructor") + void instantiate () { assertThat(ErlangReference.builder() .node("popa") .id(3) @@ -63,7 +67,8 @@ public void instantiate () { } @Test - public void newInstance () { + @DisplayName("create new instance from bytes") + void newInstance () { val node = "popa@localhost"; val ids = new long[] { 1, 0, 0 }; val creation = 42; @@ -100,7 +105,8 @@ public void newInstance () { } @Test - public void toBytes () { + @DisplayName("convert instance to byte array") + void toBytes () { val node = "popa@localhost"; val ids = new long[] { 1, 0, 0 }; val creation = 42; @@ -129,7 +135,8 @@ public void toBytes () { } @Test - public void encode () { + @DisplayName("encode instance to byte array and compare with jinterface output") + void encode () { assertThat(ErlangReference.builder() .node("popa@localhost") .ids(new long[] { 1 }) @@ -168,7 +175,8 @@ public void encode () { } @Test - public void decode () throws Exception { + @DisplayName("decode instance from byte array and compare with jinterface result") + void decode () throws Exception { byte[] bytes1 = Bytes.allocate() .put1B(REFERENCE.getCode()) .put(new ErlangAtom("popa@localhost").toBytes()) diff --git a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangStringTest.java b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangStringTest.java index 9ae437e..fad4c72 100644 --- a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangStringTest.java +++ b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangStringTest.java @@ -25,29 +25,33 @@ import io.appulse.encon.terms.ErlangTerm; import io.appulse.utils.Bytes; -import io.appulse.utils.test.TestMethodNamePrinter; import erlang.OtpErlangString; import erlang.OtpInputStream; import erlang.OtpOutputStream; import lombok.SneakyThrows; import lombok.val; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 1.0.0 */ -public class ErlangStringTest { +@DisplayName("Check Erlang's String term type") +class ErlangStringTest { - @Rule - public TestRule watcher = new TestMethodNamePrinter(); + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void encode () { + @DisplayName("encode instance to byte array and compare with jinterface output") + void encode () { assertThat(new ErlangString("").toBytes()) .isEqualTo(bytes("")); @@ -64,7 +68,8 @@ public void encode () { } @Test - public void decode () throws Exception { + @DisplayName("decode instance from byte array and compare with jinterface result") + void decode () throws Exception { val bytes = Bytes.allocate() .put1B(STRING.getCode()) .put2B("popa".length()) diff --git a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangTupleTest.java b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangTupleTest.java index 091cf5f..2a9666e 100644 --- a/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangTupleTest.java +++ b/encon-terms/src/test/java/io/appulse/encon/terms/type/ErlangTupleTest.java @@ -29,7 +29,6 @@ import io.appulse.encon.terms.ErlangTerm; import io.appulse.utils.Bytes; -import io.appulse.utils.test.TestMethodNamePrinter; import erlang.OtpErlangAtom; import erlang.OtpErlangInt; @@ -42,22 +41,27 @@ import lombok.SneakyThrows; import lombok.val; import org.assertj.core.api.SoftAssertions; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 1.0.0 */ -public class ErlangTupleTest { +@DisplayName("Check Erlang's Tuple term type") +class ErlangTupleTest { - @Rule - public TestRule watcher = new TestMethodNamePrinter(); + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void instantiate () { + @DisplayName("create new instance by constructor") + void instantiate () { assertThat(new ErlangTuple(new ErlangNil()).getType()) .isEqualTo(SMALL_TUPLE); @@ -71,7 +75,8 @@ public void instantiate () { } @Test - public void newInstance () { + @DisplayName("create new instance from bytes") + void newInstance () { val value = new ErlangNil(); val bytes = Bytes.allocate() .put1B(SMALL_TUPLE.getCode()) @@ -99,7 +104,8 @@ public void newInstance () { } @Test - public void toBytes () { + @DisplayName("convert instance to byte array") + void toBytes () { val value = new ErlangNil(); val expected = Bytes.allocate() .put1B(SMALL_TUPLE.getCode()) @@ -112,7 +118,8 @@ public void toBytes () { } @Test - public void encode () { + @DisplayName("encode instance to byte array and compare with jinterface output") + void encode () { String[] values = new String[] { "one", "two", From e4f68e135fd226f0e3ce5c1928c24a3ec3b9e142 Mon Sep 17 00:00:00 2001 From: Artem Labazin Date: Mon, 10 Dec 2018 14:30:37 +0300 Subject: [PATCH 10/20] Update encon-config for java 11 --- .../config/ConfigurationProgrammatical.java | 3 ++ ...nfigMappingEnumValueNotFoundException.java | 2 + .../io/appulse/encon/config/DumpTest.java | 34 ++++++++++----- .../appulse/encon/config/GetBooleanTest.java | 16 +++++-- .../io/appulse/encon/config/GetByteTest.java | 16 +++++-- .../io/appulse/encon/config/GetCharTest.java | 16 +++++-- .../appulse/encon/config/GetDoubleTest.java | 16 +++++-- .../io/appulse/encon/config/GetFloatTest.java | 16 +++++-- .../appulse/encon/config/GetIntegerTest.java | 16 +++++-- .../io/appulse/encon/config/GetLongTest.java | 16 +++++-- .../appulse/encon/config/GetObjectTest.java | 16 +++++-- .../io/appulse/encon/config/GetPojoTest.java | 12 ++++-- .../io/appulse/encon/config/GetShortTest.java | 16 +++++-- .../appulse/encon/config/GetStringTest.java | 16 +++++-- .../io/appulse/encon/config/LoadTest.java | 43 +++++++++++++------ 15 files changed, 197 insertions(+), 57 deletions(-) diff --git a/encon-config/src/main/java/io/appulse/encon/config/ConfigurationProgrammatical.java b/encon-config/src/main/java/io/appulse/encon/config/ConfigurationProgrammatical.java index 93a92b2..8bd51f5 100644 --- a/encon-config/src/main/java/io/appulse/encon/config/ConfigurationProgrammatical.java +++ b/encon-config/src/main/java/io/appulse/encon/config/ConfigurationProgrammatical.java @@ -190,4 +190,7 @@ private ConfigurationProgrammatical (@Singular List configs) { ConfigTree getConfigTree () { return tree; } + + public static class ConfigurationProgrammaticalBuilder { + } } diff --git a/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigMappingEnumValueNotFoundException.java b/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigMappingEnumValueNotFoundException.java index 437eb06..fea06b9 100644 --- a/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigMappingEnumValueNotFoundException.java +++ b/encon-config/src/main/java/io/appulse/encon/config/exception/ConfigMappingEnumValueNotFoundException.java @@ -28,6 +28,8 @@ @EqualsAndHashCode(callSuper = true) public class ConfigMappingEnumValueNotFoundException extends ConfigMappingUnsupportedTypeException { + private static final long serialVersionUID = 4085006616020486199L; + String nodeAsString; public ConfigMappingEnumValueNotFoundException (Class type, String nodeAsString) { diff --git a/encon-config/src/test/java/io/appulse/encon/config/DumpTest.java b/encon-config/src/test/java/io/appulse/encon/config/DumpTest.java index d1e6c2f..58f5596 100644 --- a/encon-config/src/test/java/io/appulse/encon/config/DumpTest.java +++ b/encon-config/src/test/java/io/appulse/encon/config/DumpTest.java @@ -28,22 +28,26 @@ import lombok.SneakyThrows; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 2.0.0 */ -public class DumpTest { +@DisplayName("Dumping configuration tests") +class DumpTest { static Path FOLDER; - @BeforeClass + @BeforeAll @SneakyThrows - public static void beforeClass () { + static void beforeAll () { FOLDER = Paths.get("dump_test_folder"); if (Files.exists(FOLDER)) { @@ -55,9 +59,9 @@ public static void beforeClass () { Files.createDirectories(FOLDER); } - @AfterClass + @AfterAll @SneakyThrows - public static void afterClass () { + static void afterAll () { FOLDER = Paths.get("dump_test_folder"); if (Files.exists(FOLDER)) { @@ -69,8 +73,14 @@ public static void afterClass () { Files.deleteIfExists(FOLDER); } + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } + @Test - public void dumpFileName () { + @DisplayName("dump by file name") + void dumpFileName () { ResourceUtils.getResourceUrls("dump", "file.*").forEach(url -> { Config config1 = Config.load(url); @@ -87,7 +97,8 @@ public void dumpFileName () { } @Test - public void dumpFile () { + @DisplayName("dump by file object") + void dumpFile () { ResourceUtils.getResourceUrls("dump", "file.*").forEach(url -> { Config config1 = Config.load(url); @@ -104,7 +115,8 @@ public void dumpFile () { } @Test - public void dumpPath () { + @DisplayName("dump by file path") + void dumpPath () { ResourceUtils.getResourceUrls("dump", "file.*").forEach(url -> { Config config1 = Config.load(url); diff --git a/encon-config/src/test/java/io/appulse/encon/config/GetBooleanTest.java b/encon-config/src/test/java/io/appulse/encon/config/GetBooleanTest.java index 70470c2..33028d9 100644 --- a/encon-config/src/test/java/io/appulse/encon/config/GetBooleanTest.java +++ b/encon-config/src/test/java/io/appulse/encon/config/GetBooleanTest.java @@ -24,17 +24,27 @@ import io.appulse.utils.ResourceUtils; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 2.0.0 */ -public class GetBooleanTest { +@DisplayName("Extracting boolean options from config") +class GetBooleanTest { + + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void test () { + @DisplayName("checks boolean options") + void test () { URL url = ResourceUtils.getResourceUrls("", "boolean.yml").get(0); Config config = Config.load(url); diff --git a/encon-config/src/test/java/io/appulse/encon/config/GetByteTest.java b/encon-config/src/test/java/io/appulse/encon/config/GetByteTest.java index 91ff7b8..1fc7201 100644 --- a/encon-config/src/test/java/io/appulse/encon/config/GetByteTest.java +++ b/encon-config/src/test/java/io/appulse/encon/config/GetByteTest.java @@ -23,17 +23,27 @@ import io.appulse.utils.ResourceUtils; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 2.0.0 */ -public class GetByteTest { +@DisplayName("Extracting byte options from config") +class GetByteTest { + + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void test () { + @DisplayName("checks byte options") + void test () { URL url = ResourceUtils.getResourceUrls("", "byte.yml").get(0); Config config = Config.load(url); diff --git a/encon-config/src/test/java/io/appulse/encon/config/GetCharTest.java b/encon-config/src/test/java/io/appulse/encon/config/GetCharTest.java index 55eaab8..1234588 100644 --- a/encon-config/src/test/java/io/appulse/encon/config/GetCharTest.java +++ b/encon-config/src/test/java/io/appulse/encon/config/GetCharTest.java @@ -22,17 +22,27 @@ import io.appulse.utils.ResourceUtils; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 2.0.0 */ -public class GetCharTest { +@DisplayName("Extracting char options from config") +class GetCharTest { + + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void test () { + @DisplayName("checks char options") + void test () { URL url = ResourceUtils.getResourceUrls("", "char.yml").get(0); Config config = Config.load(url); diff --git a/encon-config/src/test/java/io/appulse/encon/config/GetDoubleTest.java b/encon-config/src/test/java/io/appulse/encon/config/GetDoubleTest.java index 89e1455..c025b98 100644 --- a/encon-config/src/test/java/io/appulse/encon/config/GetDoubleTest.java +++ b/encon-config/src/test/java/io/appulse/encon/config/GetDoubleTest.java @@ -23,17 +23,27 @@ import io.appulse.utils.ResourceUtils; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 2.0.0 */ -public class GetDoubleTest { +@DisplayName("Extracting double options from config") +class GetDoubleTest { + + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void test () { + @DisplayName("checks double options") + void test () { URL url = ResourceUtils.getResourceUrls("", "double.yml").get(0); Config config = Config.load(url); diff --git a/encon-config/src/test/java/io/appulse/encon/config/GetFloatTest.java b/encon-config/src/test/java/io/appulse/encon/config/GetFloatTest.java index ff96625..4c3ccfd 100644 --- a/encon-config/src/test/java/io/appulse/encon/config/GetFloatTest.java +++ b/encon-config/src/test/java/io/appulse/encon/config/GetFloatTest.java @@ -23,17 +23,27 @@ import io.appulse.utils.ResourceUtils; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 2.0.0 */ -public class GetFloatTest { +@DisplayName("Extracting float options from config") +class GetFloatTest { + + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void test () { + @DisplayName("checks float options") + void test () { URL url = ResourceUtils.getResourceUrls("", "float.yml").get(0); Config config = Config.load(url); diff --git a/encon-config/src/test/java/io/appulse/encon/config/GetIntegerTest.java b/encon-config/src/test/java/io/appulse/encon/config/GetIntegerTest.java index 468137c..960c9e6 100644 --- a/encon-config/src/test/java/io/appulse/encon/config/GetIntegerTest.java +++ b/encon-config/src/test/java/io/appulse/encon/config/GetIntegerTest.java @@ -23,17 +23,27 @@ import io.appulse.utils.ResourceUtils; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 2.0.0 */ -public class GetIntegerTest { +@DisplayName("Extracting integer options from config") +class GetIntegerTest { + + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void test () { + @DisplayName("checks integer options") + void test () { URL url = ResourceUtils.getResourceUrls("", "int.yml").get(0); Config config = Config.load(url); diff --git a/encon-config/src/test/java/io/appulse/encon/config/GetLongTest.java b/encon-config/src/test/java/io/appulse/encon/config/GetLongTest.java index 2c9df1a..498528a 100644 --- a/encon-config/src/test/java/io/appulse/encon/config/GetLongTest.java +++ b/encon-config/src/test/java/io/appulse/encon/config/GetLongTest.java @@ -23,17 +23,27 @@ import io.appulse.utils.ResourceUtils; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 2.0.0 */ -public class GetLongTest { +@DisplayName("Extracting long options from config") +class GetLongTest { + + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void test () { + @DisplayName("checks long options") + void test () { URL url = ResourceUtils.getResourceUrls("", "long.yml").get(0); Config config = Config.load(url); diff --git a/encon-config/src/test/java/io/appulse/encon/config/GetObjectTest.java b/encon-config/src/test/java/io/appulse/encon/config/GetObjectTest.java index 245fb2b..91d0a82 100644 --- a/encon-config/src/test/java/io/appulse/encon/config/GetObjectTest.java +++ b/encon-config/src/test/java/io/appulse/encon/config/GetObjectTest.java @@ -24,17 +24,27 @@ import io.appulse.utils.ResourceUtils; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 2.0.0 */ -public class GetObjectTest { +@DisplayName("Extracting object options from config") +class GetObjectTest { + + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void test () { + @DisplayName("checks object options") + void test () { URL url = ResourceUtils.getResourceUrls("", "object.yml").get(0); Config config = Config.load(url); diff --git a/encon-config/src/test/java/io/appulse/encon/config/GetPojoTest.java b/encon-config/src/test/java/io/appulse/encon/config/GetPojoTest.java index fc357f0..92be49a 100644 --- a/encon-config/src/test/java/io/appulse/encon/config/GetPojoTest.java +++ b/encon-config/src/test/java/io/appulse/encon/config/GetPojoTest.java @@ -37,7 +37,8 @@ import lombok.experimental.FieldDefaults; import lombok.extern.slf4j.Slf4j; -import org.junit.Test; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; /** * @@ -45,7 +46,8 @@ * @since 2.0.0 */ @Slf4j -public class GetPojoTest { +@DisplayName("Casting configuration tests") +class GetPojoTest { static NodesConfig.NodeConfig.MailboxConfig NODE_1_MAILBOX = NodesConfig.NodeConfig.MailboxConfig.builder() .name("popa") @@ -97,7 +99,8 @@ public class GetPojoTest { .build(); @Test - public void loadYamlTest () { + @DisplayName("load YAML configuration") + void loadYamlTest () { URL url = ResourceUtils.getResourceUrls("", "pojo.yml").get(0); Config config = Config.load(url); @@ -105,7 +108,8 @@ public void loadYamlTest () { } @Test - public void programmaticalTest () { + @DisplayName("create programmatical configuration") + void programmaticalTest () { Config config = Config.builder() .config(NODES_CONFIG) .config(HANDLER) diff --git a/encon-config/src/test/java/io/appulse/encon/config/GetShortTest.java b/encon-config/src/test/java/io/appulse/encon/config/GetShortTest.java index a61a6d6..2eeae0f 100644 --- a/encon-config/src/test/java/io/appulse/encon/config/GetShortTest.java +++ b/encon-config/src/test/java/io/appulse/encon/config/GetShortTest.java @@ -23,17 +23,27 @@ import io.appulse.utils.ResourceUtils; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 2.0.0 */ -public class GetShortTest { +@DisplayName("Extracting short options from config") +class GetShortTest { + + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void test () { + @DisplayName("checks short options") + void test () { URL url = ResourceUtils.getResourceUrls("", "short.yml").get(0); Config config = Config.load(url); diff --git a/encon-config/src/test/java/io/appulse/encon/config/GetStringTest.java b/encon-config/src/test/java/io/appulse/encon/config/GetStringTest.java index 1c4e309..7c60858 100644 --- a/encon-config/src/test/java/io/appulse/encon/config/GetStringTest.java +++ b/encon-config/src/test/java/io/appulse/encon/config/GetStringTest.java @@ -22,17 +22,27 @@ import io.appulse.utils.ResourceUtils; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 2.0.0 */ -public class GetStringTest { +@DisplayName("Extracting string options from config") +class GetStringTest { + + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void test () { + @DisplayName("checks string options") + void test () { URL url = ResourceUtils.getResourceUrls("", "string.yml").get(0); Config config = Config.load(url); diff --git a/encon-config/src/test/java/io/appulse/encon/config/LoadTest.java b/encon-config/src/test/java/io/appulse/encon/config/LoadTest.java index bc28dfb..1ea55ce 100644 --- a/encon-config/src/test/java/io/appulse/encon/config/LoadTest.java +++ b/encon-config/src/test/java/io/appulse/encon/config/LoadTest.java @@ -19,6 +19,7 @@ import static java.util.Arrays.asList; import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.io.File; import java.net.URI; @@ -34,22 +35,34 @@ import io.appulse.utils.ResourceUtils; import lombok.SneakyThrows; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 2.0.0 */ -public class LoadTest { +@DisplayName("Configuration loading tests") +class LoadTest { - @Test(expected = ConfigLoadingFileNotFoundException.class) - public void loadNonexistentFile () { - Config.load("nonexistent.yml"); + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); } @Test - public void loadMap () { + @DisplayName("try to load nonexistent configuration file") + void loadNonexistentFile () { + assertThatThrownBy(() -> Config.load("nonexistent.yml")) + .isInstanceOf(ConfigLoadingFileNotFoundException.class); + } + + @Test + @DisplayName("load configuration from map") + void loadMap () { Map subMap = new HashMap<>(); subMap.put("name", "popa"); subMap.put("my.age", 11); @@ -65,7 +78,8 @@ public void loadMap () { } // @Test - public void loadProperties () { +// @DisplayName("load configuration from properties") + void loadProperties () { Properties properties = new Properties(); properties.put("one.two.three.four", 4); properties.put("one.two.three.five.six", 6); @@ -81,7 +95,8 @@ public void loadProperties () { } @Test - public void loadUrl () { + @DisplayName("load configuration by URL") + void loadUrl () { getUrlFiles().forEach(url -> { Config config = Config.load(url); checkConfig(config, url.toString()); @@ -89,7 +104,8 @@ public void loadUrl () { } @Test - public void loadUri () { + @DisplayName("load configuration by URI") + void loadUri () { getUriFiles().forEach(uri -> { Config config = Config.load(uri); checkConfig(config, uri.toString()); @@ -97,7 +113,8 @@ public void loadUri () { } @Test - public void loadFile () { + @DisplayName("load configuration by File") + void loadFile () { getUriFiles().stream().map(File::new).forEach(file -> { Config config = Config.load(file); checkConfig(config, file.toString()); @@ -105,7 +122,8 @@ public void loadFile () { } @Test - public void loadPath () { + @DisplayName("load configuration by Path") + void loadPath () { getUriFiles().stream().map(Paths::get).forEach(path -> { Config config = Config.load(path); checkConfig(config, path.toString()); @@ -113,7 +131,8 @@ public void loadPath () { } @Test - public void loadFileName () { + @DisplayName("load configuration by file name") + void loadFileName () { getUriFiles().stream().map(Paths::get).map(Path::toString).forEach(fileName -> { Config config = Config.load(fileName); checkConfig(config, fileName); From 8bda40a22d924d231f5918a4bef1d0a74a431707 Mon Sep 17 00:00:00 2001 From: Artem Labazin Date: Mon, 10 Dec 2018 14:42:22 +0300 Subject: [PATCH 11/20] Update encon-databind for Java 11 --- .../encon/databind/parser/PojoDescriptor.java | 3 ++ .../TermMapperDifferentWrappersTest.java | 30 ++++++++++++++----- .../encon/databind/TermMapperTest.java | 16 ++++++++-- .../java/io/appulse/encon/terms/TermType.java | 4 +-- 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/encon-databind/src/main/java/io/appulse/encon/databind/parser/PojoDescriptor.java b/encon-databind/src/main/java/io/appulse/encon/databind/parser/PojoDescriptor.java index 7d957df..c219c3b 100644 --- a/encon-databind/src/main/java/io/appulse/encon/databind/parser/PojoDescriptor.java +++ b/encon-databind/src/main/java/io/appulse/encon/databind/parser/PojoDescriptor.java @@ -46,4 +46,7 @@ public final class PojoDescriptor { public String getName () { return type.getSimpleName(); } + + public static class PojoDescriptorBuilder { + } } diff --git a/encon-databind/src/test/java/io/appulse/encon/databind/TermMapperDifferentWrappersTest.java b/encon-databind/src/test/java/io/appulse/encon/databind/TermMapperDifferentWrappersTest.java index abf9903..3a2a48e 100644 --- a/encon-databind/src/test/java/io/appulse/encon/databind/TermMapperDifferentWrappersTest.java +++ b/encon-databind/src/test/java/io/appulse/encon/databind/TermMapperDifferentWrappersTest.java @@ -27,21 +27,33 @@ import io.appulse.encon.databind.annotation.AsErlangList; import io.appulse.encon.databind.annotation.AsErlangMap; import io.appulse.encon.databind.annotation.AsErlangTuple; + import java.io.Serializable; + import lombok.experimental.FieldDefaults; import lombok.val; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @since 1.1.0 * @author Artem Labazin */ +@DisplayName("Different term wrappers tests") @FieldDefaults(level = PRIVATE, makeFinal = true) -public class TermMapperDifferentWrappersTest { +class TermMapperDifferentWrappersTest { + + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void defaultWrapper () { + @DisplayName("default wrapper") + void defaultWrapper () { val erlangTerm = TermMapper.serialize(new DefaultWrapper()); assertThat(erlangTerm.getType()) .isEqualTo(SMALL_TUPLE); @@ -51,7 +63,8 @@ public void defaultWrapper () { } @Test - public void listWrapper () { + @DisplayName("list wrapper") + void listWrapper () { val erlangTerm = TermMapper.serialize(new ListWrapper()); assertThat(erlangTerm.getType()) .isEqualTo(LIST); @@ -61,7 +74,8 @@ public void listWrapper () { } @Test - public void tupleWrapper () { + @DisplayName("tuple wrapper") + void tupleWrapper () { val erlangTerm = TermMapper.serialize(new TupleWrapper()); assertThat(erlangTerm.getType()) .isEqualTo(SMALL_TUPLE); @@ -71,7 +85,8 @@ public void tupleWrapper () { } @Test - public void mapWrapper () { + @DisplayName("map wrapper") + void mapWrapper () { val erlangTerm = TermMapper.serialize(new MapWrapper()); assertThat(erlangTerm.getType()) .isEqualTo(MAP); @@ -81,7 +96,8 @@ public void mapWrapper () { } @Test - public void binaryWrapper () { + @DisplayName("binary wrapper") + void binaryWrapper () { val erlangTerm = TermMapper.serialize(new BinaryWrapper()); assertThat(erlangTerm.getType()) .isEqualTo(BINARY); diff --git a/encon-databind/src/test/java/io/appulse/encon/databind/TermMapperTest.java b/encon-databind/src/test/java/io/appulse/encon/databind/TermMapperTest.java index 753b694..f32987c 100644 --- a/encon-databind/src/test/java/io/appulse/encon/databind/TermMapperTest.java +++ b/encon-databind/src/test/java/io/appulse/encon/databind/TermMapperTest.java @@ -38,18 +38,28 @@ import lombok.NoArgsConstructor; import lombok.experimental.FieldDefaults; import lombok.val; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @since 1.6.0 * @author Artem Labazin */ +@DisplayName("Term mapping test to POJO") @FieldDefaults(level = PRIVATE, makeFinal = true) -public class TermMapperTest { +class TermMapperTest { + + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void simple () { + @DisplayName("simple POJO mapping") + void simple () { val pojo = new Pojo( "Artem", 27, diff --git a/encon-terms/src/main/java/io/appulse/encon/terms/TermType.java b/encon-terms/src/main/java/io/appulse/encon/terms/TermType.java index 85b4c73..6aa25f0 100644 --- a/encon-terms/src/main/java/io/appulse/encon/terms/TermType.java +++ b/encon-terms/src/main/java/io/appulse/encon/terms/TermType.java @@ -487,7 +487,7 @@ public enum TermType { * *

* Encodes a map. The Arity field is an unsigned 4 byte integer in big-endian format that determines the - * number of key-value pairs in the map. Key and value pairs (Ki => Vi) are encoded in section Pairs in the + * number of key-value pairs in the map. Key and value pairs (Ki => Vi) are encoded in section Pairs in the * following order: K1, V1, K2, V2,..., Kn, Vn. *

* Duplicate keys are not allowed within the same map. @@ -661,7 +661,7 @@ public enum TermType { FUNCTION(117, ErlangFunction.class), /** - * This is the new encoding of internal funs: fun F/A and fun(Arg1,..) -> ... end. + * This is the new encoding of internal funs: fun F/A and fun(Arg1,..) -> ... end. *

* Structure: *

From 524147070c5a3beb9b40006382189032bc58603b Mon Sep 17 00:00:00 2001 From: Artem Labazin Date: Mon, 10 Dec 2018 15:31:56 +0300 Subject: [PATCH 12/20] Update base encon project for Java 11 --- .../encon/ModuleRemoteProcedureCall.java | 2 +- .../java/io/appulse/encon/NodesConfig.java | 3 + .../connection/handshake/message/Message.java | 5 +- .../io/appulse/encon/GeneratorPidTest.java | 21 +++--- .../io/appulse/encon/GeneratorPortTest.java | 21 +++--- .../appulse/encon/GeneratorReferenceTest.java | 20 +++--- .../test/java/io/appulse/encon/NodeTest.java | 69 +++++++++++-------- .../test/java/io/appulse/encon/NodesTest.java | 36 +++++----- .../connection/ConnectionModuleTest.java | 16 ++++- 9 files changed, 117 insertions(+), 76 deletions(-) diff --git a/encon/src/main/java/io/appulse/encon/ModuleRemoteProcedureCall.java b/encon/src/main/java/io/appulse/encon/ModuleRemoteProcedureCall.java index 74b6e30..302b0bd 100644 --- a/encon/src/main/java/io/appulse/encon/ModuleRemoteProcedureCall.java +++ b/encon/src/main/java/io/appulse/encon/ModuleRemoteProcedureCall.java @@ -373,7 +373,7 @@ public ErlangTerm getSync () { * * @return the second element of the tuple if the received message is a * two-tuple, otherwise null. No further error checking is - * performed. It also could return {@ null} if the specified + * performed. It also could return {@code null} if the specified * waiting time elapses before an element is available */ public ErlangTerm getSync (long timeout, TimeUnit unit) { diff --git a/encon/src/main/java/io/appulse/encon/NodesConfig.java b/encon/src/main/java/io/appulse/encon/NodesConfig.java index 3b7d202..83f3db7 100644 --- a/encon/src/main/java/io/appulse/encon/NodesConfig.java +++ b/encon/src/main/java/io/appulse/encon/NodesConfig.java @@ -281,4 +281,7 @@ public CompressionConfig (@NonNull CompressionConfig other) { } } } + + public static class NodeConfigBuilder { + } } diff --git a/encon/src/main/java/io/appulse/encon/connection/handshake/message/Message.java b/encon/src/main/java/io/appulse/encon/connection/handshake/message/Message.java index fd6c9b1..018eff4 100644 --- a/encon/src/main/java/io/appulse/encon/connection/handshake/message/Message.java +++ b/encon/src/main/java/io/appulse/encon/connection/handshake/message/Message.java @@ -18,6 +18,8 @@ import static lombok.AccessLevel.PRIVATE; +import java.lang.reflect.Constructor; + import io.netty.buffer.ByteBuf; import lombok.Getter; import lombok.NonNull; @@ -38,7 +40,8 @@ public static T parse (@NonNull ByteBuf buffer, @NonNull Cla if (!MessageType.check(buffer.readByte(), type)) { throw new IllegalArgumentException(); } - T result = type.newInstance(); + Constructor constructor = type.getConstructor(); + T result = constructor.newInstance(); result.read(buffer); return result; } diff --git a/encon/src/test/java/io/appulse/encon/GeneratorPidTest.java b/encon/src/test/java/io/appulse/encon/GeneratorPidTest.java index c4fa9bd..040dd67 100644 --- a/encon/src/test/java/io/appulse/encon/GeneratorPidTest.java +++ b/encon/src/test/java/io/appulse/encon/GeneratorPidTest.java @@ -19,26 +19,31 @@ import static org.assertj.core.api.Assertions.assertThat; import io.appulse.encon.common.NodeDescriptor; -import io.appulse.utils.test.TestMethodNamePrinter; + import lombok.val; import org.assertj.core.api.SoftAssertions; -import org.junit.Rule; -import org.junit.rules.TestRule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 1.0.0 */ -public class GeneratorPidTest { +@DisplayName("Pid generator tests") +class GeneratorPidTest { - @Rule - public TestRule watcher = new TestMethodNamePrinter(); + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void generate () { + @DisplayName("generate") + void generate () { val descriptor = NodeDescriptor.from("popa"); val creation = 1; diff --git a/encon/src/test/java/io/appulse/encon/GeneratorPortTest.java b/encon/src/test/java/io/appulse/encon/GeneratorPortTest.java index 65617fe..3c01f81 100644 --- a/encon/src/test/java/io/appulse/encon/GeneratorPortTest.java +++ b/encon/src/test/java/io/appulse/encon/GeneratorPortTest.java @@ -19,26 +19,31 @@ import static org.assertj.core.api.Assertions.assertThat; import io.appulse.encon.common.NodeDescriptor; -import io.appulse.utils.test.TestMethodNamePrinter; + import lombok.val; import org.assertj.core.api.SoftAssertions; -import org.junit.Rule; -import org.junit.rules.TestRule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 1.0.0 */ -public class GeneratorPortTest { +@DisplayName("Port generator tests") +class GeneratorPortTest { - @Rule - public TestRule watcher = new TestMethodNamePrinter(); + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void generate () { + @DisplayName("generate") + void generate () { val descriptor = NodeDescriptor.from("popa"); val creation = 1; diff --git a/encon/src/test/java/io/appulse/encon/GeneratorReferenceTest.java b/encon/src/test/java/io/appulse/encon/GeneratorReferenceTest.java index bedb085..ae43d90 100644 --- a/encon/src/test/java/io/appulse/encon/GeneratorReferenceTest.java +++ b/encon/src/test/java/io/appulse/encon/GeneratorReferenceTest.java @@ -19,26 +19,30 @@ import static org.assertj.core.api.Assertions.assertThat; import io.appulse.encon.common.NodeDescriptor; -import io.appulse.utils.test.TestMethodNamePrinter; import lombok.val; import org.assertj.core.api.SoftAssertions; -import org.junit.Rule; -import org.junit.rules.TestRule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 1.0.0 */ -public class GeneratorReferenceTest { +@DisplayName("Reference generator tests") +class GeneratorReferenceTest { - @Rule - public TestRule watcher = new TestMethodNamePrinter(); + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void generateReference () { + @DisplayName("generate") + void generateReference () { val descriptor = NodeDescriptor.from("popa"); val creation = 1; diff --git a/encon/src/test/java/io/appulse/encon/NodeTest.java b/encon/src/test/java/io/appulse/encon/NodeTest.java index 2c31a9c..ed866c1 100644 --- a/encon/src/test/java/io/appulse/encon/NodeTest.java +++ b/encon/src/test/java/io/appulse/encon/NodeTest.java @@ -31,8 +31,8 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.ThreadLocalRandom; -import io.appulse.encon.connection.regular.Message; import io.appulse.encon.ModuleRemoteProcedureCall.RpcResponse; import io.appulse.encon.NodesConfig.NodeConfig; import io.appulse.encon.NodesConfig.NodeConfig.ServerConfig; @@ -40,23 +40,21 @@ import io.appulse.encon.mailbox.exception.ReceivedExitException; import io.appulse.encon.terms.ErlangTerm; import io.appulse.encon.terms.type.ErlangAtom; -import io.appulse.utils.test.TestMethodNamePrinter; import io.appulse.epmd.java.server.cli.CommonOptions; import io.appulse.epmd.java.server.command.server.ServerCommandExecutor; import io.appulse.epmd.java.server.command.server.ServerCommandOptions; import io.appulse.utils.SocketUtils; -import java.util.concurrent.ThreadLocalRandom; - import lombok.val; import lombok.extern.slf4j.Slf4j; import org.assertj.core.api.SoftAssertions; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.After; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * @@ -64,7 +62,8 @@ * @since 1.0.0 */ @Slf4j -public class NodeTest { +@DisplayName("Node tests") +class NodeTest { private static final String ELIXIR_ECHO_SERVER = "echo@localhost"; @@ -72,14 +71,10 @@ public class NodeTest { private static ServerCommandExecutor epmdServer; - @Rule - public TestRule watcher = new TestMethodNamePrinter(); - - Node node; - @BeforeClass - public static void beforeClass () { + @BeforeAll + static void beforeAll () { if (SocketUtils.isPortAvailable(4369)) { executor = Executors.newSingleThreadExecutor(); epmdServer = new ServerCommandExecutor(new CommonOptions(), new ServerCommandOptions()); @@ -87,8 +82,8 @@ public static void beforeClass () { } } - @AfterClass - public static void afterClass () { + @AfterAll + static void afterAll () { ofNullable(epmdServer) .ifPresent(ServerCommandExecutor::close); @@ -96,8 +91,13 @@ public static void afterClass () { .ifPresent(ExecutorService::shutdown); } - @After - public void after () throws Exception { + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } + + @AfterEach + void afterEach () throws Exception { if (node != null) { node.close(); node = null; @@ -106,7 +106,8 @@ public void after () throws Exception { } @Test - public void register () { + @DisplayName("node registration") + void register () { val name = createName(); node = Nodes.singleNode(name, true); @@ -135,7 +136,8 @@ public void register () { } @Test - public void ping () throws Exception { + @DisplayName("sending ping message") + void ping () throws Exception { val name1 = createName(); val name2 = createName(); node = Nodes.singleNode(name1, NodeConfig.builder() @@ -173,7 +175,8 @@ public void ping () throws Exception { } @Test - public void instantiating () throws Exception { + @DisplayName("simple instantiating") + void instantiating () throws Exception { val name = createName(); node = Nodes.singleNode(name, NodeConfig.builder() .shortName(true) @@ -183,7 +186,8 @@ public void instantiating () throws Exception { } @Test - public void sendFromOneToAnotherNode () throws Exception { + @DisplayName("send message from one node to another") + void sendFromOneToAnotherNode () throws Exception { val name1 = createName(); val name2 = createName(); @@ -215,7 +219,8 @@ public void sendFromOneToAnotherNode () throws Exception { } @Test - public void sendWithRedirect () throws Exception { + @DisplayName("send message from A node, through Elixir echo, to B node") + void sendWithRedirect () throws Exception { val config = NodeConfig.builder() .shortName(true) .cookie("secret") @@ -274,7 +279,8 @@ public void sendWithRedirect () throws Exception { } @Test - public void send () throws Exception { + @DisplayName("send message to Elixir echo server and catch back") + void send () throws Exception { val name = createName(); node = Nodes.singleNode(name, NodeConfig.builder() .shortName(true) @@ -316,7 +322,8 @@ public void send () throws Exception { } @Test - public void link () throws Exception { + @DisplayName("link two nodes") + void link () throws Exception { val name = createName(); node = Nodes.singleNode(name, true); @@ -344,7 +351,8 @@ public void link () throws Exception { } @Test - public void exit () throws Exception { + @DisplayName("send exit message from node A to node B") + void exit () throws Exception { val name = createName(); node = Nodes.singleNode(name, true); @@ -371,7 +379,8 @@ public void exit () throws Exception { } @Test - public void remoteProcedureCall () throws Exception { + @DisplayName("send RPC message to Elixir echo server") + void remoteProcedureCall () throws Exception { val name = createName(); node = Nodes.singleNode(name, NodeConfig.builder() .shortName(true) diff --git a/encon/src/test/java/io/appulse/encon/NodesTest.java b/encon/src/test/java/io/appulse/encon/NodesTest.java index 24c035c..1a4e8ba 100644 --- a/encon/src/test/java/io/appulse/encon/NodesTest.java +++ b/encon/src/test/java/io/appulse/encon/NodesTest.java @@ -27,33 +27,29 @@ import io.appulse.epmd.java.server.command.server.ServerCommandExecutor; import io.appulse.epmd.java.server.command.server.ServerCommandOptions; import io.appulse.utils.SocketUtils; -import io.appulse.utils.test.TestMethodNamePrinter; import io.appulse.encon.NodesConfig.NodeConfig; -import lombok.val; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 1.0.0 */ -public class NodesTest { +@DisplayName("Nodes cluster tests") +class NodesTest { private static ExecutorService executor; private static ServerCommandExecutor epmdServer; - @Rule - public TestRule watcher = new TestMethodNamePrinter(); - - @BeforeClass - public static void beforeClass () { + @BeforeAll + static void beforeClass () { if (SocketUtils.isPortAvailable(4369)) { executor = Executors.newSingleThreadExecutor(); epmdServer = new ServerCommandExecutor(new CommonOptions(), new ServerCommandOptions()); @@ -61,8 +57,8 @@ public static void beforeClass () { } } - @AfterClass - public static void afterClass () { + @AfterAll + static void afterClass () { ofNullable(epmdServer) .ifPresent(ServerCommandExecutor::close); @@ -70,8 +66,14 @@ public static void afterClass () { .ifPresent(ExecutorService::shutdown); } + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } + @Test - public void instantiating () { + @DisplayName("start several nodes from programmatically config") + void instantiating () { Config config = Config.builder() .config(NodesConfig.builder() .node("kojima1", NodeConfig.DEFAULT) diff --git a/encon/src/test/java/io/appulse/encon/connection/ConnectionModuleTest.java b/encon/src/test/java/io/appulse/encon/connection/ConnectionModuleTest.java index aaae7c9..0cf1389 100644 --- a/encon/src/test/java/io/appulse/encon/connection/ConnectionModuleTest.java +++ b/encon/src/test/java/io/appulse/encon/connection/ConnectionModuleTest.java @@ -20,17 +20,27 @@ import java.util.concurrent.CompletableFuture; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin * @since 1.0.0 */ -public class ConnectionModuleTest { +@DisplayName("Connection module tests") +class ConnectionModuleTest { + + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } @Test - public void futureTests () { + @DisplayName("future POC") + void futureTests () { CompletableFuture future = CompletableFuture.completedFuture("Hello world"); assertThat(future) .isCompleted() From 7b2f6042fc8e8b23a217737e2480a71eabd79eb7 Mon Sep 17 00:00:00 2001 From: Artem Labazin Date: Mon, 10 Dec 2018 15:34:39 +0300 Subject: [PATCH 13/20] Correct author JavaDoc --- .../encon/databind/deserializer/PojoDeserializerBinary.java | 2 +- .../databind/serializer/PojoSerializerAbstractCollection.java | 2 +- .../appulse/encon/databind/serializer/PojoSerializerBinary.java | 2 +- .../appulse/encon/handler/mailbox/AbstractMailboxHandler.java | 2 +- .../io/appulse/encon/handler/mailbox/DefaultMailboxHandler.java | 2 +- .../java/io/appulse/encon/handler/message/MessageHandler.java | 2 +- .../handler/message/exception/MethodInvocationException.java | 2 +- .../handler/message/matcher/BuilderProxyMethodInterceptor.java | 2 +- .../java/io/appulse/encon/handler/message/matcher/Matchers.java | 2 +- .../encon/handler/message/matcher/MethodArgumentMatcher.java | 2 +- .../handler/message/matcher/MethodArgumentsTransformer.java | 2 +- .../encon/handler/message/matcher/MethodArgumentsWrapper.java | 2 +- .../appulse/encon/handler/message/matcher/MethodDescriptor.java | 2 +- .../io/appulse/encon/handler/message/matcher/MethodInvoker.java | 2 +- .../io/appulse/encon/handler/message/matcher/MethodMatcher.java | 2 +- .../handler/message/matcher/MethodMatcherMessageHandler.java | 2 +- .../message/matcher/MethodMatcherMessageHandlerBuilder.java | 2 +- .../io/appulse/encon/handler/message/matcher/Primitives.java | 2 +- .../encon/handler/message/matcher/ThreadLocalStorage.java | 2 +- .../message/matcher/MethodMatcherMessageHandlerTest.java | 2 +- .../encon/spring/BeanPostProcessorErlangMailboxAnnotation.java | 2 +- .../encon/spring/BeanPostProcessorInjectMailboxAnnotation.java | 2 +- .../appulse/encon/spring/BeanPostProcessorMailboxHandler.java | 2 +- .../src/main/java/io/appulse/encon/spring/EnconProperties.java | 2 +- .../src/main/java/io/appulse/encon/spring/ErlangMailbox.java | 2 +- .../src/main/java/io/appulse/encon/spring/InjectMailbox.java | 2 +- .../main/java/io/appulse/encon/spring/MailboxOperations.java | 2 +- .../main/java/io/appulse/encon/spring/MatchingCaseMapping.java | 2 +- .../src/main/java/io/appulse/encon/spring/MessageWrapper.java | 2 +- .../io/appulse/encon/examples/echo/server/spring/MyPojo1.java | 2 +- 30 files changed, 30 insertions(+), 30 deletions(-) diff --git a/encon-databind/src/main/java/io/appulse/encon/databind/deserializer/PojoDeserializerBinary.java b/encon-databind/src/main/java/io/appulse/encon/databind/deserializer/PojoDeserializerBinary.java index f57fce8..0282d08 100644 --- a/encon-databind/src/main/java/io/appulse/encon/databind/deserializer/PojoDeserializerBinary.java +++ b/encon-databind/src/main/java/io/appulse/encon/databind/deserializer/PojoDeserializerBinary.java @@ -25,7 +25,7 @@ * Eralng's term binary deserializer to specified type. * * @since 1.1.0 - * @author alabazin + * @author Artem Labazin */ public class PojoDeserializerBinary implements Deserializer { diff --git a/encon-databind/src/main/java/io/appulse/encon/databind/serializer/PojoSerializerAbstractCollection.java b/encon-databind/src/main/java/io/appulse/encon/databind/serializer/PojoSerializerAbstractCollection.java index 286bf5a..9ce528c 100644 --- a/encon-databind/src/main/java/io/appulse/encon/databind/serializer/PojoSerializerAbstractCollection.java +++ b/encon-databind/src/main/java/io/appulse/encon/databind/serializer/PojoSerializerAbstractCollection.java @@ -26,7 +26,7 @@ * Abstract collection serializer. * * @since 1.1.0 - * @author alabazin + * @author Artem Labazin */ abstract class PojoSerializerAbstractCollection implements Serializer { diff --git a/encon-databind/src/main/java/io/appulse/encon/databind/serializer/PojoSerializerBinary.java b/encon-databind/src/main/java/io/appulse/encon/databind/serializer/PojoSerializerBinary.java index 2f380f6..089b3d7 100644 --- a/encon-databind/src/main/java/io/appulse/encon/databind/serializer/PojoSerializerBinary.java +++ b/encon-databind/src/main/java/io/appulse/encon/databind/serializer/PojoSerializerBinary.java @@ -30,7 +30,7 @@ * POJO's serializer into Erlang's binary. * * @since 1.1.0 - * @author alabazin + * @author Artem Labazin */ public class PojoSerializerBinary implements Serializer { diff --git a/encon-handler/src/main/java/io/appulse/encon/handler/mailbox/AbstractMailboxHandler.java b/encon-handler/src/main/java/io/appulse/encon/handler/mailbox/AbstractMailboxHandler.java index 96852bc..766eddd 100644 --- a/encon-handler/src/main/java/io/appulse/encon/handler/mailbox/AbstractMailboxHandler.java +++ b/encon-handler/src/main/java/io/appulse/encon/handler/mailbox/AbstractMailboxHandler.java @@ -39,7 +39,7 @@ * you only need to "tell" how to get a message from a queue. * * @since 1.4.0 - * @author alabazin + * @author Artem Labazin */ @Slf4j @RequiredArgsConstructor diff --git a/encon-handler/src/main/java/io/appulse/encon/handler/mailbox/DefaultMailboxHandler.java b/encon-handler/src/main/java/io/appulse/encon/handler/mailbox/DefaultMailboxHandler.java index 053a0d5..34a66ea 100644 --- a/encon-handler/src/main/java/io/appulse/encon/handler/mailbox/DefaultMailboxHandler.java +++ b/encon-handler/src/main/java/io/appulse/encon/handler/mailbox/DefaultMailboxHandler.java @@ -29,7 +29,7 @@ * Default {@link AbstractMailboxHandler} implementation. * * @since 1.5.0 - * @author alabazin + * @author Artem Labazin */ @FieldDefaults(level = PRIVATE, makeFinal = true) public class DefaultMailboxHandler extends AbstractMailboxHandler { diff --git a/encon-handler/src/main/java/io/appulse/encon/handler/message/MessageHandler.java b/encon-handler/src/main/java/io/appulse/encon/handler/message/MessageHandler.java index d157e6c..d2a600c 100644 --- a/encon-handler/src/main/java/io/appulse/encon/handler/message/MessageHandler.java +++ b/encon-handler/src/main/java/io/appulse/encon/handler/message/MessageHandler.java @@ -24,7 +24,7 @@ * Received messages handler interface. * * @since 1.4.0 - * @author alabazin + * @author Artem Labazin */ public interface MessageHandler { diff --git a/encon-handler/src/main/java/io/appulse/encon/handler/message/exception/MethodInvocationException.java b/encon-handler/src/main/java/io/appulse/encon/handler/message/exception/MethodInvocationException.java index fcda5cc..ec5cd70 100644 --- a/encon-handler/src/main/java/io/appulse/encon/handler/message/exception/MethodInvocationException.java +++ b/encon-handler/src/main/java/io/appulse/encon/handler/message/exception/MethodInvocationException.java @@ -30,7 +30,7 @@ /** * * @since 1.6.0 - * @author alabazin + * @author Artem Labazin */ @Getter @FieldDefaults(level = PRIVATE, makeFinal = true) diff --git a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/BuilderProxyMethodInterceptor.java b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/BuilderProxyMethodInterceptor.java index 5a0322d..2e77e19 100644 --- a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/BuilderProxyMethodInterceptor.java +++ b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/BuilderProxyMethodInterceptor.java @@ -35,7 +35,7 @@ /** * * @since 1.4.0 - * @author alabazin + * @author Artem Labazin */ @Slf4j @Builder diff --git a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/Matchers.java b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/Matchers.java index fa0178d..9b71ec6 100644 --- a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/Matchers.java +++ b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/Matchers.java @@ -41,7 +41,7 @@ * The set of pattern matching helpers. * * @since 1.4.0 - * @author alabazin + * @author Artem Labazin */ public final class Matchers { diff --git a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodArgumentMatcher.java b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodArgumentMatcher.java index 5f16029..be47a2e 100644 --- a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodArgumentMatcher.java +++ b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodArgumentMatcher.java @@ -34,7 +34,7 @@ * Method argument matcher. * * @since 1.4.0 - * @author alabazin + * @author Artem Labazin */ public interface MethodArgumentMatcher { diff --git a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodArgumentsTransformer.java b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodArgumentsTransformer.java index c301d14..69ba98f 100644 --- a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodArgumentsTransformer.java +++ b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodArgumentsTransformer.java @@ -33,7 +33,7 @@ /** * * @since 1.6.0 - * @author alabazin + * @author Artem Labazin */ @Slf4j @Getter diff --git a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodArgumentsWrapper.java b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodArgumentsWrapper.java index 9cc2a9f..13e8440 100644 --- a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodArgumentsWrapper.java +++ b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodArgumentsWrapper.java @@ -24,7 +24,7 @@ /** * * @since 1.4.0 - * @author alabazin + * @author Artem Labazin */ enum MethodArgumentsWrapper { diff --git a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodDescriptor.java b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodDescriptor.java index 3f5a849..7e2248d 100644 --- a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodDescriptor.java +++ b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodDescriptor.java @@ -38,7 +38,7 @@ /** * * @since 1.6.0 - * @author alabazin + * @author Artem Labazin */ @Slf4j @Getter diff --git a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodInvoker.java b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodInvoker.java index 55df095..842aa91 100644 --- a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodInvoker.java +++ b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodInvoker.java @@ -36,7 +36,7 @@ * Method invoker. * * @since 1.6.0 - * @author alabazin + * @author Artem Labazin */ @Slf4j @Getter diff --git a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodMatcher.java b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodMatcher.java index 5ee391c..b2f793e 100644 --- a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodMatcher.java +++ b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodMatcher.java @@ -34,7 +34,7 @@ /** * * @since 1.6.0 - * @author alabazin + * @author Artem Labazin */ @Slf4j @Getter diff --git a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodMatcherMessageHandler.java b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodMatcherMessageHandler.java index bb5397b..52f0cdb 100644 --- a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodMatcherMessageHandler.java +++ b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodMatcherMessageHandler.java @@ -40,7 +40,7 @@ * incoming messages handlers. * * @since 1.4.0 - * @author alabazin + * @author Artem Labazin */ @Slf4j @Getter diff --git a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodMatcherMessageHandlerBuilder.java b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodMatcherMessageHandlerBuilder.java index 5b02993..32664ee 100644 --- a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodMatcherMessageHandlerBuilder.java +++ b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodMatcherMessageHandlerBuilder.java @@ -42,7 +42,7 @@ * Builder of a new {@link MethodMatcherMessageHandler} instance. * * @since 1.4.0 - * @author alabazin + * @author Artem Labazin */ @NoArgsConstructor(access = PACKAGE) @FieldDefaults(level = PRIVATE, makeFinal = true) diff --git a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/Primitives.java b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/Primitives.java index c1a4da2..91123ff 100644 --- a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/Primitives.java +++ b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/Primitives.java @@ -22,7 +22,7 @@ /** * * @since 1.4.0 - * @author alabazin + * @author Artem Labazin */ final class Primitives { diff --git a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/ThreadLocalStorage.java b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/ThreadLocalStorage.java index 6759cfa..61bc028 100644 --- a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/ThreadLocalStorage.java +++ b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/ThreadLocalStorage.java @@ -22,7 +22,7 @@ /** * * @since 1.4.0 - * @author alabazin + * @author Artem Labazin */ final class ThreadLocalStorage { diff --git a/encon-handler/src/test/java/io/appulse/encon/handler/message/matcher/MethodMatcherMessageHandlerTest.java b/encon-handler/src/test/java/io/appulse/encon/handler/message/matcher/MethodMatcherMessageHandlerTest.java index 540faf1..3680224 100644 --- a/encon-handler/src/test/java/io/appulse/encon/handler/message/matcher/MethodMatcherMessageHandlerTest.java +++ b/encon-handler/src/test/java/io/appulse/encon/handler/message/matcher/MethodMatcherMessageHandlerTest.java @@ -42,7 +42,7 @@ /** * - * @author alabazin + * @author Artem Labazin */ public class MethodMatcherMessageHandlerTest { diff --git a/encon-spring/src/main/java/io/appulse/encon/spring/BeanPostProcessorErlangMailboxAnnotation.java b/encon-spring/src/main/java/io/appulse/encon/spring/BeanPostProcessorErlangMailboxAnnotation.java index 6c0880e..2ce5d6c 100644 --- a/encon-spring/src/main/java/io/appulse/encon/spring/BeanPostProcessorErlangMailboxAnnotation.java +++ b/encon-spring/src/main/java/io/appulse/encon/spring/BeanPostProcessorErlangMailboxAnnotation.java @@ -41,7 +41,7 @@ /** * * @since 1.6.0 - * @author alabazin + * @author Artem Labazin */ @RequiredArgsConstructor @FieldDefaults(level = PRIVATE, makeFinal = true) diff --git a/encon-spring/src/main/java/io/appulse/encon/spring/BeanPostProcessorInjectMailboxAnnotation.java b/encon-spring/src/main/java/io/appulse/encon/spring/BeanPostProcessorInjectMailboxAnnotation.java index 2e6cc4b..42ac9e2 100644 --- a/encon-spring/src/main/java/io/appulse/encon/spring/BeanPostProcessorInjectMailboxAnnotation.java +++ b/encon-spring/src/main/java/io/appulse/encon/spring/BeanPostProcessorInjectMailboxAnnotation.java @@ -43,7 +43,7 @@ /** * * @since 1.6.0 - * @author alabazin + * @author Artem Labazin */ @RequiredArgsConstructor @FieldDefaults(level = PRIVATE, makeFinal = true) diff --git a/encon-spring/src/main/java/io/appulse/encon/spring/BeanPostProcessorMailboxHandler.java b/encon-spring/src/main/java/io/appulse/encon/spring/BeanPostProcessorMailboxHandler.java index 6aafc5b..7936d10 100644 --- a/encon-spring/src/main/java/io/appulse/encon/spring/BeanPostProcessorMailboxHandler.java +++ b/encon-spring/src/main/java/io/appulse/encon/spring/BeanPostProcessorMailboxHandler.java @@ -45,7 +45,7 @@ /** * * @since 1.6.0 - * @author alabazin + * @author Artem Labazin */ @Slf4j @RequiredArgsConstructor diff --git a/encon-spring/src/main/java/io/appulse/encon/spring/EnconProperties.java b/encon-spring/src/main/java/io/appulse/encon/spring/EnconProperties.java index 2a9eaaf..9e80a1d 100644 --- a/encon-spring/src/main/java/io/appulse/encon/spring/EnconProperties.java +++ b/encon-spring/src/main/java/io/appulse/encon/spring/EnconProperties.java @@ -35,7 +35,7 @@ /** * * @since 1.6.0 - * @author alabazin + * @author Artem Labazin */ @Data @Component diff --git a/encon-spring/src/main/java/io/appulse/encon/spring/ErlangMailbox.java b/encon-spring/src/main/java/io/appulse/encon/spring/ErlangMailbox.java index 2128d5e..333ff74 100644 --- a/encon-spring/src/main/java/io/appulse/encon/spring/ErlangMailbox.java +++ b/encon-spring/src/main/java/io/appulse/encon/spring/ErlangMailbox.java @@ -30,7 +30,7 @@ /** * * @since 1.6.0 - * @author alabazin + * @author Artem Labazin */ @Component @Documented diff --git a/encon-spring/src/main/java/io/appulse/encon/spring/InjectMailbox.java b/encon-spring/src/main/java/io/appulse/encon/spring/InjectMailbox.java index 3cba90d..1ca3202 100644 --- a/encon-spring/src/main/java/io/appulse/encon/spring/InjectMailbox.java +++ b/encon-spring/src/main/java/io/appulse/encon/spring/InjectMailbox.java @@ -26,7 +26,7 @@ /** * * @since 1.6.0 - * @author alabazin + * @author Artem Labazin */ @Documented @Target(FIELD) diff --git a/encon-spring/src/main/java/io/appulse/encon/spring/MailboxOperations.java b/encon-spring/src/main/java/io/appulse/encon/spring/MailboxOperations.java index 7ef8201..9d92994 100644 --- a/encon-spring/src/main/java/io/appulse/encon/spring/MailboxOperations.java +++ b/encon-spring/src/main/java/io/appulse/encon/spring/MailboxOperations.java @@ -40,7 +40,7 @@ /** * * @since 1.6.0 - * @author alabazin + * @author Artem Labazin */ @Builder @RequiredArgsConstructor diff --git a/encon-spring/src/main/java/io/appulse/encon/spring/MatchingCaseMapping.java b/encon-spring/src/main/java/io/appulse/encon/spring/MatchingCaseMapping.java index 4d9a63a..827fbc3 100644 --- a/encon-spring/src/main/java/io/appulse/encon/spring/MatchingCaseMapping.java +++ b/encon-spring/src/main/java/io/appulse/encon/spring/MatchingCaseMapping.java @@ -26,7 +26,7 @@ /** * * @since 1.6.0 - * @author alabazin + * @author Artem Labazin */ @Documented @Target(METHOD) diff --git a/encon-spring/src/main/java/io/appulse/encon/spring/MessageWrapper.java b/encon-spring/src/main/java/io/appulse/encon/spring/MessageWrapper.java index df63562..f1b20e0 100644 --- a/encon-spring/src/main/java/io/appulse/encon/spring/MessageWrapper.java +++ b/encon-spring/src/main/java/io/appulse/encon/spring/MessageWrapper.java @@ -30,7 +30,7 @@ /** * * @since 1.6.0 - * @author alabazin + * @author Artem Labazin */ enum MessageWrapper { diff --git a/examples/echo-server-spring/src/main/java/io/appulse/encon/examples/echo/server/spring/MyPojo1.java b/examples/echo-server-spring/src/main/java/io/appulse/encon/examples/echo/server/spring/MyPojo1.java index ab43073..f0a7457 100644 --- a/examples/echo-server-spring/src/main/java/io/appulse/encon/examples/echo/server/spring/MyPojo1.java +++ b/examples/echo-server-spring/src/main/java/io/appulse/encon/examples/echo/server/spring/MyPojo1.java @@ -32,7 +32,7 @@ /** * * @since 1.6.0 - * @author alabazin + * @author Artem Labazin */ @Data @Builder From f75c466c5a3c9015563982bfa5e4c62acb668915 Mon Sep 17 00:00:00 2001 From: Artem Labazin Date: Mon, 10 Dec 2018 16:01:49 +0300 Subject: [PATCH 14/20] Update encon-handler for Java 11 --- .../handler/message/matcher/Matchers.java | 8 +++--- .../MethodMatcherMessageHandlerBuilder.java | 2 ++ .../MethodMatcherMessageHandlerTest.java | 27 +++++++++++-------- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/Matchers.java b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/Matchers.java index 9b71ec6..442ecf8 100644 --- a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/Matchers.java +++ b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/Matchers.java @@ -48,7 +48,7 @@ public final class Matchers { /** * Matches anything, including nulls and varargs. *

- * For primitive types use {@code #any*()} family or {@link #isA(Class)} or {@link #any(Class)}. + * For primitive types use {@code #any*()} family or {@link #is(Class)} or {@link #any(Class)}. * * @param the accepted type * @@ -82,7 +82,7 @@ public static T any (Class type) { * * @return {@code null} */ - public static T isA (Class type) { + public static T is (Class type) { reportMatcher(new InstanceOf(type)); return defaultValue(type); } @@ -356,7 +356,7 @@ public static T eq (T value) { * * @return {@code null} */ - public static T isNull () { + public static T nullMatches () { reportMatcher(NULL); return null; } @@ -368,7 +368,7 @@ public static T isNull () { * * @return {@code null} */ - public static T isNotNull () { + public static T notNullMatches () { reportMatcher(NOT_NULL); return null; } diff --git a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodMatcherMessageHandlerBuilder.java b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodMatcherMessageHandlerBuilder.java index 32664ee..31c41d8 100644 --- a/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodMatcherMessageHandlerBuilder.java +++ b/encon-handler/src/main/java/io/appulse/encon/handler/message/matcher/MethodMatcherMessageHandlerBuilder.java @@ -29,6 +29,7 @@ import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; @@ -77,6 +78,7 @@ public MethodMatcherMessageHandler build () { return new MethodMatcherMessageHandler(map); } + @SuppressFBWarnings("UPM_UNCALLED_PRIVATE_METHOD") private T createProxy (T object, MethodArgumentsWrapper wrapper) { val cacheKey = WrapperCacheKey.of(object.getClass(), wrapper); val proxy = wrappedCache.get(cacheKey); diff --git a/encon-handler/src/test/java/io/appulse/encon/handler/message/matcher/MethodMatcherMessageHandlerTest.java b/encon-handler/src/test/java/io/appulse/encon/handler/message/matcher/MethodMatcherMessageHandlerTest.java index 3680224..3b95d8b 100644 --- a/encon-handler/src/test/java/io/appulse/encon/handler/message/matcher/MethodMatcherMessageHandlerTest.java +++ b/encon-handler/src/test/java/io/appulse/encon/handler/message/matcher/MethodMatcherMessageHandlerTest.java @@ -33,26 +33,30 @@ import io.appulse.encon.handler.message.matcher.MethodMatcherMessageHandler; import io.appulse.encon.terms.ErlangTerm; -import io.appulse.utils.test.TestMethodNamePrinter; -import lombok.val; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; +import lombok.val; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; /** * * @author Artem Labazin */ -public class MethodMatcherMessageHandlerTest { - - @Rule - public TestRule watcher = new TestMethodNamePrinter(); +@DisplayName("Method matcher message handler tests") +class MethodMatcherMessageHandlerTest { static List list = new ArrayList<>(); + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } + @Test - public void test () { + @DisplayName("different handlers matches") + void test () { MyService1 service1 = new MyService1(); MyService2 service2 = new MyService2(); @@ -76,7 +80,8 @@ public void test () { } @Test - public void throwsAmbigousException () { + @DisplayName("throws ambigous exception") + void throwsAmbigousException () { MyService2 service = new MyService2(); val builder = MethodMatcherMessageHandler.builder() .wrap(service); From 3fffca70971cdec155374ab539985e7a588918cf Mon Sep 17 00:00:00 2001 From: Artem Labazin Date: Mon, 10 Dec 2018 16:54:34 +0300 Subject: [PATCH 15/20] Update examples for Java 11 --- encon-config/pom.xml | 1 - encon/pom.xml | 1 - .../encon/examples/custom/queue/MainTest.java | 6 +-- .../encon/examples/databind/MainTest.java | 6 +-- .../examples/echo/server/spring/MainTest.java | 54 ++++++++++--------- .../examples/echo/server/EchoClientNode.java | 4 +- .../examples/echo/server/EchoServerNode.java | 4 +- .../encon/examples/echo/server/MainTest.java | 22 ++++---- .../examples/handler/advanced/MainTest.java | 6 +-- .../examples/handler/basic/MainTest.java | 6 +-- .../examples/load/config/spring/MainTest.java | 13 +++-- .../encon/examples/load/config/MainTest.java | 6 +-- .../encon/examples/simple/MainTest.java | 6 +-- pom.xml | 6 +++ 14 files changed, 73 insertions(+), 68 deletions(-) diff --git a/encon-config/pom.xml b/encon-config/pom.xml index 89331e6..dd4ee74 100644 --- a/encon-config/pom.xml +++ b/encon-config/pom.xml @@ -35,7 +35,6 @@ limitations under the License. org.yaml snakeyaml - 1.23 diff --git a/encon/pom.xml b/encon/pom.xml index 8fe814d..879baba 100644 --- a/encon/pom.xml +++ b/encon/pom.xml @@ -64,7 +64,6 @@ limitations under the License. org.yaml snakeyaml - 1.23 diff --git a/examples/custom-queue/src/test/java/io/appulse/encon/examples/custom/queue/MainTest.java b/examples/custom-queue/src/test/java/io/appulse/encon/examples/custom/queue/MainTest.java index e129bc8..04175d3 100644 --- a/examples/custom-queue/src/test/java/io/appulse/encon/examples/custom/queue/MainTest.java +++ b/examples/custom-queue/src/test/java/io/appulse/encon/examples/custom/queue/MainTest.java @@ -29,17 +29,17 @@ import io.appulse.encon.mailbox.Mailbox; import io.appulse.encon.terms.ErlangTerm; -import org.junit.Test; +import org.junit.jupiter.api.Test; /** * * @since 1.6.2 * @author Artem Labazin */ -public class MainTest { +class MainTest { @Test - public void test () throws Exception { + void test () throws Exception { ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.execute(() -> Main.main(null)); diff --git a/examples/databind/src/test/java/io/appulse/encon/examples/databind/MainTest.java b/examples/databind/src/test/java/io/appulse/encon/examples/databind/MainTest.java index 59e1cec..6c6b0b3 100644 --- a/examples/databind/src/test/java/io/appulse/encon/examples/databind/MainTest.java +++ b/examples/databind/src/test/java/io/appulse/encon/examples/databind/MainTest.java @@ -30,17 +30,17 @@ import io.appulse.encon.mailbox.Mailbox; import io.appulse.encon.terms.ErlangTerm; -import org.junit.Test; +import org.junit.jupiter.api.Test; /** * * @since 1.6.2 * @author Artem Labazin */ -public class MainTest { +class MainTest { @Test - public void test () throws Exception { + void test () throws Exception { ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.execute(() -> Main.main(null)); diff --git a/examples/echo-server-spring/src/test/java/io/appulse/encon/examples/echo/server/spring/MainTest.java b/examples/echo-server-spring/src/test/java/io/appulse/encon/examples/echo/server/spring/MainTest.java index 56ced74..8067d50 100644 --- a/examples/echo-server-spring/src/test/java/io/appulse/encon/examples/echo/server/spring/MainTest.java +++ b/examples/echo-server-spring/src/test/java/io/appulse/encon/examples/echo/server/spring/MainTest.java @@ -35,19 +35,19 @@ import io.appulse.epmd.java.server.command.server.ServerCommandExecutor; import io.appulse.epmd.java.server.command.server.ServerCommandOptions; import io.appulse.utils.SocketUtils; -import io.appulse.utils.test.TestMethodNamePrinter; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestRule; -import org.junit.runner.RunWith; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.ComponentScan; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.context.junit4.SpringRunner; /** * @@ -60,24 +60,15 @@ EchoClient.class, EnconProperties.class }) -@RunWith(SpringRunner.class) -public class MainTest { +@ExtendWith(SpringExtension.class) +class MainTest { private static ExecutorService executor; private static ServerCommandExecutor epmdServer; - @Rule - public TestRule watcher = new TestMethodNamePrinter(); - - @Autowired - EchoClient client; - - @Autowired - EchoServer server; - - @BeforeClass - public static void beforeClass () { + @BeforeAll + static void beforeAll () { if (SocketUtils.isPortAvailable(4369)) { executor = Executors.newSingleThreadExecutor(); epmdServer = new ServerCommandExecutor(new CommonOptions(), new ServerCommandOptions()); @@ -85,8 +76,8 @@ public static void beforeClass () { } } - @AfterClass - public static void afterClass () { + @AfterAll + static void afterAll () { ofNullable(epmdServer) .ifPresent(ServerCommandExecutor::close); @@ -94,8 +85,19 @@ public static void afterClass () { .ifPresent(ExecutorService::shutdown); } + @Autowired + EchoClient client; + + @Autowired + EchoServer server; + + @BeforeEach + void beforeEach (TestInfo testInfo) { + System.out.println("- " + testInfo.getDisplayName()); + } + @Test - public void term () { + void term () { ErlangTerm request = tuple( client.pid(), tuple( @@ -115,7 +117,7 @@ public void term () { } @Test - public void pojo () { + void pojo () { MyPojo2 request = new MyPojo2( client.pid(), "Artem", diff --git a/examples/echo-server/src/main/java/io/appulse/encon/examples/echo/server/EchoClientNode.java b/examples/echo-server/src/main/java/io/appulse/encon/examples/echo/server/EchoClientNode.java index 705d71a..d6ea068 100644 --- a/examples/echo-server/src/main/java/io/appulse/encon/examples/echo/server/EchoClientNode.java +++ b/examples/echo-server/src/main/java/io/appulse/encon/examples/echo/server/EchoClientNode.java @@ -35,13 +35,13 @@ * @author Artem Labazin */ @FieldDefaults(level = PRIVATE, makeFinal = true) -class EchoClientNode implements Closeable { +public class EchoClientNode implements Closeable { Node node; Mailbox mailbox; - EchoClientNode (String cookie) { + public EchoClientNode (String cookie) { NodeConfig config = NodeConfig.builder() .shortName(TRUE) .cookie(cookie) diff --git a/examples/echo-server/src/main/java/io/appulse/encon/examples/echo/server/EchoServerNode.java b/examples/echo-server/src/main/java/io/appulse/encon/examples/echo/server/EchoServerNode.java index 04171ad..185fd4a 100644 --- a/examples/echo-server/src/main/java/io/appulse/encon/examples/echo/server/EchoServerNode.java +++ b/examples/echo-server/src/main/java/io/appulse/encon/examples/echo/server/EchoServerNode.java @@ -40,13 +40,13 @@ */ @Slf4j @FieldDefaults(level = PRIVATE, makeFinal = true) -class EchoServerNode implements Runnable, Closeable { +public class EchoServerNode implements Runnable, Closeable { Node node; Mailbox mailbox; - EchoServerNode (String nodeName, String cookie, String mailboxName) { + public EchoServerNode (String nodeName, String cookie, String mailboxName) { NodeConfig config = NodeConfig.builder() .shortName(TRUE) .cookie(cookie) diff --git a/examples/echo-server/src/test/java/io/appulse/encon/examples/echo/server/MainTest.java b/examples/echo-server/src/test/java/io/appulse/encon/examples/echo/server/MainTest.java index e5e83dc..03e9bd7 100644 --- a/examples/echo-server/src/test/java/io/appulse/encon/examples/echo/server/MainTest.java +++ b/examples/echo-server/src/test/java/io/appulse/encon/examples/echo/server/MainTest.java @@ -20,9 +20,9 @@ import static io.appulse.encon.terms.Erlang.number; import static io.appulse.encon.terms.Erlang.string; import static io.appulse.encon.terms.Erlang.tuple; -import static org.junit.Assert.assertEquals; import static java.util.Arrays.asList; import static java.util.Collections.singleton; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -39,16 +39,16 @@ import lombok.Data; import lombok.NoArgsConstructor; import lombok.EqualsAndHashCode; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** * * @since 1.6.0 * @author Artem Labazin */ -public class MainTest { +class MainTest { final String SERVER_NODE_NAME = "echo-server"; final String SERVER_MAILBOX_NAME = "echo"; @@ -59,8 +59,8 @@ public class MainTest { EchoServerNode server; EchoClientNode client; - @Before - public void before () { + @BeforeEach + void beforeEach () { server = new EchoServerNode(SERVER_NODE_NAME, COOKIE, SERVER_MAILBOX_NAME); client = new EchoClientNode(COOKIE); @@ -68,15 +68,15 @@ public void before () { executor.execute(server); } - @After - public void after () { + @AfterEach + void afterEach () { client.close(); server.close(); executor.shutdown(); } @Test - public void term () { + void term () { ErlangTerm request = tuple( atom("ok"), number(42), @@ -91,7 +91,7 @@ public void term () { } @Test - public void pojo () { + void pojo () { MyPojo request = new MyPojo( "Artem", 27, diff --git a/examples/handler-advanced/src/test/java/io/appulse/encon/examples/handler/advanced/MainTest.java b/examples/handler-advanced/src/test/java/io/appulse/encon/examples/handler/advanced/MainTest.java index 0776ce6..5c2f073 100644 --- a/examples/handler-advanced/src/test/java/io/appulse/encon/examples/handler/advanced/MainTest.java +++ b/examples/handler-advanced/src/test/java/io/appulse/encon/examples/handler/advanced/MainTest.java @@ -28,17 +28,17 @@ import io.appulse.encon.Nodes; import io.appulse.encon.mailbox.Mailbox; -import org.junit.Test; +import org.junit.jupiter.api.Test; /** * * @since 1.6.2 * @author Artem Labazin */ -public class MainTest { +class MainTest { @Test - public void test () throws Exception { + void test () throws Exception { Server server = new Server(); server.start(); diff --git a/examples/handler-basic/src/test/java/io/appulse/encon/examples/handler/basic/MainTest.java b/examples/handler-basic/src/test/java/io/appulse/encon/examples/handler/basic/MainTest.java index 7d2348e..d84c8fe 100644 --- a/examples/handler-basic/src/test/java/io/appulse/encon/examples/handler/basic/MainTest.java +++ b/examples/handler-basic/src/test/java/io/appulse/encon/examples/handler/basic/MainTest.java @@ -26,17 +26,17 @@ import io.appulse.encon.mailbox.Mailbox; import io.appulse.encon.terms.ErlangTerm; -import org.junit.Test; +import org.junit.jupiter.api.Test; /** * * @since 1.6.2 * @author Artem Labazin */ -public class MainTest { +class MainTest { @Test - public void test () throws Exception { + void test () throws Exception { Server server = new Server(); server.start(); diff --git a/examples/load-config-spring/src/test/java/io/appulse/encon/examples/load/config/spring/MainTest.java b/examples/load-config-spring/src/test/java/io/appulse/encon/examples/load/config/spring/MainTest.java index fcb04a5..4522701 100644 --- a/examples/load-config-spring/src/test/java/io/appulse/encon/examples/load/config/spring/MainTest.java +++ b/examples/load-config-spring/src/test/java/io/appulse/encon/examples/load/config/spring/MainTest.java @@ -16,7 +16,6 @@ package io.appulse.encon.examples.load.config.spring; - import static io.appulse.encon.common.DistributionFlag.BIG_CREATION; import static io.appulse.encon.common.DistributionFlag.BIT_BINARIES; import static io.appulse.encon.common.DistributionFlag.EXTENDED_PIDS_PORTS; @@ -38,12 +37,12 @@ import io.appulse.encon.config.Config; import lombok.extern.slf4j.Slf4j; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.ApplicationContext; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.junit.jupiter.SpringExtension; /** * @@ -51,9 +50,9 @@ * @author Artem Labazin */ @Slf4j -@RunWith(SpringRunner.class) +@ExtendWith(SpringExtension.class) @SpringBootTest(classes = Main.class) -public class MainTest { +class MainTest { @Autowired Config defaultConfig; @@ -62,7 +61,7 @@ public class MainTest { ApplicationContext context; @Test - public void test () { + void test () { try { assertThat(context.containsBean("node-1")).isTrue(); assertThat(context.containsBean("node-2")).isTrue(); diff --git a/examples/load-config/src/test/java/io/appulse/encon/examples/load/config/MainTest.java b/examples/load-config/src/test/java/io/appulse/encon/examples/load/config/MainTest.java index e8e6aec..7e860d9 100644 --- a/examples/load-config/src/test/java/io/appulse/encon/examples/load/config/MainTest.java +++ b/examples/load-config/src/test/java/io/appulse/encon/examples/load/config/MainTest.java @@ -36,7 +36,7 @@ import io.appulse.encon.Node; import lombok.extern.slf4j.Slf4j; -import org.junit.Test; +import org.junit.jupiter.api.Test; /** * @@ -44,10 +44,10 @@ * @author Artem Labazin */ @Slf4j -public class MainTest { +class MainTest { @Test - public void test () { + void test () { Server server = new Server(); server.start(); diff --git a/examples/simple/src/test/java/io/appulse/encon/examples/simple/MainTest.java b/examples/simple/src/test/java/io/appulse/encon/examples/simple/MainTest.java index 5c7e2e6..c4663a6 100644 --- a/examples/simple/src/test/java/io/appulse/encon/examples/simple/MainTest.java +++ b/examples/simple/src/test/java/io/appulse/encon/examples/simple/MainTest.java @@ -29,17 +29,17 @@ import io.appulse.encon.mailbox.Mailbox; import io.appulse.encon.terms.ErlangTerm; -import org.junit.Test; +import org.junit.jupiter.api.Test; /** * * @since 1.6.2 * @author Artem Labazin */ -public class MainTest { +class MainTest { @Test - public void test () throws Exception { + void test () throws Exception { ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.execute(() -> Main.main(null)); diff --git a/pom.xml b/pom.xml index d0a519c..b68ad06 100644 --- a/pom.xml +++ b/pom.xml @@ -196,6 +196,12 @@ limitations under the License. server 1.0.2 + + + org.yaml + snakeyaml + 1.23 + org.erlang.otp From b4ad8aa1a4e87cc41505a51be1b58022441fd628 Mon Sep 17 00:00:00 2001 From: Artem Labazin Date: Mon, 10 Dec 2018 17:08:17 +0300 Subject: [PATCH 16/20] Set java 11 in Travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0b3f6c0..552dd25 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: java jdk: - - oraclejdk8 + - openjdk11 install: mvn --settings .settings.xml install -DskipTests=true -Dmaven.javadoc.skip=true -Dgpg.skip -B -V From 9e921787a07e38e3575793ffd61f6258df3a69fb Mon Sep 17 00:00:00 2001 From: Artem Labazin Date: Mon, 10 Dec 2018 18:15:31 +0300 Subject: [PATCH 17/20] Update benchmark README.md for Java 11 --- benchmark/README.md | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/benchmark/README.md b/benchmark/README.md index 01ccce5..f6db055 100644 --- a/benchmark/README.md +++ b/benchmark/README.md @@ -80,25 +80,31 @@ In this test we have only one node and two mailboxes which send the message to e ## How to setup the environment -1. Add Java repository: +1. Update and upgrade the distro: ```bash -$> sudo add-apt-repository --yes ppa:webupd8team/java +$> sudo apt-get update --yes && sudo apt-get upgrade --yes ``` -2. Update and upgrade the distro: +2. Install `git`, `curl`, `zip` and `unzip`: ```bash -$> sudo apt-get update --yes && sudo apt-get upgrade --yes +$> sudo apt-get install --yes git curl zip unzip +``` + +3. Install `sdkman`: + +```bash +$> curl -s "https://get.sdkman.io" | bash ``` -3. Install `Git`, `Java 8` and `Maven`: +4. Install `Java`: ```bash -$> sudo apt-get install --yes oracle-java8-installer git maven +$> sdk install java 11.0.1-open ``` -4. Clone the repo: +5. Clone the repo: ```bash $> git clone https://github.com/appulse-projects/encon-java.git @@ -115,7 +121,7 @@ $> cd encon-java 2. Build the project with only needed dependencies: ```bash -$> mvn clean package \ +$> ./mvnw clean package \ -DskipTests \ -Dgpg.skip \ -Dfindbugs.skip=true \ @@ -128,18 +134,19 @@ $> mvn clean package \ 3. Run the tests ```bash -$> nohup java -Xms1G -Xmx2G -jar benchmark/target/benchmarks.jar > job.logs 2>&1 & +$> nohup java -Xms3G -Xmx4G -jar benchmark/target/benchmarks.jar > job.logs 2>&1 & ``` ### One-liner ```bash -$> sudo add-apt-repository --yes ppa:webupd8team/java && \ - sudo apt-get update --yes && sudo apt-get upgrade --yes && \ - sudo apt-get install --yes oracle-java8-installer git maven && \ +$> sudo apt-get update --yes && sudo apt-get upgrade --yes && \ + sudo apt-get install --yes git curl zip unzip && \ + curl -s "https://get.sdkman.io" | bash && \ + sdk install java 11.0.1-open && \ git clone https://github.com/appulse-projects/encon-java.git && \ cd encon-java && \ - mvn clean package \ + ./mvnw clean package \ -DskipTests \ -Dgpg.skip \ -Dfindbugs.skip=true \ @@ -147,5 +154,5 @@ $> sudo add-apt-repository --yes ppa:webupd8team/java && \ -Dcheckstyle.skip \ -Dmaven.test.skip=true \ -pl benchmark -am && \ - nohup java -Xms1G -Xmx2G -jar benchmark/target/benchmarks.jar > job.logs 2>&1 & + nohup java -Xms3G -Xmx4G -jar benchmark/target/benchmarks.jar > job.logs 2>&1 & ``` From 7ceaaad7f72a123e7324201c7110a8b6467ba4b6 Mon Sep 17 00:00:00 2001 From: Artem Labazin Date: Mon, 10 Dec 2018 21:44:03 +0300 Subject: [PATCH 18/20] merge with master --- CHANGELOG.md | 16 ++ .../java/io/appulse/encon/terms/Erlang.java | 8 +- .../io/appulse/encon/terms/ErlangTerm.java | 4 +- .../appulse/encon/terms/type/ErlangAtom.java | 145 +++++------------- .../appulse/encon/terms/type/ErlangPid.java | 45 ------ 5 files changed, 62 insertions(+), 156 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d49052e..c1c4724 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Add handshake error handling (exceptions? error logs?). - Turn on checkstyle JavaDocs module. - Add updates to the protocol, like new `ControlMessage`. +- Do we really need `ErlangInteger.cache` methods? +- Add atom's table equivalent. ## [2.0.0](https://github.com/appulse-projects/encon-java/releases/tag/2.0.0) - 2018-10-14 @@ -29,6 +31,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Module `encon-config` now is a configuration framework for laoding, dumping and mapping different configurations and a fancy and flexible way; - According to the new `encon-config` implementation, all configurations were moved to the appropriate modules. +## [1.6.7](https://github.com/appulse-projects/encon-java/releases/tag/1.6.7) - 2018-10-07 + +### Changed + +- Quick fix for [GitHub issue](https://github.com/appulse-projects/encon-java/issues/13), removed `ErlangPid` and `EralngAtom` caches. + +## [1.6.6](https://github.com/appulse-projects/encon-java/releases/tag/1.6.6) - 2018-10-02 + +### Changed + +- Quick fix for [GitHub issue](https://github.com/appulse-projects/encon-java/issues/11), refactored `ErlangInteger` cache; + +- Correctly setup `checkstyle`/`epmd`/`findbugs` validation phases. + ## [1.6.5](https://github.com/appulse-projects/encon-java/releases/tag/1.6.5) - 2018-09-28 ### Changed diff --git a/encon-terms/src/main/java/io/appulse/encon/terms/Erlang.java b/encon-terms/src/main/java/io/appulse/encon/terms/Erlang.java index 00c6b1f..847f4d0 100644 --- a/encon-terms/src/main/java/io/appulse/encon/terms/Erlang.java +++ b/encon-terms/src/main/java/io/appulse/encon/terms/Erlang.java @@ -55,7 +55,7 @@ public final class Erlang { /** * Cached enpty (0-size string) {@link ErlangAtom} instance. */ - public static final ErlangAtom EMPTY_ATOM = ErlangAtom.cached(""); + public static final ErlangAtom EMPTY_ATOM = new ErlangAtom(""); /** * Creates new {@link ErlangAtom} instance from {@code boolean} (true/false value) . @@ -65,7 +65,9 @@ public final class Erlang { * @return {@link ErlangAtom} new instance */ public static ErlangAtom atom (boolean value) { - return ErlangAtom.cached(value); + return value + ? ErlangAtom.ATOM_TRUE + : ErlangAtom.ATOM_FALSE; } /** @@ -76,7 +78,7 @@ public static ErlangAtom atom (boolean value) { * @return {@link ErlangAtom} new instance */ public static ErlangAtom atom (@NonNull String value) { - return ErlangAtom.cached(value); + return new ErlangAtom(value); } /** diff --git a/encon-terms/src/main/java/io/appulse/encon/terms/ErlangTerm.java b/encon-terms/src/main/java/io/appulse/encon/terms/ErlangTerm.java index 1ca8da3..38d64cb 100644 --- a/encon-terms/src/main/java/io/appulse/encon/terms/ErlangTerm.java +++ b/encon-terms/src/main/java/io/appulse/encon/terms/ErlangTerm.java @@ -108,7 +108,7 @@ public static T newInstance (@NonNull ByteBuf buffer) { return (T) new ErlangPort(type, buffer); case PID: case NEW_PID: - return (T) ErlangPid.cached(type, buffer); + return (T) new ErlangPid(type, buffer); case SMALL_TUPLE: case LARGE_TUPLE: return (T) new ErlangTuple(type, buffer); @@ -133,7 +133,7 @@ public static T newInstance (@NonNull ByteBuf buffer) { case SMALL_ATOM_UTF8: case ATOM: case SMALL_ATOM: - return (T) ErlangAtom.cached(type, buffer); + return (T) new ErlangAtom(type, buffer); default: val message = String.format("Unknown term type %s (%d)", type.name(), typeByte); throw new ErlangTermDecodeException(message); diff --git a/encon-terms/src/main/java/io/appulse/encon/terms/type/ErlangAtom.java b/encon-terms/src/main/java/io/appulse/encon/terms/type/ErlangAtom.java index a0b9232..f9cf9f8 100644 --- a/encon-terms/src/main/java/io/appulse/encon/terms/type/ErlangAtom.java +++ b/encon-terms/src/main/java/io/appulse/encon/terms/type/ErlangAtom.java @@ -21,25 +21,20 @@ import static io.appulse.encon.terms.TermType.SMALL_ATOM_UTF8; import static java.nio.charset.StandardCharsets.ISO_8859_1; import static java.nio.charset.StandardCharsets.UTF_8; -import static java.util.Locale.ENGLISH; import static lombok.AccessLevel.PRIVATE; import java.nio.charset.Charset; -import java.util.Arrays; import io.appulse.encon.terms.ErlangTerm; import io.appulse.encon.terms.TermType; import io.appulse.encon.terms.exception.IllegalErlangTermTypeException; -import io.appulse.utils.cache.LruCache; import io.netty.buffer.ByteBuf; -import io.netty.util.ByteProcessor; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; import lombok.ToString; import lombok.experimental.FieldDefaults; -import lombok.experimental.NonFinal; /** * An atom is a literal, a constant with name. An atom is to be enclosed in @@ -51,83 +46,48 @@ * @author Artem Labazin */ @ToString +@SuppressWarnings("deprecation") @EqualsAndHashCode(callSuper = true, of = "bytes") @FieldDefaults(level = PRIVATE, makeFinal = true) public class ErlangAtom extends ErlangTerm { private static final long serialVersionUID = -2748345367418129439L; - private static final int MAX_ATOM_CODE_POINTS_LENGTH = 255; - - private static final int MAX_SMALL_ATOM_BYTES_LENGTH = 255; - - private static final LruCache CACHE = new LruCache<>(1000); + public static final ErlangAtom ATOM_TRUE = new ErlangAtom(true); - private static final ErlangAtom ATOM_TRUE = cached(Boolean.TRUE.toString().toLowerCase(ENGLISH)); + public static final ErlangAtom ATOM_FALSE = new ErlangAtom(false); - private static final ErlangAtom ATOM_FALSE = cached(Boolean.FALSE.toString().toLowerCase(ENGLISH)); - - public static ErlangAtom cached (boolean value) { - return value - ? ATOM_TRUE - : ATOM_FALSE; - } - - public static ErlangAtom cached (String value) { - Charset charset = UTF_8; - byte[] bytes = value.getBytes(charset); - int hashCode = Arrays.hashCode(bytes); - return CACHE.computeIfAbsent(hashCode, key -> new ErlangAtom(value, charset, bytes)); - } - - @SuppressWarnings("deprecation") - public static ErlangAtom cached (TermType type, ByteBuf buffer) { - ByteArrayHashCode byteProcessor = new ByteArrayHashCode(); - - int length = type == SMALL_ATOM || type == SMALL_ATOM_UTF8 - ? buffer.readUnsignedByte() - : buffer.readUnsignedShort(); - - buffer.forEachByte(buffer.readerIndex(), length, byteProcessor); + private static final int MAX_ATOM_CODE_POINTS_LENGTH = 255; - return CACHE.compute(byteProcessor.getHashCode(), (key, value) -> { - if (value == null) { - return new ErlangAtom(type, buffer, length); - } else { - buffer.skipBytes(length); - return value; - } - }); - } + private static final int MAX_SMALL_ATOM_BYTES_LENGTH = 255; - @NonFinal - String value; + @Getter(lazy = true, value = PRIVATE) + String value = createString(); byte[] bytes; transient Charset charset; /** - * Constructs Erlang's atom object with specific {@link String} value. + * Constructs Erlang's term object with specific {@link TermType} from {@link ByteBuf}. * - * @param value {@link String} atom's value + * @param type object's type + * + * @param buffer byte buffer */ - public ErlangAtom (@NonNull String value) { - super(); + public ErlangAtom (TermType type, ByteBuf buffer) { + super(type); - this.value = value.codePointCount(0, value.length()) <= MAX_ATOM_CODE_POINTS_LENGTH - ? value - // Throwing an exception would be better I think, but truncation - // seems to be the way it has been done in other parts of OTP... - : new String(value.codePoints().toArray(), 0, MAX_ATOM_CODE_POINTS_LENGTH); + int length = type == SMALL_ATOM || type == SMALL_ATOM_UTF8 + ? buffer.readUnsignedByte() + : buffer.readUnsignedShort(); - charset = UTF_8; - bytes = this.value.getBytes(charset); - if (bytes.length > MAX_SMALL_ATOM_BYTES_LENGTH) { - setType(ATOM_UTF8); - } else { - setType(SMALL_ATOM_UTF8); - } + charset = type == SMALL_ATOM_UTF8 || type == ATOM_UTF8 + ? UTF_8 + : ISO_8859_1; + + bytes = new byte[length]; + buffer.readBytes(bytes); } /** @@ -136,46 +96,31 @@ public ErlangAtom (@NonNull String value) { * @param value {@code boolean} atom's value */ public ErlangAtom (boolean value) { - super(SMALL_ATOM_UTF8); - charset = UTF_8; - this.value = Boolean.toString(value); - bytes = value - ? Boolean.TRUE.toString().getBytes(charset) - : Boolean.FALSE.toString().getBytes(charset); + this(Boolean.toString(value), UTF_8); } /** - * Constructs Erlang's term object with specific {@link TermType} from {@link ByteBuf}. - * - * @param type object's type - * - * @param buffer byte buffer + * Constructs Erlang's atom object with specific {@link String} value. * - * @param length amount of useful bytes + * @param value {@link String} atom's value */ - private ErlangAtom (TermType type, ByteBuf buffer, int length) { - super(type); - - charset = type == SMALL_ATOM_UTF8 || type == ATOM_UTF8 - ? UTF_8 - : ISO_8859_1; - - bytes = new byte[length]; - buffer.readBytes(bytes); + public ErlangAtom (String value) { + this(value, UTF_8); } - @SuppressWarnings("PMD.ArrayIsStoredDirectly") - private ErlangAtom (String value, Charset charset, byte[] bytes) { + public ErlangAtom (@NonNull String value, @NonNull Charset charset) { super(); - this.value = value.codePointCount(0, value.length()) <= MAX_ATOM_CODE_POINTS_LENGTH - ? value - // Throwing an exception would be better I think, but truncation - // seems to be the way it has been done in other parts of OTP... - : new String(value.codePoints().toArray(), 0, MAX_ATOM_CODE_POINTS_LENGTH); + if (value.codePointCount(0, value.length()) <= MAX_ATOM_CODE_POINTS_LENGTH) { + this.value.set(value); + } else { + // Throwing an exception would be better I think, but truncation + // seems to be the way it has been done in other parts of OTP... + this.value.set(new String(value.codePoints().toArray(), 0, MAX_ATOM_CODE_POINTS_LENGTH)); + } this.charset = charset; - this.bytes = bytes; + this.bytes = getValue().getBytes(charset); if (bytes.length > MAX_SMALL_ATOM_BYTES_LENGTH) { setType(ATOM_UTF8); } else { @@ -195,10 +140,7 @@ public boolean asBoolean (boolean defaultValue) { @Override public String asText (String defaultValue) { - if (value == null) { - value = new String(bytes, charset); - } - return value; + return getValue(); } @Override @@ -233,16 +175,7 @@ protected void serialize (ByteBuf buffer) { buffer.writeBytes(bytes); } - @Getter - @FieldDefaults(level = PRIVATE) - private static class ByteArrayHashCode implements ByteProcessor { - - int hashCode = 1; - - @Override - public boolean process (byte value) throws Exception { - hashCode = 31 * hashCode + value; - return true; - } + private String createString () { + return new String(bytes, charset); } } diff --git a/encon-terms/src/main/java/io/appulse/encon/terms/type/ErlangPid.java b/encon-terms/src/main/java/io/appulse/encon/terms/type/ErlangPid.java index cd512ee..efc783f 100644 --- a/encon-terms/src/main/java/io/appulse/encon/terms/type/ErlangPid.java +++ b/encon-terms/src/main/java/io/appulse/encon/terms/type/ErlangPid.java @@ -17,8 +17,6 @@ package io.appulse.encon.terms.type; import static io.appulse.encon.terms.TermType.PID; -import static io.appulse.encon.terms.TermType.SMALL_ATOM; -import static io.appulse.encon.terms.TermType.SMALL_ATOM_UTF8; import static java.util.Optional.ofNullable; import static lombok.AccessLevel.PRIVATE; @@ -27,10 +25,8 @@ import io.appulse.encon.terms.ErlangTerm; import io.appulse.encon.terms.TermType; import io.appulse.encon.terms.exception.IllegalErlangTermTypeException; -import io.appulse.utils.cache.LruCache; import io.netty.buffer.ByteBuf; -import io.netty.util.ByteProcessor; import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -51,34 +47,6 @@ public class ErlangPid extends ErlangTerm { private static final long serialVersionUID = 7083159089429831665L; - private static final LruCache CACHE = new LruCache<>(1000); - - @SuppressWarnings("deprecation") - public static ErlangPid cached (TermType type, ByteBuf buffer) { - int index = buffer.readerIndex(); - byte nodeNameType = buffer.readByte(); - int nodeNameLength = nodeNameType == SMALL_ATOM.getCode() || nodeNameType == SMALL_ATOM_UTF8.getCode() - ? buffer.readUnsignedByte() - : buffer.readUnsignedShort(); - - int length = type == PID - ? nodeNameLength + 9 - : nodeNameLength + 12; - - ByteArrayHashCode byteProcessor = new ByteArrayHashCode(); - buffer.forEachByte(buffer.readerIndex(), length, byteProcessor); - - return CACHE.compute(byteProcessor.getHashCode(), (key, value) -> { - if (value == null) { - buffer.readerIndex(index); - return new ErlangPid(type, buffer); - } else { - buffer.skipBytes(length); - return value; - } - }); - } - @NonFinal NodeDescriptor descriptor; @@ -183,17 +151,4 @@ protected void serialize (ByteBuf buffer) { throw new IllegalErlangTermTypeException(getClass(), getType()); } } - - @Getter - @FieldDefaults(level = PRIVATE) - private static class ByteArrayHashCode implements ByteProcessor { - - int hashCode = 1; - - @Override - public boolean process (byte value) throws Exception { - hashCode = 31 * hashCode + value; - return true; - } - } } From 9a0341674a3cb0269001a90ec31ccdeb8a552861 Mon Sep 17 00:00:00 2001 From: Artem Labazin Date: Mon, 10 Dec 2018 23:00:40 +0300 Subject: [PATCH 19/20] fix benchmark installation --- benchmark/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/benchmark/README.md b/benchmark/README.md index f6db055..426a4d8 100644 --- a/benchmark/README.md +++ b/benchmark/README.md @@ -96,6 +96,7 @@ $> sudo apt-get install --yes git curl zip unzip ```bash $> curl -s "https://get.sdkman.io" | bash +$> source "$HOME/.sdkman/bin/sdkman-init.sh" ``` 4. Install `Java`: @@ -143,6 +144,7 @@ $> nohup java -Xms3G -Xmx4G -jar benchmark/target/benchmarks.jar > job.logs 2>&1 $> sudo apt-get update --yes && sudo apt-get upgrade --yes && \ sudo apt-get install --yes git curl zip unzip && \ curl -s "https://get.sdkman.io" | bash && \ + source "$HOME/.sdkman/bin/sdkman-init.sh" && \ sdk install java 11.0.1-open && \ git clone https://github.com/appulse-projects/encon-java.git && \ cd encon-java && \ From 2df662d7da7b03be3cdf8f19425a69c7caf785c1 Mon Sep 17 00:00:00 2001 From: Artem Labazin Date: Tue, 11 Dec 2018 11:50:12 +0300 Subject: [PATCH 20/20] update benchmark readme --- benchmark/README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/benchmark/README.md b/benchmark/README.md index 426a4d8..1cf381c 100644 --- a/benchmark/README.md +++ b/benchmark/README.md @@ -37,9 +37,9 @@ H/W path Device Class Description * **JMH version:** 1.21 -* **VM version:** JDK 1.8.0_181, Java HotSpot(TM) 64-Bit Server VM, 25.181-b13 +* **VM version:** JDK 11.0.1, OpenJDK 64-Bit Server VM, 11.0.1+13 -* **VM options:** -Xms1G -Xmx2G +* **VM options:** -Xms3G -Xmx4G * **Warmup:** 10 iterations, 10 s each @@ -59,14 +59,14 @@ The installation consist of a server node at separate thread, which echoes the m | implementation | clients | score | error | units | |:---------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------:|------------:|------------:|:------| -| [encon](https://github.com/appulse-projects/encon-java/blob/master/benchmark/src/main/java/io/appulse/encon/benchmark/Encon_Node2NodeBenchmarks.java#L130) | 1 | `11679.266` | `414.090` | ops/s | -| [jinterface](https://github.com/appulse-projects/encon-java/blob/master/benchmark/src/main/java/io/appulse/encon/benchmark/JInterface_Node2NodeBenchmarks.java#L109) | 1 | `11862.914` | `385.573` | ops/s | -| [encon](https://github.com/appulse-projects/encon-java/blob/master/benchmark/src/main/java/io/appulse/encon/benchmark/Encon_Node2NodeBenchmarks.java#L138) | 2 | `22337.500` | `918.292` | ops/s | -| [jinterface](https://github.com/appulse-projects/encon-java/blob/master/benchmark/src/main/java/io/appulse/encon/benchmark/JInterface_Node2NodeBenchmarks.java#L117) | 2 | `18217.878` | `861.270` | ops/s | -| [encon](https://github.com/appulse-projects/encon-java/blob/master/benchmark/src/main/java/io/appulse/encon/benchmark/Encon_Node2NodeBenchmarks.java#L146) | 4 | `36001.870` | `2033.472` | ops/s | -| [jinterface](https://github.com/appulse-projects/encon-java/blob/master/benchmark/src/main/java/io/appulse/encon/benchmark/JInterface_Node2NodeBenchmarks.java#L125) | 4 | `23202.485` | `1295.186` | ops/s | -| [encon](https://github.com/appulse-projects/encon-java/blob/master/benchmark/src/main/java/io/appulse/encon/benchmark/Encon_Node2NodeBenchmarks.java#L154) | 8 | `44742.858` | `1865.853` | ops/s | -| [jinterface](https://github.com/appulse-projects/encon-java/blob/master/benchmark/src/main/java/io/appulse/encon/benchmark/JInterface_Node2NodeBenchmarks.java#L133) | 8 | `23495.184` | `671.766` | ops/s | +| [encon](https://github.com/appulse-projects/encon-java/blob/master/benchmark/src/main/java/io/appulse/encon/benchmark/Encon_Node2NodeBenchmarks.java#L130) | 1 | `13404.955` | `832.219` | ops/s | +| [jinterface](https://github.com/appulse-projects/encon-java/blob/master/benchmark/src/main/java/io/appulse/encon/benchmark/JInterface_Node2NodeBenchmarks.java#L109) | 1 | `11382.375` | `358.907` | ops/s | +| [encon](https://github.com/appulse-projects/encon-java/blob/master/benchmark/src/main/java/io/appulse/encon/benchmark/Encon_Node2NodeBenchmarks.java#L138) | 2 | `21676.979` | `654.934` | ops/s | +| [jinterface](https://github.com/appulse-projects/encon-java/blob/master/benchmark/src/main/java/io/appulse/encon/benchmark/JInterface_Node2NodeBenchmarks.java#L117) | 2 | `18982.318` | `395.596` | ops/s | +| [encon](https://github.com/appulse-projects/encon-java/blob/master/benchmark/src/main/java/io/appulse/encon/benchmark/Encon_Node2NodeBenchmarks.java#L146) | 4 | `33532.304` | `609.782` | ops/s | +| [jinterface](https://github.com/appulse-projects/encon-java/blob/master/benchmark/src/main/java/io/appulse/encon/benchmark/JInterface_Node2NodeBenchmarks.java#L125) | 4 | `23027.511` | `327.508` | ops/s | +| [encon](https://github.com/appulse-projects/encon-java/blob/master/benchmark/src/main/java/io/appulse/encon/benchmark/Encon_Node2NodeBenchmarks.java#L154) | 8 | `48659.749` | `572.108` | ops/s | +| [jinterface](https://github.com/appulse-projects/encon-java/blob/master/benchmark/src/main/java/io/appulse/encon/benchmark/JInterface_Node2NodeBenchmarks.java#L133) | 8 | `25457.217` | `295.665` | ops/s | ### Mailbox to mailbox @@ -74,8 +74,8 @@ In this test we have only one node and two mailboxes which send the message to e | implementation | score | error | units | |:-----------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------:|------------:|:------| -| [encon](https://github.com/appulse-projects/encon-java/blob/master/benchmark/src/main/java/io/appulse/encon/benchmark/Encon_SimpleBenchmarks.java#L57) | `4080746.356` | `79809.419` | ops/s | -| [jinterface](https://github.com/appulse-projects/encon-java/blob/master/benchmark/src/main/java/io/appulse/encon/benchmark/JInterface_SimpleBenchmarks.java#L51) | `4885380.490` | `61920.971` | ops/s | +| [encon](https://github.com/appulse-projects/encon-java/blob/master/benchmark/src/main/java/io/appulse/encon/benchmark/Encon_SimpleBenchmarks.java#L57) | `2906135.871` | `46718.600` | ops/s | +| [jinterface](https://github.com/appulse-projects/encon-java/blob/master/benchmark/src/main/java/io/appulse/encon/benchmark/JInterface_SimpleBenchmarks.java#L51) | `3388805.729` | `10400.968` | ops/s | ## How to setup the environment