factor 0.5.13 → 0.5.15

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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 569dc92eda75eb91dfaaacba2fdfdee5087137ed
4
+ data.tar.gz: c379ed9d1349d42aff4ee6705b7afecffba8a787
5
+ SHA512:
6
+ metadata.gz: 8eab23ca046a13ae752b270059d71c07b6b52870724c813d1550afe30f4631138a7e5b8686c47163a849ac72e5dceb79cde1441f5127da6945d7fd7218ac02bf
7
+ data.tar.gz: 9537cbbc57f1ce1ce52f353d4eb0c25dda422b570b1474c071fbf90bffc916f7b8e8dc3118fc5f7d91a3bd4adf0a1677d3c75cc021902e77ab8e0e87e115abb1
File without changes
metadata CHANGED
@@ -1,142 +1,139 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: factor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.13
5
- prerelease:
4
+ version: 0.5.15
6
5
  platform: ruby
7
6
  authors:
8
7
  - Maciej Skierkowski
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2014-10-07 00:00:00.000000000 Z
11
+ date: 2014-10-21 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: commander
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ~>
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
19
  version: 4.2.1
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ~>
24
+ - - "~>"
28
25
  - !ruby/object:Gem::Version
29
26
  version: 4.2.1
30
- - !ruby/object:Gem::Dependency
31
- name: rest_client
32
- requirement: !ruby/object:Gem::Requirement
33
- none: false
34
- requirements:
35
- - - ~>
36
- - !ruby/object:Gem::Version
37
- version: 1.7.3
38
- type: :runtime
39
- prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ~>
44
- - !ruby/object:Gem::Version
45
- version: 1.7.3
46
27
  - !ruby/object:Gem::Dependency
47
28
  name: faye-websocket
48
29
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
30
  requirements:
51
- - - ~>
31
+ - - "~>"
52
32
  - !ruby/object:Gem::Version
53
33
  version: 0.7.5
54
34
  type: :runtime
55
35
  prerelease: false
56
36
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
37
  requirements:
59
- - - ~>
38
+ - - "~>"
60
39
  - !ruby/object:Gem::Version
61
40
  version: 0.7.5
62
41
  - !ruby/object:Gem::Dependency
63
42
  name: colored
64
43
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
44
  requirements:
67
- - - ~>
45
+ - - "~>"
68
46
  - !ruby/object:Gem::Version
69
47
  version: '1.2'
70
48
  type: :runtime
71
49
  prerelease: false
72
50
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
51
  requirements:
75
- - - ~>
52
+ - - "~>"
76
53
  - !ruby/object:Gem::Version
77
54
  version: '1.2'
78
55
  - !ruby/object:Gem::Dependency
79
56
  name: configatron
80
57
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
58
  requirements:
83
- - - ~>
59
+ - - "~>"
84
60
  - !ruby/object:Gem::Version
85
61
  version: 4.2.0
86
62
  type: :runtime
87
63
  prerelease: false
88
64
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
65
  requirements:
91
- - - ~>
66
+ - - "~>"
92
67
  - !ruby/object:Gem::Version
93
68
  version: 4.2.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: rest-client
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.7.2
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.7.2
83
+ - !ruby/object:Gem::Dependency
84
+ name: erubis
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 2.7.0
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 2.7.0
94
97
  - !ruby/object:Gem::Dependency
95
98
  name: codeclimate-test-reporter
96
99
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
100
  requirements:
99
- - - ~>
101
+ - - "~>"
100
102
  - !ruby/object:Gem::Version
101
103
  version: 0.4.1
102
104
  type: :development
103
105
  prerelease: false
104
106
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
107
  requirements:
107
- - - ~>
108
+ - - "~>"
108
109
  - !ruby/object:Gem::Version
109
110
  version: 0.4.1
110
111
  - !ruby/object:Gem::Dependency
111
112
  name: rspec
112
113
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
114
  requirements:
115
- - - ~>
115
+ - - "~>"
116
116
  - !ruby/object:Gem::Version
117
117
  version: 3.1.0
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
121
  requirements:
123
- - - ~>
122
+ - - "~>"
124
123
  - !ruby/object:Gem::Version
125
124
  version: 3.1.0
126
125
  - !ruby/object:Gem::Dependency
127
126
  name: rake
128
127
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
128
  requirements:
131
- - - ~>
129
+ - - "~>"
132
130
  - !ruby/object:Gem::Version
133
131
  version: 10.3.2
134
132
  type: :development
135
133
  prerelease: false
136
134
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
135
  requirements:
139
- - - ~>
136
+ - - "~>"
140
137
  - !ruby/object:Gem::Version
141
138
  version: 10.3.2
142
139
  description: CLI to manager workflows on Factor.io
@@ -147,52 +144,38 @@ executables:
147
144
  extensions: []
148
145
  extra_rdoc_files: []
149
146
  files:
150
- - .gitignore
151
- - .travis.yml
152
- - Gemfile
153
- - Gemfile.lock
154
- - LICENSE
155
- - README.md
156
- - Rakefile
147
+ - "./spec/base_spec.rb"
148
+ - "./spec/listener_spec.rb"
149
+ - "./spec/registry_spec.rb"
150
+ - "./spec/spec_helper.rb"
151
+ - "./spec/workflow_spec.rb"
157
152
  - bin/factor
158
- - factor.gemspec
159
- - lib/commands/base.rb
160
- - lib/commands/workflows.rb
161
- - lib/factor.rb
162
- - lib/factor/version.rb
163
- - lib/listener.rb
164
- - lib/runtime.rb
165
- - lib/websocket_manager.rb
166
- - spec/base_spec.rb
167
- - spec/listener_spec.rb
168
- - spec/spec_helper.rb
169
- - spec/workflow_spec.rb
170
153
  homepage: https://factor.io
171
154
  licenses: []
155
+ metadata: {}
172
156
  post_install_message:
173
157
  rdoc_options: []
174
158
  require_paths:
175
159
  - lib
176
160
  required_ruby_version: !ruby/object:Gem::Requirement
177
- none: false
178
161
  requirements:
179
- - - ! '>='
162
+ - - ">="
180
163
  - !ruby/object:Gem::Version
181
164
  version: '0'
182
165
  required_rubygems_version: !ruby/object:Gem::Requirement
183
- none: false
184
166
  requirements:
185
- - - ! '>='
167
+ - - ">="
186
168
  - !ruby/object:Gem::Version
187
169
  version: '0'
188
170
  requirements: []
189
171
  rubyforge_project:
190
- rubygems_version: 1.8.25
172
+ rubygems_version: 2.2.2
191
173
  signing_key:
192
- specification_version: 3
174
+ specification_version: 4
193
175
  summary: CLI to manager workflows on Factor.io
194
176
  test_files:
195
- - spec/base_spec.rb
196
- - spec/listener_spec.rb
197
- - spec/spec_helper.rb
198
- - spec/workflow_spec.rb
177
+ - "./spec/base_spec.rb"
178
+ - "./spec/listener_spec.rb"
179
+ - "./spec/registry_spec.rb"
180
+ - "./spec/spec_helper.rb"
181
+ - "./spec/workflow_spec.rb"
data/.gitignore DELETED
@@ -1,19 +0,0 @@
1
- *.gem
2
- *.rbc
3
- *.log
4
- .bundle
5
- .config
6
- coverage
7
- InstalledFiles
8
- lib/bundler/man
9
- pkg
10
- rdoc
11
- spec/reports
12
- test/tmp
13
- test/version_tmp
14
- tmp
15
-
16
- # YARD artifacts
17
- .yardoc
18
- _yardoc
19
- doc/
@@ -1,14 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 1.9.3
4
- env:
5
- matrix:
6
- secure: Tq2/ECBrOTUmGLk/IaoeukgjCZ3ZfBVvAh8rvX6c2GJ0MopTXbWGRAaOxK+CXPqEW1X3NCtvJx26ti+QiXfEufACHllfYFpGeD9+AEreDyyFjA10X4/vgh5k4EiFP7p+3VAj8N1i2/+H5554IRxJgmhWNR7iATOavRf7g05nfec=
7
- deploy:
8
- provider: rubygems
9
- api_key:
10
- secure: EVy47RrKK9cntDCXnc+akDp51TwsOl9saXvELArQSUOVsY3CaPhnvd1KPFW/EJoJ3OQiDG8xiR1j8sMn8ldwjSdjQ64q66eEMQBBSQBnwxDqv2vZbCZYcAu9MQpQfX1LdY5E2wvkos5nB1/d138wWoXzD2Ylvlf15YI7CxiV/hA=
11
- gem: factor
12
- on:
13
- tags: true
14
- repo: factor-io/factor
data/Gemfile DELETED
@@ -1,3 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec
@@ -1,58 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- factor (0.5.13)
5
- colored (~> 1.2)
6
- commander (~> 4.2.1)
7
- configatron (~> 4.2.0)
8
- faye-websocket (~> 0.7.5)
9
- rest_client (~> 1.7.3)
10
-
11
- GEM
12
- remote: https://rubygems.org/
13
- specs:
14
- codeclimate-test-reporter (0.4.1)
15
- simplecov (>= 0.7.1, < 1.0.0)
16
- colored (1.2)
17
- commander (4.2.1)
18
- highline (~> 1.6.11)
19
- configatron (4.2.0)
20
- diff-lcs (1.2.5)
21
- docile (1.1.5)
22
- eventmachine (1.0.3)
23
- faye-websocket (0.7.5)
24
- eventmachine (>= 0.12.0)
25
- websocket-driver (>= 0.3.5)
26
- highline (1.6.21)
27
- multi_json (1.10.1)
28
- netrc (0.7.7)
29
- rake (10.3.2)
30
- rest_client (1.7.3)
31
- netrc (~> 0.7.7)
32
- rspec (3.1.0)
33
- rspec-core (~> 3.1.0)
34
- rspec-expectations (~> 3.1.0)
35
- rspec-mocks (~> 3.1.0)
36
- rspec-core (3.1.5)
37
- rspec-support (~> 3.1.0)
38
- rspec-expectations (3.1.2)
39
- diff-lcs (>= 1.2.0, < 2.0)
40
- rspec-support (~> 3.1.0)
41
- rspec-mocks (3.1.2)
42
- rspec-support (~> 3.1.0)
43
- rspec-support (3.1.1)
44
- simplecov (0.9.1)
45
- docile (~> 1.1.0)
46
- multi_json (~> 1.0)
47
- simplecov-html (~> 0.8.0)
48
- simplecov-html (0.8.0)
49
- websocket-driver (0.3.5)
50
-
51
- PLATFORMS
52
- ruby
53
-
54
- DEPENDENCIES
55
- codeclimate-test-reporter (~> 0.4.1)
56
- factor!
57
- rake (~> 10.3.2)
58
- rspec (~> 3.1.0)
data/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) {{{year}}} {{{fullname}}}
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
data/README.md DELETED
@@ -1,13 +0,0 @@
1
- [![Code Climate](https://codeclimate.com/github/factor-io/factor.png)](https://codeclimate.com/github/factor-io/factor)
2
- [![Test Coverage](https://codeclimate.com/github/factor-io/factor/coverage.png)](https://codeclimate.com/github/factor-io/factor)
3
- [![Dependency Status](https://gemnasium.com/factor-io/factor.svg)](https://gemnasium.com/factor-io/factor)
4
- [![Build Status](https://travis-ci.org/factor-io/factor.svg)](https://travis-ci.org/factor-io/factor)
5
- [![Gem Version](https://badge.fury.io/rb/factor.svg)](http://badge.fury.io/rb/factor)
6
-
7
- Factor.io Server Runtime
8
- ==========
9
-
10
- gem install factor
11
- git clone git@github.com/factor-io/example-workflows.git
12
- cd example-workflows
13
- factor s
data/Rakefile DELETED
@@ -1,12 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
5
-
6
- desc 'Run specs'
7
- RSpec::Core::RakeTask.new do |t|
8
- t.verbose = false
9
- t.rspec_opts = '--color --order random'
10
- end
11
-
12
- task default: :spec
@@ -1,30 +0,0 @@
1
- # encoding: UTF-8
2
- $LOAD_PATH.push File.expand_path('../lib', __FILE__)
3
- require 'factor/version'
4
-
5
- Gem::Specification.new do |s|
6
- s.name = 'factor'
7
- s.version = Factor::VERSION
8
- s.platform = Gem::Platform::RUBY
9
- s.authors = ['Maciej Skierkowski']
10
- s.email = ['maciej@factor.io']
11
- s.homepage = 'https://factor.io'
12
- s.summary = 'CLI to manager workflows on Factor.io'
13
- s.description = 'CLI to manager workflows on Factor.io'
14
-
15
- s.files = `git ls-files`.split("\n")
16
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
- s.executables = `git ls-files -- bin/*`.split("\n").map do |f|
18
- File.basename(f)
19
- end
20
- s.require_paths = ['lib']
21
-
22
- s.add_runtime_dependency 'commander', '~> 4.2.1'
23
- s.add_runtime_dependency 'rest_client', '~> 1.7.3'
24
- s.add_runtime_dependency 'faye-websocket', '~> 0.7.5'
25
- s.add_runtime_dependency 'colored', '~> 1.2'
26
- s.add_runtime_dependency 'configatron', '~> 4.2.0'
27
- s.add_development_dependency 'codeclimate-test-reporter', '~> 0.4.1'
28
- s.add_development_dependency 'rspec', '~> 3.1.0'
29
- s.add_development_dependency 'rake', '~> 10.3.2'
30
- end
@@ -1,100 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require 'colored'
4
- require 'configatron'
5
- require 'yaml'
6
- require 'fileutils'
7
-
8
- module Factor
9
- module Commands
10
- # Base command with common methods used by all commands
11
- class Command
12
- DEFAULT_FILENAME = {
13
- connectors: File.expand_path('./connectors.yml'),
14
- credentials: File.expand_path('./credentials.yml')
15
- }
16
-
17
- attr_accessor :destination_stream
18
-
19
- def info(options = {})
20
- log_line :info, options
21
- end
22
-
23
- def error(options = {})
24
- log_line :error, options
25
- end
26
-
27
- def warn(options = {})
28
- log_line :warn, options
29
- end
30
-
31
- def success(options = {})
32
- log_line :success, options
33
- end
34
-
35
- def exception(message, exception)
36
- error 'message' => message
37
- error 'message' => " #{exception.message}"
38
- exception.backtrace.each do |line|
39
- error 'message' => " #{line}"
40
- end
41
- end
42
-
43
- def load_config(options = {})
44
- load_config_data :credentials, options
45
- load_config_data :connectors, options
46
- end
47
-
48
- private
49
-
50
- def load_config_data(config_type, options = {})
51
- relative_path = options[config_type] || DEFAULT_FILENAME[config_type]
52
- absolute_path = File.expand_path(relative_path)
53
- info message: "Loading #{config_type} from #{absolute_path}"
54
- data = YAML.load(File.read(absolute_path))
55
- configatron[config_type].configure_from_hash(data)
56
- rescue => ex
57
- exception "Couldn't load #{config_type} from #{absolute_path}", ex
58
- end
59
-
60
- def log_line(section, options = {})
61
- options = { message: options } if options.is_a?(String)
62
- tag = tag(options)
63
- message = options['message'] || options[:message]
64
- section_text = format_section(section)
65
- write "[ #{section_text} ] [#{time}]#{tag} #{message}" if message
66
- end
67
-
68
- def format_section(section)
69
- formated_section = section.to_s.upcase.center(10)
70
- case section
71
- when :error then formated_section.red
72
- when :info then formated_section.bold
73
- when :warn then formated_section.yellow
74
- when :success then formated_section.green
75
- else formated_section
76
- end
77
- end
78
-
79
- def tag(options)
80
- primary = options['service_id'] || options['instance_id']
81
- secondary = if options['service_id'] && options['instance_id']
82
- ":#{options['instane_id']}"
83
- else
84
- ''
85
- end
86
- primary ? "[#{primary}#{secondary}]" : ''
87
- end
88
-
89
- def time
90
- Time.now.localtime.strftime('%m/%d/%y %T.%L')
91
- end
92
-
93
- def write(message)
94
- stream = @destination_stream || $stdout
95
- stream.puts(message)
96
- stream.flush
97
- end
98
- end
99
- end
100
- end
@@ -1,112 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require 'configatron'
4
-
5
- require 'commands/base'
6
- require 'runtime'
7
-
8
- module Factor
9
- module Commands
10
- # Workflow is a Command to start the factor runtime from the CLI
11
- class Workflow < Factor::Commands::Command
12
- def initialize
13
- @workflows = {}
14
- end
15
-
16
- def server(_args, options)
17
- config_settings = {}
18
- config_settings[:credentials] = options.credentials
19
- config_settings[:connectors] = options.connectors
20
- workflow_filename = File.expand_path(options.path || '.')
21
- @destination_stream = File.new(options.log, 'w+') if options.log
22
-
23
- load_config(config_settings)
24
- load_all_workflows(workflow_filename)
25
- block_until_interupt
26
- log_message 'status' => 'info', 'message' => 'Good bye!'
27
- end
28
-
29
- private
30
-
31
- def load_all_workflows(workflow_filename)
32
- glob_ending = workflow_filename[-1] == '/' ? '' : '/'
33
- glob = "#{workflow_filename}#{glob_ending}*.rb"
34
- file_list = Dir.glob(glob)
35
- if !file_list.all? { |file| File.file?(file) }
36
- error "#{workflow_filename} is neither a file or directory"
37
- elsif file_list.count == 0
38
- error 'No workflows in this directory to run'
39
- else
40
- file_list.each { |filename| load_workflow(filename) }
41
- end
42
- end
43
-
44
- def block_until_interupt
45
- log_message 'status' => 'info', 'message' => 'Ctrl-c to exit'
46
- begin
47
- loop do
48
- sleep 1
49
- end
50
- rescue Interrupt
51
- log_message 'status' => 'info', 'message' => 'Exiting app...'
52
- ensure
53
- @workflows.keys.each { |filename| unload_workflow(filename) }
54
- end
55
- end
56
-
57
- def load_workflow(filename)
58
- workflow_filename = File.expand_path(filename)
59
- log_message(
60
- 'status' => 'info',
61
- 'message' => "Loading workflow from #{workflow_filename}")
62
- begin
63
- workflow_definition = File.read(workflow_filename)
64
- rescue => ex
65
- exception "Couldn't read file #{workflow_filename}", ex
66
- return
67
- end
68
-
69
- log_message(
70
- 'status' => 'info',
71
- 'message' => 'Setting up workflow processor')
72
- begin
73
- connector_settings = configatron.connectors.to_hash
74
- credential_settings = configatron.credentials.to_hash
75
- runtime = Runtime.new(connector_settings, credential_settings)
76
- runtime.logger = method(:log_message)
77
- rescue => ex
78
- message = "Couldn't setup workflow process for #{workflow_filename}"
79
- exception message, ex
80
- end
81
-
82
- @workflows[workflow_filename] = fork do
83
- begin
84
- log_message(
85
- 'status' => 'info',
86
- 'message' => "Starting #{workflow_filename}")
87
- runtime.load(workflow_definition)
88
- rescue => ex
89
- exception "Couldn't load #{workflow_filename}", ex
90
- end
91
- end
92
- end
93
-
94
- def unload_workflow(filename)
95
- workflow_filename = File.expand_path(filename)
96
- log_message(
97
- 'status' => 'info',
98
- 'message' => "Stopping #{workflow_filename}")
99
- Process.kill('SIGINT', @workflows[workflow_filename])
100
- end
101
-
102
- def log_message(message_info)
103
- case message_info['status']
104
- when 'info' then info message_info
105
- when 'success' then success message_info
106
- when 'warn' then warn message_info
107
- else error message_info
108
- end
109
- end
110
- end
111
- end
112
- end
@@ -1,22 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require 'commander/import'
4
-
5
- require 'factor/version'
6
- require 'commands/workflows'
7
-
8
- program :name, 'Factor.io Server'
9
- program :version, Factor::VERSION
10
- program :description, 'Factor.io Server to run workflows'
11
-
12
- command 'server' do |c|
13
- c.syntax = 'factor server [options]'
14
- c.description = 'Start the Factor.io Server in the current local directory'
15
- c.option '--log FILE', String, 'Log file path. Default is stdout.'
16
- c.option '--credentials FILE', String, 'credentials.yml file path.'
17
- c.option '--connectors FILE', String, 'connectors.yml file path'
18
- c.option '--path FILE', String, 'Path to workflows'
19
- c.when_called Factor::Commands::Workflow, :server
20
- end
21
-
22
- alias_command 's', 'server'
@@ -1,6 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- # Primary Factor.io module
4
- module Factor
5
- VERSION = '0.5.13'
6
- end
@@ -1,44 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require 'rest_client'
4
- require 'websocket_manager'
5
-
6
- module Factor
7
- # Class Listener for integrating with connector service
8
- class Listener
9
- def initialize(url)
10
- @url = url
11
- end
12
-
13
- def definition
14
- get("#{@url}/definition")
15
- end
16
-
17
- def listener(listener_id)
18
- listen("#{@url}/listeners/#{listener_id}")
19
- end
20
-
21
- def action(action_id)
22
- listen("#{@url}/actions/#{action_id}")
23
- end
24
-
25
- private
26
-
27
- def post(uri_path, payload)
28
- content = { 'payload' => MultiJson.dump(payload) }
29
- JSON.parse(RestClient.post(uri_path, content))
30
- end
31
-
32
- def get(uri_path)
33
- JSON.parse(RestClient.get(uri_path))
34
- end
35
-
36
- def delete(uri_path)
37
- JSON.parse(RestClient.delete(uri_path))
38
- end
39
-
40
- def listen(uri_path)
41
- WebSocketManager.new(uri_path)
42
- end
43
- end
44
- end
@@ -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
@@ -1,94 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require 'faye/websocket'
4
- require 'uri'
5
-
6
- module Factor
7
- # class for managing the web socket connections
8
- class WebSocketManager
9
- attr_accessor :keep_open, :events, :state
10
-
11
- def initialize(uri, headers = {})
12
- u = URI(uri)
13
- @uri = u.to_s
14
- @settings = { ping: 10, retry: 5 }
15
- @settings[:headers] = headers if headers && headers != {}
16
- @state = :closed
17
- @events = {}
18
- end
19
-
20
- def open
21
- if closed?
22
- @state = :opening
23
- connect
24
- end
25
- @state
26
- end
27
-
28
- def close
29
- if open?
30
- @state = :closing
31
- @ws.close
32
- end
33
- @state
34
- end
35
-
36
- def on(event, &block)
37
- @events[event] = block
38
- end
39
-
40
- def open?
41
- @state == :open
42
- end
43
-
44
- def opening?
45
- @state == :opening
46
- end
47
-
48
- def closed?
49
- @state == :closed
50
- end
51
-
52
- def closing?
53
- @state == :closing
54
- end
55
-
56
- def send(msg)
57
- @ws.send(msg)
58
- end
59
-
60
- private
61
-
62
- def call_event(event, data)
63
- @events[event].call(data) if @events[event]
64
- end
65
-
66
- def connect
67
- EM.run do
68
- begin
69
- @ws = Faye::WebSocket::Client.new(@uri, nil, @settings)
70
-
71
- @ws.on :close do |event|
72
- @state = :closed
73
- call_event :close, event
74
- end
75
-
76
- @ws.on :message do |msg|
77
- call_event :message, msg
78
- end
79
-
80
- @ws.on :open do |event|
81
- @state = :open
82
- call_event :open, event
83
- end
84
-
85
- @ws.on :error do |event|
86
- call_event :error, event
87
- end
88
- rescue => ex
89
- call_event :fail, ex.message
90
- end
91
- end
92
- end
93
- end
94
- end