rbeai 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/lib/rbeai/GetLogic.rb +144 -0
  2. data/lib/rbeai/Main.rb +70 -0
  3. data/lib/rbeai/PipeTask.rb +216 -0
  4. data/lib/rbeai/PutLogic.rb +123 -0
  5. data/lib/rbeai/RouterLogic.rb +155 -0
  6. data/lib/rbeai/RouterPipeTask.rb +62 -0
  7. data/lib/rbeai/TasksLogic.rb +285 -0
  8. data/lib/rbeai/TransfLogic.rb +145 -0
  9. data/lib/rbeai/WorkerPool.rb +72 -0
  10. data/lib/rbeai/Workflow.rb +79 -0
  11. data/lib/rbeai/templates/csv2xml_nh.awk +14 -0
  12. data/lib/rbeai/templates/csv2xml_wh.awk +16 -0
  13. data/lib/rbeai.rb +13 -0
  14. data/rbeai-0.0.1.gem +0 -0
  15. data/rbeai.gemspec +20 -0
  16. data/test/config/conf.rb +2 -0
  17. data/test/test1.rb +4 -0
  18. data/test/test_files/empty_file.txt +0 -0
  19. data/test/test_files/empty_file.unused +0 -0
  20. data/test/test_files/test_router_1.txt +1 -0
  21. data/test/test_files/test_router_1.xml_91 +5 -0
  22. data/test/test_files/test_router_1.xml_92 +6 -0
  23. data/test/test_files/test_router_1.xml_fail +5 -0
  24. data/test/test_files/test_transf_1.xml +28 -0
  25. data/test/test_files/test_transf_2.txt +5 -0
  26. data/test/test_files/test_transf_3.xml +28 -0
  27. data/test/test_get_send_email.rb +11 -0
  28. data/test/test_get_send_file.rb +11 -0
  29. data/test/test_get_send_ftp.rb +11 -0
  30. data/test/test_router.rb +11 -0
  31. data/test/test_transf_1.rb +11 -0
  32. data/test/test_transf_2.awk +1 -0
  33. data/test/test_transf_2.rb +11 -0
  34. data/test/test_transf_3.rb +11 -0
  35. data/test/test_transf_3.xsl +10 -0
  36. data/test/tmp/test_get_send_file/1130328204.12500/getfile/empty_file.txt +0 -0
  37. data/test/tmp/test_get_send_ftp/1130328178.76500/getfile/empty_file.txt +0 -0
  38. data/test/workflows/test_get_send_email.wf +28 -0
  39. data/test/workflows/test_get_send_file.wf +21 -0
  40. data/test/workflows/test_get_send_ftp.wf +28 -0
  41. data/test/workflows/test_router_1.wf +35 -0
  42. data/test/workflows/test_start_end.wf +8 -0
  43. data/test/workflows/test_transf_1.wf +26 -0
  44. data/test/workflows/test_transf_2.wf +25 -0
  45. data/test/workflows/test_transf_3.wf +25 -0
  46. metadata +128 -0
@@ -0,0 +1,144 @@
1
+ require 'rio'
2
+ require 'rmail/parser'
3
+ require 'net/pop'
4
+ require 'rexml/document'
5
+
6
+ include REXML
7
+
8
+ module RbEAI
9
+
10
+ class GetLogic
11
+
12
+
13
+ def initialize(xmlDoc, task)
14
+ @task = task
15
+ protNode = XPath.first(xmlDoc, "./protocol")
16
+ protocol = protNode.attributes["def"]
17
+ @logic = case protocol
18
+ when "file" then GetFileLogic.new(protNode, task)
19
+ when "ftp" then GetFileLogic.new(protNode, task)
20
+ when "email" then GetEmailLogic.new(protNode, task)
21
+ end
22
+ end
23
+
24
+ def getFiles()
25
+ return @logic.getFiles()
26
+ end
27
+
28
+ end
29
+
30
+ class GetFileLogic
31
+
32
+ def initialize(protNode, task)
33
+ @task = task
34
+ @location = task.location
35
+ @pattern = task.pattern
36
+ end
37
+
38
+ def getFiles()
39
+ files = []
40
+ filesaux = []
41
+ files = rio("#{@location}")["#{@pattern}"]
42
+ files.each do |file|
43
+ filesaux << @task.persist(file)
44
+ end
45
+ return filesaux
46
+ end
47
+
48
+ end
49
+
50
+ class GetFtpLogic
51
+
52
+ def initialize(protNode, task)
53
+ @task = task
54
+ @location = task.location
55
+ @pattern = task.pattern
56
+ end
57
+
58
+ def getFiles()
59
+ files = []
60
+ filesaux = []
61
+ files = rio("#{@location}")
62
+ regexp = Regexp.new("#{@pattern}")
63
+ files.each do |file|
64
+ puts "file = #{file}"
65
+ filesaux << @task.persistFtp(file) if regexp.match("#{file}")
66
+ end
67
+ return filesaux
68
+ end
69
+
70
+ end
71
+
72
+ # <protocol def="email">
73
+ # <location address="" port=""/>
74
+ # <account name="" pwd=""/>
75
+ # <pattern>out.xml</pattern>
76
+ # </protocol>
77
+
78
+ class GetEmailLogic
79
+
80
+ def initialize(protNode, task)
81
+ @task = task
82
+ location = XPath.first(protNode, "./location")
83
+ account = XPath.first(protNode, "./account")
84
+ @address = location.attributes["address"]
85
+ @port = location.attributes["port"]
86
+ @name = account.attributes["name"]
87
+ @pwd = account.attributes["pwd"]
88
+ @pattern = task.pattern
89
+ end
90
+
91
+ def getFiles()
92
+ files = []
93
+ pop = Net::POP3.new(@address)
94
+ pop.start(@name, @pwd)
95
+ if pop.mails.empty?
96
+ puts 'No mail.'
97
+ else
98
+ i = 1
99
+ pop.each_mail do |m|
100
+ str = m.pop
101
+ i = i + 1
102
+ begin
103
+ email = RMail::Parser.read(str)
104
+ aux = true
105
+ _parseMail(email, @pattern, "mail_#{i}").each do |file|
106
+ _persistAndDelete(m, str, "mail_#{i}.txt") if aux
107
+ aux = false
108
+ files << file
109
+ end
110
+ rescue Exception
111
+ puts $!
112
+ end
113
+ end
114
+ puts "#{pop.mails.size} mails popped."
115
+ end
116
+ pop.finish
117
+ return files
118
+ end
119
+
120
+ private
121
+
122
+ def _persistAndDelete(mail, str, basename)
123
+ @task.persistStr(str, "#{basename}.txt")
124
+ #mail.delete
125
+ end
126
+
127
+ def _parseMail(email, fnameExpr, basename)
128
+ result = []
129
+ if email.multipart?
130
+ i = 0
131
+ email.each_part do |part|
132
+ fname = part.header.param('Content-Disposition','filename')
133
+ re = Regexp.new(fnameExpr.to_s)
134
+ if re.match(fname)
135
+ result << @task.persistStr(part.decode, "#{basename}_att_#{i}.txt")
136
+ end
137
+ end
138
+ end
139
+ return result
140
+ end
141
+
142
+ end
143
+
144
+ end #module
data/lib/rbeai/Main.rb ADDED
@@ -0,0 +1,70 @@
1
+ require 'rio'
2
+ require 'gserver'
3
+ require 'rbeai/Workflow'
4
+
5
+ include REXML
6
+
7
+ module RbEAI
8
+
9
+
10
+ class MAIN < GServer
11
+
12
+ load 'config/conf.rb'
13
+
14
+ def initialize()
15
+ #server_port = 8888
16
+ #server_log = true
17
+ @wflowlist = []
18
+ super(port = @@server_port, host = "localhost", maxConnections = 1, audit = @@server_log)
19
+ end
20
+
21
+ def serve(io)
22
+ command = io.gets.strip
23
+ if command == "stop"
24
+ io.puts "Exiting ..."
25
+ stop()
26
+ end
27
+ end
28
+
29
+ def start()
30
+ files = []
31
+ files = rio("workflows")["*.wf"]
32
+ files.each do |file|
33
+ puts file
34
+ awflow = Workflow.new(File.new(file))
35
+ awflow.run
36
+ @wflowlist << awflow
37
+ end
38
+ super()
39
+ end
40
+
41
+ def shutdown()
42
+ _endWflows()
43
+ super()
44
+ end
45
+
46
+ def stop()
47
+ _endWflows()
48
+ super()
49
+ end
50
+
51
+ private
52
+
53
+ def _endWflows()
54
+ @wflowlist.each do |wflow|
55
+ wflow.finish
56
+ end
57
+ end
58
+
59
+ end #class
60
+
61
+
62
+ end #module
63
+
64
+ #wf = Workflow.new(wfstr)
65
+ #wf.run()
66
+ #sleep(10)
67
+ #wf.finish()
68
+ #eai = MAIN.new()
69
+ #eai.start
70
+ #eai.join
@@ -0,0 +1,216 @@
1
+ require 'thread'
2
+ require 'thwait'
3
+
4
+ module RbEAI
5
+
6
+ class Control
7
+
8
+ attr_accessor :controlQueue, :control
9
+
10
+ def initialize(controlQueue, dataQueue)
11
+ @controlQueue = controlQueue
12
+ @dataQueue = dataQueue
13
+ end
14
+
15
+ def start(threadPool)
16
+ @control = Thread.new() do
17
+ #print "Running control thread \n"
18
+ begin
19
+ obj = @controlQueue.deq
20
+ end until obj == :FINISH_THREADS
21
+ threadPool.size.times { @dataQueue.enq(:FINISH_WORK) }
22
+ threadPool.waitJoinAll()
23
+ #print "Finished control thread \n"
24
+ end
25
+ end
26
+
27
+ def waitJoin()
28
+ @control.join()
29
+ end
30
+
31
+ def finish()
32
+ @controlQueue.enq(:FINISH_THREADS)
33
+ end
34
+
35
+ end
36
+
37
+ class ThreadPool
38
+
39
+ attr_accessor :size
40
+
41
+ def initialize(size, task, method, inputQueue, resultQueue, bufferQueue, controlQueue)
42
+ @size = size
43
+ @task = task
44
+ @method = method
45
+ @inputQueue = inputQueue
46
+ @resultQueue = resultQueue
47
+ @bufferQueue = bufferQueue
48
+ @controlQueue = controlQueue
49
+ @threadgroup = ThreadsWait.new
50
+ end
51
+
52
+ def start(name)
53
+ @size.times do
54
+ th = Thread.new(@method) do |method|
55
+ #print "Running #{name} th \n"
56
+ begin
57
+ obj = @inputQueue.deq
58
+ #print "#{name} -> #{obj}\n"
59
+ if obj != :FINISH_WORK && obj != :FINISH_THREADS
60
+ if @bufferQueue != nil
61
+ method.call(@bufferQueue, obj)
62
+ @resultQueue.enq(obj)
63
+ else
64
+ method.call(@resultQueue, obj)
65
+ end
66
+ elsif obj == :FINISH_THREADS
67
+ @controlQueue.enq(:FINISH_THREADS)
68
+ end
69
+ end until obj == :FINISH_WORK
70
+ #print "Finished th \n"
71
+ end
72
+ @threadgroup.join_nowait(th)
73
+ end
74
+ end
75
+
76
+ def waitJoinAll()
77
+ @threadgroup.all_waits
78
+ @task.doBuffered(@bufferQueue) if @bufferQueue != nil
79
+ end
80
+
81
+ end
82
+
83
+ class PipeTask
84
+
85
+ def initialize(inputQueue, task, control)
86
+ @inputQueue = inputQueue
87
+ @task = task
88
+ @control = control
89
+ @resultQueue = Queue.new
90
+ @bufferQueue = task.respond_to?(:doBuffered) ? Queue.new : nil
91
+ @nextPipe = if @task.respond_to?(:nextTask) and @task.nextTask != nil
92
+ getNextPipe(@resultQueue, @task.nextTask, Control.new(Queue.new, @resultQueue))
93
+ else nil
94
+ end
95
+ @size = task.size
96
+ @threadPool = ThreadPool.new(@size, @task, @task.method(:doJob), @inputQueue, @resultQueue, @bufferQueue, control.controlQueue)
97
+ end
98
+
99
+ def run()
100
+ @nextPipe.run() if @nextPipe != nil
101
+ @threadPool.start(@task.name)
102
+ @control.start(@threadPool)
103
+ end
104
+
105
+ def waitToEnd()
106
+ #print "JOIN-#{@task.name}\n"
107
+ @control.waitJoin()
108
+ print "END-#{@task.name}\n"
109
+ @nextPipe.finish() if @nextPipe != nil
110
+ @nextPipe.waitToEnd() if @nextPipe != nil
111
+ end
112
+
113
+ def finish()
114
+ @control.finish()
115
+ #@inputQueue.enq(:FINISH_THREADS)
116
+ end
117
+
118
+ protected
119
+
120
+ def getNextPipe(inputQueue, task, control)
121
+ nextPipe = nil
122
+ if task.class == RouterTask
123
+ then nextPipe = RouterPipeTask.new(inputQueue, task, control)
124
+ else nextPipe = PipeTask.new(inputQueue, task, control)
125
+ end
126
+ #nextPipe = PipeTask.new(@resultQueue, @task.nextTask, Control.new(Queue.new, @resultQueue))
127
+ return nextPipe
128
+ end
129
+
130
+ end
131
+
132
+
133
+ class RouterPipeTask < PipeTask
134
+
135
+ def initialize(inputQueue, task, control)
136
+ @inputQueue = inputQueue
137
+ @task = task
138
+ @control = control
139
+ @resultQueue = task.initQueues()
140
+ @bufferQueue = nil
141
+ @nextPipe = _getNextPipes()
142
+ @size = task.size
143
+ @threadPool = ThreadPool.new(@size, @task, @task.method(:doJob), inputQueue, @resultQueue, @bufferQueue, control.controlQueue)
144
+ end
145
+
146
+ def run()
147
+ _RunNextPipes()
148
+ @threadPool.start(@task.name)
149
+ @control.start(@threadPool)
150
+ end
151
+
152
+ def waitToEnd()
153
+ #print "JOIN-#{@task.name}\n"
154
+ @control.waitJoin
155
+ print "END-#{@task.name}\n"
156
+ _WaitToEndNextPipes()
157
+ end
158
+
159
+ private
160
+
161
+ def _getNextPipes()
162
+ nextPipeList = Hash.new(0)
163
+ @task.nextTask.each do | key, task |
164
+ inputQueue = @resultQueue[key]
165
+ controlQueue = Queue.new
166
+ control = Control.new(controlQueue, inputQueue)
167
+ nextPipeList[key] = getNextPipe(inputQueue, task, control)
168
+ end
169
+ return nextPipeList
170
+ end
171
+
172
+ def _RunNextPipes()
173
+ @nextPipe.each do | key, pipe |
174
+ pipe.run() if pipe != nil
175
+ end
176
+ end
177
+
178
+ def _WaitToEndNextPipes()
179
+ @nextPipe.each do | key, pipe |
180
+ pipe.finish() if pipe != nil
181
+ end
182
+ @nextPipe.each do | key, pipe |
183
+ pipe.waitToEnd() if pipe != nil
184
+ end
185
+ end
186
+
187
+ end
188
+
189
+ class Hello
190
+
191
+ attr_accessor :size
192
+
193
+ def initialize
194
+ @size = 20
195
+ end
196
+
197
+ def doJob(aQueue, obj)
198
+ print "#{Thread.current.to_s}-#{obj}\n"
199
+ aQueue.enq("true")
200
+ end
201
+
202
+
203
+ def getItemsNext(numItems)
204
+ return 200
205
+ end
206
+ end
207
+
208
+ #h = Hello.new
209
+ #inputQ = Queue.new
210
+ #wp = PipeTask.new(inputQ, Queue.new, h)
211
+ #wp.run(1000)
212
+ #1000.times { |i| inputQ.enq(i) }
213
+ #wp.waitToEnd()
214
+
215
+ end #module
216
+
@@ -0,0 +1,123 @@
1
+ require 'rio'
2
+ require 'rmail/parser'
3
+ require 'net/smtp'
4
+ require "base64"
5
+ require 'rexml/document'
6
+
7
+ include REXML
8
+
9
+ module RbEAI
10
+
11
+ class PutLogic
12
+
13
+
14
+ def initialize(xmlDoc, task)
15
+ @task = task
16
+ protNode = XPath.first(xmlDoc, "./protocol")
17
+ protocol = protNode.attributes["def"]
18
+ @logic = case protocol
19
+ when "file", "ftp" then PutFileLogic.new(task)
20
+ when "email" then PutEmailLogic.new(protNode, task)
21
+ end
22
+ end
23
+
24
+ def putFile(obj)
25
+ return @logic.putFile(obj)
26
+ end
27
+
28
+ end
29
+
30
+ class PutFileLogic
31
+
32
+ def initialize(task)
33
+ @task = task
34
+ @location = task.location
35
+ end
36
+
37
+ def putFile(obj)
38
+ rio("#{obj}") > rio("#{@location}")
39
+ end
40
+
41
+ end
42
+
43
+
44
+
45
+ # <task name="sendfile" type="Put" rate="0s" pool="1">
46
+ # <next>final</next>
47
+ # <protocol def="mail">
48
+ # <location address="" port=""/>
49
+ # <account name="" pwd=""/>
50
+ # <from></from>
51
+ # <to></to>
52
+ # <cc></cc>
53
+ # <bcc></bcc>
54
+ # <subject></subject>
55
+ # </protocol>
56
+ # </task>
57
+
58
+ class PutEmailLogic
59
+
60
+ def initialize(protNode, task)
61
+ @task = task
62
+ location = XPath.first(protNode, "./location")
63
+ account = XPath.first(protNode, "./account")
64
+ @address = location.attributes["address"]
65
+ @domain = location.attributes["domain"]
66
+ @port = location.attributes["port"]
67
+ @name = account.attributes["name"]
68
+ @pwd = account.attributes["pwd"]
69
+ @from = XPath.first(protNode, "./from/text()")
70
+ @to = XPath.first(protNode, "./to/text()")
71
+ @subject = XPath.first(protNode, "./subject/text()")
72
+ @bodymsg = XPath.first(protNode, "./body/text()")
73
+ @attachment = XPath.first(protNode, "./attachment/text()")
74
+ end
75
+
76
+ def putFile(obj)
77
+ begin
78
+ smtp = if @name != nil
79
+ Net::SMTP.start(@address, @port, @domain, @name, @pwd, :login)
80
+ elsif @domain != nil
81
+ Net::SMTP.start(@address, @port, @domain)
82
+ else
83
+ Net::SMTP.start(@address, @port)
84
+ end
85
+ message = _buildMessage(obj)
86
+ smtp.send_message message, "#{@from}", "#{@to}".split(",").each { |to| to.strip! }
87
+ smtp.finish
88
+ rescue Exception
89
+ puts $!
90
+ end
91
+ end
92
+
93
+ private
94
+
95
+ def _buildMessage(obj)
96
+ message = RMail::Message.new
97
+ header = message.header
98
+ # HEADER ###############################
99
+ header.from= "#{@from}"
100
+ header.to = "#{@to}"
101
+ header.subject= "#{@subject}"
102
+ header.add('Content-Type', 'multipart/mixed')
103
+ # BODY #################################
104
+ abody = RMail::Message.new
105
+ abody.body = "#{@bodymsg}"
106
+ message.add_part(abody)
107
+ # ATTACHMENT ###########################
108
+ part= RMail::Message.new
109
+ headerpart = part.header
110
+ headerpart.add('Content-Type', 'text/plain', nil, 'name' => "#{@attachment}" )
111
+ headerpart.add('Content-Transfer-Encoding', 'base64')
112
+ headerpart.add('Content-Description', "#{@attachment}" )
113
+ headerpart.add('Content-Disposition', 'attachment', nil, 'filename' => "#{@attachment}" )
114
+ aux = ""
115
+ rio("#{obj}") > aux
116
+ part.body = Base64.encode64(aux)
117
+ message.add_part(part)
118
+ return message
119
+ end
120
+
121
+ end
122
+
123
+ end #module
@@ -0,0 +1,155 @@
1
+ require 'rio'
2
+ require 'rexml/document'
3
+ require 'rexml/sax2listener'
4
+ require 'rexml/parsers/sax2parser'
5
+
6
+ include REXML
7
+
8
+ module RbEAI
9
+
10
+ class RouterLogic
11
+
12
+ attr_accessor :destinations, :default
13
+
14
+ def initialize(xmlDoc)
15
+ @destinations = []
16
+ XPath.each(xmlDoc, "./next/goto[count(when) > 0]") do |el|
17
+ taskname = el.attributes["task"]
18
+ @destinations << [taskname, LogicFilter.new(el)]
19
+ end
20
+ XPath.each(xmlDoc, "./next/goto[count(when) = 0]") do |el|
21
+ taskname = el.attributes["task"]
22
+ @destinations << [taskname, LogicFilter.new(el)]
23
+ end
24
+ end
25
+
26
+ def enroute(file)
27
+ targettask = nil
28
+
29
+ @destinations.each do | item |
30
+ taskname = item[0]
31
+ filter = item[1]
32
+ if filter.match(file)
33
+ targettask = taskname
34
+ break
35
+ end
36
+ end
37
+
38
+ return targettask
39
+ end
40
+
41
+ end
42
+
43
+ class LogicFilter
44
+
45
+ def initialize(xmlDoc)
46
+ @parsers = []
47
+ XPath.each(xmlDoc, "./when") do |el|
48
+ @parsers << _getParser(el)
49
+ end
50
+ end
51
+
52
+ def match(file)
53
+ result = true
54
+ @parsers.each do | parser |
55
+ begin
56
+ if parser.match(file)
57
+ result = true
58
+ break
59
+ else
60
+ result = false
61
+ end
62
+ rescue Exception
63
+ result = false
64
+ end
65
+ end
66
+ return result
67
+ end
68
+
69
+ private
70
+
71
+ def _getParser(node)
72
+ filter = node.attributes["filter"]
73
+ re = Regexp.new('(re|xpath|sax|name):(.+)')
74
+ mr = re.match(filter)
75
+ case mr[1]
76
+ when 're' then RexParser.new(node, mr[2])
77
+ when 'xpath' then XPazParser.new(node, mr[2])
78
+ when 'sax' then SazParser.new(node, mr[2])
79
+ when 'name' then NameParser.new(node, mr[2])
80
+ end
81
+ end
82
+
83
+ end
84
+
85
+ class RexParser
86
+
87
+ def initialize(node, expression)
88
+ @resultList = node.elements["."].text
89
+ @regexp = Regexp.new(expression)
90
+ end
91
+
92
+ def match(file)
93
+ ario = rio(file)
94
+ ario > aString
95
+ mr = @regexp.match(aString)
96
+ return @resultList.include?(mr[0])
97
+ end
98
+
99
+ end
100
+
101
+ class NameParser
102
+
103
+ def initialize(node, expression)
104
+ @regexp = Regexp.new(expression)
105
+ end
106
+
107
+ def match(file)
108
+ filename = File.basename(file)
109
+ return @regexp.match(filename)
110
+ end
111
+
112
+ end
113
+
114
+ class XPazParser
115
+
116
+ def initialize(node, expression)
117
+ @resultList = node.elements["."].text
118
+ @xpath = expression
119
+ end
120
+
121
+ def match(file)
122
+ ario = rio("#{file}")
123
+ xmlString = ario.contents
124
+ xmldoc = REXML::Document.new(xmlString)
125
+ result = false
126
+ XPath.each(xmldoc, "#{@xpath}") do |el|
127
+ result = @resultList.include?(el.text)
128
+ break if result
129
+ end
130
+ return result
131
+ end
132
+
133
+ end
134
+
135
+ class SazParser
136
+
137
+ def initialize(node, expression)
138
+ @resultList = node.elements["."].text
139
+ @node = expression
140
+ end
141
+
142
+ def match(file)
143
+ result = "nil"
144
+ f = File.new(file)
145
+ parser = Parsers::SAX2Parser.new( f )
146
+ parser.listen( :characters , @node) do |text|
147
+ result = text if @resultList.include?(text)
148
+ end
149
+ parser.parse
150
+ return @resultList.include?(result)
151
+ end
152
+
153
+ end
154
+
155
+ end #module