jets 0.10.4 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/Gemfile.lock +12 -12
- data/README.md +4 -2
- data/exe/jets +2 -2
- data/lib/jets/application.rb +41 -5
- data/lib/jets/aws_info.rb +20 -0
- data/lib/jets/builders/code_builder.rb +201 -296
- data/lib/jets/builders/gem_replacer.rb +1 -1
- data/lib/jets/builders/handler_generator.rb +62 -43
- data/lib/jets/builders/md5.rb +55 -0
- data/lib/jets/builders/md5_zip.rb +60 -0
- data/lib/jets/builders/rack_packager.rb +29 -0
- data/lib/jets/builders/rackup_wrappers/rackup +23 -0
- data/lib/jets/builders/rackup_wrappers/rackup.rb +7 -0
- data/lib/jets/builders/reconfigure_rails/config/initializers/jets.rb +14 -0
- data/lib/jets/builders/reconfigure_rails.rb +99 -0
- data/lib/jets/builders/ruby_packager.rb +198 -0
- data/lib/jets/builders/{deducer.rb → shim_vars/app.rb} +14 -10
- data/lib/jets/builders/shim_vars/base.rb +24 -0
- data/lib/jets/builders/{shared_deducer.rb → shim_vars/shared.rb} +4 -3
- data/lib/jets/builders/shim_vars.rb +5 -0
- data/lib/jets/builders/templates/handler.js +9 -0
- data/lib/jets/builders/templates/shim.js +271 -0
- data/lib/jets/builders/tidy.rb +80 -0
- data/lib/jets/builders/util.rb +28 -0
- data/lib/jets/builders.rb +8 -2
- data/lib/jets/cfn/builders/function_builder.rb +0 -10
- data/lib/jets/cfn/builders/parent_builder.rb +7 -6
- data/lib/jets/cfn/ship.rb +9 -103
- data/lib/jets/cfn/upload.rb +139 -0
- data/lib/jets/cfn.rb +1 -0
- data/lib/jets/commands/build.rb +17 -19
- data/lib/jets/commands/deploy.rb +2 -0
- data/lib/jets/commands/help/deploy.md +2 -2
- data/lib/jets/commands/help/import/rack.md +13 -0
- data/lib/jets/commands/help/import/rails.md +11 -0
- data/lib/jets/commands/import/base.rb +39 -0
- data/lib/jets/commands/import/rack.rb +16 -0
- data/lib/jets/commands/import/rail.rb +68 -0
- data/lib/jets/commands/import/sequence.rb +68 -0
- data/lib/jets/commands/import.rb +14 -0
- data/lib/jets/commands/main.rb +2 -1
- data/lib/jets/commands/new.rb +1 -1
- data/lib/jets/commands/sequence.rb +26 -22
- data/lib/jets/commands/templates/skeleton/Gemfile.tt +5 -2
- data/lib/jets/commands/templates/skeleton/README.md +11 -2
- data/lib/jets/commands/templates/skeleton/app/jobs/application_job.rb +1 -1
- data/lib/jets/commands/templates/skeleton/app/views/layouts/application.html.erb.tt +1 -1
- data/lib/jets/commands/templates/skeleton/config/application.rb.tt +12 -5
- data/lib/jets/commands/templates/skeleton/config/database.yml.tt +5 -1
- data/lib/jets/commands/templates/skeleton/config/environments/development.rb +3 -0
- data/lib/jets/commands/templates/skeleton/config/environments/production.rb +5 -0
- data/lib/jets/commands/templates/skeleton/public/{images/favicon.ico → favicon.ico} +0 -0
- data/lib/jets/commands/templates/skeleton/spec/controllers/posts_controller_spec.rb +1 -3
- data/lib/jets/commands.rb +1 -0
- data/lib/jets/controller/base.rb +1 -1
- data/lib/jets/controller/layout.rb +3 -0
- data/lib/jets/controller/params.rb +3 -2
- data/lib/jets/controller/request.rb +4 -0
- data/lib/jets/core.rb +20 -18
- data/lib/jets/core_ext/kernel.rb +9 -5
- data/lib/jets/default/application.rb +1 -1
- data/lib/jets/inflections.rb +16 -8
- data/lib/jets/internal/app/controllers/jets/public_controller.rb +17 -22
- data/lib/jets/internal/app/controllers/jets/rack_controller.rb +15 -0
- data/lib/jets/naming.rb +0 -23
- data/lib/jets/rack/hash_converter.rb +25 -0
- data/lib/jets/rack/request.rb +71 -0
- data/lib/jets/rack/server.rb +47 -0
- data/lib/jets/rack.rb +7 -0
- data/lib/jets/rails_overrides/asset_tag_helper.rb +12 -11
- data/lib/jets/resource/function.rb +13 -5
- data/lib/jets/router.rb +1 -1
- data/lib/jets/ruby_server.rb +63 -18
- data/lib/jets/server/api_gateway.rb +1 -1
- data/lib/jets/stack/resource.rb +3 -1
- data/lib/jets/version.rb +1 -1
- data/lib/jets.rb +3 -5
- metadata +34 -9
- data/lib/jets/builders/node-hello.js +0 -73
- data/lib/jets/builders/node-shim.js +0 -182
- data/lib/jets/internal/app/controllers/jets/public_controller/python/show.py +0 -47
- data/lib/jets/internal/app/controllers/jets/public_controller/python/show.pyc +0 -0
data/lib/jets/ruby_server.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
41
|
-
|
42
|
-
|
43
|
-
#
|
44
|
-
|
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
|
-
#
|
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
|
59
|
-
|
60
|
-
|
61
|
-
|
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
|
|
data/lib/jets/stack/resource.rb
CHANGED
@@ -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
|
-
|
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
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.
|
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
|
+
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/
|
446
|
-
- lib/jets/builders/
|
447
|
-
- lib/jets/builders/
|
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/
|
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/
|
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
|
Binary file
|