jets 0.10.4 → 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 (84) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -0
  3. data/Gemfile.lock +12 -12
  4. data/README.md +4 -2
  5. data/exe/jets +2 -2
  6. data/lib/jets/application.rb +41 -5
  7. data/lib/jets/aws_info.rb +20 -0
  8. data/lib/jets/builders/code_builder.rb +201 -296
  9. data/lib/jets/builders/gem_replacer.rb +1 -1
  10. data/lib/jets/builders/handler_generator.rb +62 -43
  11. data/lib/jets/builders/md5.rb +55 -0
  12. data/lib/jets/builders/md5_zip.rb +60 -0
  13. data/lib/jets/builders/rack_packager.rb +29 -0
  14. data/lib/jets/builders/rackup_wrappers/rackup +23 -0
  15. data/lib/jets/builders/rackup_wrappers/rackup.rb +7 -0
  16. data/lib/jets/builders/reconfigure_rails/config/initializers/jets.rb +14 -0
  17. data/lib/jets/builders/reconfigure_rails.rb +99 -0
  18. data/lib/jets/builders/ruby_packager.rb +198 -0
  19. data/lib/jets/builders/{deducer.rb → shim_vars/app.rb} +14 -10
  20. data/lib/jets/builders/shim_vars/base.rb +24 -0
  21. data/lib/jets/builders/{shared_deducer.rb → shim_vars/shared.rb} +4 -3
  22. data/lib/jets/builders/shim_vars.rb +5 -0
  23. data/lib/jets/builders/templates/handler.js +9 -0
  24. data/lib/jets/builders/templates/shim.js +271 -0
  25. data/lib/jets/builders/tidy.rb +80 -0
  26. data/lib/jets/builders/util.rb +28 -0
  27. data/lib/jets/builders.rb +8 -2
  28. data/lib/jets/cfn/builders/function_builder.rb +0 -10
  29. data/lib/jets/cfn/builders/parent_builder.rb +7 -6
  30. data/lib/jets/cfn/ship.rb +9 -103
  31. data/lib/jets/cfn/upload.rb +139 -0
  32. data/lib/jets/cfn.rb +1 -0
  33. data/lib/jets/commands/build.rb +17 -19
  34. data/lib/jets/commands/deploy.rb +2 -0
  35. data/lib/jets/commands/help/deploy.md +2 -2
  36. data/lib/jets/commands/help/import/rack.md +13 -0
  37. data/lib/jets/commands/help/import/rails.md +11 -0
  38. data/lib/jets/commands/import/base.rb +39 -0
  39. data/lib/jets/commands/import/rack.rb +16 -0
  40. data/lib/jets/commands/import/rail.rb +68 -0
  41. data/lib/jets/commands/import/sequence.rb +68 -0
  42. data/lib/jets/commands/import.rb +14 -0
  43. data/lib/jets/commands/main.rb +2 -1
  44. data/lib/jets/commands/new.rb +1 -1
  45. data/lib/jets/commands/sequence.rb +26 -22
  46. data/lib/jets/commands/templates/skeleton/Gemfile.tt +5 -2
  47. data/lib/jets/commands/templates/skeleton/README.md +11 -2
  48. data/lib/jets/commands/templates/skeleton/app/jobs/application_job.rb +1 -1
  49. data/lib/jets/commands/templates/skeleton/app/views/layouts/application.html.erb.tt +1 -1
  50. data/lib/jets/commands/templates/skeleton/config/application.rb.tt +12 -5
  51. data/lib/jets/commands/templates/skeleton/config/database.yml.tt +5 -1
  52. data/lib/jets/commands/templates/skeleton/config/environments/development.rb +3 -0
  53. data/lib/jets/commands/templates/skeleton/config/environments/production.rb +5 -0
  54. data/lib/jets/commands/templates/skeleton/public/{images/favicon.ico → favicon.ico} +0 -0
  55. data/lib/jets/commands/templates/skeleton/spec/controllers/posts_controller_spec.rb +1 -3
  56. data/lib/jets/commands.rb +1 -0
  57. data/lib/jets/controller/base.rb +1 -1
  58. data/lib/jets/controller/layout.rb +3 -0
  59. data/lib/jets/controller/params.rb +3 -2
  60. data/lib/jets/controller/request.rb +4 -0
  61. data/lib/jets/core.rb +20 -18
  62. data/lib/jets/core_ext/kernel.rb +9 -5
  63. data/lib/jets/default/application.rb +1 -1
  64. data/lib/jets/inflections.rb +16 -8
  65. data/lib/jets/internal/app/controllers/jets/public_controller.rb +17 -22
  66. data/lib/jets/internal/app/controllers/jets/rack_controller.rb +15 -0
  67. data/lib/jets/naming.rb +0 -23
  68. data/lib/jets/rack/hash_converter.rb +25 -0
  69. data/lib/jets/rack/request.rb +71 -0
  70. data/lib/jets/rack/server.rb +47 -0
  71. data/lib/jets/rack.rb +7 -0
  72. data/lib/jets/rails_overrides/asset_tag_helper.rb +12 -11
  73. data/lib/jets/resource/function.rb +13 -5
  74. data/lib/jets/router.rb +1 -1
  75. data/lib/jets/ruby_server.rb +63 -18
  76. data/lib/jets/server/api_gateway.rb +1 -1
  77. data/lib/jets/stack/resource.rb +3 -1
  78. data/lib/jets/version.rb +1 -1
  79. data/lib/jets.rb +3 -5
  80. metadata +34 -9
  81. data/lib/jets/builders/node-hello.js +0 -73
  82. data/lib/jets/builders/node-shim.js +0 -182
  83. data/lib/jets/internal/app/controllers/jets/public_controller/python/show.py +0 -47
  84. data/lib/jets/internal/app/controllers/jets/public_controller/python/show.pyc +0 -0
@@ -2,11 +2,6 @@ require 'socket'
2
2
  require 'json'
3
3
  require 'stringio'
4
4
 
5
- # Save copy of old stdout, since Jets.boot messes with it.
6
- # So we can use $normal_stdout.puts for debugging.
7
- $normal_stdout ||= $stdout
8
- $normal_stderr ||= $stderr
9
-
10
5
  # https://ruby-doc.org/stdlib-2.3.0/libdoc/socket/rdoc/TCPServer.html
11
6
  # https://stackoverflow.com/questions/806267/how-to-fire-and-forget-a-subprocess
12
7
  #
@@ -27,27 +22,73 @@ module Jets
27
22
  # INT - ^C
28
23
  trap('INT') do
29
24
  puts "Shutting down ruby_server.rb..."
25
+ FileUtils.rm_f("/tmp/jets-rackup.pid") # remove the rack subprocess pid in case it exists
30
26
  sleep 0.1
31
27
  exit
32
28
  end
29
+
33
30
  if ENV['FOREGROUND'] # Usage above
34
- serve
31
+ # start_rack_server # commented out because we expect user to start the rack server in the foreground
32
+ serve # ruby_server
35
33
  return
36
34
  end
37
35
 
38
- # Reaching here means we'll run the server in the background
36
+ # Reaching here means we'll run the server in the "background"
39
37
  pid = Process.fork
40
- if pid.nil?
41
- serve
42
- else
43
- # parent process
44
- Process.detach(pid)
38
+
39
+ if pid.nil? # we're in child process
40
+ start_rack_server
41
+ serve # ruby_server
42
+ else # we're in parent process
43
+ # Detach main jets ruby server
44
+ Process.detach(pid) # dettached but still in the "foreground" since server loop runs in the foreground
45
+ end
46
+ end
47
+
48
+ # Megamode support
49
+ def start_rack_server
50
+ return unless Jets.rack?
51
+
52
+ # Fire and forget for concurrent, will wait with wait_for_rack_socket
53
+ Thread.new do
54
+ Jets::Rack::Server.start
45
55
  end
56
+
57
+ wait_for_rack_socket # blocks until rack server is up
46
58
  end
47
59
 
60
+ # blocks until rack server is up
61
+ def wait_for_rack_socket
62
+ return unless Jets.rack?
63
+
64
+ retries = 0
65
+ max_retries = 30 # 15 seconds at a delay of 0.5s
66
+ delay = 0.5
67
+ if ENV['C9_USER'] # overrides for local testing
68
+ max_retries = 3
69
+ delay = 3
70
+ end
71
+ begin
72
+ server = TCPSocket.new('localhost', 9292)
73
+ server.close
74
+ rescue Errno::ECONNREFUSED
75
+ puts "Unable to connect to localhost:9292. Delay for #{delay} and will try to connect again." if ENV['JETS_DEBUG']
76
+ sleep(delay)
77
+ retries += 1
78
+ if retries < max_retries
79
+ retry
80
+ else
81
+ puts "Giving up on trying to connect to localhost:9292"
82
+ return false
83
+ end
84
+ end
85
+ puts "Connected to localhost:9292 successfully"
86
+ true
87
+ end
88
+
89
+ # runs in the child process
48
90
  def serve
49
- # child process
50
- server = TCPServer.new(8080) # Server bind to port 8080
91
+ server = TCPServer.new(PORT) # Server bind to port 8080
51
92
  puts "Ruby server started on port #{PORT}" if ENV['FOREGROUND'] || ENV['JETS_DEBUG'] || ENV['C9_USER']
52
93
 
53
94
  loop do
@@ -55,10 +96,14 @@ module Jets
55
96
 
56
97
  input_completed, event, handler = nil, nil, nil
57
98
  unless input_completed
58
- event = client.gets.strip # text
59
- # puts event # uncomment for debugging, Jets has changed stdout to stderr
60
- handler = client.gets.strip # text
61
- # puts handler # uncomment for debugging, Jets has changed stdout to stderr
99
+ event = client.gets&.strip # text or nil
100
+ handler = client.gets&.strip # text or nil
101
+ # The event is nil when a client connects and immediately disconnects without sending data
102
+ if event.nil?
103
+ # puts "event was nil" # uncomment to debug
104
+ next
105
+ end
106
+
62
107
  input_completed = true
63
108
  end
64
109
 
@@ -7,7 +7,7 @@ class Jets::Server
7
7
  route = RouteMatcher.new(env).find_route
8
8
  if route
9
9
  proxy = LambdaAwsProxy.new(route, env)
10
- triplet = proxy.response
10
+ proxy.response # triplet
11
11
  else
12
12
  [404, {'Content-Type' => 'text/html'}, [routes_error_message(env)]]
13
13
  end
@@ -22,7 +22,9 @@ class Jets::Stack
22
22
  attributes = template.values.first
23
23
  s3_key = attributes.dig('Properties','Code','S3Key')
24
24
  if s3_key == "code_s3_key_placeholder"
25
- attributes['Properties']['Code']['S3Key'] = Jets::Naming.code_s3_key
25
+ checksum = Jets::Builders::Md5.checksums["stage/code"]
26
+ code_zip = "code-#{checksum}.zip"
27
+ attributes['Properties']['Code']['S3Key'] = "jets/code/#{code_zip}"
26
28
  end
27
29
  template
28
30
  end
data/lib/jets/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Jets
2
- VERSION = "0.10.4"
2
+ VERSION = "1.0.0"
3
3
  end
data/lib/jets.rb CHANGED
@@ -25,6 +25,7 @@ module Jets
25
25
  autoload :Dotenv, 'jets/dotenv'
26
26
  autoload :Erb, "jets/erb"
27
27
  autoload :Generator, "jets/generator"
28
+ autoload :Inflections, "jets/inflections"
28
29
  autoload :IO, "jets/io"
29
30
  autoload :Job, 'jets/job'
30
31
  autoload :Klass, 'jets/klass'
@@ -34,6 +35,7 @@ module Jets
34
35
  autoload :PolyFun, 'jets/poly_fun'
35
36
  autoload :Preheat, "jets/preheat"
36
37
  autoload :Processors, 'jets/processors'
38
+ autoload :Rack, "jets/rack"
37
39
  autoload :Rdoc, "jets/rdoc"
38
40
  autoload :Resource, "jets/resource"
39
41
  autoload :Route, "jets/route"
@@ -44,7 +46,6 @@ module Jets
44
46
  autoload :Stack, "jets/stack"
45
47
  autoload :Timing, "jets/timing"
46
48
  autoload :Util, "jets/util"
47
- autoload :Inflections, "jets/inflections"
48
49
 
49
50
  extend Core # root, logger, etc
50
51
  end
@@ -66,9 +67,6 @@ end
66
67
  # TODO: move require "pg" into loader class and abstract to support more gems
67
68
  if File.exist?("#{Jets.root}config/database.yml")
68
69
  require "active_record"
69
- # Note: think this is only needed for specs
70
- # Apps require pg in their own Gemfile via bundler
71
- exists = File.exist?("/var/task/bundled/gems/ruby/2.5.0/gems/pg-0.21.0/lib/pg_ext.so")
72
- # Jets.logger.info("pg_ext.so exists #{exists.inspect}")
73
70
  require "pg" if Gem.loaded_specs.has_key?('pg')
71
+ require "mysql2" if Gem.loaded_specs.has_key?('mysql2')
74
72
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jets
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.4
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-10-11 00:00:00.000000000 Z
11
+ date: 2018-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -439,12 +439,24 @@ files:
439
439
  - lib/jets/booter.rb
440
440
  - lib/jets/builders.rb
441
441
  - lib/jets/builders/code_builder.rb
442
- - lib/jets/builders/deducer.rb
443
442
  - lib/jets/builders/gem_replacer.rb
444
443
  - lib/jets/builders/handler_generator.rb
445
- - lib/jets/builders/node-hello.js
446
- - lib/jets/builders/node-shim.js
447
- - lib/jets/builders/shared_deducer.rb
444
+ - lib/jets/builders/md5.rb
445
+ - lib/jets/builders/md5_zip.rb
446
+ - lib/jets/builders/rack_packager.rb
447
+ - lib/jets/builders/rackup_wrappers/rackup
448
+ - lib/jets/builders/rackup_wrappers/rackup.rb
449
+ - lib/jets/builders/reconfigure_rails.rb
450
+ - lib/jets/builders/reconfigure_rails/config/initializers/jets.rb
451
+ - lib/jets/builders/ruby_packager.rb
452
+ - lib/jets/builders/shim_vars.rb
453
+ - lib/jets/builders/shim_vars/app.rb
454
+ - lib/jets/builders/shim_vars/base.rb
455
+ - lib/jets/builders/shim_vars/shared.rb
456
+ - lib/jets/builders/templates/handler.js
457
+ - lib/jets/builders/templates/shim.js
458
+ - lib/jets/builders/tidy.rb
459
+ - lib/jets/builders/util.rb
448
460
  - lib/jets/camelizer.rb
449
461
  - lib/jets/cfn.rb
450
462
  - lib/jets/cfn/builders.rb
@@ -460,6 +472,7 @@ files:
460
472
  - lib/jets/cfn/builders/shared_builder.rb
461
473
  - lib/jets/cfn/ship.rb
462
474
  - lib/jets/cfn/status.rb
475
+ - lib/jets/cfn/upload.rb
463
476
  - lib/jets/cli.rb
464
477
  - lib/jets/commands.rb
465
478
  - lib/jets/commands/base.rb
@@ -496,12 +509,19 @@ files:
496
509
  - lib/jets/commands/help/dynamodb/generate.md
497
510
  - lib/jets/commands/help/dynamodb/migrate.md
498
511
  - lib/jets/commands/help/generate.md
512
+ - lib/jets/commands/help/import/rack.md
513
+ - lib/jets/commands/help/import/rails.md
499
514
  - lib/jets/commands/help/new.md
500
515
  - lib/jets/commands/help/routes.md
501
516
  - lib/jets/commands/help/runner.md
502
517
  - lib/jets/commands/help/server.md
503
518
  - lib/jets/commands/help/status.md
504
519
  - lib/jets/commands/help/url.md
520
+ - lib/jets/commands/import.rb
521
+ - lib/jets/commands/import/base.rb
522
+ - lib/jets/commands/import/rack.rb
523
+ - lib/jets/commands/import/rail.rb
524
+ - lib/jets/commands/import/sequence.rb
505
525
  - lib/jets/commands/main.rb
506
526
  - lib/jets/commands/markdown.rb
507
527
  - lib/jets/commands/markdown/creator.rb
@@ -536,12 +556,14 @@ files:
536
556
  - lib/jets/commands/templates/skeleton/config/application.rb.tt
537
557
  - lib/jets/commands/templates/skeleton/config/database.yml.tt
538
558
  - lib/jets/commands/templates/skeleton/config/dynamodb.yml
559
+ - lib/jets/commands/templates/skeleton/config/environments/development.rb
560
+ - lib/jets/commands/templates/skeleton/config/environments/production.rb
539
561
  - lib/jets/commands/templates/skeleton/config/routes.rb
540
562
  - lib/jets/commands/templates/skeleton/db/.gitkeep
541
563
  - lib/jets/commands/templates/skeleton/public/404.html
542
564
  - lib/jets/commands/templates/skeleton/public/422.html
543
565
  - lib/jets/commands/templates/skeleton/public/500.html
544
- - lib/jets/commands/templates/skeleton/public/images/favicon.ico
566
+ - lib/jets/commands/templates/skeleton/public/favicon.ico
545
567
  - lib/jets/commands/templates/skeleton/public/index.html.tt
546
568
  - lib/jets/commands/templates/skeleton/spec/controllers/posts_controller_spec.rb
547
569
  - lib/jets/commands/templates/skeleton/spec/fixtures/payloads/posts-index.json
@@ -586,8 +608,7 @@ files:
586
608
  - lib/jets/generator/templates/rails/scaffold_controller/controller.rb
587
609
  - lib/jets/inflections.rb
588
610
  - lib/jets/internal/app/controllers/jets/public_controller.rb
589
- - lib/jets/internal/app/controllers/jets/public_controller/python/show.py
590
- - lib/jets/internal/app/controllers/jets/public_controller/python/show.pyc
611
+ - lib/jets/internal/app/controllers/jets/rack_controller.rb
591
612
  - lib/jets/internal/app/jobs/jets/preheat_job.rb
592
613
  - lib/jets/io.rb
593
614
  - lib/jets/job.rb
@@ -613,6 +634,10 @@ files:
613
634
  - lib/jets/processors.rb
614
635
  - lib/jets/processors/deducer.rb
615
636
  - lib/jets/processors/main_processor.rb
637
+ - lib/jets/rack.rb
638
+ - lib/jets/rack/hash_converter.rb
639
+ - lib/jets/rack/request.rb
640
+ - lib/jets/rack/server.rb
616
641
  - lib/jets/rails_overrides.rb
617
642
  - lib/jets/rails_overrides/asset_tag_helper.rb
618
643
  - lib/jets/rails_overrides/common_methods.rb
@@ -1,73 +0,0 @@
1
- 'use strict';
2
- console.log('Loading hello world function');
3
-
4
- // https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html
5
-
6
- exports.handler = function(event, context, callback) {
7
- let name = "you";
8
- let city = 'World';
9
- let time = 'day';
10
- let day = '';
11
- let responseCode = 200;
12
- console.log("request: " + JSON.stringify(event));
13
-
14
- // This is a simple illustration of app-specific logic to return the response.
15
- // Although only 'event.queryStringParameters' are used here, other request data,
16
- // such as 'event.headers', 'event.pathParameters', 'event.body', 'event.stageVariables',
17
- // and 'event.requestContext' can be used to determine what response to return.
18
- //
19
- if (event.queryStringParameters !== null && event.queryStringParameters !== undefined) {
20
- if (event.queryStringParameters.name !== undefined &&
21
- event.queryStringParameters.name !== null &&
22
- event.queryStringParameters.name !== "") {
23
- console.log("Received name: " + event.queryStringParameters.name);
24
- name = event.queryStringParameters.name;
25
- }
26
- }
27
-
28
- if (event.pathParameters !== null && event.pathParameters !== undefined) {
29
- if (event.pathParameters.proxy !== undefined &&
30
- event.pathParameters.proxy !== null &&
31
- event.pathParameters.proxy !== "") {
32
- console.log("Received proxy: " + event.pathParameters.proxy);
33
- city = event.pathParameters.proxy;
34
- }
35
- }
36
-
37
- if (event.headers !== null && event.headers !== undefined) {
38
- if (event.headers['day'] !== undefined && event.headers['day'] !== null && event.headers['day'] !== "") {
39
- console.log("Received day: " + event.headers.day);
40
- day = event.headers.day;
41
- }
42
- }
43
-
44
- if (event.body !== null && event.body !== undefined) {
45
- let body = JSON.parse(event.body)
46
- if (body.time)
47
- time = body.time;
48
- }
49
-
50
- let greeting = 'Good ' + time + ', ' + name + ' of ' + city + '. ';
51
- if (day) greeting += 'Happy ' + day + '!';
52
-
53
- var responseBody = {
54
- message: greeting,
55
- input: event
56
- };
57
-
58
- // The output from a Lambda proxy integration must be
59
- // of the following JSON object. The 'headers' property
60
- // is for custom response headers in addition to standard
61
- // ones. The 'body' property must be a JSON string. For
62
- // base64-encoded payload, you must also set the 'isBase64Encoded'
63
- // property to 'true'.
64
- var response = {
65
- statusCode: responseCode,
66
- headers: {
67
- "x-custom-header" : "my custom header value"
68
- },
69
- body: JSON.stringify(responseBody)
70
- };
71
- console.log("response: " + JSON.stringify(response))
72
- callback(null, response);
73
- };
@@ -1,182 +0,0 @@
1
- 'use strict';
2
-
3
- const spawn = require('child_process').spawn;
4
- const fs = require('fs');
5
- const readline = require('readline');
6
- const TMP_LOG_PATH = '/tmp/shim-subprocess.log';
7
- const subprocess_out = fs.openSync(TMP_LOG_PATH, 'a');
8
- const subprocess_err = fs.openSync(TMP_LOG_PATH, 'a');
9
- const JETS_DEBUG = process.env.JETS_DEBUG // set JETS_DEBUG=1 to see more debugging info
10
- const JETS_OUTPUT = '/tmp/jets-output.log';
11
-
12
- function once() {
13
- // Uncomment fake run once locally. No need to do this on real lambda environment.
14
- // var filename = '/tmp/once.txt';
15
- // if (fs.existsSync(filename)) {
16
- // return;
17
- // }
18
- // fs.closeSync(fs.openSync(filename, 'w'));
19
-
20
- // start tcp server and detach
21
- const subprocess = spawn('bin/ruby_server', {
22
- detached: true,
23
- stdio: [ 'ignore', subprocess_out, subprocess_err ]
24
- });
25
- subprocess.on('error', function(err) {
26
- log('bin/ruby_server error', err);
27
- });
28
-
29
- subprocess.on('close', function(exit_code) {
30
- log("Subprocess was shut down or deattached!");
31
- });
32
-
33
- // prevent the parent from waiting for a subprocess to exit
34
- // https://nodejs.org/api/child_process.html
35
- subprocess.unref();
36
- }
37
-
38
- once();
39
-
40
- // Produces an Error object that displays in the AWS Lambda test console nicely.
41
- // The backtrace are the ruby lines, not the nodejs shim error lines.
42
- // The json payload in the Lambda console looks something like this:
43
- //
44
- // {
45
- // "errorMessage": "RubyError: RuntimeError: error in submethod",
46
- // "errorType": "RubyError",
47
- // "stackTrace": [
48
- // [
49
- // "line1",
50
- // "line2",
51
- // "line3"
52
- // ]
53
- // ]
54
- // }
55
- //
56
- function rubyError(resp) {
57
- var name = resp["errorType"]
58
- var message = resp["errorMessage"]
59
- var stack = resp["stackTrace"]
60
- stack.unshift(message); // JS error includes the error message at the top of the stacktrac also
61
- stack = stack.join("\n")
62
-
63
- var error = new Error(message)
64
- error.name = name
65
- error.stack = stack
66
- return error
67
- }
68
-
69
- // On AWS Lambda, we can log to either stdout or stderr and we're okay.
70
- // But locally when we're testing the shim, the log output can mess up piping
71
- // to jq. So not logging to stdout because when testing this shim locally the
72
- // stdout output messes up a pipe to jq.
73
- function log(text, level="info") {
74
- if (level == "info" && JETS_DEBUG) {
75
- // only log if JETS_DEBUG is set
76
- console.error(text);
77
- } else if (level == "debug") {
78
- // always log if "debug" passed into method
79
- console.error(text);
80
- }
81
- }
82
-
83
- ////////////////////////////
84
- // main logic for handler
85
- const net = require('net');
86
- const PORT = 8080;
87
- const HOST = '127.0.0.1';
88
-
89
- function request(event, handler, callback) {
90
- log("event:");
91
- log(event);
92
- var client = new net.Socket();
93
- client.connect(PORT, HOST, function() {
94
- log('Connected to socket');
95
- client.write(JSON.stringify(event));
96
- client.write("\r\n") // important: \r\n is how server knows input is done
97
- client.write(handler);
98
- client.write("\r\n") // important: \r\n is how server knows input is done
99
- });
100
-
101
- // string concatation in javascript is faster than array concatation
102
- // http://bit.ly/2gBMDs6
103
- var stdout_buffer = ""; // stdout buffer
104
- client.on('data', function(buffer) {
105
- log('Received data from socket: ' + buffer);
106
- stdout_buffer += buffer;
107
- });
108
-
109
- client.on('close', function() {
110
- log('Socket connection closed');
111
- // If server is not yet running, socket immediately closes and stdout_buffer
112
- // is still empty. Return right away for this case, so request can retry.
113
- if (stdout_buffer == "") {
114
- return;
115
- }
116
-
117
- if (fs.existsSync(JETS_OUTPUT)) {
118
- // Thanks: https://stackoverflow.com/questions/6156501/read-a-file-one-line-at-a-time-in-node-js
119
- var rd = readline.createInterface({
120
- input: fs.createReadStream(JETS_OUTPUT),
121
- // output: process.stdout,
122
- console: false
123
- });
124
-
125
- rd.on('line', function(line) {
126
- // Important to use console.error in case locally testing shim or we see
127
- // stdout "twice", once from here and once from ruby-land and it's confusing.
128
- // AWS lambda will write console.error and console.log to CloudWatch.
129
- console.error(line); // output to AWS Lambda Logs
130
- });
131
- }
132
-
133
- var resp = JSON.parse(stdout_buffer);
134
- if (resp["errorMessage"]) {
135
- // Customize error object for lambda format
136
- var error = rubyError(resp)
137
- callback(error);
138
- } else {
139
- callback(null, resp);
140
- }
141
- client.destroy(); // kill client after server's response
142
- });
143
-
144
- client.on('error', function(error) {
145
- log("Socket error:");
146
- log(error);
147
- log("Retrying request");
148
- setTimeout(function() {
149
- if (fs.existsSync(TMP_LOG_PATH)) {
150
- var contents = fs.readFileSync(TMP_LOG_PATH, 'utf8');
151
- if (contents != "") {
152
- log("subprocess output:", "debug");
153
- log(contents, "debug");
154
- }
155
- }
156
- request(event, handler, callback);
157
- }, 500);
158
- });
159
- };
160
-
161
- <% @deducer.functions.each do |function_name| %>
162
- exports.<%= function_name %> = (event, context, callback) => {
163
- request(event, "<%= @deducer.handler_for(function_name) %>", callback);
164
- }
165
- <% end %>
166
-
167
- // for local testing
168
- if (require.main === module) {
169
- // fake event and context
170
- var event = {"hello": "world"}
171
- // var event = {"_prewarm": "1"} // prewarm special payload
172
- // var event = {"body": {"hello": "world"}} // API Gateway wrapper structure
173
- var context = {"fake": "context"}
174
- exports.<%= @deducer.functions.first %>(event, context, (error, message) => {
175
- log("\nLOCAL TESTING OUTPUT")
176
- if (error) {
177
- console.log("error message: %o", error)
178
- } else {
179
- console.log(JSON.stringify(message)) // stringify
180
- }
181
- })
182
- }
@@ -1,47 +0,0 @@
1
- from pprint import pprint
2
- import json
3
- import os
4
- import os.path
5
- import mimetypes
6
- import sys
7
-
8
- def lambda_handler(event, context):
9
- public_path = "public%s" % event["path"]
10
-
11
- body = None
12
- if os.path.exists(public_path):
13
- body = render(public_path)
14
-
15
- if body:
16
- mimetype = mimetypes.guess_type(public_path)
17
- headers = {"Content-Type": mimetype[0]}
18
- return response(body, 200, headers)
19
- else:
20
- return response("404 Not Found: %s" % public_path, 404)
21
-
22
- def render(file=None):
23
- with open(file,'r') as f:
24
- return(f.read())
25
-
26
- def response(body, status_code=200, headers={}):
27
- default_headers = {
28
- 'Content-Type': 'text/html',
29
- 'Access-Control-Allow-Origin': '*'
30
- }
31
- # http://treyhunner.com/2016/02/how-to-merge-dictionaries-in-python/
32
- headers = {**default_headers, **headers}
33
- return {
34
- 'statusCode': str(status_code),
35
- 'body': body,
36
- 'headers': headers,
37
- }
38
-
39
- def log(message):
40
- print(message, file=sys.stderr)
41
-
42
- if __name__ == '__main__':
43
- with open('event.json') as f:
44
- data = json.load(f)
45
- # pprint(data)
46
- # print(lambda_handler(data, {}))
47
- print(json.dumps(lambda_handler(data, {}))) # if result is json