Skip to content

Commit a323424

Browse files
authored
Merge pull request #3 from renoki-co/feature/eventbridge
[feature] EventBridge
2 parents afd7b44 + 9108394 commit a323424

File tree

6 files changed

+208
-0
lines changed

6 files changed

+208
-0
lines changed

README.md

+48
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,54 @@ class MyCloudwatchController extends CloudwatchWebhook
197197
}
198198
```
199199

200+
## EventBridge Events
201+
202+
EventBridge is supported for all `aws.*` sources coming within the message payload. You can implement your own methods just by creating a method similar to `on[source_name]Event`.
203+
204+
For example, you might have this EC2 Spot Termination notice:
205+
206+
```json
207+
{
208+
"id":"7bf73129-1428-4cd3-a780-95db273d1602",
209+
"detail-type":"EC2 Instance State-change Notification",
210+
"source":"aws.ec2",
211+
"account":"123456789012",
212+
"time":"2015-11-11T21:29:54Z",
213+
"region":"us-east-1",
214+
"resources":[
215+
"arn:aws:ec2:us-east-1:123456789012:instance/i-abcd1111"
216+
],
217+
"detail":{
218+
"instance-id":"i-abcd1111",
219+
"state":"pending"
220+
}
221+
}
222+
```
223+
224+
Because the source is called `aws.ec2`, you should create a `onEc2Event` method within your extended class:
225+
226+
```php
227+
use RenokiCo\AwsWebhooks\Http\Controllers\EventbridgeWebhook;
228+
229+
class MyEventbridgeController extends EventbridgeWebhook
230+
{
231+
/**
232+
* Handle the EC2 events.
233+
*
234+
* @param array $message
235+
* @param array $originalMessage
236+
* @param \Illuminate\Http\Request $request
237+
* @return void
238+
*/
239+
protected function onEc2Event(array $message, array $originalMessage, Request $request)
240+
{
241+
foreach ($message['resources'] as $instanceArn) {
242+
//
243+
}
244+
}
245+
}
246+
```
247+
200248
## 🐛 Testing
201249

202250
``` bash
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace RenokiCo\AwsWebhooks\Http\Controllers;
4+
5+
use Illuminate\Http\Request;
6+
use Illuminate\Support\Str;
7+
use Rennokki\LaravelSnsEvents\Http\Controllers\SnsController;
8+
9+
class EventbridgeWebhook extends SnsController
10+
{
11+
/**
12+
* Handle logic at the controller level on notification.
13+
*
14+
* @param array $snsMessage
15+
* @param \Illuminate\Http\Request $request
16+
* @return void
17+
*/
18+
protected function onNotification(array $snsMessage, Request $request): void
19+
{
20+
$decodedMessage = json_decode($snsMessage['Message'], true);
21+
22+
$service = Str::ucfirst(Str::after($decodedMessage['source'], 'aws.'));
23+
24+
$methodToCall = "on{$service}Event";
25+
26+
if (method_exists($this, $methodToCall)) {
27+
call_user_func(
28+
[$this, $methodToCall],
29+
$decodedMessage, $snsMessage, $request
30+
);
31+
}
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace RenokiCo\AwsWebhooks\Test\Controllers;
4+
5+
use Aws\Sns\MessageValidator;
6+
use Illuminate\Http\Request;
7+
use RenokiCo\AwsWebhooks\Http\Controllers\EventbridgeWebhook;
8+
9+
class EventbridgeController extends EventbridgeWebhook
10+
{
11+
/**
12+
* Get the message validator instance.
13+
*
14+
* @param \Illuminate\Http\Request $request
15+
* @return \Aws\Sns\MessageValidator
16+
*/
17+
protected function getMessageValidator(Request $request)
18+
{
19+
return new MessageValidator(function ($url) use ($request) {
20+
return $request->certificate ?: $url;
21+
});
22+
}
23+
24+
/**
25+
* Handle the event coming from Autoscaling.
26+
*
27+
* @param array $message
28+
* @param array $originalMessage
29+
* @param \Illuminate\Http\Request $request
30+
* @return void
31+
*/
32+
protected function onGameliftEvent(array $message, array $originalMessage, Request $request)
33+
{
34+
//
35+
}
36+
}

tests/EventbridgeTest.php

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace RenokiCo\AwsWebhooks\Test;
4+
5+
class EventbridgeTest extends TestCase
6+
{
7+
public function test_call_with_existing_event()
8+
{
9+
$payload = $this->getGameliftMessage();
10+
11+
$this->withHeaders($this->getHeadersForMessage($payload))
12+
->json('GET', route('eventbridge', ['certificate' => static::$certificate]), $payload)
13+
->assertSee('OK');
14+
}
15+
16+
public function test_call_with_inexisting_event()
17+
{
18+
$payload = $this->getEc2Message();
19+
20+
$this->withHeaders($this->getHeadersForMessage($payload))
21+
->json('GET', route('eventbridge', ['certificate' => static::$certificate]), $payload)
22+
->assertSee('OK');
23+
}
24+
}

tests/TestCase.php

+64
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,68 @@ public function getCloudwatchMessage(string $currentState = 'ALARM', string $pre
9595
],
9696
]);
9797
}
98+
99+
/**
100+
* Get an example EC2 notification payload.
101+
*
102+
* @return array
103+
*/
104+
public function getEc2Message(): array
105+
{
106+
return $this->getNotificationPayload([
107+
'version' => 0,
108+
'id' => '72d6566c-e6bd-117d-5bbc-2779c679abd5',
109+
'detail-type' => 'EC2 Spot Instance Interruption Warning',
110+
'source' => 'aws.ec2',
111+
'account' => '12345678910',
112+
'time' => '2020-03-06T08:25:40Z',
113+
'region' => 'eu-west-1',
114+
'resources' => [
115+
'arn:aws:ec2:eu-west-1a:instance/i-0cefe48f36d7c281a',
116+
],
117+
'detail' => [
118+
'instance-id' => 'i-0cefe48f36d7c281a',
119+
'instance-action' => 'terminate',
120+
],
121+
]);
122+
}
123+
124+
/**
125+
* Get an example Gamelift notification payload.
126+
*
127+
* @return array
128+
*/
129+
public function getGameliftMessage(): array
130+
{
131+
return $this->getNotificationPayload([
132+
'version' => 0,
133+
'id' => '72d6566c-e6bd-117d-5bbc-2779c679abd5',
134+
'detail-type' => 'GameLift Matchmaking Event',
135+
'source' => 'aws.gamelift',
136+
'account' => '12345678910',
137+
'time' => '2020-03-06T08:25:40Z',
138+
'region' => 'eu-west-1',
139+
'resources' => [
140+
'arn:aws:gamelift:us-west-2:123456789012:matchmakingconfiguration/SampleConfiguration',
141+
],
142+
'detail' => [
143+
'tickets' => [
144+
[
145+
'ticketId' => 'ticket-1',
146+
'startTime' => '2017-08-08T21:15:35.676Z',
147+
'players' => [
148+
['playerId' => 'player-1'],
149+
],
150+
],
151+
],
152+
'estimatedWaitMillis' => 'NOT_AVAILABLE',
153+
'type' => 'MatchmakingSearching',
154+
'gameSessionInfo' => [
155+
'players' => [
156+
['playerId' => 'player-1'],
157+
],
158+
],
159+
],
160+
]);
161+
}
98162
}

tests/routes/web.php

+3
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@
55

66
Route::any('/cloudwatch', 'RenokiCo\AwsWebhooks\Test\Controllers\CloudwatchController@handle')
77
->name('cloudwatch');
8+
9+
Route::any('/eventbridge', 'RenokiCo\AwsWebhooks\Test\Controllers\EventbridgeController@handle')
10+
->name('eventbridge');

0 commit comments

Comments
 (0)