Skip to content

Commit 06f7f03

Browse files
committed
Move ::invokeable() to RuntimeApi
1 parent 7e4ff7a commit 06f7f03

File tree

9 files changed

+96
-84
lines changed

9 files changed

+96
-84
lines changed

src/main/php/com/amazon/aws/lambda/Handler.class.php

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,6 @@ public function __construct(Environment $environment) {
2020
/** @return com.amazon.aws.lambda.Environment */
2121
public function environment() { return $this->environment; }
2222

23-
/** @return com.amazon.aws.lambda.Lambda|com.amazon.aws.lambda.XXX|callable */
23+
/** @return com.amazon.aws.lambda.Lambda|com.amazon.aws.lambda.Streaming|callable */
2424
public abstract function target();
25-
26-
/**
27-
* Returns an invokeable
28-
*
29-
* @param com.amazon.aws.lambda.RuntimeApi
30-
* @return com.amazon.aws.lambda.Invokeable
31-
* @throws lang.IllegalArgumentException
32-
*/
33-
public final function invokeable($api) {
34-
$target= $this->target();
35-
if ($target instanceof Lambda) {
36-
return new Invokeable([$target, 'process'], $api->buffered());
37-
} else if ($target instanceof XXX) {
38-
return new Invokeable([$target, 'yyy'], $api->streaming());
39-
} else if (is_callable($target)) {
40-
$n= (new ReflectionFunction($target))->getNumberOfParameters();
41-
return new Invokeable($target, $n < 3 ? $api->buffered() : $api->streaming());
42-
} else {
43-
throw new IllegalArgumentException('Expected callable|Lambda|XXX, have '.typeof($target));
44-
}
45-
}
4625
}

src/main/php/com/amazon/aws/lambda/InvokeMode.class.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
<?php namespace com\amazon\aws\lambda;
22

3+
use lang\Value;
4+
use util\Comparison;
5+
36
/** @see https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html#runtimes-custom-response-streaming */
4-
abstract class InvokeMode {
5-
protected $api;
7+
abstract class InvokeMode implements Value {
8+
use Comparison;
9+
10+
protected $api, $name;
611

712
/** Creates a new invoke mode instance */
8-
public function __construct(RuntimeApi $api) {
13+
public function __construct(RuntimeApi $api, $name) {
914
$this->api= $api;
15+
$this->name= $name;
1016
}
1117

1218
/**
@@ -19,4 +25,8 @@ public function __construct(RuntimeApi $api) {
1925
*/
2026
public abstract function invoke($lambda, $event, $context);
2127

28+
/** @return string */
29+
public function toString() {
30+
return strtr(self::class, '\\', '.').'<'.$this->name.'>';
31+
}
2232
}

src/main/php/com/amazon/aws/lambda/RuntimeApi.class.php

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php namespace com\amazon\aws\lambda;
22

3-
use Throwable as Any;
3+
use ReflectionFunction, Throwable as Any;
44
use io\Channel;
55
use io\streams\InputStream;
66
use lang\{Throwable, IllegalStateException, IllegalArgumentException};
@@ -33,7 +33,7 @@ public function __construct($endpoint, $version= '2018-06-01') {
3333

3434
/** Returns the buffered invoke mode */
3535
public function buffered(): InvokeMode {
36-
return new class($this) extends InvokeMode {
36+
return new class($this, 'BUFFERED') extends InvokeMode {
3737
public function invoke($lambda, $event, $context) {
3838
try {
3939
$result= $lambda($event, $context);
@@ -47,7 +47,7 @@ public function invoke($lambda, $event, $context) {
4747

4848
/** Returns the streaming invoke mode */
4949
public function streaming(): InvokeMode {
50-
return new class($this) extends InvokeMode implements Stream {
50+
return new class($this, 'RESPONSE_STREAM') extends InvokeMode implements Stream {
5151
private $request= null;
5252
private $response= null;
5353
private $stream= null;
@@ -128,6 +128,26 @@ public function invoke($lambda, $event, $context) {
128128
};
129129
}
130130

131+
/**
132+
* Returns an invokeable
133+
*
134+
* @param callable|com.amazon.aws.lambda.Lambda|com.amazon.aws.lambda.Streaming $target
135+
* @return com.amazon.aws.lambda.Invokeable
136+
* @throws lang.IllegalArgumentException
137+
*/
138+
public final function invokeable($target) {
139+
if ($target instanceof Lambda) {
140+
return new Invokeable([$target, 'process'], $this->buffered());
141+
} else if ($target instanceof Streaming) {
142+
return new Invokeable([$target, 'handle'], $this->streaming());
143+
} else if (is_callable($target)) {
144+
$n= (new ReflectionFunction($target))->getNumberOfParameters();
145+
return new Invokeable($target, $n < 3 ? $this->buffered() : $this->streaming());
146+
} else {
147+
throw new IllegalArgumentException('Expected callable|Lambda|Streaming, have '.typeof($target));
148+
}
149+
}
150+
131151
/**
132152
* Marshals an exception according to the AWS specification.
133153
*

src/main/php/xp/lambda/AwsRunner.class.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public static function main($args) {
5151

5252
// Initialization
5353
try {
54-
$lambda= self::handler($variables, Console::$out)->invokeable($api);
54+
$lambda= $api->invokeable(self::handler($variables, Console::$out)->target());
5555
} catch (Throwable $t) {
5656
$api->report('init/error', $t);
5757
return 1;

src/main/php/xp/lambda/LocalRuntime.class.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public function __construct($out) { $this->out= $out; }
1010

1111
/** Returns the local buffered mode */
1212
public function buffered(): InvokeMode {
13-
return new class($this) extends InvokeMode {
13+
return new class($this, 'BUFFERED') extends InvokeMode {
1414
public function invoke($lambda, $event, $context) {
1515
$result= $lambda($event, $context);
1616
$this->api->out->writeLine($result);
@@ -20,7 +20,7 @@ public function invoke($lambda, $event, $context) {
2020

2121
/** Returns the local streaming mode */
2222
public function streaming(): InvokeMode {
23-
return new class($this) extends InvokeMode {
23+
return new class($this, 'RESPONSE_STREAM') extends InvokeMode {
2424
public function invoke($lambda, $event, $context) {
2525
$stream= new class($this->api) implements Stream {
2626
private $api;

src/main/php/xp/lambda/RunLambda.class.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@ public function run(): int {
4242
$deadlineMs= (time() + 900) * 1000;
4343
$variables= $_ENV + ['AWS_LAMBDA_FUNCTION_NAME' => $name, 'AWS_REGION' => $region, 'AWS_LOCAL' => true];
4444
$environment= new Environment(getcwd(), Console::$out, $variables);
45+
$runtime= new LocalRuntime(Console::$out);
4546

4647
try {
47-
$lambda= $this->impl->newInstance($environment)->invokeable(new LocalRuntime(Console::$out));
48+
$lambda= $runtime->invokeable($this->impl->newInstance($environment)->target());
4849
} catch (Throwable $e) {
4950
Console::$err->writeLine($e);
5051
return 127;
Lines changed: 3 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
11
<?php namespace com\amazon\aws\lambda\unittest;
22

3-
use com\amazon\aws\lambda\{Context, Environment, Handler, Lambda, RuntimeApi};
4-
use lang\IllegalArgumentException;
5-
use test\{Assert, Expect, Test};
3+
use com\amazon\aws\lambda\{Environment, Handler};
4+
use test\{Assert, Test};
65

7-
class HandlerTest extends RuntimeTest {
8-
private $headers= [
9-
'Lambda-Runtime-Aws-Request-Id' => ['3e1afeb0-cde4-1d0e-c3c0-66b15046bb88'],
10-
'Lambda-Runtime-Invoked-Function-Arn' => ['arn:aws:lambda:us-east-1:1185465369:function:test'],
11-
'Lambda-Runtime-Trace-Id' => ['Root=1-dc99d00f-c079a84d433534434534ef0d;Parent=91ed514f1e5c03b2;Sampled=1'],
12-
];
6+
class HandlerTest {
137

148
#[Test]
159
public function can_create() {
@@ -26,36 +20,4 @@ public function target() { /* TBI */ }
2620
};
2721
Assert::equals($env, $fixture->environment());
2822
}
29-
30-
#[Test]
31-
public function return_function() {
32-
$fixture= new class(new Environment('.')) extends Handler {
33-
public function target() {
34-
return function($event, $context) { return 'Test'; };
35-
}
36-
};
37-
Assert::equals('Test', ($fixture->invokeable($this->runtime)->callable)(null, new Context($this->headers, [])));
38-
}
39-
40-
#[Test]
41-
public function return_lambda() {
42-
$fixture= new class(new Environment('.')) extends Handler {
43-
public function target() {
44-
return new class() implements Lambda {
45-
public function process($event, $context) { return 'Test'; }
46-
};
47-
}
48-
};
49-
Assert::equals('Test', ($fixture->invokeable($this->runtime)->callable)(null, new Context($this->headers, [])));
50-
}
51-
52-
#[Test, Expect(IllegalArgumentException::class)]
53-
public function cannot_return_null() {
54-
$fixture= new class(new Environment('.')) extends Handler {
55-
public function target() {
56-
return null;
57-
}
58-
};
59-
$fixture->invokeable($this->runtime);
60-
}
6123
}

src/test/php/com/amazon/aws/lambda/unittest/RuntimeApiTest.class.php

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
<?php namespace com\amazon\aws\lambda\unittest;
22

3-
use com\amazon\aws\lambda\RuntimeApi;
4-
use test\{Assert, Test};
3+
use com\amazon\aws\lambda\{Context, RuntimeApi, Lambda, Streaming};
4+
use lang\IllegalArgumentException;
5+
use test\{Assert, Expect, Test};
56

67
class RuntimeApiTest {
8+
use TestContext;
79

810
#[Test]
911
public function can_create() {
@@ -31,4 +33,26 @@ public function endpoint_timeout_is_15_minutes() {
3133
$runtime= new RuntimeApi('localhost:9000');
3234
Assert::equals(15 * 60, $runtime->conn->getTimeout());
3335
}
36+
37+
#[Test]
38+
public function return_function() {
39+
$runtime= new RuntimeApi('localhost:9000');
40+
$invokeable= $runtime->invokeable(function($event, $context) { return 'Test'; });
41+
Assert::equals('Test', ($invokeable->callable)(null, new Context($this->headers, [])));
42+
}
43+
44+
#[Test]
45+
public function return_lambda() {
46+
$runtime= new RuntimeApi('localhost:9000');
47+
$invokeable= $runtime->invokeable(new class() implements Lambda {
48+
public function process($event, $context) { return 'Test'; }
49+
});
50+
Assert::equals('Test', ($invokeable->callable)(null, new Context($this->headers, [])));
51+
}
52+
53+
#[Test, Expect(IllegalArgumentException::class)]
54+
public function cannot_return_null() {
55+
$runtime= new RuntimeApi('localhost:9000');
56+
$runtime->invokeable(null);
57+
}
3458
}

src/test/php/com/amazon/aws/lambda/unittest/StreamingTest.class.php

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<?php namespace com\amazon\aws\lambda\unittest;
22

3-
use com\amazon\aws\lambda\Context;
3+
use com\amazon\aws\lambda\{Context, Streaming};
44
use io\streams\MemoryInputStream;
55
use lang\IllegalStateException;
6-
use test\{Assert, Expect, Test};
6+
use test\{Assert, Expect, Test, Values};
77

88
class StreamingTest extends RuntimeTest {
99
use TestContext;
@@ -22,6 +22,26 @@ private function invoke($lambda) {
2222
;
2323
}
2424

25+
/**
26+
* Lambda implementations for `write_event_stream` test.
27+
*
28+
* @return iterable
29+
*/
30+
private function implementations() {
31+
yield [$this->runtime->invokeable(function($event, $stream, $context) {
32+
$stream->use('text/event-stream');
33+
$stream->write("data: One\n\n");
34+
$stream->write("data: Two\n\n");
35+
})];
36+
yield [$this->runtime->invokeable(new class() implements Streaming {
37+
public function handle($event, $stream, $context) {
38+
$stream->use('text/event-stream');
39+
$stream->write("data: One\n\n");
40+
$stream->write("data: Two\n\n");
41+
}
42+
})];
43+
}
44+
2545
#[Test]
2646
public function can_create() {
2747
$this->runtime->streaming();
@@ -62,13 +82,9 @@ public function reports_exceptions_before_streaming_via_error() {
6282
);
6383
}
6484

65-
#[Test]
66-
public function write_event_stream() {
67-
$response= $this->invoke(function($event, $stream, $context) {
68-
$stream->use('text/event-stream');
69-
$stream->write("data: One\n\n");
70-
$stream->write("data: Two\n\n");
71-
});
85+
#[Test, Values(from: 'implementations')]
86+
public function write_event_stream($lambda) {
87+
$response= $this->invoke($lambda->callable);
7288

7389
Assert::equals(
7490
"POST /2018-06-01/runtime/invocation/3e1afeb0-cde4-1d0e-c3c0-66b15046bb88/response HTTP/1.1\r\n".

0 commit comments

Comments
 (0)