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
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