cpee 2.0.7 → 2.0.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. data/cockpit/config.json +3 -0
  3. data/cockpit/css/track.css +17 -6
  4. data/cockpit/css/ui.css +6 -2
  5. data/cockpit/css/wfadaptor.css +1 -1
  6. data/cockpit/edit.html +1 -0
  7. data/cockpit/index.html +2 -2
  8. data/cockpit/js/instance.js +75 -55
  9. data/cockpit/js/track.js +10 -0
  10. data/cockpit/js/ui.js +47 -16
  11. data/cockpit/templates/Track Test Local.xml +82 -0
  12. data/cockpit/templates/Track Test.xml +82 -0
  13. data/cockpit/templates/instantiate.local/Take_Sub.xml +59 -0
  14. data/cockpit/templates/instantiate/Take_Perf.xml +46 -0
  15. data/cockpit/templates/instantiate/Take_Sub.xml +58 -0
  16. data/cockpit/templates/instantiate/Take_X.xml +48 -0
  17. data/cockpit/themes/compact/rngs/call.rng +5 -0
  18. data/cockpit/themes/compact/rngs/callmanipulate.rng +6 -1
  19. data/cockpit/themes/compact/rngs/closed_loop.rng +53 -0
  20. data/cockpit/themes/compact/rngs/closed_loop_cancel.rng +5 -0
  21. data/cockpit/themes/compact/rngs/closed_loop_control.rng +28 -0
  22. data/cockpit/themes/compact/rngs/closed_loop_measuring.rng +9 -0
  23. data/cockpit/themes/compact/rngs/loop.rng +1 -1
  24. data/cockpit/themes/compact/rngs/parallel.rng +1 -1
  25. data/cockpit/themes/compact/symbols/closed_loop.svg +5 -0
  26. data/cockpit/themes/compact/symbols/closed_loop_cancel.svg +5 -0
  27. data/cockpit/themes/compact/symbols/closed_loop_control.svg +5 -0
  28. data/cockpit/themes/compact/symbols/closed_loop_measuring.svg +6 -0
  29. data/cockpit/themes/default/rngs/call.rng +5 -0
  30. data/cockpit/themes/default/rngs/callmanipulate.rng +6 -1
  31. data/cockpit/themes/default/rngs/closed_loop.rng +53 -0
  32. data/cockpit/themes/default/rngs/closed_loop_cancel.rng +5 -0
  33. data/cockpit/themes/default/rngs/closed_loop_control.rng +28 -0
  34. data/cockpit/themes/default/rngs/closed_loop_measuring.rng +9 -0
  35. data/cockpit/themes/default/rngs/loop.rng +1 -1
  36. data/cockpit/themes/default/rngs/parallel.rng +1 -1
  37. data/cockpit/themes/default/symbols/closed_loop.svg +5 -0
  38. data/cockpit/themes/default/symbols/closed_loop_cancel.svg +5 -0
  39. data/cockpit/themes/default/symbols/closed_loop_control.svg +5 -0
  40. data/cockpit/themes/default/symbols/closed_loop_measuring.svg +6 -0
  41. data/cockpit/themes/diana/rngs/alternative.rng +25 -0
  42. data/cockpit/themes/diana/rngs/call.rng +122 -0
  43. data/cockpit/themes/diana/rngs/callmanipulate.rng +145 -0
  44. data/cockpit/themes/diana/rngs/choose.rng +14 -0
  45. data/cockpit/themes/diana/rngs/closed_loop.rng +53 -0
  46. data/cockpit/themes/diana/rngs/closed_loop_cancel.rng +5 -0
  47. data/cockpit/themes/diana/rngs/closed_loop_control.rng +28 -0
  48. data/cockpit/themes/diana/rngs/closed_loop_measuring.rng +9 -0
  49. data/cockpit/themes/diana/rngs/critical.rng +5 -0
  50. data/cockpit/themes/diana/rngs/escape.rng +1 -0
  51. data/cockpit/themes/diana/rngs/group.rng +3 -0
  52. data/cockpit/themes/diana/rngs/loop.rng +22 -0
  53. data/cockpit/themes/diana/rngs/manipulate.rng +9 -0
  54. data/cockpit/themes/diana/rngs/otherwise.rng +22 -0
  55. data/cockpit/themes/diana/rngs/parallel.rng +21 -0
  56. data/cockpit/themes/diana/rngs/parallel_branch.rng +8 -0
  57. data/cockpit/themes/diana/rngs/scripts.rng +23 -0
  58. data/cockpit/themes/diana/rngs/stop.rng +5 -0
  59. data/cockpit/themes/diana/rngs/terminate.rng +1 -0
  60. data/cockpit/themes/diana/symbols/alternative.svg +5 -0
  61. data/cockpit/themes/diana/symbols/arrow.svg +3 -0
  62. data/cockpit/themes/diana/symbols/call.svg +6 -0
  63. data/cockpit/themes/diana/symbols/callmanipulate.svg +8 -0
  64. data/cockpit/themes/diana/symbols/choose.svg +5 -0
  65. data/cockpit/themes/diana/symbols/choose_exclusive.svg +5 -0
  66. data/cockpit/themes/diana/symbols/choose_inclusive.svg +4 -0
  67. data/cockpit/themes/diana/symbols/closed_loop.svg +5 -0
  68. data/cockpit/themes/diana/symbols/closed_loop_cancel.svg +5 -0
  69. data/cockpit/themes/diana/symbols/closed_loop_control.svg +5 -0
  70. data/cockpit/themes/diana/symbols/closed_loop_measuring.svg +6 -0
  71. data/cockpit/themes/diana/symbols/complex.svg +8 -0
  72. data/cockpit/themes/diana/symbols/critical.svg +4 -0
  73. data/cockpit/themes/diana/symbols/end.svg +3 -0
  74. data/cockpit/themes/diana/symbols/escape.svg +5 -0
  75. data/cockpit/themes/diana/symbols/event_end.svg +3 -0
  76. data/cockpit/themes/diana/symbols/loop.svg +5 -0
  77. data/cockpit/themes/diana/symbols/manipulate.svg +4 -0
  78. data/cockpit/themes/diana/symbols/otherwise.svg +5 -0
  79. data/cockpit/themes/diana/symbols/parallel.svg +5 -0
  80. data/cockpit/themes/diana/symbols/parallel_branch.svg +5 -0
  81. data/cockpit/themes/diana/symbols/parallel_branch_compact.svg +4 -0
  82. data/cockpit/themes/diana/symbols/parallel_branch_event.svg +14 -0
  83. data/cockpit/themes/diana/symbols/parallel_branch_normal.svg +5 -0
  84. data/cockpit/themes/diana/symbols/scripts.svg +4 -0
  85. data/cockpit/themes/diana/symbols/start.svg +3 -0
  86. data/cockpit/themes/diana/symbols/stop.svg +5 -0
  87. data/cockpit/themes/diana/symbols/terminate.svg +4 -0
  88. data/cockpit/themes/diana/theme.js +1650 -0
  89. data/cockpit/themes/extended/rngs/call.rng +5 -0
  90. data/cockpit/themes/extended/rngs/callmanipulate.rng +6 -1
  91. data/cockpit/themes/extended/rngs/closed_loop.rng +53 -0
  92. data/cockpit/themes/extended/rngs/closed_loop_cancel.rng +5 -0
  93. data/cockpit/themes/extended/rngs/closed_loop_control.rng +28 -0
  94. data/cockpit/themes/extended/rngs/closed_loop_measuring.rng +9 -0
  95. data/cockpit/themes/extended/rngs/loop.rng +1 -1
  96. data/cockpit/themes/extended/rngs/parallel.rng +1 -1
  97. data/cockpit/themes/extended/symbols/closed_loop.svg +5 -0
  98. data/cockpit/themes/extended/symbols/closed_loop_cancel.svg +5 -0
  99. data/cockpit/themes/extended/symbols/closed_loop_control.svg +5 -0
  100. data/cockpit/themes/extended/symbols/closed_loop_measuring.svg +6 -0
  101. data/cockpit/themes/extended/theme.js +4 -0
  102. data/cockpit/themes/model/symbols/closed_loop.svg +5 -0
  103. data/cockpit/themes/model/symbols/closed_loop_cancel.svg +5 -0
  104. data/cockpit/themes/model/symbols/closed_loop_control.svg +5 -0
  105. data/cockpit/themes/model/symbols/closed_loop_measuring.svg +6 -0
  106. data/cockpit/themes/model/theme.js +1 -1
  107. data/cockpit/themes/packed/rngs/call.rng +5 -0
  108. data/cockpit/themes/packed/rngs/callmanipulate.rng +6 -1
  109. data/cockpit/themes/packed/rngs/closed_loop.rng +53 -0
  110. data/cockpit/themes/packed/rngs/closed_loop_cancel.rng +5 -0
  111. data/cockpit/themes/packed/rngs/closed_loop_control.rng +28 -0
  112. data/cockpit/themes/packed/rngs/closed_loop_measuring.rng +9 -0
  113. data/cockpit/themes/packed/rngs/loop.rng +1 -1
  114. data/cockpit/themes/packed/rngs/parallel.rng +1 -1
  115. data/cockpit/themes/packed/symbols/closed_loop.svg +5 -0
  116. data/cockpit/themes/packed/symbols/closed_loop_cancel.svg +5 -0
  117. data/cockpit/themes/packed/symbols/closed_loop_control.svg +5 -0
  118. data/cockpit/themes/packed/symbols/closed_loop_measuring.svg +6 -0
  119. data/cockpit/themes/preset/rngs/call.rng +5 -0
  120. data/cockpit/themes/preset/rngs/callmanipulate.rng +6 -1
  121. data/cockpit/themes/preset/rngs/closed_loop.rng +53 -0
  122. data/cockpit/themes/preset/rngs/closed_loop_cancel.rng +5 -0
  123. data/cockpit/themes/preset/rngs/closed_loop_control.rng +28 -0
  124. data/cockpit/themes/preset/rngs/closed_loop_measuring.rng +9 -0
  125. data/cockpit/themes/preset/rngs/loop.rng +1 -1
  126. data/cockpit/themes/preset/rngs/parallel.rng +1 -1
  127. data/cockpit/themes/preset/symbols/closed_loop.svg +5 -0
  128. data/cockpit/themes/preset/symbols/closed_loop_cancel.svg +5 -0
  129. data/cockpit/themes/preset/symbols/closed_loop_control.svg +5 -0
  130. data/cockpit/themes/preset/symbols/closed_loop_measuring.svg +6 -0
  131. data/cockpit/track.html +37 -8
  132. data/cpee.gemspec +2 -2
  133. data/lib/cpee/implementation.rb +15 -6
  134. data/lib/cpee/implementation_notifications.rb +80 -51
  135. data/lib/cpee/implementation_properties.rb +5 -2
  136. data/lib/cpee/persistence.rb +3 -0
  137. data/server/handlerwrappers/default.rb +3 -0
  138. data/server/routing/forward-events.rb +2 -1
  139. data/server/routing/forward-votes.rb +1 -1
  140. data/server/server.conf +4 -0
  141. data/tools/cpee +16 -8
  142. data/tools/server/server.rb +1 -0
  143. metadata +109 -10
  144. data/cockpit/templates/convert_cpee2.rb +0 -15
  145. data/cockpit/themes/convert_cpee2.rb +0 -8
@@ -0,0 +1,5 @@
1
+ <element xmlns="http://relaxng.org/ns/structure/1.0" xmlns:rngui="http://rngui.org" rngui:version="1.2" ns="http://cpee.org/ns/description/1.0" name="closed_loop_cancel" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
2
+ <attribute name="condition" rngui:label="Condition">
3
+ <data type="string" rngui:label="Condition"/>
4
+ </attribute>
5
+ </element>
@@ -0,0 +1,28 @@
1
+ <element xmlns="http://relaxng.org/ns/structure/1.0" xmlns:rngui="http://rngui.org" rngui:version="1.2" ns="http://cpee.org/ns/description/1.0" name="closed_loop_control" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
2
+ <element name="_expected" rngui:header="Values Expected to Change">
3
+ <zeroOrMore rngui:label="Add Value">
4
+ <element name="change">
5
+ <element name="type" rngui:label="Control type">
6
+ <choice>
7
+ <value>:PID</value>
8
+ <value>:PI</value>
9
+ <value>:PD</value>
10
+ <value>:P</value>
11
+ <value>:I</value>
12
+ <value>:PT1</value>
13
+ <value>:PT2</value>
14
+ </choice>
15
+ </element>
16
+ <element name="value" rngui:label="Value">
17
+ <data type="string" rngui:label="a dataelement"/>
18
+ </element>
19
+ <element name="upper" rngui:label="Upper Limit">
20
+ <data type="float" rngui:label="Max value after next measure"/>
21
+ </element>
22
+ <element name="lower" rngui:label="Lower Limit">
23
+ <data type="float" rngui:label="Min value after next measure"/>
24
+ </element>
25
+ </element>
26
+ </zeroOrMore>
27
+ </element>
28
+ </element>
@@ -0,0 +1,9 @@
1
+ <element xmlns="http://relaxng.org/ns/structure/1.0" xmlns:rngui="http://rngui.org" rngui:version="1.2" ns="http://cpee.org/ns/description/1.0" name="closed_loop_measuring" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
2
+ <element name="_expected" rngui:header="Values Expected to Change">
3
+ <zeroOrMore rngui:label="Add Value">
4
+ <element name="value" rngui:label="Value">
5
+ <data type="string" rngui:label="a dataelement"/>
6
+ </element>
7
+ </zeroOrMore>
8
+ </element>
9
+ </element>
@@ -19,4 +19,4 @@
19
19
  <data type="nonNegativeInteger" rngui:label="Times"/>
20
20
  </element>
21
21
  </element>
22
- </element>
22
+ </element>
@@ -18,4 +18,4 @@
18
18
  <data type="string"/>
19
19
  </attribute>
20
20
  </element>
21
- </element>
21
+ </element>
@@ -0,0 +1,5 @@
1
+ <svg class="clickable" xmlns="http://www.w3.org/2000/svg">
2
+ <rect transform="rotate(45,14,12)" x="7" y="3" width="21" height="21" class="cline hfill stand"/>
3
+ <path d="m 17.620194,6.2873424 c 7.577463,7.5774646 -7.577463,10.5124376 0,18.0898996" class="stand" style="fill-opacity: 0"/>
4
+ <path d="m 14.036033,6.2873424 c 7.577463,7.5774646 -7.5774629,10.5124376 0,18.0898996" class="stand" style="fill-opacity: 0"/>
5
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg class="clickable" xmlns="http://www.w3.org/2000/svg">
2
+ <circle cx="15" cy="15" r="14" class="cline stand"/>
3
+ <circle cx="15" cy="15" r="11" class="rfill hfill cline stand"/>
4
+ <path d="M 7.8583963,10.061007 10.29692,7.6153325 15.17399,12.506704 20.051062,7.6153325 22.489583,10.06103 17.612536,14.952378 22.489583,19.84375 20.051062,22.289424 15.17399,17.398076 10.296942,22.289424 7.8583963,19.84375 12.735466,14.952378 Z" class="stand"/>
5
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg class="clickable" xmlns="http://www.w3.org/2000/svg">
2
+ <circle cx="15" cy="15" r="14" class="cline stand"/>
3
+ <circle cx="15" cy="15" r="11" class="rfill hfill cline stand"/>
4
+ <circle cx="15" cy="15" r="7" class="stand"/> <path d="M 17,17 19.84375,19.84375" class="black stand"/>
5
+ </svg>
@@ -0,0 +1,6 @@
1
+ <svg class="clickable" xmlns="http://www.w3.org/2000/svg">
2
+ <circle cx="15" cy="15" r="14" class="cline stand"/>
3
+ <circle cx="15" cy="15" r="11" class="rfill hfill cline stand"/>
4
+ <path d="M 14.904335,6.0646408 A 9.0152948,9.0152948 0 0 0 5.9550908,15.079625 H 23.985106 a 9.0152948,9.0152948 0 0 0 -9.015008,-9.0149842 9.0152948,9.0152948 0 0 0 -0.06567,0 z" class="standfat"/>
5
+ <path d="M 14.970098,15.079625 11.963937,10.870986" class="black stand"/>
6
+ </svg>
@@ -62,12 +62,41 @@
62
62
  <div class='hidden' id='relaxngworker'></div>
63
63
  <div id="trackfull">
64
64
  <div id='graphcolumn'>
65
- <div id="usage">
66
- <span id="title"></span> | <span id='state'>
67
- <span id="state_text"></span>
65
+ <div id="trackusage">
66
+ <div id='tracktitle'>
67
+ <span>
68
+ <a class="x-ui-button" name="glob_reload" title='reload' href=''>
69
+ <svg viewBox="0 -1.5 7 12" width="10" height="16">
70
+ <path
71
+ style="fill:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stop-color:#000000"
72
+ d="M 3.5,1.5 C 1.431441,1.5001975 -0.24540803,3.1770466 -0.24560554,5.2456055 -0.2454082,7.3141647 1.4314408,8.991014 3.5,8.9912113 5.5685591,8.991014 7.2454081,7.3141647 7.2456054,5.2456055 7.2454079,3.1770466 5.5685589,1.5001975 3.5,1.5 Z M 3.437195,4.0616198 c 0.020931,-5.551e-4 0.041873,-5.551e-4 0.062805,0 0.6537674,3.133e-4 1.1836723,0.5302183 1.1839856,1.1839857 C 4.6836723,5.8993729 4.1537674,6.4292778 3.5,6.4295912 2.8462325,6.4292778 2.3163276,5.8993729 2.3160142,5.2456055 2.315414,4.6155841 2.8080758,4.0953252 3.437195,4.0616198 Z"/>
73
+ </svg>
74
+ </a>
75
+ <a class="x-ui-button" name="glob_edit" title='edit' target='_blank' href='' id='current-monitor'><svg viewBox="0 -1.5 7 12" width="10" height="16">
76
+ <path
77
+ style="fill:#000000;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
78
+ d="M -0.25,7.8194404 0.57057194,10.599984 3.1882886,9.3540573 Z"/>
79
+ <path
80
+ style="fill:#000000;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
81
+ d="M 3.5215262,8.6074434 6.0527848,2.9361926 2.6144961,1.4015756 0.08323736,7.0728263 Z"/>
82
+ <path
83
+ style="fill:#000000;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
84
+ d="M 6.4439758,2.0597335 6.9719316,0.87685566 3.533643,-0.6577613 3.005687,0.52511656 Z"/>
85
+ </svg></a>
86
+ <a class="x-ui-button" name="glob_unshow" title='unshow'>
87
+ <svg viewBox="0 -1.5 7 12" width="10" height="16">
88
+ <path
89
+ style="fill:#000000;stroke-width:0;stop-color:#000000"
90
+ d="M 5.75,1.4999999 3.5,3.75 1.25,1.4999999 -0.25000013,3 2,5.25 -0.25000013,7.5 1.25,9.0000002 3.5,6.75 5.75,9.0000002 7.2500001,7.5 5,5.25 7.2500001,3 Z"/>
91
+ </svg>
92
+ </a>
93
+ </span>
94
+ <span> - </span>
95
+ <span id="title">Loading ...</span>
96
+ </div>
97
+ <div id='state'>
68
98
  <span id="state_any">
69
- <span> </span>
70
- <button name="state_start" title='start'>
99
+ <button name="state_start" title='start' style='display:none'>
71
100
  <svg viewBox="0 -1.5 7 12" width="10" height="16">
72
101
  <path
73
102
  style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
@@ -82,7 +111,6 @@
82
111
  </svg>
83
112
  </button>
84
113
  <span id="state_extended">
85
- <span> / </span>
86
114
  <button name="state_replay" title='replay'>
87
115
  <svg viewBox="0 -1.5 7 12" width="10" height="16">
88
116
  <path
@@ -90,7 +118,6 @@
90
118
  d="m -0.24999978,8.9999993 c 0,-2.7488167 0,-5.4976332 0,-8.24644997 C 1.1183278,0.76955385 2.4884861,0.71666052 3.8555376,0.79065567 4.5083287,0.83810218 5.2238942,1.0790874 5.5755039,1.7307256 6.1661398,2.7080902 6.0299484,4.2180754 5.1108772,4.9019222 4.7622397,5.1617467 4.3480204,5.2956156 3.9336064,5.3605366 4.9287868,5.9394132 5.4254071,7.0996814 6.0167729,8.0858876 6.1549588,8.3769029 6.4657247,8.7723933 6.5,8.9999999 c -0.5944185,0 -1.1888371,0 -1.7832559,0 C 4.0758679,7.9893475 3.4946311,6.9294648 2.7923497,5.9678488 2.4230355,5.5319748 1.8508715,5.5458842 1.3513114,5.5576027 c -0.1507526,-0.00412 -0.044576,0.272902 -0.076255,0.3990664 0,1.0144436 0,2.028887 0,3.0433307 -0.50835205,-3e-7 -1.01670555,8e-7 -1.52505618,-5e-7 z M 1.2750578,4.2411336 C 2.111059,4.2189781 2.9581852,4.3060525 3.7849326,4.1387394 4.4863715,3.8915585 4.5732952,2.6432813 3.9026802,2.2941453 3.5098807,2.068434 3.050719,2.1857044 2.6267379,2.1489138 c -0.4505578,-0.00242 -0.90112,0.00147 -1.3516801,-3.456e-4 0,0.6975176 0,1.3950347 0,2.0925522 z"
91
119
  </svg>
92
120
  </button>
93
- <span> / </span>
94
121
  <button name="state_abandon" title='abandon'>
95
122
  <svg viewBox="0 -1.5 7 12" width="10" height="16">
96
123
  <path
@@ -99,8 +126,10 @@
99
126
  </svg>
100
127
  </button>
101
128
  </span>
129
+ <span> - Status: </span>
102
130
  </span>
103
- </span>
131
+ <span id="state_text">loading ...</span>
132
+ </div>
104
133
  </div>
105
134
  <div id='graphgrid'>
106
135
  <svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:x="http://www.w3.org/1999/xlink" id='graphcanvas' width='1' height='1'></svg>
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "cpee"
3
- s.version = "2.0.7"
3
+ s.version = "2.0.14"
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.license = "LGPL-3.0"
6
6
  s.summary = "Preliminary release of cloud process execution engine (cpee.org). If you just need workflow execution, without a rest service exposing it, then use WEEL."
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
21
21
  s.email = 'juergen.mangler@gmail.com'
22
22
  s.homepage = 'http://cpee.org/'
23
23
 
24
- s.add_runtime_dependency 'riddl', '~> 0.105'
24
+ s.add_runtime_dependency 'riddl', '~> 0.108'
25
25
  s.add_runtime_dependency 'weel', '~> 1.99', '>= 1.99.90'
26
26
  s.add_runtime_dependency 'highline', '~> 2.0'
27
27
  s.add_runtime_dependency 'json', '~>2.1'
@@ -72,7 +72,9 @@ module CPEE
72
72
  opts[:infinite_loop_stop] ||= 10000
73
73
  opts[:redis_path] ||= '/tmp/redis.sock'
74
74
  opts[:redis_db] ||= 3
75
+ opts[:sse_keepalive_frequency] ||= 10
75
76
 
77
+ opts[:sse_connections] = {}
76
78
  opts[:redis] = Redis.new(path: opts[:redis_path], db: opts[:redis_db])
77
79
  opts[:statemachine] = CPEE::StateMachine.new opts[:states], %w{running simulating replaying finishing stopping abandoned finished} do |id|
78
80
  opts[:redis].get("instance:#{id}/state")
@@ -88,13 +90,20 @@ module CPEE
88
90
 
89
91
  Proc.new do
90
92
  parallel do
91
- CPEE::watch_services(@riddl_opts[:watchdog_start_off])
92
- EM.add_periodic_timer(@riddl_opts[:watchdog_frequency]) do
93
- CPEE::watch_services(@riddl_opts[:watchdog_start_off])
93
+ CPEE::watch_services(opts[:watchdog_start_off])
94
+ EM.add_periodic_timer(opts[:watchdog_frequency]) do ### start services
95
+ CPEE::watch_services(opts[:watchdog_start_off])
96
+ end
97
+ EM.defer do ### catch all sse connections
98
+ CPEE::Notifications::sse_distributor(opts)
99
+ end
100
+ EM.add_periodic_timer(opts[:sse_keepalive_frequency]) do
101
+ CPEE::Notifications::sse_heartbeat(opts)
94
102
  end
95
103
  end
104
+
96
105
  cleanup do
97
- CPEE::cleanup_services(@riddl_opts[:watchdog_start_off])
106
+ CPEE::cleanup_services(opts[:watchdog_start_off])
98
107
  end
99
108
 
100
109
  interface 'main' do
@@ -183,7 +192,7 @@ module CPEE
183
192
  doc = XML::Smart::open_unprotected(opts[:properties_init])
184
193
  doc.register_namespace 'p', 'http://cpee.org/ns/properties/2.0'
185
194
  name = @p[0].value
186
- id = redis.zcount('instances','-inf','+inf').to_i + 1
195
+ id = redis.zrevrange('instances', 0, 0).first.to_i + 1
187
196
  uuid = SecureRandom.uuid
188
197
  instance = 'instance:' + id.to_s
189
198
  redis.multi do |multi|
@@ -218,7 +227,7 @@ module CPEE
218
227
  end
219
228
  end rescue nil # all the ones that are not ok, are ignored
220
229
  end
221
- multi.set(File.join(instance, 'attributes', 'uuid'), SecureRandom.uuid)
230
+ multi.set(File.join(instance, 'attributes', 'uuid'), uuid)
222
231
  multi.zadd(File.join(instance, 'attributes'), -2, 'uuid')
223
232
  multi.set(File.join(instance, 'attributes', 'info'), name)
224
233
  multi.zadd(File.join(instance, 'attributes'), -1, 'info')
@@ -73,35 +73,40 @@ module CPEE
73
73
  id = @a[0]
74
74
  opts = @a[1]
75
75
  key = @r[-1]
76
- Riddl::Parameter::Complex.new("subscriptions","text/xml") do
77
- ret = XML::Smart::string <<-END
78
- <subscription xmlns='http://riddl.org/ns/common-patterns/notifications-producer/2.0'/>
79
- END
80
- url = CPEE::Persistence::extract_item(id,opts,File.join('handler',key,'url'))
81
- ret.root.attributes['url'] = url if url && !url.empty?
82
- items = {}
83
- CPEE::Persistence::extract_handler(id,opts,key).each do |h|
84
- t, i, v = h.split('/')
85
- items[t] ||= []
86
- items[t] << [i,v]
87
- end
88
- items.each do |k,v|
89
- ret.root.add('topic').tap do |n|
90
- n.attributes['id'] = k
91
- v.each do |e|
92
- n.add *e
76
+ if CPEE::Persistence::exists_handler?(id,opts,key)
77
+ Riddl::Parameter::Complex.new("subscriptions","text/xml") do
78
+ ret = XML::Smart::string <<-END
79
+ <subscription xmlns='http://riddl.org/ns/common-patterns/notifications-producer/2.0'/>
80
+ END
81
+ url = CPEE::Persistence::extract_item(id,opts,File.join('handler',key,'url'))
82
+ ret.root.attributes['url'] = url if url && !url.empty?
83
+ items = {}
84
+ CPEE::Persistence::extract_handler(id,opts,key).each do |h|
85
+ t, i, v = h.split('/')
86
+ items[t] ||= []
87
+ items[t] << [i,v]
88
+ end
89
+ items.each do |k,v|
90
+ ret.root.add('topic').tap do |n|
91
+ n.attributes['id'] = k
92
+ v.each do |e|
93
+ n.add *e
94
+ end
93
95
  end
94
96
  end
97
+ ret.to_s
95
98
  end
96
- ret.to_s
97
- end
99
+ else
100
+ @status = 404
101
+ end
98
102
  end
99
103
  end #}}}
100
104
 
101
- class CreateSubscription < Riddl::Implementation #{{{
105
+ class CreateSubscription < Riddl::Implementation #{{{
102
106
  def response
103
107
  id = @a[0]
104
108
  opts = @a[1]
109
+
105
110
  key = Digest::MD5.hexdigest(Kernel::rand().to_s)
106
111
 
107
112
  url = @p[0].name == 'url' ? @p.shift.value : nil
@@ -124,15 +129,19 @@ module CPEE
124
129
  opts = @a[1]
125
130
  key = @r.last
126
131
 
127
- url = @p[0].name == 'url' ? @p.shift.value : nil
128
- values = []
129
- while @p.length > 0
130
- topic = @p.shift.value
131
- base = @p.shift
132
- type = base.name
133
- values += base.value.split(',').map { |i| File.join(topic,type[0..-2],i) }
132
+ if CPEE::Persistence::exists_handler?(id,opts,key)
133
+ url = @p[0].name == 'url' ? @p.shift.value : nil
134
+ values = []
135
+ while @p.length > 0
136
+ topic = @p.shift.value
137
+ base = @p.shift
138
+ type = base.name
139
+ values += base.value.split(',').map { |i| File.join(topic,type[0..-2],i) }
140
+ end
141
+ @header = CPEE::Persistence::set_handler(id,opts,key,url,values,true)
142
+ else
143
+ @status = 404
134
144
  end
135
- @header = CPEE::Persistence::set_handler(id,opts,key,url,values,true)
136
145
  end
137
146
  end #}}}
138
147
 
@@ -146,41 +155,61 @@ module CPEE
146
155
  opts = @a[1]
147
156
  key = @r.last
148
157
 
149
- DeleteSubscription::set(id,opts,key)
158
+ if CPEE::Persistence::exists_handler?(id,opts,key)
159
+ DeleteSubscription::set(id,opts,key)
160
+ else
161
+ @status = 404
162
+ end
150
163
  nil
151
164
  end
152
165
  end #}}}
153
166
 
154
- class SSE < Riddl::SSEImplementation #{{{
155
- def onopen
156
- @id = @a[0]
157
- @opts = @a[1]
158
- @key = @r[-2]
159
- @conn = Redis.new(path: @opts[:redis_path], db: @opts[:redis_db])
160
- EM.defer do
161
- @conn.subscribe("forward:#{@id}/#{@key}", "forward-end:#{@id}/#{@key}") do |on|
162
- on.message do |what, message|
163
- if what == "forward-end:#{@id}/#{@key}"
164
- @conn.unsubscribe
165
- else
166
- send message
167
+ def self::sse_distributor(opts) #{{{
168
+ conn = Redis.new(path: opts[:redis_path], db: opts[:redis_db])
169
+ conn.psubscribe('forward:*','event:state/change') do |on|
170
+ on.pmessage do |pat, what, message|
171
+ if pat == 'forward:*'
172
+ _, id, key = what.match(/forward(-end)?:([^\/]+)\/(.+)/).captures
173
+ opts.dig(:sse_connections,id.to_i,key)&.send message
174
+ elsif pat == 'event:state/change'
175
+ mess = JSON.parse(message[message.index(' ')+1..-1])
176
+ state = mess.dig('content','state')
177
+ if state == 'finished' || state == 'abandoned'
178
+ opts.dig(:sse_connections,mess.dig('instance').to_i)&.each do |key,sse|
179
+ EM.add_timer(10) do # just to be sure that all messages arrived. 10 seconds should be enough ... we think ... therefore we are (not sure)
180
+ sse.close
181
+ end
167
182
  end
168
183
  end
169
184
  end
170
- @conn.close
171
185
  end
172
- EM.defer do
173
- until closed?
174
- send_with_id 'hearbeat', '42'
175
- sleep 10
176
- end
186
+ end
187
+ conn.close
188
+ end #}}}
189
+ def self::sse_heartbeat(opts) #{{{
190
+ opts.dig(:sse_connections).each do |id,keys|
191
+ keys.each do |key,sse|
192
+ sse.send_with_id('heartbeat', '42') unless sse&.closed?
193
+ end
194
+ end
195
+ end #}}}
196
+ class SSE < Riddl::SSEImplementation #{{{
197
+ def onopen
198
+ @opts = @a[1]
199
+ @id = @a[0]
200
+ @key = @r[-2]
201
+ if CPEE::Persistence::exists_handler?(@id,@opts,@key)
202
+ @opts[:sse_connections][@id] ||= {}
203
+ @opts[:sse_connections][@id][@key] = self
204
+ true
205
+ else
206
+ false
177
207
  end
178
208
  end
179
209
 
180
210
  def onclose
181
- tredis = Redis.new(path: @opts[:redis_path], db: @opts[:redis_db])
182
- tredis.publish("forward-end:#{@id}/#{@key}",true)
183
- tredis.close
211
+ @opts.dig(:sse_connections,@id)&.delete(@key)
212
+ @opts.dig(:sse_connections)&.delete(@id) if @opts.dig(:sse_connections,@id)&.length == 0
184
213
  DeleteSubscription::set(@id,@opts,@key)
185
214
  end
186
215
  end #}}}
@@ -660,8 +660,11 @@ module CPEE
660
660
  @status = 422 # semantic error
661
661
  else
662
662
  begin
663
- PutDescription::set(id,opts,@p[0].value.read)
664
- rescue
663
+ # force-encoding because johannes managed to sneak in ascii special characters. why the browser is not sanitizing it is beyond me.
664
+ PutDescription::set(id,opts,@p[0].value.read.force_encoding('UTF-8'))
665
+ rescue => e
666
+ puts e.message
667
+ puts e.backtrace
665
668
  @status = 400
666
669
  end
667
670
  end
@@ -125,6 +125,9 @@ module CPEE
125
125
  def self::extract_handler(id,opts,key) #{{{
126
126
  opts[:redis].smembers("instance:#{id}/handlers/#{key}")
127
127
  end #}}}
128
+ def self::exists_handler?(id,opts,key) #{{{
129
+ opts[:redis].exists?("instance:#{id}/handlers/#{key}")
130
+ end #}}}
128
131
  def self::extract_handlers(id,opts) #{{{
129
132
  opts[:redis].smembers("instance:#{id}/handlers").map do |e|
130
133
  [e, opts[:redis].get("instance:#{id}/handlers/#{e}/url")]
@@ -126,6 +126,9 @@ class DefaultHandlerWrapper < WEEL::HandlerWrapperBase
126
126
  if headers['CPEE_INSTANTIATION']
127
127
  @controller.notify("task/instantiation", :activity_uuid => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :received => CPEE::ValueHelper.parse(headers['CPEE_INSTANTIATION']))
128
128
  end
129
+ if headers['CPEE_EVENT']
130
+ @controller.notify("task/#{headers['CPEE_EVENT'].gsub(/[^\w_-]/,'')}", :activity_uuid => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint)
131
+ end
129
132
  if headers['CPEE_CALLBACK'] && headers['CPEE_CALLBACK'] == 'true' && result.any?
130
133
  headers['CPEE_UPDATE'] = true
131
134
  callback result, headers
@@ -39,7 +39,8 @@ Daemonite.new do |opts|
39
39
  if url.nil? || url == ""
40
40
  redis.publish("forward:#{instance}/#{key}",mess)
41
41
  else
42
- client = Riddl::Client.new(url,'http://riddl.org/ns/common-patterns/notifications-consumer/2.0/consumer.xml')
42
+ p "#{type}/#{topic}/#{event}-#{url}"
43
+ client = Riddl::Client.new(url)
43
44
  client.post [
44
45
  Riddl::Parameter::Simple::new('type',type),
45
46
  Riddl::Parameter::Simple::new('topic',topic),