Przeglądaj źródła

Merge branch 'dev' of github.com:emqtt/emqttd into dev

huangdan 10 lat temu
rodzic
commit
90b0835950

+ 6 - 0
CHANGELOG.md

@@ -2,6 +2,12 @@
 emqttd ChangeLog
 ==================
 
+0.7.1-alpha (2015-05-04)
+-------------------------
+
+Add doc/design/* and merge doc/* to github Wiki
+
+
 0.7.0-alpha (2015-05-02)
 -------------------------
 

+ 15 - 0
Makefile

@@ -38,3 +38,18 @@ plugins:
 
 dist: rel plugins
 
+PLT  = $(BASE_DIR)/.emqttd_dialyzer.plt
+APPS = erts kernel stdlib sasl crypto ssl os_mon syntax_tools \
+	   public_key mnesia inets compiler
+
+check_plt: compile
+	dialyzer --check_plt --plt $(PLT) --apps $(APPS) \
+		deps/*/ebin apps/*/ebin
+
+build_plt: compile
+	dialyzer --build_plt --output_plt $(PLT) --apps $(APPS) \
+		deps/*/ebin apps/*/ebin
+
+dialyzer: compile
+	dialyzer -Wno_return --plt $(PLT) deps/*/ebin apps/*/ebin
+

+ 26 - 9
README.md

@@ -5,15 +5,18 @@ emqttd is a massively scalable and clusterable MQTT V3.1/V3.1.1 broker written i
 
 emqttd requires Erlang R17+ to build.
 
+
 ## Goals
 
-emqttd aims to provide a solid, enterprise grade open-source MQTT broker that could support ten millions of concurrent MQTT clients.
+emqttd is aimed to provide a solid, enterprise grade, extensible open-source MQTT broker for IoT(M2M) applications that need to support ten millions of concurrent MQTT clients.
 
-## Architecture
+* Easy to install
+* Massively scalable
+* Easy to extend
+* Solid stable
 
-![emqttd architecture](http://emqtt.io/static/img/Architecture.png)
 
-## Featues
+## Features
 
 * Full MQTT V3.1/V3.1.1 protocol specification support
 * QoS0, QoS1, QoS2 Publish and Subscribe
@@ -25,7 +28,7 @@ emqttd aims to provide a solid, enterprise grade open-source MQTT broker that co
 * HTTP Publish API Support
 * [$SYS/borkers/#](https://github.com/emqtt/emqtt/wiki/$SYS-Topics-of-Broker) Support
 * Client Authentication with clientId, ipaddress
-* Client Authentication with  username, password.
+* Client Authentication with username, password.
 * Client ACL control with ipaddress, clientid, username.
 * Cluster brokers on several servers.
 * Bridge brokers locally or remotelly
@@ -33,11 +36,19 @@ emqttd aims to provide a solid, enterprise grade open-source MQTT broker that co
 * Extensible architecture with plugin support
 * Passed eclipse paho interoperability tests
 
+
+## Design
+
+![emqttd architecture](http://emqtt.io/static/img/Architecture.png)
+
+
 ## QuickStart
 
 Download binary packeges for linux, mac and freebsd from [http://emqtt.io/downloads](http://emqtt.io/downloads).
 
-```
+For example:
+
+```sh
 tar xvf emqttd-ubuntu64-0.7.0-alpha.tgz && cd emqttd
 
 # start console
@@ -61,9 +72,11 @@ git clone https://github.com/emqtt/emqttd.git
 cd emqttd && make && make dist
 ```
 
+
 ## GetStarted
 
-Read [GettingStarted](https://github.com/emqtt/emqttd/wiki/GettingStarted) for more installation and configuration guide.
+Read [emqtt wiki](https://github.com/emqtt/emqttd/wiki) for detailed installation and configuration guide.
+
 
 ## Benchmark
 
@@ -71,17 +84,21 @@ Benchmark 0.6.1-alpha on a ubuntu/14.04 server with 8 cores, 32G memory from Qin
 
 200K+ Connections, 200K+ Topics, 20K+ In/Out Messages/sec, 20Mbps+ In/Out with 8G Memory, 50%CPU/core
 
+
 ## License
 
 The MIT License (MIT)
 
+
 ## Contributors
 
 [@hejin1026](https://github.com/hejin1026)
-
 [@desoulter](https://github.com/desoulter)
-
 [@turtleDeng](https://github.com/turtleDeng)
+[@Hades32](https://github.com/Hades32)
+[@huangdan](https://github.com/huangdan)
+
+
 
 ## Author
 

+ 1 - 1
apps/emqttd/src/emqttd.erl

@@ -162,7 +162,7 @@ loaded_plugins() ->
 -spec unload_all_plugins() -> [{App :: atom(), ok | {error, any()}}].
 unload_all_plugins() ->
     PluginApps = application:get_env(emqttd, plugins, []),
-    [{App, unload_plugin(App)} || {App, _Env} <- PluginApps].
+    [{App, unload_plugin(App)} || App <- PluginApps].
 
 
 %%------------------------------------------------------------------------------

+ 19 - 13
apps/emqttd/src/emqttd_app.erl

@@ -31,7 +31,7 @@
 -behaviour(application).
 
 %% Application callbacks
--export([start/2, stop/1]).
+-export([start/2, prep_stop/1, stop/1]).
 
 -define(PRINT_MSG(Msg), io:format(Msg)).
 
@@ -47,24 +47,24 @@
     State     :: term(),
     Reason    :: term().
 start(_StartType, _StartArgs) ->
-	print_banner(),
+    print_banner(),
     emqttd_mnesia:start(),
     {ok, Sup} = emqttd_sup:start_link(),
-	start_servers(Sup),
-	{ok, Listeners} = application:get_env(listeners),
+    start_servers(Sup),
+    {ok, Listeners} = application:get_env(listeners),
     emqttd:load_all_plugins(),
     emqttd:open_listeners(Listeners),
-	register(emqttd, self()),
+    register(emqttd, self()),
     print_vsn(),
-	{ok, Sup}.
+    {ok, Sup}.
 
 print_banner() ->
-	?PRINT("starting emqttd on node '~s'~n", [node()]).
+    ?PRINT("starting emqttd on node '~s'~n", [node()]).
 
 print_vsn() ->
-	{ok, Vsn} = application:get_key(vsn),
-	{ok, Desc} = application:get_key(description),
-	?PRINT("~s ~s is running now~n", [Desc, Vsn]).
+    {ok, Vsn} = application:get_key(vsn),
+    {ok, Desc} = application:get_key(description),
+    ?PRINT("~s ~s is running now~n", [Desc, Vsn]).
 
 start_servers(Sup) ->
     Servers = [{"emqttd event", emqttd_event},
@@ -128,10 +128,16 @@ worker_spec(Name, Opts) ->
         {Name, start_link, [Opts]},
             permanent, 10000, worker, [Name]}.
 
+%% close all listeners first...
+prep_stop(State) ->
+    %%TODO: esockd app should be running...
+    {ok, Listeners} = application:get_env(listeners),
+    emqttd:close_listeners(Listeners),
+    timer:sleep(2),
+    State.
+
 -spec stop(State :: term()) -> term().
 stop(_State) ->
-	{ok, Listeners} = application:get_env(listeners),
-    emqttd:close_listeners(Listeners),
-    emqttd:unload_all_plugins(),
     ok.
 
+

+ 1 - 1
apps/emqttd/src/emqttd_bridge_sup.erl

@@ -74,7 +74,7 @@ start_bridge(Node, SubTopic, Options) when is_atom(Node) and is_binary(SubTopic)
 -spec stop_bridge(atom(), binary()) -> {ok, pid()} | ok.
 stop_bridge(Node, SubTopic) ->
     ChildId = bridge_id(Node, SubTopic),
-    case supervisor:terminate_child(ChildId) of
+    case supervisor:terminate_child(?MODULE, ChildId) of
         ok -> 
             supervisor:delete_child(?MODULE, ChildId);
         {error, Reason} ->

+ 26 - 17
apps/emqttd/src/emqttd_ctl.erl

@@ -57,10 +57,10 @@ status([]) ->
     {InternalStatus, _ProvidedStatus} = init:get_status(),
     ?PRINT("Node ~p is ~p~n", [node(), InternalStatus]),
     case lists:keysearch(emqttd, 1, application:which_applications()) of
-	false ->
-		?PRINT_MSG("emqttd is not running~n");
-	{value,_Version} ->
-		?PRINT_MSG("emqttd is running~n")
+    false ->
+        ?PRINT_MSG("emqttd is not running~n");
+    {value,_Version} ->
+        ?PRINT_MSG("emqttd is running~n")
     end.
 
 %%------------------------------------------------------------------------------
@@ -72,32 +72,41 @@ cluster([]) ->
     ?PRINT("cluster nodes: ~p~n", [Nodes]);
 
 cluster([SNode]) ->
-	Node = node_name(SNode),
-	case net_adm:ping(Node) of
-	pong ->
-		application:stop(emqttd),
-        application:stop(esockd),
-        emqttd_mnesia:cluster(Node),
-        application:start(esockd),
-		application:start(emqttd),
-		?PRINT("cluster with ~p successfully.~n", [Node]);
-	pang ->
+    Node = node_name(SNode),
+    case net_adm:ping(Node) of
+    pong ->
+        case emqttd:is_running(Node) of
+            true ->
+                %%TODO: should not unload here.
+                emqttd:unload_all_plugins(),
+                application:stop(emqttd),
+                application:stop(esockd),
+                application:stop(gproc),
+                emqttd_mnesia:cluster(Node),
+                application:start(gproc),
+                application:start(esockd),
+                application:start(emqttd),
+                ?PRINT("cluster with ~p successfully.~n", [Node]);
+            false ->
+                ?PRINT("emqttd is not running on ~p~n", [Node])
+        end;
+    pang ->
         ?PRINT("failed to connect to ~p~n", [Node])
-	end.
+    end.
 
 %%------------------------------------------------------------------------------
 %% @doc Add usern
 %% @end
 %%------------------------------------------------------------------------------
 useradd([Username, Password]) ->
-	?PRINT("~p~n", [emqttd_auth_username:add_user(bin(Username), bin(Password))]).
+    ?PRINT("~p~n", [emqttd_auth_username:add_user(bin(Username), bin(Password))]).
 
 %%------------------------------------------------------------------------------
 %% @doc Delete user
 %% @end
 %%------------------------------------------------------------------------------
 userdel([Username]) ->
-	?PRINT("~p~n", [emqttd_auth_username:remove_user(bin(Username))]).
+    ?PRINT("~p~n", [emqttd_auth_username:remove_user(bin(Username))]).
 
 vm([]) ->
     [vm([Name]) || Name <- ["load", "memory", "process", "io"]];

+ 1 - 1
apps/emqttd/src/emqttd_event.erl

@@ -114,5 +114,5 @@ payload(connected, Params) ->
     iolist_to_binary(io_lib:format("from: ~s~nprotocol: ~p~nsession: ~s", [From, Proto, Sess]));
 
 payload(disconnected, Reason) ->
-    list_to_binary(io_lib:format(["reason: ~p", Reason])).
+    list_to_binary(io_lib:format("reason: ~p", [Reason])).
 

+ 0 - 199
doc/GetStarted.md

@@ -1,199 +0,0 @@
-# eMQTT Get Started
-
-## Overview
-
-eMQTT is a clusterable, massively scalable, fault-tolerant and extensible MQTT V3.1/V3.1.1 broker written in Erlang/OTP. 
-
-eMQTT is aimed to provide a solid-stable broker that could be clusterd to support millions of connections and clients.
-
-## Requires
-
-eMQTT is cross-platform, could run on windows, linux, freebsd and mac os x.
-
-eMQTT requires Erlang R17+ to build from source.
-
-## Featues
-
-### Full MQTT V3.1.1 Support
-
-MQTT V3.1.1 and V3.1 protocol support
-
-QoS0, QoS1, QoS2 Publish and Subscribe
-
-Session Management and Offline Messages
-
-Retained Messages
-
-Passed eclipse paho interoperability tests
-
-### Clusterable, Massively Scalable
-
-Massive Connections Clients Support
-
-Cluster brokers on servers or cloud hosts
-
-Bridge brokers locally or remotelly
-
-## Download, Install
-
-### Download
-
-Dowload binary packages from [http://emqtt.io/downloads](http://emqtt.io/downloads].
-
-Please build from source if no packages for your platform, or contact us.
-
-### Install
-
-Extract tgz package to your installed directory. for example:
-
-```
-tar xvf emqtt-ubuntu64-0.3.0-beta.tgz && cd emqtt  
-```
-
-### Startup
-
-Startup console for debug:
-
-```
-cd emqtt && ./bin/emqtt console
-```
-
-You could see all RECV/SENT MQTT Packages on console.
-
-Start as daemon:
-
-```
-cd emqtt && ./bin/emqtt start
-```
-
-eMQTT occupies 1883 port for MQTT, 8083 for HTTP API.
-
-### Status
-
-```
-cd emqtt && ./bin/emqtt_ctl status
-```
-
-### Stop
-
-```
-cd emqtt && ./bin/emqtt stop
-```
-
-## Configuration
-
-### etc/app.config
-
-```
-{emqtt, [
-    %Authetication. Internal, Anonymous Default.
-    {auth, {anonymous, []}},
-    {access, []},
-    {session, [
-        {expires, 1}, %hours
-        {max_queue, 1000},
-        {store_qos0, false}
-    ]},
-    {retain, [
-        {store_limit, 100000}
-    ]},
-    {listen, [
-        {mqtt, 1883, [
-            {acceptors, 4},
-            {max_conns, 1024}
-        ]},
-        {http, 8083, [
-            {acceptors, 1},
-            {max_conns, 512}
-        ]}
-    ]}
-]}
-```
-
-### etc/vm.args
-
-```
--name emqtt@127.0.0.1
-
--setcookie emqtt
-```
-
-## Cluster
-
-Suppose we cluster two nodes on 'host1', 'host2', Steps:
-
-### configure and start node on host1  
-
-configure 'etc/vm.args':
-
-```
--name emqtt@host1
-```
-
-then start:
-
-```
-./bin/emqtt start
-```
-
-### configure and start node on host2
-
-configure 'etc/vm.args':
-
-```
--name emqtt@host2
-```
-
-```
-./bin/emqtt start
-```
-
-### cluster two nodes
-
-Cluster from 'host2':
-
-```
-./bin/emqtt_ctl cluster emqtt@host1
-```
-
-or cluster from 'host1':
-
-```
-./bin/emqtt_ctl cluster emqtt@host2
-```
-
-then check clustered nodes on any host:
-
-```
-./bin/emqtt_ctl cluster
-```
-
-## HTTP API
-
-eMQTT support HTTP API to publish message from your APP to MQTT client.
-
-Example:
-
-```
-curl -v --basic -u user:passwd -d "qos=1&retain=0&topic=/a/b/c&message=hello from http..." -k http://localhost:8083/mqtt/publish
-```
-
-### URL
-
-```
-HTTP POST http://host:8083/mqtt/publish
-```
-
-### Parameters
-
-Name    |  Description
---------|---------------
-qos     |  QoS(0, 1, 2)
-retain  |  Retain(0, 1)
-topic   |  Topic
-message |  Message
-
-## Contact 
-
-feng@emqtt.io
-

+ 0 - 30
doc/acl.md

@@ -1,30 +0,0 @@
-
-# ACL
-
-## Protocol
-
-Authentication of users and devices
-
-Authorization of access to Server resources
-
-An implementation may restrict access to Server resources based on information provided by the Client such as User Name, Client Identifier, the hostname/IP address of the Client, or the outcome of authentication mechanisms.
-
-Identify a MQTT User: Peername, ClientId, Username
-
-
-## Access Rule
-
-allow | deny Who subscribe | publish Topic | all
-
-allow {clientid, {regexp, "abcd"}} subscribe "anna"
-deny  {clientid, "xxxx"} publish "#"
-allow {clientid, "abcd"} publish "#"
-allow {peername, "127.0.0.1"} subscribe "$SYS/#"
-allow {peername, "127.0.0.1"} subscribe all
-allow {clientid, "clientid"} subscribe  "#"
-allow {clientid, {regexp, "abcd"}} publish "anna"
-allow all subscribe all
-deny  all subscribe all
-allow all
-deny all
-

+ 0 - 34
doc/broker.md

@@ -1,34 +0,0 @@
-# Broker Topics
-
-## Version
-
-$SYS/broker/version
-
-## Uptime
-
-$SYS/broker/uptime
-
-## Recevied and Sent
-
-$SYS/broker/bytes/received
-$SYS/broker/bytes/sent
-
-$SYS/broker/packets/received
-$SYS/broker/packets/sent
-
-$SYS/broker/messages/received
-$SYS/broker/messages/sent
-$SYS/broker/messages/retained
-$SYS/broker/messages/stored
-$SYS/broker/messages/dropped
-
-## Client Presence
-
-$SYS/broker/clients/connected
-$SYS/broker/clients/disconnected
-
-$SYS/broker/clients/${clientId}/presences/online
-$SYS/broker/clients/${clientId}presences/offline
-
-
-

+ 0 - 25
doc/cluster.md

@@ -1,25 +0,0 @@
-
-            zookeeper
-                |
-    eMQTT1  eMQTT2  eMQTT3
-
-
-Bridge
-
-
-    eMQTT1 --> eMQTT2
-
-
-Cluster
- 
-    eMQTT1 <--> eMQTT2
-
-
-Cluster and Bridge
-
-    eMQTT1      eMQTT3
-          ----> 
-    eMQTT2      eMQTT4
-
-Mnesia Cluster
-

+ 0 - 37
doc/design.md

@@ -1,37 +0,0 @@
-# eMQTT Desgin Guide
-
-## KeepAlive
-
-## Retained
-
-## QOS1 
-
-## QOS2
-
-## Durable Subscriptions
-
-Durable Sub:
-
-Client->Queue->Router->Queue->Client
-
-Normal Sub:
-
-Client->Router->Client
-
-Router to register queues
-
-## Topic Tree
-
-## Offline Message
-
-## ACL
-
-## Authentication with clientId
-
-## SSL/TLS Socket
-
-## $SYS/topics and Broker statistics...
-
-## Cluster 
-
-## Bridge

doc/Architecture.png → doc/design/Architecture.png


doc/Architecture.graphml → doc/design/Design_Cluster.graphml


BIN
doc/design/Design_Cluster.png


+ 274 - 0
doc/design/Design_Standalone.graphml

@@ -0,0 +1,274 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
+  <!--Created by yEd 3.13-->
+  <key for="graphml" id="d0" yfiles.type="resources"/>
+  <key for="port" id="d1" yfiles.type="portgraphics"/>
+  <key for="port" id="d2" yfiles.type="portgeometry"/>
+  <key for="port" id="d3" yfiles.type="portuserdata"/>
+  <key attr.name="url" attr.type="string" for="node" id="d4"/>
+  <key attr.name="description" attr.type="string" for="node" id="d5"/>
+  <key for="node" id="d6" yfiles.type="nodegraphics"/>
+  <key attr.name="Description" attr.type="string" for="graph" id="d7"/>
+  <key attr.name="url" attr.type="string" for="edge" id="d8"/>
+  <key attr.name="description" attr.type="string" for="edge" id="d9"/>
+  <key for="edge" id="d10" yfiles.type="edgegraphics"/>
+  <graph edgedefault="directed" id="G">
+    <data key="d7"/>
+    <node id="n0">
+      <data key="d5"/>
+      <data key="d6">
+        <y:ShapeNode>
+          <y:Geometry height="45.0" width="44.0" x="130.0" y="200.0"/>
+          <y:Fill color="#3182BD" transparent="false"/>
+          <y:BorderStyle color="#3182BD" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="10.6328125" x="16.68359375" y="13.43359375">P<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+          <y:Shape type="ellipse"/>
+        </y:ShapeNode>
+      </data>
+    </node>
+    <node id="n1">
+      <data key="d5"/>
+      <data key="d6">
+        <y:ShapeNode>
+          <y:Geometry height="45.0" width="44.0" x="130.0" y="279.0"/>
+          <y:Fill color="#756BB1" transparent="false"/>
+          <y:BorderStyle color="#756BB1" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="10.6328125" x="16.68359375" y="13.43359375">P<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+          <y:Shape type="ellipse"/>
+        </y:ShapeNode>
+      </data>
+    </node>
+    <node id="n2">
+      <data key="d5"/>
+      <data key="d6">
+        <y:ShapeNode>
+          <y:Geometry height="45.0" width="44.0" x="458.0" y="202.5"/>
+          <y:Fill color="#756BB1" transparent="false"/>
+          <y:BorderStyle color="#756BB1" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="10.462890625" x="16.7685546875" y="13.43359375">S<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+          <y:Shape type="ellipse"/>
+        </y:ShapeNode>
+      </data>
+    </node>
+    <node id="n3">
+      <data key="d5"/>
+      <data key="d6">
+        <y:ShapeNode>
+          <y:Geometry height="45.0" width="44.0" x="458.0" y="277.5"/>
+          <y:Fill color="#3182BD" transparent="false"/>
+          <y:BorderStyle color="#3182BD" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="10.462890625" x="16.7685546875" y="13.43359375">S<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+          <y:Shape type="ellipse"/>
+        </y:ShapeNode>
+      </data>
+    </node>
+    <node id="n4">
+      <data key="d5"/>
+      <data key="d6">
+        <y:ShapeNode>
+          <y:Geometry height="124.0" width="125.0" x="250.0" y="193.0"/>
+          <y:Fill color="#74C476" transparent="false"/>
+          <y:BorderStyle color="#74C476" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="60.5" y="60.0">
+            <y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+          <y:Shape type="ellipse"/>
+        </y:ShapeNode>
+      </data>
+    </node>
+    <node id="n5">
+      <data key="d5"/>
+      <data key="d6">
+        <y:ShapeNode>
+          <y:Geometry height="17.0" width="16.0" x="333.0" y="246.5"/>
+          <y:Fill color="#FD8D3C" transparent="false"/>
+          <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="11.587890625" x="2.2060546875" y="-0.56640625">#<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+          <y:Shape type="ellipse"/>
+        </y:ShapeNode>
+      </data>
+    </node>
+    <node id="n6">
+      <data key="d5"/>
+      <data key="d6">
+        <y:ShapeNode>
+          <y:Geometry height="17.0" width="16.0" x="292.0" y="246.5"/>
+          <y:Fill color="#FD8D3C" transparent="false"/>
+          <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="13.5390625" x="1.23046875" y="-0.56640625">+<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+          <y:Shape type="ellipse"/>
+        </y:ShapeNode>
+      </data>
+    </node>
+    <node id="n7">
+      <data key="d5"/>
+      <data key="d6">
+        <y:ShapeNode>
+          <y:Geometry height="17.0" width="16.0" x="273.0" y="277.5"/>
+          <y:Fill color="#FD8D3C" transparent="false"/>
+          <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="11.359375" x="2.3203125" y="-0.56640625">x<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+          <y:Shape type="ellipse"/>
+        </y:ShapeNode>
+      </data>
+    </node>
+    <node id="n8">
+      <data key="d5"/>
+      <data key="d6">
+        <y:ShapeNode>
+          <y:Geometry height="17.0" width="16.0" x="308.0" y="277.5"/>
+          <y:Fill color="#FD8D3C" transparent="false"/>
+          <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="10.26953125" x="2.865234375" y="-0.56640625">y<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+          <y:Shape type="ellipse"/>
+        </y:ShapeNode>
+      </data>
+    </node>
+    <node id="n9">
+      <data key="d5"/>
+      <data key="d6">
+        <y:ShapeNode>
+          <y:Geometry height="17.0" width="16.0" x="308.0" y="216.5"/>
+          <y:Fill color="#FD8D3C" transparent="false"/>
+          <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="8.48828125" x="3.755859375" y="-0.56640625">t<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+          <y:Shape type="ellipse"/>
+        </y:ShapeNode>
+      </data>
+    </node>
+    <edge id="e0" source="n0" target="n3">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="270.0" y="222.5"/>
+            <y:Point x="360.0" y="300.0"/>
+          </y:Path>
+          <y:LineStyle color="#3182BD" type="dashed" width="1.0"/>
+          <y:Arrows source="none" target="plain"/>
+          <y:BendStyle smoothed="true"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e1" source="n1" target="n2">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+            <y:Point x="270.0" y="300.0"/>
+            <y:Point x="360.0" y="225.0"/>
+          </y:Path>
+          <y:LineStyle color="#756BB1" type="dashed" width="1.0"/>
+          <y:Arrows source="none" target="plain"/>
+          <y:BendStyle smoothed="true"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e2" source="n6" target="n9">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e3" source="n7" target="n6">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e4" source="n8" target="n6">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e5" source="n9" target="n5">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+  </graph>
+  <data key="d0">
+    <y:Resources/>
+  </data>
+</graphml>

BIN
doc/design/Design_Standalone.png


BIN
doc/design/PubSub_CleanSess_0.png


BIN
doc/design/PubSub_CleanSess_1.png


BIN
doc/emqtt.png


+ 993 - 0
doc/emqttd.graphml

@@ -0,0 +1,993 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
+  <!--Created by yEd 3.13-->
+  <key for="graphml" id="d0" yfiles.type="resources"/>
+  <key for="port" id="d1" yfiles.type="portgraphics"/>
+  <key for="port" id="d2" yfiles.type="portgeometry"/>
+  <key for="port" id="d3" yfiles.type="portuserdata"/>
+  <key attr.name="url" attr.type="string" for="node" id="d4"/>
+  <key attr.name="description" attr.type="string" for="node" id="d5"/>
+  <key for="node" id="d6" yfiles.type="nodegraphics"/>
+  <key attr.name="Description" attr.type="string" for="graph" id="d7"/>
+  <key attr.name="url" attr.type="string" for="edge" id="d8"/>
+  <key attr.name="description" attr.type="string" for="edge" id="d9"/>
+  <key for="edge" id="d10" yfiles.type="edgegraphics"/>
+  <graph edgedefault="directed" id="G">
+    <data key="d7"/>
+    <node id="n0" yfiles.foldertype="group">
+      <data key="d4"/>
+      <data key="d6">
+        <y:ProxyAutoBoundsNode>
+          <y:Realizers active="0">
+            <y:GroupNode>
+              <y:Geometry height="334.0" width="357.5" x="242.0" y="185.0"/>
+              <y:Fill color="#F5F5F5" transparent="false"/>
+              <y:BorderStyle color="#F5F5F5" type="dashed" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="node_width" borderDistance="0.0" configuration="CroppingLabel" fontFamily="Dialog" fontSize="18" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="27.19921875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="357.5" x="0.0" y="153.400390625">emqttd broker cluster</y:NodeLabel>
+              <y:Shape type="roundrectangle"/>
+              <y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
+              <y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
+              <y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
+            </y:GroupNode>
+            <y:GroupNode>
+              <y:Geometry height="50.0" width="50.0" x="180.0" y="140.0"/>
+              <y:Fill color="#F5F5F5" transparent="false"/>
+              <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
+              <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="63.75830078125" x="-6.879150390625" y="0.0">Folder 1</y:NodeLabel>
+              <y:Shape type="roundrectangle"/>
+              <y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
+              <y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
+              <y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
+            </y:GroupNode>
+          </y:Realizers>
+        </y:ProxyAutoBoundsNode>
+      </data>
+      <graph edgedefault="directed" id="n0:">
+        <node id="n0::n0">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="124.0" width="125.0" x="257.0" y="200.0"/>
+              <y:Fill color="#74C476" transparent="false"/>
+              <y:BorderStyle color="#74C476" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="60.5" y="60.0">
+                <y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n1">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="17.0" width="16.0" x="340.0" y="253.5"/>
+              <y:Fill color="#FD8D3C" transparent="false"/>
+              <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="11.587890625" x="2.2060546875" y="-0.56640625">#<y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n2">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="17.0" width="16.0" x="299.0" y="253.5"/>
+              <y:Fill color="#FD8D3C" transparent="false"/>
+              <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="13.5390625" x="1.23046875" y="-0.56640625">+<y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n3">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="17.0" width="16.0" x="280.0" y="284.5"/>
+              <y:Fill color="#FD8D3C" transparent="false"/>
+              <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="11.359375" x="2.3203125" y="-0.56640625">x<y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n4">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="17.0" width="16.0" x="315.0" y="284.5"/>
+              <y:Fill color="#FD8D3C" transparent="false"/>
+              <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="10.26953125" x="2.865234375" y="-0.56640625">y<y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n5">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="17.0" width="16.0" x="315.0" y="223.5"/>
+              <y:Fill color="#FD8D3C" transparent="false"/>
+              <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="8.48828125" x="3.755859375" y="-0.56640625">t<y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n6">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="124.0" width="125.0" x="459.5" y="200.0"/>
+              <y:Fill color="#74C476" transparent="false"/>
+              <y:BorderStyle color="#74C476" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="60.5" y="60.0">
+                <y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n7">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="17.0" width="16.0" x="542.5" y="253.5"/>
+              <y:Fill color="#FD8D3C" transparent="false"/>
+              <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="11.587890625" x="2.2060546875" y="-0.56640625">#<y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n8">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="17.0" width="16.0" x="501.5" y="253.5"/>
+              <y:Fill color="#FD8D3C" transparent="false"/>
+              <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="13.5390625" x="1.23046875" y="-0.56640625">+<y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n9">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="17.0" width="16.0" x="482.5" y="284.5"/>
+              <y:Fill color="#FD8D3C" transparent="false"/>
+              <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="11.359375" x="2.3203125" y="-0.56640625">x<y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n10">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="17.0" width="16.0" x="517.5" y="284.5"/>
+              <y:Fill color="#FD8D3C" transparent="false"/>
+              <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="10.26953125" x="2.865234375" y="-0.56640625">y<y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n11">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="17.0" width="16.0" x="517.5" y="223.5"/>
+              <y:Fill color="#FD8D3C" transparent="false"/>
+              <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="8.48828125" x="3.755859375" y="-0.56640625">t<y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n12">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="124.0" width="125.0" x="257.0" y="380.0"/>
+              <y:Fill color="#74C476" transparent="false"/>
+              <y:BorderStyle color="#74C476" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="60.5" y="60.0">
+                <y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n13">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="17.0" width="16.0" x="340.0" y="433.5"/>
+              <y:Fill color="#FD8D3C" transparent="false"/>
+              <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="11.587890625" x="2.2060546875" y="-0.56640625">#<y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n14">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="17.0" width="16.0" x="299.0" y="433.5"/>
+              <y:Fill color="#FD8D3C" transparent="false"/>
+              <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="13.5390625" x="1.23046875" y="-0.56640625">+<y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n15">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="17.0" width="16.0" x="280.0" y="464.5"/>
+              <y:Fill color="#FD8D3C" transparent="false"/>
+              <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="11.359375" x="2.3203125" y="-0.56640625">x<y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n16">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="17.0" width="16.0" x="315.0" y="464.5"/>
+              <y:Fill color="#FD8D3C" transparent="false"/>
+              <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="10.26953125" x="2.865234375" y="-0.56640625">y<y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n17">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="17.0" width="16.0" x="315.0" y="403.5"/>
+              <y:Fill color="#FD8D3C" transparent="false"/>
+              <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="8.48828125" x="3.755859375" y="-0.56640625">t<y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n18">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="124.0" width="125.0" x="459.5" y="380.0"/>
+              <y:Fill color="#74C476" transparent="false"/>
+              <y:BorderStyle color="#74C476" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" modelName="custom" textColor="#000000" visible="true" width="4.0" x="60.5" y="60.0">
+                <y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n19">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="17.0" width="16.0" x="542.5" y="433.5"/>
+              <y:Fill color="#FD8D3C" transparent="false"/>
+              <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="11.587890625" x="2.2060546875" y="-0.56640625">#<y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n20">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="17.0" width="16.0" x="501.5" y="433.5"/>
+              <y:Fill color="#FD8D3C" transparent="false"/>
+              <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="13.5390625" x="1.23046875" y="-0.56640625">+<y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n21">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="17.0" width="16.0" x="482.5" y="464.5"/>
+              <y:Fill color="#FD8D3C" transparent="false"/>
+              <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="11.359375" x="2.3203125" y="-0.56640625">x<y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n22">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="17.0" width="16.0" x="517.5" y="464.5"/>
+              <y:Fill color="#FD8D3C" transparent="false"/>
+              <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="10.26953125" x="2.865234375" y="-0.56640625">y<y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+        <node id="n0::n23">
+          <data key="d6">
+            <y:ShapeNode>
+              <y:Geometry height="17.0" width="16.0" x="517.5" y="403.5"/>
+              <y:Fill color="#FD8D3C" transparent="false"/>
+              <y:BorderStyle color="#FD8D3C" type="line" width="1.0"/>
+              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="8.48828125" x="3.755859375" y="-0.56640625">t<y:LabelModel>
+                  <y:SmartNodeLabelModel distance="4.0"/>
+                </y:LabelModel>
+                <y:ModelParameter>
+                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+                </y:ModelParameter>
+              </y:NodeLabel>
+              <y:Shape type="ellipse"/>
+            </y:ShapeNode>
+          </data>
+        </node>
+      </graph>
+    </node>
+    <node id="n1">
+      <data key="d6">
+        <y:ShapeNode>
+          <y:Geometry height="45.0" width="44.0" x="257.0" y="596.5"/>
+          <y:Fill color="#3182BD" transparent="false"/>
+          <y:BorderStyle color="#3182BD" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="37.861328125" x="3.0693359375" y="13.43359375">Client<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+          <y:Shape type="ellipse"/>
+        </y:ShapeNode>
+      </data>
+    </node>
+    <node id="n2">
+      <data key="d6">
+        <y:ShapeNode>
+          <y:Geometry height="45.0" width="44.0" x="338.0" y="567.5"/>
+          <y:Fill color="#756BB1" transparent="false"/>
+          <y:BorderStyle color="#756BB1" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="42.994140625" x="0.5029296875" y="13.43359375">Sensor<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+          <y:Shape type="ellipse"/>
+        </y:ShapeNode>
+      </data>
+    </node>
+    <node id="n3">
+      <data key="d6">
+        <y:ShapeNode>
+          <y:Geometry height="45.0" width="44.0" x="447.5" y="589.5"/>
+          <y:Fill color="#756BB1" transparent="false"/>
+          <y:BorderStyle color="#756BB1" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="42.994140625" x="0.5029296875" y="13.43359375">Sensor<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+          <y:Shape type="ellipse"/>
+        </y:ShapeNode>
+      </data>
+    </node>
+    <node id="n4">
+      <data key="d6">
+        <y:ShapeNode>
+          <y:Geometry height="45.0" width="44.0" x="542.5" y="596.5"/>
+          <y:Fill color="#3182BD" transparent="false"/>
+          <y:BorderStyle color="#3182BD" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="37.861328125" x="3.0693359375" y="13.43359375">Client<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+          <y:Shape type="ellipse"/>
+        </y:ShapeNode>
+      </data>
+    </node>
+    <node id="n5">
+      <data key="d5"/>
+      <data key="d6">
+        <y:ShapeNode>
+          <y:Geometry height="64.0" width="357.5" x="242.0" y="58.0"/>
+          <y:Fill color="#BDBDBD" transparent="false"/>
+          <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="109.533203125" x="123.9833984375" y="22.933593750000014">Application Server<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+          <y:Shape type="roundrectangle"/>
+        </y:ShapeNode>
+      </data>
+    </node>
+    <node id="n6">
+      <data key="d5"/>
+      <data key="d6">
+        <y:ShapeNode>
+          <y:Geometry height="45.0" width="85.0" x="71.5" y="239.5"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="28.50390625" x="28.248046875" y="13.43359375">Web<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+          <y:Shape type="roundrectangle"/>
+        </y:ShapeNode>
+      </data>
+    </node>
+    <node id="n7">
+      <data key="d5"/>
+      <data key="d6">
+        <y:ShapeNode>
+          <y:Geometry height="45.0" width="85.0" x="71.5" y="419.5"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="28.50390625" x="28.248046875" y="13.43359375">Web<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+          <y:Shape type="roundrectangle"/>
+        </y:ShapeNode>
+      </data>
+    </node>
+    <node id="n8">
+      <data key="d5"/>
+      <data key="d6">
+        <y:ShapeNode>
+          <y:Geometry height="64.0" width="49.0" x="685.0" y="230.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="43.052734375" x="2.9736328125" y="22.93359375">iPhone<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+          <y:Shape type="roundrectangle"/>
+        </y:ShapeNode>
+      </data>
+    </node>
+    <node id="n9">
+      <data key="d5"/>
+      <data key="d6">
+        <y:ShapeNode>
+          <y:Geometry height="64.0" width="49.0" x="685.0" y="410.0"/>
+          <y:Fill color="#C0C0C0" transparent="false"/>
+          <y:BorderStyle color="#C0C0C0" type="line" width="1.0"/>
+          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="50.58203125" x="-0.791015625" y="22.93359375">Android<y:LabelModel>
+              <y:SmartNodeLabelModel distance="4.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+            </y:ModelParameter>
+          </y:NodeLabel>
+          <y:Shape type="roundrectangle"/>
+        </y:ShapeNode>
+      </data>
+    </node>
+    <edge id="n0::e0" source="n0::n0" target="n0::n6">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#74C476" type="dashed" width="2.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="n0::e1" source="n0::n0" target="n0::n12">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#74C476" type="dashed" width="2.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="n0::e2" source="n0::n2" target="n0::n5">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="n0::e3" source="n0::n3" target="n0::n2">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="n0::e4" source="n0::n4" target="n0::n2">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="n0::e5" source="n0::n5" target="n0::n1">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="n0::e6" source="n0::n6" target="n0::n18">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#74C476" type="dashed" width="2.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="n0::e7" source="n0::n8" target="n0::n11">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="n0::e8" source="n0::n9" target="n0::n8">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="n0::e9" source="n0::n10" target="n0::n8">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="n0::e10" source="n0::n11" target="n0::n7">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="n0::e11" source="n0::n12" target="n0::n18">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#74C476" type="dashed" width="2.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="n0::e12" source="n0::n14" target="n0::n17">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="n0::e13" source="n0::n15" target="n0::n14">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="n0::e14" source="n0::n16" target="n0::n14">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="n0::e15" source="n0::n17" target="n0::n13">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="n0::e16" source="n0::n20" target="n0::n23">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="n0::e17" source="n0::n21" target="n0::n20">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="n0::e18" source="n0::n22" target="n0::n20">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="n0::e19" source="n0::n23" target="n0::n19">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#FD8D3C" type="line" width="1.0"/>
+          <y:Arrows source="none" target="none"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e0" source="n0::n18" target="n4">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#3182BD" type="dashed" width="1.0"/>
+          <y:Arrows source="standard" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e1" source="n2" target="n0::n12">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#756BB1" type="dashed" width="1.0"/>
+          <y:Arrows source="standard" target="standard"/>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e2" source="n0::n18" target="n3">
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="-22.749321892003195" sy="57.76129269460557" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#756BB1" type="dashed" width="1.0"/>
+          <y:Arrows source="standard" target="standard"/>
+          <y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="38.833984375" x="-31.872099564693826" y="37.92230224609375">MQTT<y:LabelModel>
+              <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/>
+            </y:ModelParameter>
+            <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
+          </y:EdgeLabel>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e3" source="n5" target="n0::n0">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="-101.25" sy="32.0078125" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#BDBDBD" type="line" width="1.0"/>
+          <y:Arrows source="none" target="standard"/>
+          <y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="34.626953125" x="-17.3134765625" y="29.92578125">HTTP<y:LabelModel>
+              <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/>
+            </y:ModelParameter>
+            <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
+          </y:EdgeLabel>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e4" source="n5" target="n0::n6">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="101.25" sy="31.9765625" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#BDBDBD" type="dashed" width="2.0"/>
+          <y:Arrows source="standard" target="standard"/>
+          <y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="38.833984375" x="-19.4169921875" y="29.92284393310547">MQTT<y:LabelModel>
+              <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/>
+            </y:ModelParameter>
+            <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
+          </y:EdgeLabel>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e5" source="n6" target="n0::n0">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#C0C0C0" type="dashed" width="1.0"/>
+          <y:Arrows source="standard" target="standard"/>
+          <y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="66.671875" x="16.89422607421875" y="-9.06640625">WebSocket<y:LabelModel>
+              <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/>
+            </y:ModelParameter>
+            <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
+          </y:EdgeLabel>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e6" source="n7" target="n0::n12">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#C0C0C0" type="dashed" width="1.0"/>
+          <y:Arrows source="standard" target="standard"/>
+          <y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="66.671875" x="16.89422607421875" y="-9.06640625">WebSocket<y:LabelModel>
+              <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/>
+            </y:ModelParameter>
+            <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
+          </y:EdgeLabel>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e7" source="n0::n6" target="n8">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#C0C0C0" type="dashed" width="1.0"/>
+          <y:Arrows source="standard" target="standard"/>
+          <y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="38.833984375" x="30.8330078125" y="-9.06640625">MQTT<y:LabelModel>
+              <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/>
+            </y:ModelParameter>
+            <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
+          </y:EdgeLabel>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e8" source="n0::n18" target="n9">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#C0C0C0" type="dashed" width="1.0"/>
+          <y:Arrows source="standard" target="standard"/>
+          <y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="38.833984375" x="30.8330078125" y="-9.06640625">MQTT<y:LabelModel>
+              <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/>
+            </y:ModelParameter>
+            <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
+          </y:EdgeLabel>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+    <edge id="e9" source="n1" target="n0::n12">
+      <data key="d9"/>
+      <data key="d10">
+        <y:PolyLineEdge>
+          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+          <y:LineStyle color="#3182BD" type="dashed" width="1.0"/>
+          <y:Arrows source="standard" target="standard"/>
+          <y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="38.833984375" x="-8.698938402078966" y="-55.90826416015625">MQTT<y:LabelModel>
+              <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
+            </y:LabelModel>
+            <y:ModelParameter>
+              <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="center" ratio="0.5" segment="0"/>
+            </y:ModelParameter>
+            <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
+          </y:EdgeLabel>
+          <y:BendStyle smoothed="false"/>
+        </y:PolyLineEdge>
+      </data>
+    </edge>
+  </graph>
+  <data key="d0">
+    <y:Resources/>
+  </data>
+</graphml>

BIN
doc/emqttd.png


+ 0 - 1
doc/hooks_chain.md

@@ -1 +0,0 @@
-packet, message handler chain???

BIN
doc/mqtt-v3.1.1-os.pdf


+ 0 - 36
doc/protocol.md

@@ -1,36 +0,0 @@
-# MQTT Protocol Guide
-
-## Server or Broker
-
-A program or device that acts as an intermediary between Clients which publish Application Messages and Clients which have made Subscriptions. 
-
-A Server Accepts Network Connections from Clients.  
-Accepts Application Messages published by Clients. 
-Processes Subscribe and Unsubscribe requests from Clients.  
-Forwards Application Messages that match Client Subscriptions.
-
-
-Client ----> Broker(Server) ----> Client
-
-Publisher ----> Broker -----> Subscriber
-
-## Subscription and Session
-
-### Subscription
-
-A Subscription comprises a Topic Filter and a maximum QoS. A Subscription is associated with a single Session. A Session can contain more than one Subscription. Each Subscription within a session has a different Topic Filter.
-
-### Session
-
-A stateful interaction between a Client and a Server. Some Sessions last only as long as the Network
-
-Connection, others can span multiple consecutive Network Connections between a Client and a Server.
-
-## Topic Name and Filter
-
-An expression contained in a Subscription, to indicate an interest in one or more topics. A Topic Filter can include wildcard characters.
-
-
-## Packet Identifier
-
-

+ 0 - 40
doc/pubsub.md

@@ -1,40 +0,0 @@
-# PubSub
-
-## Qos 
-
-PubQos | SubQos | In Message | Out Message
--------|--------|------------|-------------
-   0   |   0    |   -        | - 
-   0   |   1    |   -        | - 
-   0   |   2    |   -        | - 
-   1   |   0    |   -        | - 
-   1   |   1    |   -        | - 
-   1   |   2    |   -        | - 
-   2   |   0    |   -        | - 
-   2   |   1    |   -        | - 
-   2   |   2    |   -        | - 
-
-
-## Publish
-
-
-## Performance
-
-Mac Air(11): 
-
-Function     | Time(microseconds)
--------------|--------------------
-match        | 6.25086
-triples      | 13.86881
-words        | 3.41177
-binary:split | 3.03776
-
-iMac:
-
-Function     | Time(microseconds)
--------------|--------------------
-match        | 3.2348
-triples      | 6.93524
-words        | 1.89616
-binary:split | 1.65243
-

+ 0 - 133
doc/quickstart.md

@@ -1,133 +0,0 @@
-## Quick Start
-
-## Startup in Five Minutes
-
-```
-$ git clone git://github.com/emqtt/emqttd.git
-
-$ cd emqttd
-
-$ make && make dist
-
-$ cd rel/emqttd
-
-$ ./bin/emqttd console
-```
-
-## Deploy and Start
-
-### start
-
-```
-cp -R rel/emqttd $INSTALL_DIR
-
-cd $INSTALL_DIR/emqttd
-
-./bin/emqttd start
-
-```
-
-### stop
-
-```
-./bin/emqttd stop
-
-```
-
-## Configuration
-
-### etc/app.config
-
-```
- {emqttd, [
-    {auth, {anonymous, []}}, %internal, anonymous
-    {listen, [
-        {mqtt, 1883, [
-            {acceptors, 4},
-            {max_clients, 1024}
-        ]},
-        {mqtts, 8883, [
-            {acceptors, 4},
-            {max_clients, 1024},
-            %{cacertfile, "etc/ssl/cacert.pem"}, 
-            {ssl, [{certfile, "etc/ssl.crt"},
-                   {keyfile,  "etc/ssl.key"}]}
-        ]},
-        {http, 8083, [
-            {acceptors, 1},
-            {max_clients, 512}
-        ]}
-    ]}
- ]}
-
-```
-
-### etc/vm.args
-
-```
-
--name emqttd@127.0.0.1
-
--setcookie emqtt
-
-```
-
-When nodes clustered, vm.args should be configured as below:
-
-```
--name emqttd@host1
-```
-
-## Cluster
-
-Suppose we cluster two nodes on 'host1', 'host2', Steps:
-
-on 'host1':
-
-```
-./bin/emqttd start
-```
-
-on 'host2':
-
-```
-./bin/emqttd start
-
-./bin/emqttd_ctl cluster emqttd@host1
-```
-
-Run './bin/emqttd_ctl cluster' on 'host1' or 'host2' to check cluster nodes.
-
-## HTTP API
-
-emqttd support http to publish message.
-
-Example:
-
-```
-curl -v --basic -u user:passwd -d "qos=1&retain=0&topic=a/b/c&message=hello from http..." -k http://localhost:8083/mqtt/publish
-```
-
-### URL
-
-```
-HTTP POST http://host:8083/mqtt/publish
-```
-
-### Parameters
-
-Name    |  Description
---------|---------------
-qos     |  QoS(0, 1, 2)
-retain  |  Retain(0, 1)
-topic   |  Topic
-message |  Message
-
-
-## Contributors
-
-@hejin1026 <260495915 at qq.com>
-
-@desoulter <assoulter123 at gmail.com>
-
-@turtleDeng

+ 0 - 6
doc/retain.md

@@ -1,6 +0,0 @@
-# Retained Message
-
-## API
-
-store(
-

+ 0 - 19
doc/route.md

@@ -1,19 +0,0 @@
-
-
-ClientA -> SessionA -> Route -> PubSub -> SessionB -> ClientB
-
-
-ClientA -> Session -> PubSub -> Route -> SessionB -> ClientB
-                        |        |
-                      Trie    Subscriber                 
-
-
-ClientPidA -> ClientPidB
-
-
-ClientPidA -> SessionPidB -> ClientB
-
-
-ClientPidA -> SessionPidA -> SessionPidB -> ClientPidB
-
-

+ 0 - 50
doc/session.md

@@ -1,50 +0,0 @@
-# Session Design
-
-## session manager
-
-```erlang
-
-%% lookup sesssion
-emqtt_sm:lookup_session(ClientId)
-
-%% Start new or resume existing session
-emqtt_sm:start_session(ClientId)
-
-%% destroy session, discard all data
-emqtt_sm:destory_session(ClientId)
-
-%% close session, save all data
-emqtt_sm:close_session(ClientId)
-```
-
-## session supervisor
-
-usage?
-
-## session
-
-```
-%%system process
-process_flag(trap_exit, true),
-
-session:start()
-session:subscribe(
-session:publish(
-session:resume(
-session:suspend(
-%%destory all data
-session:destory(
-%%save all data
-session:close()
-
-```
-
-## sm and session
-
-sm manage and monitor session
-
-## client and session
-
-    client(normal process)<--link to -->session(system process)
-
-

+ 0 - 4
doc/state_design.md

@@ -1,4 +0,0 @@
-
-
-client state --> parse_state
-             --> proto_state --> session_state

+ 0 - 4
doc/systopics.md

@@ -1,4 +0,0 @@
-# eMQTT $SYS Topics
-
-Wiki: [$SYS Topics of Broker](https://github.com/emqtt/emqtt/wiki/$SYS-Topics-of-Broker)
-

+ 0 - 22
doc/topic.md

@@ -1,22 +0,0 @@
-Topic Types:
-
-static: 
-
-    /brokers/alerts/
-    /brokers/clients/connected
-    /brokers/clients/disconnected
-
-dynamic:
-    
-    created when subscribe...
-
-bridge:
-
-    cretated when bridge...
-
-
-## Create Topics
-
-emqttd_pubsub:create(Type, Name) 
-emqttd_pubsub:create(#topic{name = Name, node= node(), type = Type}).
-

+ 0 - 14
doc/user-guide.md

@@ -1,14 +0,0 @@
-# eMQTT User Guide
-
-## Introduction
-
-## Installation
-
-### Install Requirements
-
-## Configuration
-
-## Cluster
-
-## Bridge
-

+ 21 - 0
plugins/emqttd_auth_mysql/README.md

@@ -0,0 +1,21 @@
+##  Overview
+
+Authentication with user table of MySQL database.
+
+## Demo User Table
+
+```
+CREATE TABLE `mqtt_users` (
+  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `username` varchar(60) DEFAULT NULL,
+  `password` varchar(60) DEFAULT NULL,
+  `salt` varchar(20) DEFAULT NULL,
+  `created` datetime DEFAULT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `mqtt_users_username` (`username`)
+) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
+```
+
+## Plugin config
+
+

+ 19 - 0
plugins/emqttd_auth_mysql/rebar.config

@@ -0,0 +1,19 @@
+%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ts=4 sw=4 ft=erlang et
+
+{require_min_otp_vsn, "R17"}.
+
+%% fail_on_warning, 
+{erl_opts, [debug_info, {parse_transform, lager_transform}]}.
+
+{erl_opts, [warn_export_all,
+            warn_unused_import,
+            {i, "include"},
+			{src_dirs, ["src"]}]}.
+
+{xref_checks, [undefined_function_calls]}.
+
+{deps, [
+	{'Emysql', "*", {git, "git://github.com/Eonblast/Emysql.git", {branch, "master"}}}
+]}.
+

+ 12 - 0
plugins/emqttd_auth_mysql/src/emqttd_auth_mysql.app.src

@@ -0,0 +1,12 @@
+{application, emqttd_auth_mysql,
+ [
+  {description, ""},
+  {vsn, "0.1"},
+  {registered, []},
+  {applications, [
+                  kernel,
+                  stdlib
+                 ]},
+  {mod, {emqttd_auth_mysql_app, []}},
+  {env, []}
+ ]}.

+ 54 - 0
plugins/emqttd_auth_mysql/src/emqttd_auth_mysql.erl

@@ -0,0 +1,54 @@
+%%%-----------------------------------------------------------------------------
+%%% Copyright (c) 2012-2015 eMQTT.IO, All Rights Reserved.
+%%%
+%%% Permission is hereby granted, free of charge, to any person obtaining a copy
+%%% of this software and associated documentation files (the "Software"), to deal
+%%% in the Software without restriction, including without limitation the rights
+%%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+%%% copies of the Software, and to permit persons to whom the Software is
+%%% furnished to do so, subject to the following conditions:
+%%%
+%%% The above copyright notice and this permission notice shall be included in all
+%%% copies or substantial portions of the Software.
+%%%
+%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+%%% SOFTWARE.
+%%%-----------------------------------------------------------------------------
+%%% @doc
+%%% emqttd authentication by mysql user table.
+%%%
+%%% @end
+%%%-----------------------------------------------------------------------------
+-module(emqttd_auth_mysql).
+
+-author("Feng Lee <feng@emqtt.io>").
+
+-include_lib("emqttd/include/emqttd.hrl").
+
+-behaviour(emqttd_auth_mod).
+
+-export([init/1, check/3, description/0]).
+
+-record(state, {user_tab}).
+
+init(Opts) -> 
+    UserTab = proplists:get_value(user_table, Opts, mqtt_users),
+    {ok, #state{user_tab = UserTab}}.
+
+check(#mqtt_client{username = undefined}, _Password, _State) ->
+    {error, "Username undefined"};
+check(_Client, undefined, _State) ->
+    {error, "Password undefined"};
+check(#mqtt_client{username = Username}, Password, #state{user_tab = UserTab}) ->
+    case emysql:select(UserTab, {{username, Username}, {password, erlang:md5(Password)}}) of
+        {ok, []} -> {error, "Username or Password not match"};
+        {ok, _Record} -> ok
+    end.
+
+description() -> "Authentication by MySQL".
+

+ 19 - 0
plugins/emqttd_auth_mysql/src/emqttd_auth_mysql_app.erl

@@ -0,0 +1,19 @@
+-module(emqttd_auth_mysql_app).
+
+-behaviour(application).
+
+%% Application callbacks
+-export([start/2, stop/1]).
+
+%% ===================================================================
+%% Application callbacks
+%% ===================================================================
+
+start(_StartType, _StartArgs) ->
+    {ok, Sup} = emqttd_auth_mysql_sup:start_link(),
+    emqttd_access_control:register_mod(auth, emqttd_auth_mysql, []),
+    {ok, Sup}.
+
+stop(_State) ->
+    emqttd_access_control:unregister_mod(auth, emqttd_auth_mysql),
+    ok.

+ 27 - 0
plugins/emqttd_auth_mysql/src/emqttd_auth_mysql_sup.erl

@@ -0,0 +1,27 @@
+-module(emqttd_auth_mysql_sup).
+
+-behaviour(supervisor).
+
+%% API
+-export([start_link/0]).
+
+%% Supervisor callbacks
+-export([init/1]).
+
+%% Helper macro for declaring children of supervisor
+-define(CHILD(I, Type), {I, {I, start_link, []}, permanent, 5000, Type, [I]}).
+
+%% ===================================================================
+%% API functions
+%% ===================================================================
+
+start_link() ->
+    supervisor:start_link({local, ?MODULE}, ?MODULE, []).
+
+%% ===================================================================
+%% Supervisor callbacks
+%% ===================================================================
+
+init([]) ->
+    {ok, { {one_for_one, 5, 10}, []} }.
+

+ 1 - 2
rebar.config

@@ -2,7 +2,6 @@
 %% ex: ts=4 sw=4 ft=erlang et
 
 {require_min_otp_vsn, "R17"}.
-{cover_enabled, true}.
 
 %% fail_on_warning, 
 {erl_opts, [debug_info, {parse_transform, lager_transform}]}.
@@ -15,7 +14,7 @@
 {eunit_opts, [verbose]}.
 
 {xref_checks, [undefined_function_calls]}.
-{cover_enabled, false}.
+{cover_enabled, true}.
 
 {validate_app_modules, true}.
 

+ 1 - 1
rel/files/acl.config

@@ -1,6 +1,6 @@
 %%%-----------------------------------------------------------------------------
 %% 
-%% [ACL Design](https://github.com/emqtt/emqttd/wiki/ACL-Design)
+%% [ACL](https://github.com/emqtt/emqttd/wiki/ACL)
 %% 
 %% -type who() :: all | binary() |
 %%               {ipaddr, esockd_access:cidr()} |