Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions src/bref/bref/Context.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

declare(strict_types=1);

namespace Bref\Context;

/**
* The execution context of a Lambda.
*
* @see https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html
*/
final class Context implements \JsonSerializable
{
/** @var string */
private $awsRequestId;

/** @var int Holds the deadline Unix timestamp in millis */
private $deadlineMs;

/** @var string */
private $invokedFunctionArn;

/** @var string */
private $traceId;

public function __construct(string $awsRequestId, int $deadlineMs, string $invokedFunctionArn, string $traceId)
{
$this->awsRequestId = $awsRequestId;
$this->deadlineMs = $deadlineMs;
$this->invokedFunctionArn = $invokedFunctionArn;
$this->traceId = $traceId;
}

/**
* Returns the identifier of the invocation request.
*/
public function getAwsRequestId(): string
{
return $this->awsRequestId;
}

/**
* Returns the number of milliseconds left before the execution times out.
*/
public function getRemainingTimeInMillis(): int
{
return $this->deadlineMs - intval(microtime(true) * 1000);
}

/**
* Returns the Amazon Resource Name (ARN) used to invoke the function.
* Indicates if the invoker specified a version number or alias.
*/
public function getInvokedFunctionArn(): string
{
return $this->invokedFunctionArn;
}

/**
* Returns content of the AWS X-Ray trace information header.
*
* @see https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-tracingheader
*/
public function getTraceId(): string
{
return $this->traceId;
}

public function jsonSerialize(): array
{
return [
'awsRequestId' => $this->awsRequestId,
'deadlineMs' => $this->deadlineMs,
'invokedFunctionArn' => $this->invokedFunctionArn,
'traceId' => $this->traceId,
];
}
}
20 changes: 20 additions & 0 deletions src/bref/bref/Handler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace Bref\Event;

use Bref\Context\Context;

/**
* Handles any kind of Lambda events.
*/
interface Handler
{
/**
* @param mixed $event the raw event data
*
* @return mixed|void
*/
public function handle($event, Context $context);
}
13 changes: 13 additions & 0 deletions src/bref/bref/autoload.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

/**
* To support use of runtime/bref without bref/bref we include two small
* classes here.
*/
if (!class_exists(\Bref\Context\Context::class)) {
require_once __DIR__.'/Context.php';
}

if (!interface_exists(\Bref\Event\Handler::class)) {
require_once __DIR__.'/Handler.php';
}
7 changes: 5 additions & 2 deletions src/bref/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,24 @@
"require": {
"ext-json": "*",
"ext-sockets": "*",
"bref/bref": "^1.3",
"clue/arguments": "^2.1",
"psr/http-server-handler": "^1.0",
"riverline/multipart-parser": "^2.0",
"symfony/runtime": "^5.3 || ^6.0"
},
"require-dev": {
"bref/bref": "^1.3",
"symfony/http-foundation": "^5.3 || ^6.0",
"symfony/http-kernel": "^5.4 || ^6.0",
"symfony/phpunit-bridge": "^5.3"
},
"autoload": {
"psr-4": {
"Runtime\\Bref\\": "src/"
}
},
"files": [
"bref/autoload.php"
]
},
"autoload-dev": {
"psr-4": {
Expand Down
26 changes: 18 additions & 8 deletions src/bref/src/Runtime.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Runtime\Bref;

use Bref\Event\Handler;
use Bref\Event\Http\HttpHandler;
use Bref\Event\Http\Psr15Handler;
use Illuminate\Contracts\Http\Kernel;
use Psr\Container\ContainerInterface;
Expand Down Expand Up @@ -33,24 +34,33 @@ public function __construct(array $options = [])

public function getRunner(?object $application): RunnerInterface
{
if ($application instanceof ContainerInterface) {
$handler = explode(':', $_SERVER['_HANDLER']);
if (!isset($handler[1]) || '' === $handler[1]) {
throw new \RuntimeException(sprintf('Application is instance of ContainerInterface but the handler does not contain a service. The handler must be on format "path/to/file.php:App\\Lambda\\MyHandler". You provided "%s".', $_SERVER['_HANDLER']));
}
$application = $application->get($handler[1]);
}

if ($application instanceof HttpKernelInterface) {
if (!class_exists(HttpHandler::class)) {
throw new \RuntimeException(sprintf('The Bref Runtime needs package bref/bref to support %s applications. Try running "composer require bref/bref".', HttpKernelInterface::class));
}
$application = new SymfonyHttpHandler($application);
}

if ($application instanceof Kernel) {
if (!class_exists(HttpHandler::class)) {
throw new \RuntimeException(sprintf('The Bref Runtime needs package bref/bref to support %s applications. Try running "composer require bref/bref".', Kernel::class));
}
$application = new LaravelHttpHandler($application);
}

if ($application instanceof RequestHandlerInterface) {
$application = new Psr15Handler($application);
}

if ($application instanceof ContainerInterface) {
$handler = explode(':', $_SERVER['_HANDLER']);
if (!isset($handler[1]) || '' === $handler[1]) {
throw new \RuntimeException(sprintf('Application is instance of ContainerInterface but the handler does not contain a service. The handler must be on format "path/to/file.php:App\\Lambda\\MyHandler". You provided "%s".', $_SERVER['_HANDLER']));
if (!class_exists(Psr15Handler::class)) {
throw new \RuntimeException(sprintf('The Bref Runtime needs package bref/bref to support %s applications. Try running "composer require bref/bref".', RequestHandlerInterface::class));
}
$application = $application->get($handler[1]);
$application = new Psr15Handler($application);
}

if ($application instanceof Handler) {
Expand Down