cloud_powers 0.2.7.23 → 1.0.0

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.
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
@@ -1,453 +0,0 @@
1
- require 'logger'
2
- require 'fileutils'
3
- require 'pathname'
4
- require 'uri'
5
- require 'syslog/logger'
6
- require_relative 'smash_error'
7
-
8
- module Smash
9
- module CloudPowers
10
- module Helper
11
-
12
- # Sets an Array of instance variables, individually to a value that a
13
- # user given block returns.
14
- #
15
- # Parameters
16
- #
17
- # * keys +Array+
18
- # * * each object will be used as the name for the instance variable that
19
- # your block returns
20
- # +block+ (optional)
21
- # * this block is called for each object in the Array and is used as the value
22
- # for the instance variable that is being named and created for each key
23
- # Returns Array
24
- # * each object will either be the result of `#instance_variable_set(key, value)`
25
- # or instance_variable_get(key)
26
- # Example
27
- # keys = ['foo', 'bar', 'yo']
28
- #
29
- # attr_map!(keys) { |key| sleep 1; "#{key}:#{Time.now.to_i}" }
30
- # # => ['foo:1475434058', 'bar:1475434059', 'yo:1475434060']
31
- #
32
- # puts @bar
33
- # # => 'bar:1475434059'
34
- def attr_map!(keys)
35
- keys.map do |key|
36
- new_i_var = to_i_var(key)
37
- value = yield key if block_given?
38
- instance_variable_set(new_i_var, value) unless instance_variable_get(new_i_var)
39
- end
40
- end
41
-
42
- # This is a way to find out if you are trying to work with a resource
43
- # available to CloudPowers
44
- #
45
- # Returns <Array>
46
- # Use +.constants+ to find all the modules and classes available.
47
- #
48
- # Notes
49
- # * TODO: make this smartly pick up all the objects, within reason and
50
- # considering need, that we have access to
51
- def available_resources
52
- [:Task].concat(Smash::CloudPowers.constants)
53
- end
54
-
55
- # Does its best job at guessing where this method was called from, in terms
56
- # of where it is located on the file system. It helps track down where a
57
- # project root is etc.
58
- #
59
- # Returns
60
- # +String+
61
- #
62
- # Notes
63
- # * Uses +$0+ to figure out what the current file is
64
- def called_from
65
- File.expand_path(File.dirname($0))
66
- end
67
-
68
- # creates a default logger
69
- #
70
- # Parameters
71
- # * log_to +String+ (optional) - location to send logging information to; default is STDOUT
72
- #
73
- # Returns
74
- # +Logger+
75
- #
76
- # Notes
77
- # * TODO: at least make this have overridable defaults
78
- def create_logger(log_to = STDOUT)
79
- logger = Logger.new(log_to)
80
- logger.datetime_format = '%Y-%m-%d %H:%M:%S'
81
- logger
82
- end
83
-
84
- # Allows you to modify all keys, including nested, with a block that you pass.
85
- # If no block is passed, a copy is returned.
86
- #
87
- # Parameters
88
- # * params +Hash+|+Array+ - hash to be modified
89
- # * +block+ (optional) - a block to be used to modify each key should
90
- # modify the key and return that value so it can be used in the copy
91
- #
92
- # Returns
93
- # +Hash+|+Array+ - a copy of the given Array or Hash, with all Hash keys modified
94
- #
95
- # Example
96
- # hash = { 'foo' => 'v1', 'bar' => { fleep: { 'florp' => 'yo' } } }
97
- # modify_keys_with(hash) { |key| key.to_sym }
98
- # # => { foo: 'v1', bar: { fleep: { florp: 'yo' } } }
99
- #
100
- # Notes
101
- # * see `#modify_keys_with()` for handling first-level keys
102
- # * see `#pass_the_buck()` for the way nested structures are handled
103
- # * case for different types taken from _MultiXML_ (multi_xml.rb)
104
- # * TODO: look at optimization
105
- def deep_modify_keys_with(params)
106
- case params
107
- when Hash
108
- params.inject({}) do |carry, (k, v)|
109
- carry.tap do |h|
110
- if block_given?
111
- key = yield k
112
-
113
- value = if v.kind_of?(Hash)
114
- deep_modify_keys_with(v) { |new_key| Proc.new.call(new_key) }
115
- else
116
- v
117
- end
118
-
119
- h[key] = value
120
- else
121
- h[k] = v
122
- end
123
- end
124
- end
125
- when Array
126
- params.map{ |value| symbolize_keys(value) }
127
- else
128
- params
129
- end
130
- end
131
-
132
- # Join the message and backtrace into a String with line breaks
133
- #
134
- # Parameters
135
- # * error +Exception+
136
- #
137
- # Returns
138
- # +String+
139
- def format_error_message(error)
140
- begin
141
- [error.message, error.backtrace.join("\n")].join("\n")
142
- rescue Exception
143
- # if the formatting won't work, return the original exception
144
- error
145
- end
146
- end
147
-
148
- # Gets the path from the environment and sets @log_file using the path
149
- #
150
- # Returns
151
- # @log_file +String+
152
- #
153
- # Notes
154
- # * See +#zfind()+
155
- def log_file
156
- @log_file ||= zfind('LOG_FILE')
157
- end
158
-
159
- # Returns An instance of Logger, cached as @logger@log_file path <String>
160
- #
161
- # Returns
162
- # +Logger+
163
- #
164
- # Notes
165
- # * See +#create_logger+
166
- def logger
167
- @logger ||= create_logger
168
- end
169
-
170
- # Allows you to modify all first-level keys with a block that you pass.
171
- # If no block is passed, a copy is returned.
172
- #
173
- # Parameters
174
- # * params +Hash+|+Array+
175
- # * block (optional) - should modify the key and return that value so it can be used in the copy
176
- #
177
- # Returns
178
- # +Hash+|+Array+ - a copy of the given Array or Hash, with all Hash keys modified
179
- #
180
- # Example
181
- # hash = { 'foo' => 'v1', 'bar' => { fleep: { 'florp' => 'yo' } } }
182
- # modify_keys_with(hash) { |k| k.to_sym }
183
- # # => { :foo => 'v1', :bar => { fleep: { 'florp' => 'yo' } } }
184
- #
185
- # Notes
186
- # * see +#deep_modify_keys_with()+ for handling nested keys
187
- # * case for different types taken from _MultiXML_ (multi_xml.rb)
188
- def modify_keys_with(params)
189
- params.inject({}) do |carry, (k, v)|
190
- carry.tap do |h|
191
- key = block_given? ? (yield k) : k
192
- h[key] = v
193
- end
194
- end
195
- end
196
-
197
- # Lets you retry a piece of logic with 1 second sleep in between attempts
198
- # until another bit of logic does what it's supposed to, kind of like
199
- # continuing to poll something and doing something when a package is ready
200
- # to be taken and processed.
201
- #
202
- # Parameters
203
- # * allowed_attempts +Number+|+Infinity(default)+ - The number of times
204
- # the loop should be allowed to...well, loop, before a failed retry occurs.
205
- # * &test +Block+ - A predicate method or block of code that is callable
206
- # is used to test if the block being retried is successful yet.
207
- # * []
208
- #
209
- # Example
210
- # check_stuff = lambda { |params| return true }
211
- # smart_retry(3, check_stuff(params)) { do_stuff_that_needs_to_be_checked }
212
- def smart_retry(test, allowed_attempts = Float::INFINITY)
213
- result = yield if block_given?
214
- tries = 1
215
- until test.call(result) || tries >= allowed_attempts
216
- result = yield if block_given?
217
- tries += 1
218
- sleep 1
219
- end
220
- end
221
-
222
- # Gives a common home for tasks to live so they can be easily grouped and
223
- # found. This method will create nested directories, based on the
224
- # <tt>#project_root()</tt> method and an additional 'lib/tasks' directory.
225
- # If no project root has been set by the time this method is called, a new
226
- # directory will be created relative to the gem's project root.
227
- #
228
- # Returns
229
- # +String+
230
- #
231
- # Notes
232
- # * # If no project root has been set by the time this method is called, a new
233
- # directory will be created relative to the gem's project root. This might
234
- # have deeper implications than you want to deal with so it's always a good
235
- # idea to set your project root as soon as you can.
236
- # * TODO: find a way to have this method figure out the actual project's
237
- # root, as opposed to just making common <i>"good"</i> assumptions.
238
- def task_home
239
- string_th = FileUtils.mkdir_p("#{project_root}/lib/tasks/").first
240
- @task_home ||= Pathname.new(string_th).realpath.to_s
241
- end
242
-
243
- # Gives the path from the project root to lib/tasks[/#{file}.rb]
244
- #
245
- # Parameters
246
- # * file +String+ (optional) (default is '') - name of a file
247
- #
248
- # Returns
249
- # * path/file +String+ if +file+ parameter is given. return has
250
- # '.rb' extension included
251
- # * file +String+ if +file+ parameter is not given it will return the <tt>#task_require_path()</tt>
252
- #
253
- # Notes
254
- # * See <tt>#task_home</tt>
255
- def task_path(file = '')
256
- return task_home if file.empty?
257
- Pathname.new("#{task_home}/#{file}").to_s
258
- end
259
-
260
-
261
- # Check if the task file exists in the task directory
262
- #
263
- # Parameters
264
- # * file +String+
265
- #
266
- # Returns
267
- # +Boolean+
268
- #
269
- # Notes
270
- # * See +#task_home()+
271
- def task_exist?(file)
272
- begin
273
- File.new("#{task_home}/#{file}")
274
- true
275
- rescue Errno::ENOENT
276
- false
277
- end
278
- end
279
-
280
- # Gives the path from the project root to lib/tasks[/file]
281
- #
282
- # Parameters String (optional)
283
- # * file_name name of a file
284
- #
285
- # Returns
286
- # * path/file +String+ if +file_name+ was given
287
- # * path to task_directory if +file_name+ was <i>not</i> given
288
- #
289
- # Notes
290
- # * Neither path nor file will have a file extension
291
- # * See <tt>#task_home</tt>
292
- def task_require_path(file_name = '')
293
- begin
294
- file_sans_extension = File.basename(file_name, '.*')
295
- (Pathname.new(task_home) + file_sans_extension).to_s
296
- rescue Errno::ENOENT
297
- nil
298
- end
299
- end
300
-
301
- # Change strings into camelCase
302
- #
303
- # Parameters
304
- # * var +String+
305
- #
306
- # Returns
307
- # +String+
308
- def to_camel(var)
309
- var = var.to_s unless var.kind_of? String
310
- step_one = to_snake(var)
311
- step_two = to_pascal(step_one)
312
- step_two[0, 1].downcase + step_two[1..-1]
313
- end
314
-
315
- # Change strings into a hyphen delimited phrase
316
- #
317
- # Parameters
318
- # * var +String+
319
- #
320
- # Returns
321
- # +String+
322
- def to_hyph(var)
323
- var = var.to_s unless var.kind_of? String
324
-
325
- var.gsub(/:{2}|\//, '-').
326
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
327
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
328
- gsub(/\s+/, '-').
329
- tr("_", "-").
330
- gsub(/^\W/, '').
331
- downcase
332
- end
333
-
334
- # Change strings into an i-var format
335
- #
336
- # Parameters
337
- # * var +String+
338
- #
339
- # Returns
340
- # +String+
341
- def to_i_var(var)
342
- var = var.to_s unless var.kind_of? String
343
- /^\W*@\w+/ =~ var ? to_snake(var) : "@#{to_snake(var)}"
344
- end
345
-
346
- # Change strings into PascalCase
347
- #
348
- # Parameters
349
- # * var +String+
350
- #
351
- # Returns
352
- # +String+
353
- def to_pascal(var)
354
- var = var.to_s unless var.kind_of? String
355
- var.gsub(/^(.{1})|\W.{1}|\_.{1}/) { |s| s.gsub(/[^a-z0-9]+/i, '').capitalize }
356
- end
357
-
358
- # Change strings into a ruby_file_name with extension
359
- #
360
- # Parameters
361
- # * var +String+
362
- #
363
- # Returns
364
- # +String+
365
- #
366
- # Notes
367
- # * given_string.rb
368
- # * includes ruby file extension
369
- # * see #to_snake()
370
- def to_ruby_file_name(name)
371
- name[/\.rb$/].nil? ? "#{to_snake(name)}.rb" : "#{to_snake(name)}"
372
- end
373
-
374
- # Change strings into PascalCase
375
- #
376
- # Parameters
377
- # * var +String+
378
- #
379
- # Returns
380
- # +String+
381
- #
382
- # Notes
383
- # * given_string
384
- # * will not have file extensions
385
- # * see #to_ruby_file_name()
386
- def to_snake(var)
387
- var = var.to_s unless var.kind_of? String
388
-
389
- var.gsub(/:{2}|\//, '_').
390
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
391
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
392
- gsub(/\s+/, '_').
393
- tr("-", "_").
394
- downcase
395
- end
396
-
397
- # This method provides a default overrideable message body for things like
398
- # basic status updates.
399
- #
400
- # Parameters
401
- # * instanceId +Hash+
402
- #
403
- # Notes
404
- # * camel casing is used on the keys because most other languages prefer
405
- # that and it's not a huge problem in ruby. Besides, there's some other
406
- # handy methods in this module to get you through those issues, like
407
- # +#to_snake()+ and or +#modify_keys_with()+
408
- def update_message_body(opts = {})
409
- # TODO: Better implementation of merging message bodies and config needed
410
- unless opts.kind_of? Hash
411
- update = opts.to_s
412
- opts = {}
413
- opts[:extraInfo] = { message: update }
414
- end
415
- updated_extra_info = opts.delete(:extraInfo) || {}
416
-
417
- {
418
- instanceId: @instance_id || 'none-aquired',
419
- type: 'status-update',
420
- content: 'running',
421
- extraInfo: updated_extra_info
422
- }.merge(opts)
423
- end
424
-
425
- # Predicate method to check if a String is parsable, as JSON
426
- #
427
- # Parameters
428
- # * json +String+
429
- #
430
- # Returns
431
- # +Boolean+
432
- def valid_json?(json)
433
- begin
434
- JSON.parse(json)
435
- true
436
- rescue Exception
437
- false
438
- end
439
- end
440
-
441
- # Predicate method to check if a String is a valid URL
442
- #
443
- # Parameters
444
- # * url +String+
445
- #
446
- # Returns
447
- # +Boolean+
448
- def valid_url?(url)
449
- url =~ /\A#{URI::regexp}\z/
450
- end
451
- end
452
- end
453
- end