cpee 1.4.8 → 1.4.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/cockpit/config.json +6 -0
- data/cockpit/css/ui.css +7 -7
- data/cockpit/index.html +4 -4
- data/cockpit/js/instance.js +6 -3
- data/cockpit/themes/compact/theme.js +107 -6
- data/cockpit/themes/default/rngs/call.rng +29 -0
- data/cockpit/themes/default/rngs/callmanipulate.rng +29 -0
- data/cpee.gemspec +1 -1
- data/lib/cpee/controller.rb +1 -1
- data/lib/cpee/instantiation.rb +44 -21
- data/lib/engine/instances.rng +5 -2
- data/lib/instantiation.xml +5 -1
- data/log/elasticsearch.rb +1 -106
- data/log/elasticsearch_logging.rb +237 -0
- data/log/legacy/test_es.rb +26 -0
- data/log/legacy/test_split.rb +211 -0
- data/log/trace.yaml +17717 -0
- data/log/trace_sic.yaml +18343 -0
- data/server/handlerwrappers/default.rb +28 -23
- data/server/instances/1/properties.xml +158 -31
- data/server/instances/2/properties.xml +137 -12
- data/server/instances/3/properties.xml +116 -80
- data/server/resources/base.xml +78 -0
- data/server/resources/test.rb +19 -0
- data/server/resources/test.xml +33 -0
- data/server/resources/topics.xml +6 -3
- data/server/resources/transformation_dslx.xsl +5 -0
- data/server/server.pid +1 -0
- metadata +13 -71
- data/log/logs/1/test +0 -1
- data/server/instances/10/notifications/182434032285ca1d06a8b6554b8889c8/consumer-secret +0 -1
- data/server/instances/10/notifications/182434032285ca1d06a8b6554b8889c8/producer-secret +0 -1
- data/server/instances/10/notifications/182434032285ca1d06a8b6554b8889c8/subscription.xml +0 -23
- data/server/instances/10/notifications/512a3785631a5245dbb45fa150ea72ed/consumer-secret +0 -1
- data/server/instances/10/notifications/512a3785631a5245dbb45fa150ea72ed/producer-secret +0 -1
- data/server/instances/10/notifications/512a3785631a5245dbb45fa150ea72ed/subscription.xml +0 -6
- data/server/instances/10/properties.xml +0 -187
- data/server/instances/11/properties.xml +0 -191
- data/server/instances/12/properties.xml +0 -191
- data/server/instances/13/properties.xml +0 -204
- data/server/instances/14/properties.xml +0 -31
- data/server/instances/15/properties.xml +0 -30
- data/server/instances/16/properties.xml +0 -29
- data/server/instances/17/properties.xml +0 -29
- data/server/instances/18/properties.xml +0 -31
- data/server/instances/19/properties.xml +0 -31
- data/server/instances/20/properties.xml +0 -191
- data/server/instances/21/properties.xml +0 -156
- data/server/instances/22/properties.xml +0 -118
- data/server/instances/23/properties.xml +0 -118
- data/server/instances/24/properties.xml +0 -156
- data/server/instances/25/properties.xml +0 -156
- data/server/instances/26/properties.xml +0 -156
- data/server/instances/27/properties.xml +0 -140
- data/server/instances/28/properties.xml +0 -156
- data/server/instances/29/properties.xml +0 -156
- data/server/instances/30/properties.xml +0 -354
- data/server/instances/31/properties.xml +0 -354
- data/server/instances/313/notifications/crisp/consumer-secret +0 -1
- data/server/instances/313/notifications/crisp/producer-secret +0 -1
- data/server/instances/313/notifications/crisp/subscription.xml +0 -7
- data/server/instances/313/notifications/logging/consumer-secret +0 -1
- data/server/instances/313/notifications/logging/producer-secret +0 -1
- data/server/instances/313/notifications/logging/subscription.xml +0 -7
- data/server/instances/313/notifications/logging_yaml/consumer-secret +0 -1
- data/server/instances/313/notifications/logging_yaml/producer-secret +0 -1
- data/server/instances/313/notifications/logging_yaml/subscription.xml +0 -7
- data/server/instances/313/properties.xml +0 -524
- data/server/instances/32/properties.xml +0 -628
- data/server/instances/33/properties.xml +0 -156
- data/server/instances/4/properties.xml +0 -114
- data/server/instances/5/properties.xml +0 -114
- data/server/instances/6/properties.xml +0 -206
- data/server/instances/662/notifications/crisp/consumer-secret +0 -1
- data/server/instances/662/notifications/crisp/producer-secret +0 -1
- data/server/instances/662/notifications/crisp/subscription.xml +0 -7
- data/server/instances/662/notifications/logging/consumer-secret +0 -1
- data/server/instances/662/notifications/logging/producer-secret +0 -1
- data/server/instances/662/notifications/logging/subscription.xml +0 -7
- data/server/instances/662/notifications/logging_yaml/consumer-secret +0 -1
- data/server/instances/662/notifications/logging_yaml/producer-secret +0 -1
- data/server/instances/662/notifications/logging_yaml/subscription.xml +0 -7
- data/server/instances/662/properties.xml +0 -427
- data/server/instances/663/properties.xml +0 -31
- data/server/instances/664/properties.xml +0 -425
- data/server/instances/665/properties.xml +0 -425
- data/server/instances/666/properties.xml +0 -427
- data/server/instances/667/properties.xml +0 -427
- data/server/instances/668/properties.xml +0 -425
- data/server/instances/669/properties.xml +0 -425
- data/server/instances/670/properties.xml +0 -31
- data/server/instances/671/properties.xml +0 -158
- data/server/instances/672/properties.xml +0 -199
- data/server/instances/673/properties.xml +0 -52
- data/server/instances/7/properties.xml +0 -156
- data/server/instances/8/properties.xml +0 -118
- data/server/instances/9/properties.xml +0 -120
data/lib/engine/instances.rng
CHANGED
@@ -19,7 +19,7 @@
|
|
19
19
|
<element name="instances">
|
20
20
|
<zeroOrMore>
|
21
21
|
<ref name="instance"/>
|
22
|
-
</zeroOrMore>
|
22
|
+
</zeroOrMore>
|
23
23
|
</element>
|
24
24
|
</start>
|
25
25
|
|
@@ -28,11 +28,14 @@
|
|
28
28
|
<attribute name='id'>
|
29
29
|
<data type="integer"/>
|
30
30
|
</attribute>
|
31
|
+
<attribute name='uuid'>
|
32
|
+
<data type="string"/>
|
33
|
+
</attribute>
|
31
34
|
<attribute name='state'>
|
32
35
|
<data type="string"/>
|
33
36
|
</attribute>
|
34
37
|
<data type="string"/>
|
35
38
|
</element>
|
36
|
-
</define>
|
39
|
+
</define>
|
37
40
|
|
38
41
|
</grammar>
|
data/lib/instantiation.xml
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
<description datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" xmlns="http://riddl.org/ns/description/1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
|
2
|
-
|
3
2
|
<message name="xmlsimple">
|
4
3
|
<parameter name="xml" mimetype="*/xml"/>
|
5
4
|
</message>
|
@@ -64,6 +63,11 @@
|
|
64
63
|
<resource relative="url">
|
65
64
|
<post in="url" out="result"/>
|
66
65
|
</resource>
|
66
|
+
<resource relative="callback">
|
67
|
+
<resource>
|
68
|
+
<post/>
|
69
|
+
</resource>
|
70
|
+
</resource>
|
67
71
|
</resource>
|
68
72
|
|
69
73
|
</description>
|
data/log/elasticsearch.rb
CHANGED
@@ -1,111 +1,6 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
|
-
|
3
|
-
require 'json'
|
4
|
-
require 'yaml'
|
5
|
-
require 'rubygems'
|
6
|
-
require 'riddl/server'
|
7
|
-
require 'riddl/utils/fileserve'
|
8
|
-
require 'json'
|
9
|
-
require 'time'
|
2
|
+
require_relative 'elasticsearch_logging'
|
10
3
|
|
11
|
-
require 'faraday'
|
12
|
-
require 'elasticsearch'
|
13
|
-
require 'logger'
|
14
|
-
|
15
|
-
class Logging < Riddl::Implementation #{{{
|
16
|
-
def doc(topic,event_name,esc,template,instancenr,notification)
|
17
|
-
uuid = notification['instance_uuid']
|
18
|
-
return unless uuid
|
19
|
-
|
20
|
-
activity = notification['activity']
|
21
|
-
parameters = notification['parameters']
|
22
|
-
receiving = notification['received']
|
23
|
-
|
24
|
-
log = YAML::load(File.read(template))
|
25
|
-
log["log"]["trace"]["concept:name"] ||= instancenr.to_i
|
26
|
-
log["log"]["trace"]["cpee:name"] ||= notification['instance_name'] if notification["instance_name"]
|
27
|
-
log["log"]["trace"]["cpee:uuid"] ||= notification['instance_uuid'] if notification["instance_uuid"]
|
28
|
-
unless esc.indices.exists? index: 'trace'
|
29
|
-
esc.indices.create index: 'trace', body: {
|
30
|
-
"mappings" => {
|
31
|
-
"entry" => {
|
32
|
-
"properties" => {
|
33
|
-
"concept:name" => {
|
34
|
-
"type" => "integer"
|
35
|
-
},
|
36
|
-
"cpee:name" => {
|
37
|
-
"type" => "text"
|
38
|
-
},
|
39
|
-
"cpee:uuid": {
|
40
|
-
"type" => "text"
|
41
|
-
}
|
42
|
-
}
|
43
|
-
}
|
44
|
-
}
|
45
|
-
}
|
46
|
-
end
|
47
|
-
|
48
|
-
esc.index index: 'trace', type: 'entry', id: log["log"]["trace"]["cpee:uuid"], body: log["log"]["trace"]
|
49
|
-
p notification['attributes']
|
50
|
-
|
51
|
-
event = {}
|
52
|
-
event["trace:id"] = instancenr
|
53
|
-
event["concept:name"] = notification["label"] if notification["label"]
|
54
|
-
if notification["endpoint"]
|
55
|
-
event["concept:endpoint"] = notification["endpoint"]
|
56
|
-
end
|
57
|
-
event["id:id"] = (activity.nil? || activity == "") ? 'external' : activity
|
58
|
-
event["cpee:uuid"] = notification['instance_uuid'] if notification["instance_uuid"]
|
59
|
-
case event_name
|
60
|
-
when 'receiving', 'change'
|
61
|
-
event["lifecycle:transition"] = "unknown"
|
62
|
-
when 'done'
|
63
|
-
event["lifecycle:transition"] = "complete"
|
64
|
-
else
|
65
|
-
event["lifecycle:transition"] = "start"
|
66
|
-
end
|
67
|
-
event["cpee:lifecycle:transition"] = "#{topic}/#{event_name}"
|
68
|
-
data_send = ((parameters["arguments"].nil? ? [] : parameters["arguments"]) rescue [])
|
69
|
-
event["list"] = {"data_send" => data_send} unless data_send.empty?
|
70
|
-
if notification['changed']&.any?
|
71
|
-
if event.has_key? "list"
|
72
|
-
event["list"]["data_changed"] ||= notification['changed']
|
73
|
-
else
|
74
|
-
event["list"] = {"data_changer" => notification['changed']}
|
75
|
-
end
|
76
|
-
end
|
77
|
-
if notification['values']&.any?
|
78
|
-
if event.has_key? "list"
|
79
|
-
event["list"]["data_values"] ||= notification['values']
|
80
|
-
else
|
81
|
-
event["list"] = {"data_values" => notification['values']}
|
82
|
-
end
|
83
|
-
end
|
84
|
-
if receiving&.any?
|
85
|
-
if event.has_key? "list"
|
86
|
-
event["list"]["data_received"] ||= receiving
|
87
|
-
else
|
88
|
-
event["list"] = {"data_receiver" => receiving}
|
89
|
-
end
|
90
|
-
end
|
91
|
-
event["time:timestamp"]= Time.now.iso8601
|
92
|
-
|
93
|
-
iname = "instance_" + notification['instance_name'].downcase.gsub(/[^a-z]/,'_')
|
94
|
-
esc.indices.create index: iname rescue nil
|
95
|
-
esc.index index: iname, type: 'entry', body: event
|
96
|
-
nil
|
97
|
-
end
|
98
|
-
|
99
|
-
def response
|
100
|
-
topic = @p[1].value
|
101
|
-
event_name = @p[2].value
|
102
|
-
esc = @a[0]
|
103
|
-
template = @a[1]
|
104
|
-
instancenr = @h['CPEE_INSTANCE'].split('/').last
|
105
|
-
notification = JSON.parse(@p[3].value)
|
106
|
-
doc topic, event_name, esc, template, instancenr, notification
|
107
|
-
end
|
108
|
-
end #}}}
|
109
4
|
|
110
5
|
Riddl::Server.new(File.join(__dir__,'/log.xml'), :host => 'localhost', :port => 9307) do
|
111
6
|
accessible_description true
|
@@ -0,0 +1,237 @@
|
|
1
|
+
require 'pp'
|
2
|
+
require 'time'
|
3
|
+
require 'digest'
|
4
|
+
|
5
|
+
require 'json'
|
6
|
+
require 'yaml'
|
7
|
+
require 'riddl/server'
|
8
|
+
require 'faraday'
|
9
|
+
require 'elasticsearch'
|
10
|
+
|
11
|
+
class Logging < Riddl::Implementation
|
12
|
+
|
13
|
+
def doc(topic,event_name,esc,template,instancenr,notification)
|
14
|
+
uuid = notification['instance_uuid']
|
15
|
+
return unless uuid
|
16
|
+
|
17
|
+
# activity = notification['activity']
|
18
|
+
# parameters = notification['parameters']
|
19
|
+
# receiving = notification['received']
|
20
|
+
# attributes = notification['attributes']
|
21
|
+
|
22
|
+
unless esc.indices.exists? index: 'artefacts' #{{{
|
23
|
+
esc.indices.create index: 'artefacts', body: {
|
24
|
+
"mappings" => {
|
25
|
+
"entry" => {
|
26
|
+
"properties" => {
|
27
|
+
"group" => {
|
28
|
+
"type" => "keyword"
|
29
|
+
|
30
|
+
},
|
31
|
+
"name" => {
|
32
|
+
"type" => "keyword"
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
end #}}}
|
39
|
+
unless esc.indices.exists? index: 'instances' #{{{
|
40
|
+
esc.indices.create index: 'instances', body: {
|
41
|
+
"mappings" => {
|
42
|
+
"entry" => {
|
43
|
+
"properties" => {
|
44
|
+
"uuid" => {
|
45
|
+
"type" => "text"
|
46
|
+
},
|
47
|
+
"group" => {
|
48
|
+
"type" => "keyword"
|
49
|
+
},
|
50
|
+
"name" => {
|
51
|
+
"type" => "keyword"
|
52
|
+
},
|
53
|
+
"date": {
|
54
|
+
"type": "date",
|
55
|
+
"format": "date_time_no_millis"
|
56
|
+
},
|
57
|
+
"info": {
|
58
|
+
"type": "keyword"
|
59
|
+
}
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
64
|
+
end #}}}
|
65
|
+
unless esc.indices.exists? index: 'spawned' #{{{
|
66
|
+
esc.indices.create index: 'spawned', body: {
|
67
|
+
"mappings" => {
|
68
|
+
"entry" => {
|
69
|
+
"properties" => {
|
70
|
+
"uuid" => {
|
71
|
+
"type" => "text"
|
72
|
+
},
|
73
|
+
"spawned_uuid" => {
|
74
|
+
"type" => "text"
|
75
|
+
},
|
76
|
+
"date": {
|
77
|
+
"type": "date",
|
78
|
+
"format": "date_time_no_millis"
|
79
|
+
},
|
80
|
+
}
|
81
|
+
}
|
82
|
+
}
|
83
|
+
}
|
84
|
+
end #}}}
|
85
|
+
unless esc.indices.exists? index: 'sensors' #{{{
|
86
|
+
esc.indices.create index: 'sensors', body: {
|
87
|
+
"mappings" => {
|
88
|
+
"entry" => {
|
89
|
+
"properties" => {
|
90
|
+
"uuid" => {
|
91
|
+
"type" => "text"
|
92
|
+
},
|
93
|
+
"sensor" => {
|
94
|
+
"type" => "keyword"
|
95
|
+
},
|
96
|
+
"task" => {
|
97
|
+
"type" => "keyword"
|
98
|
+
},
|
99
|
+
"visualizer_url" => {
|
100
|
+
"type" => "text"
|
101
|
+
},
|
102
|
+
"visualizer_params" => {
|
103
|
+
"type" => "nested"
|
104
|
+
}
|
105
|
+
}
|
106
|
+
}
|
107
|
+
}
|
108
|
+
}
|
109
|
+
end #}}}
|
110
|
+
unless esc.indices.exists? index: 'values' #{{{
|
111
|
+
esc.indices.create index: 'values', body: {
|
112
|
+
"mappings" => {
|
113
|
+
"entry" => {
|
114
|
+
"properties" => {
|
115
|
+
"uuid" => {
|
116
|
+
"type" => "keyword"
|
117
|
+
},
|
118
|
+
"sensor" => {
|
119
|
+
"type" => "keyword"
|
120
|
+
},
|
121
|
+
"task" => {
|
122
|
+
"type" => "keyword"
|
123
|
+
},
|
124
|
+
"timestamp": {
|
125
|
+
"type": "date",
|
126
|
+
"format": "date_time"
|
127
|
+
},
|
128
|
+
"value" => {
|
129
|
+
"type" => "text",
|
130
|
+
"fields" => {
|
131
|
+
"value_f" => {
|
132
|
+
"type" => "float",
|
133
|
+
"store" => true
|
134
|
+
},
|
135
|
+
"value_l" => {
|
136
|
+
"type" => "long",
|
137
|
+
"store" => true
|
138
|
+
}
|
139
|
+
}
|
140
|
+
}
|
141
|
+
}
|
142
|
+
}
|
143
|
+
}
|
144
|
+
}
|
145
|
+
end #}}}
|
146
|
+
|
147
|
+
uuid = notification.dig('instance_uuid')
|
148
|
+
|
149
|
+
if notification.dig('attributes','artefacts') #{{{
|
150
|
+
artefacts = JSON.parse(notification.dig('attributes','artefacts'))
|
151
|
+
|
152
|
+
artefacts.each do |a|
|
153
|
+
aid = Digest::MD5.hexdigest(a['group'] + '_' + a['name'])
|
154
|
+
iid = Digest::MD5.hexdigest(a['group'] + '_' + a['name'] + '_' + uuid)
|
155
|
+
esc.index index: 'artefacts', type: 'entry', id: aid, body: a
|
156
|
+
esc.index index: 'instances', type: 'entry', id: iid, body: {
|
157
|
+
'uuid': uuid,
|
158
|
+
'group': a['group'],
|
159
|
+
'name': a['name'],
|
160
|
+
'date': Time.now.iso8601,
|
161
|
+
'info': notification.dig('attributes','info')
|
162
|
+
}
|
163
|
+
|
164
|
+
end
|
165
|
+
end #}}}
|
166
|
+
|
167
|
+
case "#{topic}/#{event_name}"
|
168
|
+
when "dataelements/change", "endpoints/change"
|
169
|
+
sensors = JSON.parse(notification.dig('attributes','sensors') || '[]')
|
170
|
+
sensors.each do |s|
|
171
|
+
sid = Digest::MD5.hexdigest(uuid + '_' + s['name'])
|
172
|
+
esc.index index: 'sensors', type: 'entry', id: sid, body: {
|
173
|
+
'uuid': uuid,
|
174
|
+
'sensor': s['name'],
|
175
|
+
'visualizer_url': s['visualizer_url'],
|
176
|
+
'visualizer_params': [s['visualizer_params']]
|
177
|
+
}
|
178
|
+
esc.index index: 'values', type: 'entry', body: {
|
179
|
+
'uuid': uuid,
|
180
|
+
'sensor': s['name'],
|
181
|
+
'timestamp': notification.dig('timestamp'),
|
182
|
+
'value': s['value']
|
183
|
+
}
|
184
|
+
end
|
185
|
+
when "activity/receiving"
|
186
|
+
sensors = JSON.parse(notification.dig('sensors') || '[]')
|
187
|
+
tdoc = notification.dig('received')
|
188
|
+
sensors.each do |s|
|
189
|
+
sid = Digest::MD5.hexdigest(uuid + '_' + s['name'])
|
190
|
+
esc.index index: 'sensors', type: 'entry', id: sid, body: {
|
191
|
+
'uuid': uuid,
|
192
|
+
'sensor': s['name'],
|
193
|
+
'task': notification.dig('activity'),
|
194
|
+
'visualizer_url': s['visualizer_url'],
|
195
|
+
'visualizer_params': (s['visualizer_params'].nil? || s['visualizer_params'].empty? ? [] : [s['visualizer_params']])
|
196
|
+
}
|
197
|
+
status, result = Riddl::Client.new(s['extractor_url']).post [
|
198
|
+
Riddl::Parameter::Simple.new('data',JSON.pretty_generate(tdoc)),
|
199
|
+
Riddl::Parameter::Simple.new('what',s['extractor_arg'])
|
200
|
+
]
|
201
|
+
if status >= 200 && status < 300
|
202
|
+
ret = JSON::parse(result[0]&.value.read) rescue []
|
203
|
+
ret.each do |v,t|
|
204
|
+
esc.index index: 'values', type: 'entry', body: {
|
205
|
+
'uuid': uuid,
|
206
|
+
'sensor': s['name'],
|
207
|
+
'timestamp': t,
|
208
|
+
'value': v
|
209
|
+
}
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
end
|
214
|
+
end
|
215
|
+
nil
|
216
|
+
end
|
217
|
+
|
218
|
+
def response #{{{
|
219
|
+
### save events for later replay
|
220
|
+
# a = {
|
221
|
+
# :topic => @p[1].value,
|
222
|
+
# :event_name => @p[2].value,
|
223
|
+
# :instancenr => @h['CPEE_INSTANCE'].split('/').last,
|
224
|
+
# :notification => JSON.parse(@p[3].value)
|
225
|
+
# }.to_yaml
|
226
|
+
# File.open('events.yaml','a') do |f|
|
227
|
+
# f << a
|
228
|
+
# end
|
229
|
+
topic = @p[1].value
|
230
|
+
event_name = @p[2].value
|
231
|
+
esc = @a[0]
|
232
|
+
template = @a[1]
|
233
|
+
instancenr = @h['CPEE_INSTANCE'].split('/').last
|
234
|
+
notification = JSON.parse(@p[3].value)
|
235
|
+
doc topic, event_name, esc, template, instancenr, notification
|
236
|
+
end #}}}
|
237
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'elasticsearch'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
client = Elasticsearch::Client.new hosts: ['localhost:8400']
|
6
|
+
unless client.indices.exists? index: 'trace'
|
7
|
+
client.indices.create index: 'trace', body: {
|
8
|
+
"mappings" => {
|
9
|
+
"entry" => {
|
10
|
+
"properties" => {
|
11
|
+
"concept:name" => {
|
12
|
+
"type" => "integer"
|
13
|
+
},
|
14
|
+
"cpee:name" => {
|
15
|
+
"type" => "text"
|
16
|
+
},
|
17
|
+
"cpee:uuid": {
|
18
|
+
"type" => "text"
|
19
|
+
}
|
20
|
+
}
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
client.index index: 'trace', type: 'entry', id: , body: log["log"]["trace"]
|
@@ -0,0 +1,211 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'pp'
|
3
|
+
|
4
|
+
#{{{
|
5
|
+
yaml1 = <<-END
|
6
|
+
event:
|
7
|
+
cpee:lifecycle:transition: activity/receiving
|
8
|
+
list:
|
9
|
+
data_receiver:
|
10
|
+
- message:
|
11
|
+
mimetype: application/json
|
12
|
+
content:
|
13
|
+
- ID: ns=2;s=/Channel/ProgramInfo/actBlock
|
14
|
+
meta:
|
15
|
+
StatusCodea: Good
|
16
|
+
- ID: ns=2;s=/Channel/Spindle/driveLoad
|
17
|
+
meta:
|
18
|
+
StatusCodeb: Good
|
19
|
+
- message:
|
20
|
+
mimetype: application/xml
|
21
|
+
content:
|
22
|
+
- ID: ns=2;s=/Channel/ProgramInfo/actBlock
|
23
|
+
meta:
|
24
|
+
StatusCodec: Good
|
25
|
+
- ID: ns=2;s=/Channel/Spindle/driveLoad
|
26
|
+
meta:
|
27
|
+
StatusCoded: Good
|
28
|
+
time:timestamp: '2018-05-03T14:08:14+02:00'
|
29
|
+
END
|
30
|
+
#}}}
|
31
|
+
#{{{
|
32
|
+
yaml2 = <<-END
|
33
|
+
event:
|
34
|
+
trace:id: '160'
|
35
|
+
concept:name: Fetch
|
36
|
+
concept:endpoint: https://centurio.work/data/mt45/queue/48623a67-7b67-4902-b5d4-7243f1d090e2/push
|
37
|
+
id:id: a1
|
38
|
+
lifecycle:transition: unknown
|
39
|
+
cpee:lifecycle:transition: activity/receiving
|
40
|
+
list:
|
41
|
+
data_receiver:
|
42
|
+
- message:
|
43
|
+
mimetype: application/json
|
44
|
+
content:
|
45
|
+
- ID: ns=2;s=/Channel/ProgramInfo/actBlock
|
46
|
+
source: opcua
|
47
|
+
name: Program/actBlock
|
48
|
+
description: Current part program block.
|
49
|
+
path: "/Object/Sinumerik/Channel/ProgramInfo/actBlock"
|
50
|
+
value:
|
51
|
+
timestamp: '2018-05-03 14:16:55.241000'
|
52
|
+
meta:
|
53
|
+
StatusCode: Good
|
54
|
+
ServerTimestamp: '2018-05-03 12:16:55.318853'
|
55
|
+
VariantType: VariantType.String
|
56
|
+
ClientHandle: '212'
|
57
|
+
- ID: ns=2;s=/Channel/Spindle/driveLoad
|
58
|
+
source: opcua
|
59
|
+
name: Spindle/driveLoad
|
60
|
+
description: Load
|
61
|
+
path: "/Object/Sinumerik/Channel/Spindle/driveLoad"
|
62
|
+
value: 0.030517578125
|
63
|
+
timestamp: '2018-05-03 14:16:55.241000'
|
64
|
+
meta:
|
65
|
+
StatusCode: Good
|
66
|
+
ServerTimestamp: '2018-05-03 12:16:55.318853'
|
67
|
+
VariantType: VariantType.Double
|
68
|
+
ClientHandle: '217'
|
69
|
+
- ID: ns=2;s=/Channel/MachineAxis/aaLeadP[u1,3]
|
70
|
+
source: opcua
|
71
|
+
name: Axis/Z/aaLeadP
|
72
|
+
description: ''
|
73
|
+
path: "/Object/Sinumerik/Channel/MachineAxis/aaLeadP[u1,3]"
|
74
|
+
value: 162.51611
|
75
|
+
timestamp: '2018-05-03 14:16:55.241000'
|
76
|
+
meta:
|
77
|
+
StatusCode: Good
|
78
|
+
ServerTimestamp: '2018-05-03 12:16:55.318853'
|
79
|
+
VariantType: VariantType.Double
|
80
|
+
ClientHandle: '222'
|
81
|
+
- ID: ns=2;s=/Channel/MachineAxis/aaTorque[u1,1]
|
82
|
+
source: opcua
|
83
|
+
name: Axis/X/aaTorque
|
84
|
+
description: ''
|
85
|
+
path: "/Object/Sinumerik/Channel/MachineAxis/aaTorque[u1,1]"
|
86
|
+
value: -2.072
|
87
|
+
timestamp: '2018-05-03 14:16:55.241000'
|
88
|
+
meta:
|
89
|
+
StatusCode: Good
|
90
|
+
ServerTimestamp: '2018-05-03 12:16:55.318853'
|
91
|
+
VariantType: VariantType.Double
|
92
|
+
ClientHandle: '223'
|
93
|
+
- ID: ns=2;s=/Channel/MachineAxis/aaTorque[u1,2]
|
94
|
+
source: opcua
|
95
|
+
name: Axis/Y/aaTorque
|
96
|
+
description: ''
|
97
|
+
path: "/Object/Sinumerik/Channel/MachineAxis/aaTorque[u1,2]"
|
98
|
+
value: 0.107
|
99
|
+
timestamp: '2018-05-03 14:16:55.241000'
|
100
|
+
meta:
|
101
|
+
StatusCode: Good
|
102
|
+
ServerTimestamp: '2018-05-03 12:16:55.318853'
|
103
|
+
VariantType: VariantType.Double
|
104
|
+
ClientHandle: '224'
|
105
|
+
time:timestamp: '2018-05-03T14:08:14+02:00'
|
106
|
+
END
|
107
|
+
#}}}
|
108
|
+
|
109
|
+
def traverse(node,paths=[[]],anal=[],depth=0)
|
110
|
+
cpath = paths.last.dup
|
111
|
+
case node
|
112
|
+
when Hash
|
113
|
+
node.each do |k,v|
|
114
|
+
unless cpath.empty?
|
115
|
+
paths.last << [] unless paths.last.last.class == Array
|
116
|
+
paths << cpath.dup
|
117
|
+
end
|
118
|
+
paths.last << k
|
119
|
+
traverse(v,paths,anal,depth+1)
|
120
|
+
end
|
121
|
+
when Array
|
122
|
+
node.each_with_index do |e,i|
|
123
|
+
posanal = [depth,paths.length,nil,[]]
|
124
|
+
anal << posanal
|
125
|
+
|
126
|
+
unless cpath.empty?
|
127
|
+
paths.last << [] unless paths.last.last.class == Array
|
128
|
+
paths << cpath.dup
|
129
|
+
end
|
130
|
+
paths.last << i
|
131
|
+
traverse(e,paths,posanal.last,depth+1)
|
132
|
+
dp = cpath.dup
|
133
|
+
dp << [] unless dp.last.class == Array
|
134
|
+
paths << dp unless paths.include?(dp)
|
135
|
+
|
136
|
+
posanal[2] = paths.length - 1
|
137
|
+
end
|
138
|
+
else
|
139
|
+
paths.last << [] unless paths.last.last.class == Array
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def duplicate(doc,paths,anal)
|
144
|
+
res = []
|
145
|
+
deep_cloned = Marshal::load(Marshal.dump(paths))
|
146
|
+
anal.each_with_index do |e,ei|
|
147
|
+
local_cloned = Marshal::load(Marshal.dump(deep_cloned))
|
148
|
+
anal.select{ |a| a == e }.each do |a|
|
149
|
+
(a[1]).upto(a[2]) do |i|
|
150
|
+
local_cloned[i].last << a[0]
|
151
|
+
end
|
152
|
+
end
|
153
|
+
anal.reject{ |a| a == e }.each do |a|
|
154
|
+
(a[1]).upto(a[2]) do |i|
|
155
|
+
local_cloned[i] = nil
|
156
|
+
end
|
157
|
+
end
|
158
|
+
if !e[3]&.empty?
|
159
|
+
e[3..-1].each_with_index do |ee,eei|
|
160
|
+
ret = duplicate(doc,local_cloned,ee)
|
161
|
+
res.concat ret
|
162
|
+
end
|
163
|
+
else
|
164
|
+
res << extract_from_doc(doc,local_cloned.compact)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
res
|
168
|
+
end
|
169
|
+
|
170
|
+
def extract_from_doc(doc,paths)
|
171
|
+
ret = {}
|
172
|
+
paths.each do |p|
|
173
|
+
next if p.nil?
|
174
|
+
a = doc.dig(*p[0..-2])
|
175
|
+
|
176
|
+
py = p.dup
|
177
|
+
p[-1].each_with_index do |px,i|
|
178
|
+
py.delete_at(px-i)
|
179
|
+
end
|
180
|
+
|
181
|
+
x1 = py[-2]
|
182
|
+
x2 = py[0..-3]
|
183
|
+
where = ret
|
184
|
+
if x2.any?
|
185
|
+
where = ret.dig(*x2)
|
186
|
+
end
|
187
|
+
where[x1] = {}
|
188
|
+
|
189
|
+
unless a.class == Hash || a.class == Array
|
190
|
+
where[x1] = a
|
191
|
+
end
|
192
|
+
end
|
193
|
+
ret
|
194
|
+
end
|
195
|
+
|
196
|
+
doc = YAML.load(yaml2)
|
197
|
+
|
198
|
+
paths = [[]]
|
199
|
+
anal = []
|
200
|
+
traverse(doc,paths,anal)
|
201
|
+
anal.uniq!
|
202
|
+
|
203
|
+
paths.each do |p|
|
204
|
+
p p
|
205
|
+
end
|
206
|
+
|
207
|
+
res = duplicate(doc,paths,anal)
|
208
|
+
|
209
|
+
res.each do |r|
|
210
|
+
pp r
|
211
|
+
end
|