cloud_powers 0.2.7.23 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.test.env.example +6 -6
  4. data/.travis.yml +1 -1
  5. data/README +190 -0
  6. data/cloud_powers.gemspec +4 -4
  7. data/lib/cloud_powers.rb +3 -13
  8. data/lib/cloud_powers/aws_resources.rb +21 -4
  9. data/lib/cloud_powers/creatable.rb +122 -0
  10. data/lib/cloud_powers/helpers.rb +58 -0
  11. data/lib/cloud_powers/helpers/lang_help.rb +288 -0
  12. data/lib/cloud_powers/helpers/logic_help.rb +152 -0
  13. data/lib/cloud_powers/helpers/path_help.rb +90 -0
  14. data/lib/cloud_powers/node.rb +69 -68
  15. data/lib/cloud_powers/node/instance.rb +52 -0
  16. data/lib/cloud_powers/resource.rb +44 -0
  17. data/lib/cloud_powers/storage.rb +27 -14
  18. data/lib/{stubs → cloud_powers/stubs}/aws_stubs.rb +37 -14
  19. data/lib/cloud_powers/synapse/broadcast.rb +117 -0
  20. data/lib/cloud_powers/synapse/broadcast/channel.rb +44 -0
  21. data/lib/cloud_powers/synapse/pipe.rb +211 -0
  22. data/lib/cloud_powers/synapse/pipe/stream.rb +41 -0
  23. data/lib/cloud_powers/synapse/queue.rb +357 -0
  24. data/lib/cloud_powers/synapse/queue/board.rb +61 -95
  25. data/lib/cloud_powers/synapse/queue/poller.rb +29 -0
  26. data/lib/cloud_powers/synapse/synapse.rb +10 -12
  27. data/lib/cloud_powers/synapse/web_soc.rb +13 -0
  28. data/lib/cloud_powers/synapse/web_soc/soc_client.rb +52 -0
  29. data/lib/cloud_powers/synapse/web_soc/soc_server.rb +48 -0
  30. data/lib/cloud_powers/version.rb +1 -1
  31. data/lib/cloud_powers/zenv.rb +13 -12
  32. metadata +24 -13
  33. data/lib/cloud_powers/context.rb +0 -275
  34. data/lib/cloud_powers/delegator.rb +0 -113
  35. data/lib/cloud_powers/helper.rb +0 -453
  36. data/lib/cloud_powers/synapse/websocket/websocclient.rb +0 -53
  37. data/lib/cloud_powers/synapse/websocket/websocserver.rb +0 -46
  38. data/lib/cloud_powers/workflow_factory.rb +0 -160
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloud_powers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7.23
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Phillipps
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2016-11-03 00:00:00.000000000 Z
13
+ date: 2016-12-23 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport-core-ext
@@ -199,16 +199,16 @@ description: |2
199
199
  It was developed specifically for the Brain project but hopefully can be used
200
200
  in any other ruby project that needs to use cloud service providers' resources.
201
201
 
202
- Version 0.2.8 has a some EC2, S3, SQS, SNS, Kinesis, websockets and a few other
202
+ Version 1.0 has a some EC2, S3, SQS, SNS, Kinesis, websockets and a few other
203
203
  features you can find in the docs. There is also limitted support for stubbing
204
204
  AWS RESTful API calls. That can come in handy for local testing and extra setup on
205
205
  AWS resource clients.
206
206
 
207
- The next versions will have more Kinesis, Workflow integration and IoT.
208
-
209
207
  This project is actively being developed, so more additions, specs and docs
210
208
  will be added and updated frequently with new funcionality but the gem will
211
- follow good practices for versioning. Input is always welcome.
209
+ follow good practices for versioning and so the behavior won't change on
210
+ existing features.
211
+ Input is always welcome. :thumbsup:
212
212
  Enjoy!
213
213
  email:
214
214
  - adam.phillipps@gmail.com
@@ -225,6 +225,7 @@ files:
225
225
  - ".travis.yml"
226
226
  - Gemfile
227
227
  - LICENSE.txt
228
+ - README
228
229
  - README.md
229
230
  - README.rdoc.mdown
230
231
  - Rakefile
@@ -234,24 +235,34 @@ files:
234
235
  - lib/cloud_powers.rb
235
236
  - lib/cloud_powers/auth.rb
236
237
  - lib/cloud_powers/aws_resources.rb
237
- - lib/cloud_powers/context.rb
238
- - lib/cloud_powers/delegator.rb
239
- - lib/cloud_powers/helper.rb
238
+ - lib/cloud_powers/creatable.rb
239
+ - lib/cloud_powers/helpers.rb
240
+ - lib/cloud_powers/helpers/lang_help.rb
241
+ - lib/cloud_powers/helpers/logic_help.rb
242
+ - lib/cloud_powers/helpers/path_help.rb
240
243
  - lib/cloud_powers/node.rb
244
+ - lib/cloud_powers/node/instance.rb
245
+ - lib/cloud_powers/resource.rb
241
246
  - lib/cloud_powers/self_awareness.rb
242
247
  - lib/cloud_powers/smash_error.rb
243
248
  - lib/cloud_powers/storage.rb
249
+ - lib/cloud_powers/stubs/aws_stubs.rb
250
+ - lib/cloud_powers/synapse/broadcast.rb
244
251
  - lib/cloud_powers/synapse/broadcast/broadcast.rb
252
+ - lib/cloud_powers/synapse/broadcast/channel.rb
253
+ - lib/cloud_powers/synapse/pipe.rb
245
254
  - lib/cloud_powers/synapse/pipe/pipe.rb
255
+ - lib/cloud_powers/synapse/pipe/stream.rb
256
+ - lib/cloud_powers/synapse/queue.rb
246
257
  - lib/cloud_powers/synapse/queue/board.rb
258
+ - lib/cloud_powers/synapse/queue/poller.rb
247
259
  - lib/cloud_powers/synapse/queue/queue.rb
248
260
  - lib/cloud_powers/synapse/synapse.rb
249
- - lib/cloud_powers/synapse/websocket/websocclient.rb
250
- - lib/cloud_powers/synapse/websocket/websocserver.rb
261
+ - lib/cloud_powers/synapse/web_soc.rb
262
+ - lib/cloud_powers/synapse/web_soc/soc_client.rb
263
+ - lib/cloud_powers/synapse/web_soc/soc_server.rb
251
264
  - lib/cloud_powers/version.rb
252
- - lib/cloud_powers/workflow_factory.rb
253
265
  - lib/cloud_powers/zenv.rb
254
- - lib/stubs/aws_stubs.rb
255
266
  homepage: https://github.com/adam-phillipps/cloud_powers
256
267
  licenses:
257
268
  - MIT
@@ -1,275 +0,0 @@
1
- require 'json'
2
- require_relative 'helper'
3
-
4
- module Smash
5
- module CloudPowers
6
- # The Context class is the class that handles serializing the Context so that it
7
- # can be passed from node to node and rebuilt. This provides a way for nodes in
8
- # the same Brain to have an awareness of required communication modes, for example.
9
- # Because resources generally require some sort of information to connect with
10
- # or create and a Brain operates in the same Context, it can use the Context to
11
- # decouple the creation and usage from the coordination.
12
- class Context
13
- include Smash::CloudPowers::Helper
14
-
15
- attr_accessor :package # The given data structure that is used to build @structure
16
-
17
- # Attempts to create a Context out of the argument(s) you've
18
- # passed.
19
- #
20
- # Parameters
21
- # * args +Hash+|+JSON+|+Array+|+Enumerable+
22
- # * * expample +Hash+:
23
- # * * * each key is a module or class that is in CloudPowers and each value
24
- # is either an array of configurations information or a single configuration.
25
- # { task: 'demo', queue: [:backlog, :sned], pipe: :status_stream }
26
- # * * expample Array
27
- # * * * each key is followed by 0..n valid configurations information
28
- # [:task, 'demo', :queue, :backlog, :sned, :pipe, :status_stream]
29
- #
30
- # Returns
31
- # +Smash::Context+
32
- def initialize(args)
33
- unless valid_args?(args)
34
- raise ArgumentError.new 'Can be either a Hash, JSON, or an Enumerable ' +
35
- "arguments: #{args}"
36
- end
37
- @package = args
38
- @structure = decipher(args)
39
- end
40
-
41
- # Decipher figures out which translation method to use by making some simple type checks, etc.
42
- # and then routing the args to the correct method.
43
- #
44
- # Notes
45
- # * See +#translate_json()+
46
- # * See +#translate_list()+
47
- def decipher(args)
48
- case args
49
- when Hash
50
- args
51
- when String
52
- translate_json(args)
53
- when Enumerable
54
- translate_list(args)
55
- end
56
- end
57
-
58
- # Creates a flat Array of the 2-D Array that gets returned from `#simplify()`
59
- #
60
- # Returns +Array+
61
- #
62
- # Example
63
- # example_context.structure
64
- # # => { task: 'demo', queue: [:backlog, :sned], pipe: [:status_stream] }
65
- # example.flatten
66
- # # => [:task, 'demo', :queue, :backlog, :sned, :pipe, :status_stream]
67
- #
68
- # Notes
69
- # * See +#simplify()
70
- # * See +#Array::flatten()+
71
- def flatten
72
- simplify.flatten
73
- end
74
-
75
- # Create an array version of @sructure by calling `#to_a()` on it
76
- #
77
- # Returns
78
- # <tt>Array[Array..n]</tt>
79
- #
80
- # Example
81
- # example_context.structure
82
- # # => { task: 'demo', queue: [:backlog, :sned], pipe: [:status_stream] }
83
- # example.simplify
84
- # # => [:task, 'demo', :queue, [:backlog, :sned], :pipe, [:status_stream]]
85
- #
86
- # Notes
87
- # * This uses the different Constants, like Smash, Synapse and anything it can find
88
- # to decide what should be used as a key and what its following values array should
89
- # contain. It basically says:
90
- # 1. if the nth item is a known key (from the above search), add it as an object in the Array.
91
- # 2. else, add it to the last sub-Array
92
- # 3. move to n+1 in the +structure Hash+
93
- # * TODO: Check if this has a limit to n-layers
94
- def simplify
95
- @structure.to_a
96
- end
97
-
98
- # A Hash that represents the resources and some configuration for them
99
- #
100
- # Returns +Hash+
101
- def structure
102
- modify_keys_with(@structure) { |key| key.to_sym }
103
- end
104
-
105
- # Valid scheme for @structure is assured by running the arguments through
106
- # the decipher method, which is how @structure is set in +#new(args)+
107
- def structure=(args)
108
- @structure = decipher(args)
109
- end
110
-
111
- # Parse the given JSON
112
- # Parameters
113
- # +JSON+
114
- # Returns
115
- # +Hash+
116
- def translate_json(json_string)
117
- begin
118
- JSON.parse(json_string)
119
- rescue JSON::ParserError
120
- raise ArgumentError "Incorrectly formatted JSON"
121
- end
122
- end
123
-
124
- # Re-layer this flattened Array or enumerable list so that it looks like the
125
- # Hash that it used to be before the Smash::Context#flatten() method was called
126
- #
127
- # Parameters
128
- # +Array+|+List+|+Enumerable+
129
- #
130
- # Example
131
- # * flat
132
- #
133
- # [
134
- # object_name_1, config_1a, config_2a, ...,
135
- # object_2, config_1b, etc,
136
- # ...
137
- # ]
138
- #
139
- # * or grouped
140
- #
141
- # [
142
- # [object_name_1, config_1a, config_2a, ...],
143
- # [object_2, config_1b, etc],
144
- # ...
145
- # ]
146
- #
147
- # * or structured
148
- #
149
- # [
150
- # [object_name_1, [config_1a, config_2a, ...]],
151
- # [object_2, [config_1b, etc]],
152
- # ...
153
- # ]
154
- #
155
- # * returns
156
- #
157
- # {
158
- # object_1: [config_1a, config_2a, ...],
159
- # object_2: [config_1b, ...],
160
- # ...
161
- # }
162
- # Returns
163
- # +Hash+
164
- #
165
- # Notes
166
- # If +#valid_package_hash?()+ is called on this Hash, it will return true
167
- def translate_list(list)
168
- list.first.kind_of?(Enumerable) ? translate_simplified(list) : translate_flattened(list)
169
- end
170
-
171
- # Translates an Array into a valid @structure Hash
172
- # Parameters arr <Array>
173
- # e.g.
174
- # [:task, ['demo'], :queue, ['name1','name2',.,.,.,.,.], {other config hash},..., :pipe, ['name1']
175
- # Returns
176
- # +Hash+
177
- # Notes
178
- # * calling +#valid_hash_format?()+ on returned Hash will return true
179
- def translate_flattened(list)
180
- arr = list.to_a
181
- results = []
182
- # get the indexes of CloudPowers resources in arr
183
- key_locations = arr.each_with_index.collect do |key, i, _|
184
- i if available_resources.include?(to_pascal(key).to_sym)
185
- end.reject(&:nil?)
186
- key_locations << arr.size # add the last index into the ranges
187
- # use each pair as ranges to slice up the Array
188
- key_locations.each_cons(2) do |current_i, next_i|
189
- results << [arr[current_i], arr[(current_i+1)..(next_i-1)]]
190
- end
191
-
192
- translate_simplified(results)
193
- end
194
-
195
- # Translates a 2D Array into a valid @structure Hash
196
- # Parameters arr <Array>
197
- # e.g.
198
- # ```
199
- # [
200
- # [:task, 'demo'],
201
- # [:queue, 'name1', {other config hash},...],
202
- # [:pipe, 'name1']
203
- # ...
204
- # ]
205
- # ```
206
- # - Needs to be a 2D Array
207
- # - First object of each inner-Array is the key
208
- # - All following values in that inner Array are separate configuration
209
- # information pieces that can be used in the `#create!()` method for that particular resource
210
- # Returns Hash
211
- # well formatted for the @structure
212
- def translate_simplified(arr)
213
- arr.inject({}) do |hash, key_config_map|
214
- hash.tap do |h|
215
- key = key_config_map.shift
216
- h[key.to_sym] = *key_config_map.flatten
217
- end
218
- end
219
- end
220
-
221
- # Uses `#to_json()` on the @structure
222
- # Returns Hash
223
- def to_json
224
- structure.to_json
225
- end
226
-
227
- # The Context class can be initialized in any of the formats that a Context
228
- # class _should_ exist in. It can be a vanilla version, where the @structure
229
- # is a Hash, structured correctly or it can be serialized into JSON or it can
230
- # be an Array
231
- # Parameters args String
232
- # Returns Boolean
233
- def valid_args?(args)
234
- case args
235
- when Hash
236
- valid_hash_format?(args)
237
- when String
238
- valid_json_format?(args)
239
- when Enumerable
240
- valid_array_format?(args)
241
- else
242
- false
243
- end
244
- end
245
-
246
- # Makes sure that the list is enumerable and that at least the first term
247
- # is a resource name from Smash::CloudPowers. All other objects can
248
- # potentially be configurations.
249
- # Parameters list <Array|Enumerable>
250
- # Returns Boolean
251
- def valid_array_format?(list)
252
- use = list.first.kind_of?(Enumerable) ? list.first.first : list.first
253
- ((list.kind_of? Enumerable) && (available_resources.include?(to_pascal(use).to_sym)))
254
- end
255
-
256
- # Makes sure that each key is the name of something CloudPowers can interact with
257
- # Parameters hash <Hash>
258
- # Returns Boolean
259
- def valid_hash_format?(hash)
260
- keys_arr = hash.keys.map { |key| to_pascal(key).to_sym }
261
- (keys_arr - available_resources).empty?
262
- end
263
-
264
- # Parses the json_string which yields a Hash or an exception. From there,
265
- # use the #valid_hash_format?() method
266
- def valid_json_format?(json_string)
267
- begin
268
- valid_hash_format?(JSON.parse(json_string))
269
- rescue JSON::ParserError
270
- false
271
- end
272
- end
273
- end
274
- end
275
- end
@@ -1,113 +0,0 @@
1
- # require 'auth'
2
- # require 'aws_resources'
3
- require 'json'
4
- require_relative 'helper'
5
- require_relative 'storage'
6
-
7
- module Smash
8
- module CloudPowers
9
- # The Delegator module is a way to dynamically source and use
10
- # Ruby source code. You pass a message or something that can
11
- # respond to +#body()+ and give back a String. The String should
12
- # be the name of the class you're trying to instantiate and use
13
- module Delegator
14
- extend Smash::CloudPowers::Auth
15
- include Smash::CloudPowers::AwsResources
16
- include Smash::CloudPowers::Helper
17
- include Smash::CloudPowers::Storage
18
-
19
- # Predicate method to return true for valid job titles and false for invalid ones
20
- #
21
- # Parameters
22
- # * name +String+ (optional) - name of the task in snake_case
23
- #
24
- # Returns
25
- # +Boolean+
26
- #
27
- # Notes
28
- # * TODO: needs improvement
29
- def approved_task?(name = nil)
30
- ['demo', 'testinz', 'true_roas'].include? to_snake(name)
31
- end
32
-
33
- # responsible for sourcing, loading into the global namespace
34
- # and use of Ruby source code, through the +#new()+ method on
35
- # that class
36
- #
37
- # Parameters
38
- # * id +String+ - the instance id of the calling node. This gets
39
- # used in communication tools etc.
40
- # * msg - Anything that responds to +#body()+ and returns a String
41
- # that can be used in the search for the file in your local and S3
42
- # bucket locations
43
- #
44
- # Returns
45
- # +Object+ - a newly instantiated object of the class that matches
46
- # the name retrieved from the +msg+ parameter
47
- #
48
- # Example
49
- # class Job; include Smash::CloudPowers::Delegator; end
50
- # job = Job.new
51
- # # the message responds to +#body()+ with "ExampleTask"
52
- # job.build('abc-1234', Aws::SQS::Message)
53
- # # => +ExampleTask:Object+
54
- def build(id, msg)
55
- body = decipher_message(msg)
56
- begin
57
- task = body['task']
58
- if approved_task? task
59
- source_task(task)
60
- require_relative task_require_path(task)
61
- Smash.const_get(to_pascal(task)).public_send :create, id, body
62
- else
63
- Smash::Task.new(id, body) # returns a default Task
64
- end
65
- rescue JSON::ParserError
66
- message = [msg.body, format_error_message(e)].join("\n")
67
- logger.info "Message in backlog is ill-formatted: #{message}"
68
- pipe_to(:status_stream) { sitrep(extraInfo: { message: message }) }
69
- end
70
- end
71
-
72
- # Get the body of the message out from a few different types of objects.
73
- # The idea is to allow JSON, a String or some object that responds to :body
74
- # through while continually attempting to decipher other types of objects
75
- # finally giving up. But wait, after it gives up, it just turns it into a
76
- # Hash and assumes that the value is a Task name.
77
- #
78
- # Parameters
79
- # * msg +String+
80
- #
81
- # Returns
82
- # +Hash+
83
- #
84
- # Example
85
- # # given hash_message = { task: 'example' }
86
- # # givem json_message = "\{"task":"example"\}"
87
- # # given message_with_body = <Object @body="stuff stuff stuff">
88
- #
89
- # decipher_message(hash_message)
90
- # # => { task: 'example' }
91
- # decipher_message(json_message)
92
- # # => { task: 'example' }
93
- # decipher_message(message_with_body)
94
- # # => { task: 'example' }
95
- # decipher_message('some ridiculous string')
96
- # # => { task: 'some_ridiculous_string'}
97
- #
98
- # Notes
99
- # See +#to_snake()+
100
- def decipher_message(msg)
101
- begin
102
- if msg.respond_to? :body
103
- decipher_message(msg.body)
104
- else
105
- msg.kind_of?(Hash) ? msg : JSON.parse(msg)
106
- end
107
- rescue Exception
108
- { task: to_snake(msg.to_s) }
109
- end
110
- end
111
- end
112
- end
113
- end