LanGrove 0.0.1 → 0.0.2
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.
- data/.watchr +11 -3
- data/Rakefile +12 -5
- data/functional/.gitignore +1 -0
- data/{bin/datagram_example → functional/bin/datagram} +2 -0
- data/{config/environments/development.rb → functional/config/.gitignore} +0 -0
- data/{config → functional/config}/boot.rb +0 -0
- data/functional/config/daemons.yml +12 -0
- data/{config → functional/config}/environment.rb +0 -0
- data/{config/environments/production.rb → functional/config/environments/development.rb} +0 -0
- data/{config/environments/test.rb → functional/config/environments/production.rb} +0 -0
- data/{lib/jobs/Rakefile → functional/config/environments/test.rb} +0 -0
- data/functional/lib/daemon/datagram.rb +23 -0
- data/functional/lib/handler/socket_to_file.rb +36 -0
- data/functional/lib/protocol/socket_to_file.rb +55 -0
- data/{libexec → functional/libexec}/daemon.rb +14 -3
- data/functional/log/.gitignore +3 -0
- data/functional/tmp/README +1 -0
- data/lib/langrove.rb +1 -0
- data/lib/langrove/_base.rb +26 -0
- data/lib/langrove/adaptor/base.rb +3 -0
- data/lib/langrove/adaptor/datagram.rb +27 -0
- data/lib/langrove/adaptor_base.rb +89 -0
- data/lib/langrove/client/base.rb +2 -0
- data/lib/langrove/client/datagram.rb +28 -0
- data/lib/langrove/client_base.rb +114 -0
- data/lib/langrove/daemon/base.rb +2 -0
- data/lib/{daemon_base.rb → langrove/daemon_base.rb} +30 -23
- data/lib/langrove/ext.rb +7 -0
- data/lib/langrove/ext/class_loader.rb +146 -0
- data/lib/{ext → langrove/ext}/config_item.rb +4 -5
- data/lib/{ext → langrove/ext}/config_loader.rb +2 -2
- data/lib/langrove/ext/fake_logger.rb +8 -0
- data/lib/{ext → langrove/ext}/persistable.rb +2 -2
- data/lib/{ext → langrove/ext}/string.rb +0 -0
- data/lib/langrove/handler/base.rb +2 -0
- data/lib/{handler_base.rb → langrove/handler_base.rb} +25 -9
- data/lib/langrove/protocol/base.rb +2 -0
- data/lib/langrove/protocol/syslog.rb +32 -0
- data/lib/langrove/protocol_base.rb +32 -0
- data/lib/langrove/version.rb +3 -0
- data/spec/functional/daemon/datagram_spec.rb +115 -0
- data/spec/langrove/adaptor/datagram_spec.rb +6 -0
- data/spec/langrove/adaptor_base_spec.rb +48 -0
- data/spec/langrove/client/datagram_spec.rb +1 -0
- data/spec/langrove/client_base_spec.rb +5 -0
- data/spec/langrove/daemon_base_spec.rb +101 -0
- data/spec/langrove/ext/class_loader_spec.rb +83 -0
- data/spec/langrove/ext/config_item_spec.rb +81 -0
- data/spec/langrove/ext/config_loader_spec.rb +5 -0
- data/{tmp/TMP → spec/langrove/ext/fake_logger_spec.rb} +0 -0
- data/spec/{ext → langrove/ext}/persistable_spec.rb +8 -9
- data/spec/{ext → langrove/ext}/string_spec.rb +1 -1
- data/spec/langrove/handler_base_spec.rb +57 -0
- data/spec/langrove/protocol/syslog_spec.rb +45 -0
- data/spec/langrove/protocol_base_spec.rb +6 -0
- data/spec/todo_spec.rb +1 -2
- data/tmp/README +2 -0
- metadata +150 -46
- data/config/daemons.yml.tmpl +0 -78
- data/lib/adaptor/base.rb +0 -1
- data/lib/adaptor/datagram.rb +0 -20
- data/lib/adaptor/socket_handler.rb +0 -27
- data/lib/adaptor_base.rb +0 -39
- data/lib/client/base.rb +0 -1
- data/lib/client/puppet_state.rb +0 -74
- data/lib/client/radio_state.rb +0 -81
- data/lib/client_base.rb +0 -24
- data/lib/daemon/base.rb +0 -1
- data/lib/daemon/datagram_example.rb +0 -12
- data/lib/handler/base.rb +0 -1
- data/lib/handler/socket_to_file.rb +0 -30
- data/lib/jobs/jobs.rb +0 -1
- data/lib/jobs/updated_puppet_state.rb +0 -17
- data/lib/protocol_base.rb +0 -5
- data/spec/adaptor/datagram_spec.rb +0 -6
- data/spec/adaptor/socket_handler_spec.rb +0 -5
- data/spec/adaptor_base_spec.rb +0 -45
- data/spec/client_base_spec.rb +0 -5
- data/spec/daemon_base_spec.rb +0 -97
- data/spec/ext/config_item_spec.rb +0 -77
- data/spec/ext/config_loader_spec.rb +0 -5
- data/spec/functional/datagram_spec.rb +0 -122
- data/spec/handler_base_spec.rb +0 -71
- data/spec/protocol_base_spec.rb +0 -6
data/.watchr
CHANGED
@@ -13,7 +13,15 @@ watch("spec/.*/*_spec.rb") do |match|
|
|
13
13
|
run_spec match[0]
|
14
14
|
end
|
15
15
|
|
16
|
-
watch("
|
17
|
-
|
18
|
-
|
16
|
+
watch("(.*/*).rb") do |match|
|
17
|
+
file = match[1]
|
18
|
+
file.gsub!('lib/','')
|
19
|
+
file.gsub!('spec/','')
|
20
|
+
file.sub!('_spec','')
|
21
|
+
puts "====#{file}==="
|
22
|
+
if /demo/.match(match[0]) then
|
23
|
+
run_spec %{spec/#{file}_spec.rb}
|
24
|
+
next
|
25
|
+
end
|
26
|
+
run_spec %{spec/#{file}_spec.rb}
|
19
27
|
end
|
data/Rakefile
CHANGED
@@ -3,15 +3,22 @@ $LOAD_PATH.unshift 'lib'
|
|
3
3
|
desc "Publish a new version to ruby-gems.org"
|
4
4
|
task :publish do
|
5
5
|
require 'langrove/version'
|
6
|
-
|
6
|
+
|
7
7
|
sh "gem build langrove.gemspec"
|
8
8
|
sh "gem push langrove-#{LanGrove::Version}.gem"
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
sh "git tag v#{LanGrove::Version}"
|
11
|
+
sh "git push origin v#{LanGrove::Version}"
|
12
|
+
sh "git push origin master"
|
13
|
+
sh "git clean -fd"
|
14
14
|
|
15
15
|
# exec "rake documentation"
|
16
16
|
|
17
17
|
end
|
18
|
+
|
19
|
+
desc "Push to github"
|
20
|
+
task :push_world do
|
21
|
+
|
22
|
+
puts "TODO"
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
tmp/*.*
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'langrove/daemon/base'
|
2
|
+
|
3
|
+
class Datagram < LanGrove::Daemon::Base
|
4
|
+
|
5
|
+
#
|
6
|
+
# Consider tossing this dependancy.
|
7
|
+
#
|
8
|
+
# Not entirely certain this layer in the abstraction
|
9
|
+
# will be useful.
|
10
|
+
#
|
11
|
+
# Except, by
|
12
|
+
#
|
13
|
+
# << using this layer in the abstraction >>
|
14
|
+
#
|
15
|
+
#
|
16
|
+
# the eval "require 'module/class_name.rb'" in the
|
17
|
+
# langrove/ext/class_loader could possibly be avoided
|
18
|
+
# if the implementation requires all necessary modules
|
19
|
+
# ahead of starting the daemon.
|
20
|
+
#
|
21
|
+
#
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#
|
2
|
+
# Define a Handler by extending LanGrove::Handler::Base
|
3
|
+
# and extending the functions:
|
4
|
+
#
|
5
|
+
# 1. <YourClass>.receive( data )
|
6
|
+
#
|
7
|
+
# Data arriving from the Adaptor will arrive into
|
8
|
+
# this function having already been decoded by the
|
9
|
+
# configured Protocol for this Handler
|
10
|
+
#
|
11
|
+
# # 2. <YourClass>.transmit
|
12
|
+
# #
|
13
|
+
|
14
|
+
require 'langrove'
|
15
|
+
|
16
|
+
module Handler
|
17
|
+
|
18
|
+
class SocketToFile < LanGrove::Handler::Base
|
19
|
+
|
20
|
+
def receive( data )
|
21
|
+
|
22
|
+
@logger.info( "#{self}.receive: #{data}" )
|
23
|
+
|
24
|
+
File.open( data[:filename], 'w' ) do |f|
|
25
|
+
|
26
|
+
f.write( data[:content] )
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
@logger.info "Wrote data: '#{data[ :content ]}' to file: '#{ data[ :filename ]}'"
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#
|
2
|
+
# Define a Protocol by extending LanGrove::Protocol::Base
|
3
|
+
# and extending the functions:
|
4
|
+
#
|
5
|
+
# 1. <YourClass>.decode( data )
|
6
|
+
#
|
7
|
+
# Data arriving from the Adaptor will be passed to
|
8
|
+
# the config assigned protocol. The Handler will
|
9
|
+
# be expecting decoded data in the form of a Hash
|
10
|
+
#
|
11
|
+
# SPECIFICALLY: One of the keys should correspond
|
12
|
+
# to the :route_by in the config.
|
13
|
+
#
|
14
|
+
# # 2. <YourClass>.encode( .. )
|
15
|
+
# #
|
16
|
+
|
17
|
+
|
18
|
+
require 'langrove'
|
19
|
+
|
20
|
+
module Protocol
|
21
|
+
|
22
|
+
#
|
23
|
+
# Module is only necessary if you choose to
|
24
|
+
# structure associations of class by name.
|
25
|
+
#
|
26
|
+
# eg.
|
27
|
+
#
|
28
|
+
# Protocol::SocketToFile
|
29
|
+
# Handler::SocketToFile
|
30
|
+
#
|
31
|
+
|
32
|
+
class SocketToFile < LanGrove::Protocol::Base
|
33
|
+
|
34
|
+
def decode( data )
|
35
|
+
|
36
|
+
#
|
37
|
+
# OVERRIDE
|
38
|
+
#
|
39
|
+
# Becasuse your protocol
|
40
|
+
#
|
41
|
+
|
42
|
+
@logger.info( "#{self}.decode: #{data}" ) unless @logger.nil?
|
43
|
+
|
44
|
+
{
|
45
|
+
|
46
|
+
:filename => data.split('|')[0],
|
47
|
+
:content => data.split('|',2)[1]
|
48
|
+
|
49
|
+
}
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -1,9 +1,8 @@
|
|
1
|
-
require '
|
2
|
-
require 'ext/config_loader'
|
1
|
+
require 'langrove'
|
3
2
|
|
4
3
|
CLASS_NAME = DAEMON_NAME.camelize
|
5
4
|
CONFIG_FILE = "#{DAEMON_ROOT}/config/daemons.yml"
|
6
|
-
CONFIG_HASH = ConfigLoader.yaml( CONFIG_FILE )
|
5
|
+
CONFIG_HASH = LanGrove::ConfigLoader.yaml( CONFIG_FILE )
|
7
6
|
|
8
7
|
daemon = nil
|
9
8
|
|
@@ -50,6 +49,18 @@ DaemonKit::Application.running! do |config|
|
|
50
49
|
#
|
51
50
|
# Latebind the daemon class
|
52
51
|
#
|
52
|
+
# TODO: see about tossing the libexec
|
53
|
+
# or modifying class loader to enable
|
54
|
+
# alternate load path to allow this pattern:
|
55
|
+
#
|
56
|
+
# daemon = LanGrove::ClassLoader.create( {
|
57
|
+
#
|
58
|
+
# :module => 'Daemon',
|
59
|
+
# :class => DAEMON_NAME.camelize
|
60
|
+
#
|
61
|
+
# } ).new( CONFIG_HASH, DAEMON_NAME, DaemonKit.logger )
|
62
|
+
#
|
63
|
+
|
53
64
|
require "daemon/#{DAEMON_NAME}"
|
54
65
|
daemon = Object.const_get( CLASS_NAME ).new( CONFIG_HASH, DAEMON_NAME, DaemonKit.logger )
|
55
66
|
daemon.run
|
@@ -0,0 +1 @@
|
|
1
|
+
Certain test write files into here
|
data/lib/langrove.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'langrove/_base'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#$LOAD_PATH.unshift 'langrove' unless $LOAD_PATH.include?( 'langrove' )
|
2
|
+
|
3
|
+
#$LOAD_PATH.inspect
|
4
|
+
|
5
|
+
#
|
6
|
+
# For the implementation client
|
7
|
+
#
|
8
|
+
module Adaptor; end
|
9
|
+
module Client; end
|
10
|
+
module Daemon; end
|
11
|
+
module Handler; end
|
12
|
+
module Protocol; end
|
13
|
+
|
14
|
+
module LanGrove
|
15
|
+
|
16
|
+
class DaemonConfigException < Exception; end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'langrove/ext'
|
21
|
+
|
22
|
+
require 'langrove/daemon/base'
|
23
|
+
require 'langrove/adaptor/base'
|
24
|
+
require 'langrove/handler/base'
|
25
|
+
require 'langrove/protocol/base'
|
26
|
+
require 'langrove/client/base'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'langrove/adaptor/base'
|
2
|
+
|
3
|
+
module LanGrove::Adaptor
|
4
|
+
|
5
|
+
class Datagram < Base
|
6
|
+
|
7
|
+
def listen( handler, protocol )
|
8
|
+
|
9
|
+
@logger.info "starting listen at UDP #{@iface}:#{@port}"
|
10
|
+
|
11
|
+
EventMachine::open_datagram_socket( @iface, @port,
|
12
|
+
|
13
|
+
@client ) do |client|
|
14
|
+
|
15
|
+
@logger.info "client assign handler: #{handler}"
|
16
|
+
client.handler = handler
|
17
|
+
|
18
|
+
@logger.info "client instanciate protocol: #{protocol}"
|
19
|
+
client.protocol = protocol.new( nil, @logger )
|
20
|
+
|
21
|
+
@logger.info "client assign config: #{@client_config}"
|
22
|
+
client.config = @client_config.clone
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
|
3
|
+
require 'langrove'
|
4
|
+
|
5
|
+
module LanGrove::Adaptor
|
6
|
+
|
7
|
+
class Base
|
8
|
+
|
9
|
+
def initialize( config, logger )
|
10
|
+
|
11
|
+
@config = config
|
12
|
+
@logger = logger
|
13
|
+
|
14
|
+
@iface = '127.0.0.1'
|
15
|
+
@port = 12701
|
16
|
+
|
17
|
+
@iface = @config[ :iface ] if @config.has_key? :iface
|
18
|
+
@port = @config[ :port ] if @config.has_key? :port
|
19
|
+
|
20
|
+
if @config.has_key? :connector then
|
21
|
+
|
22
|
+
#
|
23
|
+
# TODO: may need to override default connection handler
|
24
|
+
#
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# initialize the client specified in config
|
30
|
+
#
|
31
|
+
# daemons:
|
32
|
+
# name_of_daemon:
|
33
|
+
# adaptor:
|
34
|
+
# connection: TcpServer
|
35
|
+
# client:
|
36
|
+
# class: Client <---------
|
37
|
+
# handler:
|
38
|
+
# collection: CollectionOfClients
|
39
|
+
#
|
40
|
+
#
|
41
|
+
|
42
|
+
@logger.info "TODO: loading client is not tested"
|
43
|
+
|
44
|
+
client = nil
|
45
|
+
|
46
|
+
begin
|
47
|
+
|
48
|
+
#
|
49
|
+
# TODO: make this more informative on error
|
50
|
+
#
|
51
|
+
|
52
|
+
@client_config = @config[ :client ]
|
53
|
+
client = @client_config[ :class ]
|
54
|
+
|
55
|
+
rescue
|
56
|
+
|
57
|
+
error = "Missing config item(s) for adaptor: #{@config.inspect}"
|
58
|
+
|
59
|
+
@logger.error "EXIT: #{error}"
|
60
|
+
|
61
|
+
raise LanGrove::DaemonConfigException.new(
|
62
|
+
|
63
|
+
"Missing config item for daemon: #{@daemon_name}"
|
64
|
+
|
65
|
+
)
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
@logger.info "Load definition: Client::#{client}"
|
70
|
+
|
71
|
+
@client = LanGrove::ClassLoader.create( {
|
72
|
+
|
73
|
+
:module => 'Client',
|
74
|
+
:class => client
|
75
|
+
|
76
|
+
} )
|
77
|
+
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
def listen( handler, protocol )
|
82
|
+
|
83
|
+
raise LanGrove::DaemonConfigException.new( "NotYetExtended: undefined listen()" )
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
require 'langrove'
|
3
|
+
|
4
|
+
module LanGrove
|
5
|
+
|
6
|
+
module Client
|
7
|
+
|
8
|
+
class Datagram < Base
|
9
|
+
|
10
|
+
def receive( data )
|
11
|
+
|
12
|
+
#
|
13
|
+
# Quick hack, datagram client routes
|
14
|
+
# data back to the Handler - to get
|
15
|
+
# back to friday position.
|
16
|
+
#
|
17
|
+
# But with the gem
|
18
|
+
#
|
19
|
+
|
20
|
+
@handler.receive( data )
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
require 'langrove'
|
3
|
+
|
4
|
+
module LanGrove
|
5
|
+
|
6
|
+
module Client
|
7
|
+
|
8
|
+
class Base < EventMachine::Connection
|
9
|
+
|
10
|
+
#
|
11
|
+
# Misnomer.
|
12
|
+
#
|
13
|
+
#
|
14
|
+
# This is not the client,
|
15
|
+
#
|
16
|
+
#
|
17
|
+
# It is the server's perspective of the client,
|
18
|
+
#
|
19
|
+
# These are generally stored in the daemon's
|
20
|
+
# handler collection,
|
21
|
+
#
|
22
|
+
# Which contains this and all similar clients,
|
23
|
+
#
|
24
|
+
# Each bonded through the daemon's connection
|
25
|
+
# adaptor to the socket that couples them to
|
26
|
+
# their actual client..
|
27
|
+
#
|
28
|
+
|
29
|
+
#
|
30
|
+
# The handler collection specified in config
|
31
|
+
# is bound to this attribute after connect.
|
32
|
+
#
|
33
|
+
attr_accessor :handler
|
34
|
+
attr_accessor :protocol
|
35
|
+
attr_accessor :config
|
36
|
+
|
37
|
+
#
|
38
|
+
# Data arriving through the Adaptor is passed
|
39
|
+
# through the config assigned protocol and
|
40
|
+
# then arrives here in whatever format the
|
41
|
+
# <Protocol>.decode() method returned.
|
42
|
+
#
|
43
|
+
#
|
44
|
+
def receive( decoded_data )
|
45
|
+
|
46
|
+
#
|
47
|
+
# OVERRIDE
|
48
|
+
#
|
49
|
+
# - Inbound data arrived at the adaptor
|
50
|
+
#
|
51
|
+
# - It has passed through the protocol as
|
52
|
+
# defined in config.
|
53
|
+
#
|
54
|
+
# The protocol arranged the data into
|
55
|
+
# a Hash of:
|
56
|
+
#
|
57
|
+
# - key and value pairs
|
58
|
+
#
|
59
|
+
# - key and more_complicated_thing pairs.
|
60
|
+
#
|
61
|
+
# - The decoded data was then passed into
|
62
|
+
# this function.
|
63
|
+
#
|
64
|
+
#
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
def receive_data( data )
|
69
|
+
|
70
|
+
#
|
71
|
+
# Note: The protocol currently lives on the Handler
|
72
|
+
#
|
73
|
+
# It MIG( ...in progress... )HT move,
|
74
|
+
#
|
75
|
+
# To a separate instance of the protocol object
|
76
|
+
# residing in each Client::ClientType instance
|
77
|
+
# in the Handler::Base.client collection.
|
78
|
+
#
|
79
|
+
# Pending examining the logical barrier of having
|
80
|
+
# the Handler route to the Cleint per a key value
|
81
|
+
# extracted from the decoded data - as decoded by
|
82
|
+
# the client's instance of the protocol not yet
|
83
|
+
# accessable within the as yet undeterminable
|
84
|
+
# instance in the Handlers collection.
|
85
|
+
#
|
86
|
+
# Catch22(ish)
|
87
|
+
#
|
88
|
+
# But that was suitable as a pettern for the
|
89
|
+
# datagram server.
|
90
|
+
#
|
91
|
+
# Perhaps after implementing Adapter::TcpServer
|
92
|
+
#
|
93
|
+
# And gaining a more knowsome notion of the
|
94
|
+
# intricacies of the application layer, esp
|
95
|
+
# ACKing and NAKing.
|
96
|
+
#
|
97
|
+
# Then the possibilities of the Client::ClientType
|
98
|
+
# being a decendant of <self> --
|
99
|
+
#
|
100
|
+
# ie. The EM::Connection as instanciated upon each
|
101
|
+
# socket connect.
|
102
|
+
#
|
103
|
+
# -- will likely resolve.
|
104
|
+
#
|
105
|
+
#
|
106
|
+
receive( @protocol.decode( data ) )
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|