view release on metacpan or search on metacpan
0.0.18 2020-06-02T19:54:22Z
- Perl 5.30.3 and 5.28.3 are released
0.0.17 2020-04-28T10:07:10Z
- new region Europe (Milan) eu-south-1 is available
0.0.16 2020-04-23T00:23:44Z
- new region Africa (Cape Town) af-south-1 is available
0.0.15 2020-04-17T11:53:53Z
- fix syntax error of POD
0.0.14 2020-04-11T11:37:43Z
- AWS::Lambda::PSGI supports API Gateway v2 now
0.0.13 2020-03-15T00:14:09Z
- perl 5.30.2 is released
0.0.12 2020-03-11T06:42:11Z
- bump up AWS::XRay to 0.11
lib/AWS/Lambda/AL2.pm
lib/AWS/Lambda/AL2023.pm
lib/AWS/Lambda/Bootstrap.pm
lib/AWS/Lambda/Context.pm
lib/AWS/Lambda/PSGI.pm
lib/AWS/Lambda/ResponseWriter.pm
minil.toml
script/bootstrap
t/00_compile.t
t/01_echo.t
t/02_error.t
t/03_init_error.t
t/04_handler_not_found.t
t/10_lambda_next.t
t/11_lambda_response.t
t/12_lambda_error.t
t/13_lambda_init_error.t
t/14_streaming.t
t/15_lambda_response_streaming.t
t/20_psgi.t
t/21_psgi_response_streaming.t
t/lib/BootstrapMock.pm
t/test_handlers/echo.pl
t/test_handlers/error.pl
t/test_handlers/init_error.pl
t/test_handlers/streaming.pl
t/testdata/alb-base64-request.json
t/testdata/alb-get-request.json
t/testdata/alb-post-request.json
t/testdata/apigateway-base64-request.json
t/testdata/apigateway-get-request.json
t/testdata/apigateway-post-request.json
t/testdata/apigateway-v2-base64-request.json
t/testdata/apigateway-v2-get-request.json
t/testdata/apigateway-v2-post-request.json
lib/AWS/Lambda/Bootstrap.pm view on Meta::CPAN
my $task_root = $self->{task_root};
my $handler = $self->{handler};
my $name = $self->{function_name};
return try {
package main;
require "${task_root}/${handler}.pl";
my $f = main->can($name) // die "handler $name is not found";
$self->{function} = $f;
} catch {
$self->lambda_init_error($_);
$self->{function} = sub {};
undef;
};
}
sub handle_event {
my $self = shift;
$self->_init or return;
my ($payload, $context) = $self->lambda_next;
my $response = try {
local $AWS::Lambda::context = $context;
local $ENV{_X_AMZN_TRACE_ID} = $context->{trace_id};
$self->{function}->($payload, $context);
} catch {
my $err = $_;
print STDERR "$err";
$self->lambda_error($err, $context);
bless {}, 'AWS::Lambda::ErrorSentinel';
};
my $ref = ref($response);
if ($ref eq 'AWS::Lambda::ErrorSentinel') {
return;
}
if ($ref eq 'CODE') {
$self->lambda_response_streaming($response, $context);
} else {
$self->lambda_response($response, $context);
lib/AWS/Lambda/Bootstrap.pm view on Meta::CPAN
response_url => $url,
http => $self->{http},
);
$writer->_request($content_type);
return $writer;
});
} catch {
my $err = $_;
print STDERR "$err";
if ($writer) {
$writer->_close_with_error($err);
} else {
$self->lambda_error($err, $context);
}
};
if ($writer) {
my $response = $writer->_handle_response;
if (!$response->{success}) {
die "failed to response of execution: $response->{status} $response->{reason}";
}
}
}
sub lambda_error {
my $self = shift;
my ($error, $context) = @_;
my $runtime_api = $self->{runtime_api};
my $api_version = $self->{api_version};
my $request_id = $context->aws_request_id;
my $url = "http://${runtime_api}/${api_version}/runtime/invocation/${request_id}/error";
my $type = blessed($error) // "Error";
my $resp = $self->{http}->post($url, {
content => encode_json({
errorMessage => "$error",
errorType => "$type",
}),
});
if (!$resp->{success}) {
die "failed to send error of execution: $resp->{status} $resp->{reason}";
}
}
sub lambda_init_error {
my $self = shift;
my $error = shift;
my $runtime_api = $self->{runtime_api};
my $api_version = $self->{api_version};
my $url = "http://${runtime_api}/${api_version}/runtime/init/error";
my $type = blessed($error) // "Error";
my $resp = $self->{http}->post($url, {
content => encode_json({
errorMessage => "$error",
errorType => "$type",
}),
});
if (!$resp->{success}) {
die "failed to send error of execution: $resp->{status} $resp->{reason}";
}
}
1;
__END__
=encoding utf-8
=head1 NAME
lib/AWS/Lambda/PSGI.pm view on Meta::CPAN
if ($key !~ /^(?:CONTENT_LENGTH|CONTENT_TYPE)$/) {
$key = "HTTP_$key";
}
if (ref $value eq "ARRAY") {
$value = join ", ", @$value;
}
$env->{$key} = $value;
}
$env->{'psgi.version'} = [1, 1];
$env->{'psgi.errors'} = *STDERR;
$env->{'psgi.run_once'} = Plack::Util::FALSE;
$env->{'psgi.multithread'} = Plack::Util::FALSE;
$env->{'psgi.multiprocess'} = Plack::Util::FALSE;
$env->{'psgi.streaming'} = Plack::Util::FALSE;
$env->{'psgi.nonblocking'} = Plack::Util::FALSE;
$env->{'psgix.harakiri'} = Plack::Util::TRUE;
$env->{'psgix.input.buffered'} = Plack::Util::TRUE;
# inject the request id that compatible with Plack::Middleware::RequestId
if ($ctx) {
lib/AWS/Lambda/PSGI.pm view on Meta::CPAN
while (my ($key, $value) = each %$headers) {
$key =~ s/-/_/g;
$key = uc $key;
if ($key !~ /^(?:CONTENT_LENGTH|CONTENT_TYPE)$/) {
$key = "HTTP_$key";
}
$env->{$key} = $value;
}
$env->{'psgi.version'} = [1, 1];
$env->{'psgi.errors'} = *STDERR;
$env->{'psgi.run_once'} = Plack::Util::FALSE;
$env->{'psgi.multithread'} = Plack::Util::FALSE;
$env->{'psgi.multiprocess'} = Plack::Util::FALSE;
$env->{'psgi.streaming'} = Plack::Util::FALSE;
$env->{'psgi.nonblocking'} = Plack::Util::FALSE;
$env->{'psgix.harakiri'} = Plack::Util::TRUE;
$env->{'psgix.input.buffered'} = Plack::Util::TRUE;
# inject the request id that compatible with Plack::Middleware::RequestId
if ($ctx) {
lib/AWS/Lambda/ResponseWriter.pm view on Meta::CPAN
my $self = shift;
if ($self->{closed}) {
# already closed
return;
}
my $handle = $self->{handle};
$self->{closed} = 1;
return $handle->write("0\x0D\x0A\x0D\x0A");
}
sub _close_with_error {
my ($self, $error) = @_;
if ($self->{closed}) {
# already closed
return;
}
$self->{closed} = 1;
my $handle = $self->{handle};
$handle->write("0\x0D\x0A");
my $type = blessed($error) // "Error";
return $handle->write_header_lines({
"lambda-runtime-function-error-type" => "$type",
"lambda-runtime-function-error-body" => encode_base64("$error", ""),
}, {
"lambda-runtime-function-error-type" => "Lambda-Runtime-Function-Error-Type",
"lambda-runtime-function-error-body" => "Lambda-Runtime-Function-Error-Body",
});
}
1;
t/02_error.t view on Meta::CPAN
use strict;
use warnings;
use utf8;
use Test::More;
use FindBin;
use lib "$FindBin::Bin/lib";
use BootstrapMock;
my $error;
my $bootstrap = BootstrapMock->new(
handler => "error.handle",
runtime_api => "example.com",
task_root => "$FindBin::Bin/test_handlers",
lambda_next => sub {
return +{
key1 => 1,
key2 => 2,
key3 => 3,
}, undef;
},
lambda_error => sub {
my $self = shift;
$error = shift;
},
);
ok !$bootstrap->handle_event;
like $error, qr/some error/;
done_testing;
t/03_init_error.t view on Meta::CPAN
use warnings;
use utf8;
use Test::More;
use FindBin;
use lib "$FindBin::Bin/lib";
use BootstrapMock;
use AWS::Lambda::Context;
use Try::Tiny;
my $error;
my $bootstrap = BootstrapMock->new(
handler => "init_error.handle",
runtime_api => "example.com",
task_root => "$FindBin::Bin/test_handlers",
lambda_init_error => sub {
my $self = shift;
$error = shift;
},
);
ok !$bootstrap->handle_event;
like $error, qr/did not return a true value/;
done_testing;
t/04_handler_not_found.t view on Meta::CPAN
use warnings;
use utf8;
use Test::More;
use FindBin;
use lib "$FindBin::Bin/lib";
use BootstrapMock;
use AWS::Lambda::Context;
use Try::Tiny;
my $error;
my $bootstrap = BootstrapMock->new(
handler => "echo.handle_not_found",
runtime_api => "example.com",
task_root => "$FindBin::Bin/test_handlers",
lambda_init_error => sub {
my $self = shift;
$error = shift;
},
);
ok !$bootstrap->handle_event;
like $error, qr/handler handle_not_found is not found/;
done_testing;
t/12_lambda_error.t view on Meta::CPAN
my $sock = shift;
my $server = HTTP::Server::PSGI->new(
listen_sock => $sock,
);
$server->run(sub {
my $env = shift;
my $req = Plack::Request->new($env);
is $req->method, "POST", "http method";
my $body = $req->body;
my $response = decode_json(<$body>);
cmp_deeply $response, {errorMessage=>"some error ð¨", errorType=>'Error'}, "response";
my $res = $req->new_response(200);
$res->finalize;
});
},
max_wait => 10, # seconds
);
my $bootstrap = AWS::Lambda::Bootstrap->new(
handler => "echo.handle",
runtime_api => "example.com",
task_root => "$FindBin::Bin/test_handlers",
runtime_api => "127.0.0.1:" . $app_server->port,
);
my $error = "some error ð¨";
my $context = AWS::Lambda::Context->new(
deadline_ms => 1542409706888,
aws_request_id => "8476a536-e9f4-11e8-9739-2dfe598c3fcd",
invoked_function_arn => 'arn:aws:lambda:us-east-2:123456789012:function:custom-runtime',
);
$bootstrap->lambda_error($error, $context);
$app_server->stop;
done_testing;
t/13_lambda_init_error.t view on Meta::CPAN
my $sock = shift;
my $server = HTTP::Server::PSGI->new(
listen_sock => $sock,
);
$server->run(sub {
my $env = shift;
my $req = Plack::Request->new($env);
is $req->method, "POST", "http method";
my $body = $req->body;
my $response = decode_json(<$body>);
cmp_deeply $response, {errorMessage=>"some error ð¨", errorType=>'Error'}, "response";
my $res = $req->new_response(200);
$res->finalize;
});
},
max_wait => 10, # seconds
);
my $bootstrap = AWS::Lambda::Bootstrap->new(
handler => "echo.handle",
runtime_api => "example.com",
task_root => "$FindBin::Bin/test_handlers",
runtime_api => "127.0.0.1:" . $app_server->port,
);
my $error = "some error ð¨";
$bootstrap->lambda_init_error($error);
$app_server->stop;
done_testing;
t/lib/BootstrapMock.pm view on Meta::CPAN
our @ISA = qw(AWS::Lambda::Bootstrap);
sub new {
my $class = shift;
my %args = @_;
my $self = $class->SUPER::new(%args);
$self->{lambda_next} = $args{lambda_next} // sub { die "unexpected call of lambda_next" };
$self->{lambda_response} = $args{lambda_response} // sub { die "unexpected call of lambda_response" };
$self->{lambda_response_streaming} = $args{lambda_response_streaming} // sub { die "unexpected call of lambda_response_streaming" };
$self->{lambda_error} = $args{lambda_error} // sub { die "unexpected call of lambda_error" };
$self->{lambda_init_error} = $args{lambda_init_error} // sub { die "unexpected call of lambda_init_error" };
return $self;
}
sub lambda_next {
my $self = shift;
return $self->{lambda_next}->($self, @_);
}
sub lambda_response {
my $self = shift;
return $self->{lambda_response}->($self, @_);
}
sub lambda_response_streaming {
my $self = shift;
return $self->{lambda_response_streaming}->($self, @_);
}
sub lambda_error {
my $self = shift;
return $self->{lambda_error}->($self, @_);
}
sub lambda_init_error {
my $self = shift;
return $self->{lambda_init_error}->($self, @_);
}
1;
t/test_handlers/error.pl view on Meta::CPAN
use utf8;
use strict;
use warnings;
sub handle {
die "some error";
}
1;