Skip to content

Commit

Permalink
feature/base (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
cdinopol committed Dec 26, 2023
1 parent 3f003ec commit 531a250
Show file tree
Hide file tree
Showing 19 changed files with 548 additions and 0 deletions.
Binary file added .docs/workflow.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## Purpose and approach

- Describe the problem or feature in addition to a link to the issues.
49 changes: 49 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Tests

on:
push:
branches:
- main
pull_request: ~

jobs:
build:
name: Test Suite
runs-on: ubuntu-20.04

steps:
- uses: actions/checkout@v2

- name: Setup PHP, with composer and extensions
uses: shivammathur/setup-php@v2
with:
php-version: 8.0
extensions: mbstring, xml, hash, ctype, iconv, curl

- name: Get composer cache directory
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT

- name: Cache composer dependencies
uses: actions/cache@v1
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: composer-${{ hashFiles('composer.lock') }}
restore-keys: composer-

- name: Install Composer dependencies
run: composer install -n

- uses: symfonycorp/security-checker-action@v4

- name: Validate composer.lock
run: composer validate --strict

- name: Run pint
run: vendor/bin/pint --test

- name: Run pest
run: vendor/bin/pest

- name: Run Phpstan
run: vendor/bin/phpstan --no-progress --debug --memory-limit=1G
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/.phpunit.cache
/vendor
.phpunit.result.cache
/.fleet
/.idea
/.vscode
/.phpstorm.meta.php
clover.xml
/build
composer.lock
52 changes: 52 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Laravel SNS-SQS Queue
[![Latest Stable Version](https://poser.pugx.org/acdphp/laravel-sns-sqs-queue/v)](https://packagist.org/packages/acdphp/laravel-sns-sqs-queue)

Fanout Laravel queue jobs with AWS SNS and SQS for microservices communication.

![workflow](./.docs/workflow.jpg)

## Installation
1. Install the package
```shell
composer require acdphp/laravel-sns-sqs-queue
```

2. Add new queue connection in your `config/queue.php`. *(Similar to default sqs connection but with added `endpoint` and `sns_topic_arn`)*
```php
'connections' => [
...
'sns-sqs' => [
'driver' => 'sns-sqs',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
'queue' => env('SQS_QUEUE', 'default'),
'suffix' => env('SQS_SUFFIX'),
'after_commit' => false,
'endpoint' => env('AWS_ENDPOINT'),
'sns_topic_arn' => env('SNS_TOPIC_ARN', 'arn:aws:sns:us-east-1:your-account-id:topic'),
],
]
```

3. Usage
1. Globally set your `QUEUE_CONNECTION` to `sns-sqs`
2. OR Job specific (recommended to only use this for microservice message jobs):
```php
class MicroserviceMessageJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct($yourData, $anotherData)
{
$this->onConnection('sns-sqs');
}
```
## Notes
- Fanout Jobs must exist in all applications that should handle the message with the same namespace and constructor arguments for it work properly.
- Publishing to SNS uses HTTP/S protocol which is synchronous. This means that your job dispatch will hold off the process until the SNS responds back. Consider using a better technology, for instance, using AMQP (like this [library](https://github.com/vyuldashev/laravel-queue-rabbitmq)) for better performance.
## License
The MIT License (MIT). Please see [License File](LICENSE) for more information.
71 changes: 71 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"name": "acdphp/laravel-sns-sqs-queue",
"description": "Fanout Laravel queue jobs with AWS SNS and SQS for microservices communication.",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Carlo Dinopol",
"email": "carlo.dinopol@gmail.com"
}
],
"minimum-stability": "stable",
"require": {
"php": "^8.0",
"aws/aws-sdk-php": "^3.295"
},
"require-dev": {
"laravel/pint": "^1.5",
"phpstan/phpstan": "^1.10",
"larastan/larastan": "^2.7",
"ekino/phpstan-banned-code": "^1.0",
"orchestra/testbench": "^7.37",
"pestphp/pest": "^1.23",
"pestphp/pest-plugin-laravel": "^1.4",
"mockery/mockery": "^1.6"
},
"autoload": {
"psr-4": {
"Acdphp\\SnsSqsQueue\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"Acdphp\\SnsSqsQueue\\Tests\\": "tests",
"Workbench\\App\\": "workbench/app/"
}
},
"extra": {
"laravel": {
"providers": [
"Acdphp\\SnsSqsQueue\\SnsSqsQueueServiceProvider"
]
}
},
"config": {
"allow-plugins": {
"pestphp/pest-plugin": true
}
},
"scripts": {
"post-autoload-dump": [
"@clear",
"@prepare"
],
"clear": "@php vendor/bin/testbench package:purge-skeleton --ansi",
"prepare": "@php vendor/bin/testbench package:discover --ansi",
"build": "@php vendor/bin/testbench workbench:build --ansi",
"serve": [
"Composer\\Config::disableProcessTimeout",
"@build",
"@php vendor/bin/testbench serve"
],
"lint": [
"@php vendor/bin/pint",
"@php vendor/bin/phpstan analyse"
],
"test": [
"@php vendor/bin/pest"
]
}
}
35 changes: 35 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
includes:
- ./vendor/larastan/larastan/extension.neon
- ./vendor/ekino/phpstan-banned-code/extension.neon

parameters:
checkModelProperties: true
paths:
- src
level: 6
checkMissingIterableValueType: false
reportUnmatchedIgnoredErrors: false
checkGenericClassInNonGenericObjectType: false
banned_code:
nodes:
- { type: Stmt_Echo, functions: null }
- { type: Expr_Eval, functions: null }
- { type: Expr_Exit, functions: null }
- { type: Expr_Print, functions: null }
-
type: Expr_FuncCall
functions:
- dd
- ddd
- debug_backtrace
- dump
- exec
- passthru
- phpinfo
- print_r
- proc_open
- shell_exec
- system
- var_dump
- print
use_from_tests: false
29 changes: 29 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
backupGlobals="false"
bootstrap="vendor/autoload.php"
colors="true"
executionOrder="random"
failOnWarning="true"
failOnRisky="true"
failOnEmptyTestSuite="true"
cacheDirectory=".phpunit.cache"
backupStaticProperties="false"
>
<testsuites>
<testsuite name="Feature">
<directory>tests/Feature</directory>
</testsuite>
</testsuites>
<source>
<include>
<directory suffix=".php">./src</directory>
</include>
</source>
<php>
<env name="APP_ENV" value="testing"/>
<env name="APP_KEY" value="base64:2fl+Ktvkfl+Fuz4Qp/A75G2RTiWVA/ZoKZvp6fiiM10="/>
</php>
</phpunit>
34 changes: 34 additions & 0 deletions src/Queue/Connectors/SnsSqsConnector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Acdphp\SnsSqsQueue\Queue\Connectors;

use Acdphp\SnsSqsQueue\Queue\SnsSqsQueue;
use Aws\Sns\SnsClient;
use Aws\Sqs\SqsClient;
use Illuminate\Queue\Connectors\SqsConnector;
use Illuminate\Support\Arr;

class SnsSqsConnector extends SqsConnector
{
/**
* {@inheritdoc}
*/
public function connect(array $config)
{
$config = $this->getDefaultConfiguration($config);

if ($config['key'] && $config['secret']) {
$config['credentials'] = Arr::only($config, ['key', 'secret', 'token']);
}

return new SnsSqsQueue(
new SnsClient($config),
$config['sns_topic_arn'],
new SqsClient($config),
$config['queue'],
$config['prefix'] ?? '',
$config['suffix'] ?? '',
$config['after_commit'] ?? null
);
}
}
60 changes: 60 additions & 0 deletions src/Queue/SnsSqsQueue.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

namespace Acdphp\SnsSqsQueue\Queue;

use Aws\Sns\SnsClient;
use Aws\Sqs\SqsClient;
use Illuminate\Queue\SqsQueue;

class SnsSqsQueue extends SqsQueue
{
protected SnsClient $sns;

protected string $topicArn;

public function __construct(
SnsClient $sns,
string $topicArn,
SqsClient $sqs,
$default,
$prefix = '',
$suffix = '',
$dispatchAfterCommit = false
) {
$this->sns = $sns;
$this->topicArn = $topicArn;

parent::__construct($sqs, $default, $prefix, $suffix, $dispatchAfterCommit);
}

/**
* {@inheritdoc}
*/
public function pushRaw($payload, $queue = null, array $options = [])
{
return $this->sns->publish([
'TopicArn' => $this->topicArn,
'Message' => $payload,
])->get('MessageId');
}

/**
* {@inheritdoc}
*/
public function later($delay, $job, $data = '', $queue = null)
{
return $this->enqueueUsing(
$job,
$this->createPayload($job, $queue ?: $this->default, $data),
$queue,
$delay,
function ($payload, $queue, $delay) {
return $this->sns->publish([
'TopicArn' => $this->topicArn,
'MessageBody' => $payload,
'DelaySeconds' => $this->secondsUntil($delay),
])->get('MessageId');
}
);
}
}
23 changes: 23 additions & 0 deletions src/SnsSqsQueueServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Acdphp\SnsSqsQueue;

use Acdphp\SnsSqsQueue\Queue\Connectors\SnsSqsConnector;
use Illuminate\Queue\QueueManager;
use Illuminate\Support\ServiceProvider;

class SnsSqsQueueServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->afterResolving(QueueManager::class, function (QueueManager $manager) {
$manager->addConnector('sns-sqs', function () {
return new SnsSqsConnector();
});
});
}

public function boot(): void
{
}
}
16 changes: 16 additions & 0 deletions testbench.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
providers:
- Workbench\App\Providers\WorkbenchServiceProvider
- Acdphp\SnsSqsQueue\SnsSqsQueueServiceProvider

workbench:
start: '/'
install: true
discovers:
web: false
api: false
commands: false
components: false
views: false
build: []
assets: []
sync: []
5 changes: 5 additions & 0 deletions tests/Feature/ExampleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

test('confirm environment is set to testing', function () {
expect(config('app.env'))->toBe('testing');
});
Loading

0 comments on commit 531a250

Please sign in to comment.