Skip to content
Closed
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
3 changes: 0 additions & 3 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,3 @@ trim_trailing_whitespace = false

[*.{yml,yaml}]
indent_size = 2

[docker-compose.yml]
indent_size = 4
17 changes: 8 additions & 9 deletions .env.testing
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
APP_NAME=Laravel
APP_ENV=local
APP_ENV=testing
APP_KEY=base64:Bq7kBLzjHsoonNahT0xa08HqG4jQD62dw1LRXMCNdCE=
APP_DEBUG=true
APP_DEBUG=false
APP_TIMEZONE=UTC
APP_URL=http://localhost

Expand All @@ -20,11 +20,11 @@ LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug

DB_CONNECTION=pgsql
DB_HOST=172.19.18.161
DB_PORT=5433
DB_DATABASE=api_email
DB_USERNAME=postgres
DB_PASSWORD=12345678
DB_HOST=db-email
DB_PORT=5432
DB_DATABASE=api_email_test
DB_USERNAME=api_email
DB_PASSWORD=pass

SESSION_DRIVER=database
SESSION_LIFETIME=120
Expand Down Expand Up @@ -55,7 +55,6 @@ MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"


AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
Expand Down Expand Up @@ -83,7 +82,7 @@ NGINX_PHP_UPSTREAM_CONTAINER=php-fpm
NGINX_PHP_UPSTREAM_PORT=9000
NGINX_SSL_PATH=./docker/nginx/ssl/
### PARA AS FILAS
MAPA_URL=http://localhost:8088/
MAPA_URL=http://172.19.18.213:8088/

#### RABBITMW ####
RABBITMQ_DEFAULT_HOST=rabbitmq
Expand Down
49 changes: 49 additions & 0 deletions .github/workflows/cicd.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: CICD

on:
pull_request:
branches:
- main
types:
- closed

workflow_dispatch:

jobs:
BUILD:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:

- uses: actions/checkout@v4.1.1

- name: Read version file
id: get_version
run: |
VERSION=$(cat version.txt)
echo "app_version=$VERSION" >> $GITHUB_ENV

- name: Docker Login
uses: docker/login-action@v3.0.0
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}

- name: Criação da Imagem docker
uses: docker/build-push-action@v5.0.0
with:
context: ./
file: ./Dockerfile
push: true
tags: |
secultceara/api-email:latest
secultceara/api-email:${{ env.app_version }}

#DEPLOY:
# needs: BUILD
# runs-on: mapahomolog
# steps:
# - name: Pull da imagem do dockerhub
# run: sudo docker pull secultceara/mapasculturais:homolog
# - name: Restart do docker-compose para atualizar o container com a nova imagem
# run: cd /opt/docker/mapa5 && sudo docker-compose down && sudo docker-compose up -d
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ docker-data
data
storage
/docker/logs/
docker/logs/nginx/error.log

xdebug.log
tests/coverage-html
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,14 @@ Instruções [aqui](https://github.com/secultce/api-email/blob/develop/docs/TASK
### JWT Auth

É usado o pacote jwt-auth (https://jwt-auth.readthedocs.io/en/develop/) para criar tokens de acesso que são enviados nas requisições, para garantir que pessoas não autorizadas acessem os dados retornados nos endpoints usados na api.

### Workers

Para cada novo componente que precise trabalhar com as tarefas de filas por exemplo, deve ser adicionar o comando no arquivo *supervisord.conf* , que se encontra no caminho ***docker/php-fpm/*** e escrever algo como:

[program:name_command]
command=php artisan command:command
autostart=true
autorestart=true
stderr_logfile=/dev/stderr
stdout_logfile=/dev/stdout
48 changes: 31 additions & 17 deletions app/Console/Commands/ConsumePublishedRecourseEmails.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
namespace App\Console\Commands;

use App\Mail\PublishedRecourse;
use Exception;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Mail;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

class ConsumePublishedRecourseEmails extends Command
{
Expand All @@ -25,28 +27,24 @@ class ConsumePublishedRecourseEmails extends Command

/**
* Execute the console command.
*
* @throws Exception
*/
public function handle()
public function handle(): void
{
// Conectar ao RabbitMQ
$connection = new AMQPStreamConnection(env('RABBITMQ_DEFAULT_HOST'), env('RABBITMQ_DEFAULT_PORT'), env('RABBITMQ_DEFAULT_USER'), env('RABBITMQ_DEFAULT_PASS'));
$queue = config('app.rabbitmq.queues.published_recourses_queue');
$connection = new AMQPStreamConnection(
config('app.rabbitmq.host'),
config('app.rabbitmq.port'),
config('app.rabbitmq.user'),
config('app.rabbitmq.pass'),
);
$channel = $connection->channel();
$channel->queue_declare($queue, false, true, false, false);

$channel->queue_declare('published_recourses_queue', false, true, false, false);
$this->info('🎯 Aguardando e-mails para envio...');

$callback = function ($msg) {
$data = json_decode($msg->body, true);

if ($this->sendEmail($data)) {
$msg->ack(); // Confirma o processamento
$this->info("📧 E-mail enviado para: {$data['email']}");
} else {
$this->error("❌ Falha ao enviar e-mail para: {$data['email']}");
}
};

$channel->basic_consume('published_recourses_queue', '', false, false, false, false, $callback);
$channel->basic_consume(queue: $queue, callback: $this->processMessage(...));

while ($channel->is_consuming()) {
$channel->wait();
Expand All @@ -62,8 +60,24 @@ private function sendEmail($data): bool
Mail::to($data['email'])->send(new PublishedRecourse($data));

return true;
} catch (\Exception $e) {
} catch (Exception $e) {
logger($e->getMessage());

return false;
}
}

protected function processMessage(AMQPMessage $msg): void
{
$data = json_decode($msg->body, true);

if ($this->sendEmail($data)) {
$msg->ack(); // Confirma o processamento
$this->info("📧 E-mail enviado para: {$data['email']}");

return;
}

$this->error("❌ Falha ao enviar e-mail para: {$data['email']}");
}
}
63 changes: 35 additions & 28 deletions app/Console/Commands/ConsumerCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
namespace App\Console\Commands;

use App\Mail\AnswerNotification;
use Illuminate\Support\Facades\Mail;
use App\Mail\EmailRegistrationOpp;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Mail;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

class ConsumerCommand extends Command
{
Expand All @@ -22,51 +23,57 @@ class ConsumerCommand extends Command
*
* @var string
*/
protected $description = 'Cosumidor das filas do Rabbitmq para as diligências';
protected $description = 'Consumidor das filas do Rabbitmq para as diligências';

/**
* Execute the console command.
*
* @throws \Exception
*/
public function handle()
public function handle(): int
{
$queue = env('RABBITMQ_QUEUE_PC');
$queue = config('app.rabbitmq.queues.accountability');
$connection = new AMQPStreamConnection(
env('RABBITMQ_DEFAULT_HOST'),
env('RABBITMQ_DEFAULT_PORT'),
env('RABBITMQ_DEFAULT_USER'),
env('RABBITMQ_DEFAULT_PASS'),
'/'
config('app.rabbitmq.host'),
config('app.rabbitmq.port'),
config('app.rabbitmq.user'),
config('app.rabbitmq.pass'),
'/',
);
$channel = $connection->channel();
$channel->queue_declare($queue, false, true, false, false);

$callback = function ($msg) {
$data = json_decode($msg->body);
if( $msg->getRoutingKey() == env('RABBITMQ_QUEUE_PC_ROUTE_KEY_PROP') )
{
Mail::to($data->email)->send(new EmailRegistrationOpp(
$data->name,
$data->number,
$data->days
));
}
if($msg->getRoutingKey() == env('RABBITMQ_QUEUE_PC_ROUTE_KEY_ADM'))
{
Mail::to($data->comission)->cc($data->owner)->send(new AnswerNotification(
$data->registration,
));
};
$msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);
};
$channel->basic_qos(null, 1, null);
$channel->basic_consume($queue, '', false, false, false, false, $callback);
$channel->basic_consume(queue: $queue, callback: $this->processMessage(...));

while ($channel->is_consuming()) {
$this->info('🎯 Aguardando e-mails para envio...');
$channel->wait();
}

$channel->close();

return Command::SUCCESS;
}

protected function processMessage(AMQPMessage $msg): void
{
$data = json_decode($msg->body);

if ($msg->getRoutingKey() == config('app.rabbitmq.route_key_prop')) {
Mail::to($data->email)->send(new EmailRegistrationOpp(
$data->name,
$data->number,
$data->days
));
}

if ($msg->getRoutingKey() == config('app.rabbitmq.route_key_adm')) {
Mail::to($data->comission)->cc($data->owner)->send(new AnswerNotification(
$data->registration
));
}

$msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);
}
}
58 changes: 1 addition & 57 deletions app/Http/Controllers/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,78 +9,22 @@

class UserController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
//
}

/**
* Show the form for creating a new resource.
*/
public function create()
{
//
}

/**
* Handle an incoming registration request.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function store(Request $request): JsonResponse
{

// $request->validate([
// 'name' => ['required', 'string', 'max:255'],
// 'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:'.User::class],
// 'password' => ['required', 'confirmed', Rules\Password::defaults()],
// ]);

$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
// event(new Registered($user));

$token = $user->createToken('here-token-name');

return response()->json( ['token' => $token->plainTextToken]);
}

/**
* Display the specified resource.
*/
public function show(string $id)
{
//
}

/**
* Show the form for editing the specified resource.
*/
public function edit(string $id)
{
//
}

/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
//
}

/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
//
return response()->json(['token' => $token->plainTextToken]);
}

public function draft(Request $request)
Expand Down
Loading