rflow 0.0.5 → 1.0.0a1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +21 -0
- data/.yardopts +1 -0
- data/Gemfile +5 -1
- data/Guardfile +8 -0
- data/LICENSE +190 -0
- data/NOTES +26 -13
- data/README.md +448 -0
- data/Rakefile +5 -12
- data/bin/rflow +23 -20
- data/example/basic_config.rb +2 -2
- data/example/basic_extensions.rb +8 -8
- data/example/http_config.rb +1 -1
- data/example/http_extensions.rb +15 -15
- data/lib/rflow.rb +15 -387
- data/lib/rflow/component.rb +105 -50
- data/lib/rflow/component/port.rb +25 -24
- data/lib/rflow/components/raw.rb +4 -4
- data/lib/rflow/components/raw/extensions.rb +2 -2
- data/lib/rflow/configuration.rb +54 -36
- data/lib/rflow/configuration/component.rb +2 -3
- data/lib/rflow/configuration/connection.rb +9 -10
- data/lib/rflow/configuration/migrations/{20010101000001_create_settings.rb → 20010101000000_create_settings.rb} +2 -2
- data/lib/rflow/configuration/migrations/20010101000001_create_shards.rb +21 -0
- data/lib/rflow/configuration/migrations/20010101000002_create_components.rb +7 -2
- data/lib/rflow/configuration/migrations/20010101000003_create_ports.rb +3 -3
- data/lib/rflow/configuration/migrations/20010101000004_create_connections.rb +2 -2
- data/lib/rflow/configuration/port.rb +3 -4
- data/lib/rflow/configuration/ruby_dsl.rb +59 -35
- data/lib/rflow/configuration/setting.rb +8 -7
- data/lib/rflow/configuration/shard.rb +24 -0
- data/lib/rflow/configuration/uuid_keyed.rb +3 -3
- data/lib/rflow/connection.rb +21 -10
- data/lib/rflow/connections/zmq_connection.rb +45 -44
- data/lib/rflow/logger.rb +67 -0
- data/lib/rflow/master.rb +127 -0
- data/lib/rflow/message.rb +14 -14
- data/lib/rflow/pid_file.rb +84 -0
- data/lib/rflow/shard.rb +148 -0
- data/lib/rflow/version.rb +1 -1
- data/rflow.gemspec +22 -28
- data/schema/message.avsc +8 -8
- data/spec/fixtures/config_ints.rb +4 -4
- data/spec/fixtures/config_shards.rb +30 -0
- data/spec/fixtures/extensions_ints.rb +8 -8
- data/spec/rflow_component_port_spec.rb +58 -0
- data/spec/rflow_configuration_ruby_dsl_spec.rb +148 -0
- data/spec/rflow_configuration_spec.rb +4 -4
- data/spec/rflow_message_data_raw.rb +2 -2
- data/spec/rflow_message_data_spec.rb +6 -6
- data/spec/rflow_message_spec.rb +13 -13
- data/spec/rflow_spec.rb +294 -71
- data/spec/schema_spec.rb +2 -2
- data/spec/spec_helper.rb +6 -4
- data/temp.rb +21 -21
- metadata +56 -65
- data/.rvmrc +0 -1
- data/README +0 -0
data/lib/rflow/component.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
1
3
|
require 'rflow/message'
|
2
4
|
require 'rflow/component/port'
|
3
5
|
|
@@ -8,7 +10,7 @@ class RFlow
|
|
8
10
|
RFlow::Configuration.add_available_component(subclass)
|
9
11
|
end
|
10
12
|
|
11
|
-
|
13
|
+
|
12
14
|
# The Component class methods used in the creation of a component
|
13
15
|
class << self
|
14
16
|
def defined_input_ports
|
@@ -23,7 +25,7 @@ class RFlow
|
|
23
25
|
# Port defintions only have names
|
24
26
|
|
25
27
|
# TODO: consider class-based UUIDs to identify component types
|
26
|
-
|
28
|
+
|
27
29
|
# Define an input port with a given name
|
28
30
|
def input_port(port_name)
|
29
31
|
define_port(defined_input_ports, port_name)
|
@@ -41,89 +43,142 @@ class RFlow
|
|
41
43
|
|
42
44
|
# Create the port accessor method based on the port name
|
43
45
|
define_method port_name.to_s.to_sym do
|
44
|
-
port = ports.by_name[port_name.to_s]
|
46
|
+
port = ports.by_name[port_name.to_s]
|
45
47
|
return port if port
|
46
|
-
|
48
|
+
|
47
49
|
# If the port was not connected, return a port-like object
|
48
50
|
# that can respond/log but doesn't send any data. Note,
|
49
51
|
# it won't be available in the 'by_uuid' collection, as it
|
50
|
-
# doesn't have a configured
|
52
|
+
# doesn't have a configured uuid
|
51
53
|
RFlow.logger.debug "'#{self.name}##{port_name}' not connected, creating a disconnected port"
|
52
|
-
|
54
|
+
|
55
|
+
disconnected_port = DisconnectedPort.new(OpenStruct.new(:name => port_name, :uuid => 0))
|
53
56
|
ports << disconnected_port
|
54
57
|
disconnected_port
|
55
58
|
end
|
56
59
|
end
|
60
|
+
|
61
|
+
|
62
|
+
# Attempt to instantiate a component described by the config
|
63
|
+
# specification. This assumes that the specification of a
|
64
|
+
# component is a fully qualified Ruby class that has already
|
65
|
+
# been loaded. It will first attempt to find subclasses of
|
66
|
+
# RFlow::Component (in the available_components hash) and then
|
67
|
+
# attempt to constantize the specification into a different
|
68
|
+
# class. Future releases will support external (i.e. non-managed
|
69
|
+
# components), but the current stuff only supports Ruby classes
|
70
|
+
def build(config)
|
71
|
+
if config.managed?
|
72
|
+
RFlow.logger.debug "Instantiating component '#{config.name}' as '#{config.specification}' (#{config.uuid})"
|
73
|
+
begin
|
74
|
+
RFlow.logger.debug RFlow.configuration.available_components.inspect
|
75
|
+
instantiated_component = if RFlow.configuration.available_components.include? config.specification
|
76
|
+
RFlow.logger.debug "Component found in configuration.available_components['#{config.specification}']"
|
77
|
+
RFlow.configuration.available_components[config.specification].new(config)
|
78
|
+
else
|
79
|
+
RFlow.logger.debug "Component not found in configuration.available_components, constantizing component '#{config.specification}'"
|
80
|
+
config.specification.constantize.new(config)
|
81
|
+
end
|
82
|
+
rescue NameError => e
|
83
|
+
error_message = "Could not instantiate component '#{config.name}' as '#{config.specification}' (#{config.uuid}): the class '#{config.specification}' was not found"
|
84
|
+
RFlow.logger.error error_message
|
85
|
+
raise RuntimeError, error_message
|
86
|
+
rescue Exception => e
|
87
|
+
error_message = "Could not instantiate component '#{config.name}' as '#{config.specification}' (#{config.uuid}): #{e.class} #{e.message}"
|
88
|
+
RFlow.logger.error error_message
|
89
|
+
raise RuntimeError, error_message
|
90
|
+
end
|
91
|
+
else
|
92
|
+
error_message = "Non-managed components not yet implemented for component '#{config.name}' as '#{config.specification}' (#{config.uuid})"
|
93
|
+
RFlow.logger.error error_message
|
94
|
+
raise NotImplementedError, error_message
|
95
|
+
end
|
96
|
+
|
97
|
+
instantiated_component
|
98
|
+
end
|
57
99
|
end
|
58
100
|
|
59
|
-
attr_reader :
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
@instance_uuid = uuid
|
66
|
-
@name = name
|
101
|
+
attr_reader :config, :uuid, :name, :ports
|
102
|
+
|
103
|
+
def initialize(config)
|
104
|
+
@config = config
|
105
|
+
@uuid = config.uuid
|
106
|
+
@name = config.name
|
67
107
|
@ports = PortCollection.new
|
68
|
-
|
108
|
+
|
109
|
+
configure_ports!
|
110
|
+
configure_connections!
|
111
|
+
configure!(config.options)
|
69
112
|
end
|
70
113
|
|
71
|
-
|
114
|
+
|
72
115
|
# Returns a list of connected input ports. Each port will have
|
73
116
|
# one or more keys associated with a particular connection.
|
74
117
|
def input_ports
|
75
118
|
ports.by_type["RFlow::Component::InputPort"]
|
76
119
|
end
|
77
120
|
|
78
|
-
|
121
|
+
|
79
122
|
# Returns a list of connected output ports. Each port will have
|
80
123
|
# one or more keys associated with the particular connection.
|
81
124
|
def output_ports
|
82
125
|
ports.by_type["RFlow::Component::OutputPort"]
|
83
126
|
end
|
84
127
|
|
85
|
-
|
128
|
+
|
86
129
|
# Returns a list of disconnected output ports.
|
87
130
|
def disconnected_ports
|
88
131
|
ports.by_type["RFlow::Component::DisconnectedPort"]
|
89
132
|
end
|
90
|
-
|
91
133
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
134
|
+
|
135
|
+
def configure_ports!
|
136
|
+
# Send the port configuration to each component
|
137
|
+
config.input_ports.each do |input_port_config|
|
138
|
+
RFlow.logger.debug "Configuring component '#{name}' (#{uuid}) with input port '#{input_port_config.name}' (#{input_port_config.uuid})"
|
139
|
+
configure_input_port!(input_port_config)
|
97
140
|
end
|
98
|
-
|
141
|
+
|
142
|
+
config.output_ports.each do |output_port_config|
|
143
|
+
RFlow.logger.debug "Configuring component '#{name}' (#{uuid}) with output port '#{output_port_config.name}' (#{output_port_config.uuid})"
|
144
|
+
configure_output_port!(output_port_config)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
def configure_input_port!(port_config)
|
150
|
+
unless self.class.defined_input_ports.include? port_config.name
|
151
|
+
raise ArgumentError, "Input port '#{port_config.name}' not defined on component '#{self.class}'"
|
152
|
+
end
|
153
|
+
ports << InputPort.new(port_config)
|
99
154
|
end
|
100
155
|
|
101
|
-
|
102
|
-
def configure_output_port!(
|
103
|
-
unless self.class.defined_output_ports.include?
|
104
|
-
raise ArgumentError, "Output port '#{
|
156
|
+
|
157
|
+
def configure_output_port!(port_config)
|
158
|
+
unless self.class.defined_output_ports.include? port_config.name
|
159
|
+
raise ArgumentError, "Output port '#{port_config.name}' not defined on component '#{self.class}'"
|
105
160
|
end
|
106
|
-
ports << OutputPort.new(
|
161
|
+
ports << OutputPort.new(port_config)
|
107
162
|
end
|
108
163
|
|
109
164
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
when 'RFlow::Configuration::ZMQConnection'
|
117
|
-
connection = RFlow::Connections::ZMQConnection.new(connection_uuid, connection_name, connection_options)
|
118
|
-
else
|
119
|
-
raise ArgumentError, "Only ZMQConnections currently supported"
|
165
|
+
def configure_connections!
|
166
|
+
config.input_ports.each do |input_port_config|
|
167
|
+
input_port_config.input_connections.each do |input_connection_config|
|
168
|
+
RFlow.logger.debug "Configuring input port '#{input_port_config.name}' (#{input_port_config.uuid}) key '#{input_connection_config.input_port_key}' with #{input_connection_config.type.to_s} connection '#{input_connection_config.name}' (#{input_connection_config.uuid})"
|
169
|
+
ports.by_uuid[input_port_config.uuid].add_connection(input_connection_config.input_port_key, Connection.build(input_connection_config))
|
170
|
+
end
|
120
171
|
end
|
121
172
|
|
122
|
-
|
123
|
-
|
173
|
+
config.output_ports.each do |output_port_config|
|
174
|
+
output_port_config.output_connections.each do |output_connection_config|
|
175
|
+
RFlow.logger.debug "Configuring output port '#{output_port_config.name}' (#{output_port_config.uuid}) key '#{output_connection_config.output_port_key}' with #{output_connection_config.type.to_s} connection '#{output_connection_config.name}' (#{output_connection_config.uuid})"
|
176
|
+
ports.by_uuid[output_port_config.uuid].add_connection(output_connection_config.output_port_key, Connection.build(output_connection_config))
|
177
|
+
end
|
178
|
+
end
|
124
179
|
end
|
125
180
|
|
126
|
-
|
181
|
+
|
127
182
|
# Tell the component to establish it's ports' connections, i.e. make
|
128
183
|
# the connection. Uses the underlying connection object. Also
|
129
184
|
# establishes the callbacks for each of the input ports
|
@@ -141,26 +196,26 @@ class RFlow
|
|
141
196
|
end
|
142
197
|
end
|
143
198
|
end
|
144
|
-
|
199
|
+
|
145
200
|
output_ports.each do |output_port|
|
146
201
|
output_port.connect!
|
147
202
|
end
|
148
203
|
end
|
149
204
|
|
150
|
-
|
205
|
+
|
151
206
|
def to_s
|
152
|
-
string = "Component '#{name}' (#{
|
207
|
+
string = "Component '#{name}' (#{uuid})\n"
|
153
208
|
ports.each do |port|
|
154
209
|
port.keys.each do |port_key|
|
155
210
|
port[port_key].each do |connection|
|
156
|
-
string << "\t#{port.class.to_s} '#{port.name}' (#{port.
|
211
|
+
string << "\t#{port.class.to_s} '#{port.name}' (#{port.uuid}) key '#{port_key}' connection '#{connection.name}' (#{connection.uuid})\n"
|
157
212
|
end
|
158
213
|
end
|
159
214
|
end
|
160
215
|
string
|
161
216
|
end
|
162
217
|
|
163
|
-
|
218
|
+
|
164
219
|
# Method that should be overridden by a subclass to provide for
|
165
220
|
# component-specific configuration. The subclass should use the
|
166
221
|
# self.configuration attribute (@configuration) to store its
|
@@ -168,7 +223,7 @@ class RFlow
|
|
168
223
|
# parameter is from the RFlow configuration database and is (most
|
169
224
|
# likely) a hash. Don't assume that the keys are symbols
|
170
225
|
def configure!(deserialized_configuration); end
|
171
|
-
|
226
|
+
|
172
227
|
# Main component running method. Subclasses should implement if
|
173
228
|
# they want to set up any EventMachine stuffs (servers, clients,
|
174
229
|
# etc)
|
@@ -187,6 +242,6 @@ class RFlow
|
|
187
242
|
# before the global RFlow exit. Sublcasses should implement to
|
188
243
|
# cleanup any leftover state, e.g. flush file handles, etc
|
189
244
|
def cleanup!; end
|
190
|
-
|
245
|
+
|
191
246
|
end # class Component
|
192
247
|
end # class RFlow
|
data/lib/rflow/component/port.rb
CHANGED
@@ -10,7 +10,7 @@ class RFlow
|
|
10
10
|
connection.send_message(message)
|
11
11
|
end
|
12
12
|
end
|
13
|
-
end
|
13
|
+
end
|
14
14
|
|
15
15
|
# Collection class to make it easier to index by both names,
|
16
16
|
# UUIDs, and types.
|
@@ -25,7 +25,7 @@ class RFlow
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def <<(port)
|
28
|
-
by_uuid[port.
|
28
|
+
by_uuid[port.uuid.to_s] = port
|
29
29
|
by_name[port.name.to_s] = port
|
30
30
|
by_type[port.class.to_s] << port
|
31
31
|
ports << port
|
@@ -42,12 +42,14 @@ class RFlow
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
45
|
-
|
46
45
|
|
47
|
-
# Bare superclass for (potential) later methods. Currently empty
|
48
|
-
class Port; end
|
49
46
|
|
50
|
-
|
47
|
+
class Port
|
48
|
+
attr_reader :connected
|
49
|
+
def connected?; @connected; end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
51
53
|
# Allows for a list of connections to be assigned to each port/key
|
52
54
|
# combination. Note that binding an input port to an un-indexed
|
53
55
|
# output port will result in messages from all indexed connections
|
@@ -55,14 +57,16 @@ class RFlow
|
|
55
57
|
# result in the same message being sent to all indexed
|
56
58
|
# connections.
|
57
59
|
class HashPort < Port
|
58
|
-
attr_reader :
|
59
|
-
|
60
|
-
def initialize(
|
61
|
-
@
|
62
|
-
@
|
60
|
+
attr_reader :config, :name, :uuid, :connections_for
|
61
|
+
|
62
|
+
def initialize(config)
|
63
|
+
@config = config
|
64
|
+
@name = config.name
|
65
|
+
@uuid = config.uuid
|
63
66
|
@connections_for = Hash.new {|hash, key| hash[key] = Array.new.extend(ConnectionCollection)}
|
64
67
|
end
|
65
68
|
|
69
|
+
|
66
70
|
# Returns an extended Array of all the connections that should
|
67
71
|
# be sent/received on this port. Merges the nil-keyed port
|
68
72
|
# (i.e. any connections for a port without a key) to those
|
@@ -79,7 +83,7 @@ class RFlow
|
|
79
83
|
connections_for[key] << connection
|
80
84
|
end
|
81
85
|
|
82
|
-
|
86
|
+
|
83
87
|
# Return a list of connected keys
|
84
88
|
def keys
|
85
89
|
connections_for.keys
|
@@ -94,13 +98,13 @@ class RFlow
|
|
94
98
|
end
|
95
99
|
end
|
96
100
|
|
97
|
-
|
101
|
+
|
98
102
|
# Send a message to all connections on all keys for this port,
|
99
103
|
# but only once per connection.
|
100
104
|
def send_message(message)
|
101
105
|
all_connections.send_message(message)
|
102
106
|
end
|
103
|
-
|
107
|
+
|
104
108
|
|
105
109
|
# Should be overridden. Called when it is time to actually
|
106
110
|
# establish the connection
|
@@ -113,38 +117,35 @@ class RFlow
|
|
113
117
|
connections
|
114
118
|
end.flatten.uniq.extend(ConnectionCollection)
|
115
119
|
end
|
116
|
-
|
120
|
+
|
117
121
|
end
|
118
122
|
|
119
|
-
|
123
|
+
|
120
124
|
class InputPort < HashPort
|
121
125
|
def connect!
|
122
126
|
connections_for.each do |port_key, connections|
|
123
127
|
connections.each do |connection|
|
124
128
|
connection.connect_input!
|
129
|
+
@connected = true
|
125
130
|
end
|
126
131
|
end
|
127
132
|
end
|
128
133
|
end
|
129
134
|
|
130
|
-
|
135
|
+
|
131
136
|
class OutputPort < HashPort
|
132
137
|
def connect!
|
133
138
|
connections_for.each do |port_key, keyed_connections|
|
134
139
|
keyed_connections.each do |connection|
|
135
140
|
connection.connect_output!
|
141
|
+
@connected = true
|
136
142
|
end
|
137
143
|
end
|
138
144
|
end
|
139
145
|
end
|
140
146
|
|
147
|
+
|
141
148
|
class DisconnectedPort < HashPort; end
|
142
|
-
|
149
|
+
|
143
150
|
end
|
144
151
|
end
|
145
|
-
|
146
|
-
__END__
|
147
|
-
|
148
|
-
out[even] -> a
|
149
|
-
out[odd] -> b
|
150
|
-
out[nil] -> c
|
data/lib/rflow/components/raw.rb
CHANGED
@@ -3,14 +3,14 @@ require 'rflow/components/raw/extensions'
|
|
3
3
|
class RFlow
|
4
4
|
module Components
|
5
5
|
module Raw
|
6
|
-
|
6
|
+
|
7
7
|
# Load the schemas
|
8
8
|
SCHEMA_DIRECTORY = ::File.expand_path(::File.join(::File.dirname(__FILE__), '..', '..', '..', 'schema'))
|
9
|
-
|
9
|
+
|
10
10
|
SCHEMA_FILES = {
|
11
11
|
'raw.avsc' => 'RFlow::Message::Data::Raw',
|
12
12
|
}
|
13
|
-
|
13
|
+
|
14
14
|
SCHEMA_FILES.each do |file_name, data_type_name|
|
15
15
|
schema_string = ::File.read(::File.join(SCHEMA_DIRECTORY, file_name))
|
16
16
|
RFlow::Configuration.add_available_data_type data_type_name, 'avro', schema_string
|
@@ -20,7 +20,7 @@ class RFlow
|
|
20
20
|
RFlow::Configuration.add_available_data_extension('RFlow::Message::Data::Raw',
|
21
21
|
RFlow::Components::Raw::Extensions::RawExtension)
|
22
22
|
|
23
|
-
|
23
|
+
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
data/lib/rflow/configuration.rb
CHANGED
@@ -17,13 +17,13 @@ class RFlow
|
|
17
17
|
# An exception class
|
18
18
|
class ConfigurationInvalid < StandardError; end
|
19
19
|
|
20
|
-
|
20
|
+
|
21
21
|
# A class to hold DB config and connection information
|
22
22
|
class ConfigDB < ActiveRecord::Base
|
23
23
|
self.abstract_class = true
|
24
24
|
end
|
25
|
-
|
26
|
-
|
25
|
+
|
26
|
+
|
27
27
|
# A collection class for data extensions that supports a naive
|
28
28
|
# prefix-based 'inheritance' on lookup. When looking up a key
|
29
29
|
# with [] all existing keys will be examined to determine if the
|
@@ -55,10 +55,10 @@ class RFlow
|
|
55
55
|
def clear
|
56
56
|
@hash.clear
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
end
|
60
60
|
|
61
|
-
|
61
|
+
|
62
62
|
class << self
|
63
63
|
|
64
64
|
# A collection of data types (schemas) indexed by their name and
|
@@ -119,7 +119,7 @@ class RFlow
|
|
119
119
|
available_data_extensions.add data_type_name, data_extension
|
120
120
|
end
|
121
121
|
|
122
|
-
|
122
|
+
|
123
123
|
# Used when RFlow::Component is subclassed to add another
|
124
124
|
# available component to the list.
|
125
125
|
def self.add_available_component(component)
|
@@ -141,8 +141,8 @@ class RFlow
|
|
141
141
|
ConfigDB.establish_connection(:adapter => "sqlite3",
|
142
142
|
:database => config_database_path)
|
143
143
|
end
|
144
|
-
|
145
|
-
|
144
|
+
|
145
|
+
|
146
146
|
# Using default ActiveRecord migrations, attempt to migrate the
|
147
147
|
# database to the latest version.
|
148
148
|
def self.migrate_database
|
@@ -160,7 +160,7 @@ class RFlow
|
|
160
160
|
load config_file_path
|
161
161
|
end
|
162
162
|
|
163
|
-
|
163
|
+
|
164
164
|
# Connect to the configuration database, migrate it to the latest
|
165
165
|
# version, and process a config file if provided.
|
166
166
|
def self.initialize_database(config_database_path, config_file_path=nil)
|
@@ -172,7 +172,7 @@ class RFlow
|
|
172
172
|
:database => config_database_path)
|
173
173
|
|
174
174
|
migrate_database
|
175
|
-
|
175
|
+
|
176
176
|
expanded_config_file_path = File.expand_path config_file_path if config_file_path
|
177
177
|
|
178
178
|
working_dir = Dir.getwd
|
@@ -183,12 +183,14 @@ class RFlow
|
|
183
183
|
end
|
184
184
|
|
185
185
|
RFlow.logger.debug "Defaulting non-existing config values"
|
186
|
-
merge_defaults!
|
186
|
+
merge_defaults!
|
187
187
|
|
188
188
|
Dir.chdir working_dir
|
189
|
+
|
190
|
+
self.new(config_database_path)
|
189
191
|
end
|
190
192
|
|
191
|
-
|
193
|
+
|
192
194
|
# Make sure that the configuration has all the necessary values set.
|
193
195
|
def self.merge_defaults!
|
194
196
|
Setting::DEFAULTS.each do |name, default_value_or_proc|
|
@@ -202,8 +204,8 @@ class RFlow
|
|
202
204
|
end
|
203
205
|
end
|
204
206
|
end
|
205
|
-
|
206
|
-
|
207
|
+
|
208
|
+
|
207
209
|
attr_accessor :config_database_path
|
208
210
|
attr_accessor :cached_settings
|
209
211
|
attr_accessor :cached_components
|
@@ -211,19 +213,24 @@ class RFlow
|
|
211
213
|
attr_accessor :cached_connections
|
212
214
|
|
213
215
|
|
214
|
-
def initialize(config_database_path)
|
216
|
+
def initialize(config_database_path=nil)
|
215
217
|
@cached_settings = Hash.new
|
216
218
|
@cached_components = Hash.new
|
217
219
|
@cached_ports = []
|
218
220
|
@cached_connections = []
|
219
221
|
|
220
|
-
|
221
|
-
|
222
|
+
# If there is not a config DB path, assume that an AR
|
223
|
+
# conncection has already been established
|
224
|
+
if config_database_path
|
225
|
+
@config_database_path = config_database_path
|
226
|
+
self.class.establish_config_database_connection(config_database_path)
|
227
|
+
end
|
222
228
|
|
223
229
|
# Validate the connected database. TODO: make this more
|
224
230
|
# complete, i.e. validate the various columns
|
225
231
|
begin
|
226
232
|
Setting.first
|
233
|
+
Shard.first
|
227
234
|
Component.first
|
228
235
|
Port.first
|
229
236
|
Connection.first
|
@@ -234,44 +241,54 @@ class RFlow
|
|
234
241
|
end
|
235
242
|
end
|
236
243
|
|
237
|
-
|
244
|
+
|
238
245
|
def to_s
|
239
246
|
string = "Configuration:\n"
|
247
|
+
|
240
248
|
settings.each do |setting|
|
241
249
|
string << "Setting: '#{setting.name}' = '#{setting.value}'\n"
|
242
250
|
end
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
+
|
252
|
+
shards.each do |shard|
|
253
|
+
string << "Shard #{shard.name} (#{shard.uuid}), type #{shard.class.name}, count #{shard.count}\n"
|
254
|
+
shard.components.each do |component|
|
255
|
+
string << " Component '#{component.name}' as #{component.specification} (#{component.uuid})\n"
|
256
|
+
component.output_ports.each do |output_port|
|
257
|
+
output_port.output_connections.each do |output_connection|
|
258
|
+
input_port = output_connection.input_port
|
259
|
+
string << " OutputPort '#{output_port.name}' key '#{output_connection.output_port_key}' (#{output_port.uuid}) =>\n"
|
260
|
+
string << " Connection '#{output_connection.name}' as #{output_connection.type} (#{output_connection.uuid}) =>\n"
|
261
|
+
string << " InputPort '#{input_port.name}' key '#{output_connection.input_port_key}' (#{input_port.uuid}) Component '#{input_port.component.name}' (#{input_port.component.uuid})\n"
|
262
|
+
end
|
251
263
|
end
|
252
264
|
end
|
253
265
|
end
|
254
266
|
string
|
255
267
|
end
|
256
|
-
|
268
|
+
|
257
269
|
# Helper method to access settings with minimal syntax
|
258
270
|
def [](setting_name)
|
259
271
|
Setting.find_by_name(setting_name).value rescue nil
|
260
272
|
end
|
261
273
|
|
262
|
-
|
274
|
+
def settings
|
275
|
+
Setting.all
|
276
|
+
end
|
277
|
+
|
278
|
+
def shards
|
279
|
+
Shard.all
|
280
|
+
end
|
281
|
+
|
282
|
+
def shard(shard_uuid)
|
283
|
+
Shard.find_by_uuid shard_uuid
|
284
|
+
end
|
285
|
+
|
263
286
|
def components
|
264
287
|
Component.all
|
265
288
|
end
|
266
289
|
|
267
|
-
|
268
|
-
|
269
|
-
Component.find_by_uuid component_instance_uuid
|
270
|
-
end
|
271
|
-
|
272
|
-
|
273
|
-
def settings
|
274
|
-
Setting.all
|
290
|
+
def component(component_uuid)
|
291
|
+
Component.find_by_uuid component_uuid
|
275
292
|
end
|
276
293
|
|
277
294
|
def available_components
|
@@ -282,6 +299,7 @@ end
|
|
282
299
|
|
283
300
|
# Load the models
|
284
301
|
require 'rflow/configuration/setting'
|
302
|
+
require 'rflow/configuration/shard'
|
285
303
|
require 'rflow/configuration/component'
|
286
304
|
require 'rflow/configuration/port'
|
287
305
|
require 'rflow/configuration/connection'
|