arii 1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fa7fad175dce5a6ceb4352b89870f1c76ba33278
4
+ data.tar.gz: 90107e53cb008572777cbb78b6f7be7ae67cda87
5
+ SHA512:
6
+ metadata.gz: 02b6d28829dd27c53e133a0397e956f80e5b4b8c0e279169f52af8187ec35d0f9e455c305944590ffbb8c3959366a043cfcd38eab51bccc6bd77d29cc6015265
7
+ data.tar.gz: 9c6d6e4d09ff0dbba96cfa314cf6476816d95588e4660d66453d44586734133d3e4fb967a77a6b87a665d73efa78ab320fec2071b2cd07450ca7eaeca20d0c48
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in arii.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,17 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ arii (0.0.3)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ rake (10.1.1)
10
+
11
+ PLATFORMS
12
+ ruby
13
+
14
+ DEPENDENCIES
15
+ bundler (~> 1.5)
16
+ arii!
17
+ rake
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Pedro Lopes
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # ARiiP gem
2
+
3
+ Ruby `gem` for distributed client agents. This enables launching custom **ARiiP** agents.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'arii'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install arii
18
+
19
+ ## Usage
20
+
21
+ - Check **ARiiP**'s [client](http://github.com/pdrlps/arii-client)
22
+
23
+ ## Changelog
24
+
25
+ - 2015-01-14: Reload as arii-gem
26
+
27
+ ## Contributing
28
+
29
+ 1. Fork it ( http://github.com/pdrlps/arii-gem/fork )
30
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
31
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
32
+ 4. Push to the branch (`git push origin my-new-feature`)
33
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs << 'lib/arii'
8
+ t.test_files = FileList['test/lib/arii/*_test.rb']
9
+ t.verbose = true
10
+ end
11
+
12
+ task :default => :test
data/arii.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'arii/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "arii"
8
+ spec.version = ARII::VERSION
9
+ spec.authors = ["Pedro Lopes"]
10
+ spec.email = ["hello@pedrolopes.net"]
11
+ spec.summary = %q{arii client library for distributed agents.}
12
+ spec.description = %q{ARiiP: integrate everything. Automated real-time integration & interoperability platform.}
13
+ spec.homepage = "http://ariip.com/"
14
+ spec.license = "MIT"
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.5"
21
+ spec.add_development_dependency "rake", '~> 0'
22
+
23
+ spec.add_runtime_dependency 'rest-client', '~> 0'
24
+ spec.add_runtime_dependency 'nokogiri'
25
+ spec.add_runtime_dependency 'jsonpath', '~> 0'
26
+ end
data/lib/arii/agent.rb ADDED
@@ -0,0 +1,119 @@
1
+ require 'rest_client'
2
+
3
+ module ARII
4
+ class Agent
5
+ attr_accessor :content, :identifier, :publisher, :payload, :templates, :seeds, :cache, :selectors
6
+
7
+ def initialize agent
8
+ begin
9
+ @identifier = agent[:identifier]
10
+ @publisher = agent[:publisher]
11
+ @payload = agent[:payload]
12
+ @cache = agent[:payload][:cache]
13
+ @seeds = agent[:seeds]
14
+ @selectors = agent[:payload][:selectors]
15
+ ARII::Config.log.debug(self.class.name) {"Agent #{@identifier} initialized"}
16
+ rescue Exception => e
17
+ ARII::Config.log.error(self.class.name) {"Unable to initialize agent. #{e}"}
18
+ end
19
+
20
+ end
21
+
22
+
23
+ ##
24
+ # => Perform the actual agent monitoring tasks.
25
+ #
26
+ def execute
27
+ @checkup = {}
28
+
29
+ case @publisher
30
+ when 'sql'
31
+ begin
32
+ @d = ARII::SQLDetector.new(self)
33
+ rescue Exception => e
34
+ @response = {:status => 400, :error => e}
35
+ ARII::Config.log.error(self.class.name) {"#{e}"}
36
+ end
37
+ when 'csv'
38
+ begin
39
+ @d = ARII::CSVDetector.new(self)
40
+ rescue Exception => e
41
+ @response = {:status => 400, :error => e}
42
+ ARII::Config.log.error(self.class.name) {"#{e}"}
43
+ end
44
+ when 'xml'
45
+ begin
46
+ @d = ARII::XMLDetector.new(self)
47
+ rescue Exception => e
48
+ @response = {:status => 400, :error => e}
49
+ ARII::Config.log.error(self.class.name) {"#{e}"}
50
+ end
51
+ when 'json'
52
+ begin
53
+ @d = ARII::JSONDetector.new(self)
54
+ rescue Exception => e
55
+ @response = {:status => 400, :error => e}
56
+ ARII::Config.log.error(self.class.name) {"#{e}"}
57
+ end
58
+ end
59
+
60
+
61
+ # Start checkup
62
+ begin
63
+ unless content.nil? then
64
+ @d.content = content
65
+ end
66
+ @checkup = @d.checkup
67
+ rescue Exception => e
68
+ ARII::Config.log.error(self.class.name) {"Checkup error: #{e}"}
69
+ end
70
+
71
+ # Start detection
72
+ begin
73
+ @d.objects.each do |object|
74
+ @d.detect object
75
+ end
76
+
77
+ @checkup[:templates] = @d.templates.uniq
78
+ rescue Exception => e
79
+ ARII::Config.log.error(self.class.name) {"Detection error: #{e}"}
80
+ end
81
+
82
+ begin
83
+ if @checkup[:status] == 100 then
84
+ process @checkup
85
+ end
86
+ rescue Exception => e
87
+ ARII::Config.log.error(self.class.name) {"Process error: #{e}"}
88
+ end
89
+ response = {:status => @checkup[:status], :message => "[ARII][Checkup][execute] All OK."}
90
+ end
91
+
92
+
93
+
94
+ ##
95
+ # => Process agent checks.
96
+ #
97
+ def process checkup
98
+ begin
99
+ checkup[:templates].each do |template|
100
+ ARII::Config.log.info(self.class.name) {"Delivering to #{template} template."}
101
+ checkup[:payload].each do |payload|
102
+ ARII::Config.log.debug(self.class.name) {"Processing #{payload}."}
103
+ response = RestClient.post "#{ARII::Config.host}postman/deliver/#{template}.js", payload
104
+ case response.code
105
+ when 200
106
+
107
+ else
108
+ ARII::Config.log.warn(self.class.name) {"unable to deliver \"#{payload}\" to \"#{template}\""}
109
+ end
110
+ end
111
+ end
112
+ rescue Exception => e
113
+ ARII::Config.log.error(self.class.name) {"Processing error: #{e}"}
114
+ end
115
+
116
+ end
117
+ end
118
+
119
+ end
@@ -0,0 +1,28 @@
1
+ require 'rest_client'
2
+
3
+ module ARII
4
+ class Cashier
5
+ public
6
+
7
+ ##
8
+ # = Verify
9
+ # => Verify if items have already been seen in the past (on the cache).
10
+ #
11
+ # == Params
12
+ # - *cache*: the key identifier to be verified
13
+ # - *payload*: the value for matching/verification
14
+ # - *agent*: the agent performing the verification
15
+ # - *seed*: seed data (if available)
16
+ #
17
+ def self.verify cache, agent, payload, seed
18
+ ARII::Config.log.info(self.class.name) {"Verifying\n\taccess token: #{ARII::Config.access_token}\n\thost: #{ARII::Config.host}\n\tcache: #{cache}\n\tagent: #{agent}\n\tpayload: #{payload}\tseed: #{seed}"}
19
+ begin
20
+ response = RestClient.post "#{ARII::Config.host}fluxcapacitor/verify.json", {:access_token => ARII::Config.access_token, :agent => agent[:identifier], :cache => cache, :payload => payload, :seed => seed}
21
+ rescue Exception => e
22
+ ARII::Config.log.error(self.class.name) {"#{e}"}
23
+ response = {:status => 400, :error => e}
24
+ end
25
+ response
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,53 @@
1
+ require 'rest_client'
2
+
3
+ module ARII
4
+ class Client
5
+
6
+ ##
7
+ # => Load configuration properties from client/script code
8
+ #
9
+ def initialize config, log
10
+ begin
11
+ @config = config
12
+ ARII::Config.set_access_token config[:server][:api_key]
13
+ ARII::Config.set_host config[:server][:host]
14
+ ARII::Config.set_log log
15
+
16
+ ARII::Config.log.info(self.class.name) {'Configuration loaded successfully.'}
17
+ rescue Exception => e
18
+ ARII::Config.log.error(self.class.name) {"Failed to load configuration: #{e}"}
19
+ end
20
+
21
+ end
22
+
23
+ ##
24
+ # => Validate API key.
25
+ #
26
+ def validate
27
+ begin
28
+ ARII::Config.log.info(self.class.name) {'Launching validation.'}
29
+
30
+ out = RestClient.post "#{ARII::Config.host}fluxcapacitor/validate_key.json", {:access_token => ARII::Config.access_token}
31
+ response = {:status => 100, :response => out.to_str}
32
+ rescue Exception => e
33
+ ARII::Config.log.error(self.class.name) {"Failed validation: #{e}"}
34
+ end
35
+ response
36
+ end
37
+
38
+ ##
39
+ # => Start processing agents from configuration properties.
40
+ #
41
+ def process
42
+ ARII::Config.log.info(self.class.name) {'Starting agent processing.'}
43
+ begin
44
+ @config[:agents].each do |agent|
45
+ a = ARII::Agent.new agent
46
+ a.execute
47
+ end
48
+ rescue Exception => e
49
+ ARII::Config.log.error(self.class.name) {"Failed agent processing: #{e}"}
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,63 @@
1
+ require 'csv'
2
+ require 'open-uri'
3
+
4
+ module ARII
5
+
6
+ ##
7
+ # = CSVDetector
8
+ #
9
+ # Detect changes in CSV files (using column numbers).
10
+ #
11
+ class CSVDetector < Detector
12
+
13
+ public
14
+ ##
15
+ # == Detect the changes
16
+ #
17
+ def detect object
18
+
19
+ ARII::Config.log.debug(self.class.name) {"Monitoring #{object[:uri]}"}
20
+ CSV.new(open(object[:uri]), :headers => :first_row).each do |row|
21
+ begin
22
+ unless object[:cache].nil? then
23
+ @response = Cashier.verify row[object[:cache].to_i], object, row, object[:seed]
24
+ else
25
+ @response = Cashier.verify row[0], object, row, object[:seed]
26
+ end
27
+ rescue Exception => e
28
+ ARII::Config.log.error(self.class.name) {"Loading error: #{e}"}
29
+ end
30
+
31
+ begin
32
+
33
+ # Process ARIIcache response
34
+ @cache = JSON.parse(@response, {:symbolize_names => true})
35
+ unless @cache[:templates].nil? then
36
+ @cache[:templates].each do |t|
37
+ @templates.push t
38
+ end
39
+ end
40
+ # The actual processing
41
+ #
42
+ if @cache[:cache][:status] == 100 then
43
+ ARII::Config.log.info(self.class.name) {"Not on cache, generating payload"}
44
+
45
+ payload = Hash.new
46
+
47
+ object[:selectors].each do |selector|
48
+ selector.each do |k,v|
49
+ payload[k] = row[v.to_i]
50
+ end
51
+ end
52
+ # add payload object to payloads list
53
+ @payloads.push payload
54
+ end
55
+
56
+ rescue Exception => e
57
+ ARII::Config.log.error(self.class.name) {"Processing error: #{e}"}
58
+ end
59
+ @cache[:templates]
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,47 @@
1
+ require 'csv'
2
+
3
+ module ARII
4
+
5
+ # = CSVSeedReader
6
+ #
7
+ # Load content from CSV seed.
8
+ #
9
+ class CSVSeedReader < SeedReader
10
+ ##
11
+ # == Read
12
+ #
13
+ # => Load the seed data into the @objects array for processing.
14
+ #
15
+ def read
16
+ begin
17
+ CSV.new(open(@seed[:payload][:uri]), :headers => :first_row).each do |row|
18
+ begin
19
+ object = @help.deep_copy @agent[:payload]
20
+ object.each_pair do |key,value|
21
+ variables = @help.identify_variables(object[key])
22
+ variables.each do |v|
23
+ object[key].gsub!("%{#{v}}", row[@seed[:payload][:selectors][v].to_i])
24
+ end
25
+ end
26
+
27
+ unless @seed[:payload][:cache].nil? then
28
+ object[:seed] = row[@seed[:payload][:cache].to_i]
29
+ else
30
+ object[:seed] = row[0]
31
+ end
32
+
33
+
34
+ object[:identifier] = @agent.identifier
35
+ @objects.push object
36
+ rescue Exception => e
37
+
38
+ end
39
+ end
40
+ rescue Exception => e
41
+
42
+ end
43
+
44
+ @objects
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,113 @@
1
+ #require 'seedreader'
2
+ #require 'csvseedreader'
3
+ #require 'sqlseedreader'
4
+ #require 'xmlseedreader'
5
+ #require 'jsonseedreader'
6
+
7
+
8
+ module ARII
9
+
10
+ ##
11
+ # = Detector
12
+ #
13
+ # Main change detection class, to be inherited by SQL, CSV, JSON and XML detectors (and others to come).
14
+ #
15
+ class Detector
16
+ attr_accessor :identifier, :agent, :objects, :payloads, :content, :templates
17
+
18
+ def initialize agent
19
+ begin
20
+ @agent = agent
21
+ @payloads = Array.new
22
+ @objects = Array.new
23
+ @help = ARII::Helper.new
24
+ ARII::Config.log.info(self.class.name) {"Started new #{agent.identifier} detector"}
25
+ rescue Exception => e
26
+ ARII::Config.log.error(self.class.name) {"#{e}"}
27
+ end
28
+ end
29
+
30
+
31
+ ##
32
+ # == Start original source detection process
33
+ #
34
+ def checkup
35
+
36
+ begin
37
+
38
+
39
+ ##
40
+ # => Process seed data, if available.
41
+ #
42
+ unless @agent.seeds.nil? then
43
+ @agent.seeds.each do |seed|
44
+ case seed[:publisher]
45
+ when 'csv'
46
+ begin
47
+ @sr = ARII::CSVSeedReader.new(@agent, seed)
48
+ rescue Exception => e
49
+ ARII::Config.log.error(self.class.name) {"#{e}"}
50
+ end
51
+ when 'sql'
52
+ begin
53
+ @sr = ARII::SQLSeedReader.new(@agent, seed)
54
+ rescue Exception => e
55
+ ARII::Config.log.error(self.class.name) {"#{e}"}
56
+ end
57
+ when 'xml'
58
+ begin
59
+ @sr = ARII::XMLSeedReader.new(@agent, seed)
60
+ rescue Exception => e
61
+ ARII::Config.log.error(self.class.name) {"#{e}"}
62
+ end
63
+ when 'json'
64
+ begin
65
+ @sr = ARII::JSONSeedReader.new(@agent, seed)
66
+ rescue Exception => e
67
+ ARII::Config.log.error(self.class.name) {"#{e}"}
68
+ end
69
+ end
70
+ begin
71
+ @reads = @sr.read
72
+ @reads.each do |read|
73
+ @objects.push read
74
+ end
75
+ rescue Exception => e
76
+ ARII::Config.log.error(self.class.name) {"#{e}"}
77
+ end
78
+ end
79
+
80
+ else
81
+ ##
82
+ # no seeds, simply copy agent data
83
+ object = @help.deep_copy @agent.payload
84
+ object[:identifier] = @agent.identifier
85
+ object[:cache] = @agent.cache
86
+ object[:seed] = object[:identifier]
87
+ object[:selectors] = @agent.selectors
88
+ unless self.content.nil? then
89
+ object[:content] = self.content
90
+ end
91
+ @objects.push object
92
+ end
93
+ rescue Exception => e
94
+ @response = {:status => 404, :message => "[ARII][Detector] failed to load doc, #{e}"}
95
+ ARII::Config.log.error(self.class.name) {"#{e}"}
96
+ end
97
+
98
+ begin
99
+ # increase detected events count
100
+
101
+
102
+ @templates = Array.new
103
+ @response = { :payload => @payloads, :templates => @templates, :status => 100}
104
+ rescue Exception => e
105
+ @response = {:status => 404, :message => "[ARII][Detector] failed to process queries, #{e}"}
106
+ ARII::Config.log.error(self.class.name) {"#{e}"}
107
+ end
108
+ @response
109
+ end
110
+
111
+
112
+ end
113
+ end
@@ -0,0 +1,152 @@
1
+
2
+ module ARII
3
+
4
+ ##
5
+ # = Helper Class
6
+ # => Miscellaneous helper methods and utils to deal with data.
7
+ #
8
+ class Helper
9
+ attr_accessor :replacements
10
+ @replacements
11
+
12
+ def initialize
13
+ # load each helper function into a map for replacement in the delivery
14
+ @replacements = [ ["%{ARII.date}", self.date], ["%{ARII.datetime}", self.datetime], ["%{ARII.hostname}", self.hostname]]
15
+ end
16
+
17
+ public
18
+ def hostname
19
+ ENV["APP_HOST"]
20
+ end
21
+
22
+ def datetime
23
+ Time.now.to_s
24
+ end
25
+
26
+ def date
27
+ Time.now.strftime("%Y-%m-%d").to_s
28
+ end
29
+
30
+ ##
31
+ # == Identify Variables
32
+ # => Identifies variables on string set, generates array with all scanned variables for processing.
33
+ # => Variables are enclosed in %{variable} string.
34
+ #
35
+ # * +text+ - string to be scanned
36
+ #
37
+ def identify_variables text
38
+ begin
39
+ results = Array.new
40
+ text.scan(/%{(.*?)}/).each do |m|
41
+ results.push m[0]
42
+ end
43
+ rescue Exception => e
44
+
45
+ end
46
+
47
+ results
48
+ end
49
+
50
+ ##
51
+ # == Validate payload
52
+ # => Validates content payload.
53
+ #
54
+ # + *publisher* - for publisher-specific validations
55
+ # + *payload* - content for validation
56
+ #
57
+ def self.validate_payload publisher, payload
58
+ @database_servers = ["mysql","sqlite","postgresql"]
59
+ valid = true
60
+
61
+ begin
62
+ case publisher
63
+ when 'csv', 'xml', 'json', 'file', 'js'
64
+ # file content URI is mandatory
65
+ if payload[:uri].nil? then
66
+ valid = false
67
+ end
68
+ when 'sql'
69
+
70
+ # check if database server is available
71
+ unless database_servers.include? payload[:server] then
72
+ valid = false
73
+ end
74
+
75
+ # database username is mandatory
76
+ if payload[:username].nil? then
77
+ valid = false
78
+ end
79
+
80
+ # database user password is mandatory
81
+ if payload[:password].nil? then
82
+ valid = false
83
+ end
84
+
85
+ # database name is mandatory
86
+ if payload[:database].nil? then
87
+ valid = false
88
+ end
89
+
90
+ # database query is mandatory
91
+ if payload[:query].nil? then
92
+ valid = false
93
+ end
94
+ end
95
+ rescue Exception => e
96
+
97
+ end
98
+ valid
99
+ end
100
+
101
+ ##
102
+ # == Validate Seed
103
+ # => Validates Seed-specific properties
104
+ #
105
+ # + *publisher* - for publisher-specific validations
106
+ # + *seed* - the seed hash
107
+ #
108
+ def self.validate_seed publisher, seed
109
+ begin
110
+ valid = self.validate_payload publisher, seed
111
+ if valid then
112
+ # seed must have selectors
113
+ if seed[:selectors].nil? then
114
+ valid = false
115
+ end
116
+ else
117
+ valid = false
118
+ end
119
+ rescue Exception => e
120
+
121
+ end
122
+
123
+ valid
124
+ end
125
+
126
+ ##
127
+ # == Validate Agent
128
+ # => Validates Agent-specific properties
129
+ #
130
+ # + *agent* - the agent for validation
131
+ #
132
+ def self.validate_agent
133
+ begin
134
+ valid = self.validate_seed(agent[:publisher], agent[:payload]) && self.validate_payload(agent[:publisher], agent[:payload])
135
+ rescue Exception => e
136
+
137
+ end
138
+
139
+ valid
140
+ end
141
+
142
+ ##
143
+ # == Copy Object/Hash/Array...
144
+ # => Copies any object into new object (overcome references).
145
+ #
146
+ # + *o* - the object being copied
147
+ #
148
+ def deep_copy object
149
+ Marshal.load(Marshal.dump(object))
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,67 @@
1
+ require 'open-uri'
2
+ require 'jsonpath'
3
+ require 'rest_client'
4
+ require 'json'
5
+
6
+ module ARII
7
+
8
+ # = JSONDetector
9
+ #
10
+ # Detect changes in JSON content files (uses JSONPath).
11
+ #
12
+ class JSONDetector < Detector
13
+
14
+ public
15
+
16
+ ##
17
+ # == Detect the changes
18
+ #
19
+ def detect object
20
+ ARII::Config.log.info(self.class.name) {"Monitoring #{object[:uri]}"} unless object[:uri].nil?
21
+
22
+ begin
23
+ if object[:uri] == '' then
24
+ @doc = object[:content]
25
+ else
26
+ url = RestClient.get object[:uri]
27
+ @doc = url.to_str
28
+ end
29
+ JsonPath.on(@doc,object[:query]).each do |element|
30
+ JsonPath.on(element, object[:cache]).each do |c|
31
+ @response = Cashier.verify c, object, c, object[:seed]
32
+ end
33
+
34
+ # Process ARII cache response
35
+ @cache = JSON.parse(@response, {:symbolize_names => true})
36
+ unless @cache[:templates].nil? then
37
+ @cache[:templates].each do |t|
38
+ @templates.push t
39
+ end
40
+ end
41
+
42
+ ##
43
+ # If not on cache, add to payload for processing
44
+ #
45
+ if @cache[:status] == 100 then
46
+ ARII::Config.log.info(self.class.name) {"Not on cache, generating payload"}
47
+ # add row data to payload from selectors (key => key, value => column name)
48
+ payload = Hash.new
49
+ object[:selectors].each do |selector|
50
+ selector.each do |k,v|
51
+ JsonPath.on(element, v).each do |el|
52
+ payload[k] = el
53
+ end
54
+ end
55
+ end
56
+ # add payload object to payloads list
57
+ @payloads.push payload
58
+ end
59
+
60
+ end
61
+ rescue Exception => e
62
+ ARII::Config.log.error(self.class.name) {"Loading error: #{e}"}
63
+ end
64
+ @cache[:templates]
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,52 @@
1
+ require 'json'
2
+
3
+ module ARII
4
+
5
+ # = JSONSeedReader
6
+ #
7
+ # Load content from JSON seed.
8
+ #
9
+ class JSONSeedReader < SeedReader
10
+ ##
11
+ # == Read
12
+ #
13
+ # => Load the seed data into the @objects array for processing.
14
+ #
15
+ def read
16
+ begin
17
+ url = RestClient.get @seed[:payload][:uri]
18
+ @doc = url.to_str
19
+ JsonPath.on(@doc,@seed[:payload][:query]).each do |element|
20
+
21
+ begin
22
+ object = @help.deep_copy @agent[:payload]
23
+ object.each_pair do |key,value|
24
+ variables = @help.identify_variables(object[key])
25
+ variables.each do |v|
26
+
27
+ JsonPath.on(element, @seed[:payload][:selectors][v]).each do |el|
28
+
29
+ object[key].gsub!("%{#{v}}", el.to_s)
30
+ end
31
+ end
32
+ end
33
+
34
+ JsonPath.on(element,@seed[:payload][:cache]).each do |el|
35
+ object[:seed] = el
36
+
37
+ end
38
+
39
+ object[:identifier] = @agent.identifier
40
+ @objects.push object
41
+ rescue Exception => e
42
+
43
+ end
44
+ end
45
+ rescue Exception => e
46
+
47
+ end
48
+
49
+ @objects
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,21 @@
1
+ #require 'helper'
2
+
3
+ module ARII
4
+
5
+ ##
6
+ # = Seed Reader
7
+ #
8
+ # Main seed reading class, passing data for seeds to agent, to be inherited by SQL, File and URL templates
9
+ #
10
+ class SeedReader
11
+ attr_accessor :seed, :objects, :agent
12
+
13
+ def initialize agent, seed
14
+ @agent = agent
15
+ @help = ARII::Helper.new
16
+ @seed = seed
17
+ @objects = Array.new
18
+ puts "\t\tSeed: #{@seed[:identifier]}"
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,57 @@
1
+ #require 'helper'
2
+ require 'mysql2'
3
+
4
+ module ARII
5
+
6
+ ##
7
+ # = SQLDetector
8
+ #
9
+ # Detec changes in SQL databases. MySQL support only.
10
+ #
11
+ class SQLDetector < Detector
12
+
13
+ public
14
+ ##
15
+ # == Detect the changes
16
+ #
17
+ def detect object
18
+ ARII::Config.log.debug(self.class.name) {"Monitoring #{object[:host]}"}
19
+ begin
20
+ @client = Mysql2::Client.new(:host => object[:host], :username => object[:username] , :password => object[:password] , :database => object[:database])
21
+ @client.query(@agent[:payload][:query]).each(:symbolize_keys => false) do |row|
22
+ unless object[:cache].nil? then
23
+ @response = Cashier.verify row[object[:cache]], object, row, object[:seed]
24
+ else
25
+ @response = Cashier.verify row["id"], object, row, object[:seed]
26
+ end
27
+
28
+ # Process ARII cache response
29
+ @cache = JSON.parse(@response, {:symbolize_names => true})
30
+ unless @cache[:templates].nil? then
31
+ @cache[:templates].each do |t|
32
+ @templates.push t
33
+ end
34
+ end
35
+
36
+ # The actual processing
37
+ #
38
+ if @cache[:status] == 100 then
39
+ ARII::Config.log.info(self.class.name) {"Not on cache, generating payload"}
40
+ # add row data to payload from selectors (key => key, value => column name)
41
+ payload = Hash.new
42
+ object[:selectors].each do |selector|
43
+ selector.each do |k,v|
44
+ payload[k] = row[v]
45
+ end
46
+ end
47
+ # add payload object to payloads list
48
+ @payloads.push payload
49
+ end
50
+ end
51
+ rescue Exception => e
52
+ ARII::Config.log.error(self.class.name) {"Processing error: #{e}"}
53
+ end
54
+ @cache[:templates]
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,46 @@
1
+ require 'mysql2'
2
+
3
+ module Services
4
+
5
+ # = SQLSeedReader
6
+ #
7
+ # Load content from SQL seed.
8
+ #
9
+ class SQLSeedReader < SeedReader
10
+ ##
11
+ # == Read
12
+ #
13
+ # => Load the seed data into the @objects array for processing.
14
+ #
15
+ def read
16
+ begin
17
+ @client = Mysql2::Client.new(:host => @seed[:payload][:host], :username => @seed[:payload][:username] , :password => @seed[:payload][:password] , :database => @seed[:payload][:database])
18
+ @client.query(@seed[:payload][:query], :cast => false).each(:symbolize_keys => false) do |row|
19
+ begin
20
+ object = @help.deep_copy @agent[:payload]
21
+ object.each_pair do |key,value|
22
+ variables = @help.identify_variables(object[key])
23
+ variables.each do |v|
24
+ object[key].gsub!("%{#{v}}", row[@seed[:payload][:selectors][v]].to_str)
25
+ end
26
+ end
27
+
28
+ unless @seed[:payload][:cache].nil? then
29
+ object[:seed] = row[@seed[:payload][:cache]]
30
+ else
31
+ object[:seed] = row["id"]
32
+ end
33
+ object[:identifier] = @agent.identifier
34
+ @objects.push object
35
+ rescue Exception => e
36
+
37
+ end
38
+ end
39
+ rescue Exception => e
40
+
41
+ end
42
+
43
+ @objects
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,3 @@
1
+ module ARII
2
+ VERSION = "1.0"
3
+ end
@@ -0,0 +1,62 @@
1
+ require 'open-uri'
2
+
3
+ module ARII
4
+
5
+ # = XMLDetector
6
+ #
7
+ # Detect changes in XML files (uses XPath).
8
+ #
9
+ class XMLDetector < Detector
10
+
11
+ public
12
+ ##
13
+ # == Detect the changes
14
+ #
15
+ def detect object
16
+ ARII::Config.log.info(self.class.name) {"Monitoring #{object[:uri]}"} unless object[:uri].nil?
17
+ begin
18
+ if object[:uri] == '' then
19
+ @doc = Nokogiri::XML(object[:content])
20
+ else
21
+ @doc = Nokogiri::XML(open(object[:uri]))
22
+ end
23
+ @doc.remove_namespaces!
24
+ @doc.xpath(object[:query]).each do |element|
25
+ element.xpath(object[:cache]).each do |c|
26
+ @response = Cashier.verify c.content, object, c.content, object[:seed]
27
+ end
28
+
29
+ # Process ARII cache response
30
+ @cache = JSON.parse(@response, {:symbolize_names => true})
31
+ unless @cache[:templates].nil? then
32
+ @cache[:templates].each do |t|
33
+ @templates.push t
34
+ end
35
+ end
36
+
37
+ ##
38
+ # If not on cache, add to payload for processing
39
+ #
40
+ if @cache[:status] == 100 then
41
+ ARII::Config.log.info(self.class.name) {"Not on cache, generating payload"}
42
+ # add row data to payload from selectors (key => key, value => column name)
43
+ payload = Hash.new
44
+ object[:selectors].each do |selector|
45
+
46
+ selector.each do |k,v|
47
+ element.xpath(v).each do |el|
48
+ payload[k] = el.content
49
+ end
50
+ end
51
+ end
52
+ # add payload object to payloads list
53
+ @payloads.push payload
54
+
55
+ end
56
+ end
57
+ end
58
+ rescue Exception => e
59
+ ARII::Config.log.error(self.class.name) {"Processing error: #{e}"}
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,52 @@
1
+ module ARII
2
+
3
+ # = XMLSeedReader
4
+ #
5
+ # Load content from XML seed.
6
+ #
7
+ class XMLSeedReader < SeedReader
8
+ ##
9
+ # == Read
10
+ #
11
+ # => Load the seed data into the @objects array for processing.
12
+ #
13
+ def read
14
+ begin
15
+ @doc = Nokogiri::XML(open(@seed[:payload][:uri]))
16
+ @doc.remove_namespaces!
17
+ @doc.xpath(@seed[:payload][:query]).each do |element|
18
+ begin
19
+ object = @help.deep_copy @agent[:payload]
20
+ object.each_pair do |key,value|
21
+ variables = @help.identify_variables(object[key])
22
+ variables.each do |v|
23
+ element.xpath(@seed[:payload][:selectors][v]).each do |el|
24
+ object[key].gsub!("%{#{v}}", el.content)
25
+ end
26
+ end
27
+ end
28
+
29
+ unless @seed[:payload][:cache].nil? then
30
+ element.xpath(@seed[:payload][:cache]).each do |el|
31
+ object[:seed] = el.content
32
+ end
33
+ else
34
+ element.xpath('id').each do |el|
35
+ object[:seed] = el.content
36
+ end
37
+ end
38
+
39
+ object[:identifier] = @agent.identifier
40
+ @objects.push object
41
+ rescue Exception => e
42
+
43
+ end
44
+ end
45
+ rescue Exception => e
46
+
47
+ end
48
+
49
+ @objects
50
+ end
51
+ end
52
+ end
data/lib/arii.rb ADDED
@@ -0,0 +1,43 @@
1
+ require 'logger'
2
+ require 'arii/cashier'
3
+ require 'arii/helper'
4
+ require 'arii/detector'
5
+ require 'arii/csvdetector'
6
+ require 'arii/jsondetector'
7
+ require 'arii/sqldetector'
8
+ require 'arii/xmldetector'
9
+ require 'arii/agent'
10
+ require 'arii/version'
11
+ require 'arii/client'
12
+
13
+ module ARII
14
+ class Config
15
+
16
+
17
+
18
+ def self.set_log log
19
+ @@log = log
20
+ end
21
+
22
+ def self.set_host host
23
+ host << '/' unless host.end_with?('/')
24
+ @@host = host
25
+ end
26
+
27
+ def self.set_access_token api_key
28
+ @@access_token = api_key
29
+ end
30
+
31
+ def self.log
32
+ @@log
33
+ end
34
+
35
+ def self.host
36
+ @@host
37
+ end
38
+
39
+ def self.access_token
40
+ @@access_token
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,9 @@
1
+ require_relative '../../test_helper'
2
+
3
+ describe ARII do
4
+
5
+ it "must be defined" do
6
+ ARII::VERSION.wont_be_nil
7
+ end
8
+
9
+ end
@@ -0,0 +1,4 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/pride'
3
+
4
+ require File.expand_path('../../lib/arii.rb', __FILE__)
metadata ADDED
@@ -0,0 +1,142 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: arii
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ platform: ruby
6
+ authors:
7
+ - Pedro Lopes
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rest-client
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: nokogiri
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: jsonpath
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: 'ARiiP: integrate everything. Automated real-time integration & interoperability
84
+ platform.'
85
+ email:
86
+ - hello@pedrolopes.net
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - Gemfile
93
+ - Gemfile.lock
94
+ - LICENSE
95
+ - README.md
96
+ - Rakefile
97
+ - arii.gemspec
98
+ - lib/arii.rb
99
+ - lib/arii/agent.rb
100
+ - lib/arii/cashier.rb
101
+ - lib/arii/client.rb
102
+ - lib/arii/csvdetector.rb
103
+ - lib/arii/csvseedreader.rb
104
+ - lib/arii/detector.rb
105
+ - lib/arii/helper.rb
106
+ - lib/arii/jsondetector.rb
107
+ - lib/arii/jsonseedreader.rb
108
+ - lib/arii/seedreader.rb
109
+ - lib/arii/sqldetector.rb
110
+ - lib/arii/sqlseedreader.rb
111
+ - lib/arii/version.rb
112
+ - lib/arii/xmldetector.rb
113
+ - lib/arii/xmlseedreader.rb
114
+ - test/lib/i2x/version_test.rb
115
+ - test/test_helper.rb
116
+ homepage: http://ariip.com/
117
+ licenses:
118
+ - MIT
119
+ metadata: {}
120
+ post_install_message:
121
+ rdoc_options: []
122
+ require_paths:
123
+ - lib
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ required_rubygems_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ requirements: []
135
+ rubyforge_project:
136
+ rubygems_version: 2.4.5
137
+ signing_key:
138
+ specification_version: 4
139
+ summary: arii client library for distributed agents.
140
+ test_files:
141
+ - test/lib/i2x/version_test.rb
142
+ - test/test_helper.rb