You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by po...@apache.org on 2019/06/07 09:12:28 UTC

[incubator-tamaya-extensions] branch master updated: TAMAYA-386 Move the distributed example to extensions

This is an automated email from the ASF dual-hosted git repository.

pottlinger pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-tamaya-extensions.git


The following commit(s) were added to refs/heads/master by this push:
     new 1aea57f  TAMAYA-386 Move the distributed example to extensions
     new d1b302b  Merge pull request #38 from peculater/TAMAYA-386-example-to-extensions
1aea57f is described below

commit 1aea57f6885d7170e51cdc9319afe8de52efe70a
Author: William Lieurance <wi...@namikoda.com>
AuthorDate: Fri Jun 7 01:18:54 2019 -0500

    TAMAYA-386 Move the distributed example to extensions
---
 .travis.yml                                        |   4 +-
 examples/06-distributed/pom.xml                    | 154 +++++++++++
 .../examples/distributed/ContentManagerPanel.java  | 124 +++++++++
 .../tamaya/examples/distributed/Display.java       | 301 +++++++++++++++++++++
 .../examples/distributed/DisplayContent.java       |  63 +++++
 .../examples/distributed/DisplayManager.java       | 280 +++++++++++++++++++
 .../examples/distributed/DisplayRegistration.java  | 126 +++++++++
 .../services/org.apache.tamaya.spi.PropertySource  |  19 ++
 .../src/main/resources/stylesheet.css              |  56 ++++
 .../examples/distributed/DisplayContentTest.java   |  48 ++++
 .../distributed/DisplayRegistrationTest.java       |  70 +++++
 examples/pom.xml                                   |   1 +
 12 files changed, 1245 insertions(+), 1 deletion(-)

diff --git a/.travis.yml b/.travis.yml
index 2f10f60..2edee3e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,5 @@
 language: java
-dist: trusty
+dist: xenial
 sudo: required
 
 addons:
@@ -10,6 +10,8 @@ jobs:
     include:
         - name: "Java 8"
           jdk: openjdk8
+          before_install:
+            - sudo apt-get install -y openjfx
           script: mvn clean install
           after_success: mvn sonar:sonar -Dsonar.organization=apache -Dsonar.projectKey=apache_incubator-tamaya-extensions
 
diff --git a/examples/06-distributed/pom.xml b/examples/06-distributed/pom.xml
new file mode 100644
index 0000000..9909cc4
--- /dev/null
+++ b/examples/06-distributed/pom.xml
@@ -0,0 +1,154 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~  or more contributor license agreements.  See the NOTICE file
+  ~  distributed with this work for additional information
+  ~  regarding copyright ownership.  The ASF licenses this file
+  ~  to you under the Apache License, Version 2.0 (the
+  ~  "License"); you may not use this file except in compliance
+  ~  with the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~  Unless required by applicable law or agreed to in writing,
+  ~  software distributed under the License is distributed on an
+  ~  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~  KIND, either express or implied.  See the License for the
+  ~  specific language governing permissions and limitations
+  ~  under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.tamaya.ext.examples</groupId>
+        <artifactId>examples</artifactId>
+        <version>0.4-incubating-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>06-distributed-example</artifactId>
+    <name>Apache Tamaya Example: Distributed Configuration</name>
+    <description>This project contains a simple example based on JavaFX and VertX.</description>
+    <packaging>jar</packaging>
+
+    <properties>
+        <maven.compile.targetLevel>1.8</maven.compile.targetLevel>
+        <maven.compile.sourceLevel>1.8</maven.compile.sourceLevel>
+        <maven.compile.optimize>false</maven.compile.optimize>
+        <maven.compile.deprecation>true</maven.compile.deprecation>
+        <tamaya.version>0.4-incubating-SNAPSHOT</tamaya.version>
+        <vertx.version>3.5.4</vertx.version>
+        <junit.version>4.12</junit.version>
+        <javafx.version>11.0.2</javafx.version>
+
+        <!--
+         ! We don't want to deploy this example to Maven Central.
+         ! Oliver B. Fischer, 2017-05-21
+         !-->
+        <maven.deploy.skip>true</maven.deploy.skip>
+    </properties>
+
+    <dependencies>
+        <dependency>
+           <groupId>org.openjfx</groupId>
+           <artifactId>javafx-base</artifactId>
+           <version>${javafx.version}</version>
+       </dependency>
+        <dependency>
+           <groupId>org.openjfx</groupId>
+           <artifactId>javafx-controls</artifactId>
+           <version>${javafx.version}</version>
+       </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya</groupId>
+            <artifactId>tamaya-core</artifactId>
+            <version>${tamaya.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-injection-api</artifactId>
+            <version>${tamaya.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-injection</artifactId>
+            <version>${tamaya.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.vertx</groupId>
+            <artifactId>vertx-core</artifactId>
+            <version>${vertx.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-mutable-config</artifactId>
+            <version>${tamaya.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.vertx</groupId>
+            <artifactId>vertx-hazelcast</artifactId>
+            <version>${vertx.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tamaya.ext</groupId>
+            <artifactId>tamaya-hazelcast</artifactId>
+            <version>${tamaya.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <defaultGoal>clean install</defaultGoal>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <debug>true</debug>
+                    <optimize>${maven.compile.optimize}</optimize>
+                    <source>${maven.compile.sourceLevel}</source>
+                    <target>${maven.compile.targetLevel}</target>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                    <showDeprecation>${maven.compile.deprecation}</showDeprecation>
+                </configuration>
+            </plugin>
+             <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-checkstyle-plugin</artifactId>
+                    <version>${checkstyle.version}</version>
+                    <executions>
+                        <execution>
+                            <id>checkstyle</id>
+                            <phase>validate</phase>
+                            <goals>
+                                <goal>check</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                    <configuration>
+                        <logViolationsToConsole>true</logViolationsToConsole>
+                        <includeTestSourceDirectory>true</includeTestSourceDirectory>
+                        <suppressionsLocation>buildtools/src/main/resources/checkstyle/suppressions.xml</suppressionsLocation>
+                        <configLocation>buildtools/src/main/resources/checkstyle/style.xml</configLocation>
+                    </configuration>
+
+                    <dependencies>
+                        <dependency>
+                            <groupId>com.puppycrawl.tools</groupId>
+                            <artifactId>checkstyle</artifactId>
+                            <version>8.19</version>
+                        </dependency>
+                    </dependencies>
+                </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/examples/06-distributed/src/main/java/org/apache/tamaya/examples/distributed/ContentManagerPanel.java b/examples/06-distributed/src/main/java/org/apache/tamaya/examples/distributed/ContentManagerPanel.java
new file mode 100644
index 0000000..5972396
--- /dev/null
+++ b/examples/06-distributed/src/main/java/org/apache/tamaya/examples/distributed/ContentManagerPanel.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.tamaya.examples.distributed;
+
+import io.vertx.core.Vertx;
+import io.vertx.core.json.Json;
+import javafx.application.Platform;
+import javafx.geometry.Orientation;
+import javafx.scene.layout.VBox;
+import javafx.scene.text.Font;
+import javafx.scene.text.FontWeight;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.functions.ConfigurationFunctions;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import javafx.scene.control.Button;
+import javafx.scene.control.ChoiceBox;
+import javafx.scene.control.Label;
+import javafx.scene.control.Separator;
+import javafx.scene.control.TextArea;
+import javafx.scene.control.TextField;
+
+/**
+ * Created by atsticks on 13.11.16.
+ */
+class ContentManagerPanel extends VBox{
+
+    private ChoiceBox selector = new ChoiceBox();
+    private TextField titleField = new TextField();
+    private TextArea contentField = new TextArea();
+    private TextField displayNameField = new TextField();
+    private Button sendButton = new Button("Update Content");
+    private Configuration config;
+    private Vertx vertx;
+
+    public ContentManagerPanel(Vertx vertx){
+        this.vertx = vertx;
+        displayNameField.setMinHeight(30.0);
+        displayNameField.setMinWidth(200.0);
+        displayNameField.setId("displayNameField");
+        titleField.setMinHeight(30.0);
+        titleField.setMinWidth(200.0);
+        titleField.setId("title");
+        titleField.setFont(Font.font("Arial", FontWeight.BOLD, 24));
+        titleField.setStyle("-fx-text-fill: #EFEFEF; -fx-background-color: black;");
+        contentField.setId("scene");
+        contentField.setFont(Font.font("Arial", FontWeight.LIGHT, 18));
+        getChildren().addAll(selector, new Label("Title"), titleField, new Label("content"), contentField,
+                new Label("Display Name"), displayNameField, new Separator(Orientation.VERTICAL), sendButton);
+        sendButton.setOnAction(h -> {
+            String selection = (String)selector.getSelectionModel().getSelectedItem();
+            if(selection!=null){
+                String uuid = selection.split("::")[1];
+                DisplayContent content = new DisplayContent();
+                content.content.put(Display.CONTENT_FIELD, contentField.getText());
+                content.title = titleField.getText();
+                content.displayId = uuid;
+                content.displayName = displayNameField.getText();
+                vertx.eventBus().publish(Display.DISPLAY_SHOW_TOPIC, Json.encode(content));
+            }
+        });
+        selector.setOnAction(h -> {
+            String selection = (String)selector.getSelectionModel().getSelectedItem();
+            if(selection!=null) {
+                displayNameField.setText(selection.split("::")[0]);
+            }
+        });
+        updateList();
+        vertx.periodicStream(5000).handler(h -> {
+            updateList();
+        });
+    }
+
+    public void updateList(){
+        config = Configuration.current()
+                .map(ConfigurationFunctions.section("displays.", true));
+        // resulting config:
+        // -----------------
+        // UUID.displayName
+        // UUID.content.title
+        // UUID.content.content
+        // UUID.timestamp
+        final Set<String> keys = new TreeSet<>();
+        for(Map.Entry<String,String> en:config.getProperties().entrySet()){
+            if(en.getKey().endsWith(".displayName")){
+                String uuid = en.getKey().substring(0,36);
+                keys.add(en.getValue()+"::"+uuid);
+            }
+        }
+        Platform.runLater(() -> {
+            final Set<String> exKeys = new HashSet<String>(selector.getItems());
+            for(Object item:exKeys){
+                if(!keys.contains(item)){
+                    selector.getItems().remove(item);
+                }
+            }
+            for(String item:keys){
+                if(!selector.getItems().contains(item)){
+                    selector.getItems().add(item);
+                }
+            }
+        });
+    }
+}
diff --git a/examples/06-distributed/src/main/java/org/apache/tamaya/examples/distributed/Display.java b/examples/06-distributed/src/main/java/org/apache/tamaya/examples/distributed/Display.java
new file mode 100644
index 0000000..490def0
--- /dev/null
+++ b/examples/06-distributed/src/main/java/org/apache/tamaya/examples/distributed/Display.java
@@ -0,0 +1,301 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.examples.distributed;
+
+import io.vertx.core.Vertx;
+import io.vertx.core.VertxOptions;
+import io.vertx.core.json.Json;
+import io.vertx.core.spi.cluster.ClusterManager;
+import io.vertx.spi.cluster.hazelcast.HazelcastClusterManager;
+import javafx.application.Application;
+import javafx.application.Platform;
+import javafx.scene.Group;
+import javafx.scene.Node;
+import javafx.scene.Scene;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import javafx.stage.Stage;
+import org.apache.tamaya.spisupport.propertysource.EnvironmentPropertySource;
+import org.apache.tamaya.spisupport.propertysource.SystemPropertySource;
+import org.apache.tamaya.functions.ConfigurationFunctions;
+import org.apache.tamaya.hazelcast.HazelcastPropertySource;
+import org.apache.tamaya.inject.ConfigurationInjection;
+import org.apache.tamaya.inject.api.Config;
+
+import java.time.LocalDateTime;
+import java.util.logging.Logger;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.ScrollPane;
+import javafx.scene.control.Tab;
+import javafx.scene.control.TabPane;
+import javafx.scene.control.TextArea;
+import javafx.scene.control.TextField;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.spi.ConfigurationBuilder;
+
+/**
+ * Created by atsticks on 12.11.16.
+ */
+public class Display extends Application{
+
+    private static final Logger LOG = Logger.getLogger(Display.class.getSimpleName());
+
+    public static final String DISPLAY_SHOW_TOPIC = "Display::show";
+    public static final String DISPLAY_REGISTER_TOPIC = "Display::register";
+    public static final String CONTENT_FIELD = "content";
+
+    @Config(defaultValue="UNKNOWN DISPLAY")
+    private String displayName;
+
+    private Scene scene;
+
+    private Group root = new Group();
+
+    private Stage stage;
+
+    private TextField titleField = new TextField("title");
+
+    private TextField configFilterField = new TextField("");
+
+    private TextArea contentField = new TextArea("scene");
+
+    private TextArea monitorField = new TextArea("monitor");
+
+    private DisplayContent displayContent = new DisplayContent();
+
+    private DisplayRegistration registration;
+
+    private StringBuffer monitorBuffer = new StringBuffer();
+
+    private Vertx vertx;
+
+    private static HazelcastPropertySource hazelCastPropertySource;
+
+    public Display(){
+        LOG.info("\n-----------------------------------\n" +
+                "Starting Display...\n" +
+                "-----------------------------------");
+        LOG.info("--- Starting Vertx cluster...");
+        // Reusing the hazelcast instance already in place for vertx...
+        ClusterManager mgr = new HazelcastClusterManager(
+                hazelCastPropertySource.getHazelcastInstance());
+        VertxOptions vertxOptions = new VertxOptions().setClusterManager(mgr);
+        Vertx.clusteredVertx(vertxOptions, h -> {
+            vertx = h.result();
+        });
+        LOG.info("--- Waiting for Vertx cluster...");
+        while(vertx==null){
+            try {
+                Thread.sleep(100L);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+        titleField.getStyleClass().add("title");
+        contentField.getStyleClass().add("content");
+        monitorField.getStyleClass().add("monitor");
+        titleField.setId("title");
+        titleField.setEditable(false);
+        contentField.setId("scene");
+        contentField.setEditable(false);
+    }
+
+    @Override
+    public void start(Stage stage) throws Exception {
+        this.stage = stage;
+        LOG.info("--- Configuring application...");
+        ConfigurationInjection.getConfigurationInjector()
+                .configure(this);
+        LOG.info("--- Registering display...");
+        registerDisplay();
+        LOG.info("--- Starting stage...");
+        initStage(stage);
+        registerListeners();
+        LOG.info("--- Showing stage...");
+        stage.show();
+        LOG.info("\n---------------\n" +
+                 "Display started\n" +
+                 "---------------");
+    }
+
+    private void registerDisplay() {
+        registration = new DisplayRegistration(displayName);
+        logToMonitor("Display started at " + LocalDateTime.now() +
+                "\n  id   = " + registration.getId() +
+                "\n  name = " + registration.getDisplayName());
+        // Register in the shared map every 10 seconds, with a TTL of 20 seconds...
+        vertx.eventBus().publish(DISPLAY_REGISTER_TOPIC, Json.encode(registration));
+        vertx.periodicStream(10000).handler(time -> {
+            registration = registration.update();
+            vertx.eventBus().publish(DISPLAY_REGISTER_TOPIC, Json.encode(registration));
+            vertx.sharedData().getClusterWideMap("displays", h -> {
+                h.result().put(registration.getId(), registration, 20000L, null);
+            });
+        });
+    }
+
+    private void registerListeners() {
+        // registering update hook
+        vertx.eventBus().consumer(DISPLAY_SHOW_TOPIC, h -> {
+            DisplayContent content = Json.decodeValue((String)h.body(), DisplayContent.class);
+            logToMonitor("NEW CONTENT: " + content.toString());
+            if(registration.getId().equals(content.displayId)) {
+                logToMonitor("Applying content: " + content + "...");
+                titleField.setText(content.title);
+                contentField.setText(content.content.get(CONTENT_FIELD));
+                if(content.displayName!=null) {
+                    this.registration.setDisplayName(
+                            content.displayName
+                    );
+                    Platform.runLater(() -> {
+                        this.stage.setTitle(content.displayName);
+                    });
+                }
+                logToMonitor("SUCCESS.");
+            }
+        });
+        vertx.eventBus().consumer(DISPLAY_REGISTER_TOPIC, h -> {
+            DisplayRegistration thisRegistration = Json.decodeValue((String)h.body(), DisplayRegistration.class);
+            logToMonitor("NEW DISPLAY: " + thisRegistration.toString());
+        });
+    }
+
+    private void initStage(Stage stage) {
+        stage.setTitle(registration.getDisplayName());
+        scene = new Scene(root, Color.WHITE);
+        scene.getStylesheets().add("/stylesheet.css");
+
+        BorderPane layout = new BorderPane();
+        layout.getStyleClass().add("main-layout");
+        layout.setPrefSize(600, 400);
+//        layout.setTop(createWinTitle());
+
+        Node displayPanel = createDisplayNode();
+        Node monitorPanel = createMonitorNode();
+
+        TabPane tabPane = new TabPane();
+        tabPane.getStylesheets().add("main-tabs");
+        Tab tab0 = new Tab("Display", displayPanel);
+        tab0.setClosable(false);
+        Tab tab1 = new Tab("Monitor", monitorPanel);
+        tab1.setClosable(false);
+        tabPane.getTabs().add(0, tab0);
+        tabPane.getTabs().add(1, tab1);
+        layout.setCenter(tabPane);
+        layout.setBottom(createStatusPane());
+        scene.setRoot(layout);
+        stage.setScene(scene);
+    }
+
+    private Node createStatusPane() {
+        return new Label();
+    }
+
+    private Node createMonitorNode() {
+        VBox vbox = new VBox();
+        ScrollPane monitorPane = new ScrollPane(monitorField);
+        monitorPane.setFitToHeight(true);
+        monitorPane.setFitToWidth(true);
+        monitorField.setPrefSize(2000,2000);
+        vbox.getChildren().addAll(monitorPane);
+        return vbox;
+    }
+
+    private Node createDisplayNode() {
+        VBox vbox = new VBox();
+        ScrollPane contentPane = new ScrollPane(contentField);
+        contentPane.setFitToHeight(true);
+        contentPane.setFitToWidth(true);
+        titleField.setText("- Nothing to show -");
+        contentField.setText("- Nothing to show -");
+        vbox.getChildren().addAll(titleField, contentPane, createButtonPane());
+        return vbox;
+    }
+
+    private Pane createButtonPane() {
+        HBox buttonLayout = new HBox();
+        buttonLayout.getStyleClass().add("button-pane");
+        Button showConfig = new Button("Show Config");
+        showConfig.setId("showConfig-button");
+        showConfig.onActionProperty().set(h -> {
+            if("Hide Config".equals(showConfig.getText())){
+                monitorField.setText(monitorBuffer.toString());
+                showConfig.setText("Show Config");
+            }else {
+                showConfig();
+                showConfig.setText("Hide Config");
+            }
+        });
+        configFilterField.onActionProperty().set(h -> {
+            showConfig();
+        });
+        configFilterField.setId("configFilter-field");
+        buttonLayout.getChildren().addAll(showConfig, configFilterField);
+        return buttonLayout;
+    }
+
+    private void showConfig() {
+        String filter = configFilterField.getText();
+        String configAsText;
+        if(filter!=null && !filter.trim().isEmpty()){
+            configAsText = Configuration.current()
+                    .map(ConfigurationFunctions.section(filter))
+                    .adapt(ConfigurationFunctions.textInfo());
+        }else{
+            configAsText = Configuration.current()
+                    .adapt(ConfigurationFunctions.textInfo());
+        }
+        monitorField.setText(configAsText);
+    }
+
+    public static void main(String[] args) {
+        // Programmatically setup our configuration
+        hazelCastPropertySource = new HazelcastPropertySource();
+        
+        Configuration cfg = Configuration.current();
+        ConfigurationBuilder builder = Configuration.createConfigurationBuilder()
+                .setConfiguration(cfg);
+        Configuration built = builder.addPropertySources(
+                new EnvironmentPropertySource(),
+                new SystemPropertySource(),
+                hazelCastPropertySource
+        )
+                .addDefaultPropertyConverters()
+                .build();
+        Configuration.setCurrent(built);
+        // Launch the app
+        Application.launch(Display.class);
+    }
+
+
+    public void logToMonitor(String message){
+        if(!message.endsWith("\n")){
+            monitorBuffer.append(message + '\n');
+        }else{
+            monitorBuffer.append(message);
+        }
+        synchronized (monitorField) {
+            monitorField.setText(monitorBuffer.toString());
+        }
+    }
+}
diff --git a/examples/06-distributed/src/main/java/org/apache/tamaya/examples/distributed/DisplayContent.java b/examples/06-distributed/src/main/java/org/apache/tamaya/examples/distributed/DisplayContent.java
new file mode 100644
index 0000000..2a48630
--- /dev/null
+++ b/examples/06-distributed/src/main/java/org/apache/tamaya/examples/distributed/DisplayContent.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.tamaya.examples.distributed;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Created by atsticks on 13.11.16.
+ */
+public class DisplayContent {
+    public String displayId;
+    public String title = "UNKNOWN";
+    public Map<String,String> content = new HashMap<>();
+    public long timestamp = System.currentTimeMillis();
+    public String displayName;
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o){
+            return true;
+        }
+        if (!(o instanceof DisplayContent)){
+            return false;
+        }
+        DisplayContent that = (DisplayContent) o;
+        return timestamp == that.timestamp &&
+                Objects.equals(displayId, that.displayId) &&
+                Objects.equals(title, that.title);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(displayId, title, timestamp);
+    }
+
+    @Override
+    public String toString() {
+        return "DisplayContent{" +
+                "displayId='" + displayId + '\'' +
+                ", title='" + title + '\'' +
+                ", content=" + content +
+                '}';
+    }
+}
diff --git a/examples/06-distributed/src/main/java/org/apache/tamaya/examples/distributed/DisplayManager.java b/examples/06-distributed/src/main/java/org/apache/tamaya/examples/distributed/DisplayManager.java
new file mode 100644
index 0000000..51770bc
--- /dev/null
+++ b/examples/06-distributed/src/main/java/org/apache/tamaya/examples/distributed/DisplayManager.java
@@ -0,0 +1,280 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.tamaya.examples.distributed;
+
+import io.vertx.core.Vertx;
+import io.vertx.core.VertxOptions;
+import io.vertx.core.json.Json;
+import io.vertx.core.spi.cluster.ClusterManager;
+import io.vertx.spi.cluster.hazelcast.HazelcastClusterManager;
+import javafx.application.Application;
+import javafx.scene.Group;
+import javafx.scene.Node;
+import javafx.scene.Scene;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import javafx.stage.Stage;
+import org.apache.tamaya.spisupport.propertysource.EnvironmentPropertySource;
+import org.apache.tamaya.spisupport.propertysource.SystemPropertySource;
+import org.apache.tamaya.functions.ConfigurationFunctions;
+import org.apache.tamaya.hazelcast.HazelcastPropertySource;
+import org.apache.tamaya.inject.ConfigurationInjector;
+import org.apache.tamaya.mutableconfig.MutableConfiguration;
+
+import java.util.logging.Logger;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.ScrollPane;
+import javafx.scene.control.Tab;
+import javafx.scene.control.TabPane;
+import javafx.scene.control.TextArea;
+import javafx.scene.control.TextField;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.spi.ConfigurationBuilder;
+
+/**
+ * Created by atsticks on 12.11.16.
+ */
+public class DisplayManager extends Application{
+
+    private static final Logger LOG = Logger.getLogger(DisplayManager.class.getSimpleName());
+
+    public static final String DISPLAY_SHOW_TOPIC = "Display::show";
+    public static final String DISPLAY_REGISTER_TOPIC = "Display::register";
+    public static final String CONTENT_FIELD = "content";
+
+    private Scene scene;
+
+    private Group root = new Group();
+
+    private TextField configFilterField = new TextField("");
+
+    private TextArea configField = new TextArea();
+
+    private TextArea monitorField = new TextArea("Nothing to monitor yet.");
+
+    private StringBuffer monitorBuffer = new StringBuffer();
+
+    private Vertx vertx;
+
+    private static HazelcastPropertySource hazelCastPropertySource;
+
+    public DisplayManager(){
+        LOG.info("\n-----------------------------------\n" +
+                "Starting DisplayDisplayManager...\n" +
+                "-----------------------------------");
+        LOG.info("--- Starting Vertx cluster...");
+        // Reusing the hazelcast instance already in place for vertx...
+        ClusterManager mgr = new HazelcastClusterManager(
+                hazelCastPropertySource.getHazelcastInstance());
+        VertxOptions vertxOptions = new VertxOptions().setClusterManager(mgr);
+        Vertx.clusteredVertx(vertxOptions, h -> {
+            vertx = h.result();
+        });
+        LOG.info("--- Waiting for Vertx cluster...");
+        while(vertx==null){
+            try {
+                Thread.sleep(100L);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+        monitorField.getStyleClass().add("monitor");
+        configField.getStyleClass().add("config");
+    }
+
+    @Override
+    public void start(Stage stage) throws Exception {
+        LOG.info("--- Configuring application...");
+        ConfigurationInjector.getInstance()
+                .configure(this);
+        LOG.info("--- Starting stage...");
+        initStage(stage);
+        registerListeners();
+        LOG.info("--- Showing stage...");
+        stage.show();
+        LOG.info("\n----------------------\n" +
+                 "DisplayManager started\n" +
+                 "----------------------");
+    }
+
+    private void registerListeners() {
+        // registering update hook
+        vertx.eventBus().consumer(DISPLAY_SHOW_TOPIC, h -> {
+            DisplayContent content = Json.decodeValue((String)h.body(), DisplayContent.class);
+            logToMonitor("NEW CONTENT: " + content.toString());
+            logToMonitor("Updating config for content: " + content + "...");
+            MutableConfiguration config = MutableConfiguration.create();
+            String id = content.displayId;
+            config.put("displays."+id+".title", content.title);
+            config.put("displays."+id+".timestamp", String.valueOf(content.timestamp));
+            config.put("displays."+id+".content.content", content.content.get(CONTENT_FIELD));
+            config.store();
+            logToMonitor("UPDATED.");
+        });
+        vertx.eventBus().consumer(DISPLAY_REGISTER_TOPIC, h -> {
+            DisplayRegistration registration = Json.decodeValue((String)h.body(), DisplayRegistration.class);
+            if(registration.isUpdate()){
+                logToMonitor("UDT DISPLAY: " + registration.getId());
+            }else{
+                logToMonitor("NEW DISPLAY: " + registration.toString());
+            }
+            MutableConfiguration config = MutableConfiguration.create();
+            String id = registration.getId();
+            config.put("displays."+id+".displayName", registration.getDisplayName());
+            config.put("_displays."+id+".displayName.ttl", "10000");
+            if(registration.getHost()!=null) {
+                config.put("displays." + id + ".host", registration.getHost());
+                config.put("_displays." + id + ".host.ttl", "10000");
+            }
+            config.put("displays."+id+".displayModel", registration.getDisplayModel());
+            config.put("_displays."+id+".displayModel.ttl", "10000");
+            config.store();
+            logToMonitor("UPDATED.");
+        });
+    }
+
+    private void initStage(Stage stage) {
+        stage.setTitle("Display Manager");
+        scene = new Scene(root, Color.RED);
+        scene.getStylesheets().add("/stylesheet.css");
+
+        BorderPane layout = new BorderPane();
+        layout.getStyleClass().add("main-layout");
+//        layout.setPrefSize(600, 400);
+//        layout.setTop(createWinTitle());
+
+        Node configPanel = createConfigNode();
+        Node monitorPanel = createMonitorNode();
+
+        TabPane tabPane = new TabPane();
+        tabPane.getStylesheets().add("main-tabs");
+        Tab tab0 = new Tab("Monitor", monitorPanel);
+        tab0.setClosable(false);
+        Tab tab1 = new Tab("Configuration", configPanel);
+        tab1.setClosable(false);
+        Tab tab2 = new Tab("Content Manager", new ContentManagerPanel(vertx));
+        tab2.setClosable(false);
+        tabPane.getTabs().add(0, tab0);
+        tabPane.getTabs().add(1, tab1);
+        tabPane.getTabs().add(2, tab2);
+        layout.setCenter(tabPane);
+        layout.setBottom(createStatusPane());
+        scene.setRoot(layout);
+        stage.setScene(scene);
+    }
+
+    private Node createStatusPane() {
+        return new Label();
+    }
+
+    private Node createMonitorNode() {
+        VBox vbox = new VBox();
+        ScrollPane monitorPane = new ScrollPane(monitorField);
+        monitorPane.setFitToHeight(true);
+        monitorPane.setFitToWidth(true);
+        monitorField.setPrefSize(2000,2000);
+        vbox.getChildren().addAll(monitorPane);
+        return vbox;
+    }
+
+    private Node createConfigNode() {
+        VBox vbox = new VBox();
+        ScrollPane contentPane = new ScrollPane(configField);
+        contentPane.setFitToHeight(true);
+        contentPane.setFitToWidth(true);
+        configField.setPrefSize(2000,2000);
+        vbox.getChildren().addAll(contentPane, createButtonPane());
+        return vbox;
+    }
+
+    private Node createWinTitle() {
+        Label winTitle = new Label();
+        winTitle.setMinHeight(30.0);
+        winTitle.setMinWidth(200.0);
+        winTitle.setId("wintitle");
+        winTitle.setText("Tamaya Config Demo - DisplayManager");
+        return winTitle;
+    }
+
+    private Pane createButtonPane() {
+        HBox buttonLayout = new HBox();
+        buttonLayout.getStyleClass().add("button-pane");
+        Button refreshConfig = new Button("Refresh Config");
+        refreshConfig.setId("refreshConfig-button");
+        refreshConfig.onActionProperty().set(h -> {
+                showConfig();
+            });
+        configFilterField.onActionProperty().set(h -> {
+            showConfig();
+        });
+        configFilterField.setId("configFilter-field");
+        buttonLayout.getChildren().addAll(refreshConfig, configFilterField);
+        return buttonLayout;
+    }
+
+    private void showConfig() {
+        String filter = configFilterField.getText();
+        String configAsText;
+        if(filter!=null && !filter.trim().isEmpty()){
+            configAsText = Configuration.current()
+                    .map(ConfigurationFunctions.section(filter))
+                    .adapt(ConfigurationFunctions.textInfo());
+        }else{
+            configAsText = Configuration.current()
+                    .adapt(ConfigurationFunctions.textInfo());
+        }
+        configField.setText(configAsText);
+    }
+
+    public void logToMonitor(String message){
+        if(!message.endsWith("\n")){
+            monitorBuffer.append(message).append('\n');
+        }else{
+            monitorBuffer.append(message);
+        }
+        synchronized (monitorField) {
+            monitorField.setText(monitorBuffer.toString());
+        }
+    }
+
+    public static void main(String[] args) {
+        // Programmatically setup our configuration
+        hazelCastPropertySource = new HazelcastPropertySource();
+        Configuration cfg = Configuration.current();
+        ConfigurationBuilder builder = Configuration.createConfigurationBuilder()
+                .setConfiguration(cfg);
+        Configuration built = builder.addPropertySources(
+                        new EnvironmentPropertySource(),
+                        new SystemPropertySource(),
+                        hazelCastPropertySource
+                        )
+                .addDefaultPropertyConverters()
+                .build();
+         Configuration.setCurrent(built);
+        // Launch the app
+        Application.launch(DisplayManager.class);
+    }
+
+
+
+}
diff --git a/examples/06-distributed/src/main/java/org/apache/tamaya/examples/distributed/DisplayRegistration.java b/examples/06-distributed/src/main/java/org/apache/tamaya/examples/distributed/DisplayRegistration.java
new file mode 100644
index 0000000..d7354ba
--- /dev/null
+++ b/examples/06-distributed/src/main/java/org/apache/tamaya/examples/distributed/DisplayRegistration.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.tamaya.examples.distributed;
+
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.util.Objects;
+import java.util.UUID;
+
+/**
+ * Created by atsticks on 13.11.16.
+ */
+public class DisplayRegistration implements Serializable{
+
+    private static final long serialVersionUID = 1L;
+
+    private String id;
+    private String displayName;
+    private String host;
+    private String displayModel;
+    private boolean update;
+    private long timestamp = System.currentTimeMillis();
+
+    private DisplayRegistration(){}
+
+    public DisplayRegistration(String displayName) {
+        this.displayName = Objects.requireNonNull(displayName);
+        this.displayModel = "fxDemo";
+
+        this.id = UUID.randomUUID().toString();
+    }
+
+    public DisplayRegistration(String displayName, String displayModel) {
+        this.displayModel = Objects.requireNonNull(displayModel);
+        this.displayName = Objects.requireNonNull(displayName);
+        this.id = UUID.randomUUID().toString();
+        InetAddress adr = null;
+        try {
+            adr = InetAddress.getLocalHost();
+            this.host = adr.getCanonicalHostName();
+        } catch(Exception e){
+            this.host = adr.getHostName();
+        }
+    }
+
+    public boolean isUpdate(){
+        return this.update;
+    }
+
+    public String getDisplayModel() {
+        return displayModel;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public String getHost() {
+        return host;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o){
+            return true;
+        }
+        if (!(o instanceof DisplayRegistration)){
+            return false;
+        }
+        DisplayRegistration that = (DisplayRegistration) o;
+        return Objects.equals(getId(), that.getId());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getId());
+    }
+
+    @Override
+    public String toString() {
+        return "DisplayRegistration{" +
+                "\n  id='" + id + '\'' +
+                "\n  displayName='" + displayName + '\'' +
+                "\n  host='" + host + '\'' +
+                "\n  displayModel='" + displayModel + '\'' +
+                "\n  timestamp='" + timestamp + '\'' +
+                "\n  update='" + update + '\'' +
+                "\n}";
+    }
+
+    public DisplayRegistration update() {
+        DisplayRegistration reg = new DisplayRegistration();
+        reg.displayModel = this.displayModel;
+        reg.displayName = this.displayName;
+        reg.host = this.host;
+        reg.id = this.id;
+        reg.update = true;
+        reg.timestamp = System.currentTimeMillis();
+        return reg;
+    }
+
+    public void setDisplayName(String displayName) {
+        this.displayName = Objects.requireNonNull(displayName);
+    }
+}
diff --git a/examples/06-distributed/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertySource b/examples/06-distributed/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
new file mode 100644
index 0000000..a2a4042
--- /dev/null
+++ b/examples/06-distributed/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy current the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+#org.apache.tamaya.examples.remote.client.RemotePropertySource
\ No newline at end of file
diff --git a/examples/06-distributed/src/main/resources/stylesheet.css b/examples/06-distributed/src/main/resources/stylesheet.css
new file mode 100644
index 0000000..ac00f5c
--- /dev/null
+++ b/examples/06-distributed/src/main/resources/stylesheet.css
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+.text{
+   -fx-font: bold 12pt "Arial";
+   -fx-background-color: light-grey;
+}
+.button{
+    -fx-font: bold 12pt "Arial";
+    -fx-text-fill: rgb(49, 89, 23);
+    -fx-border-color: rgb(49, 89, 23);
+    -fx-border-radius: 5;
+    -fx-padding: 3 6 6 6;
+}
+#wintitle{
+  -fx-font: bold 36pt "Arial";
+  -fx-text-fill: #FFBDBD;
+  -fx-background-color: black;
+}
+.main-layout{
+    -fx-width: 100%;
+    -fx-height: 100%;
+}
+.title{
+    -fx-font: bold 24pt "Arial";
+    -fx-text-fill: #EFEFEF;
+    -fx-background-color: light-grey;
+    -fx-text-fill: rgb(49, 89, 23);
+    -fx-border-color: rgb(49, 89, 23);
+    -fx-border-size: 0;
+    -fx-border-radius: 3;
+    -fx-padding: 3 6 6 6;
+    -fx-min-height: 40;
+    -fx-min-width: 200;
+}
+.content{
+    -fx-font: bold 18pt "Arial";
+}
+.monitor{
+    -fx-font: bold 16pt "Courier New";
+}
\ No newline at end of file
diff --git a/examples/06-distributed/src/test/java/org/apache/tamaya/examples/distributed/DisplayContentTest.java b/examples/06-distributed/src/test/java/org/apache/tamaya/examples/distributed/DisplayContentTest.java
new file mode 100644
index 0000000..b052cc1
--- /dev/null
+++ b/examples/06-distributed/src/test/java/org/apache/tamaya/examples/distributed/DisplayContentTest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.tamaya.examples.distributed;
+
+import io.vertx.core.json.Json;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Created by atsticks on 13.11.16.
+ */
+public class DisplayContentTest {
+
+    @org.junit.Test
+    public void testToString() throws Exception {
+
+    }
+
+    @org.junit.Test
+    public void testJson() throws Exception {
+        DisplayContent content = new DisplayContent();
+        content.displayId = "1234";
+        content.title = "myTitle";
+        content.content.put("content", "myContent");
+        String val = Json.encode(content);
+        DisplayContent decoded = Json.decodeValue(val, DisplayContent.class);
+        assertThat(decoded).isNotNull();
+        assertThat(decoded).isEqualTo(content);
+    }
+
+}
\ No newline at end of file
diff --git a/examples/06-distributed/src/test/java/org/apache/tamaya/examples/distributed/DisplayRegistrationTest.java b/examples/06-distributed/src/test/java/org/apache/tamaya/examples/distributed/DisplayRegistrationTest.java
new file mode 100644
index 0000000..ae2aeb2
--- /dev/null
+++ b/examples/06-distributed/src/test/java/org/apache/tamaya/examples/distributed/DisplayRegistrationTest.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.tamaya.examples.distributed;
+
+import io.vertx.core.json.Json;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Created by atsticks on 13.11.16.
+ */
+public class DisplayRegistrationTest {
+    @Test
+    public void getDisplayModel() throws Exception {
+
+    }
+
+    @Test
+    public void getDisplayName() throws Exception {
+
+    }
+
+    @Test
+    public void getHost() throws Exception {
+
+    }
+
+    @Test
+    public void getId() throws Exception {
+
+    }
+
+    @Test
+    public void testEquals() throws Exception {
+
+    }
+
+    @Test
+    public void testToString() throws Exception {
+
+    }
+
+    @org.junit.Test
+    public void testJson() throws Exception {
+        DisplayRegistration reg = new DisplayRegistration("myDisplay", "VT100");
+        String val = Json.encode(reg);
+        DisplayRegistration decoded = Json.decodeValue(val, DisplayRegistration.class);
+        assertThat(decoded).isNotNull();
+        assertThat(decoded).isEqualTo(reg);
+    }
+
+}
\ No newline at end of file
diff --git a/examples/pom.xml b/examples/pom.xml
index 551df9b..87de37f 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -41,6 +41,7 @@ under the License.
         <module>03-injection-example</module>
         <module>04-events-example</module>
         <module>05-spring-example</module>
+        <module>06-distributed</module>
     </modules>
 
 </project>