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>