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.
- data/lib/builders/action_builder.rb +20 -0
- data/lib/builders/listener_builder.rb +29 -0
- data/lib/builders/service_builder.rb +33 -0
- data/lib/builders/web_hook_builder.rb +34 -0
- data/lib/definitions/action_definition.rb +15 -0
- data/lib/definitions/listener_definition.rb +16 -0
- data/lib/definitions/service_definition.rb +19 -0
- data/lib/definitions/web_hook_definition.rb +13 -0
- data/lib/errors.rb +14 -0
- data/lib/factor-connector-api.rb +24 -0
- data/lib/instances/action_instance.rb +32 -0
- data/lib/instances/instance.rb +84 -0
- data/lib/instances/listener_instance.rb +95 -0
- data/lib/instances/service_instance.rb +81 -0
- data/lib/service_manager.rb +29 -0
- metadata +60 -0
@@ -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,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
|
data/lib/errors.rb
ADDED
@@ -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: []
|