noah-agents-dummy2 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.md +62 -0
- data/Rakefile +2 -0
- data/lib/noah/agents/dummy2_agent.rb +20 -0
- data/lib/noah-agents-dummy2.rb +1 -0
- data/noah-agents-dummy2.gemspec +20 -0
- metadata +63 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
noah-agents-dummy2
|
2
|
+
------------------
|
3
|
+
This is an example template for adding additional callback support to [Noah](https://github.com/lusis/Noah) as a distributable gem.
|
4
|
+
|
5
|
+
**This gem is pointless without having Noah installed**
|
6
|
+
|
7
|
+
## Anatomy of a Noah callback plugin
|
8
|
+
-------------------------------------
|
9
|
+
In a nutshell, a class needs to do four things to be a valid Noah callback plugin:
|
10
|
+
|
11
|
+
* mixin `Noah::Agents::Base`
|
12
|
+
* define a URI-style prefix as a constant named `PREFIX`
|
13
|
+
* define a class-level method called `callback!`
|
14
|
+
|
15
|
+
If you name your gem `noah-agents-*`, the Noah watcher daemon will automatically add your gem to a list of candidates to `require`.
|
16
|
+
|
17
|
+
Mixing in `Noah::Agents::Base` to your class will automatically register your `PREFIX` as a valid scheme for callbacks.
|
18
|
+
|
19
|
+
## How registration happens
|
20
|
+
----------------------------
|
21
|
+
When you mixin `Noah::Agents::Base` the following occurs:
|
22
|
+
|
23
|
+
* `Noah::Watchers.register_agent` is called with your class name (`Noah::Agents::Dummy2` in this case)
|
24
|
+
* the `register_agent` method adds your class to a class variable called `@@agents`
|
25
|
+
|
26
|
+
When the watcher daemon starts up, it creates an instance of `Noah::Agent`. Noah::Agent has a class variable called `@@agents` as well that is populated by calling `Noah::Watchers.agents`.
|
27
|
+
|
28
|
+
The instance of `Noah::Agent` brokers all requests to the actual callback endpoints. It automatically detects when new watchers are registered in Noah. Currently there does not exist a way to dynamically load **NEW** callback schemes. I'm working on that as well.
|
29
|
+
|
30
|
+
## Notes on the `callback!` method
|
31
|
+
-----------------------------------
|
32
|
+
The `callback!` method will be passed two paramters - an array of "matches" registered with your callback uri prefix and a message.
|
33
|
+
|
34
|
+
The current matches format is a bit of a kludge. The format for each item in the matches array is:
|
35
|
+
|
36
|
+
`pattern|endpoint`
|
37
|
+
|
38
|
+
Both the pattern and the endpoint are determined by the user when they create new Watches in Noah. An example array of matches passed in would look something like this:
|
39
|
+
|
40
|
+
['//noah/applications/my_third_app|dummy2://dummy2-my-third-app',
|
41
|
+
'//noah/configurations|dummy2://some-other-dummy-endpoint',
|
42
|
+
'//noah/ephemerals/myorg/myserver|dummy2://foobarbaz']
|
43
|
+
|
44
|
+
The pattern is in there mainly for informational/debuggin purposes at this point.
|
45
|
+
The message is currently a JSON dump of the state of an object in Noah.
|
46
|
+
|
47
|
+
Remember that a watcher agent does two things: defines which uri scheme it provides support for and sends messages to endpoints using that uri scheme. You should gracefully handle things like lookup failures or destination timeouts.
|
48
|
+
|
49
|
+
Currently, agents are required to be EventMachine-friendly (read: **Don't block the reactor!**). Looking at the actual `callback!` method for this gem:
|
50
|
+
|
51
|
+
def self.callback!(matches, message)
|
52
|
+
EM::Iterator.new(matches).each do |watch, iter|
|
53
|
+
p, ep = watch.split("|")
|
54
|
+
logger.info("Sending message to: #{ep} for pattern: #{p}")
|
55
|
+
logger.debug("message received: #{message}")
|
56
|
+
iter.next
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
It uses EM::Iterator to iterate over the list of registerd endpoints were previously matched and sends `message` to each one. If you compare this to `Noah::Agents::Dummy` and `Noah::Agents::HTTP` included in the Noah codebase, you'll probably see a bit of duplication. This is one other area I'd like to abstract out. The goal is that the iteration and logging will actually be moved OUT of this and instead the `callback!` method itself will be iterated.
|
61
|
+
|
62
|
+
Additionally, there's no in-built support for reformatting messages. This is next on the plate as the whole point of making callbacks pluggable is that events can be custom formatted for the callback endpoint. For example, a `rundeck://` endpoint might want to have no interest in the type of action performed on an object (create, update, delete) but instead only cares for the current value of that object. There's no reason to send the extranous information over.
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'noah/agents/base_agent'
|
2
|
+
|
3
|
+
module Noah::Agents
|
4
|
+
class Dummy2Agent
|
5
|
+
include Noah::Agents::Base
|
6
|
+
|
7
|
+
PREFIX = "dummy2://"
|
8
|
+
NAME = self.name
|
9
|
+
|
10
|
+
def self.callback!(matches, message)
|
11
|
+
EM::Iterator.new(matches).each do |watch, iter|
|
12
|
+
p, ep = watch.split("|")
|
13
|
+
logger.info("Sending message to: #{ep} for pattern: #{p}")
|
14
|
+
logger.debug("message received: #{message}")
|
15
|
+
iter.next
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'noah','agents','dummy2_agent')
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "noah-agents-dummy2"
|
6
|
+
s.version = "0.0.1"
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ["John E. Vincent"]
|
9
|
+
s.email = ["lusis.org+rubygems.org@gmail.com"]
|
10
|
+
s.homepage = "https://github.com/lusis/Noah"
|
11
|
+
s.summary = %q{dummy2 agent plugin for Noah}
|
12
|
+
s.description = %q{Provides dummy2 support for Noah watchers}
|
13
|
+
|
14
|
+
s.rubyforge_project = "noah-agents-dummy2"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: noah-agents-dummy2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- John E. Vincent
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-03-25 00:00:00 -04:00
|
14
|
+
default_executable:
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: Provides dummy2 support for Noah watchers
|
18
|
+
email:
|
19
|
+
- lusis.org+rubygems.org@gmail.com
|
20
|
+
executables: []
|
21
|
+
|
22
|
+
extensions: []
|
23
|
+
|
24
|
+
extra_rdoc_files: []
|
25
|
+
|
26
|
+
files:
|
27
|
+
- .gitignore
|
28
|
+
- Gemfile
|
29
|
+
- README.md
|
30
|
+
- Rakefile
|
31
|
+
- lib/noah-agents-dummy2.rb
|
32
|
+
- lib/noah/agents/dummy2_agent.rb
|
33
|
+
- noah-agents-dummy2.gemspec
|
34
|
+
has_rdoc: true
|
35
|
+
homepage: https://github.com/lusis/Noah
|
36
|
+
licenses: []
|
37
|
+
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: "0"
|
49
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
requirements: []
|
56
|
+
|
57
|
+
rubyforge_project: noah-agents-dummy2
|
58
|
+
rubygems_version: 1.6.2
|
59
|
+
signing_key:
|
60
|
+
specification_version: 3
|
61
|
+
summary: dummy2 agent plugin for Noah
|
62
|
+
test_files: []
|
63
|
+
|