jets 0.2.0 → 0.5.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 (292) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/bin/commit_docs.sh +26 -0
  3. data/.circleci/config.yml +126 -0
  4. data/.codebuild/README.md +57 -0
  5. data/.codebuild/bin/jets +3 -0
  6. data/.codebuild/buildspec-base.yml +14 -0
  7. data/.codebuild/integration.sh +54 -0
  8. data/.codebuild/jets.postman_collection.json +323 -0
  9. data/.codebuild/scripts/install-docker.sh +12 -0
  10. data/.codebuild/scripts/install-dynamodb-local.sh +22 -0
  11. data/.codebuild/scripts/install-java.sh +20 -0
  12. data/.codebuild/scripts/install-node.sh +4 -0
  13. data/.gitignore +3 -0
  14. data/.gitmodules +9 -0
  15. data/.python-version +1 -0
  16. data/.rspec +2 -0
  17. data/.ruby-version +1 -1
  18. data/CHANGELOG.md +3 -0
  19. data/Dockerfile +16 -0
  20. data/Dockerfile.base +53 -0
  21. data/Gemfile +8 -1
  22. data/Gemfile.lock +132 -28
  23. data/LICENSE.txt +1 -1
  24. data/Procfile +2 -0
  25. data/README.md +116 -17
  26. data/Rakefile +6 -0
  27. data/buildspec.yml +18 -0
  28. data/exe/jets +14 -0
  29. data/jets.gemspec +31 -3
  30. data/lib/jets.rb +56 -8
  31. data/lib/jets/application.rb +121 -0
  32. data/lib/jets/application/middleware.rb +23 -0
  33. data/lib/jets/aws_services.rb +71 -0
  34. data/lib/jets/booter.rb +95 -0
  35. data/lib/jets/builders.rb +6 -0
  36. data/lib/jets/builders/code_builder.rb +431 -0
  37. data/lib/jets/builders/deducer.rb +73 -0
  38. data/lib/jets/builders/gem_replacer.rb +154 -0
  39. data/lib/jets/builders/handler_generator.rb +76 -0
  40. data/lib/jets/builders/node-hello.js +73 -0
  41. data/lib/jets/builders/node-shim.js +151 -0
  42. data/lib/jets/cfn.rb +5 -4
  43. data/lib/jets/cfn/ship.rb +178 -0
  44. data/lib/jets/cfn/status.rb +208 -0
  45. data/lib/jets/cfn/template_builders.rb +21 -0
  46. data/lib/jets/cfn/template_builders/api_gateway_builder.rb +73 -0
  47. data/lib/jets/cfn/template_builders/api_gateway_deployment_builder.rb +38 -0
  48. data/lib/jets/cfn/template_builders/base_child_builder.rb +38 -0
  49. data/lib/jets/cfn/template_builders/controller_builder.rb +107 -0
  50. data/lib/jets/cfn/template_builders/function_builder.rb +20 -0
  51. data/lib/jets/cfn/template_builders/function_properties.rb +6 -0
  52. data/lib/jets/cfn/template_builders/function_properties/base_builder.rb +106 -0
  53. data/lib/jets/cfn/template_builders/function_properties/node_builder.rb +12 -0
  54. data/lib/jets/cfn/template_builders/function_properties/python_builder.rb +12 -0
  55. data/lib/jets/cfn/template_builders/function_properties/ruby_builder.rb +13 -0
  56. data/lib/jets/cfn/template_builders/interface.rb +91 -0
  57. data/lib/jets/cfn/template_builders/job_builder.rb +63 -0
  58. data/lib/jets/cfn/template_builders/parent_builder.rb +97 -0
  59. data/lib/jets/cfn/template_builders/rule_builder.rb +55 -0
  60. data/lib/jets/cfn/template_builders/templates/minimal-stack.yml +45 -0
  61. data/lib/jets/cfn/template_mappers.rb +23 -0
  62. data/lib/jets/cfn/template_mappers/api_gateway_deployment_mapper.rb +48 -0
  63. data/lib/jets/cfn/template_mappers/api_gateway_mapper.rb +4 -0
  64. data/lib/jets/cfn/template_mappers/child_mapper.rb +41 -0
  65. data/lib/jets/cfn/template_mappers/config_rule_mapper.rb +34 -0
  66. data/lib/jets/cfn/template_mappers/controller_mapper.rb +36 -0
  67. data/lib/jets/cfn/template_mappers/events_rule_mapper.rb +40 -0
  68. data/lib/jets/cfn/template_mappers/function_mapper.rb +4 -0
  69. data/lib/jets/cfn/template_mappers/gateway_method_mapper.rb +56 -0
  70. data/lib/jets/cfn/template_mappers/gateway_resource_mapper.rb +62 -0
  71. data/lib/jets/cfn/template_mappers/job_mapper.rb +4 -0
  72. data/lib/jets/cfn/template_mappers/lambda_function_mapper.rb +50 -0
  73. data/lib/jets/cfn/template_mappers/rule_mapper.rb +5 -0
  74. data/lib/jets/cli.rb +180 -15
  75. data/lib/jets/commands.rb +22 -0
  76. data/lib/jets/commands/base.rb +151 -0
  77. data/lib/jets/commands/build.rb +186 -0
  78. data/lib/jets/commands/call.rb +175 -0
  79. data/lib/jets/commands/call/anonymous_guesser.rb +96 -0
  80. data/lib/jets/commands/call/autoload_guesser.rb +112 -0
  81. data/lib/jets/commands/call/base_guesser.rb +33 -0
  82. data/lib/jets/commands/call/guesser.rb +51 -0
  83. data/lib/jets/commands/console.rb +12 -0
  84. data/lib/jets/commands/db.rb +15 -0
  85. data/lib/jets/commands/db/environment-task.rake +3 -0
  86. data/lib/jets/commands/db/tasks.rb +30 -0
  87. data/lib/jets/commands/dbconsole.rb +131 -0
  88. data/lib/jets/commands/delete.rb +119 -0
  89. data/lib/jets/commands/deploy.rb +53 -0
  90. data/lib/jets/commands/dynamodb.rb +22 -0
  91. data/lib/jets/commands/dynamodb/migrate.rb +9 -0
  92. data/lib/jets/commands/dynamodb/migrator.rb +36 -0
  93. data/lib/jets/commands/help.rb +9 -0
  94. data/lib/jets/commands/help/build.md +1 -0
  95. data/lib/jets/commands/help/call.md +55 -0
  96. data/lib/jets/commands/help/console.md +4 -0
  97. data/lib/jets/commands/help/db/generate.md +8 -0
  98. data/lib/jets/commands/help/dbconsole.md +5 -0
  99. data/lib/jets/commands/help/delete.md +9 -0
  100. data/lib/jets/commands/help/deploy.md +5 -0
  101. data/lib/jets/commands/help/dynamodb/generate.md +50 -0
  102. data/lib/jets/commands/help/dynamodb/migrate.md +4 -0
  103. data/lib/jets/commands/help/generate.md +5 -0
  104. data/lib/jets/commands/help/new.md +9 -0
  105. data/lib/jets/commands/help/process/controller.md +6 -0
  106. data/lib/jets/commands/help/process/function.md +5 -0
  107. data/lib/jets/commands/help/process/job.md +5 -0
  108. data/lib/jets/commands/help/process/rule.md +5 -0
  109. data/lib/jets/commands/help/routes.md +3 -0
  110. data/lib/jets/commands/help/server.md +6 -0
  111. data/lib/jets/commands/help/status.md +1 -0
  112. data/lib/jets/commands/help/url.md +5 -0
  113. data/lib/jets/commands/main.rb +111 -0
  114. data/lib/jets/commands/markdown.rb +8 -0
  115. data/lib/jets/commands/markdown/creator.rb +58 -0
  116. data/lib/jets/commands/markdown/index.rb +27 -0
  117. data/lib/jets/commands/markdown/page.rb +125 -0
  118. data/lib/jets/commands/markdown/shell.rb +11 -0
  119. data/lib/jets/commands/new.rb +110 -0
  120. data/lib/jets/commands/rake_command.rb +61 -0
  121. data/lib/jets/commands/rake_tasks.rb +45 -0
  122. data/lib/jets/commands/sequence.rb +44 -0
  123. data/lib/jets/commands/stack_info.rb +30 -0
  124. data/lib/jets/commands/templates/skeleton/.env +2 -0
  125. data/lib/jets/commands/templates/skeleton/.env.development.tt +3 -0
  126. data/lib/jets/commands/templates/skeleton/.env.test +3 -0
  127. data/lib/jets/commands/templates/skeleton/.gitignore +14 -0
  128. data/lib/jets/commands/templates/skeleton/.jetskeep +1 -0
  129. data/lib/jets/commands/templates/skeleton/Gemfile.tt +27 -0
  130. data/lib/jets/commands/templates/skeleton/Procfile +7 -0
  131. data/lib/jets/commands/templates/skeleton/README.md +4 -0
  132. data/lib/jets/commands/templates/skeleton/Rakefile +2 -0
  133. data/lib/jets/commands/templates/skeleton/app/controllers/application_controller.rb +2 -0
  134. data/lib/jets/commands/templates/skeleton/app/helpers/application_helper.rb +2 -0
  135. data/lib/jets/commands/templates/skeleton/app/jobs/application_job.rb +2 -0
  136. data/lib/jets/commands/templates/skeleton/app/models/application_item.rb +2 -0
  137. data/lib/jets/commands/templates/skeleton/app/models/application_record.rb +3 -0
  138. data/lib/jets/commands/templates/skeleton/app/views/layouts/application.html.erb.tt +24 -0
  139. data/lib/jets/commands/templates/skeleton/bin/ruby_server +18 -0
  140. data/lib/jets/commands/templates/skeleton/bin/ruby_server.rb +2 -0
  141. data/lib/jets/commands/templates/skeleton/config.ru +4 -0
  142. data/lib/jets/commands/templates/skeleton/config/application.rb.tt +26 -0
  143. data/lib/jets/commands/templates/skeleton/config/database.yml.tt +27 -0
  144. data/lib/jets/commands/templates/skeleton/config/dynamodb.yml +25 -0
  145. data/lib/jets/commands/templates/skeleton/config/routes.rb +8 -0
  146. data/lib/jets/commands/templates/skeleton/db/.gitkeep +0 -0
  147. data/lib/jets/commands/templates/skeleton/public/404.html +67 -0
  148. data/lib/jets/commands/templates/skeleton/public/422.html +67 -0
  149. data/lib/jets/commands/templates/skeleton/public/500.html +66 -0
  150. data/lib/jets/commands/templates/skeleton/public/favicon.ico +0 -0
  151. data/lib/jets/commands/templates/skeleton/public/index.html.tt +79 -0
  152. data/lib/jets/commands/templates/skeleton/spec/controllers/posts_controller_spec.rb +18 -0
  153. data/lib/jets/commands/templates/skeleton/spec/fixtures/payloads/posts-index.json +51 -0
  154. data/lib/jets/commands/templates/skeleton/spec/fixtures/payloads/posts-show.json +53 -0
  155. data/lib/jets/commands/templates/skeleton/spec/spec_helper.rb.tt +27 -0
  156. data/lib/jets/commands/templates/webpacker/app/javascript/packs/application.js.tt +14 -0
  157. data/lib/jets/commands/templates/webpacker/app/javascript/packs/theme.scss.tt +24 -0
  158. data/lib/jets/commands/templates/webpacker/app/javascript/src/jets/crud.js +87 -0
  159. data/lib/jets/commands/url.rb +45 -0
  160. data/lib/jets/commands/webpacker_template.rb +19 -0
  161. data/lib/jets/controller.rb +9 -0
  162. data/lib/jets/controller/base.rb +50 -0
  163. data/lib/jets/controller/callbacks.rb +43 -0
  164. data/lib/jets/controller/layout.rb +17 -0
  165. data/lib/jets/controller/params.rb +53 -0
  166. data/lib/jets/controller/redirection.rb +55 -0
  167. data/lib/jets/controller/renderers.rb +5 -0
  168. data/lib/jets/controller/renderers/aws_proxy_renderer.rb +69 -0
  169. data/lib/jets/controller/renderers/base_renderer.rb +16 -0
  170. data/lib/jets/controller/renderers/template_renderer.rb +107 -0
  171. data/lib/jets/controller/rendering.rb +80 -0
  172. data/lib/jets/controller/request.rb +55 -0
  173. data/lib/jets/core.rb +81 -0
  174. data/lib/jets/default/application.rb +20 -0
  175. data/lib/jets/dotenv.rb +37 -0
  176. data/lib/jets/erb.rb +51 -0
  177. data/lib/jets/generator.rb +40 -0
  178. data/lib/jets/generator/templates/erb/controller/view.html.erb +2 -0
  179. data/lib/jets/generator/templates/erb/scaffold/_form.html.erb +39 -0
  180. data/lib/jets/generator/templates/erb/scaffold/edit.html.erb +6 -0
  181. data/lib/jets/generator/templates/erb/scaffold/index.html.erb +29 -0
  182. data/lib/jets/generator/templates/erb/scaffold/new.html.erb +5 -0
  183. data/lib/jets/generator/templates/erb/scaffold/show.html.erb +9 -0
  184. data/lib/jets/generator/templates/rails/assets/javascript.js +2 -0
  185. data/lib/jets/generator/templates/rails/assets/stylesheet.css +4 -0
  186. data/lib/jets/generator/templates/rails/controller/controller.rb +13 -0
  187. data/lib/jets/generator/templates/rails/helper/helper.rb +4 -0
  188. data/lib/jets/generator/templates/rails/scaffold/scaffold.css +80 -0
  189. data/lib/jets/generator/templates/rails/scaffold_controller/api_controller.rb +62 -0
  190. data/lib/jets/generator/templates/rails/scaffold_controller/controller.rb +71 -0
  191. data/lib/jets/internal/app/controllers/jets/public_controller.rb +30 -0
  192. data/lib/jets/internal/app/controllers/jets/public_controller/python/show.py +47 -0
  193. data/lib/jets/internal/app/controllers/jets/public_controller/python/show.pyc +0 -0
  194. data/lib/jets/internal/app/controllers/jets/welcome_controller.rb +22 -0
  195. data/lib/jets/internal/app/controllers/jets/welcome_controller/python/index.py +24 -0
  196. data/lib/jets/internal/app/jobs/jets/preheat_job.rb +52 -0
  197. data/lib/jets/job.rb +5 -0
  198. data/lib/jets/job/base.rb +29 -0
  199. data/lib/jets/job/dsl.rb +58 -0
  200. data/lib/jets/job/task.rb +17 -0
  201. data/lib/jets/klass.rb +71 -0
  202. data/lib/jets/lambda.rb +18 -0
  203. data/lib/jets/lambda/dsl.rb +153 -0
  204. data/lib/jets/lambda/function.rb +29 -0
  205. data/lib/jets/lambda/function_constructor.rb +60 -0
  206. data/lib/jets/lambda/functions.rb +22 -0
  207. data/lib/jets/lambda/task.rb +77 -0
  208. data/lib/jets/naming.rb +61 -0
  209. data/lib/jets/pascalize.rb +30 -0
  210. data/lib/jets/poly_fun.rb +61 -0
  211. data/lib/jets/poly_fun/base_executor.rb +129 -0
  212. data/lib/jets/poly_fun/lambda_executor.rb +16 -0
  213. data/lib/jets/poly_fun/node_error.rb +8 -0
  214. data/lib/jets/poly_fun/node_executor.rb +54 -0
  215. data/lib/jets/poly_fun/python_error.rb +8 -0
  216. data/lib/jets/poly_fun/python_executor.rb +23 -0
  217. data/lib/jets/preheat.rb +72 -0
  218. data/lib/jets/processors.rb +4 -0
  219. data/lib/jets/processors/deducer.rb +54 -0
  220. data/lib/jets/processors/main_processor.rb +57 -0
  221. data/lib/jets/rails_overrides.rb +4 -0
  222. data/lib/jets/rails_overrides/asset_tag_helper.rb +41 -0
  223. data/lib/jets/rails_overrides/common_methods.rb +13 -0
  224. data/lib/jets/rails_overrides/rendering_helper.rb +26 -0
  225. data/lib/jets/rails_overrides/url_helper.rb +26 -0
  226. data/lib/jets/route.rb +145 -0
  227. data/lib/jets/router.rb +115 -0
  228. data/lib/jets/ruby_server.rb +91 -0
  229. data/lib/jets/rule.rb +5 -0
  230. data/lib/jets/rule/base.rb +19 -0
  231. data/lib/jets/rule/dsl.rb +64 -0
  232. data/lib/jets/rule/task.rb +44 -0
  233. data/lib/jets/server.rb +16 -0
  234. data/lib/jets/server/api_gateway.rb +39 -0
  235. data/lib/jets/server/lambda_aws_proxy.rb +122 -0
  236. data/lib/jets/server/route_matcher.rb +96 -0
  237. data/lib/jets/server/timing_middleware.rb +16 -0
  238. data/lib/jets/server/webpacker_setup.rb +7 -0
  239. data/lib/jets/timing.rb +65 -0
  240. data/lib/jets/timing/report.rb +82 -0
  241. data/lib/jets/util.rb +7 -12
  242. data/lib/jets/version.rb +1 -1
  243. data/support/clean +3 -0
  244. data/support/console +3 -0
  245. metadata +473 -76
  246. data/bin/jets +0 -14
  247. data/lib/jets/base_controller.rb +0 -54
  248. data/lib/jets/build.rb +0 -46
  249. data/lib/jets/build/handler_generator.rb +0 -46
  250. data/lib/jets/build/lambda_deducer.rb +0 -23
  251. data/lib/jets/build/templates/handler.js +0 -149
  252. data/lib/jets/build/traveling_ruby.rb +0 -133
  253. data/lib/jets/cfn/base.rb +0 -17
  254. data/lib/jets/cfn/builder.rb +0 -53
  255. data/lib/jets/cfn/namer.rb +0 -30
  256. data/lib/jets/cli/help.rb +0 -19
  257. data/lib/jets/command.rb +0 -25
  258. data/lib/jets/process.rb +0 -18
  259. data/lib/jets/process/base_processor.rb +0 -23
  260. data/lib/jets/process/controller_processor.rb +0 -36
  261. data/lib/jets/process/help.rb +0 -11
  262. data/lib/jets/process/processor_deducer.rb +0 -51
  263. data/lib/jets/project.rb +0 -23
  264. data/notes/design.md +0 -107
  265. data/notes/faq.md +0 -3
  266. data/notes/lambda_ruby_info.md +0 -34
  267. data/notes/traveling-ruby-packaging-jets.md +0 -26
  268. data/notes/traveling-ruby-packaging.md +0 -103
  269. data/notes/traveling-ruby-structure.md +0 -6
  270. data/notes/traveling-ruby.md +0 -82
  271. data/spec/fixtures/classes.rb +0 -5
  272. data/spec/fixtures/project/.gitignore +0 -3
  273. data/spec/fixtures/project/.ruby-version +0 -1
  274. data/spec/fixtures/project/Gemfile +0 -4
  275. data/spec/fixtures/project/Gemfile.lock +0 -23
  276. data/spec/fixtures/project/app/controllers/application_controller.rb +0 -2
  277. data/spec/fixtures/project/app/controllers/posts_controller.rb +0 -12
  278. data/spec/fixtures/project/bin/jets +0 -22
  279. data/spec/fixtures/project/config/routes.rb +0 -6
  280. data/spec/fixtures/project/handlers/controllers/posts.js +0 -212
  281. data/spec/lib/cli_spec.rb +0 -20
  282. data/spec/lib/jets/base_controller_spec.rb +0 -18
  283. data/spec/lib/jets/build/handler_generator_spec.rb +0 -20
  284. data/spec/lib/jets/build/lambda_deducer_spec.rb +0 -15
  285. data/spec/lib/jets/build_spec.rb +0 -34
  286. data/spec/lib/jets/cfn/builder_spec.rb +0 -18
  287. data/spec/lib/jets/cfn/namer_spec.rb +0 -16
  288. data/spec/lib/jets/process/controller_processor_spec.rb +0 -22
  289. data/spec/lib/jets/process/infer_spec.rb +0 -24
  290. data/spec/lib/jets/process_spec.rb +0 -18
  291. data/spec/lib/jets/project_spec.rb +0 -14
  292. data/spec/spec_helper.rb +0 -28
@@ -0,0 +1,5 @@
1
+ class Jets::Job
2
+ autoload :Dsl, "jets/job/dsl"
3
+ autoload :Base, "jets/job/base"
4
+ autoload :Task, "jets/job/task"
5
+ end
@@ -0,0 +1,29 @@
1
+ require 'json'
2
+
3
+ # Job public methods get turned into Lambda functions.
4
+ #
5
+ # Jets::Job::Base < Jets::Lambda::Functions
6
+ # Both Jets::Job::Base and Jets::Lambda::Functions have Dsl modules included.
7
+ # So the Jets::Job::Dsl overrides some of the Jets::Lambda::Functions behavior.
8
+ class Jets::Job
9
+ class Base < Jets::Lambda::Functions
10
+ include Dsl
11
+
12
+ class << self
13
+ def process(event, context, meth)
14
+ job = new(event, context, meth)
15
+ job.send(meth)
16
+ end
17
+
18
+ def perform_now(meth, event, context=nil)
19
+ new(event, context, meth).send(meth)
20
+ end
21
+
22
+ def perform_later(meth, event, context=nil)
23
+ function_name = "#{self.to_s.underscore}-#{meth}"
24
+ call = Jets::Commands::Call.new(function_name, JSON.dump(event), invocation_type: "Event")
25
+ call.run
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,58 @@
1
+ # Jets::Job::Base < Jets::Lambda::Functions
2
+ # Both Jets::Job::Base and Jets::Lambda::Functions have Dsl modules included.
3
+ # So the Jets::Job::Dsl overrides some of the Jets::Lambda::Functions behavior.
4
+ module Jets::Job::Dsl
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ class << self
9
+ def rate(expression)
10
+ @rate = expression
11
+ end
12
+
13
+ def cron(expression)
14
+ @cron = expression
15
+ end
16
+
17
+ # Explicitly disable scheduling for the function
18
+ def disable(value)
19
+ @disable = value
20
+ end
21
+
22
+ # This is a property of the AWS::Events::Rule not the Lambda function
23
+ def state(value)
24
+ @state = value
25
+ end
26
+
27
+ # Override register_task.
28
+ # A Job::Task is a Lambda::Task with some added DSL methods like
29
+ # rate and cron.
30
+ def register_task(meth, lang=:ruby)
31
+ if @rate || @cron || @disable
32
+ # Job lambda function.
33
+ all_tasks[meth] = Jets::Job::Task.new(self.name, meth,
34
+ rate: @rate,
35
+ cron: @cron,
36
+ state: @state,
37
+ properties: @properties,
38
+ lang: lang)
39
+ true
40
+ else
41
+ task_name = "#{name}##{meth}" # IE: HardJob#dig
42
+ puts "[WARNING] #{task_name} created without a rate or cron expression. " \
43
+ "Add a rate or cron expression above the method definition if you want this method to be scheduled. " \
44
+ "If #{task_name} is not meant to be a scheduled lambda function, you can put the method under after a private keyword to get rid of this warning. " \
45
+ "#{task_name} defined at #{caller[1].inspect}."
46
+ false
47
+ end
48
+ # Done storing options, clear out for the next added method.
49
+ clear_properties
50
+ end
51
+
52
+ def clear_properties
53
+ super
54
+ @rate, @cron, @state, @disable = nil, nil, nil, nil
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,17 @@
1
+ class Jets::Job::Task < Jets::Lambda::Task
2
+ attr_reader :state
3
+ def initialize(class_name, meth, options={})
4
+ super
5
+ @rate = options[:rate]
6
+ @cron = options[:cron]
7
+ @state = options[:state] || 'ENABLED'
8
+ end
9
+
10
+ def schedule_expression
11
+ if @rate
12
+ "rate(#{@rate})"
13
+ elsif @cron
14
+ "cron(#{@cron})"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,71 @@
1
+ # Loading a class can usually be loaded via .constantize.
2
+ # But app/functions files are anonymous ruby classes created with
3
+ # Class.new. Anonymous classes cannot be loaded via .constantize and
4
+ # go through standard autoloading.
5
+ #
6
+ # Jets::Klass provides a way to load app classes in app/controllers, app/jobs,
7
+ # app/functions in a consistent way without having to worry about the anonymous
8
+ # class loading quirk. Classes that are not anonymously defined like controllers
9
+ # and jobs are loaded via autoloading with .constantize. Anonymously defined
10
+ # classes like functions are loaded via Object.const_set.
11
+ #
12
+ # Examples:
13
+ #
14
+ # Jets::Klass.from_path("app/controllers/posts_controller.rb")
15
+ # Jets::Klass.from_path("app/jobs/hard_job.rb")
16
+ # Jets::Klass.from_path("app/functions/hello.rb")
17
+ # Jets::Klass.from_path("app/functions/hello_function.rb")
18
+ #
19
+ # Jets::Klass.from_task(task)
20
+ #
21
+ # The from_task method takes a Jets::Lambda::Task as an argument and is useful
22
+ # for the CloudFormation child stack generation there the registered task info
23
+ # is available but the path info is now.
24
+ class Jets::Klass
25
+ class << self
26
+ # from_path allows us to load any app classes in consistent way for
27
+ # app/controllers, app/jobs, and app/functions.
28
+ def from_path(path)
29
+ class_name = class_name(path)
30
+
31
+ if path.include?("/functions/") # simple function
32
+ load_anonymous_class(class_name, path)
33
+ end
34
+
35
+ class_name.constantize # autoload or nothing if load_anonymous_class called
36
+ end
37
+
38
+ # app/controllers/posts_controller.rb => PostsController
39
+ def class_name(path)
40
+ path.sub(%r{.*app\/(.*?)/},'').sub(/\.rb$/,'').classify
41
+ end
42
+
43
+ def from_task(task)
44
+ class_name = task.class_name
45
+ filename = class_name.underscore
46
+
47
+ # Examples of filename: posts_controller, hard_job, security_rule,
48
+ # hello_function, hello
49
+ valid_types = %w[controller job rule]
50
+ type = filename.split('_').last
51
+ type = "function" unless valid_types.include?(type)
52
+
53
+ path = "app/#{type.pluralize}/#{filename}.rb"
54
+ from_path(path)
55
+ end
56
+
57
+ @@loaded_anonymous_classes = []
58
+ def load_anonymous_class(class_name, path)
59
+ constructor = Jets::Lambda::FunctionConstructor.new(path)
60
+ # Dont load anonyomous class more than once to avoid these warnings:
61
+ # warning: already initialized constant Hello
62
+ # warning: previous definition of Hello was here
63
+ unless @@loaded_anonymous_classes.include?(class_name)
64
+ # use class_name as the variable name for prettier class name.
65
+ Object.const_set(class_name, constructor.build)
66
+ @@loaded_anonymous_classes << class_name
67
+ end
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,18 @@
1
+ # Task vs Functions
2
+ #
3
+ # Functions is inherited by Job::Base and Controller::Base.
4
+ # It is holds the event and context is used for processing when you
5
+ # call the lambda function.
6
+ #
7
+ # Task is a holds information for the method that gets registered
8
+ # with method_add and is used to build up the CloudFormation Lambda
9
+ # Function definition.
10
+ #
11
+ # Overview diagram : http://bit.ly/2zQeoF3
12
+ module Jets::Lambda
13
+ autoload :Dsl, "jets/lambda/dsl"
14
+ autoload :FunctionConstructor, "jets/lambda/function_constructor"
15
+ autoload :Function, "jets/lambda/function"
16
+ autoload :Functions, "jets/lambda/functions"
17
+ autoload :Task, "jets/lambda/task"
18
+ end
@@ -0,0 +1,153 @@
1
+ module Jets::Lambda::Dsl
2
+ extend ActiveSupport::Concern
3
+
4
+ def lambda_functions
5
+ self.class.lambda_functions
6
+ end
7
+
8
+ included do
9
+ class << self
10
+ def class_properties(options=nil)
11
+ if options
12
+ @class_properties ||= {}
13
+ @class_properties.deep_merge!(options)
14
+ else
15
+ @class_properties || {}
16
+ end
17
+ end
18
+ alias_method :class_props, :class_properties
19
+
20
+ def class_timeout(value)
21
+ class_properties(timeout: value)
22
+ end
23
+
24
+ def class_environment(hash)
25
+ environment = {}
26
+ environment[:variables] ||= {}
27
+ environment[:variables].merge!(hash)
28
+ class_properties(environment: environment)
29
+ end
30
+ alias_method :class_env, :class_environment
31
+
32
+ def class_memory_size(value)
33
+ class_properties(memory_size: value)
34
+ end
35
+ alias_method :class_memory, :class_memory_size
36
+
37
+ def class_role(name)
38
+ class_properties(role: name)
39
+ end
40
+
41
+ def class_handler(name)
42
+ class_properties(handler: name)
43
+ end
44
+
45
+ # convenience method that set properties
46
+ def timeout(value)
47
+ properties(timeout: value)
48
+ end
49
+
50
+ # convenience method that set properties
51
+ def environment(hash)
52
+ environment = {}
53
+ environment[:variables] ||= {}
54
+ environment[:variables].merge!(hash)
55
+ properties(environment: environment)
56
+ end
57
+ alias_method :env, :environment
58
+
59
+ # convenience method that set properties
60
+ def memory_size(value)
61
+ properties(memory_size: value)
62
+ end
63
+ alias_method :memory, :memory_size
64
+
65
+ def handler(value)
66
+ properties(handler: value)
67
+ end
68
+
69
+ def runtime(value)
70
+ properties(runtime: value)
71
+ end
72
+
73
+ def properties(options={})
74
+ @properties ||= {}
75
+ @properties.deep_merge!(options)
76
+ end
77
+ alias_method :props, :properties
78
+
79
+ # meth is a Symbol
80
+ def method_added(meth)
81
+ return if %w[initialize method_missing].include?(meth.to_s)
82
+ return unless public_method_defined?(meth)
83
+
84
+ register_task(meth)
85
+ end
86
+
87
+ def register_task(meth, lang=:ruby)
88
+ # Note: for anonymous classes like for app/functions self.name is ""
89
+ # We adjust the class name when we build the functions later in
90
+ # FunctionContstructor#adjust_tasks.
91
+ all_tasks[meth] = Jets::Lambda::Task.new(self.name, meth,
92
+ properties: @properties, lang: lang)
93
+
94
+ # Done storing options, clear out for the next added method.
95
+ clear_properties
96
+ # Important to clear @properties at the end of registering outside of
97
+ # register_task because register_task is overridden in Jets::Job::Dsl
98
+ #
99
+ # Jets::Job::Base < Jets::Lambda::Functions
100
+ #
101
+ # Both Jets::Job::Base and Jets::Lambda::Functions have Dsl modules included.
102
+ # So the Jets::Job::Dsl overrides some of the Jets::Lambda::Dsl behavior.
103
+
104
+ true
105
+ end
106
+
107
+ def clear_properties
108
+ @properties = nil
109
+ end
110
+
111
+ # Returns the all tasks for this class with their method names as keys.
112
+ #
113
+ # ==== Returns
114
+ # OrderedHash:: An ordered hash with tasks names as keys and JobTask
115
+ # objects as values.
116
+ #
117
+ def all_tasks
118
+ @all_tasks ||= ActiveSupport::OrderedHash.new
119
+ end
120
+
121
+ # Returns the tasks for this class in Array form.
122
+ #
123
+ # ==== Returns
124
+ # Array of task objects
125
+ #
126
+ def tasks
127
+ all_tasks.values
128
+ end
129
+
130
+ # The public methods defined in the project app class ulimately become
131
+ # lambda functions.
132
+ #
133
+ # Example return value:
134
+ # [:index, :new, :create, :show]
135
+ def lambda_functions
136
+ all_tasks.keys
137
+ end
138
+
139
+ # Polymorphic support
140
+ def defpoly(lang, meth)
141
+ register_task(meth, lang)
142
+ end
143
+
144
+ def python(meth)
145
+ defpoly(:python, meth)
146
+ end
147
+
148
+ def node(meth)
149
+ defpoly(:node, meth)
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,29 @@
1
+ module Jets::Lambda
2
+ class Function < Functions
3
+ # Override and change the signature so we do not have to provide info at
4
+ # initialization. So:
5
+ #
6
+ # hello_function = HelloFunction.new
7
+ # hello_function.lambda_handler(event, context)
8
+ #
9
+ # Normally controller and job functions initialize like this:
10
+ #
11
+ # controller = PostController.new(event, context, "handler_handler")
12
+ def initialize
13
+ end
14
+
15
+ def self.handler
16
+ handler_task.meth
17
+ end
18
+
19
+ def self.handler_task
20
+ tasks.first
21
+ end
22
+
23
+ # Used by main_processor.rb. Same interface as controllers and jobs.
24
+ def self.process(event, context, meth)
25
+ function = new
26
+ function.send(handler, event, context)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,60 @@
1
+ # Builds an anonymous class that represents a single Lambda function from code
2
+ # in app/functions.
3
+ #
4
+ # The build method returns an anonymous class using Class.new that contains
5
+ # the methods defined in the app/functions/hello.rb code.
6
+ #
7
+ # Ruby Class.new docs:
8
+ #
9
+ # Creates a new anonymous (unnamed) class with the given superclass (or
10
+ # Object if no parameter is given). You can give a class a name by
11
+ # assigning the class object to a constant.
12
+ # http://ruby-doc.org/core-2.1.1/Class.html#method-c-new
13
+ #
14
+ # So assigning the result of build to a constant makes for a prettier
15
+ # class name. Example:
16
+ #
17
+ # constructor = FunctionConstructor.new(code_path)
18
+ # HelloFunction = constructor.build
19
+ #
20
+ # The class name will be HelloFunction instead of (anonymous). Then usage would
21
+ # be:
22
+ #
23
+ # hello_function = HelloFunction.new
24
+ # hello_function(hello_function.handler, event, context)
25
+ #
26
+ # Or call with the process class method:
27
+ #
28
+ # HelloFunction.process(event, context, "world")
29
+ module Jets::Lambda
30
+ class FunctionConstructor
31
+ def initialize(code_path)
32
+ @code_path = full(code_path)
33
+ end
34
+
35
+ def full(path)
36
+ path = "#{Jets.root}#{path}" unless path.include?(Jets.root.to_s)
37
+ path
38
+ end
39
+
40
+ def build
41
+ code = IO.read(@code_path)
42
+ function_klass = Class.new(Jets::Lambda::Function)
43
+ function_klass.module_eval(code)
44
+ adjust_tasks(function_klass)
45
+ function_klass # assign this to a Constant for a pretty class name
46
+ end
47
+
48
+ # For anonymous classes method_added during task registeration contains ""
49
+ # for the class name. We adjust it here.
50
+ def adjust_tasks(klass)
51
+ class_name = @code_path.sub(/.*app\/functions\//,'').sub(/\.rb$/, '')
52
+ class_name = class_name.classify
53
+ klass.tasks.each do |task|
54
+ task.class_name = class_name
55
+ task.type = "function"
56
+ end
57
+ end
58
+ end
59
+ end
60
+