Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TOML support #57

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
<module>vertx-config-zookeeper</module>
<module>vertx-config-consul</module>
<module>vertx-config-vault</module>
<module>vertx-config-toml</module>
</modules>

<scm>
Expand Down
34 changes: 34 additions & 0 deletions vertx-config-toml/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-parent</artifactId>
<version>3.6.0-SNAPSHOT</version>
</parent>

<artifactId>vertx-config-toml</artifactId>

<properties>
<doc.skip>false</doc.skip>
<toml4j.version>0.7.2</toml4j.version>
</properties>

<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.moandjiezana.toml</groupId>
<artifactId>toml4j</artifactId>
<version>${toml4j.version}</version>
</dependency>
</dependencies>


</project>
45 changes: 45 additions & 0 deletions vertx-config-toml/src/main/asciidoc/toml-format.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
=== TOML Configuration Format

The TOML Configuration Format extends the Vert.x Configuration Retriever and
provides the support for the TOML Configuration Format.

==== Using the TOML Configuration Format

To use the TOML Configuration Format, add the following dependency to the
_dependencies_ section of your build descriptor:

* Maven (in your `pom.xml`):

[source,xml,subs="+attributes"]
----
<dependency>
<groupId>io.vertx.config.toml</groupId>
<artifactId>vertx-config-toml</artifactId>
<version>${maven.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>${maven.version}</version>
</dependency>
----

* Gradle (in your `build.gradle` file):

[source,groovy,subs="+attributes"]
----
compile 'io.vertx:vertx-config:${maven.version}'
compile 'io.vertx.config.toml:vertx-config-toml:${maven.version}'
----

==== Configuring the store to use TOML

Once added to your classpath or dependencies, you need to configure the
{@link io.vertx.config.ConfigRetriever} to use this format:

[source, $lang]
----
{@link examples.ConfigTomlExamples#example1(io.vertx.core.Vertx)}
----

You just need to set `format` to `toml`.
29 changes: 29 additions & 0 deletions vertx-config-toml/src/main/java/examples/ConfigTomlExamples.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package examples;

import io.vertx.config.ConfigRetriever;
import io.vertx.config.ConfigRetrieverOptions;
import io.vertx.config.ConfigStoreOptions;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;

/**
* @author <a href='lyndon.codes'>Lyndon Armitage</a>
*/
public final class ConfigTomlExamples {


public void example1(Vertx vertx) {
JsonObject storeConfig = new JsonObject().put("path", "my-config.toml");
ConfigStoreOptions storeOptions = new ConfigStoreOptions()
.setType("file")
.setFormat("toml")
.setConfig(storeConfig);

ConfigRetriever retriever = ConfigRetriever.create(
vertx,
new ConfigRetrieverOptions().addStore(storeOptions)
);

}

}
5 changes: 5 additions & 0 deletions vertx-config-toml/src/main/java/examples/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

@Source
package examples;

import io.vertx.docgen.Source;
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package io.vertx.config.toml;

import com.moandjiezana.toml.Toml;
import io.vertx.config.spi.ConfigProcessor;
import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.json.JsonObject;

import java.io.ByteArrayInputStream;
import java.util.Map;
import java.util.Objects;

/**
* <p>
* A processor for the <a href='https://github.com/toml-lang/toml'>TOML</a>
* format.
* </p>
* <p>
* Currently using the
* <a href='https://github.com/mwanji/toml4j'>toml4j library</a>. If a newer
* version of this library becomes available, you can override the dependency
* (assuming the API does not change).
* </p>
*
* @author <a href='lyndon.codes'>Lyndon Armitage</a>
*/
public final class TomlProcessor implements ConfigProcessor {

@Override
public final String name() {
return "toml";
}

@Override
public final void process(
Vertx vertx,
JsonObject configuration,
Buffer input,
Handler<AsyncResult<JsonObject>> handler
) {
Objects.requireNonNull(vertx, "vertx cannot be null");
Objects.requireNonNull(input, "input cannot be null");
Objects.requireNonNull(handler, "handler cannot be null");

if (input.length() == 0) {
handler.handle(Future.succeededFuture(new JsonObject()));
return;
}

vertx.executeBlocking(
future -> {
// Currently loads the whole config file into memory
try (
ByteArrayInputStream inputStream = new ByteArrayInputStream(
input.getBytes()
)
) {

Toml toml = new Toml().read(inputStream);
Map<String, Object> asMap = Objects.requireNonNull(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be reported to the handler.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now it is because of the try / catch. But it's a little bit convoluted

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was actually a bit of defensive programming on my part as the toml4j library provides the toMap method without any documentation. For reference:

  public Map<String, Object> toMap() {
    HashMap<String, Object> valuesCopy = new HashMap<String, Object>(values);
    
    if (defaults != null) {
      for (Map.Entry<String, Object> entry : defaults.values.entrySet()) {
        if (!valuesCopy.containsKey(entry.getKey())) {
          valuesCopy.put(entry.getKey(), entry.getValue());
        }
      }
    }

    return valuesCopy;
  }

In the processor would you have preferred something more like:

          Map<String, Object> asMap = toml.toMap();
          if (asMap != null) {
            JsonObject asJson = new JsonObject(asMap);
            future.complete(asJson);
          } else {
            future.fail(
              new NullPointerException("toml library returned a null map")
            );
          }

Instead of relying on the catch?

toml.toMap(),
"toml library returned a null map"
);
JsonObject asJson = new JsonObject(asMap);
future.complete(asJson);
} catch (Exception e) {
future.fail(e);
}
},
handler
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@ModuleGen(name = "vertx-config", groupPackage = "io.vertx")
package io.vertx.config.toml;

import io.vertx.codegen.annotations.ModuleGen;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.vertx.config.toml.TomlProcessor
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package examples;

import io.vertx.core.Vertx;
import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.junit.RunTestOnContext;
import io.vertx.ext.unit.junit.VertxUnitRunner;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.*;

@RunWith(VertxUnitRunner.class)
public class ConfigTomlExamplesTest {

@Rule
public RunTestOnContext contextRule = new RunTestOnContext();

private Vertx vertx;

@Before
public void setUp(TestContext context) throws Exception {
vertx = contextRule.vertx();
}

@Test
public void example1_doesnt_throw(TestContext context) {
ConfigTomlExamples examples = new ConfigTomlExamples();
examples.example1(vertx);
}
}