AWS-Lambda

 view release on metacpan or  search on metacpan

MANIFEST  view on Meta::CPAN

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
t/testdata/function-urls-get-request.json
t/testdata/function-urls-post-base64-request.json
t/testdata/function-urls-post-request.json
xt/21_mojo.t
xt/21_mojo_custom_domain.t
xt/21_mojoapp.pl
xt/22_dancer.t
xt/22_dancerapp.pl
META.yml
MANIFEST

README.md  view on Meta::CPAN

- [YAML::XS](https://metacpan.org/pod/YAML%3A%3AXS)
- [Net::SSLeay](https://metacpan.org/pod/Net%3A%3ASSLeay)
- [IO::Socket::SSL](https://metacpan.org/pod/IO%3A%3ASocket%3A%3ASSL)
- [Mozilla::CA](https://metacpan.org/pod/Mozilla%3A%3ACA)
- [local::lib](https://metacpan.org/pod/local%3A%3Alib)

[Paws](https://metacpan.org/pod/Paws) is optional. See the "Paws SUPPORT" section.

## AWS X-Ray SUPPORT

[AWS X-Ray](https://aws.amazon.com/xray/) is a service that collects data about requests that your application serves.
You can trace AWS Lambda requests and sends segment data with pre-install module [AWS::XRay](https://metacpan.org/pod/AWS%3A%3AXRay).

    use utf8;
    use warnings;
    use strict;
    use AWS::XRay qw/ capture /;

    sub handle {
        my ($payload, $context) = @_;
        capture "myApp" => sub {
            capture "nested" => sub {

author/perl-stripper/template.yaml  view on Meta::CPAN

AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: perl-strip

Resources:
  PerlStripper:
    Type: AWS::Serverless::Function
    Metadata:
      BuildMethod: makefile
    Properties:
      Description: Perl Stripper API
      CodeUri: ./perl-stripper/
      Handler: handler.handle
      Runtime: provided.al2
      Architectures: [arm64]
      Timeout: 120
      # https://docs.aws.amazon.com/lambda/latest/dg/configuration-function-common.html#configuration-memory-console
      MemorySize: 1769 # -> 1 vCPU

author/pod-stripper/scripts/pod_stripper.pl  view on Meta::CPAN

    my $file = shift;

    my $strip = Pod::Strip->new;
    my $module;
    { local $/ = undef;
      open my $pm, '<', $file;
      $module = <$pm>;
      close $pm
    }

    # it is not pod, but might be some data.
    # skip it for safety.
    if ($module =~ /^__DATA__$/m) {
        return
    }

    # We unlink the original pm
    unlink $file;

    open my $pm, '>', $file;
    $strip->output_fh($pm);

author/publish-perl-runtime-archives.pl  view on Meta::CPAN

use FindBin;
use Parallel::ForkManager;
use File::Basename 'basename';
use JSON qw(decode_json encode_json);

my $force = ($ARGV[0] // '') eq '-f';

sub head_or_put {
    my ($key, $zip) = @_;
    my $object = decode_json(`aws --output json --region us-east-1 s3api head-object --bucket shogo82148-lambda-perl-runtime-us-east-1 --key "$key" || echo "{}"`);
    my $current = $object->{Metadata}{md5chksum} || "";
    if (!$current) {
        say STDERR "Upload $zip to 3://shogo82148-lambda-perl-runtime-us-east-1/$key";
        my $cmd = "aws --output json --region 'us-east-1' s3api put-object --bucket 'shogo82148-lambda-perl-runtime-us-east-1' --key '$key' --body '$zip'";
        say STDERR "Executing: $cmd";
        if ($force) {
            $object = decode_json(`$cmd`);
            die "exit: $!" if $! != 0;
        }
    } else {
        say STDERR "s3://shogo82148-lambda-perl-runtime-us-east-1/$key is already updated";

author/update-aws-lambda-al.pl  view on Meta::CPAN

    "5.30",
    "5.28",
    "5.26",
];
$versions = [sort {version->parse("v$b") <=> version->parse("v$a")} @$versions];

# get the list of layers on Amazon Linux 1
my $layers = {};
my $pm = Parallel::ForkManager->new(10);
$pm->run_on_finish(sub {
    my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data) = @_;
    return unless $data;
    my ($version, $region, $arn) = @$data;
    return unless $version && $region && $arn;
    $layers->{$version} //= {};
    $layers->{$version}{$region} = $arn;
});

for my $version (@$versions) {
    for my $region (@{$regions->{x86_64}}) {
        say STDERR "loading $version in $region...";
        $pm->start("$version/$region") and next;

author/update-aws-lambda-al2.pl  view on Meta::CPAN

    "5.36",
    "5.34",
    "5.32",
];
$versions_al2 = [sort {version->parse("v$b") <=> version->parse("v$a")} @$versions_al2];

# get the list of layers on Amazon Linux 2
my $layers_al2_x86_64 = {};
my $pm_al2_x86_64 = Parallel::ForkManager->new(10);
$pm_al2_x86_64->run_on_finish(sub {
    my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data) = @_;
    return unless $data;
    my ($version, $region, $arn) = @$data;
    return unless $version && $region && $arn;

    $layers_al2_x86_64->{$version} //= {};
    $layers_al2_x86_64->{$version}{$region} = $arn;
});

for my $version (@$versions_al2) {
    for my $region (@{$regions->{x86_64}}) {
        say STDERR "loading $version in $region...";
        $pm_al2_x86_64->start("$version/$region") and next;

examples/cgi/WwwCounter/style3.css  view on Meta::CPAN

 * Border
 *   .bo : border
 * Layout
 *   .i : indent
 *   .ce : center
 *   .nw : nowrap
 *   .mb1 : margin bottom 1em
 *   .mt1 : margin top 1em
 * List
 *   .nomark : no mark
 *   .dl1 : data list
 * Semantics
 *   .cm : comment
 *   .success : success
 *   .info : information
 *   .warning : warning
 *   .caution : caution
 *   .index-title: index-title
 * Code
 *   .tab : tab
 *   .c : code box

examples/cgi/template.yaml  view on Meta::CPAN

    Properties:
      FileSystemId: !Ref FileSystem
      PosixUser:
        Uid: "1000"
        Gid: "1000"
      RootDirectory:
        CreationInfo:
          OwnerGid: "1000"
          OwnerUid: "1000"
          Permissions: "0777"
        Path: "/data"

  LambdaSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref VPC
      GroupDescription: "lambda sg"
  WwwCounter:
    Type: AWS::Serverless::Function
    Metadata:
      BuildMethod: makefile
    Properties:
      Description: Www Counter
      CodeUri: ./WwwCounter/
      Handler: handler.handle
      Runtime: provided.al2
      Environment:
        Variables:
          WWWCOUNT_DIR: /mnt/efs0
      Layers:

examples/s3-get-object/template.yaml  view on Meta::CPAN

# Perl port of https://github.com/awslabs/serverless-application-model/tree/master/examples/apps/s3-get-object

AWSTemplateFormatVersion: "2010-09-09"
Transform: "AWS::Serverless-2016-10-31"
Description: >-
  An Amazon S3 trigger that retrieves metadata for the object that has been
  updated.
Parameters:
  BucketNamePrefix:
    Type: String
    Default: sam-example
Resources:
  s3getobject:
    Type: "AWS::Serverless::Function"
    Properties:
      Handler: handler.handle
      Runtime: provided.al2
      CodeUri: s3-get-object.zip
      Description: >-
        An Amazon S3 trigger that retrieves metadata for the object that has
        been updated.
      MemorySize: 128
      Timeout: 3
      Layers:
        - !Sub arn:aws:lambda:${AWS::Region}:445285296882:layer:perl-5-32-runtime-al2:1
        - !Sub arn:aws:lambda:${AWS::Region}:445285296882:layer:perl-5-32-paws-al2:1
      Policies:
        - S3CrudPolicy:
            BucketName: !Sub "${BucketNamePrefix}-get-object"
      Events:

lib/AWS/Lambda.pm  view on Meta::CPAN

=item L<Mozilla::CA>

=item L<local::lib>

=back

L<Paws> is optional. See the "Paws SUPPORT" section.

=head2 AWS X-Ray SUPPORT

L<AWS X-Ray|https://aws.amazon.com/xray/> is a service that collects data about requests that your application serves.
You can trace AWS Lambda requests and sends segment data with pre-install module L<AWS::XRay>.

    use utf8;
    use warnings;
    use strict;
    use AWS::XRay qw/ capture /;

    sub handle {
        my ($payload, $context) = @_;
        capture "myApp" => sub {
            capture "nested" => sub {

lib/AWS/Lambda/ResponseWriter.pm  view on Meta::CPAN

    if (!$self->{closed}) {
        $self->close;
    }

    my $http = $self->{http};
    my $handle = $self->{handle};
    my $response;
    do { $response = $handle->read_response_header }
        until (substr($response->{status},0,1) ne '1');

    my $data_cb = $http->_prepare_data_cb($response, {});
    my $known_message_length = $handle->read_body($data_cb, $response);
    $handle->close;

    $response->{success} = substr( $response->{status}, 0, 1 ) eq '2';
    $response->{url} = $self->{response_url};
    return $response;
}

sub write {
    my ($self, $data) = @_;

    if ($self->{closed}) {
        # already closed
        croak "write failed: already closed";
    }

    if (!defined($data) || length($data) == 0) {
        return "0E0";
    }

    my $chunk  = sprintf '%X', length $data;
    $chunk .= "\x0D\x0A";
    $chunk .= $data;
    $chunk .= "\x0D\x0A";
    return $self->{handle}->write($chunk);
}

sub close {
    my $self = shift;
    if ($self->{closed}) {
        # already closed
        return;
    }

t/15_lambda_response_streaming.t  view on Meta::CPAN

use FindBin;
use AWS::Lambda::Bootstrap;
use AWS::Lambda::Context;
use Test::Deep;
use Test::SharedFork;
use Plack::Request;
use JSON::XS qw/decode_json/;

sub slurp {
    my $fh = shift;
    my $data = "";
    while ($fh->read(my $buf, 4096)) {
        $data .= $buf;
    }
    return $data;
}

my $app_server = Test::TCP->new(
    code => sub {
        my $port = shift;
        my $server = Starman::Server->new;
        my $app = sub {
            my $env = shift;
            my $req = Plack::Request->new($env);
            my $headers = $req->headers;

t/20_psgi.t  view on Meta::CPAN

use AWS::Lambda::Context;
use AWS::Lambda::PSGI;

sub slurp_json {
    my $name = $_[0];
    return decode_json(slurp("$FindBin::Bin/$name"));
}

sub slurp_fh {
    my $fh = shift;
    my $data = "";
    while ($fh->read(my $buf, 4096)) {
        $data .= $buf;
    }
    return decode_utf8($data);
}

my $app = AWS::Lambda::PSGI->new;

subtest "API Gateway GET Request" => sub {
    my $input = slurp_json("testdata/apigateway-get-request.json");
    my $output = $app->format_input($input);
    my $req = Plack::Request->new($output);
    is $req->method, 'GET', 'method';
    my $content;
    warning_is { $content = slurp_fh($req->input) } undef, 'no warning';
    is $content, '', 'content';
    is $req->request_uri, '/foo%20/bar?query=hoge&query=fuga', 'request uri';
    is $req->path_info, '/foo /bar', 'path info';
    is $req->query_string, 'query=hoge&query=fuga', 'query string';
    is $req->header('Header-Name'), 'Value1, Value2', 'header';
    ok !$req->env->{'psgi.streaming'}, 'psgi.streaming';
};

subtest "API Gateway POST Request" => sub {
    my $input = slurp_json("testdata/apigateway-post-request.json");
    my $output = $app->format_input($input);
    my $req = Plack::Request->new($output);
    is $req->method, 'POST', 'method';
    is $req->content_type, 'application/json', 'content-type';
    my $content;
    warning_is { $content = slurp_fh($req->input) } undef, 'no warning';
    is $content, '{"hello":"こんにちは世界"}', 'content';
    is $req->request_uri, '/', 'request uri';
    is $req->path_info, '/', 'path info';
    is $req->query_string, '', 'query string';
    ok !$req->env->{'psgi.streaming'}, 'psgi.streaming';
};

subtest "API Gateway Base64 encoded POST Request" => sub {
    my $input = slurp_json("testdata/apigateway-base64-request.json");
    my $output = $app->format_input($input);
    my $req = Plack::Request->new($output);
    is $req->method, 'POST', 'method';

    # You have to add 'application/octet-stream' to binary media types.
    # https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings-configure-with-console.html
    is $req->content_type, 'application/octet-stream', 'content-type';
    my $content;
    warning_is { $content = slurp_fh($req->input) } undef, 'no warning';
    is $content, '{"hello":"world"}', 'content';
    is $req->request_uri, '/', 'request uri';
    is $req->path_info, '/', 'path info';
    is $req->query_string, '', 'query string';
    ok !$req->env->{'psgi.streaming'}, 'psgi.streaming';
};

subtest "API Gateway v2 GET Request" => sub {
    my $input = slurp_json("testdata/apigateway-v2-get-request.json");
    my $output = $app->format_input($input);
    my $req = Plack::Request->new($output);
    is $req->method, 'GET', 'method';
    my $content;
    warning_is { $content = slurp_fh($req->input) } undef, 'no warning';
    is $content, '', 'content';
    is $req->request_uri, '/my/path?parameter1=value1&parameter1=value2&parameter2=value', 'request uri';
    is $req->path_info, '/my/path', 'path info';
    is $req->query_string, 'parameter1=value1&parameter1=value2&parameter2=value', 'query string';
    is $req->header('Header1'), 'value1,value2', 'header';
    ok !$req->env->{'psgi.streaming'}, 'psgi.streaming';
};

subtest "API Gateway v2 POST Request" => sub {
    my $input = slurp_json("testdata/apigateway-v2-post-request.json");
    my $output = $app->format_input($input);
    my $req = Plack::Request->new($output);
    is $req->method, 'POST', 'method';
    my $content;
    warning_is { $content = slurp_fh($req->input) } undef, 'no warning';
    is $content, '{"hello":"こんにちは世界"}', 'content';
    is $req->request_uri, '/my/path', 'request uri';
    is $req->path_info, '/my/path', 'path info';
    is $req->query_string, '', 'query string';
    ok !$req->env->{'psgi.streaming'}, 'psgi.streaming';
};

subtest "API Gateway v2 base64 Request" => sub {
    my $input = slurp_json("testdata/apigateway-v2-base64-request.json");
    my $output = $app->format_input($input);
    my $req = Plack::Request->new($output);
    is $req->method, 'POST', 'method';
    my $content;
    warning_is { $content = slurp_fh($req->input) } undef, 'no warning';
    is $content, '{"hello":"world"}', 'content';
    is $req->request_uri, '/my/path', 'request uri';
    is $req->path_info, '/my/path', 'path info';
    is $req->query_string, '', 'query string';
    ok !$req->env->{'psgi.streaming'}, 'psgi.streaming';
};

subtest "ALB GET Request" => sub {
    my $input = slurp_json("testdata/alb-get-request.json");
    my $output = $app->format_input($input);
    my $req = Plack::Request->new($output);
    is $req->method, 'GET', 'method';
    is slurp_fh($req->input), '', 'content';
    is $req->request_uri, '/foo/bar?query=hoge&query=fuga', 'request uri';
    is $req->path_info, '/foo/bar', 'path info';
    is $req->query_string, 'query=hoge&query=fuga', 'query string';
    is $req->header('Header-Name'), 'Value1, Value2', 'header';
    ok !$req->env->{'psgi.streaming'}, 'psgi.streaming';
};

subtest "ALB POST Request" => sub {
    my $input = slurp_json("testdata/alb-post-request.json");
    my $output = $app->format_input($input);
    my $req = Plack::Request->new($output);
    is $req->method, 'POST', 'method';
    is $req->content_type, 'application/json', 'content-type';
    is slurp_fh($req->input), '{"hello":"こんにちは世界"}', 'content';
    is $req->request_uri, '/', 'request uri';
    is $req->path_info, '/', 'path info';
    is $req->query_string, '', 'query string';
    ok !$req->env->{'psgi.streaming'}, 'psgi.streaming';
};

subtest "ALB POST Base64 Request" => sub {
    my $input = slurp_json("testdata/alb-base64-request.json");
    my $output = $app->format_input($input);
    my $req = Plack::Request->new($output);
    is $req->method, 'POST', 'method';
    is $req->content_type, 'application/octet-stream', 'content-type';
    is slurp_fh($req->input), '{"hello":"world"}', 'content';
    is $req->request_uri, '/foo/bar', 'request uri';
    is $req->path_info, '/foo/bar', 'path info';
    is $req->query_string, '', 'query string';
    ok !$req->env->{'psgi.streaming'}, 'psgi.streaming';
};

subtest "Function URLs GET Request" => sub {
    my $input = slurp_json("testdata/function-urls-get-request.json");
    my $output = $app->format_input($input);
    my $req = Plack::Request->new($output);
    is $req->method, 'GET', 'method';
    is slurp_fh($req->input), '', 'content';
    is $req->request_uri, '/foo /bar?parameter1=value1&parameter1=value2&parameter2=value', 'request uri';
    is $req->path_info, '/foo /bar', 'path info';
    is $req->query_string, 'parameter1=value1&parameter1=value2&parameter2=value', 'query string';
    is $req->header('header1'), 'value1,value2', 'header';
    ok !$req->env->{'psgi.streaming'}, 'psgi.streaming';
};

subtest "Function URLs POST Request" => sub {
    my $input = slurp_json("testdata/function-urls-post-request.json");
    my $output = $app->format_input($input);
    my $req = Plack::Request->new($output);
    is $req->method, 'POST', 'method';
    is $req->content_type, 'application/json', 'content-type';
    is slurp_fh($req->input), '{"hello":"world"}', 'content';
    is $req->request_uri, '/my/path', 'request uri';
    is $req->path_info, '/my/path', 'path info';
    is $req->query_string, '', 'query string';
    ok !$req->env->{'psgi.streaming'}, 'psgi.streaming';
};

subtest "Function URLs POST Base64 Request" => sub {
    my $input = slurp_json("testdata/function-urls-post-base64-request.json");
    my $output = $app->format_input($input);
    my $req = Plack::Request->new($output);
    is $req->method, 'POST', 'method';
    is $req->content_type, 'application/octet-stream', 'content-type';
    is slurp_fh($req->input), '{"hello":"world"}', 'content';
    is $req->request_uri, '/my/path', 'request uri';
    is $req->path_info, '/my/path', 'path info';
    is $req->query_string, '', 'query string';
    ok !$req->env->{'psgi.streaming'}, 'psgi.streaming';
};

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 1.133 second using v1.00-cache-2.02-grep-82fe00e-cpan-4673cadbf75 )