factor 0.6.3 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
data/lib/listener.rb DELETED
@@ -1,26 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require 'websocket_manager'
4
-
5
- module Factor
6
- # Class Listener for integrating with connector service
7
- class Listener
8
- def initialize(url)
9
- @url = url
10
- end
11
-
12
- def listener(listener_id)
13
- listen("#{@url}/listeners/#{listener_id}")
14
- end
15
-
16
- def action(action_id)
17
- listen("#{@url}/actions/#{action_id}")
18
- end
19
-
20
- private
21
-
22
- def listen(uri_path)
23
- WebSocketManager.new(uri_path)
24
- end
25
- end
26
- end
data/lib/runtime.rb DELETED
@@ -1,232 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require 'json'
4
- require 'securerandom'
5
- require 'yaml'
6
- require 'eventmachine'
7
- require 'uri'
8
- require 'faye/websocket'
9
- require 'ostruct'
10
-
11
- require 'listener'
12
- require 'commands/base'
13
-
14
- module Factor
15
- # Runtime class is the magic of the server
16
- class Runtime
17
- attr_accessor :logger, :name, :description, :id, :instance_id, :connectors, :credentials
18
-
19
- def initialize(connectors, credentials)
20
- @workflow_spec = {}
21
- @sockets = []
22
- @instance_id = SecureRandom.hex(3)
23
- @reconnect = true
24
-
25
- trap 'SIGINT' do
26
- info "Exiting '#{@instance_id}'"
27
- @reconnect = false
28
- @sockets.each { |s| s.close }
29
- exit
30
- end
31
-
32
- @connectors = {}
33
- flat_hash(connectors).each do |key, connector_url|
34
- @connectors[key] = Listener.new(connector_url)
35
- end
36
-
37
- @credentials = {}
38
- credentials.each do |connector_id, credential_settings|
39
- @credentials[connector_id] = credential_settings
40
- end
41
- end
42
-
43
- def load(workflow_definition)
44
- EM.run do
45
- instance_eval(workflow_definition)
46
- end
47
- end
48
-
49
- def listen(service_ref, params = {}, &block)
50
- service_map = service_ref.split('::')
51
- service_id = service_map.first
52
- listener_id = service_map.last
53
- service_key = service_map[0..-2].map{|k| k.to_sym}
54
-
55
- ws = @connectors[service_key].listener(listener_id)
56
-
57
- handle_on_open(service_ref, 'Listener', ws, params)
58
-
59
- ws.on :close do
60
- error 'Listener disconnected'
61
- if @reconnect
62
- warn 'Reconnecting...'
63
- sleep 3
64
- ws.open
65
- end
66
- end
67
-
68
- ws.on :message do |event|
69
- listener_response = JSON.parse(event.data)
70
- case listener_response['type']
71
- when'start_workflow'
72
- success "Workflow '#{service_id}::#{listener_id}' triggered"
73
- error_handle_call(listener_response, &block)
74
- when 'return'
75
- success "Workflow '#{service_ref}' started"
76
- when 'fail'
77
- error "Workflow '#{service_ref}' failed to start"
78
- when 'log'
79
- listener_response['message'] = " #{listener_response['message']}"
80
- log_message(listener_response)
81
- else
82
- error "Unknown listener response: #{listener_response}"
83
- end
84
- end
85
-
86
- ws.on :retry do |event|
87
- warn event[:message]
88
- end
89
-
90
- ws.on :error do |event|
91
- err = 'Error during WebSocket handshake: Unexpected response code: 401'
92
- if event.message == err
93
- error "Sorry but you don't have access to this listener,
94
- | either because your token is invalid or your plan doesn't
95
- | support this listener"
96
- else
97
- error 'Failure in WebSocket connection to connector service'
98
- end
99
- end
100
-
101
- ws.open
102
-
103
- @sockets << ws
104
- end
105
-
106
- def run(service_ref, params = {}, &block)
107
- service_map = service_ref.split('::')
108
- service_id = service_map.first
109
- action_id = service_map.last
110
- service_key = service_map[0..-2].map{|k| k.to_sym}
111
-
112
- ws = @connectors[service_key].action(action_id)
113
-
114
- handle_on_open(service_ref, 'Action', ws, params)
115
-
116
- ws.on :error do
117
- error 'Connection dropped while calling action'
118
- end
119
-
120
- ws.on :message do |event|
121
- action_response = JSON.parse(event.data)
122
- case action_response['type']
123
- when 'return'
124
- ws.close
125
- success "Action '#{service_ref}' responded"
126
- error_handle_call(action_response, &block)
127
- when 'fail'
128
- ws.close
129
- error " #{action_response['message']}"
130
- error "Action '#{service_ref}' failed"
131
- when 'log'
132
- action_response['message'] = " #{action_response['message']}"
133
- log_message(action_response)
134
- else
135
- error "Unknown action response: #{action_response}"
136
- end
137
- end
138
-
139
- ws.open
140
-
141
- @sockets << ws
142
- end
143
-
144
- private
145
-
146
- class DeepStruct < OpenStruct
147
- def initialize(hash=nil)
148
- @table = {}
149
- @hash_table = {}
150
-
151
- if hash
152
- hash.each do |k,v|
153
- @table[k.to_sym] = (v.is_a?(Hash) ? self.class.new(v) : v)
154
- @hash_table[k.to_sym] = v
155
-
156
- new_ostruct_member(k)
157
- end
158
- end
159
- end
160
-
161
- def to_h
162
- @hash_table
163
- end
164
-
165
- def [](idx)
166
- hash = marshal_dump
167
- hash[idx.to_sym]
168
- end
169
- end
170
-
171
- def simple_object_convert(item)
172
- if item.is_a?(Hash)
173
- DeepStruct.new(item)
174
- elsif item.is_a?(Array)
175
- item.map do |i|
176
- simple_object_convert(i)
177
- end
178
- else
179
- item
180
- end
181
- end
182
-
183
- def flat_hash(h,f=[],g={})
184
- return g.update({ f=>h }) unless h.is_a? Hash
185
- h.each { |k,r| flat_hash(r,f+[k],g) }
186
- g
187
- end
188
-
189
- def handle_on_open(service_ref, dsl_type, ws, params)
190
- service_map = service_ref.split('::')
191
- service_id = service_map.first
192
-
193
- ws.on :open do
194
- params.merge!(@credentials[service_id.to_sym] || {})
195
- success "#{dsl_type.capitalize} '#{service_ref}' called"
196
- ws.send(params.to_json)
197
- end
198
- end
199
-
200
- def error_handle_call(listener_response, &block)
201
- content = simple_object_convert(listener_response['payload'])
202
- block.call(content) if block
203
- rescue => ex
204
- error "Error in workflow definition: #{ex.message}"
205
- ex.backtrace.each do |line|
206
- error " #{line}"
207
- end
208
- end
209
-
210
- def success(msg)
211
- log_message('type' => 'log', 'status' => 'success', 'message' => msg)
212
- end
213
-
214
- def warn(msg)
215
- log_message('type' => 'log', 'status' => 'warn', 'message' => msg)
216
- end
217
-
218
- def error(msg)
219
- log_message('type' => 'log', 'status' => 'error', 'message' => msg)
220
- end
221
-
222
- def info(msg)
223
- log_message('type' => 'log', 'status' => 'info', 'message' => msg)
224
- end
225
-
226
- def log_message(message_info)
227
- message_info['instance_id'] = @instance_id
228
- message_info['workflow_id'] = @id
229
- @logger.call(message_info) if @logger
230
- end
231
- end
232
- end
data/spec/base_spec.rb DELETED
@@ -1,102 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require 'spec_helper'
4
- require 'tempfile'
5
- require 'yaml'
6
- require 'commander'
7
-
8
- describe Factor::Commands::Command do
9
- before :each do
10
- @command = Factor::Commands::Command.new
11
- end
12
-
13
- output_methods = %w(info warn error success)
14
-
15
- output_methods.each do |method_name|
16
- describe ".#{method_name}" do
17
- it "logs #{method_name}" do
18
-
19
- test_string = 'Hello World'
20
- output = capture_stdout do
21
- @command.method(method_name.to_sym).call message: test_string
22
- end
23
-
24
- expect(output).to include(test_string)
25
- expect(output).to include(method_name.upcase)
26
- end
27
- end
28
- end
29
-
30
- describe '.exception' do
31
- it 'logs exception' do
32
-
33
- test_string = 'Hello World'
34
- exception_string = 'Something be busted'
35
- output = capture_stdout do
36
- begin
37
- fail ArgumentError, exception_string
38
- rescue => ex
39
- @command.exception test_string, ex
40
- end
41
- end
42
-
43
- expect(output).to include(test_string)
44
- expect(output).to include(exception_string)
45
- expect(output).to include('ERROR')
46
-
47
- end
48
- end
49
-
50
- describe '.load_config' do
51
- it 'can load credentials and connectors' do
52
- credentials_file = Tempfile.new('credentials')
53
- connectors_file = Tempfile.new('connectors')
54
-
55
- credentials_content = {
56
- 'github' => {
57
- 'api_key' => 'fake_github_key'
58
- },
59
- 'heroku' => {
60
- 'api_key' => 'fake_heroku_key'
61
- }
62
- }
63
-
64
- connectors_content = {
65
- 'timer' => 'http://localhost:9294/v0.4/timer',
66
- 'web' => 'http://localhost:9294/v0.4/web',
67
- 'github' => 'http://localhost:9294/v0.4/github',
68
- 'heroku' => 'http://localhost:9294/v0.4/heroku'
69
- }
70
-
71
- credentials_file.write(YAML.dump(credentials_content))
72
- connectors_file.write(YAML.dump(connectors_content))
73
-
74
- credentials_file.rewind
75
- connectors_file.rewind
76
-
77
- options = Commander::Command::Options.new
78
- options.credentials = credentials_file.path
79
- options.connectors = connectors_file.path
80
-
81
- config_settings = {
82
- credentials: options.credentials,
83
- connectors: options.connectors
84
- }
85
-
86
- output = capture_stdout do
87
- @command.load_config config_settings
88
- end
89
-
90
- expect(configatron.credentials.github.api_key).to eq('fake_github_key')
91
- expect(configatron.credentials.heroku.api_key).to eq('fake_heroku_key')
92
- connectors_content.keys.each do |expected_connector_key|
93
- actual_connector = configatron.connectors[expected_connector_key]
94
- expected_connector = connectors_content[expected_connector_key]
95
- expect(actual_connector).to eq(expected_connector)
96
- end
97
-
98
- credentials_file.close
99
- connectors_file.close
100
- end
101
- end
102
- end
@@ -1,9 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require 'spec_helper'
4
-
5
- describe Factor::Listener do
6
- it 'does stuff' do
7
- expect(true).to eq(true)
8
- end
9
- end
File without changes
@@ -1,11 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require 'spec_helper'
4
-
5
- describe Factor::Commands::Workflow do
6
- describe '.server' do
7
- it 'can run a basic workflow' do
8
-
9
- end
10
- end
11
- end