Microservices refactoring

pull/1/head
Ogoun 6 years ago
parent 1a7ccf9ded
commit f28abaccd4

@ -0,0 +1,687 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" 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.18.2-->
<key attr.name="Description" attr.type="string" for="graph" id="d0"/>
<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 for="graphml" id="d7" yfiles.type="resources"/>
<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="d0"/>
<node id="n0">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="40.0" width="165.25" x="1597.0" y="0.0"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="168.71875" x="-1.734375" xml:space="preserve" y="10.6494140625">NetworkStreamFastObfuscator<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:GenericNode>
</data>
</node>
<node id="n1">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="40.0" width="345.0" x="1840.25" y="516.75"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="148.732421875" x="98.1337890625" xml:space="preserve" y="10.6494140625">ExchangeTransportFactory<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:GenericNode>
</data>
</node>
<node id="n2">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.userMessage">
<y:Geometry height="40.0" width="271.0" x="1840.25" y="596.75"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="61.3515625" x="104.82421875" xml:space="preserve" y="10.6494140625">IExService<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:GenericNode>
</data>
</node>
<node id="n3">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.userMessage">
<y:Geometry height="40.0" width="271.0" x="1840.25" y="556.75"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="52.017578125" x="109.4912109375" xml:space="preserve" y="10.6494140625">IExClient<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:GenericNode>
</data>
</node>
<node id="n4">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.predefinedProcess">
<y:Geometry height="40.0" width="301.0" x="1529.0" y="-133.0"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="82.69140625" x="109.154296875" xml:space="preserve" y="10.6494140625">ZBaseNetwork<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:GenericNode>
</data>
</node>
<node id="n5">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="40.0" width="222.0" x="1823.0" y="-40.0"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="78.6953125" x="71.65234375" xml:space="preserve" y="10.6494140625">ZSocketClient<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:GenericNode>
</data>
</node>
<node id="n6">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="40.0" width="222.0" x="1317.0" y="-40.0"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="83.359375" x="69.3203125" xml:space="preserve" y="10.6494140625">ZSocketServer<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:GenericNode>
</data>
</node>
<node id="n7">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="40.0" width="222.0" x="1317.0" y="0.0"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="128.0546875" x="46.97265625" xml:space="preserve" y="10.6494140625">&lt;ZSocketServerClient&gt;<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:GenericNode>
</data>
</node>
<node id="n8">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.annotation">
<y:Geometry height="40.0" width="210.0" x="2107.0" y="-40.0"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="66.015625" x="71.9921875" xml:space="preserve" y="10.6494140625">IZTransport<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:StyleProperties>
<y:Property class="java.lang.Byte" name="com.yworks.flowchart.style.orientation" value="0"/>
</y:StyleProperties>
</y:GenericNode>
</data>
</node>
<node id="n9">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="40.0" width="222.0" x="1823.0" y="100.25"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="48.68359375" x="86.658203125" xml:space="preserve" y="10.6494140625">ExClient<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:GenericNode>
</data>
</node>
<node id="n10">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.annotation">
<y:Geometry height="40.0" width="210.0" x="1678.25" y="249.5"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="52.017578125" x="78.9912109375" xml:space="preserve" y="10.6494140625">IExClient<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:StyleProperties>
<y:Property class="java.lang.Byte" name="com.yworks.flowchart.style.orientation" value="0"/>
</y:StyleProperties>
</y:GenericNode>
</data>
</node>
<node id="n11">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.annotation">
<y:Geometry height="40.0" width="210.0" x="2107.0" y="208.0"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="67.3515625" x="71.32421875" xml:space="preserve" y="10.6494140625">IZBackward<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:StyleProperties>
<y:Property class="java.lang.Byte" name="com.yworks.flowchart.style.orientation" value="0"/>
</y:StyleProperties>
</y:GenericNode>
</data>
</node>
<node id="n12">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="40.0" width="189.0" x="1586.5" y="179.5"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="54.021484375" x="67.4892578125" xml:space="preserve" y="10.6494140625">ExRouter<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:GenericNode>
</data>
</node>
<node id="n13">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="40.0" width="222.0" x="1317.0" y="100.25"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="58.017578125" x="81.9912109375" xml:space="preserve" y="10.6494140625">ExService<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:GenericNode>
</data>
</node>
<node id="n14">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.annotation">
<y:Geometry height="40.0" width="189.0" x="1468.0" y="249.5"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="61.3515625" x="63.82421875" xml:space="preserve" y="10.6494140625">IExService<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:StyleProperties>
<y:Property class="java.lang.Byte" name="com.yworks.flowchart.style.orientation" value="0"/>
</y:StyleProperties>
</y:GenericNode>
</data>
</node>
<node id="n15">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.annotation">
<y:Geometry height="40.0" width="189.0" x="1019.1875" y="100.25"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="111.373046875" x="38.8134765625" xml:space="preserve" y="10.6494140625">IZObservableServer<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:StyleProperties>
<y:Property class="java.lang.Byte" name="com.yworks.flowchart.style.orientation" value="0"/>
</y:StyleProperties>
</y:GenericNode>
</data>
</node>
<node id="n16">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="40.0" width="210.0" x="2107.0" y="100.25"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="92.04296875" x="58.978515625" xml:space="preserve" y="10.6494140625">FrameExchange<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:GenericNode>
</data>
</node>
<node id="n17">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.predefinedProcess">
<y:Geometry height="40.0" width="252.5" x="2392.9375" y="100.25"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="76.0234375" x="88.23828125" xml:space="preserve" y="10.6494140625">FrameBuilder<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:GenericNode>
</data>
</node>
<node id="n18">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="40.0" width="162.5" x="1599.75" y="-79.25"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="74.013671875" x="44.2431640625" xml:space="preserve" y="10.6494140625">FrameParser<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:GenericNode>
</data>
</node>
<node id="n19">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="40.0" width="189.0" x="1019.1875" y="219.4375"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="158.728515625" x="15.1357421875" xml:space="preserve" y="10.6494140625">ZExSocketObservableServer<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:GenericNode>
</data>
</node>
<node id="n20">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="40.0" width="242.5" x="2308.5" y="516.75"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="82.69140625" x="79.904296875" xml:space="preserve" y="10.6494140625">ExServiceHost<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:GenericNode>
</data>
</node>
<node id="n21">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.annotation">
<y:Geometry height="40.0" width="242.5" x="2308.5" y="406.9375"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="90.689453125" x="75.9052734375" xml:space="preserve" y="10.6494140625">IDiscoveryClient<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:StyleProperties>
<y:Property class="java.lang.Byte" name="com.yworks.flowchart.style.orientation" value="0"/>
</y:StyleProperties>
</y:GenericNode>
</data>
</node>
<node id="n22">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.annotation">
<y:Geometry height="40.0" width="310.0" x="2689.75" y="556.75"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="100.720703125" x="104.6396484375" xml:space="preserve" y="10.6494140625">IExchangeService<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:StyleProperties>
<y:Property class="java.lang.Byte" name="com.yworks.flowchart.style.orientation" value="0"/>
</y:StyleProperties>
</y:GenericNode>
</data>
</node>
<node id="n23">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.loopLimitEnd">
<y:Geometry height="40.0" width="242.5" x="2308.5" y="556.75"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="88.697265625" x="76.9013671875" xml:space="preserve" y="10.6494140625">RegisterService<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:GenericNode>
</data>
</node>
<node id="n24">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.loopLimitEnd">
<y:Geometry height="40.0" width="242.5" x="2308.5" y="596.75"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="88.697265625" x="76.9013671875" xml:space="preserve" y="10.6494140625">RegisterService<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:GenericNode>
</data>
</node>
<node id="n25">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="40.0" width="310.0" x="2689.75" y="596.75"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="91.357421875" x="109.3212890625" xml:space="preserve" y="10.6494140625">MicroserviceInfo<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:GenericNode>
</data>
</node>
<node id="n26">
<data key="d5"/>
<data key="d6">
<y:GenericNode configuration="com.yworks.flowchart.process">
<y:Geometry height="40.0" width="242.5" x="2308.5" y="315.75"/>
<y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="87.35546875" x="77.572265625" xml:space="preserve" y="10.6494140625">DiscoveryClient<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:GenericNode>
</data>
</node>
<edge id="e0" source="n4" 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:Point x="1428.0" y="-113.0"/>
</y:Path>
<y:LineStyle color="#000000" type="dashed" width="1.0"/>
<y:Arrows source="none" target="none"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e1" source="n4" 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:Point x="1934.0" y="-113.0"/>
</y:Path>
<y:LineStyle color="#000000" type="dashed" width="1.0"/>
<y:Arrows source="none" target="none"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e2" source="n5" 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="#000000" type="dashed" width="1.0"/>
<y:Arrows source="none" target="none"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e3" source="n5" 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="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e4" source="n4" target="n9">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="121.4712093140904" sy="19.986328125" tx="0.0" ty="0.0">
<y:Point x="1800.9712093140904" y="120.25"/>
</y:Path>
<y:LineStyle color="#000000" type="dashed" width="1.0"/>
<y:Arrows source="none" target="none"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e5" source="n10" target="n9">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="-6.0" ty="20.037109375">
<y:Point x="1928.0" y="269.5"/>
</y:Path>
<y:LineStyle color="#000000" type="dashed" width="1.0"/>
<y:Arrows source="none" target="none"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e6" source="n11" target="n9">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="78.0" ty="19.9609375">
<y:Point x="2012.0" y="228.0"/>
</y:Path>
<y:LineStyle color="#000000" type="dashed" width="1.0"/>
<y:Arrows source="none" target="none"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e7" source="n12" target="n9">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="94.5245361328125" sy="0.0" tx="-77.3125" ty="20.037109375">
<y:Point x="1856.6875" y="199.5"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e8" source="n6" target="n13">
<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="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e9" source="n4" target="n13">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="-113.82739982667294" sy="20.025390625" tx="0.0" ty="0.0">
<y:Point x="1565.672600173327" y="120.25"/>
</y:Path>
<y:LineStyle color="#000000" type="dashed" width="1.0"/>
<y:Arrows source="none" target="none"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e10" source="n14" target="n13">
<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="1428.0" y="269.5"/>
</y:Path>
<y:LineStyle color="#000000" type="dashed" width="1.0"/>
<y:Arrows source="none" target="none"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e11" source="n10" 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="1783.25" y="576.75"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e12" source="n14" 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="1562.5" y="616.75"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e13" source="n12" target="n13">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="71.1875" ty="19.998046875">
<y:Point x="1499.1875" y="199.5"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e14" source="n15" target="n13">
<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="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e15" source="n16" 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="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e16" source="n8" target="n16">
<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="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e17" source="n17" target="n16">
<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="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e18" source="n18" target="n7">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="110.985595703125" ty="0.0">
<y:Point x="1579.75" y="-59.25"/>
<y:Point x="1579.75" y="20.0"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e19" source="n18" target="n5">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="-1.5" sy="0.0" tx="-81.75" ty="-20.005859375">
<y:Point x="1852.25" y="-59.25"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e20" source="n15" target="n19">
<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="#000000" type="dashed" width="1.0"/>
<y:Arrows source="none" target="none"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e21" source="n0" target="n18">
<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="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e22" source="n0" target="n7">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="85.5" ty="0.0"/>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e23" source="n0" target="n5">
<data key="d9"/>
<data key="d10">
<y:PolyLineEdge>
<y:Path sx="0.0" sy="0.0" tx="-78.0" ty="20.013671875">
<y:Point x="1856.0" y="20.0"/>
</y:Path>
<y:LineStyle color="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e24" source="n1" target="n20">
<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="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e25" source="n21" target="n20">
<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="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e26" source="n22" target="n23">
<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="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e27" source="n25" target="n24">
<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="#000000" type="line" width="1.0"/>
<y:Arrows source="none" target="standard"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
<edge id="e28" source="n26" target="n21">
<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="#000000" type="dashed" width="1.0"/>
<y:Arrows source="none" target="none"/>
<y:BendStyle smoothed="false"/>
</y:PolyLineEdge>
</data>
</edge>
</graph>
<data key="d7">
<y:Resources/>
</data>
</graphml>

@ -5,7 +5,8 @@
</startup>
<appSettings>
<add key="console" value="true" />
<add key="port" value="8885" />
<add key="apiport" value="8885" />
<add key="socketport" value="8884" />
</appSettings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

@ -1,10 +1,18 @@
using ZeroLevel.Services.Applications;
using System.Collections;
using System.Collections.Generic;
using ZeroLevel.Models;
using ZeroLevel.Network;
using ZeroLevel.Network.Microservices;
using ZeroLevel.Services.Applications;
using ZeroLevel.Services.Network;
namespace ZeroLevel.Discovery
{
public sealed class DiscoveryService
: BaseWindowsService, IZeroService
{
private IExService _exInbox;
public DiscoveryService()
: base("Discovery")
{
@ -20,13 +28,23 @@ namespace ZeroLevel.Discovery
public override void StartAction()
{
Injector.Default.Register<RouteTable>(new RouteTable());
var port = Configuration.Default.First<int>("port");
var routeTable = new RouteTable();
Injector.Default.Register<RouteTable>(routeTable);
var port = Configuration.Default.First<int>("apiport");
Startup.StartWebPanel(port, false);
var socketPort = Configuration.Default.First<int>("socketport");
_exInbox = ExchangeTransportFactory.GetServer("socket", socketPort);
_exInbox.RegisterInbox<IEnumerable<ServiceEndpointsInfo>>("services", (_, __) => routeTable.Get());
_exInbox.RegisterInbox<MicroserviceInfo, InvokeResult>("register", (info, _, __) => routeTable.Append(info));
Log.Info($"TCP server started on port {socketPort}");
}
public override void StopAction()
{
_exInbox.Dispose();
}
}
}

@ -4,8 +4,8 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using ZeroLevel.Microservices;
using ZeroLevel.Models;
using ZeroLevel.Network;
using ZeroLevel.Network.Microservices;
namespace ZeroLevel.Discovery

@ -77,7 +77,6 @@
<Compile Include="DiscoveryService.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="ExchangeTransportFactory.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RouteTable.cs" />

@ -1 +1 @@
4f0bbfe8ac44b56784f7eeaa3cdef96609d6b97e
fe8032ac49bedc0ec84767ee0419b2fc618b5766

@ -1,154 +0,0 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
namespace ZeroLevel.ProxyREST
{
public abstract class BaseProxy
{
private readonly string _baseUrl;
private Uri BuildRequestUrl(string baseUri, string resource, IDictionary<string, object> parameters)
{
if (null == resource) throw new ArgumentNullException("resource");
var stringBuilder = new StringBuilder(baseUri);
if (baseUri[baseUri.Length - 1] != '/')
stringBuilder.Append('/');
if (resource[0] != '/')
{
stringBuilder.Append(resource);
}
else
{
stringBuilder.Append(resource.Substring(1));
}
parameters.
Do(list =>
{
if (list.Count > 0)
{
stringBuilder.Append("?");
foreach (string key in list.Keys)
{
var val = list[key];
if (val == null)
{
stringBuilder.Append(key);
}
else
{
var vtype = val.GetType();
if (vtype.IsArray)
{
if (vtype.GetElementType() == typeof(string))
{
var arr = (string[])val;
stringBuilder.Append(string.Join("&", arr.Select(i => string.Format("{0}[]={1}", key, i))));
}
else
{
var arr = (object[])val;
stringBuilder.Append(string.Join("&", arr.Select(i => string.Format("{0}[]={1}", key, JsonConvert.SerializeObject(i)))));
}
}
else
{
if (vtype == typeof(string))
{
stringBuilder.AppendFormat("{0}={1}", key, val);
}
else
{
stringBuilder.AppendFormat("{0}={1}", key, JsonConvert.SerializeObject(val));
}
}
}
stringBuilder.Append("&");
}
}
});
return new Uri(stringBuilder.ToString().TrimEnd('&'));
}
protected T SendRequest<T>(string resource, string method, object body, IDictionary<string, object> parameters = null)
{
string statusCode = null;
string reason = null;
try
{
var request = (HttpWebRequest)WebRequest.Create(BuildRequestUrl(_baseUrl, resource, parameters));
request.UseDefaultCredentials = true;
request.Method = method;
request.Proxy = null;
request.AutomaticDecompression = DecompressionMethods.GZip;
if (body != null)
{
request.Accept = "application/json";
request.ContentType = "application/json";
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(JsonConvert.SerializeObject(body));
streamWriter.Flush();
}
}
using (var response = (HttpWebResponse)request.GetResponse())
{
statusCode = response.StatusCode.ToString();
reason = response.StatusDescription;
if (response.StatusCode == HttpStatusCode.OK)
{
using (var stream = new StreamReader(response.GetResponseStream()))
{
string json = stream.ReadToEnd();
return JsonConvert.DeserializeObject<T>(json);
}
}
else
{
throw new Exception("Bad status code");
}
}
}
catch (Exception ex)
{
var line = $"Resource request failed. [{method}] {resource}. Error code: {(statusCode ?? "Uncknown")}. Comment: {(reason ?? ex.Message)}";
Log.Error(ex, line);
throw new InvalidOperationException(line, ex);
}
}
protected T GET<T>(string resource, IDictionary<string, object> parameters = null)
{
return SendRequest<T>(resource, "GET", null, parameters);
}
protected T POST<T>(string resource, object body, IDictionary<string, object> parameters = null)
{
return SendRequest<T>(resource, "POST", body, parameters);
}
protected T DELETE<T>(string resource, object body, IDictionary<string, object> parameters = null)
{
return SendRequest<T>(resource, "DELETE", body, parameters);
}
static BaseProxy()
{
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
ServicePointManager.Expect100Continue = false;
ServicePointManager.DefaultConnectionLimit = 8;
}
public BaseProxy(string baseUri)
{
if (false == baseUri.EndsWith("/"))
_baseUrl = baseUri + "/";
else
_baseUrl = baseUri;
}
}
}

@ -1,109 +0,0 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Reflection;
using ZeroLevel.Network.Microservices;
using ZeroLevel.Services.Network;
using ZeroLevel.Services.Network.Contract;
namespace ZeroLevel.Microservices
{
internal static class ExchangeTransportFactory
{
private static readonly Dictionary<string, Type> _customServers = new Dictionary<string, Type>();
private static readonly Dictionary<string, Type> _customClients = new Dictionary<string, Type>();
private static readonly ConcurrentDictionary<string, ExClient> _clientInstances = new ConcurrentDictionary<string, ExClient>();
/// <summary>
/// Scanning the specified assembly to find the types that implement the IExchangeServer or IExchangeClient interfaces
/// </summary>
internal static void ScanAndRegisterCustomTransport(Assembly asm)
{
foreach (var type in asm.GetExportedTypes())
{
var serverAttr = type.GetCustomAttribute<ExchangeServerAttribute>();
if (serverAttr != null &&
string.IsNullOrWhiteSpace(serverAttr.Protocol) == false &&
typeof(IZObservableServer).IsAssignableFrom(type))
{
_customServers[serverAttr.Protocol] = type;
}
var clientAttr = type.GetCustomAttribute<ExchangeClientAttribute>();
if (clientAttr != null &&
string.IsNullOrWhiteSpace(clientAttr.Protocol) == false &&
typeof(IZTransport).IsAssignableFrom(type))
{
_customClients[clientAttr.Protocol] = type;
}
}
}
/// <summary>
/// Creates a server to receive messages using the specified protocol
/// </summary>
/// <param name="protocol">Protocol</param>
/// <returns>Server</returns>
internal static ExService GetServer(string protocol)
{
ExService instance = null;
if (protocol.Equals("socket", StringComparison.OrdinalIgnoreCase))
{
instance = new ExService(new ZExSocketObservableServer(new System.Net.IPEndPoint(IPFinder.GetNonLoopbackAddress(), IPFinder.GetFreeTcpPort())));
}
else
{
var key = protocol.Trim().ToLowerInvariant();
if (_customServers.ContainsKey(key))
{
instance = new ExService((IZObservableServer)Activator.CreateInstance(_customServers[key]));
}
}
if (instance != null)
{
return instance;
}
throw new NotSupportedException($"Protocol {protocol} not supported");
}
/// <summary>
/// Creates a client to access the server using the specified protocol
/// </summary>
/// <param name="protocol">Protocol</param>
/// <param name="endpoint">Server endpoint</param>
/// <returns>Client</returns>
internal static ExClient GetClient(string protocol, string endpoint)
{
ExClient instance = null;
var cachee_key = $"{protocol}:{endpoint}";
if (_clientInstances.ContainsKey(cachee_key))
{
instance = _clientInstances[cachee_key];
if (instance.Status == ZTransportStatus.Working)
{
return instance;
}
_clientInstances.TryRemove(cachee_key, out instance);
instance.Dispose();
instance = null;
}
if (protocol.Equals("socket", StringComparison.OrdinalIgnoreCase))
{
instance = new ExClient(new ZSocketClient(SocketExtensions.CreateIPEndPoint(endpoint)));
}
else
{
var key = protocol.Trim().ToLowerInvariant();
if (_customClients.ContainsKey(key))
{
instance = new ExClient((IZTransport)Activator.CreateInstance(_customClients[key], new object[] { endpoint }));
}
}
if (instance != null)
{
_clientInstances[cachee_key] = instance;
return instance;
}
throw new NotSupportedException($"Protocol {protocol} not supported");
}
}
}

@ -1,35 +0,0 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ZeroLevel.Microservices")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ZeroLevel.Microservices")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("6452d91a-2dac-4982-83af-77472051e81b")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

@ -1,71 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{6452D91A-2DAC-4982-83AF-77472051E81B}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ZeroLevel.Microservices</RootNamespace>
<AssemblyName>ZeroLevel.Microservices</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="BaseProxy.cs" />
<Compile Include="Contracts\IDiscoveryClient.cs" />
<Compile Include="Contracts\IExchangeService.cs" />
<Compile Include="Exchange.cs" />
<Compile Include="ExchangeTransportFactory.cs" />
<Compile Include="ExServiceHost.cs" />
<Compile Include="Model\Checkpoint.cs" />
<Compile Include="Model\CheckpointArc.cs" />
<Compile Include="Model\CheckpointType.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="WebApiDiscoveryClient.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ZeroLevel\ZeroLevel.csproj">
<Project>{37020d8d-34e8-4ec3-a447-8396d5080457}</Project>
<Name>ZeroLevel</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="12.0.1" targetFramework="net472" />
</packages>

@ -5,8 +5,6 @@ VisualStudioVersion = 15.0.28307.421
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZeroLevel", "ZeroLevel\ZeroLevel.csproj", "{37020D8D-34E8-4EC3-A447-8396D5080457}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZeroLevel.Microservices", "ZeroLevel.Microservices\ZeroLevel.Microservices.csproj", "{6452D91A-2DAC-4982-83AF-77472051E81B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZeroLevel.Discovery", "ZeroLevel.Discovery\ZeroLevel.Discovery.csproj", "{4F55B23F-938C-4DA2-B6DC-B6BC66D36073}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZeroExample", "ZeroExample\ZeroExample.csproj", "{50CEBEC2-2571-4592-AFD2-970BDB41947B}"
@ -33,18 +31,6 @@ Global
{37020D8D-34E8-4EC3-A447-8396D5080457}.Release|x64.Build.0 = Release|Any CPU
{37020D8D-34E8-4EC3-A447-8396D5080457}.Release|x86.ActiveCfg = Release|Any CPU
{37020D8D-34E8-4EC3-A447-8396D5080457}.Release|x86.Build.0 = Release|Any CPU
{6452D91A-2DAC-4982-83AF-77472051E81B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6452D91A-2DAC-4982-83AF-77472051E81B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6452D91A-2DAC-4982-83AF-77472051E81B}.Debug|x64.ActiveCfg = Debug|Any CPU
{6452D91A-2DAC-4982-83AF-77472051E81B}.Debug|x64.Build.0 = Debug|Any CPU
{6452D91A-2DAC-4982-83AF-77472051E81B}.Debug|x86.ActiveCfg = Debug|Any CPU
{6452D91A-2DAC-4982-83AF-77472051E81B}.Debug|x86.Build.0 = Debug|Any CPU
{6452D91A-2DAC-4982-83AF-77472051E81B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6452D91A-2DAC-4982-83AF-77472051E81B}.Release|Any CPU.Build.0 = Release|Any CPU
{6452D91A-2DAC-4982-83AF-77472051E81B}.Release|x64.ActiveCfg = Release|Any CPU
{6452D91A-2DAC-4982-83AF-77472051E81B}.Release|x64.Build.0 = Release|Any CPU
{6452D91A-2DAC-4982-83AF-77472051E81B}.Release|x86.ActiveCfg = Release|Any CPU
{6452D91A-2DAC-4982-83AF-77472051E81B}.Release|x86.Build.0 = Release|Any CPU
{4F55B23F-938C-4DA2-B6DC-B6BC66D36073}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4F55B23F-938C-4DA2-B6DC-B6BC66D36073}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4F55B23F-938C-4DA2-B6DC-B6BC66D36073}.Debug|x64.ActiveCfg = Debug|Any CPU

@ -5,9 +5,14 @@ using ZeroLevel.Models;
namespace ZeroLevel.Services.Network
{
public interface IExClient
: IDisposable
{
event Action Connected;
void ForceConnect();
ZTransportStatus Status { get; }
IPEndPoint Endpoint { get; }
InvokeResult Send<T>(T obj);

@ -6,13 +6,13 @@ using ZeroLevel.Network.Microservices;
using ZeroLevel.Services.Network;
using ZeroLevel.Services.Network.Contract;
namespace ZeroLevel.Microservices
namespace ZeroLevel.Network
{
internal static class ExchangeTransportFactory
public static class ExchangeTransportFactory
{
private static readonly Dictionary<string, Type> _customServers = new Dictionary<string, Type>();
private static readonly Dictionary<string, Type> _customClients = new Dictionary<string, Type>();
private static readonly ConcurrentDictionary<string, ExClient> _clientInstances = new ConcurrentDictionary<string, ExClient>();
private static readonly ConcurrentDictionary<string, IExClient> _clientInstances = new ConcurrentDictionary<string, IExClient>();
/// <summary>
/// Scanning the specified assembly to find the types that implement the IExchangeServer or IExchangeClient interfaces
@ -43,12 +43,12 @@ namespace ZeroLevel.Microservices
/// </summary>
/// <param name="protocol">Protocol</param>
/// <returns>Server</returns>
internal static ExService GetServer(string protocol)
public static IExService GetServer(string protocol, int port = -1)
{
ExService instance = null;
if (protocol.Equals("socket", StringComparison.OrdinalIgnoreCase))
{
instance = new ExService(new ZExSocketObservableServer(new System.Net.IPEndPoint(IPFinder.GetNonLoopbackAddress(), IPFinder.GetFreeTcpPort())));
instance = new ExService(new ZExSocketObservableServer(new System.Net.IPEndPoint(NetUtils.GetNonLoopbackAddress(), port == -1 ? NetUtils.GetFreeTcpPort() : port)));
}
else
{
@ -64,16 +64,15 @@ namespace ZeroLevel.Microservices
}
throw new NotSupportedException($"Protocol {protocol} not supported");
}
/// <summary>
/// Creates a client to access the server using the specified protocol
/// </summary>
/// <param name="protocol">Protocol</param>
/// <param name="endpoint">Server endpoint</param>
/// <returns>Client</returns>
internal static ExClient GetClient(string protocol, string endpoint)
public static IExClient GetClientWithCache(string protocol, string endpoint)
{
ExClient instance = null;
IExClient instance = null;
var cachee_key = $"{protocol}:{endpoint}";
if (_clientInstances.ContainsKey(cachee_key))
{
@ -86,9 +85,17 @@ namespace ZeroLevel.Microservices
instance.Dispose();
instance = null;
}
instance = GetClient(protocol, endpoint);
_clientInstances[cachee_key] = instance;
return instance;
}
public static IExClient GetClient(string protocol, string endpoint)
{
ExClient instance = null;
if (protocol.Equals("socket", StringComparison.OrdinalIgnoreCase))
{
instance = new ExClient(new ZSocketClient(SocketExtensions.CreateIPEndPoint(endpoint)));
instance = new ExClient(new ZSocketClient(NetUtils.CreateIPEndPoint(endpoint)));
}
else
{
@ -100,7 +107,6 @@ namespace ZeroLevel.Microservices
}
if (instance != null)
{
_clientInstances[cachee_key] = instance;
return instance;
}
throw new NotSupportedException($"Protocol {protocol} not supported");

@ -2,7 +2,7 @@
using System.Runtime.Serialization;
using ZeroLevel.Services.Serialization;
namespace ZeroLevel.Microservices.Model
namespace ZeroLevel.Network.Microservices
{
[DataContract]
public class Checkpoint :

@ -1,6 +1,6 @@
using System.Runtime.Serialization;
namespace ZeroLevel.Microservices.Model
namespace ZeroLevel.Network.Microservices
{
[DataContract]
public sealed class CheckpointArc

@ -1,4 +1,4 @@
namespace ZeroLevel.Microservices.Model
namespace ZeroLevel.Network.Microservices
{
public enum CheckpointType
{

@ -3,31 +3,16 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using ZeroLevel.Microservices.Contracts;
using ZeroLevel.Models;
using ZeroLevel.Network;
using ZeroLevel.Network.Microservices;
using ZeroLevel.ProxyREST;
using ZeroLevel.Services.Collections;
namespace ZeroLevel.Microservices
namespace ZeroLevel.Services.Network.Microservices
{
public sealed class WebApiDiscoveryClient :
BaseProxy, IDiscoveryClient
public class DiscoveryClient
: IDiscoveryClient
{
#region WebAPI
private IEnumerable<ServiceEndpointsInfo> GetRecords()
{
return GET<IEnumerable<ServiceEndpointsInfo>>("api/v0/routes");
}
public InvokeResult Post(MicroserviceInfo info)
{
return POST<InvokeResult>("api/v0/routes", info);
}
#endregion WebAPI
private readonly ConcurrentDictionary<string, RoundRobinCollection<ServiceEndpointInfo>> _tableByKey =
new ConcurrentDictionary<string, RoundRobinCollection<ServiceEndpointInfo>>();
@ -38,10 +23,11 @@ namespace ZeroLevel.Microservices
new ConcurrentDictionary<string, RoundRobinCollection<ServiceEndpointInfo>>();
private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
private readonly IExClient _discoveryServerClient;
public WebApiDiscoveryClient(string url)
: base(url)
public DiscoveryClient(string protocol, string endpoint)
{
_discoveryServerClient = ExchangeTransportFactory.GetClient(protocol, endpoint);
UpdateServiceListInfo();
Sheduller.RemindEvery(TimeSpan.FromSeconds(30), UpdateServiceListInfo);
}
@ -79,63 +65,89 @@ namespace ZeroLevel.Microservices
private void UpdateServiceListInfo()
{
IEnumerable<ServiceEndpointsInfo> records;
try
{
records = GetRecords();
}
catch (Exception ex)
{
Log.Error(ex, "[WebApiDiscoveryClient] Update service list error, discrovery service response is absent");
return;
}
if (records == null)
{
Log.Warning("[WebApiDiscoveryClient] Update service list canceled, discrovery response is empty");
return;
}
_lock.EnterWriteLock();
try
_discoveryServerClient.ForceConnect();
if (_discoveryServerClient.Status == ZTransportStatus.Working)
{
_tableByGroups.Clear();
_tableByTypes.Clear();
var keysToRemove = new List<string>(_tableByKey.Keys);
foreach (var info in records)
IEnumerable<ServiceEndpointsInfo> records = null;
try
{
var key = info.ServiceKey.Trim().ToLowerInvariant();
UpdateOrAddRecord(key, info);
keysToRemove.Remove(key);
var ir = _discoveryServerClient.Request<IEnumerable<ServiceEndpointsInfo>>("services", response => records = response);
if (!ir.Success)
{
Log.Warning($"[DiscoveryClient] UpdateServiceListInfo. Error request to inbox 'services'. {ir.Comment}");
return;
}
}
RoundRobinCollection<ServiceEndpointInfo> removed;
foreach (var key in keysToRemove)
catch (Exception ex)
{
_tableByKey.TryRemove(key, out removed);
removed.Dispose();
Log.Error(ex, "[DiscoveryClient] UpdateServiceListInfo. Discrovery service response is absent");
return;
}
if (records == null)
{
Log.Warning("[DiscoveryClient] UpdateServiceListInfo. Discrovery response is empty");
return;
}
_lock.EnterWriteLock();
try
{
_tableByGroups.Clear();
_tableByTypes.Clear();
var keysToRemove = new List<string>(_tableByKey.Keys);
foreach (var info in records)
{
var key = info.ServiceKey.Trim().ToLowerInvariant();
UpdateOrAddRecord(key, info);
keysToRemove.Remove(key);
}
foreach (var key in keysToRemove)
{
_tableByKey.TryRemove(key, out RoundRobinCollection<ServiceEndpointInfo> removed);
removed.Dispose();
}
}
catch (Exception ex)
{
Log.Error(ex, "[DiscoveryClient] UpdateServiceListInfo. Update local routing table error.");
}
finally
{
_lock.ExitWriteLock();
}
}
catch (Exception ex)
{
Log.Error(ex, "[WebApiDiscoveryClient] Update service list error");
}
finally
else
{
_lock.ExitWriteLock();
Log.Warning("[DiscoveryClient] UpdateServiceListInfo. No connection to discovery server");
}
}
public void Register(MicroserviceInfo info)
public bool Register(MicroserviceInfo info)
{
try
_discoveryServerClient.ForceConnect();
if (_discoveryServerClient.Status == ZTransportStatus.Working)
{
var result = Post(info);
if (result.Success == false)
bool result = false;
try
{
Log.Warning($"[WebApiDiscoveryClient] Service can't register. Discovery reason: {result.Comment}. Comment: {result.Comment}");
_discoveryServerClient.Request<MicroserviceInfo, InvokeResult>("register", info, r =>
{
result = r.Success;
if (!result)
{
Log.Warning($"[DiscoveryClient] Register canceled. Discovery reason: {r.Comment}. Comment: {r.Comment}");
}
});
}
catch (Exception ex)
{
Log.Error(ex, "[DiscoveryClient] Register fault");
}
return result;
}
catch (Exception ex)
else
{
Log.Error(ex, "[WebApiDiscoveryClient] Fault register");
Log.Warning("[DiscoveryClient] Register. No connection to discovery server");
return false;
}
}

@ -4,19 +4,19 @@ using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using ZeroLevel.Microservices.Contracts;
using ZeroLevel.Network;
using ZeroLevel.Network.Microservices;
using ZeroLevel.Services.Network;
namespace ZeroLevel.Microservices
{
internal sealed class ExServiceHost
public sealed class ExServiceHost
: IDisposable
{
private class MetaService
{
public MicroserviceInfo ServiceInfo { get; set; }
public ExService Server { get; set; }
public IExService Server { get; set; }
}
private bool _disposed = false;
@ -26,13 +26,13 @@ namespace ZeroLevel.Microservices
private readonly ConcurrentDictionary<string, MetaService> _services
= new ConcurrentDictionary<string, MetaService>();
internal ExServiceHost(IDiscoveryClient client)
public ExServiceHost(IDiscoveryClient client)
{
_discoveryClient = client;
_registerTaskKey = Sheduller.RemindEvery(TimeSpan.FromMilliseconds(50), TimeSpan.FromSeconds(15), RegisterServicesInDiscovery);
}
internal IExService RegisterService(IExchangeService service)
public IExService RegisterService(IExchangeService service)
{
try
{
@ -76,7 +76,7 @@ namespace ZeroLevel.Microservices
}
}
internal IExService RegisterService(MicroserviceInfo serviceInfo)
public IExService RegisterService(MicroserviceInfo serviceInfo)
{
try
{

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ZeroLevel.Microservices.Contracts;
using ZeroLevel.Network;
using ZeroLevel.Network.Microservices;
using ZeroLevel.Services.Network;

@ -1,11 +1,11 @@
using System.Collections.Generic;
using ZeroLevel.Network.Microservices;
namespace ZeroLevel.Microservices.Contracts
namespace ZeroLevel.Network
{
public interface IDiscoveryClient
{
void Register(MicroserviceInfo info);
bool Register(MicroserviceInfo info);
IEnumerable<ServiceEndpointInfo> GetServiceEndpoints(string serviceKey);

@ -1,4 +1,4 @@
namespace ZeroLevel.Microservices.Contracts
namespace ZeroLevel.Network
{
public interface IExchangeService
{

@ -1,12 +1,13 @@
using System;
using System.Runtime.Serialization;
using ZeroLevel.Services.Serialization;
namespace ZeroLevel.Network.Microservices
{
[Serializable]
[DataContract]
public sealed class MicroserviceInfo :
IEquatable<MicroserviceInfo>
IEquatable<MicroserviceInfo>, IBinarySerializable
{
public const string DEFAULT_GROUP_NAME = "__service_default_group__";
public const string DEFAULT_TYPE_NAME = "__service_default_type__";
@ -73,6 +74,26 @@ namespace ZeroLevel.Network.Microservices
return this.ServiceKey.GetHashCode() ^ this.Protocol.GetHashCode() ^ this.Endpoint.GetHashCode();
}
public void Serialize(IBinaryWriter writer)
{
writer.WriteString(this.ServiceKey);
writer.WriteString(this.ServiceGroup);
writer.WriteString(this.ServiceType);
writer.WriteString(this.Protocol);
writer.WriteString(this.Endpoint);
writer.WriteString(this.Version);
}
public void Deserialize(IBinaryReader reader)
{
this.ServiceKey = reader.ReadString();
this.ServiceGroup = reader.ReadString();
this.ServiceType = reader.ReadString();
this.Protocol = reader.ReadString();
this.Endpoint = reader.ReadString();
this.Version = reader.ReadString();
}
public override string ToString()
{
return $"{ServiceKey} ({Version})";

@ -1,12 +1,48 @@
using System;
using System.Globalization;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
namespace ZeroLevel.Services.Network
{
public static class IPFinder
public static class NetUtils
{
public static int Compare(this IPEndPoint x, IPEndPoint y)
{
var xx = x.Address.ToString();
var yy = y.Address.ToString();
var result = string.CompareOrdinal(xx, yy);
return result == 0 ? x.Port.CompareTo(y.Port) : result;
}
public static IPEndPoint CreateIPEndPoint(string endPoint)
{
string[] ep = endPoint.Split(':');
if (ep.Length < 2) throw new FormatException("Invalid endpoint format");
IPAddress ip;
if (ep.Length > 2)
{
if (!IPAddress.TryParse(string.Join(":", ep, 0, ep.Length - 1), out ip))
{
throw new FormatException("Invalid ip-adress");
}
}
else
{
if (!IPAddress.TryParse(ep[0], out ip))
{
throw new FormatException("Invalid ip-adress");
}
}
int port;
if (!int.TryParse(ep[ep.Length - 1], NumberStyles.None, NumberFormatInfo.CurrentInfo, out port))
{
throw new FormatException("Invalid port");
}
return new IPEndPoint(ip, port);
}
public static int GetFreeTcpPort()
{
TcpListener l = new TcpListener(IPAddress.Loopback, 0);

@ -6,8 +6,8 @@ using ZeroLevel.Services.Network.Services;
namespace ZeroLevel.Services.Network
{
public class ExClient
: ZBaseNetwork, IExClient, IZBackward, IDisposable
internal sealed class ExClient
: ZBaseNetwork, IExClient, IZBackward
{
private readonly IZTransport _transport;
private readonly ExRouter _router;

@ -5,7 +5,7 @@ using ZeroLevel.Services.Network.Services;
namespace ZeroLevel.Services.Network
{
public class ExService
internal sealed class ExService
: ZBaseNetwork, IExService
{
private readonly ExRouter _router;

@ -14,9 +14,9 @@ namespace ZeroLevel.Services.Network
public IPEndPoint Endpoint => base.LocalEndpoint;
public event Action<Frame, IZBackward> OnMessage = (f, c) => { };
public event Action<Frame, IZBackward> OnMessage = (_, __) => { };
public event Func<Frame, IZBackward, Frame> OnRequest = (f, c) => null;
public event Func<Frame, IZBackward, Frame> OnRequest = (_, __) => null;
protected override void Handle(Frame frame, IZBackward client)
{

@ -1,44 +0,0 @@
using System;
using System.Globalization;
using System.Net;
namespace ZeroLevel.Services.Network
{
public static class SocketExtensions
{
public static int Compare(this IPEndPoint x, IPEndPoint y)
{
var xx = x.Address.ToString();
var yy = y.Address.ToString();
var result = string.CompareOrdinal(xx, yy);
return result == 0 ? x.Port.CompareTo(y.Port) : result;
}
public static IPEndPoint CreateIPEndPoint(string endPoint)
{
string[] ep = endPoint.Split(':');
if (ep.Length < 2) throw new FormatException("Invalid endpoint format");
IPAddress ip;
if (ep.Length > 2)
{
if (!IPAddress.TryParse(string.Join(":", ep, 0, ep.Length - 1), out ip))
{
throw new FormatException("Invalid ip-adress");
}
}
else
{
if (!IPAddress.TryParse(ep[0], out ip))
{
throw new FormatException("Invalid ip-adress");
}
}
int port;
if (!int.TryParse(ep[ep.Length - 1], NumberStyles.None, NumberFormatInfo.CurrentInfo, out port))
{
throw new FormatException("Invalid port");
}
return new IPEndPoint(ip, port);
}
}
}

@ -238,6 +238,15 @@
<Compile Include="Services\Network\Contract\IZBackward.cs" />
<Compile Include="Services\Network\Contract\IZObservableServer.cs" />
<Compile Include="Services\Network\Contract\IZTransport.cs" />
<Compile Include="Services\Network\ExchangeTransportFactory.cs" />
<Compile Include="Services\Network\Microservices\Checkpoint.cs" />
<Compile Include="Services\Network\Microservices\CheckpointArc.cs" />
<Compile Include="Services\Network\Microservices\CheckpointType.cs" />
<Compile Include="Services\Network\Microservices\DiscoveryClient.cs" />
<Compile Include="Services\Network\Microservices\Exchange.cs" />
<Compile Include="Services\Network\Microservices\ExServiceHost.cs" />
<Compile Include="Services\Network\Microservices\IDiscoveryClient.cs" />
<Compile Include="Services\Network\Microservices\IExchangeService.cs" />
<Compile Include="Services\Network\Models\ExchangeAttributes.cs" />
<Compile Include="Services\Network\Models\MicroserviceInfo.cs" />
<Compile Include="Services\Network\Models\RequestInfo.cs" />
@ -251,11 +260,10 @@
<Compile Include="Services\Network\Services\FrameBuilder.cs" />
<Compile Include="Services\Network\Services\FrameExchange.cs" />
<Compile Include="Services\Network\Services\ZExSocketObservableServer.cs" />
<Compile Include="Services\Network\SocketExtensions.cs" />
<Compile Include="Services\Network\NetUtils.cs" />
<Compile Include="Services\Network\Models\Frame.cs" />
<Compile Include="Services\Network\Services\FrameParser.cs" />
<Compile Include="Services\Network\NetworkStreamDataObfuscator.cs" />
<Compile Include="Services\Network\Services\IPFinder.cs" />
<Compile Include="Services\Network\ZBaseNetwork.cs" />
<Compile Include="Services\Network\ZSocketClient.cs" />
<Compile Include="Services\Network\ZSocketServer.cs" />

@ -1 +1 @@
7dc74ae62ea3925694bcfe614d7c1f201cc0d873
34e7ecccf08c9607e57fb18cb5dd41e7bc1a3610

Loading…
Cancel
Save

Powered by TurnKey Linux.