omf_common 6.0.0 → 6.0.2.pre.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.
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
data/Gemfile CHANGED
@@ -2,3 +2,7 @@ source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in omf_common.gemspec
4
4
  gemspec
5
+
6
+ group :test do
7
+ gem 'rake'
8
+ end
@@ -0,0 +1,56 @@
1
+ #
2
+ DESCR = %{
3
+ Broadcast a file to a topic group
4
+ }
5
+
6
+ require 'omf_common'
7
+
8
+ OP_MODE = :development
9
+ $debug = false
10
+
11
+ opts = {
12
+ communication: {
13
+ #url: 'xmpp://srv.mytestbed.net'
14
+ },
15
+ eventloop: { type: :em},
16
+ logging: {
17
+ level: 'info'
18
+ }
19
+ }
20
+
21
+ file_path = nil
22
+ resource_url = nil
23
+
24
+ op = OptionParser.new
25
+ op.banner = "Usage: #{op.program_name} [options]\n#{DESCR}\n"
26
+ op.on '-r', '--resource-url URL', "URL of resource" do |url|
27
+ resource_url = url
28
+ end
29
+ op.on '-f', '--file FILE', "File to broadcast" do |path|
30
+ file_path = path
31
+ end
32
+ op.on '-d', '--debug', "Set logging to DEBUG level" do
33
+ opts[:logging][:level] = 'debug'
34
+ $debug = true
35
+ end
36
+ op.on_tail('-h', "--help", "Show this message") { $stderr.puts op; exit }
37
+ rest = op.parse(ARGV) || []
38
+
39
+ unless resource_url && file_path
40
+ $stderr.puts 'Missing --resource-url or --file'
41
+ $stderr.puts op
42
+ exit(-1)
43
+ end
44
+
45
+ r = resource_url.split('/')
46
+ resource = r.pop
47
+ opts[:communication][:url] = r.join('/')
48
+
49
+ OmfCommon.init(OP_MODE, opts) do |el|
50
+ OmfCommon.comm.on_connected do |comm|
51
+ comm.broadcast_file(file_path, resource) do |state|
52
+ debug state.inspect
53
+ OmfCommon.eventloop.stop if state[:action] == :done
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,62 @@
1
+ #
2
+ DESCR = %{
3
+ Receive a file sent to a topic group
4
+ }
5
+
6
+ require 'omf_common'
7
+
8
+ OP_MODE = :development
9
+ $debug = false
10
+
11
+ opts = {
12
+ communication: {
13
+ #url: 'amqp://srv.mytestbed.net'
14
+ },
15
+ eventloop: { type: :em},
16
+ logging: {
17
+ level: 'info'
18
+ }
19
+ }
20
+
21
+ file_path = nil
22
+ resource_url = nil
23
+
24
+ op = OptionParser.new
25
+ op.banner = "Usage: #{op.program_name} [options]\n#{DESCR}\n"
26
+ op.on '-r', '--resource-url URL', "URL of resource" do |url|
27
+ resource_url = url
28
+ end
29
+ op.on '-f', '--file FILE', "Path to store received file" do |path|
30
+ file_path = path
31
+ end
32
+ op.on '-d', '--debug', "Set logging to DEBUG level" do
33
+ opts[:logging][:level] = 'debug'
34
+ $debug = true
35
+ end
36
+ op.on_tail('-h', "--help", "Show this message") { $stderr.puts op; exit }
37
+ rest = op.parse(ARGV) || []
38
+
39
+ unless resource_url && file_path
40
+ $stderr.puts 'Missing --resource-url or --file'
41
+ $stderr.puts op
42
+ exit(-1)
43
+ end
44
+
45
+ r = resource_url.split('/')
46
+ resource = r.pop
47
+ opts[:communication][:url] = r.join('/')
48
+
49
+ OmfCommon.init(OP_MODE, opts) do |el|
50
+ OmfCommon.comm.on_connected do |comm|
51
+ comm.receive_file(resource_url, file_path) do |state|
52
+ debug state
53
+ case state[:action]
54
+ when :progress
55
+ puts "Progress: #{(state[:progress] * 100).to_i}%"
56
+ when :done
57
+ puts "Fully received '#{file_path}' (#{state[:mime_type]})"
58
+ OmfCommon.eventloop.stop
59
+ end
60
+ end
61
+ end
62
+ end
data/bin/omf_keygen ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'omf_common'
4
+
5
+ OmfCommon::Auth::CertificateStore.init
6
+
7
+ root = OmfCommon::Auth::Certificate.create(nil, 'omf_ca', 'ca', 'omf')
8
+
9
+ ec_key = OpenSSL::PKey::RSA.new(2048)
10
+ rc_key = OpenSSL::PKey::RSA.new(2048)
11
+
12
+ ec_pub = ec_key.public_key
13
+ rc_pub = rc_key.public_key
14
+
15
+ ec = root.create_for('ec', 'ec', 'controller', 'omf', 365, ec_pub)
16
+ rc = root.create_for('rc', 'rc', 'controller', 'omf', 365, rc_pub)
17
+
18
+ %w(root ec_key rc_key ec_pub rc_pub ec rc).each do |n|
19
+ File.write("#{n}.pem", eval(n).to_pem)
20
+ info "Generated #{n}.pem"
21
+ end
@@ -1,4 +1,7 @@
1
- require 'optparse'
1
+ #!/usr/bin/env ruby
2
+ BIN_DIR = File.dirname(File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__)
3
+ TOP_DIR = File.join(BIN_DIR, '..')
4
+ $: << File.join(TOP_DIR, 'lib')
2
5
 
3
6
  DESCR = %{
4
7
  Monitor a set of resources (topics) and print all observed messages.
@@ -9,13 +12,16 @@ that there will be a delay until the new monitors are in place which
9
12
  can result in missed messages.
10
13
  }
11
14
 
15
+ require 'optparse'
12
16
  require 'omf_common'
13
17
 
14
18
  OP_MODE = :development
15
19
 
16
20
  opts = {
17
21
  communication: {
18
- url: 'amqp://srv.mytestbed.net'
22
+ #url: 'xmpp://srv.mytestbed.net',
23
+ auth: {}
24
+
19
25
  },
20
26
  eventloop: { type: :em},
21
27
  logging: {
@@ -25,23 +31,25 @@ opts = {
25
31
 
26
32
  observed_topic = nil
27
33
  $follow_children = true
34
+ $debug = false
28
35
 
29
36
  op = OptionParser.new
30
37
  op.banner = "Usage: #{op.program_name} [options] topic1 topic2 ...\n#{DESCR}\n"
31
- op.on '-c', '--comms-url URL', "URL to communication layer [#{opts[:communication][:url]}]" do |url|
38
+ op.on '-c', '--comms-url URL', "URL of communication server (e.g. xmpp://my.server.com)" do |url|
32
39
  opts[:communication][:url] = url
33
40
  end
34
41
  op.on '-f', "--[no-]follow-children", "Follow all newly created resources [#{$follow_children}]" do |flag|
35
42
  $follow_children = flag
36
43
  end
37
- op.on '-d', '--debug', "Set logging to DEBUG level" do
44
+ op.on '-d', '--debug', "Set log level to DEBUG" do
38
45
  opts[:logging][:level] = 'debug'
46
+ $debug = true
39
47
  end
40
48
  op.on_tail('-h', "--help", "Show this message") { $stderr.puts op; exit }
41
49
  observed_topics = op.parse(ARGV)
42
50
 
43
- unless observed_topics
44
- $stderr.puts 'Missing declaration of topics to follow'
51
+ unless opts[:communication][:url] && observed_topics
52
+ $stderr.puts "ERROR: Missing declaration of --comms-url or topics to follow\n\n"
45
53
  $stderr.puts op
46
54
  exit(-1)
47
55
  end
@@ -56,8 +64,13 @@ def observe(tname, comm)
56
64
  comm.subscribe(tname) do |topic|
57
65
  topic.on_message do |msg|
58
66
  ts = Time.now.strftime('%H:%M:%S')
59
- puts "#{ts} #{msg.type}(#{msg.itype}) #{msg.inspect}"
60
- puts " #{topic.id}"
67
+ puts "#{ts} #{msg.type}(#{msg.itype}) #{$debug ? msg.inspect : ''}"
68
+ #puts " #{topic.id}"
69
+ if (src_topic = msg.src.id) == topic.id
70
+ puts " #{topic.id}"
71
+ else
72
+ puts " #{src_topic} via #{topic.id}"
73
+ end
61
74
  msg.each_property do |name, value|
62
75
  puts " #{name}: #{value}"
63
76
  end
@@ -0,0 +1,118 @@
1
+ #!/usr/bin/env ruby
2
+ BIN_DIR = File.dirname(File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__)
3
+ TOP_DIR = File.join(BIN_DIR, '..')
4
+ $: << File.join(TOP_DIR, 'lib')
5
+
6
+ DESCR = %{
7
+ Send a create message to a specific resource (topic) and print out any replies.
8
+
9
+ Any additional command line arguments are interpreted as property:value and are
10
+ sent with the create message.
11
+ }
12
+
13
+ require 'omf_common'
14
+
15
+ OP_MODE = :development
16
+ $debug = false
17
+
18
+ opts = {
19
+ communication: {
20
+ #url: 'xmpp://srv.mytestbed.net'
21
+ },
22
+ eventloop: { type: :em},
23
+ logging: {
24
+ level: 'info'
25
+ }
26
+ }
27
+
28
+ resource_url = nil
29
+ resource_type = nil
30
+ resource_properties = {}
31
+
32
+ op = OptionParser.new
33
+ op.banner = "Usage: #{op.program_name} [options] property1:value1 property2:value2 ...\n#{DESCR}\n"
34
+ op.on '-r', '--resource-url URL', "URL of resource (e.g. xmpp://my.server.com/topic1)" do |url|
35
+ resource_url = url
36
+ end
37
+ op.on '-t', '--type TYPE', "Type of resource to create (e.g. node)" do |type|
38
+ resource_type = type
39
+ end
40
+ op.on '-y', '--yaml YAML_FILE', "Read type and property from YAML file" do |yfile|
41
+ require 'yaml'
42
+ y = YAML.load_file(yfile)
43
+ unless o = y['create']
44
+ puts "Expected top level 'create', but found '#{y.keys.inspect}'"
45
+ abort
46
+ end
47
+ resource_type = o['type']
48
+ resource_properties = o['properties']
49
+ end
50
+ op.on '-d', '--debug', "Set log level to DEBUG" do
51
+ opts[:logging][:level] = 'debug'
52
+ $debug = true
53
+ end
54
+ op.on_tail('-h', "--help", "Show this message") { $stderr.puts op; exit }
55
+ rest = op.parse(ARGV) || []
56
+
57
+ unless resource_url || resource_type
58
+ $stderr.puts 'Missing --resource-url --type or'
59
+ $stderr.puts op
60
+ exit(-1)
61
+ end
62
+
63
+ r = resource_url.split('/')
64
+ resource = r.pop
65
+ opts[:communication][:url] = r.join('/')
66
+
67
+ key = nil
68
+ def err_exit
69
+ $stderr.puts("Options need to be of the 'key: value' type")
70
+ exit(-1)
71
+ end
72
+ rest.each do |s|
73
+ sa = s.split(':')
74
+ if sa.length == 2
75
+ err_exit if key
76
+ resource_properties[sa[0]] = sa[1]
77
+ else
78
+ if s.end_with?(':')
79
+ err_exit if key
80
+ key = s[0]
81
+ else
82
+ err_exit unless key
83
+ resource_properties[key] = s[0]
84
+ key = nil
85
+ end
86
+ end
87
+ end
88
+ err_exit if key
89
+
90
+ def print_message(msg, resource)
91
+ puts "#{resource} <#{msg.type}(#{msg.itype})> #{$debug ? msg.inspect : ''}"
92
+ if msg.itype == 'WARN'
93
+ puts " #{msg.inspect}"
94
+ end
95
+ msg.each_property do |name, value|
96
+ puts " #{name}: #{value}"
97
+ end
98
+ puts "------"
99
+ end
100
+
101
+ OmfCommon.init(OP_MODE, opts) do |el|
102
+ OmfCommon.comm.on_connected do |comm|
103
+ comm.subscribe(resource) do |ptopic|
104
+ uid = resource_properties[:uid] ||= SecureRandom.uuid # uuid of newly created object
105
+ # Already subscribe to the new object's topic to avoid missing
106
+ # any initial messages
107
+ comm.subscribe(uid) do |ctopic|
108
+ ctopic.on_message do |msg|
109
+ print_message(msg, 'NEW')
110
+ end
111
+
112
+ ptopic.create(resource_type, resource_properties) do |msg|
113
+ print_message(msg, resource)
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
@@ -1,4 +1,8 @@
1
- #
1
+ #!/usr/bin/env ruby
2
+ BIN_DIR = File.dirname(File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__)
3
+ TOP_DIR = File.join(BIN_DIR, '..')
4
+ $: << File.join(TOP_DIR, 'lib')
5
+
2
6
  DESCR = %{
3
7
  Send a request to a specific resource (topic) and print out any replies.
4
8
 
@@ -12,7 +16,7 @@ OP_MODE = :development
12
16
 
13
17
  opts = {
14
18
  communication: {
15
- # url: 'amqp://srv.mytestbed.net'
19
+ #url: 'xmpp://srv.mytestbed.net'
16
20
  },
17
21
  eventloop: { type: :em},
18
22
  logging: {
@@ -23,18 +27,18 @@ opts = {
23
27
  resource_url = nil
24
28
 
25
29
  op = OptionParser.new
26
- op.banner = "Usage: #{op.program_name} [options] prop1 prop2 ...\n#{DESCR}\n"
27
- op.on '-r', '--resource-url URL', "URL of resource" do |url|
30
+ op.banner = "Usage: #{op.program_name} [options] [prop1 prop2 ...]\n#{DESCR}\n"
31
+ op.on '-r', '--resource-url URL', "URL of resource (e.g. xmpp://my.server.com/topic1)" do |url|
28
32
  resource_url = url
29
33
  end
30
- op.on '-d', '--debug', "Set logging to DEBUG level" do
34
+ op.on '-d', '--debug', "Set log level to DEBUG" do
31
35
  opts[:logging][:level] = 'debug'
32
36
  end
33
37
  op.on_tail('-h', "--help", "Show this message") { $stderr.puts op; exit }
34
38
  req_properties = op.parse(ARGV) || []
35
39
 
36
40
  unless resource_url
37
- $stderr.puts 'Missing --resource-url'
41
+ $stderr.puts "ERROR: Missing --resource-url\n\n"
38
42
  $stderr.puts op
39
43
  exit(-1)
40
44
  end
@@ -47,7 +51,8 @@ OmfCommon.init(OP_MODE, opts) do |el|
47
51
  OmfCommon.comm.on_connected do |comm|
48
52
  comm.subscribe(resource) do |topic|
49
53
  topic.request(req_properties) do |msg|
50
- puts "#{resource} <#{msg.type}(#{msg.itype})> #{msg.inspect}"
54
+ dm = (opts[:logging][:level] == 'debug') ? " #{msg.inspect}" : ""
55
+ puts "#{resource} <#{msg.type}(#{msg.itype})>#{dm}"
51
56
  msg.each_property do |name, value|
52
57
  puts " #{name}: #{value}"
53
58
  end
@@ -1,25 +1,23 @@
1
1
  # OMF_VERSIONS = 6.0
2
2
  require 'omf_common'
3
+ require 'omf_common/auth/certificate'
3
4
 
5
+ root_cert = OmfCommon::Auth::Certificate.create('sa', 'authority')
4
6
  opts = {
5
7
  communication: {
6
- url: 'amqp://localhost',
8
+ auth: {
9
+ #store: 'amqp://localhost',
10
+ certs: [
11
+ root_cert.to_pem_compact
12
+ ]
13
+ }
7
14
  }
8
15
  }
9
16
 
10
- # $stdout.sync = true
11
- # Logging.appenders.stdout(
12
- # 'my_format',
13
- # :layout => Logging.layouts.pattern(:date_pattern => '%H:%M:%S',
14
- # :pattern => '%d %5l %c{2}: %m\n',
15
- # :color_scheme => 'none'))
16
- # Logging.logger.root.appenders = 'my_format'
17
- # Logging.logger.root.level = :debug if opts[:debug]
18
-
19
- # Environment setup
20
- #OmfCommon.init(:developement, opts)
21
- OmfCommon.init(:local)
22
17
 
18
+ OmfCommon.init(:local, opts)
19
+ # Create a certificate for this controller
20
+ root_cert.create_for(:controller, :controller, OmfCommon.comm.local_address())
23
21
 
24
22
 
25
23
  def create_engine(garage)
@@ -54,7 +52,7 @@ end
54
52
  # This method is called whenever a new engine has been created by the garage.
55
53
  #
56
54
  # @param [Topic] engine Topic representing the created engine
57
- #
55
+ #
58
56
  def on_engine_created(engine, garage)
59
57
  # Monitor all status information from teh engine
60
58
  engine.on_inform_status do |msg|
@@ -74,19 +72,19 @@ def on_engine_created(engine, garage)
74
72
  #engine.request() do |msg|
75
73
  puts ">>> REPLY #{msg.inspect}"
76
74
  end
77
-
78
-
79
75
 
80
76
 
81
- return
82
-
77
+
78
+
79
+ return
80
+
83
81
  # Now we will apply 50% throttle to the engine
84
82
  engine.configure(throttle: 50)
85
83
 
86
84
  # Some time later, we want to reduce the throttle to 0, to avoid blowing up the engine
87
85
  engine.after(5) do
88
86
  engine.configure(throttle: 0)
89
-
87
+
90
88
  # While we are at it, also test error handling
91
89
  engine.request([:error]) do |msg|
92
90
  if msg.success?
@@ -110,14 +108,15 @@ end
110
108
 
111
109
  OmfCommon.eventloop.run do |el|
112
110
  OmfCommon.comm.on_connected do |comm|
113
-
111
+
114
112
  # Create garage proxy
115
113
  load File.join(File.dirname(__FILE__), '..', '..', 'omf_rc', 'example', 'garage_controller.rb')
116
- garage_inst = OmfRc::ResourceFactory.create(:garage, hrn: :garage_1)
117
-
114
+ garage_cert = root_cert.create_for(:garage1, :garage)
115
+ garage_inst = OmfRc::ResourceFactory.create(:garage, uid: :garage_1, certificate: garage_cert)
116
+
118
117
  # Get handle on existing entity
119
118
  comm.subscribe('garage_1') do |garage|
120
-
119
+
121
120
  garage.on_inform_failed do |msg|
122
121
  logger.error msg
123
122
  end
@@ -126,7 +125,7 @@ OmfCommon.eventloop.run do |el|
126
125
  create_engine(garage)
127
126
  end
128
127
  end
129
-
128
+
130
129
  el.after(20) { el.stop }
131
130
  end
132
131
  end