omf_common 6.0.0 → 6.0.2.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/Gemfile +4 -0
  2. data/bin/file_broadcaster.rb +56 -0
  3. data/bin/file_receiver.rb +62 -0
  4. data/bin/omf_keygen +21 -0
  5. data/bin/{monitor_topic.rb → omf_monitor_topic} +21 -8
  6. data/bin/omf_send_create +118 -0
  7. data/bin/{send_request.rb → omf_send_request} +12 -7
  8. data/example/engine_alt.rb +23 -24
  9. data/example/ls_app.yaml +21 -0
  10. data/lib/omf_common.rb +73 -12
  11. data/lib/omf_common/auth.rb +15 -0
  12. data/lib/omf_common/auth/certificate.rb +174 -0
  13. data/lib/omf_common/auth/certificate_store.rb +72 -0
  14. data/lib/omf_common/auth/ssh_pub_key_convert.rb +80 -0
  15. data/lib/omf_common/comm.rb +66 -9
  16. data/lib/omf_common/comm/amqp/amqp_communicator.rb +40 -13
  17. data/lib/omf_common/comm/amqp/amqp_file_transfer.rb +259 -0
  18. data/lib/omf_common/comm/amqp/amqp_topic.rb +14 -21
  19. data/lib/omf_common/comm/local/local_communicator.rb +31 -2
  20. data/lib/omf_common/comm/local/local_topic.rb +19 -3
  21. data/lib/omf_common/comm/topic.rb +48 -34
  22. data/lib/omf_common/comm/xmpp/communicator.rb +19 -10
  23. data/lib/omf_common/comm/xmpp/topic.rb +22 -81
  24. data/lib/omf_common/default_logging.rb +11 -0
  25. data/lib/omf_common/eventloop.rb +14 -0
  26. data/lib/omf_common/eventloop/em.rb +39 -6
  27. data/lib/omf_common/eventloop/local_evl.rb +15 -0
  28. data/lib/omf_common/exec_app.rb +29 -15
  29. data/lib/omf_common/message.rb +53 -5
  30. data/lib/omf_common/message/json/json_message.rb +149 -39
  31. data/lib/omf_common/message/xml/message.rb +112 -39
  32. data/lib/omf_common/protocol/6.0.rnc +5 -1
  33. data/lib/omf_common/protocol/6.0.rng +12 -0
  34. data/lib/omf_common/version.rb +1 -1
  35. data/omf_common.gemspec +7 -2
  36. data/test/fixture/omf_test.cert.pem +15 -0
  37. data/test/fixture/omf_test.pem +15 -0
  38. data/test/fixture/omf_test.pub +1 -0
  39. data/test/fixture/omf_test.pub.pem +6 -0
  40. data/test/omf_common/auth/certificate_spec.rb +113 -0
  41. data/test/omf_common/auth/ssh_pub_key_convert_spec.rb +13 -0
  42. data/test/omf_common/comm/topic_spec.rb +175 -0
  43. data/test/omf_common/comm/xmpp/communicator_spec.rb +15 -16
  44. data/test/omf_common/comm/xmpp/topic_spec.rb +63 -10
  45. data/test/omf_common/comm_spec.rb +66 -9
  46. data/test/omf_common/message/xml/message_spec.rb +43 -13
  47. data/test/omf_common/message_spec.rb +14 -0
  48. data/test/test_helper.rb +25 -0
  49. metadata +78 -15
  50. data/bin/send_create.rb +0 -94
@@ -5,10 +5,6 @@ module OmfCommon
5
5
  class AMQP
6
6
  class Topic < OmfCommon::Comm::Topic
7
7
 
8
- # def self.address_for(name)
9
- # "#{name}@local"
10
- # end
11
-
12
8
  def to_s
13
9
  "AMQP::Topic<#{id}>"
14
10
  end
@@ -28,7 +24,7 @@ module OmfCommon
28
24
  if @subscribed
29
25
  call_now = true
30
26
  else
31
- @on_subscrided_handlers << block
27
+ @on_subscribed_handlers << block
32
28
  end
33
29
  end
34
30
  if call_now
@@ -48,7 +44,7 @@ module OmfCommon
48
44
  @exchange = channel.topic(id, :auto_delete => true)
49
45
  @lock = Monitor.new
50
46
  @subscribed = false
51
- @on_subscrided_handlers = []
47
+ @on_subscribed_handlers = []
52
48
 
53
49
  # Subscribe as well
54
50
  #puts "QQ0(#{id})"
@@ -56,18 +52,21 @@ module OmfCommon
56
52
  #puts "QQ1(#{id}): #{queue}"
57
53
  queue.bind(@exchange)
58
54
  queue.subscribe do |headers, payload|
59
- #puts "===(#{id}) Incoming message '#{payload}'"
60
- msg = Message.parse(payload)
61
- #puts "---(#{id}) Parsed message '#{msg}'"
62
- on_incoming_message(msg)
55
+ #puts "===(#{id}) Incoming message '#{headers.content_type}'"
56
+ debug "Received message on #{@address}"
57
+ Message.parse(payload, headers.content_type) do |msg|
58
+ #puts "---(#{id}) Parsed message '#{msg}'"
59
+ on_incoming_message(msg)
60
+ end
63
61
  end
62
+ debug "Subscribed to '#@id'"
64
63
  # Call all accumulated on_subscribed handlers
65
64
  @lock.synchronize do
66
65
  @subscribed = true
67
- @on_subscrided_handlers.each do |block|
66
+ @on_subscribed_handlers.each do |block|
68
67
  after(0, &block)
69
68
  end
70
- @on_subscrided_handlers = nil
69
+ @on_subscribed_handlers = nil
71
70
  end
72
71
  end
73
72
  end
@@ -75,16 +74,10 @@ module OmfCommon
75
74
 
76
75
  def _send_message(msg, block = nil)
77
76
  super
78
- debug "(#{id}) Send message #{msg.inspect}"
79
- content = msg.marshall
80
- @exchange.publish(content)
81
- # OmfCommon.eventloop.after(0) do
82
- # on_incoming_message(msg)
83
- # end
77
+ content_type, content = msg.marshall(self)
78
+ debug "(#{id}) Send message (#{content_type}) #{msg.inspect}"
79
+ @exchange.publish(content, content_type: content_type, message_id: msg.mid)
84
80
  end
85
-
86
-
87
-
88
81
  end # class
89
82
  end # module
90
83
  end # module
@@ -1,11 +1,10 @@
1
1
  require 'omf_common/comm/local/local_topic'
2
- require 'omf_common/comm/monkey_patches'
2
+ require 'securerandom'
3
3
 
4
4
  module OmfCommon
5
5
  class Comm
6
6
  class Local
7
7
  class Communicator < OmfCommon::Comm
8
-
9
8
  # def initialize(opts = {})
10
9
  # # ignore arguments
11
10
  # end
@@ -13,6 +12,8 @@ module OmfCommon
13
12
  # Initialize comms layer
14
13
  #
15
14
  def init(opts = {})
15
+ @distributed_files = {}
16
+ super
16
17
  end
17
18
 
18
19
  # Shut down comms layer
@@ -49,6 +50,34 @@ module OmfCommon
49
50
  end
50
51
  end
51
52
 
53
+ def broadcast_file(file_path, topic_url = nil, opts = {}, &block)
54
+ topic_url ||= SecureRandom.uuid
55
+ @distributed_files[topic_url] = file_path
56
+ "bdcst:local:#{topic_url}"
57
+ end
58
+
59
+ def receive_file(topic_url, file_path = nil, opts = {}, &block)
60
+ if topic_url.start_with? 'local:'
61
+ topic_url = topic_url[6 .. -1]
62
+ end
63
+ file_path ||= File.join(Dir.tmpdir, Dir::Tmpname.make_tmpname('bdcast', ''))
64
+ OmfCommon.eventloop.after(0) do
65
+ #puts ">>>>>> #{topic_url}::#{@distributed_files.keys}"
66
+ unless original = @distributed_files[topic_url]
67
+ raise "File '#{topic_url}' hasn't started broadcasting"
68
+ end
69
+ mime_type = `file -b --mime-type #{original}`
70
+ `cp #{original} #{file_path}`
71
+ unless $?.success?
72
+ error "Couldn't copy '#{original}' to '#{file_path}'"
73
+ end
74
+ if block
75
+ block.call({action: :done, mime_type: mime_type.strip, path: file_path, size: -1, received: -1})
76
+ end
77
+ end
78
+ file_path
79
+ end
80
+
52
81
  # Publish to a pubsub topic
53
82
  #
54
83
  # @param [String] topic Pubsub topic name
@@ -4,7 +4,14 @@ module OmfCommon
4
4
  class Comm
5
5
  class Local
6
6
  class Topic < OmfCommon::Comm::Topic
7
-
7
+ @@marshall_messages = true
8
+
9
+ # If set to 'true' marshall and immediately unmarshall before handing it on
10
+ # messages
11
+ def self.marshall_messages=(flag)
12
+ @@marshall_messages = (flag == true)
13
+ end
14
+
8
15
  # def self.address_for(name)
9
16
  # "#{name}@local"
10
17
  # end
@@ -30,8 +37,17 @@ module OmfCommon
30
37
  def _send_message(msg, block = nil)
31
38
  super
32
39
  debug "(#{id}) Send message #{msg.inspect}"
33
- OmfCommon.eventloop.after(0) do
34
- on_incoming_message(msg)
40
+ if @@marshall_messages
41
+ content_type, payload = msg.marshall(self)
42
+ Message.parse(payload, content_type) do
43
+ OmfCommon.eventloop.after(0) do
44
+ on_incoming_message(msg)
45
+ end
46
+ end
47
+ else
48
+ OmfCommon.eventloop.after(0) do
49
+ on_incoming_message(msg)
50
+ end
35
51
  end
36
52
  end
37
53
 
@@ -33,9 +33,6 @@ module OmfCommon
33
33
  # Request the creation of a new resource. Returns itself
34
34
  #
35
35
  def create(res_type, config_props = {}, core_props = {}, &block)
36
- # new_res = nil
37
- #res_name = res_name.to_sym
38
- #config_props[:name] ||= res_name
39
36
  config_props[:type] ||= res_type
40
37
  debug "Create resource of type '#{res_type}'"
41
38
  create_message_and_publish(:create, config_props, core_props, block)
@@ -54,56 +51,61 @@ module OmfCommon
54
51
  end
55
52
 
56
53
  def inform(type, props = {}, core_props = {}, &block)
54
+ core_props[:src] ||= OmfCommon.comm.local_address
57
55
  msg = OmfCommon::Message.create(:inform, props, core_props.merge(itype: type))
58
56
  publish(msg, &block)
59
57
  self
60
58
  end
61
59
 
62
- # def inform(type, props = {}, &block)
63
- # msg = OmfCommon::Message.create(:inform, props)
64
- # msg.itype = type
65
- # publish(msg, &block)
66
- # self
67
- # end
68
-
69
60
  def release(resource, core_props = {}, &block)
70
61
  unless resource.is_a? self.class
71
- raise "Expected '#{self.class}', but got '#{resource.class}'"
62
+ raise ArgumentError, "Expected '#{self.class}', but got '#{resource.class}'"
72
63
  end
64
+ core_props[:src] ||= OmfCommon.comm.local_address
73
65
  msg = OmfCommon::Message.create(:release, {}, core_props.merge(res_id: resource.id))
74
66
  publish(msg, &block)
75
67
  self
76
68
  end
77
69
 
78
-
79
70
  def create_message_and_publish(type, props = {}, core_props = {}, block = nil)
80
71
  debug "(#{id}) create_message_and_publish '#{type}': #{props.inspect}"
72
+ core_props[:src] ||= OmfCommon.comm.local_address
81
73
  msg = OmfCommon::Message.create(type, props, core_props)
82
74
  publish(msg, &block)
83
75
  end
84
76
 
85
77
  def publish(msg, &block)
86
- # TODO should it be _send_message(msg, &block) ?
87
- #raise "Expected message but got '#{msg.class}" unless msg.is_a?(OmfCommon::Message)
78
+ raise "Expected message but got '#{msg.class}" unless msg.is_a?(OmfCommon::Message)
88
79
  _send_message(msg, block)
89
80
  end
90
81
 
82
+ # TODO we should fix this long list related to INFORM messages
83
+ # according to FRCP, inform types are (underscore form):
84
+ # :creation_ok, :creation_failed, :status, :error, :warn, :released
85
+ #
86
+ # and we shall add :message for ALL types of messages.
91
87
  [:created,
92
88
  :create_succeeded, :create_failed,
93
89
  :inform_status, :inform_failed,
94
90
  :released, :failed,
95
- :message
91
+ :creation_ok, :creation_failed, :status, :error, :warn
96
92
  ].each do |itype|
97
93
  mname = "on_#{itype}"
98
94
  define_method(mname) do |*args, &message_block|
99
- debug "(#{id}) register handler for '#{mname}'"
100
- @lock.synchronize do
101
- (@handlers[itype] ||= []) << message_block
102
- end
103
- self
95
+ warn_deprecation(mname, :on_message, :on_inform)
96
+
97
+ add_message_handler(itype, &message_block)
104
98
  end
105
99
  end
106
100
 
101
+ def on_message(*args, &message_block)
102
+ add_message_handler(:message, &message_block)
103
+ end
104
+
105
+ def on_inform(*args, &message_block)
106
+ add_message_handler(:inform, &message_block)
107
+ end
108
+
107
109
  # Unsubscribe from the underlying comms layer
108
110
  #
109
111
  def unsubscribe()
@@ -111,7 +113,7 @@ module OmfCommon
111
113
  end
112
114
 
113
115
  def on_subscribed(&block)
114
- raise "Not implemented"
116
+ raise NotImplementedError
115
117
  end
116
118
 
117
119
  # For detecting message publishing error, means if callback indeed yield a Topic object, there is no publishing error, thus always false
@@ -120,7 +122,7 @@ module OmfCommon
120
122
  end
121
123
 
122
124
  def address
123
- raise "Not implemented"
125
+ raise NotImplementedError
124
126
  end
125
127
 
126
128
  def after(delay_sec, &block)
@@ -140,34 +142,43 @@ module OmfCommon
140
142
  @context2cbk = {}
141
143
  end
142
144
 
143
-
145
+ # _send_message will also register callbacks for reply messages by default
146
+ #
144
147
  def _send_message(msg, block = nil)
145
148
  if (block)
146
149
  # register callback for responses to 'mid'
147
- @context2cbk[msg.mid.to_s] = {block: block, created_at: Time.now}
150
+ debug "(#{id}) register callback for responses to 'mid: #{msg.mid}'"
151
+ @lock.synchronize do
152
+ @context2cbk[msg.mid.to_s] = { block: block, created_at: Time.now }
153
+ end
148
154
  end
149
155
  end
150
156
 
157
+ # Process a message received from this topic.
158
+ #
159
+ # @param [OmfCommon::Message] msg Message received
160
+ # @param [Hash] auth_info Authentication information
161
+ # @option auth_info [Symbol] :signer Id
151
162
  def on_incoming_message(msg)
152
163
  type = msg.operation
153
164
  debug "(#{id}) Deliver message '#{type}': #{msg.inspect}"
154
165
  htypes = [type, :message]
155
166
  if type == :inform
156
- if it = msg.itype.to_s.downcase
157
- #puts "TTT> #{it}"
167
+ # TODO keep converting itype is painful, need to solve this.
168
+ if (it = msg.itype(:ruby)) # format itype as lower case string
158
169
  case it
159
170
  when "creation_ok"
160
171
  htypes << :create_succeeded
161
172
  when 'status'
162
173
  htypes << :inform_status
163
- else
164
- htypes << it.to_sym
165
174
  end
175
+
176
+ htypes << it.to_sym
166
177
  end
167
178
  end
168
179
 
169
180
  debug "(#{id}) Message type '#{htypes.inspect}' (#{msg.class}:#{msg.cid})"
170
- hs = htypes.map do |ht| @handlers[ht] end.compact.flatten
181
+ hs = htypes.map { |ht| @handlers[ht] }.compact.flatten
171
182
  debug "(#{id}) Distributing message to '#{hs.inspect}'"
172
183
  hs.each do |block|
173
184
  block.call msg
@@ -176,14 +187,17 @@ module OmfCommon
176
187
  debug "(#{id}) Distributing message to '#{cbk.inspect}'"
177
188
  cbk[:last_used] = Time.now
178
189
  cbk[:block].call(msg)
179
- # else
180
- # if msg.cid
181
- # puts "====NOOOO for #{msg.cid} - #{@context2cbk.keys.inspect}"
182
- # end
183
190
  end
184
-
185
191
  end
186
192
 
193
+ def add_message_handler(handler_name, &message_block)
194
+ raise ArgumentError, 'Missing message callback' if message_block.nil?
195
+ debug "(#{id}) register handler for '#{handler_name}'"
196
+ @lock.synchronize do
197
+ (@handlers[handler_name] ||= []) << message_block
198
+ end
199
+ self
200
+ end
187
201
 
188
202
  end
189
203
  end
@@ -25,18 +25,17 @@ class Comm
25
25
  { :var => "pubsub#publish_model", :value => "open" }]
26
26
  })
27
27
 
28
+ def conn_info
29
+ { proto: :xmpp, user: jid.node, domain: jid.domain }
30
+ end
31
+
28
32
  # Capture system :INT & :TERM signal
29
33
  def on_interrupted(&block)
30
- if block
31
- trap(:INT) { block.call(self) }
32
- trap(:TERM) { block.call(self) }
33
- end
34
+ @cbks[:interpreted] << block
34
35
  end
35
36
 
36
37
  def on_connected(&block)
37
- when_ready do
38
- block.call(self)
39
- end
38
+ @cbks[:connected] << block
40
39
  end
41
40
 
42
41
  # Set up XMPP options and start the Eventmachine, connect to XMPP server
@@ -63,6 +62,10 @@ class Comm
63
62
 
64
63
  connect(username, password, server)
65
64
 
65
+ when_ready do
66
+ @cbks[:connected].each { |cbk| cbk.call(self) }
67
+ end
68
+
66
69
  disconnected do
67
70
  unless normal_shutdown_mode
68
71
  unless retry_counter > 0
@@ -76,6 +79,11 @@ class Comm
76
79
  shutdown
77
80
  end
78
81
  end
82
+
83
+ trap(:INT) { @cbks[:interpreted].empty? ? disconnect : @cbks[:interpreted].each { |cbk| cbk.call(self) } }
84
+ trap(:TERM) { @cbks[:interpreted].empty? ? disconnect : @cbks[:interpreted].each { |cbk| cbk.call(self) } }
85
+
86
+ super
79
87
  end
80
88
 
81
89
  # Set up XMPP options and start the Eventmachine, connect to XMPP server
@@ -151,7 +159,7 @@ class Comm
151
159
  def publish(topic, message, &block)
152
160
  raise StandardError, "Invalid message" unless message.valid?
153
161
 
154
- message = message.xml unless message.kind_of? String
162
+ message = message.marshall[1] unless message.kind_of? String
155
163
 
156
164
  new_block = proc do |stanza|
157
165
  published_messages << OpenSSL::Digest::SHA1.new(message.to_s)
@@ -166,8 +174,8 @@ class Comm
166
174
  #
167
175
  def topic_event(additional_guard = nil, &block)
168
176
  guard_block = proc do |event|
169
- passed = (event.items?) && (!event.delayed?) && event.items.first.payload &&
170
- !published_messages.include?(OpenSSL::Digest::SHA1.new(event.items.first.payload))
177
+ passed = !event.delayed? && event.items? && !event.items.first.payload.nil? #&&
178
+ #!published_messages.include?(OpenSSL::Digest::SHA1.new(event.items.first.payload))
171
179
 
172
180
  MPReceived.inject(Time.now.to_f, jid, event.node, event.items.first.payload.to_s.gsub("\n",'')) if OmfCommon::Measure.enabled? && passed
173
181
 
@@ -184,6 +192,7 @@ class Comm
184
192
 
185
193
  def initialize(opts = {})
186
194
  self.published_messages = []
195
+ @cbks = {connected: [], interpreted: []}
187
196
  super
188
197
  end
189
198
 
@@ -2,69 +2,11 @@ module OmfCommon
2
2
  class Comm
3
3
  class XMPP
4
4
  class Topic < OmfCommon::Comm::Topic
5
- %w(creation.ok creation.failed status released error warn).each do |itype|
6
- define_method("on_#{itype.gsub(/\./, '_')}") do |*args, &message_block|
7
- mid = args[0].mid if args[0]
8
-
9
- raise ArgumentError, 'Missing callback' if message_block.nil?
10
-
11
- event_block = proc do |event|
12
- message_block.call(OmfCommon::Message.parse(event.items.first.payload))
13
- end
14
-
15
- guard_block = proc do |event|
16
- (event.items?) && (!event.delayed?) &&
17
- event.items.first.payload &&
18
- (omf_message = OmfCommon::Message.parse(event.items.first.payload)) &&
19
- event.node == id.to_s &&
20
- omf_message.operation == :inform &&
21
- omf_message.read_content(:itype) == itype.upcase &&
22
- (mid ? (omf_message.cid == mid) : true)
23
- end
24
-
25
- OmfCommon.comm.topic_event(guard_block, &event_block)
26
- end
27
- end
28
-
29
- def on_message(message_guard_proc = nil, ref_id = 0, &message_block)
30
- @lock.synchronize do
31
- @on_message_cbks[ref_id] ||= []
32
- @on_message_cbks[ref_id] << message_block
33
- end
34
-
35
- event_block = proc do |event|
36
- @on_message_cbks.each do |id, cbks|
37
- cbks.each do |cbk|
38
- cbk.call(OmfCommon::Message.parse(event.items.first.payload))
39
- end
40
- end
41
- end
42
-
43
- guard_block = proc do |event|
44
- (event.items?) && (!event.delayed?) &&
45
- event.items.first.payload &&
46
- (omf_message = OmfCommon::Message.parse(event.items.first.payload)) &&
47
- event.node == id.to_s &&
48
- (valid_guard?(message_guard_proc) ? message_guard_proc.call(omf_message) : true)
49
- end
50
- OmfCommon.comm.topic_event(guard_block, &event_block)
51
- end
52
-
53
- def delete_on_message_cbk_by_id(id)
54
- @lock.synchronize do
55
- @on_message_cbks[id] && @on_message_cbks.reject! { |k| k == id.to_s }
56
- end
57
- end
58
-
59
- def inform(type, props = {}, core_props = {}, &block)
60
- msg = OmfCommon::Message.create(:inform, props, core_props.merge(itype: type))
61
- publish(msg, &block)
62
- self
63
- end
64
-
65
- def publish(msg, &block)
66
- _send_message(msg, &block)
67
- end
5
+ # def delete_on_message_cbk_by_id(id)
6
+ # @lock.synchronize do
7
+ # @on_message_cbks[id] && @on_message_cbks.reject! { |k| k == id.to_s }
8
+ # end
9
+ # end
68
10
 
69
11
  def address
70
12
  "xmpp://#{id.to_s}@#{OmfCommon.comm.jid.domain}"
@@ -81,8 +23,6 @@ class XMPP
81
23
  private
82
24
 
83
25
  def initialize(id, opts = {}, &block)
84
- @on_message_cbks = Hashie::Mash.new
85
-
86
26
  id = $1 if id =~ /^xmpp:\/\/(.+)@.+$/
87
27
 
88
28
  super
@@ -103,6 +43,8 @@ class XMPP
103
43
  end
104
44
  end
105
45
 
46
+ # Create xmpp pubsub topic, then subscribe to it
47
+ #
106
48
  OmfCommon.comm._create(id.to_s) do |stanza|
107
49
  if stanza.error?
108
50
  e_stanza = Blather::StanzaError.import(stanza)
@@ -116,31 +58,30 @@ class XMPP
116
58
  OmfCommon.comm._subscribe(id.to_s, &topic_block)
117
59
  end
118
60
  end
119
- end
120
61
 
121
- def _send_message(msg, &block)
122
- # while sending a message, need to setup handler for replying messages
123
- OmfCommon.comm.publish(self.id, msg) do |stanza|
124
- if !stanza.error? && !block.nil?
125
- on_error(msg, &block)
126
- on_warn(msg, &block)
127
- case msg.operation
128
- when :create
129
- on_creation_ok(msg, &block)
130
- on_creation_failed(msg, &block)
131
- when :configure, :request
132
- on_status(msg, &block)
133
- when :release
134
- on_released(msg, &block)
135
- end
62
+ event_block = proc do |event|
63
+ OmfCommon::Message.parse(event.items.first.payload) do |parsed_msg|
64
+ on_incoming_message(parsed_msg)
136
65
  end
137
66
  end
67
+
68
+ OmfCommon.comm.topic_event(default_guard, &event_block)
69
+ end
70
+
71
+ def _send_message(msg, block)
72
+ super
73
+ OmfCommon.comm.publish(self.id, msg)
138
74
  end
139
75
 
140
76
  def valid_guard?(guard_proc)
141
77
  guard_proc && guard_proc.class == Proc
142
78
  end
143
79
 
80
+ def default_guard
81
+ proc do |event|
82
+ event.node == self.id.to_s
83
+ end
84
+ end
144
85
  end
145
86
  end
146
87
  end