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.
Files changed (84) hide show
  1. data/.watchr +11 -3
  2. data/Rakefile +12 -5
  3. data/functional/.gitignore +1 -0
  4. data/{bin/datagram_example → functional/bin/datagram} +2 -0
  5. data/{config/environments/development.rb → functional/config/.gitignore} +0 -0
  6. data/{config → functional/config}/boot.rb +0 -0
  7. data/functional/config/daemons.yml +12 -0
  8. data/{config → functional/config}/environment.rb +0 -0
  9. data/{config/environments/production.rb → functional/config/environments/development.rb} +0 -0
  10. data/{config/environments/test.rb → functional/config/environments/production.rb} +0 -0
  11. data/{lib/jobs/Rakefile → functional/config/environments/test.rb} +0 -0
  12. data/functional/lib/daemon/datagram.rb +23 -0
  13. data/functional/lib/handler/socket_to_file.rb +36 -0
  14. data/functional/lib/protocol/socket_to_file.rb +55 -0
  15. data/{libexec → functional/libexec}/daemon.rb +14 -3
  16. data/functional/log/.gitignore +3 -0
  17. data/functional/tmp/README +1 -0
  18. data/lib/langrove.rb +1 -0
  19. data/lib/langrove/_base.rb +26 -0
  20. data/lib/langrove/adaptor/base.rb +3 -0
  21. data/lib/langrove/adaptor/datagram.rb +27 -0
  22. data/lib/langrove/adaptor_base.rb +89 -0
  23. data/lib/langrove/client/base.rb +2 -0
  24. data/lib/langrove/client/datagram.rb +28 -0
  25. data/lib/langrove/client_base.rb +114 -0
  26. data/lib/langrove/daemon/base.rb +2 -0
  27. data/lib/{daemon_base.rb → langrove/daemon_base.rb} +30 -23
  28. data/lib/langrove/ext.rb +7 -0
  29. data/lib/langrove/ext/class_loader.rb +146 -0
  30. data/lib/{ext → langrove/ext}/config_item.rb +4 -5
  31. data/lib/{ext → langrove/ext}/config_loader.rb +2 -2
  32. data/lib/langrove/ext/fake_logger.rb +8 -0
  33. data/lib/{ext → langrove/ext}/persistable.rb +2 -2
  34. data/lib/{ext → langrove/ext}/string.rb +0 -0
  35. data/lib/langrove/handler/base.rb +2 -0
  36. data/lib/{handler_base.rb → langrove/handler_base.rb} +25 -9
  37. data/lib/langrove/protocol/base.rb +2 -0
  38. data/lib/langrove/protocol/syslog.rb +32 -0
  39. data/lib/langrove/protocol_base.rb +32 -0
  40. data/lib/langrove/version.rb +3 -0
  41. data/spec/functional/daemon/datagram_spec.rb +115 -0
  42. data/spec/langrove/adaptor/datagram_spec.rb +6 -0
  43. data/spec/langrove/adaptor_base_spec.rb +48 -0
  44. data/spec/langrove/client/datagram_spec.rb +1 -0
  45. data/spec/langrove/client_base_spec.rb +5 -0
  46. data/spec/langrove/daemon_base_spec.rb +101 -0
  47. data/spec/langrove/ext/class_loader_spec.rb +83 -0
  48. data/spec/langrove/ext/config_item_spec.rb +81 -0
  49. data/spec/langrove/ext/config_loader_spec.rb +5 -0
  50. data/{tmp/TMP → spec/langrove/ext/fake_logger_spec.rb} +0 -0
  51. data/spec/{ext → langrove/ext}/persistable_spec.rb +8 -9
  52. data/spec/{ext → langrove/ext}/string_spec.rb +1 -1
  53. data/spec/langrove/handler_base_spec.rb +57 -0
  54. data/spec/langrove/protocol/syslog_spec.rb +45 -0
  55. data/spec/langrove/protocol_base_spec.rb +6 -0
  56. data/spec/todo_spec.rb +1 -2
  57. data/tmp/README +2 -0
  58. metadata +150 -46
  59. data/config/daemons.yml.tmpl +0 -78
  60. data/lib/adaptor/base.rb +0 -1
  61. data/lib/adaptor/datagram.rb +0 -20
  62. data/lib/adaptor/socket_handler.rb +0 -27
  63. data/lib/adaptor_base.rb +0 -39
  64. data/lib/client/base.rb +0 -1
  65. data/lib/client/puppet_state.rb +0 -74
  66. data/lib/client/radio_state.rb +0 -81
  67. data/lib/client_base.rb +0 -24
  68. data/lib/daemon/base.rb +0 -1
  69. data/lib/daemon/datagram_example.rb +0 -12
  70. data/lib/handler/base.rb +0 -1
  71. data/lib/handler/socket_to_file.rb +0 -30
  72. data/lib/jobs/jobs.rb +0 -1
  73. data/lib/jobs/updated_puppet_state.rb +0 -17
  74. data/lib/protocol_base.rb +0 -5
  75. data/spec/adaptor/datagram_spec.rb +0 -6
  76. data/spec/adaptor/socket_handler_spec.rb +0 -5
  77. data/spec/adaptor_base_spec.rb +0 -45
  78. data/spec/client_base_spec.rb +0 -5
  79. data/spec/daemon_base_spec.rb +0 -97
  80. data/spec/ext/config_item_spec.rb +0 -77
  81. data/spec/ext/config_loader_spec.rb +0 -5
  82. data/spec/functional/datagram_spec.rb +0 -122
  83. data/spec/handler_base_spec.rb +0 -71
  84. 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("lib/(.*/*).rb") do |match|
17
- puts match
18
- run_spec %{spec/#{match[1]}_spec.rb}
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
- #sh "git tag v#{LanGrove::Version}"
11
- #sh "git push origin v#{Resque::Version}"
12
- #sh "git push origin master"
13
- #sh "git clean -fd"
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/*.*
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
+
3
+ DAEMON_ROOT = File.expand_path('../../../functional/', __FILE__)
2
4
  DAEMON_NAME = File.basename $0
3
5
  require File.expand_path('../../config/environment', __FILE__)
4
6
  DaemonKit::Application.exec( DAEMON_ROOT + '/libexec/daemon.rb' )
File without changes
@@ -0,0 +1,12 @@
1
+ :daemons:
2
+ datagram:
3
+ :periodic: 5
4
+ :adaptor:
5
+ :connection: Datagram
6
+ :iface: 127.0.0.1
7
+ :port: 12701
8
+ :client:
9
+ :class: Datagram
10
+ :handler:
11
+ :collection: SocketToFile
12
+ :protocol: SocketToFile
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 'ext/string'
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,3 @@
1
+ *.log
2
+ *.pid
3
+ *.yml
@@ -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,3 @@
1
+ module LanGrove::Adaptor; end
2
+ require 'langrove/adaptor_base'
3
+ require 'langrove/adaptor/datagram'
@@ -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,2 @@
1
+ module LanGrove::Client; end
2
+ require 'langrove/client_base'
@@ -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