You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by an...@apache.org on 2016/11/13 22:28:44 UTC
[4/4] incubator-tamaya git commit: TAMAYA-195: Added hazelcast
support (small multi VM JavaFX Demo).
TAMAYA-195: Added hazelcast support (small multi VM JavaFX Demo).
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/57df9012
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/57df9012
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/57df9012
Branch: refs/heads/master
Commit: 57df9012d1ef6e736b925a41df2c2c60fe460110
Parents: fcf2730
Author: anatole <an...@apache.org>
Authored: Sun Nov 13 23:27:18 2016 +0100
Committer: anatole <an...@apache.org>
Committed: Sun Nov 13 23:27:18 2016 +0100
----------------------------------------------------------------------
examples/11-distributed/pom.xml | 85 ++++++
.../distributed/ContentManagerPanel.java | 122 ++++++++
.../tamaya/examples/distributed/Display.java | 293 +++++++++++++++++++
.../examples/distributed/DisplayContent.java | 59 ++++
.../examples/distributed/DisplayManager.java | 276 +++++++++++++++++
.../distributed/DisplayRegistration.java | 123 ++++++++
.../org.apache.tamaya.spi.PropertySource | 19 ++
.../src/main/resources/stylesheet.css | 38 +++
.../distributed/DisplayContentTest.java | 48 +++
.../distributed/DisplayRegistrationTest.java | 70 +++++
10 files changed, 1133 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/57df9012/examples/11-distributed/pom.xml
----------------------------------------------------------------------
diff --git a/examples/11-distributed/pom.xml b/examples/11-distributed/pom.xml
new file mode 100644
index 0000000..5c5b8d3
--- /dev/null
+++ b/examples/11-distributed/pom.xml
@@ -0,0 +1,85 @@
+<!--
+ ~ 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</groupId>
+ <artifactId>tamaya-examples</artifactId>
+ <version>0.3-incubating-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <artifactId>tamaya-example-distributed</artifactId>
+ <groupId>org.apache.tamaya.examples</groupId>
+ <name>Apache Tamaya Example: Distributed Configuration</name>
+ <description>This project contains a simple example based on JavaFX and Vertx.</description>
+ <packaging>jar</packaging>
+
+ <properties>
+ <jdkVersion>1.8</jdkVersion>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tamaya</groupId>
+ <artifactId>tamaya-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-injection-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-injection</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.vertx</groupId>
+ <artifactId>vertx-core</artifactId>
+ <version>3.2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-mutable-config</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.vertx</groupId>
+ <artifactId>vertx-hazelcast</artifactId>
+ <version>3.3.3</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-hazelcast</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>java-hamcrest</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/57df9012/examples/11-distributed/src/main/java/org/apache/tamaya/examples/distributed/ContentManagerPanel.java
----------------------------------------------------------------------
diff --git a/examples/11-distributed/src/main/java/org/apache/tamaya/examples/distributed/ContentManagerPanel.java b/examples/11-distributed/src/main/java/org/apache/tamaya/examples/distributed/ContentManagerPanel.java
new file mode 100644
index 0000000..9ac7aeb
--- /dev/null
+++ b/examples/11-distributed/src/main/java/org/apache/tamaya/examples/distributed/ContentManagerPanel.java
@@ -0,0 +1,122 @@
+/*
+ * 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 com.sun.deploy.uitoolkit.impl.fx.ui.FXAppContext;
+import io.vertx.core.Vertx;
+import io.vertx.core.json.Json;
+import javafx.application.Platform;
+import javafx.embed.swing.SwingFXUtils;
+import javafx.geometry.Orientation;
+import javafx.scene.control.*;
+import javafx.scene.layout.VBox;
+import javafx.scene.text.Font;
+import javafx.scene.text.FontWeight;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.functions.ConfigurationFunctions;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * 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 = ConfigurationProvider.getConfiguration()
+ .with(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);
+ }
+ }
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/57df9012/examples/11-distributed/src/main/java/org/apache/tamaya/examples/distributed/Display.java
----------------------------------------------------------------------
diff --git a/examples/11-distributed/src/main/java/org/apache/tamaya/examples/distributed/Display.java b/examples/11-distributed/src/main/java/org/apache/tamaya/examples/distributed/Display.java
new file mode 100644
index 0000000..fb95a07
--- /dev/null
+++ b/examples/11-distributed/src/main/java/org/apache/tamaya/examples/distributed/Display.java
@@ -0,0 +1,293 @@
+/*
+ * 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.control.*;
+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.ConfigurationProvider;
+import org.apache.tamaya.core.propertysource.EnvironmentPropertySource;
+import org.apache.tamaya.core.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 org.apache.tamaya.spi.*;
+
+import java.time.LocalDateTime;
+import java.util.logging.Logger;
+
+/**
+ * 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 registration = Json.decodeValue((String)h.body(), DisplayRegistration.class);
+ logToMonitor("NEW DISPLAY: " + registration.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 = null;
+ if(filter!=null && !filter.trim().isEmpty()){
+ configAsText = ConfigurationProvider.getConfiguration()
+ .with(ConfigurationFunctions.section(filter))
+ .query(ConfigurationFunctions.textInfo());
+ }else{
+ configAsText = ConfigurationProvider.getConfiguration()
+ .query(ConfigurationFunctions.textInfo());
+ }
+ monitorField.setText(configAsText);
+ }
+
+ public static void main(String[] args) {
+ // Programmatically setup our configuration
+ hazelCastPropertySource = new HazelcastPropertySource();
+ ConfigurationContext ctx = ConfigurationProvider.getConfigurationContextBuilder()
+ .addPropertySources(
+ new EnvironmentPropertySource(),
+ new SystemPropertySource(),
+ hazelCastPropertySource
+ )
+ .addDefaultPropertyConverters()
+ .build();
+ ConfigurationProvider.setConfiguration(
+ ConfigurationProvider.createConfiguration(ctx));
+ // 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());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/57df9012/examples/11-distributed/src/main/java/org/apache/tamaya/examples/distributed/DisplayContent.java
----------------------------------------------------------------------
diff --git a/examples/11-distributed/src/main/java/org/apache/tamaya/examples/distributed/DisplayContent.java b/examples/11-distributed/src/main/java/org/apache/tamaya/examples/distributed/DisplayContent.java
new file mode 100644
index 0000000..18ba302
--- /dev/null
+++ b/examples/11-distributed/src/main/java/org/apache/tamaya/examples/distributed/DisplayContent.java
@@ -0,0 +1,59 @@
+/*
+ * 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 +
+ '}';
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/57df9012/examples/11-distributed/src/main/java/org/apache/tamaya/examples/distributed/DisplayManager.java
----------------------------------------------------------------------
diff --git a/examples/11-distributed/src/main/java/org/apache/tamaya/examples/distributed/DisplayManager.java b/examples/11-distributed/src/main/java/org/apache/tamaya/examples/distributed/DisplayManager.java
new file mode 100644
index 0000000..efd200b
--- /dev/null
+++ b/examples/11-distributed/src/main/java/org/apache/tamaya/examples/distributed/DisplayManager.java
@@ -0,0 +1,276 @@
+/*
+ * 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.control.*;
+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.scene.text.Font;
+import javafx.scene.text.FontWeight;
+import javafx.stage.Stage;
+import org.apache.tamaya.ConfigurationProvider;
+import org.apache.tamaya.core.propertysource.EnvironmentPropertySource;
+import org.apache.tamaya.core.propertysource.SystemPropertySource;
+import org.apache.tamaya.functions.ConfigurationFunctions;
+import org.apache.tamaya.hazelcast.HazelcastPropertySource;
+import org.apache.tamaya.inject.ConfigurationInjection;
+import org.apache.tamaya.mutableconfig.MutableConfiguration;
+import org.apache.tamaya.mutableconfig.MutableConfigurationProvider;
+import org.apache.tamaya.spi.ConfigurationContext;
+
+import java.util.logging.Logger;
+
+/**
+ * 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...");
+ ConfigurationInjection.getConfigurationInjector()
+ .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 = MutableConfigurationProvider.createMutableConfiguration();
+ 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 = MutableConfigurationProvider.createMutableConfiguration();
+ 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 = null;
+ if(filter!=null && !filter.trim().isEmpty()){
+ configAsText = ConfigurationProvider.getConfiguration()
+ .with(ConfigurationFunctions.section(filter))
+ .query(ConfigurationFunctions.textInfo());
+ }else{
+ configAsText = ConfigurationProvider.getConfiguration()
+ .query(ConfigurationFunctions.textInfo());
+ }
+ configField.setText(configAsText);
+ }
+
+ public void logToMonitor(String message){
+ if(!message.endsWith("\n")){
+ monitorBuffer.append(message + '\n');
+ }else{
+ monitorBuffer.append(message);
+ }
+ synchronized (monitorField) {
+ monitorField.setText(monitorBuffer.toString());
+ }
+ }
+
+ public static void main(String[] args) {
+ // Programmatically setup our configuration
+ hazelCastPropertySource = new HazelcastPropertySource();
+ ConfigurationContext ctx = ConfigurationProvider.getConfigurationContextBuilder()
+ .addPropertySources(
+ new EnvironmentPropertySource(),
+ new SystemPropertySource(),
+ hazelCastPropertySource
+ )
+ .addDefaultPropertyConverters()
+ .build();
+ ConfigurationProvider.setConfiguration(
+ ConfigurationProvider.createConfiguration(ctx));
+ // Launch the app
+ Application.launch(DisplayManager.class);
+ }
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/57df9012/examples/11-distributed/src/main/java/org/apache/tamaya/examples/distributed/DisplayRegistration.java
----------------------------------------------------------------------
diff --git a/examples/11-distributed/src/main/java/org/apache/tamaya/examples/distributed/DisplayRegistration.java b/examples/11-distributed/src/main/java/org/apache/tamaya/examples/distributed/DisplayRegistration.java
new file mode 100644
index 0000000..a2a181e
--- /dev/null
+++ b/examples/11-distributed/src/main/java/org/apache/tamaya/examples/distributed/DisplayRegistration.java
@@ -0,0 +1,123 @@
+/*
+ * 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);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/57df9012/examples/11-distributed/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
----------------------------------------------------------------------
diff --git a/examples/11-distributed/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertySource b/examples/11-distributed/src/main/resources/META-INF/services/org.apache.tamaya.spi.PropertySource
new file mode 100644
index 0000000..a2a4042
--- /dev/null
+++ b/examples/11-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
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/57df9012/examples/11-distributed/src/main/resources/stylesheet.css
----------------------------------------------------------------------
diff --git a/examples/11-distributed/src/main/resources/stylesheet.css b/examples/11-distributed/src/main/resources/stylesheet.css
new file mode 100644
index 0000000..2eb6c4f
--- /dev/null
+++ b/examples/11-distributed/src/main/resources/stylesheet.css
@@ -0,0 +1,38 @@
+.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
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/57df9012/examples/11-distributed/src/test/java/org/apache/tamaya/examples/distributed/DisplayContentTest.java
----------------------------------------------------------------------
diff --git a/examples/11-distributed/src/test/java/org/apache/tamaya/examples/distributed/DisplayContentTest.java b/examples/11-distributed/src/test/java/org/apache/tamaya/examples/distributed/DisplayContentTest.java
new file mode 100644
index 0000000..bf92e88
--- /dev/null
+++ b/examples/11-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.junit.Assert.*;
+
+/**
+ * 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);
+ assertNotNull(decoded);
+ assertEquals(content, decoded);
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/57df9012/examples/11-distributed/src/test/java/org/apache/tamaya/examples/distributed/DisplayRegistrationTest.java
----------------------------------------------------------------------
diff --git a/examples/11-distributed/src/test/java/org/apache/tamaya/examples/distributed/DisplayRegistrationTest.java b/examples/11-distributed/src/test/java/org/apache/tamaya/examples/distributed/DisplayRegistrationTest.java
new file mode 100644
index 0000000..c23728d
--- /dev/null
+++ b/examples/11-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.junit.Assert.*;
+
+/**
+ * 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);
+ assertNotNull(decoded);
+ assertEquals(reg, decoded);
+ }
+
+}
\ No newline at end of file