factor-connector-api 0.0.1

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.
@@ -0,0 +1,20 @@
1
+ # encoding: UTF-8
2
+
3
+ # DSL for building actions
4
+ module Factor
5
+ module Connector
6
+ class ActionBuilder
7
+ def initialize(id, &block)
8
+ @id = id.to_s
9
+ @start = block
10
+ end
11
+
12
+ def build
13
+ ad = ActionDefinition.new
14
+ ad.id = @id
15
+ ad.start = @start
16
+ ad
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: UTF-8
2
+
3
+ # DSL for building listeners
4
+ module Factor
5
+ module Connector
6
+ class ListenerBuilder
7
+ def initialize(id, &block)
8
+ @id = id.to_s
9
+ instance_eval(&block) if block
10
+ end
11
+
12
+ def start(&code)
13
+ @start = code
14
+ end
15
+
16
+ def stop(&code)
17
+ @stop = code
18
+ end
19
+
20
+ def build
21
+ ld = ListenerDefinition.new
22
+ ld.id = @id
23
+ ld.start = @start
24
+ ld.stop = @stop
25
+ ld
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,33 @@
1
+ # encoding: UTF-8
2
+
3
+ # DSL for building services
4
+ module Factor
5
+ module Connector
6
+ class ServiceBuilder
7
+ def initialize(id, &block)
8
+ @listeners = {}
9
+ @actions = {}
10
+ @id = id.to_s
11
+ instance_eval(&block) if block
12
+ end
13
+
14
+ def listener(id, &block)
15
+ listener = ListenerBuilder.new(id, &block).build
16
+ @listeners[listener.id] = listener
17
+ end
18
+
19
+ def action(id, &block)
20
+ action = ActionBuilder.new(id, &block).build
21
+ @actions[action.id] = action
22
+ end
23
+
24
+ def build
25
+ sd = ServiceDefinition.new
26
+ sd.listeners = @listeners
27
+ sd.actions = @actions
28
+ sd.id = @id
29
+ sd
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: UTF-8
2
+
3
+ # DSL for creating web hooks
4
+ module Factor
5
+ module Connector
6
+ class WebHookBuilder
7
+ def initialize(vals = {}, &block)
8
+ @id = vals[:id].to_s
9
+ @method = vals[:method] || 'POST'
10
+ instance_eval(&block) if block
11
+ end
12
+
13
+ def id(val)
14
+ @id = val.to_s
15
+ end
16
+
17
+ def method(val)
18
+ @method = val
19
+ end
20
+
21
+ def start(&code)
22
+ @start = code
23
+ end
24
+
25
+ def build
26
+ wd = WebHookDefinition.new
27
+ wd.id = @id
28
+ wd.method = @method
29
+ wd.start = @start
30
+ wd
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: UTF-8
2
+
3
+ # action definition as defined by DSL
4
+ class ActionDefinition
5
+ attr_accessor :id, :start
6
+
7
+ def initialize
8
+ end
9
+
10
+ def to_hash
11
+ {
12
+ id: @id
13
+ }
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: UTF-8
2
+
3
+ # Listener definition as defined by DSL
4
+ class ListenerDefinition
5
+ attr_accessor :id, :start, :stop, :web_hooks
6
+
7
+ def initialize
8
+ @web_hooks = {}
9
+ end
10
+
11
+ def to_hash
12
+ {
13
+ id: @id
14
+ }
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: UTF-8
2
+
3
+ # Definition of service as defined by DSL
4
+ class ServiceDefinition
5
+ attr_accessor :id, :listeners, :actions
6
+
7
+ def initialize
8
+ @listeners = {}
9
+ @actions = {}
10
+ end
11
+
12
+ def to_hash
13
+ {
14
+ id: @id,
15
+ listeners: @listeners.map { |k, v| v.to_hash },
16
+ actions: @actions.map { |k, v| v.to_hash },
17
+ }
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ # web hook definition as generated by DSL
4
+ class WebHookDefinition
5
+ attr_accessor :id, :method, :start
6
+
7
+ def to_hash
8
+ {
9
+ id: @id,
10
+ method: @method
11
+ }
12
+ end
13
+ end
data/lib/errors.rb ADDED
@@ -0,0 +1,14 @@
1
+ # encoding: UTF-8
2
+
3
+ module Factor
4
+ module Connector
5
+ class Error < StandardError
6
+ attr_accessor :state, :exception
7
+
8
+ def initialize(params = {})
9
+ @exception = params[:exception]
10
+ super(params[:message] || '')
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,24 @@
1
+ require_relative './service_manager.rb'
2
+
3
+ module Factor
4
+ module Connector
5
+ @@service_managers={}
6
+
7
+ def self.load(filename)
8
+ service_manager = Factor::Connector::ServiceManager.load(filename)
9
+ service_id = service_manager.definition.id
10
+ @@service_managers[service_id] = service_manager
11
+ end
12
+
13
+ def self.service(id, &block)
14
+ service_manager = Factor::Connector::ServiceManager.new
15
+ service_manager.service(id,&block)
16
+ @@service_managers[id] = service_manager
17
+ end
18
+
19
+ def self.get_service_manager(service_id)
20
+ @@service_managers[service_id]
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,32 @@
1
+
2
+ require_relative './instance.rb'
3
+
4
+ module Factor
5
+ module Connector
6
+ class ActionInstance < Factor::Connector::Instance
7
+ include Celluloid
8
+ attr_accessor :service_id
9
+
10
+ def start(params)
11
+ begin
12
+ self.instance_exec params, &@definition.start
13
+ rescue Factor::Connector::Error => ex
14
+ respond type:'fail', message:ex.message
15
+ exception ex.exception,params:params if ex.exception
16
+ rescue => ex
17
+ respond type:'fail', message:"Couldn't run action for unexpected reason. We've been informed and looking into it."
18
+ exception ex,params:params
19
+ end
20
+ end
21
+
22
+ def action_callback(params={})
23
+ respond type:'return', payload:params
24
+ end
25
+
26
+ def fail(message,params={})
27
+ respond type:'fail', message: message
28
+ raise Factor::Connector::Error, exception:params[:exception], message:message if !params[:throw]
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,84 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'addressable/uri'
4
+ require 'zip/zipfilesystem'
5
+ require 'rubygems/package'
6
+ require 'zlib'
7
+ require 'open-uri'
8
+ require 'fileutils'
9
+
10
+ require_relative '../errors.rb'
11
+
12
+ module Factor
13
+ module Connector
14
+ class Instance
15
+ attr_accessor :definition, :callback, :instance_id
16
+
17
+ def initialize(options = {})
18
+ @definition = options[:definition] if options[:definition]
19
+ end
20
+
21
+ def callback=(block)
22
+ @callback = block if block
23
+ end
24
+
25
+ def respond(params)
26
+ @callback.call(params) if @callback
27
+ end
28
+
29
+ def id
30
+ @definition.id
31
+ end
32
+
33
+ def info(message)
34
+ log 'info', message
35
+ end
36
+
37
+ def error(message)
38
+ log 'error', message
39
+ end
40
+
41
+ def warn(message)
42
+ log 'warn', message
43
+ end
44
+
45
+ def debug(message)
46
+ log 'debug', message
47
+ end
48
+
49
+ def log(status, message)
50
+ respond type: 'log', status: status, message: message
51
+ end
52
+
53
+ protected
54
+
55
+ def exception(ex, parameters = {})
56
+ debug "exception: #{ex.message}"
57
+ debug 'backtrace:'
58
+ ex.backtrace.each do |line|
59
+ debug " #{line}"
60
+ end
61
+ debug "parameters: #{parameters}"
62
+ end
63
+
64
+ private
65
+
66
+ def targz_to_zip(file)
67
+ stringio = Zip::ZipOutputStream.write_buffer do |zipio|
68
+ Gem::Package::TarReader.new(Zlib::GzipReader.open(file.path)) do |tar|
69
+ tar.each do |entry|
70
+ zipio.put_next_entry entry.full_name
71
+ zipio.write entry.read
72
+ end
73
+ end
74
+
75
+ end
76
+ stringio.rewind
77
+ file = File.new(file.path.gsub(/.gz/, '.zip').gsub(/.tar/, ''), 'w+')
78
+ file.write stringio.read
79
+ file.rewind
80
+ file
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,95 @@
1
+ # encoding: UTF-8
2
+
3
+ require_relative './instance.rb'
4
+
5
+
6
+ module Factor
7
+ module Connector
8
+ class ListenerInstance < Factor::Connector::Instance
9
+ include Celluloid
10
+ attr_accessor :web_hooks, :service_id
11
+
12
+ def initialize(options = {})
13
+ @web_hooks = {}
14
+ super(options)
15
+ end
16
+
17
+ def start(params)
18
+ @params = params
19
+
20
+ begin
21
+ instance_exec @params, &@definition.start if @definition && @definition.start
22
+ respond type: 'return'
23
+ rescue Factor::Connector::Error => ex
24
+ error ex.message
25
+ respond type: 'fail'
26
+ exception ex.exception, params: @params if ex.exception
27
+ rescue => ex
28
+ error "Couldn't start listener for unexpected reason. We've been informed and looking into it."
29
+ respond type: 'fail'
30
+ exception ex, params: @params
31
+ end
32
+ end
33
+
34
+ def stop
35
+ begin
36
+ instance_exec @params, &@definition.stop if @definition && @definition.stop
37
+ respond type: 'stopped'
38
+ rescue Factor::Connector::Error => ex
39
+ error ex.message
40
+ respond type: 'fail'
41
+ exception ex.exception, params: @params if ex.exception
42
+ rescue ex
43
+ error "Couldn't stop listener for unexpected reason. We've been informed and looking into it."
44
+ respond type: 'fail'
45
+ exception ex, params: @params
46
+ end
47
+ end
48
+
49
+ def start_workflow(params)
50
+ @callback.call(type: 'start_workflow', payload: params) if @callback
51
+ end
52
+
53
+ def call_web_hook(web_hook_id, hook_params, request, response)
54
+ web_hook = @web_hooks[web_hook_id]
55
+ begin
56
+ self.instance_exec @params, hook_params, request, response, &web_hook.start
57
+ rescue Factor::Connector::Error => ex
58
+ error ex.message
59
+ exception ex.exception, params: hook_params, hook_id: web_hook_id if ex.exception
60
+ rescue => ex
61
+ error "Couldn't call webhook for unexpected reason. We've been informed and looking into it."
62
+ exception ex, params: @params
63
+ end
64
+ end
65
+
66
+ def web_hook(vals = {}, &block)
67
+ web_hook = WebHookBuilder.new(vals, &block).build
68
+ @web_hooks[web_hook.id] = web_hook
69
+ hook_url(@service_id, self.id, @instance_id, web_hook.id)
70
+ end
71
+
72
+ def get_web_hook(web_hook_id)
73
+ hook_url(@service_id, self.id, @instance_id, web_hook_id)
74
+ end
75
+
76
+ def fail(message, params = {})
77
+ raise Factor::Connector::Error, exception: params[:exception], message: message
78
+ end
79
+
80
+ private
81
+
82
+ def hook_url(service_id, listener_id, instance_id, web_hook_id)
83
+ scheme = ENV['RACK_ENV'] == 'production' ? 'https' : 'http'
84
+ host = ENV['CONNECTOR_HOST'] || 'localhost:9294'
85
+ service_path = "/v0.4/#{service_id}"
86
+ listener_path = "/listeners/#{listener_id}"
87
+ instance_path = "/instances/#{instance_id}"
88
+ hooks_path = "/hooks/#{web_hook_id}"
89
+ path = service_path + listener_path + instance_path + hooks_path
90
+
91
+ "#{scheme}://#{host}#{path}"
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,81 @@
1
+ require 'celluloid'
2
+
3
+ require 'definitions/action_definition'
4
+ require 'definitions/listener_definition'
5
+ require 'definitions/service_definition'
6
+ require 'definitions/web_hook_definition'
7
+
8
+ require 'builders/action_builder'
9
+ require 'builders/listener_builder'
10
+ require 'builders/service_builder'
11
+ require 'builders/web_hook_builder'
12
+
13
+ require 'instances/instance'
14
+ require 'instances/action_instance'
15
+ require 'instances/listener_instance'
16
+
17
+ module Factor
18
+ module Connector
19
+ class ServiceInstance < Factor::Connector::Instance
20
+ attr_accessor :definition, :step_data, :callback, :listener_instances, :action_instances
21
+
22
+ def initialize(options = {})
23
+ @listener_instances = {}
24
+ @action_instances = {}
25
+ @instance_id = SecureRandom.hex
26
+ super(options)
27
+ end
28
+
29
+ def call_hook(listener_id,hook_id,data,request,response)
30
+ listener_instance = @listener_instances[listener_id]
31
+ listener_instance.async.call_web_hook(hook_id,data,request,response)
32
+ end
33
+
34
+ def call_action(action_id,params)
35
+ action_instance = ActionInstance.new
36
+ action_instance.service_id = self.id
37
+ action_instance.instance_id = @instance_id
38
+ action_instance.definition = @definition.actions[action_id]
39
+ action_instance.callback = @callback
40
+ action_instances[action_id] = action_instance
41
+ action_instance.async.start(params)
42
+ end
43
+
44
+ def start_listener(listener_id,params)
45
+ listener_instance = ListenerInstance.new
46
+ listener_instance.service_id = self.id
47
+ listener_instance.instance_id = @instance_id
48
+ listener_instance.definition = @definition.listeners[listener_id]
49
+ listener_instance.callback = @callback
50
+ @listener_instances[listener_id]=listener_instance
51
+ listener_instance.async.start(params)
52
+ end
53
+
54
+ def stop_listener(listener_id)
55
+ if !@listener_instances[listener_id]
56
+ warn "Listener isn't running, no need to stop"
57
+ respond type:'stopped'
58
+ else
59
+ @listener_instances[listener_id].stop
60
+ @listener_instances[listener_id].terminate
61
+ @listener_instances.delete listener_id
62
+ end
63
+ end
64
+
65
+ def stop_action(action_id)
66
+ if @action_instances[action_id]
67
+ @action_instances[action_id].terminate
68
+ @action_instances.delete action_id
69
+ end
70
+ end
71
+
72
+ def has_action?(action_id)
73
+ @definition.actions.include?(action_id)
74
+ end
75
+
76
+ def has_listener?(listener_id)
77
+ @definition.listeners.include?(listener_id)
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: UTF-8
2
+
3
+ Dir.glob('./lib/definitions/*.rb') { |p| require p }
4
+ Dir.glob('./lib/builders/*.rb') { |p| require p }
5
+ require_relative './instances/service_instance.rb'
6
+ # require 'instances/service_instance'
7
+
8
+ module Factor
9
+ module Connector
10
+ class ServiceManager
11
+ attr_accessor :definition
12
+
13
+ def service(id, &block)
14
+ @definition = Factor::Connector::ServiceBuilder.new(id, &block).build
15
+ end
16
+
17
+ def instance
18
+ instance = Factor::Connector::ServiceInstance.new(definition: @definition)
19
+ instance
20
+ end
21
+
22
+ def self.load(filename)
23
+ dsl = new
24
+ dsl.instance_eval(File.read(filename))
25
+ dsl
26
+ end
27
+ end
28
+ end
29
+ end
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: factor-connector-api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Maciej Skierkowski
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-09-30 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Timer Factor.io Connector
15
+ email:
16
+ - maciej@factor.io
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - ./lib/builders/action_builder.rb
22
+ - ./lib/builders/listener_builder.rb
23
+ - ./lib/builders/service_builder.rb
24
+ - ./lib/builders/web_hook_builder.rb
25
+ - ./lib/definitions/action_definition.rb
26
+ - ./lib/definitions/listener_definition.rb
27
+ - ./lib/definitions/service_definition.rb
28
+ - ./lib/definitions/web_hook_definition.rb
29
+ - ./lib/errors.rb
30
+ - ./lib/factor-connector-api.rb
31
+ - ./lib/instances/action_instance.rb
32
+ - ./lib/instances/instance.rb
33
+ - ./lib/instances/listener_instance.rb
34
+ - ./lib/instances/service_instance.rb
35
+ - ./lib/service_manager.rb
36
+ homepage: https://factor.io
37
+ licenses: []
38
+ post_install_message:
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubyforge_project:
56
+ rubygems_version: 1.8.25
57
+ signing_key:
58
+ specification_version: 3
59
+ summary: Timer Factor.io Connector
60
+ test_files: []