jets 0.10.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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