langrove 0.0.4.3 → 0.0.4.4
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/bin/langrove +1 -1
- data/functional/config/daemons.yml +8 -7
- data/functional/config/environment.rb +1 -1
- data/functional/lib/client/socket_to_file.rb +47 -0
- data/functional/lib/protocol/socket_to_file.rb +1 -1
- data/lib/langrove/adaptor/datagram.rb +44 -8
- data/lib/langrove/adaptor_base.rb +1 -52
- data/lib/langrove/client_base.rb +4 -42
- data/lib/langrove/daemon_base.rb +92 -8
- data/lib/langrove/ext/find.rb +90 -0
- data/lib/langrove/handler_base.rb +70 -63
- data/lib/langrove/version.rb +1 -1
- data/spec/functional/daemon/datagram_spec.rb +6 -0
- data/spec/langrove/daemon_base_spec.rb +46 -6
- data/spec/langrove/ext/find_spec.rb +53 -0
- data/spec/langrove/handler_base_spec.rb +60 -14
- metadata +21 -23
- data/functional/.gitignore +0 -1
- data/functional/bin/datagram +0 -6
- data/functional/config/.gitignore +0 -0
- data/functional/lib/handler/socket_to_file.rb +0 -42
- data/functional/log/.gitignore +0 -3
data/bin/langrove
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
:daemons:
|
2
2
|
datagram:
|
3
3
|
:periodic: 5
|
4
|
+
:protocol:
|
5
|
+
:class: SocketToFile
|
4
6
|
:adaptor:
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
:connection: Datagram
|
8
|
+
:iface: 127.0.0.1
|
9
|
+
:port: 12701
|
10
|
+
:client:
|
11
|
+
:class: SocketToFile
|
10
12
|
:handler:
|
11
|
-
:collection:
|
12
|
-
:protocol: SocketToFile
|
13
|
+
:collection: Base
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#
|
2
|
+
# Define a Client by extending LanGrove::Handler::Client
|
3
|
+
# and extending the functions:
|
4
|
+
#
|
5
|
+
# 1. <YourClass>.receive( decoded_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 Daemon
|
10
|
+
#
|
11
|
+
# # 2. <YourClass>.transmit
|
12
|
+
# #
|
13
|
+
|
14
|
+
require 'langrove'
|
15
|
+
|
16
|
+
module Client
|
17
|
+
|
18
|
+
class SocketToFile < LanGrove::Client::Base
|
19
|
+
|
20
|
+
def periodic
|
21
|
+
|
22
|
+
#
|
23
|
+
# OVERRIDE
|
24
|
+
#
|
25
|
+
# To perform activities on the periodic ticker.
|
26
|
+
#
|
27
|
+
@logger.debug( "#{self}.periodic" )
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
def receive( data )
|
32
|
+
|
33
|
+
@logger.debug( "#{self}.receive: #{data}" )
|
34
|
+
|
35
|
+
File.open( data[:filename], 'w' ) do |f|
|
36
|
+
|
37
|
+
f.write( data[:content] )
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
@logger.debug "Wrote data: '#{data[ :content ]}' to file: '#{ data[ :filename ]}'"
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -4,22 +4,58 @@ module LanGrove::Adaptor
|
|
4
4
|
|
5
5
|
class Datagram < Base
|
6
6
|
|
7
|
-
def listen(
|
7
|
+
def listen( client, protocol, handler )
|
8
|
+
|
9
|
+
#
|
10
|
+
# <client> = {
|
11
|
+
#
|
12
|
+
# :class => <loaded class constant>
|
13
|
+
# :config => <client's branch of config>
|
14
|
+
#
|
15
|
+
# }
|
16
|
+
#
|
17
|
+
# <protocol> = { ...the same, but protocolic }
|
18
|
+
#
|
19
|
+
#
|
8
20
|
|
9
21
|
@logger.info "starting listen at UDP #{@iface}:#{@port}"
|
10
22
|
|
11
23
|
EventMachine::open_datagram_socket( @iface, @port,
|
12
24
|
|
13
|
-
|
25
|
+
client[:class] ) do | client_connected |
|
26
|
+
|
27
|
+
#
|
28
|
+
# EM::open_datagram_socket (udp) yields on connect
|
29
|
+
# to the socket.
|
30
|
+
#
|
31
|
+
# EM::start_server (tcp) yields on connect from the
|
32
|
+
# client.
|
33
|
+
#
|
34
|
+
|
35
|
+
#
|
36
|
+
# Initialize the client with a Protocol
|
37
|
+
#
|
38
|
+
|
39
|
+
client_connected.logger = @logger
|
40
|
+
|
41
|
+
client_connected.config = client[ :config ]
|
14
42
|
|
15
|
-
|
16
|
-
client.handler = handler
|
43
|
+
client_connected.protocol = protocol[ :class ]\
|
17
44
|
|
18
|
-
|
19
|
-
|
45
|
+
.new( protocol[ :config ], @logger )
|
46
|
+
|
47
|
+
@logger.info( "TODO: make a reference to the Client on the Handler" )
|
48
|
+
|
49
|
+
#
|
50
|
+
# Insert the Client into th Handler collection
|
51
|
+
#
|
52
|
+
handler.connect( client_connected )
|
20
53
|
|
21
|
-
|
22
|
-
|
54
|
+
#
|
55
|
+
# Client is ready and running inside the reactor
|
56
|
+
#
|
57
|
+
# EM::start_server will yield again on the next connect.
|
58
|
+
#
|
23
59
|
|
24
60
|
end
|
25
61
|
end
|
@@ -24,61 +24,10 @@ module LanGrove::Adaptor
|
|
24
24
|
#
|
25
25
|
|
26
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
27
|
|
79
28
|
end
|
80
29
|
|
81
|
-
def listen(
|
30
|
+
def listen( client, protocol, handler )
|
82
31
|
|
83
32
|
raise LanGrove::DaemonConfigException.new( "NotYetExtended: undefined listen()" )
|
84
33
|
|
data/lib/langrove/client_base.rb
CHANGED
@@ -26,13 +26,11 @@ module LanGrove
|
|
26
26
|
# their actual client..
|
27
27
|
#
|
28
28
|
|
29
|
-
#
|
30
|
-
# The handler collection specified in config
|
31
|
-
# is bound to this attribute after connect.
|
32
|
-
#
|
33
29
|
attr_accessor :handler
|
34
30
|
attr_accessor :protocol
|
35
31
|
attr_accessor :config
|
32
|
+
attr_accessor :logger
|
33
|
+
|
36
34
|
|
37
35
|
#
|
38
36
|
# Data arriving through the Adaptor is passed
|
@@ -51,8 +49,8 @@ module LanGrove
|
|
51
49
|
# - It has passed through the protocol as
|
52
50
|
# defined in config.
|
53
51
|
#
|
54
|
-
# The protocol arranged the data
|
55
|
-
# a Hash of:
|
52
|
+
# The protocol should have arranged the data
|
53
|
+
# into a Hash of:
|
56
54
|
#
|
57
55
|
# - key and value pairs
|
58
56
|
#
|
@@ -67,42 +65,6 @@ module LanGrove
|
|
67
65
|
|
68
66
|
def receive_data( data )
|
69
67
|
|
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
68
|
receive( @protocol.decode( data ) )
|
107
69
|
|
108
70
|
end
|
data/lib/langrove/daemon_base.rb
CHANGED
@@ -7,11 +7,23 @@ module LanGrove::Daemon class Base
|
|
7
7
|
def listen
|
8
8
|
|
9
9
|
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
10
|
+
# <Client> and <Protocol> are passed into
|
11
|
+
# the Adaptor.listen for binding onto the
|
12
|
+
# sockets at connect.
|
13
13
|
#
|
14
|
-
@adaptor.listen(
|
14
|
+
@adaptor.listen(
|
15
|
+
|
16
|
+
#
|
17
|
+
# pass Client, Protocol and Handler to 'listener'
|
18
|
+
#
|
19
|
+
|
20
|
+
{ :class => @client, :config => @my_config[ :client ] },
|
21
|
+
|
22
|
+
{ :class => @protocol, :config => @my_config[ :protocol ] },
|
23
|
+
|
24
|
+
@handler
|
25
|
+
|
26
|
+
)
|
15
27
|
|
16
28
|
end
|
17
29
|
|
@@ -84,10 +96,20 @@ module LanGrove::Daemon class Base
|
|
84
96
|
@adaptor = nil
|
85
97
|
|
86
98
|
#
|
87
|
-
#
|
99
|
+
# The client collection class.
|
88
100
|
#
|
89
101
|
@handler = nil
|
90
102
|
|
103
|
+
#
|
104
|
+
# The client type
|
105
|
+
#
|
106
|
+
@client = nil
|
107
|
+
|
108
|
+
#
|
109
|
+
# The protocol type
|
110
|
+
#
|
111
|
+
@protocol = nil
|
112
|
+
|
91
113
|
|
92
114
|
begin
|
93
115
|
|
@@ -108,9 +130,19 @@ module LanGrove::Daemon class Base
|
|
108
130
|
|
109
131
|
@server = @my_config[ :server ] if @my_config.has_key? :server
|
110
132
|
|
133
|
+
@logger.info "TODO: fall back to default Adaptor::Base"
|
134
|
+
|
111
135
|
adaptor = @my_config[ :adaptor ][ :connection ]
|
112
136
|
|
137
|
+
@logger.info "TODO: fall back to default Handler::Base"
|
138
|
+
|
113
139
|
handler = @my_config[ :handler ][ :collection ]
|
140
|
+
|
141
|
+
client = @my_config[ :client ][ :class ]
|
142
|
+
|
143
|
+
protocol = @my_config[ :protocol ][ :class ]
|
144
|
+
|
145
|
+
@logger.info "TODO: Warn instead of raise and allow nil into ClassLoader -> load default"
|
114
146
|
|
115
147
|
rescue
|
116
148
|
|
@@ -126,6 +158,7 @@ module LanGrove::Daemon class Base
|
|
126
158
|
|
127
159
|
end
|
128
160
|
|
161
|
+
|
129
162
|
#
|
130
163
|
# initialize the connection adaptor specified in config
|
131
164
|
#
|
@@ -137,7 +170,7 @@ module LanGrove::Daemon class Base
|
|
137
170
|
# collection: CollectionOfClients
|
138
171
|
#
|
139
172
|
|
140
|
-
@logger.info "
|
173
|
+
@logger.info "CREATE: Adaptor::#{adaptor}.new( @my_config[ :adaptor ], logger )"
|
141
174
|
|
142
175
|
@adaptor = LanGrove::ClassLoader.create( {
|
143
176
|
|
@@ -160,7 +193,7 @@ module LanGrove::Daemon class Base
|
|
160
193
|
# CollectionOfClients ---> is the handler passed into listen()
|
161
194
|
#
|
162
195
|
|
163
|
-
@logger.info "
|
196
|
+
@logger.info "CREATE: Handler::#{handler}.new( config_hash, '#{daemon_name}', logger )"
|
164
197
|
|
165
198
|
@handler = LanGrove::ClassLoader.create( {
|
166
199
|
|
@@ -169,6 +202,58 @@ module LanGrove::Daemon class Base
|
|
169
202
|
|
170
203
|
} ).new( @config, @daemon_name, @logger )
|
171
204
|
|
205
|
+
|
206
|
+
#
|
207
|
+
# initialize the client specified in config
|
208
|
+
#
|
209
|
+
# daemons:
|
210
|
+
# name_of_daemon:
|
211
|
+
# client:
|
212
|
+
# class: Client <---------
|
213
|
+
# adaptor:
|
214
|
+
# connection: TcpServer
|
215
|
+
# handler:
|
216
|
+
# collection: CollectionOfClients
|
217
|
+
#
|
218
|
+
#
|
219
|
+
|
220
|
+
@logger.info "DEFINE: Client::#{client}"
|
221
|
+
|
222
|
+
@client = LanGrove::ClassLoader.create( {
|
223
|
+
|
224
|
+
:module => 'Client',
|
225
|
+
:class => client
|
226
|
+
|
227
|
+
} )
|
228
|
+
|
229
|
+
|
230
|
+
#
|
231
|
+
# initialize the client specified in config
|
232
|
+
#
|
233
|
+
# daemons:
|
234
|
+
# name_of_daemon:
|
235
|
+
# protocol:
|
236
|
+
# class: Protocol <---------
|
237
|
+
# more: config
|
238
|
+
# client:
|
239
|
+
# class: Client
|
240
|
+
# adaptor:
|
241
|
+
# connection: TcpServer
|
242
|
+
# handler:
|
243
|
+
# collection: CollectionOfClients
|
244
|
+
#
|
245
|
+
#
|
246
|
+
|
247
|
+
@logger.info "DEFINE: Protocol::#{protocol}"
|
248
|
+
|
249
|
+
@protocol = LanGrove::ClassLoader.create( {
|
250
|
+
|
251
|
+
:module => 'Protocol',
|
252
|
+
:class => protocol
|
253
|
+
|
254
|
+
} )
|
255
|
+
|
256
|
+
|
172
257
|
#
|
173
258
|
# Notifiy the handler
|
174
259
|
#
|
@@ -176,7 +261,6 @@ module LanGrove::Daemon class Base
|
|
176
261
|
#
|
177
262
|
|
178
263
|
@handler.start_daemon
|
179
|
-
|
180
264
|
|
181
265
|
end
|
182
266
|
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module LanGrove
|
2
|
+
|
3
|
+
class Find
|
4
|
+
|
5
|
+
def self.with( arg_hash , &block )
|
6
|
+
|
7
|
+
type = :file
|
8
|
+
@path = '.'
|
9
|
+
|
10
|
+
#
|
11
|
+
# TODO: filter
|
12
|
+
#
|
13
|
+
|
14
|
+
@incl = nil
|
15
|
+
|
16
|
+
@relative = false
|
17
|
+
|
18
|
+
|
19
|
+
arg_hash.each do |key, value|
|
20
|
+
|
21
|
+
case key
|
22
|
+
|
23
|
+
when :type
|
24
|
+
|
25
|
+
type = value
|
26
|
+
|
27
|
+
when :path
|
28
|
+
|
29
|
+
@path = value
|
30
|
+
|
31
|
+
when :include
|
32
|
+
|
33
|
+
@incl = value
|
34
|
+
|
35
|
+
when :relative
|
36
|
+
|
37
|
+
@relative = value
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
self.send( :"find_#{type}", @path, &block )
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.find_file( path, &block )
|
49
|
+
|
50
|
+
puts "in #{path}"
|
51
|
+
|
52
|
+
Dir.entries( path ).each do | sub |
|
53
|
+
|
54
|
+
next if sub == '.'
|
55
|
+
next if sub == '..'
|
56
|
+
|
57
|
+
subdir = "#{path}/#{sub}"
|
58
|
+
|
59
|
+
begin
|
60
|
+
|
61
|
+
if @incl.nil? then
|
62
|
+
|
63
|
+
yield relative(subdir) if block
|
64
|
+
|
65
|
+
else
|
66
|
+
|
67
|
+
yield relative(subdir) unless /#{@incl}/.match( subdir ).nil?
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
next
|
72
|
+
|
73
|
+
end if File.file?( subdir ) and block
|
74
|
+
|
75
|
+
find_file( subdir, &block )
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.relative( file_path )
|
82
|
+
|
83
|
+
return file_path.gsub( "#{@path}/",'' ) if @relative
|
84
|
+
return file_path
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
@@ -54,88 +54,95 @@ module LanGrove::Handler class Base
|
|
54
54
|
def periodic
|
55
55
|
|
56
56
|
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
# Changes are pending.
|
60
|
-
#
|
61
|
-
# OVERRIDE
|
57
|
+
# Call periodic on all clients
|
58
|
+
# in the collection
|
62
59
|
#
|
63
|
-
|
64
|
-
|
65
|
-
|
60
|
+
|
61
|
+
@clients.each do |key, value|
|
62
|
+
|
63
|
+
if value == 1 then
|
64
|
+
|
65
|
+
key.periodic
|
66
|
+
|
67
|
+
next
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
value.periodic
|
72
|
+
|
73
|
+
end
|
66
74
|
|
67
75
|
end
|
68
76
|
|
69
|
-
def
|
70
|
-
|
71
|
-
@config = config_hash
|
72
|
-
@daemon_name = daemon_name
|
73
|
-
@logger = logger
|
74
|
-
|
75
|
-
@my_config = @config[ :daemons ][ @daemon_name ][ :handler ]
|
77
|
+
def connect( client )
|
76
78
|
|
77
|
-
|
79
|
+
#
|
80
|
+
# A client has connected at the Adaptor
|
81
|
+
#
|
82
|
+
# It should be inserted into the collection
|
83
|
+
# of clients maintained here.
|
84
|
+
#
|
85
|
+
@logger.debug "Client::#{client} registers with Handler#{self}"
|
78
86
|
|
79
|
-
if
|
87
|
+
if client.respond_to?( :unique_key ) then
|
80
88
|
|
81
|
-
|
89
|
+
@clients[ client.unique_key ] = client
|
90
|
+
return
|
82
91
|
|
83
92
|
end
|
84
93
|
|
94
|
+
@clients[ client ] = 1
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
def disconnect( client )
|
99
|
+
|
85
100
|
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
101
|
+
# A client has disconnected
|
102
|
+
#
|
103
|
+
# It should be removed from the collection.
|
89
104
|
#
|
90
|
-
|
105
|
+
|
91
106
|
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
#
|
95
|
-
# -
|
96
|
-
# - THIS MAY NEED TO CHANGE (thinks & thinks & thinks)
|
107
|
+
# TODO: There will likely be a callback
|
108
|
+
# in the EM::Connection superclass
|
109
|
+
# that can be used here.
|
97
110
|
#
|
98
|
-
#
|
99
|
-
# client is paired with its own instance of the protocol.
|
111
|
+
# Client::Base extends EM::Connection
|
100
112
|
#
|
101
|
-
# - For now it wil be instanciated here and binded to each client at
|
102
|
-
# connect - to be shared for the decoding. That should be fine for
|
103
|
-
# as long as the protocol itself stores no state and is simply a
|
104
|
-
# code path (Still, thinks & ...
|
105
|
-
#
|
106
113
|
|
107
|
-
#
|
108
|
-
# initialize the protocol specified in config
|
109
|
-
#
|
110
|
-
# daemons:
|
111
|
-
#
|
112
|
-
# viking-invasion-early-warning-net_CoreHub_co_uk-D4RK1:
|
113
|
-
#
|
114
|
-
# adaptor:
|
115
|
-
# connection: TriFocalOcularRotisserie
|
116
|
-
# lightsource:
|
117
|
-
# type: Fire
|
118
|
-
# fuel: Peat
|
119
|
-
#
|
120
|
-
# handler:
|
121
|
-
# collection: ScottishCoastalVillages
|
122
|
-
# protocol: MedievalLanternMorse <----------
|
123
|
-
#
|
124
|
-
# Note: This is the application layer protocol
|
125
|
-
# and is therefore entirely agnostic of
|
126
|
-
# transport and disassociated from the
|
127
|
-
# adapter in use.
|
128
|
-
#
|
129
|
-
|
130
|
-
@logger.info "Load definition: Protocol::#{protocol}"
|
114
|
+
@logger.info( "TODO: implement #{self.classname}disconnect()" )
|
131
115
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
116
|
+
end
|
117
|
+
|
118
|
+
def initialize( config_hash, daemon_name, logger )
|
119
|
+
|
120
|
+
@config = config_hash
|
121
|
+
@daemon_name = daemon_name
|
122
|
+
@logger = logger
|
123
|
+
|
124
|
+
@clients = {}
|
125
|
+
|
126
|
+
begin
|
127
|
+
|
128
|
+
@logger.info "TODO: fall back to default Handler::Base"
|
136
129
|
|
137
|
-
|
130
|
+
@my_config = @config[ :daemons ][ @daemon_name ][ :handler ]
|
138
131
|
|
132
|
+
rescue
|
133
|
+
|
134
|
+
error = "Missing config item for daemon: #{@daemon_name}"
|
135
|
+
|
136
|
+
@logger.error "EXIT: #{error}"
|
137
|
+
|
138
|
+
raise LanGrove::DaemonConfigException.new(
|
139
|
+
|
140
|
+
"Missing config item for daemon: #{@daemon_name}"
|
141
|
+
|
142
|
+
)
|
143
|
+
|
144
|
+
end
|
145
|
+
|
139
146
|
end
|
140
147
|
|
141
148
|
end; end
|
data/lib/langrove/version.rb
CHANGED
@@ -11,6 +11,7 @@ describe LanGrove::Daemon::Base do
|
|
11
11
|
@adaptor_class = 'Base'
|
12
12
|
@collection_class = 'Base'
|
13
13
|
@client_class = 'Base'
|
14
|
+
@protocol_class = 'Base'
|
14
15
|
|
15
16
|
@config = {
|
16
17
|
|
@@ -22,13 +23,20 @@ describe LanGrove::Daemon::Base do
|
|
22
23
|
|
23
24
|
:adaptor => {
|
24
25
|
|
25
|
-
:connection => @adaptor_class
|
26
|
+
:connection => @adaptor_class
|
27
|
+
|
28
|
+
},
|
29
|
+
|
30
|
+
:client => {
|
31
|
+
|
32
|
+
:class => @client_class
|
33
|
+
|
34
|
+
},
|
35
|
+
|
36
|
+
:protocol => {
|
37
|
+
|
38
|
+
:class => @protocol_class
|
26
39
|
|
27
|
-
:client => {
|
28
|
-
|
29
|
-
:class => @client_class
|
30
|
-
|
31
|
-
}
|
32
40
|
},
|
33
41
|
|
34
42
|
:handler => {
|
@@ -84,6 +92,38 @@ describe LanGrove::Daemon::Base do
|
|
84
92
|
|
85
93
|
end
|
86
94
|
|
95
|
+
it 'loads the client defininition by config' do
|
96
|
+
|
97
|
+
client = subject.instance_variable_get( :@client )
|
98
|
+
|
99
|
+
client.should == LanGrove::Client::Base
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'does not instanciate the client' do
|
104
|
+
|
105
|
+
client = subject.instance_variable_get( :@client )
|
106
|
+
|
107
|
+
client.should_not be_a(LanGrove::Client::Base)
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'loads the protocol defininition by config' do
|
112
|
+
|
113
|
+
protocol = subject.instance_variable_get( :@protocol )
|
114
|
+
|
115
|
+
protocol.should == LanGrove::Protocol::Base
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'does not instanciate the protocol' do
|
120
|
+
|
121
|
+
protocol = subject.instance_variable_get( :@protocol )
|
122
|
+
|
123
|
+
protocol.should_not be_a(LanGrove::Protocol::Base)
|
124
|
+
|
125
|
+
end
|
126
|
+
|
87
127
|
it 'it schedules periodics'
|
88
128
|
|
89
129
|
it 'when run, it calls to listen if server is true' do
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'langrove/ext/find'
|
2
|
+
|
3
|
+
describe LanGrove::Find do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
|
7
|
+
|
8
|
+
@path = File.expand_path('../../../../bin', __FILE__ )
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'searches finds' do
|
13
|
+
|
14
|
+
test = []
|
15
|
+
|
16
|
+
LanGrove::Find.with(
|
17
|
+
|
18
|
+
:type => :file,
|
19
|
+
:path => @path,
|
20
|
+
:relative => true
|
21
|
+
|
22
|
+
) do |found|
|
23
|
+
|
24
|
+
test << found
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
test.length.should == 1
|
29
|
+
test[0].should == 'langrove'
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'searches filters' do
|
34
|
+
|
35
|
+
test = []
|
36
|
+
|
37
|
+
LanGrove::Find.with(
|
38
|
+
|
39
|
+
:type => :file,
|
40
|
+
:path => @path,
|
41
|
+
:include => 'scotch mist'
|
42
|
+
|
43
|
+
) do |found|
|
44
|
+
|
45
|
+
test << found
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
test.length.should == 0
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -24,34 +24,80 @@ describe LanGrove::Handler::Base do
|
|
24
24
|
|
25
25
|
end
|
26
26
|
|
27
|
-
|
27
|
+
subject do
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
LanGrove::Handler::Base.new( @config, @daemon_name, @logger )
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'maintains a connected client collection with' do
|
34
|
+
|
35
|
+
it 'in a hash' do
|
32
36
|
|
33
|
-
|
37
|
+
clients = subject.instance_variable_get( :@clients )
|
34
38
|
|
35
|
-
|
39
|
+
clients.should be_a( Hash )
|
36
40
|
|
37
41
|
end
|
42
|
+
|
43
|
+
context 'connect()' do
|
38
44
|
|
39
|
-
|
45
|
+
it 'using a key defined by the client' do
|
46
|
+
|
47
|
+
client = double( 'Client' )
|
48
|
+
client.should_receive( :respond_to? ).with( :unique_key ).and_return( true )
|
49
|
+
client.should_receive( :unique_key ).and_return('KEY1')
|
50
|
+
|
51
|
+
subject.connect( client )
|
52
|
+
|
53
|
+
clients = subject.instance_variable_get( :@clients )
|
54
|
+
|
55
|
+
clients['KEY1'].should == client
|
56
|
+
|
57
|
+
end
|
40
58
|
|
41
|
-
|
59
|
+
it 'using the client itself as the key if unique is not defined' do
|
60
|
+
|
61
|
+
client = double( 'Client' )
|
62
|
+
client.should_receive( :respond_to? ).with( :unique_key ).and_return( false )
|
63
|
+
|
64
|
+
subject.connect( client )
|
65
|
+
|
66
|
+
clients = subject.instance_variable_get( :@clients )
|
67
|
+
|
68
|
+
clients[ client ].should == 1
|
69
|
+
|
70
|
+
end
|
42
71
|
|
43
|
-
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'disconnect()' do
|
44
75
|
|
45
|
-
|
76
|
+
it 'to remove the client from the collection'
|
46
77
|
|
47
|
-
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'call the periodic ticker to all attached clients' do
|
48
81
|
|
49
|
-
|
82
|
+
client1 = Object.const_set( 'Client', Class.new() do
|
83
|
+
|
84
|
+
self.class_eval { attr_accessor :unique }
|
50
85
|
|
51
|
-
)
|
86
|
+
end).new
|
87
|
+
client1.unique = 'kEy'
|
88
|
+
|
89
|
+
client2 = Object.new
|
90
|
+
|
91
|
+
client1.should_receive( :periodic )
|
92
|
+
client2.should_receive( :periodic )
|
93
|
+
|
94
|
+
subject.connect( client1 )
|
95
|
+
subject.connect( client2 )
|
96
|
+
|
97
|
+
subject.periodic
|
52
98
|
|
53
99
|
end
|
54
100
|
|
55
101
|
end
|
56
|
-
|
102
|
+
|
57
103
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: langrove
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.4.
|
4
|
+
version: 0.0.4.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,11 +12,11 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2012-04-
|
15
|
+
date: 2012-04-24 00:00:00.000000000Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: watchr
|
19
|
-
requirement: &
|
19
|
+
requirement: &2153525920 !ruby/object:Gem::Requirement
|
20
20
|
none: false
|
21
21
|
requirements:
|
22
22
|
- - ! '>='
|
@@ -24,10 +24,10 @@ dependencies:
|
|
24
24
|
version: '0'
|
25
25
|
type: :development
|
26
26
|
prerelease: false
|
27
|
-
version_requirements: *
|
27
|
+
version_requirements: *2153525920
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: rspec
|
30
|
-
requirement: &
|
30
|
+
requirement: &2153525420 !ruby/object:Gem::Requirement
|
31
31
|
none: false
|
32
32
|
requirements:
|
33
33
|
- - ~>
|
@@ -35,10 +35,10 @@ dependencies:
|
|
35
35
|
version: '2.9'
|
36
36
|
type: :development
|
37
37
|
prerelease: false
|
38
|
-
version_requirements: *
|
38
|
+
version_requirements: *2153525420
|
39
39
|
- !ruby/object:Gem::Dependency
|
40
40
|
name: rake
|
41
|
-
requirement: &
|
41
|
+
requirement: &2153524900 !ruby/object:Gem::Requirement
|
42
42
|
none: false
|
43
43
|
requirements:
|
44
44
|
- - ~>
|
@@ -49,10 +49,10 @@ dependencies:
|
|
49
49
|
version: 0.8.7
|
50
50
|
type: :development
|
51
51
|
prerelease: false
|
52
|
-
version_requirements: *
|
52
|
+
version_requirements: *2153524900
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
54
|
name: eventmachine
|
55
|
-
requirement: &
|
55
|
+
requirement: &2153524160 !ruby/object:Gem::Requirement
|
56
56
|
none: false
|
57
57
|
requirements:
|
58
58
|
- - ~>
|
@@ -63,10 +63,10 @@ dependencies:
|
|
63
63
|
version: 0.12.10
|
64
64
|
type: :runtime
|
65
65
|
prerelease: false
|
66
|
-
version_requirements: *
|
66
|
+
version_requirements: *2153524160
|
67
67
|
- !ruby/object:Gem::Dependency
|
68
68
|
name: em-http-request
|
69
|
-
requirement: &
|
69
|
+
requirement: &2153523420 !ruby/object:Gem::Requirement
|
70
70
|
none: false
|
71
71
|
requirements:
|
72
72
|
- - ~>
|
@@ -77,10 +77,10 @@ dependencies:
|
|
77
77
|
version: 0.3.0
|
78
78
|
type: :runtime
|
79
79
|
prerelease: false
|
80
|
-
version_requirements: *
|
80
|
+
version_requirements: *2153523420
|
81
81
|
- !ruby/object:Gem::Dependency
|
82
82
|
name: daemon-kit
|
83
|
-
requirement: &
|
83
|
+
requirement: &2153522680 !ruby/object:Gem::Requirement
|
84
84
|
none: false
|
85
85
|
requirements:
|
86
86
|
- - ~>
|
@@ -91,10 +91,10 @@ dependencies:
|
|
91
91
|
version: 0.1.8.2
|
92
92
|
type: :runtime
|
93
93
|
prerelease: false
|
94
|
-
version_requirements: *
|
94
|
+
version_requirements: *2153522680
|
95
95
|
- !ruby/object:Gem::Dependency
|
96
96
|
name: resque
|
97
|
-
requirement: &
|
97
|
+
requirement: &2153521940 !ruby/object:Gem::Requirement
|
98
98
|
none: false
|
99
99
|
requirements:
|
100
100
|
- - ~>
|
@@ -105,7 +105,7 @@ dependencies:
|
|
105
105
|
version: 1.20.0
|
106
106
|
type: :runtime
|
107
107
|
prerelease: false
|
108
|
-
version_requirements: *
|
108
|
+
version_requirements: *2153521940
|
109
109
|
description: ''
|
110
110
|
email: richard@clue.co.za
|
111
111
|
executables:
|
@@ -120,20 +120,17 @@ files:
|
|
120
120
|
- .rvmrc
|
121
121
|
- .watchr
|
122
122
|
- Rakefile
|
123
|
-
-
|
124
|
-
- functional/bin/datagram
|
125
|
-
- functional/config/.gitignore
|
123
|
+
- tmp/README
|
126
124
|
- functional/config/boot.rb
|
127
125
|
- functional/config/daemons.yml
|
128
126
|
- functional/config/environment.rb
|
129
127
|
- functional/config/environments/development.rb
|
130
128
|
- functional/config/environments/production.rb
|
131
129
|
- functional/config/environments/test.rb
|
130
|
+
- functional/lib/client/socket_to_file.rb
|
132
131
|
- functional/lib/daemon/datagram.rb
|
133
|
-
- functional/lib/handler/socket_to_file.rb
|
134
132
|
- functional/lib/protocol/socket_to_file.rb
|
135
133
|
- functional/libexec/daemon.rb
|
136
|
-
- functional/log/.gitignore
|
137
134
|
- functional/tmp/README
|
138
135
|
- lib/langrove/_base.rb
|
139
136
|
- lib/langrove/adaptor/base.rb
|
@@ -148,6 +145,7 @@ files:
|
|
148
145
|
- lib/langrove/ext/config_item.rb
|
149
146
|
- lib/langrove/ext/config_loader.rb
|
150
147
|
- lib/langrove/ext/fake_logger.rb
|
148
|
+
- lib/langrove/ext/find.rb
|
151
149
|
- lib/langrove/ext/persistable.rb
|
152
150
|
- lib/langrove/ext/string.rb
|
153
151
|
- lib/langrove/ext.rb
|
@@ -168,13 +166,13 @@ files:
|
|
168
166
|
- spec/langrove/ext/config_item_spec.rb
|
169
167
|
- spec/langrove/ext/config_loader_spec.rb
|
170
168
|
- spec/langrove/ext/fake_logger_spec.rb
|
169
|
+
- spec/langrove/ext/find_spec.rb
|
171
170
|
- spec/langrove/ext/persistable_spec.rb
|
172
171
|
- spec/langrove/ext/string_spec.rb
|
173
172
|
- spec/langrove/handler_base_spec.rb
|
174
173
|
- spec/langrove/protocol/syslog_spec.rb
|
175
174
|
- spec/langrove/protocol_base_spec.rb
|
176
175
|
- spec/todo_spec.rb
|
177
|
-
- tmp/README
|
178
176
|
homepage: ''
|
179
177
|
licenses: []
|
180
178
|
post_install_message:
|
@@ -195,7 +193,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
195
193
|
version: '0'
|
196
194
|
requirements: []
|
197
195
|
rubyforge_project:
|
198
|
-
rubygems_version: 1.8.
|
196
|
+
rubygems_version: 1.8.8
|
199
197
|
signing_key:
|
200
198
|
specification_version: 3
|
201
199
|
summary: eventmachine based networked daemon framework
|
data/functional/.gitignore
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
tmp/*.*
|
data/functional/bin/datagram
DELETED
File without changes
|
@@ -1,42 +0,0 @@
|
|
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 periodic
|
21
|
-
|
22
|
-
@logger.info( "periodic" )
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
def receive( data )
|
27
|
-
|
28
|
-
@logger.info( "#{self}.receive: #{data}" )
|
29
|
-
|
30
|
-
File.open( data[:filename], 'w' ) do |f|
|
31
|
-
|
32
|
-
f.write( data[:content] )
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
@logger.info "Wrote data: '#{data[ :content ]}' to file: '#{ data[ :filename ]}'"
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
data/functional/log/.gitignore
DELETED