hrr_rb_netconf 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 80d570618616c7c6db898307a743eb31cba40b7811d0b9c5dd18e6691b679a21
4
- data.tar.gz: 2eb821c7bafcf5afdfbe3d866494bbd308954b59e11554f6cfe0a1cd12d27e47
3
+ metadata.gz: 0feb4042406ce9043aa1f3f535da2ffbe4136197a28800f805e43860e43755a4
4
+ data.tar.gz: 8ec823251fe7a8c26223a7bc856b83263437833bf90938e6ff065ede68be97dd
5
5
  SHA512:
6
- metadata.gz: fd4001d68726903b2d708bc494dec4e582c7383ff699e3f092d43c5284a7c5336e47e9288299b5a121ec93ba8ba1615f6766f99acaffbbd4042c8fcaad2d187b
7
- data.tar.gz: '088857bc573595df3813b9eca6baaff492f5307053d18d56b1263e0da3303fca30a9cc5e9d29451936fd2f07d92816031781842a9082755a7798c9ec7e24ff35'
6
+ metadata.gz: 5755adcd86b0cb11c12e192542a10731dbfe3a00414bc901a652bd08a23b28bb1ba39a392f95a52b8c830c9132bc87b610e2381d1e01c9ceffd6c5009f136ce5
7
+ data.tar.gz: 7d72b95b3153cb54c28cfe808e24de5351a0c9327076b1b6dd1b1a8237a4ef29a9d1e456c0c9d9f5128d6fc1aae354b6956167516015d759855baa35d774a1ca
data/.travis.yml CHANGED
@@ -11,6 +11,7 @@ rvm:
11
11
  - 2.4
12
12
  - 2.5
13
13
  - 2.6
14
+ - 2.7
14
15
  - ruby-head
15
16
  os:
16
17
  - linux
data/README.md CHANGED
@@ -207,9 +207,16 @@ The following capabilities are currently supported.
207
207
 
208
208
  Required feature: xpath
209
209
 
210
+ - urn:ietf:params:netconf:capability:notification:1.0
211
+
212
+ Required feature: notification
213
+
214
+ Required datastore operations:
215
+ - create-subscription
216
+
210
217
  ## Contributing
211
218
 
212
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/hrr_rb_netconf. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
219
+ Bug reports and pull requests are welcome on GitHub at https://github.com/hirura/hrr_rb_netconf. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
213
220
 
214
221
  ## Code of Conduct
215
222
 
@@ -22,7 +22,9 @@ Gem::Specification.new do |spec|
22
22
 
23
23
  spec.required_ruby_version = '>= 2.0.0'
24
24
 
25
- spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_dependency "hrr_rb_relaxed_xml"
26
+
27
+ spec.add_development_dependency "rake", "~> 12.0"
26
28
  spec.add_development_dependency "rspec", "~> 3.0"
27
29
  spec.add_development_dependency "simplecov", "~> 0.16"
28
30
  end
@@ -121,7 +121,7 @@ module HrrRbNetconf
121
121
  end
122
122
  @logger.debug { "Sending message: #{buf.inspect}" }
123
123
  begin
124
- @io_w.write "#{buf}\n]]>]]>\n"
124
+ @io_w.write "#{buf}\n]]>]]>"
125
125
  rescue => e
126
126
  @logger.info { "Sender IO closed: #{e.class}: #{e.message}" }
127
127
  raise IOError, "Sender IO closed: #{e.class}: #{e.message}"
@@ -9,15 +9,8 @@ module HrrRbNetconf
9
9
  DEPENDENCIES = ['urn:ietf:params:netconf:capability:candidate:1.0']
10
10
  IF_FEATURES = ['candidate', 'confirmed-commit']
11
11
 
12
- oper_proc('cancel-commit'){ |session, datastore, input_e|
13
- datastore.run 'cancel-commit', input_e
14
- '<ok />'
15
- }
16
-
17
12
  model 'commit', ['confirmed'], 'leaf', 'type' => 'empty'
18
13
  model 'commit', ['confirm-timeout'], 'leaf', 'type' => 'integer', 'range' => [1, 2**32-1], 'default' => '600'
19
- model 'commit', ['persist'], 'leaf', 'type' => 'string'
20
- model 'commit', ['persist-id'], 'leaf', 'type' => 'string'
21
14
  end
22
15
  end
23
16
  end
@@ -0,0 +1,81 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'rexml/document'
5
+ require 'hrr_rb_netconf/logger'
6
+
7
+ module HrrRbNetconf
8
+ class Server
9
+ class Capability
10
+ class Notification_1_0 < Capability
11
+ ID = 'urn:ietf:params:netconf:capability:notification:1.0'
12
+ DEPENDENCIES = []
13
+ IF_FEATURES = ['notification']
14
+
15
+ oper_proc('create-subscription'){ |session, datastore, input_e|
16
+ logger = Logger.new HrrRbNetconf::Server::Capability::Notification_1_0
17
+ stream_e = input_e.elements['stream']
18
+ unless stream_e
19
+ logger.debug { "create-subscription doesn't have stream, so use NETCONF stream" }
20
+ stream_e = input_e.add_element('stream')
21
+ stream_e.text = 'NETCONF'
22
+ end
23
+ stream = stream_e.text
24
+ start_time_e = input_e.elements['startTime']
25
+ start_time = unless start_time_e
26
+ nil
27
+ else
28
+ DateTime.rfc3339(start_time_e.text)
29
+ end
30
+ stop_time_e = input_e.elements['stopTime']
31
+ stop_time = unless stop_time_e
32
+ nil
33
+ else
34
+ DateTime.rfc3339(stop_time_e.text)
35
+ end
36
+ if ! session.subscription_creatable? stream
37
+ logger.error { "Not available stream: #{stream}" }
38
+ raise Error['bad-element'].new('protocol', 'error', info: {'bad-element' => 'stream'})
39
+ end
40
+ if start_time.nil? && stop_time
41
+ logger.error { "startTime element doesn't exist, but stopTime does" }
42
+ raise Error['missing-element'].new('protocol', 'error', info: {'bad-element' => 'startTime'})
43
+ end
44
+ if start_time && stop_time && (start_time > stop_time)
45
+ logger.error { "stopTime is earlier than startTime" }
46
+ raise Error['bad-element'].new('protocol', 'error', info: {'bad-element' => 'stopTime'})
47
+ end
48
+ if start_time && (start_time > DateTime.now)
49
+ logger.error { "startTime is later than current time" }
50
+ raise Error['bad-element'].new('protocol', 'error', info: {'bad-element' => 'startTime'})
51
+ end
52
+ begin
53
+ events = datastore.run('create-subscription', input_e)
54
+ rescue Error
55
+ raise
56
+ rescue => e
57
+ logger.error { "Exception in datastore.run('create-subscription', input_e): #{e.message}" }
58
+ raise Error['operation-failed'].new('application', 'error')
59
+ end
60
+ begin
61
+ if start_time
62
+ session.notification_replay stream, start_time, stop_time, events
63
+ end
64
+ rescue Error
65
+ raise
66
+ rescue => e
67
+ logger.error { "Exception in session.notification_replay: #{e.message}" }
68
+ raise Error['operation-failed'].new('protocol', 'error')
69
+ end
70
+ session.create_subscription stream, start_time, stop_time
71
+ '<ok />'
72
+ }
73
+
74
+ model 'create-subscription', ['stream'], 'leaf', 'type' => 'string'
75
+ model 'create-subscription', ['filter'], 'leaf', 'type' => 'anyxml'
76
+ model 'create-subscription', ['startTime'], 'leaf', 'type' => 'string'
77
+ model 'create-subscription', ['stopTime'], 'leaf', 'type' => 'string'
78
+ end
79
+ end
80
+ end
81
+ end
@@ -14,7 +14,6 @@ module HrrRbNetconf
14
14
  '<ok />'
15
15
  }
16
16
 
17
- model 'edit-config', ['test-option'], 'leaf', 'type' => 'enumeration', 'enum' => ['test-then-set', 'set', 'test-only'], 'default' => 'test-then-set'
18
17
  model 'validate', ['source'], 'container'
19
18
  model 'validate', ['source', 'config-source'], 'choice', 'mandatory' => true
20
19
  model 'validate', ['source', 'config-source', 'running'], 'leaf', 'type' => 'empty'
@@ -204,3 +204,4 @@ require 'hrr_rb_netconf/server/capability/validate_1_0'
204
204
  require 'hrr_rb_netconf/server/capability/validate_1_1'
205
205
  require 'hrr_rb_netconf/server/capability/url_1_0'
206
206
  require 'hrr_rb_netconf/server/capability/xpath_1_0'
207
+ require 'hrr_rb_netconf/server/capability/notification_1_0'
@@ -0,0 +1,47 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_relaxed_xml'
5
+ require 'hrr_rb_netconf/logger'
6
+
7
+ module HrrRbNetconf
8
+ class Server
9
+ class NotificationEvent
10
+ def initialize arg1, arg2=nil
11
+ unless arg2
12
+ @event_xml = case arg1
13
+ when HrrRbRelaxedXML::Document
14
+ arg1
15
+ else
16
+ HrrRbRelaxedXML::Document.new(arg2, {:ignore_whitespace_nodes => :all})
17
+ end
18
+ event_time = @event_xml.elements['eventTime'].text
19
+ @event_xml.elements['eventTime'].text = DateTime.parse(event_time).rfc3339
20
+ else
21
+ event_time_e = REXML::Element.new('eventTime')
22
+ event_time_e.text = case arg1
23
+ when REXML::Element
24
+ DateTime.parse(arg1.text).rfc3339
25
+ else
26
+ DateTime.parse(arg1.to_s).rfc3339
27
+ end
28
+ event_e = case arg2
29
+ when REXML::Document
30
+ arg2.root.deep_clone
31
+ when REXML::Element
32
+ arg2.deep_clone
33
+ else
34
+ REXML::Document.new(arg2, {:ignore_whitespace_nodes => :all}).root
35
+ end
36
+ @event_xml = HrrRbRelaxedXML::Document.new
37
+ @event_xml.add event_time_e
38
+ @event_xml.add event_e
39
+ end
40
+ end
41
+
42
+ def to_xml
43
+ @event_xml
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ module HrrRbNetconf
5
+ class Server
6
+ class NotificationStream
7
+ attr_reader :blk
8
+
9
+ def initialize blk, replay_support
10
+ @blk = blk
11
+ @replay_support = replay_support
12
+ end
13
+
14
+ def match? event_xml
15
+ if @blk.call(event_xml)
16
+ true
17
+ else
18
+ false
19
+ end
20
+ end
21
+
22
+ def support_replay?
23
+ @replay_support
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,40 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_netconf/logger'
5
+ require 'hrr_rb_netconf/server/notification_stream'
6
+
7
+ module HrrRbNetconf
8
+ class Server
9
+ class NotificationStreams
10
+ def initialize
11
+ @streams = Hash.new
12
+ @streams['NETCONF'] = NotificationStream.new(Proc.new { true }, false)
13
+ end
14
+
15
+ def has_stream? stream
16
+ @streams.has_key? stream
17
+ end
18
+
19
+ def stream_support_replay? stream
20
+ @streams[stream].support_replay?
21
+ end
22
+
23
+ def update stream, blk, replay_support
24
+ if blk.nil? && (! @streams.has_key?( stream ))
25
+ raise ArgumentError, "Requires block for new stream: #{stream}"
26
+ end
27
+ blk ||= @streams[stream].blk
28
+ @streams[stream] = NotificationStream.new(blk, replay_support)
29
+ end
30
+
31
+ def matched_streams event_xml
32
+ @streams.select{ |k, v| v.match? event_xml }.keys
33
+ end
34
+
35
+ def event_match_stream? event_xml, stream
36
+ @streams[stream].match? event_xml
37
+ end
38
+ end
39
+ end
40
+ end
@@ -1,7 +1,12 @@
1
1
  # coding: utf-8
2
2
  # vim: et ts=2 sw=2
3
3
 
4
+ require 'time'
5
+ require 'date'
6
+ require 'thread'
7
+ require 'monitor'
4
8
  require 'rexml/document'
9
+ require 'hrr_rb_relaxed_xml'
5
10
  require 'hrr_rb_netconf/logger'
6
11
  require 'hrr_rb_netconf/server/capability'
7
12
  require 'hrr_rb_netconf/server/operation'
@@ -28,6 +33,12 @@ module HrrRbNetconf
28
33
  end
29
34
  @strict_capabilities = strict_capabilities
30
35
  @closed = false
36
+ @notification_enabled = false
37
+ @monitor = Monitor.new
38
+ @subscribed_streams = Hash.new
39
+ @subscribed_streams_stop_time = Hash.new
40
+ @notification_replay_thread = nil
41
+ @subscription_termination_thread = nil
31
42
  end
32
43
 
33
44
  def start
@@ -46,10 +57,10 @@ module HrrRbNetconf
46
57
  def close
47
58
  @logger.info { "Being closed" }
48
59
  @closed = true
49
- begin
50
- @io_r.close_read
51
- rescue
52
- end
60
+ @io_r.close_read rescue nil
61
+ @notification_replay_thread.exit if @notification_replay_thread rescue nil
62
+ @notification_termination_thread.exit if @notification_termination_thread rescue nil
63
+ @logger.info { "Closed" }
53
64
  end
54
65
 
55
66
  def closed?
@@ -79,7 +90,7 @@ module HrrRbNetconf
79
90
  formatter.compact = true
80
91
  formatter.write(xml_doc, buf)
81
92
  @logger.debug { "Sending hello message: #{buf.inspect}" }
82
- @io_w.write "#{buf}\n]]>]]>\n"
93
+ @io_w.write "#{buf}\n]]>]]>"
83
94
  end
84
95
 
85
96
  def receive_hello
@@ -118,45 +129,40 @@ module HrrRbNetconf
118
129
 
119
130
  begin
120
131
  loop do
121
- if closed?
122
- break
123
- end
124
-
132
+ break if closed?
125
133
  begin
134
+ received_message = @receiver.receive_message
135
+ break unless received_message
136
+ rescue Error => e
137
+ rpc_reply_e = REXML::Element.new("rpc-reply")
138
+ rpc_reply_e.add_namespace("urn:ietf:params:xml:ns:netconf:base:1.0")
139
+ rpc_reply_e.add e.to_rpc_error
140
+ rescue => e
141
+ @logger.error { e.message }
142
+ raise
143
+ end
144
+ @monitor.synchronize do
126
145
  begin
127
- received_message = @receiver.receive_message
128
- break unless received_message
129
146
  rpc_reply_e = operation.run received_message
130
147
  rescue Error => e
131
- if received_message
132
- rpc_reply_e = received_message.clone
133
- rpc_reply_e.name = "rpc-reply"
134
- else
135
- rpc_reply_e = REXML::Element.new("rpc-reply")
136
- rpc_reply_e.add_namespace("urn:ietf:params:xml:ns:netconf:base:1.0")
137
- end
148
+ rpc_reply_e = received_message.clone
149
+ rpc_reply_e.name = "rpc-reply"
138
150
  rpc_reply_e.add e.to_rpc_error
151
+ rescue => e
152
+ @logger.error { e.message }
153
+ raise
154
+ ensure
155
+ begin
156
+ @sender.send_message rpc_reply_e if rpc_reply_e
157
+ rescue IOError
158
+ break
159
+ end
139
160
  end
140
-
141
- begin
142
- @sender.send_message rpc_reply_e
143
- rescue IOError
144
- break
145
- end
146
- rescue => e
147
- @logger.error { e.message }
148
- raise
149
161
  end
150
162
  end
151
163
  ensure
152
- begin
153
- datastore_session.close
154
- rescue
155
- end
156
- begin
157
- @io_w.close_write
158
- rescue
159
- end
164
+ datastore_session.close rescue nil
165
+ @io_w.close_write rescue nil
160
166
  end
161
167
  @logger.info { "Exit operation_loop" }
162
168
  end
@@ -172,6 +178,144 @@ module HrrRbNetconf
172
178
  def unlock target
173
179
  @server.unlock target, @session_id
174
180
  end
181
+
182
+ def subscription_creatable? stream
183
+ @logger.info { "Check subscription for stream: #{stream}" }
184
+ if ! @server.has_notification_stream? stream
185
+ @logger.error { "Server doesn't have notification stream: #{stream}" }
186
+ false
187
+ elsif @subscribed_streams.has_key? stream
188
+ @logger.error { "Session already has subscription for stream: #{stream}" }
189
+ false
190
+ else
191
+ @logger.info { "Subscription creatable for stream: #{stream}" }
192
+ true
193
+ end
194
+ end
195
+
196
+ def create_subscription stream, start_time, stop_time
197
+ @logger.info { "Create subscription for stream: #{stream}" }
198
+ @subscribed_streams[stream] = true
199
+ start_notification_termination_thread stream, start_time, stop_time if stop_time
200
+ @logger.info { "Create subscription done for stream: #{stream}" }
201
+ end
202
+
203
+ def terminate_subscription stream
204
+ @logger.info { "Terminate subscription for stream: #{stream}" }
205
+ @subscribed_streams.delete stream
206
+ @logger.info { "Terminate subscription done for stream: #{stream}" }
207
+ end
208
+
209
+ def notification_replay stream, start_time, stop_time, events
210
+ if @server.notification_stream_support_replay? stream
211
+ start_notification_replay_thread stream, start_time, stop_time, events
212
+ else
213
+ @logger.error { "Notification replay is not supported by stream: #{stream}" }
214
+ raise Error['operation-failed'].new('protocol', 'error')
215
+ end
216
+ end
217
+
218
+ def stream_subscribed? stream
219
+ @subscribed_streams.has_key? stream
220
+ end
221
+
222
+ def start_notification_replay_thread stream, start_time, stop_time, events
223
+ @notification_replay_thread = Thread.new do
224
+ @logger.info { "Notification replay start for stream: #{stream}" }
225
+ begin
226
+ @monitor.synchronize do
227
+ unless events.respond_to? :each
228
+ @logger.error { "Argument `events' doesn't respond to :each method: #{events}" }
229
+ else
230
+ begin
231
+ events.each{ |arg1, arg2|
232
+ event_xml = NotificationEvent.new(arg1, arg2).to_xml
233
+ if @server.event_match_stream? event_xml, stream
234
+ if start_time
235
+ event_time = DateTime.rfc3339(event_xml.elements['eventTime'].text)
236
+ if start_time < event_time
237
+ if stop_time.nil? || event_time < stop_time
238
+ send_notification event_xml
239
+ end
240
+ end
241
+ end
242
+ end
243
+ }
244
+ rescue => e
245
+ @logger.error { "Got an exception during processing replay: #{e.message}" }
246
+ end
247
+ end
248
+ send_replay_complete stream
249
+ end
250
+ ensure
251
+ @logger.info { "Notification replay completed for stream: #{stream}" }
252
+ end
253
+ end
254
+ end
255
+
256
+ def start_notification_termination_thread stream, start_time, stop_time
257
+ @notification_termination_thread = Thread.new do
258
+ @logger.info { "Notification termination thread start for stream: #{stream}" }
259
+ begin
260
+ loop do
261
+ now = DateTime.now
262
+ if now.to_time < stop_time.to_time
263
+ sleep_time = ((stop_time.to_time - now.to_time) / 2.0).ceil
264
+ @logger.debug { "Notification termination thread for stream: #{stream}: sleep [sec]: #{sleep_time}" }
265
+ sleep sleep_time
266
+ else
267
+ @logger.info { "Notification termination thread terminates subscription for stream: #{stream}" }
268
+ @monitor.synchronize do
269
+ terminate_subscription stream
270
+ send_notification_complete stream
271
+ end
272
+ break
273
+ end
274
+ end
275
+ ensure
276
+ @logger.info { "Notification termination completed for stream: #{stream}" }
277
+ end
278
+ end
279
+ end
280
+
281
+ def send_notification event_e
282
+ @monitor.synchronize do
283
+ notif_e = REXML::Element.new("notification")
284
+ notif_e.add_namespace("urn:ietf:params:xml:ns:netconf:notification:1.0")
285
+ event_e.elements.each{ |e|
286
+ notif_e.add e.deep_clone
287
+ }
288
+ begin
289
+ @sender.send_message notif_e
290
+ rescue IOError => e
291
+ @logger.warn { "Failed sending notification: #{e.message}" }
292
+ end
293
+ end
294
+ end
295
+
296
+ def filter_and_send_notification matched_streams, event_xml
297
+ unless (matched_streams & @subscribed_streams.keys).empty?
298
+ #event_e = filter(event_xml)
299
+ event_e = event_xml
300
+ send_notification event_e
301
+ end
302
+ end
303
+
304
+ def send_replay_complete stream
305
+ event_xml = HrrRbRelaxedXML::Document.new
306
+ event_time_e = event_xml.add_element('eventTime')
307
+ event_time_e.text = DateTime.now.rfc3339
308
+ event_e = event_xml.add_element("replayComplete")
309
+ send_notification event_xml
310
+ end
311
+
312
+ def send_notification_complete stream
313
+ event_xml = HrrRbRelaxedXML::Document.new
314
+ event_time_e = event_xml.add_element('eventTime')
315
+ event_time_e.text = DateTime.now.rfc3339
316
+ event_e = event_xml.add_element("notificationComplete")
317
+ send_notification event_xml
318
+ end
175
319
  end
176
320
  end
177
321
  end
@@ -1,13 +1,17 @@
1
1
  # coding: utf-8
2
2
  # vim: et ts=2 sw=2
3
3
 
4
+ require 'date'
4
5
  require 'thread'
6
+ require 'hrr_rb_relaxed_xml'
5
7
  require 'hrr_rb_netconf/logger'
6
8
  require 'hrr_rb_netconf/server/error'
7
9
  require 'hrr_rb_netconf/server/errors'
8
10
  require 'hrr_rb_netconf/server/datastore'
9
11
  require 'hrr_rb_netconf/server/capabilities'
10
12
  require 'hrr_rb_netconf/server/session'
13
+ require 'hrr_rb_netconf/server/notification_event'
14
+ require 'hrr_rb_netconf/server/notification_streams'
11
15
 
12
16
  module HrrRbNetconf
13
17
  class Server
@@ -26,6 +30,7 @@ module HrrRbNetconf
26
30
  @locks = Hash.new
27
31
  @lock_mutex = Mutex.new
28
32
  @last_session_id = SESSION_ID_MIN - 1
33
+ @notification_streams = NotificationStreams.new
29
34
  end
30
35
 
31
36
  def allocate_session_id
@@ -44,7 +49,7 @@ module HrrRbNetconf
44
49
  end
45
50
 
46
51
  def start_session io
47
- @logger.info { "Starting session" }
52
+ @logger.info { "Start session" }
48
53
  session_id = SESSION_ID_UNALLOCATED
49
54
  begin
50
55
  @mutex.synchronize do
@@ -52,11 +57,7 @@ module HrrRbNetconf
52
57
  @logger.info { "Session ID: #{session_id}" }
53
58
  @sessions[session_id] = Session.new self, @capabilities, @datastore, session_id, io, @strict_capabilities
54
59
  end
55
- t = Thread.new {
56
- @sessions[session_id].start
57
- }
58
- @logger.info { "Session started: Session ID: #{session_id}" }
59
- t.join
60
+ @sessions[session_id].start
60
61
  rescue => e
61
62
  @logger.error { "Session terminated: Session ID: #{session_id}" }
62
63
  raise
@@ -105,5 +106,32 @@ module HrrRbNetconf
105
106
  end
106
107
  end
107
108
  end
109
+
110
+ def notification_stream stream, replay_support: false, &blk
111
+ @notification_streams.update stream, blk, replay_support
112
+ end
113
+
114
+ def has_notification_stream? stream
115
+ @notification_streams.has_stream? stream
116
+ end
117
+
118
+ def notification_stream_support_replay? stream
119
+ @notification_streams.stream_support_replay? stream
120
+ end
121
+
122
+ def event_match_stream? event_xml, stream
123
+ @notification_streams.event_match_stream? event_xml, stream
124
+ end
125
+
126
+ def send_notification arg1, arg2=nil
127
+ event_xml = NotificationEvent.new(arg1, arg2).to_xml
128
+ matched_streams = @notification_streams.matched_streams event_xml
129
+ @logger.info { "Send notification" }
130
+ @logger.debug { "Event time: #{event_xml.elements['eventTime'].text}, Event: #{event_xml.elements.to_a}" }
131
+ @sessions.each{ |session_id, session|
132
+ session.filter_and_send_notification matched_streams, event_xml
133
+ }
134
+ @logger.info { "Send notification done" }
135
+ end
108
136
  end
109
137
  end
@@ -2,5 +2,5 @@
2
2
  # vim: et ts=2 sw=2
3
3
 
4
4
  module HrrRbNetconf
5
- VERSION = "0.1.0"
5
+ VERSION = "0.1.1"
6
6
  end
metadata CHANGED
@@ -1,29 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hrr_rb_netconf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - hirura
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-01 00:00:00.000000000 Z
11
+ date: 2020-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: hrr_rb_relaxed_xml
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: rake
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
31
  - - "~>"
18
32
  - !ruby/object:Gem::Version
19
- version: '10.0'
33
+ version: '12.0'
20
34
  type: :development
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
38
  - - "~>"
25
39
  - !ruby/object:Gem::Version
26
- version: '10.0'
40
+ version: '12.0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rspec
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -82,6 +96,7 @@ files:
82
96
  - lib/hrr_rb_netconf/server/capability/candidate_1_0.rb
83
97
  - lib/hrr_rb_netconf/server/capability/confirmed_commit_1_0.rb
84
98
  - lib/hrr_rb_netconf/server/capability/confirmed_commit_1_1.rb
99
+ - lib/hrr_rb_netconf/server/capability/notification_1_0.rb
85
100
  - lib/hrr_rb_netconf/server/capability/rollback_on_error_1_0.rb
86
101
  - lib/hrr_rb_netconf/server/capability/startup_1_0.rb
87
102
  - lib/hrr_rb_netconf/server/capability/url_1_0.rb
@@ -120,6 +135,9 @@ files:
120
135
  - lib/hrr_rb_netconf/server/filter/xpath.rb
121
136
  - lib/hrr_rb_netconf/server/model.rb
122
137
  - lib/hrr_rb_netconf/server/model/node.rb
138
+ - lib/hrr_rb_netconf/server/notification_event.rb
139
+ - lib/hrr_rb_netconf/server/notification_stream.rb
140
+ - lib/hrr_rb_netconf/server/notification_streams.rb
123
141
  - lib/hrr_rb_netconf/server/operation.rb
124
142
  - lib/hrr_rb_netconf/server/session.rb
125
143
  - lib/hrr_rb_netconf/version.rb
@@ -142,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
142
160
  - !ruby/object:Gem::Version
143
161
  version: '0'
144
162
  requirements: []
145
- rubygems_version: 3.0.3
163
+ rubygems_version: 3.1.2
146
164
  signing_key:
147
165
  specification_version: 4
148
166
  summary: Pure Ruby NETCONF server implementation