right_agent 0.5.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 (147) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +78 -0
  3. data/Rakefile +86 -0
  4. data/lib/right_agent.rb +66 -0
  5. data/lib/right_agent/actor.rb +163 -0
  6. data/lib/right_agent/actor_registry.rb +76 -0
  7. data/lib/right_agent/actors/agent_manager.rb +189 -0
  8. data/lib/right_agent/agent.rb +735 -0
  9. data/lib/right_agent/agent_config.rb +403 -0
  10. data/lib/right_agent/agent_identity.rb +209 -0
  11. data/lib/right_agent/agent_tags_manager.rb +213 -0
  12. data/lib/right_agent/audit_formatter.rb +107 -0
  13. data/lib/right_agent/broker_client.rb +683 -0
  14. data/lib/right_agent/command.rb +30 -0
  15. data/lib/right_agent/command/agent_manager_commands.rb +134 -0
  16. data/lib/right_agent/command/command_client.rb +136 -0
  17. data/lib/right_agent/command/command_constants.rb +42 -0
  18. data/lib/right_agent/command/command_io.rb +128 -0
  19. data/lib/right_agent/command/command_parser.rb +87 -0
  20. data/lib/right_agent/command/command_runner.rb +105 -0
  21. data/lib/right_agent/command/command_serializer.rb +63 -0
  22. data/lib/right_agent/console.rb +65 -0
  23. data/lib/right_agent/core_payload_types.rb +42 -0
  24. data/lib/right_agent/core_payload_types/cookbook.rb +61 -0
  25. data/lib/right_agent/core_payload_types/cookbook_position.rb +46 -0
  26. data/lib/right_agent/core_payload_types/cookbook_repository.rb +116 -0
  27. data/lib/right_agent/core_payload_types/cookbook_sequence.rb +70 -0
  28. data/lib/right_agent/core_payload_types/dev_repositories.rb +90 -0
  29. data/lib/right_agent/core_payload_types/event_categories.rb +38 -0
  30. data/lib/right_agent/core_payload_types/executable_bundle.rb +138 -0
  31. data/lib/right_agent/core_payload_types/login_policy.rb +72 -0
  32. data/lib/right_agent/core_payload_types/login_user.rb +62 -0
  33. data/lib/right_agent/core_payload_types/planned_volume.rb +94 -0
  34. data/lib/right_agent/core_payload_types/recipe_instantiation.rb +60 -0
  35. data/lib/right_agent/core_payload_types/repositories_bundle.rb +50 -0
  36. data/lib/right_agent/core_payload_types/right_script_attachment.rb +95 -0
  37. data/lib/right_agent/core_payload_types/right_script_instantiation.rb +73 -0
  38. data/lib/right_agent/core_payload_types/secure_document.rb +66 -0
  39. data/lib/right_agent/core_payload_types/secure_document_location.rb +63 -0
  40. data/lib/right_agent/core_payload_types/software_repository_instantiation.rb +61 -0
  41. data/lib/right_agent/daemonize.rb +35 -0
  42. data/lib/right_agent/dispatcher.rb +348 -0
  43. data/lib/right_agent/enrollment_result.rb +217 -0
  44. data/lib/right_agent/exceptions.rb +30 -0
  45. data/lib/right_agent/ha_broker_client.rb +1278 -0
  46. data/lib/right_agent/idempotent_request.rb +140 -0
  47. data/lib/right_agent/log.rb +418 -0
  48. data/lib/right_agent/monkey_patches.rb +29 -0
  49. data/lib/right_agent/monkey_patches/amqp_patch.rb +274 -0
  50. data/lib/right_agent/monkey_patches/ruby_patch.rb +49 -0
  51. data/lib/right_agent/monkey_patches/ruby_patch/array_patch.rb +29 -0
  52. data/lib/right_agent/monkey_patches/ruby_patch/darwin_patch.rb +24 -0
  53. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch.rb +24 -0
  54. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch/file_patch.rb +30 -0
  55. data/lib/right_agent/monkey_patches/ruby_patch/object_patch.rb +49 -0
  56. data/lib/right_agent/monkey_patches/ruby_patch/singleton_patch.rb +46 -0
  57. data/lib/right_agent/monkey_patches/ruby_patch/string_patch.rb +107 -0
  58. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch.rb +32 -0
  59. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/file_patch.rb +90 -0
  60. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/process_patch.rb +63 -0
  61. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/stdio_patch.rb +27 -0
  62. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/time_patch.rb +55 -0
  63. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/win32ole_patch.rb +34 -0
  64. data/lib/right_agent/multiplexer.rb +91 -0
  65. data/lib/right_agent/operation_result.rb +270 -0
  66. data/lib/right_agent/packets.rb +637 -0
  67. data/lib/right_agent/payload_formatter.rb +104 -0
  68. data/lib/right_agent/pid_file.rb +159 -0
  69. data/lib/right_agent/platform.rb +319 -0
  70. data/lib/right_agent/platform/darwin.rb +227 -0
  71. data/lib/right_agent/platform/linux.rb +268 -0
  72. data/lib/right_agent/platform/windows.rb +1204 -0
  73. data/lib/right_agent/scripts/agent_controller.rb +522 -0
  74. data/lib/right_agent/scripts/agent_deployer.rb +379 -0
  75. data/lib/right_agent/scripts/common_parser.rb +153 -0
  76. data/lib/right_agent/scripts/log_level_manager.rb +193 -0
  77. data/lib/right_agent/scripts/stats_manager.rb +256 -0
  78. data/lib/right_agent/scripts/usage.rb +58 -0
  79. data/lib/right_agent/secure_identity.rb +92 -0
  80. data/lib/right_agent/security.rb +32 -0
  81. data/lib/right_agent/security/cached_certificate_store_proxy.rb +63 -0
  82. data/lib/right_agent/security/certificate.rb +102 -0
  83. data/lib/right_agent/security/certificate_cache.rb +89 -0
  84. data/lib/right_agent/security/distinguished_name.rb +56 -0
  85. data/lib/right_agent/security/encrypted_document.rb +84 -0
  86. data/lib/right_agent/security/rsa_key_pair.rb +76 -0
  87. data/lib/right_agent/security/signature.rb +86 -0
  88. data/lib/right_agent/security/static_certificate_store.rb +69 -0
  89. data/lib/right_agent/sender.rb +937 -0
  90. data/lib/right_agent/serialize.rb +29 -0
  91. data/lib/right_agent/serialize/message_pack.rb +102 -0
  92. data/lib/right_agent/serialize/secure_serializer.rb +131 -0
  93. data/lib/right_agent/serialize/secure_serializer_initializer.rb +47 -0
  94. data/lib/right_agent/serialize/serializable.rb +135 -0
  95. data/lib/right_agent/serialize/serializer.rb +149 -0
  96. data/lib/right_agent/stats_helper.rb +731 -0
  97. data/lib/right_agent/subprocess.rb +38 -0
  98. data/lib/right_agent/tracer.rb +124 -0
  99. data/right_agent.gemspec +60 -0
  100. data/spec/actor_registry_spec.rb +81 -0
  101. data/spec/actor_spec.rb +99 -0
  102. data/spec/agent_config_spec.rb +226 -0
  103. data/spec/agent_identity_spec.rb +75 -0
  104. data/spec/agent_spec.rb +571 -0
  105. data/spec/broker_client_spec.rb +961 -0
  106. data/spec/command/agent_manager_commands_spec.rb +51 -0
  107. data/spec/command/command_io_spec.rb +93 -0
  108. data/spec/command/command_parser_spec.rb +79 -0
  109. data/spec/command/command_runner_spec.rb +72 -0
  110. data/spec/command/command_serializer_spec.rb +51 -0
  111. data/spec/core_payload_types/dev_repositories_spec.rb +64 -0
  112. data/spec/core_payload_types/executable_bundle_spec.rb +59 -0
  113. data/spec/core_payload_types/login_user_spec.rb +98 -0
  114. data/spec/core_payload_types/right_script_attachment_spec.rb +65 -0
  115. data/spec/core_payload_types/spec_helper.rb +23 -0
  116. data/spec/dispatcher_spec.rb +372 -0
  117. data/spec/enrollment_result_spec.rb +53 -0
  118. data/spec/ha_broker_client_spec.rb +1673 -0
  119. data/spec/idempotent_request_spec.rb +136 -0
  120. data/spec/log_spec.rb +177 -0
  121. data/spec/monkey_patches/amqp_patch_spec.rb +100 -0
  122. data/spec/monkey_patches/eventmachine_spec.rb +62 -0
  123. data/spec/monkey_patches/string_patch_spec.rb +99 -0
  124. data/spec/multiplexer_spec.rb +48 -0
  125. data/spec/operation_result_spec.rb +171 -0
  126. data/spec/packets_spec.rb +418 -0
  127. data/spec/platform/platform_spec.rb +60 -0
  128. data/spec/results_mock.rb +45 -0
  129. data/spec/secure_identity_spec.rb +50 -0
  130. data/spec/security/cached_certificate_store_proxy_spec.rb +56 -0
  131. data/spec/security/certificate_cache_spec.rb +71 -0
  132. data/spec/security/certificate_spec.rb +49 -0
  133. data/spec/security/distinguished_name_spec.rb +46 -0
  134. data/spec/security/encrypted_document_spec.rb +55 -0
  135. data/spec/security/rsa_key_pair_spec.rb +55 -0
  136. data/spec/security/signature_spec.rb +66 -0
  137. data/spec/security/static_certificate_store_spec.rb +52 -0
  138. data/spec/sender_spec.rb +887 -0
  139. data/spec/serialize/message_pack_spec.rb +131 -0
  140. data/spec/serialize/secure_serializer_spec.rb +102 -0
  141. data/spec/serialize/serializable_spec.rb +90 -0
  142. data/spec/serialize/serializer_spec.rb +174 -0
  143. data/spec/spec.opts +2 -0
  144. data/spec/spec_helper.rb +77 -0
  145. data/spec/stats_helper_spec.rb +681 -0
  146. data/spec/tracer_spec.rb +114 -0
  147. metadata +320 -0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009-2011 RightScale, Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ 'Software'), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,78 @@
1
+ = RightAgent
2
+
3
+ = DESCRIPTION
4
+
5
+ == Synopsis
6
+
7
+ RightAgent provides a foundation for running an agent on a server to interface
8
+ in a secure fashion with other agents in the RightScale system. A RightAgent
9
+ uses RabbitMQ as the message bus and the RightScale mapper as the routing node.
10
+ Servers running a RightAgent establish a queue on startup for receiving packets
11
+ routed to it via the mapper. The packets are structured to invoke services in
12
+ the agent represented by actors and methods. The RightAgent may respond to these
13
+ requests with a result packet that the mapper then routes to the originator.
14
+ Similarly a RightAgent can also make requests of other RightAgents in the
15
+ RightScale system.
16
+
17
+ Refer to the wiki (https://github.com/rightscale/right_agent/wikis) for up-to-date
18
+ documentation.
19
+
20
+ Also use the built-in issues tracker (https://github.com/rightscale/right_agent/issues)
21
+ to report issues.
22
+
23
+ == Interface
24
+
25
+ A RightAgent exposes its services via actors and methods that are invoked by requests
26
+ packets it receives via its message queue. All RightAgents have a general purpose actor
27
+ named agent_manager that provides the following services:
28
+
29
+ * <b>agent_manager/ping</b>: Respond with basic status information to indicate that active
30
+ * <b>agent_manager/stats</b>: Retrieve statistics about agent operation
31
+ * <b>agent_manager/set_log_level</b>: Change log level of agent
32
+ * <b>agent_manager/execute</b>: Eval code in context of agent
33
+ * <b>agent_manager/connect</b>: Connect agent to additional broker or reconnect it to one
34
+ * <b>agent_manager/disconnect</b>: Disconnect agent from broker
35
+
36
+ RightAgent comes with several library modules for forming basic command line tools:
37
+
38
+ * <b>agent_deployer</b>: Build a configuration file for running the agent (rad tool)
39
+ * <b>agent_controller</b>: Manage an agent that has been configured (rnac tool)
40
+ * <b>stats_manager</b>: Display operation statistics for an agent (rstat tool)
41
+ * <b>log_level_manager</b>: Retrieve and set log level for an agent (rlog tool)
42
+
43
+ == Supported Configuration
44
+
45
+ RightAgent has been tested on EC2 instances running CentOS 5.2 and Ubuntu 8.10.
46
+
47
+ == Work in Progress
48
+
49
+ RightAgent is work in progress, expect more documentation and examples in the near future.
50
+
51
+ = ADDITIONAL RESOURCES
52
+
53
+ * [1] RabbitMQ is http://www.rabbitmq.com/documentation.html
54
+
55
+ = LICENSE
56
+
57
+ <b>RightAgent</b>
58
+
59
+ Copyright:: Copyright (c) 2011 RightScale, Inc.
60
+
61
+ Permission is hereby granted, free of charge, to any person obtaining
62
+ a copy of this software and associated documentation files (the
63
+ 'Software'), to deal in the Software without restriction, including
64
+ without limitation the rights to use, copy, modify, merge, publish,
65
+ distribute, sublicense, and/or sell copies of the Software, and to
66
+ permit persons to whom the Software is furnished to do so, subject to
67
+ the following conditions:
68
+
69
+ The above copyright notice and this permission notice shall be
70
+ included in all copies or substantial portions of the Software.
71
+
72
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
73
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
74
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
75
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
76
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
77
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
78
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,86 @@
1
+ #-- -*-ruby-*-
2
+ # Copyright: Copyright (c) 2010 RightScale, Inc.
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # 'Software'), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ require 'rubygems'
25
+ require 'bundler/setup'
26
+ require 'fileutils'
27
+ require 'rake'
28
+ require 'rspec/core/rake_task'
29
+ require 'rake/rdoctask'
30
+ require 'rake/gempackagetask'
31
+ require 'rake/clean'
32
+
33
+ task :default => 'spec'
34
+
35
+ # == Gem packaging == #
36
+
37
+ desc "Package gem"
38
+ gemtask = Rake::GemPackageTask.new(Gem::Specification.load("right_agent.gemspec")) do |package|
39
+ package.package_dir = ENV['PACKAGE_DIR'] || 'pkg'
40
+ package.need_zip = true
41
+ package.need_tar = true
42
+ end
43
+
44
+ directory gemtask.package_dir
45
+
46
+ CLEAN.include(gemtask.package_dir)
47
+
48
+ # == Unit tests == #
49
+
50
+ RSPEC_OPTS = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
51
+
52
+ desc 'Run unit tests'
53
+ RSpec::Core::RakeTask.new do |t|
54
+ t.rspec_opts = RSPEC_OPTS
55
+ end
56
+
57
+ namespace :spec do
58
+ desc 'Run unit tests with RCov'
59
+ RSpec::Core::RakeTask.new(:rcov) do |t|
60
+ t.rspec_opts = RSPEC_OPTS
61
+ t.rcov = true
62
+ t.rcov_opts = %q[--exclude "spec"]
63
+ end
64
+
65
+ desc 'Print Specdoc for all unit tests'
66
+ RSpec::Core::RakeTask.new(:doc) do |t|
67
+ t.rspec_opts = ["--format", "documentation"]
68
+ end
69
+ end
70
+
71
+ # == Documentation == #
72
+
73
+ desc 'Generate API documentation to doc/rdocs/index.html'
74
+ Rake::RDocTask.new do |rd|
75
+ rd.rdoc_dir = 'doc/rdocs'
76
+ rd.main = 'README.rdoc'
77
+ rd.rdoc_files.include 'README.rdoc', 'lib/**/*.rb'
78
+ end
79
+ CLEAN.include('doc/rdocs')
80
+
81
+ # == Emacs integration ==
82
+
83
+ desc 'Rebuild TAGS file for emacs'
84
+ task :tags do
85
+ sh 'rtags -R lib spec'
86
+ end
@@ -0,0 +1,66 @@
1
+ #
2
+ # Copyright (c) 2009-2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ require 'rubygems'
24
+ require 'amqp'
25
+ require 'mq'
26
+ require 'json'
27
+ require 'yaml'
28
+ require 'openssl'
29
+
30
+ # Cannot use File.normalize_path here because not defined until after this include
31
+ require File.expand_path(File.join(File.dirname(__FILE__), 'right_agent', 'platform'))
32
+
33
+ unless defined?(RIGHT_AGENT_BASE_DIR)
34
+ RIGHT_AGENT_BASE_DIR = File.normalize_path(File.join(File.dirname(__FILE__), 'right_agent'))
35
+ end
36
+
37
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'monkey_patches'))
38
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'agent_config'))
39
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'payload_formatter'))
40
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'packets'))
41
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'enrollment_result'))
42
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'console'))
43
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'daemonize'))
44
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'pid_file'))
45
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'exceptions'))
46
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'multiplexer'))
47
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'log'))
48
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'tracer'))
49
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'audit_formatter'))
50
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'serialize'))
51
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'security'))
52
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'operation_result'))
53
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'subprocess'))
54
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'stats_helper'))
55
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'broker_client'))
56
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'ha_broker_client'))
57
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'command'))
58
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'agent_identity'))
59
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'agent_tags_manager'))
60
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'actor'))
61
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'actor_registry'))
62
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'dispatcher'))
63
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'sender'))
64
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'secure_identity'))
65
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'idempotent_request'))
66
+ require File.normalize_path(File.join(RIGHT_AGENT_BASE_DIR, 'agent'))
@@ -0,0 +1,163 @@
1
+ #
2
+ # Copyright (c) 2009-2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ module RightScale
24
+
25
+ # This mixin provides agent actor functionality.
26
+ #
27
+ # To use it simply include it your class containing the functionality to be exposed:
28
+ #
29
+ # class Foo
30
+ # include RightScale::Actor
31
+ # expose :bar
32
+ #
33
+ # def bar(payload)
34
+ # # ...
35
+ # end
36
+ #
37
+ # end
38
+ module Actor
39
+
40
+ # Callback invoked whenever Actor is included in another module or class.
41
+ #
42
+ # === Parameters
43
+ # base(Module):: Module that included Actor module
44
+ #
45
+ # === Return
46
+ # true:: Always return true
47
+ def self.included(base)
48
+ base.send :include, InstanceMethods
49
+ base.extend(ClassMethods)
50
+ end
51
+
52
+ module ClassMethods
53
+
54
+ # Construct default prefix by which actor is identified in requests
55
+ #
56
+ # === Return
57
+ # prefix(String):: Default prefix
58
+ def default_prefix
59
+ prefix = to_s.to_const_path
60
+ end
61
+
62
+ # Add methods to list of services supported by actor
63
+ #
64
+ # === Parameters
65
+ # meths(Array):: Symbol names for methods being exposed as actor services
66
+ #
67
+ # === Return
68
+ # @exposed(Array):: List of unique methods exposed
69
+ def expose(*meths)
70
+ @exposed ||= []
71
+ meths.each do |meth|
72
+ @exposed << meth unless @exposed.include?(meth)
73
+ end
74
+ @exposed
75
+ end
76
+
77
+ # Get /prefix/method paths that actor responds to
78
+ #
79
+ # === Parameters
80
+ # prefix(String):: Prefix by which actor is identified in requests
81
+ #
82
+ # === Return
83
+ # (Array):: /prefix/method strings
84
+ def provides_for(prefix)
85
+ return [] unless @exposed
86
+ @exposed.select do |meth|
87
+ if instance_methods.include?(meth.to_s) or instance_methods.include?(meth.to_sym)
88
+ true
89
+ else
90
+ Log.warning("Exposing non-existing method #{meth} in actor #{name}")
91
+ false
92
+ end
93
+ end.map {|meth| "/#{prefix}/#{meth}".squeeze('/')}
94
+ end
95
+
96
+ # Set method called when dispatching to this actor fails
97
+ #
98
+ # The callback method is required to accept the following parameters:
99
+ # method(Symbol):: Actor method being dispatched to
100
+ # deliverable(Packet):: Packet delivered to dispatcher
101
+ # exception(Exception):: Exception raised
102
+ #
103
+ # === Parameters
104
+ # proc(Proc|Symbol|String):: Procedure to be called on exception
105
+ #
106
+ # === Block
107
+ # Block to be executed if no Proc provided
108
+ #
109
+ # === Return
110
+ # @exception_callback(Proc):: Callback procedure
111
+ def on_exception(proc = nil, &blk)
112
+ raise 'No callback provided for on_exception' unless proc || blk
113
+ @exception_callback = proc || blk
114
+ end
115
+
116
+ # Get exception callback procedure
117
+ #
118
+ # === Return
119
+ # @exception_callback(Proc):: Callback procedure
120
+ def exception_callback
121
+ @exception_callback
122
+ end
123
+
124
+ end # ClassMethods
125
+
126
+ module InstanceMethods
127
+
128
+ # Agents using actors are required to define a Sender class providing linkage
129
+ # to a class that can perform the following send functions
130
+
131
+ # Helper method to send a request to one or more targets with no response expected
132
+ def send_push(*args)
133
+ Sender.instance.send_push(*args)
134
+ end
135
+
136
+ # Helper method to send a request to one or more targets with no response expected
137
+ # The request is persisted en route to reduce the chance of it being lost at the expense of some
138
+ # additional network overhead
139
+ def send_persistent_push(*args)
140
+ Sender.instance.send_persistent_push(*args)
141
+ end
142
+
143
+ # Helper method to send a request to a single target with a response expected
144
+ # The request is retried if the response is not received in a reasonable amount of time
145
+ # The request is timed out if not received in time, typically configured to 2 minutes
146
+ # The request is allowed to expire per the agent's configured time-to-live, typically 1 minute
147
+ def send_retryable_request(*args, &blk)
148
+ Sender.instance.send_retryable_request(*args, &blk)
149
+ end
150
+
151
+ # Helper method to send a request to a single target with a response expected
152
+ # The request is persisted en route to reduce the chance of it being lost at the expense of some
153
+ # additional network overhead
154
+ # The request is never retried if there is the possibility of it being duplicated
155
+ def send_persistent_request(*args, &blk)
156
+ Sender.instance.send_persistent_request(*args, &blk)
157
+ end
158
+
159
+ end # InstanceMethods
160
+
161
+ end # Actor
162
+
163
+ end # RightScale
@@ -0,0 +1,76 @@
1
+ #
2
+ # Copyright (c) 2009-2011 RightScale Inc
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ module RightScale
24
+
25
+ class ActorRegistry
26
+
27
+ # (Hash) Actors that are registered; key is actor prefix and value is actor
28
+ attr_reader :actors
29
+
30
+ # Initialize registry
31
+ def initialize
32
+ @actors = {}
33
+ end
34
+
35
+ # Register as an actor
36
+ #
37
+ # === Parameters
38
+ # actor(Actor):: Actor to be registered
39
+ # prefix(String):: Prefix used in request to identify actor
40
+ #
41
+ # === Return
42
+ # (Actor):: Actor registered
43
+ #
44
+ # === Raises
45
+ # ArgumentError if actor is not an Actor
46
+ def register(actor, prefix)
47
+ raise ArgumentError, "#{actor.inspect} is not a RightScale::Actor subclass instance" unless RightScale::Actor === actor
48
+ log_msg = "[actor] #{actor.class.to_s}"
49
+ log_msg += ", prefix #{prefix}" if prefix && !prefix.empty?
50
+ Log.info(log_msg)
51
+ prefix ||= actor.class.default_prefix
52
+ actors[prefix.to_s] = actor
53
+ end
54
+
55
+ # Retrieve services provided by all of the registered actors
56
+ #
57
+ # === Return
58
+ # services(Array):: List of unique /prefix/method path strings
59
+ def services
60
+ actors.map {|prefix, actor| actor.class.provides_for(prefix) }.flatten.uniq
61
+ end
62
+
63
+ # Retrieve actor by prefix
64
+ #
65
+ # === Parameters
66
+ # prefix(String):: Prefix identifying actor
67
+ #
68
+ # === Return
69
+ # actor(Actor):: Retrieved actor, may be nil
70
+ def actor_for(prefix)
71
+ actor = actors[prefix]
72
+ end
73
+
74
+ end # ActorRegistry
75
+
76
+ end # RightScale