Skip to content

Commit

Permalink
Merge pull request #9 from brasizza/main
Browse files Browse the repository at this point in the history
Sistema de broadcast + Socket server
  • Loading branch information
rodrigorahman committed Mar 27, 2023
2 parents 8ffaa8f + ad4e83a commit dda0501
Show file tree
Hide file tree
Showing 27 changed files with 622 additions and 87 deletions.
22 changes: 21 additions & 1 deletion README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,4 +233,24 @@ You will get the response with a new token and a new refresh_token:
```
Now just send the request again, passing the new token.

## ATTENTION: Remember that you have now received a new access token and the old one MUST be discarded!
## ATTENTION: Remember that you have now received a new access token and the old one MUST be discarded!

# Broadcast event system
A broadcast system was developed to send data to other applications with a simple initial configuration in your config.yaml
Initially, the system is compatible with sending to ***socket and slack***

```yaml

enableSocket: true
#Indicates whether you want to start a socket server along with the rest server (true/false)
socketPort: 8081
#Indicates the default socket access port: 8081
broadcastProvider: socket
#Indicates which type of broadcast it wants to send by default: eg socket, slack or just socket or just slack
slack:
slackUrl:
#Indicates the url of the slack webhook
slackChannel:
#Indicates the slack channel to send always starting with #
```
To send the events, the providers need to be configured, and in the case of the socket, only if there are connected clients are they sent, thus guaranteeing that no unnecessary service is triggered.
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -275,4 +275,28 @@ Para fazer a busca por um campo com o ID do usuário logado, você precisa envia

`http://localhost:8080/products?user_id=#userAuthRef`

O JRS vai substituir a tag #userAuthRef pelo o id do usuário logado e realizar o filtro no campo user_id
O JRS vai substituir a tag #userAuthRef pelo o id do usuário logado e realizar o filtro no campo user_id



# Sistema de broadcast event
Foi desenvolvido um sistema de broadcast para enviar dados para outras aplicações com uma configuração inicial simples no seu config.yaml
Inicialmente o sistema está compatível com o envio para ***socket e slack***

```yaml

enableSocket: true
#Indica se você quer que inicie um servidor de socket junto com o servidor rest (true/false)
socketPort: 8081
#Indica a porta de acesso do socket padrão: 8081
broadcastProvider: socket
#Indica pra qual tipo de broadcast ele quer enviar por padrão : ex socket,slack ou só socket ou só slack
slack:
slackUrl:
#Indica a url do webhook do slack
slackChannel:
#Indica o canal do slack para ser enviado sempre começando com #
```

## Para emitir os eventos, os providers precisam estar configurados , e no caso do socket somente se existir clientes conectados o envio é efetuado, assim garantindo que não seja disparado nenhum serviço sem necessidade

26 changes: 25 additions & 1 deletion README.pt-br.md
Original file line number Diff line number Diff line change
Expand Up @@ -274,4 +274,28 @@ Para fazer a busca por um campo com o ID do usuário logado, você precisa envia

`http://localhost:8080/products?user_id=#userAuthRef`

O JRS vai substituir a tag #userAuthRef pelo o id do usuário logado e realizar o filtro no campo user_id
O JRS vai substituir a tag #userAuthRef pelo o id do usuário logado e realizar o filtro no campo user_id



# Sistema de broadcast event
Foi desenvolvido um sistema de broadcast para enviar dados para outras aplicações com uma configuração inicial simples no seu config.yaml
Inicialmente o sistema está compatível com o envio para ***socket e slack***

```yaml

enableSocket: true
#Indica se você quer que inicie um servidor de socket junto com o servidor rest (true/false)
socketPort: 8081
#Indica a porta de acesso do socket padrão: 8081
broadcastProvider: socket
#Indica pra qual tipo de broadcast ele quer enviar por padrão : ex socket,slack ou só socket ou só slack
slack:
slackUrl:
#Indica a url do webhook do slack
slackChannel:
#Indica o canal do slack para ser enviado sempre começando com #
```

Para emitir os eventos, os providers precisam estar configurados , e no caso do socket somente se existir clientes conectados o envio é efetuado, assim garantindo que não seja disparado nenhum serviço sem necessidade

2 changes: 2 additions & 0 deletions backend/config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
name: Json Rest Server
port: 8080
host: 0.0.0.0
enableSocket: false
socketPort: 8081
database: database.json

# storage:
Expand Down
25 changes: 15 additions & 10 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@ name: Json Rest Server
port: 8080
host: 0.0.0.0
database: database.json

enableSocket: false
socketPort: 8081
broadcastProvider: #socket,slack or only socket or only slack
slack:
slackUrl: '' #your webhook url from slack
slackChannel: '' #your channel starting with #
# storage:
# folder: storage/
# name: "file"

auth:
jwtSecret: cwsMXDtuP447WZQ63nM4dWZ3RppyMl
jwtExpire: 3600
unauthorizedStatusCode: 401
urlSkip:
- /users:
method: post
- /products/{*}:
method: get
# auth:
# jwtSecret: cwsMXDtuP447WZQ63nM4dWZ3RppyMl
# jwtExpire: 3600
# unauthorizedStatusCode: 401
# urlSkip:
# - /users:
# method: post
# - /products/{*}:
# method: get
60 changes: 59 additions & 1 deletion database.json
Original file line number Diff line number Diff line change
@@ -1 +1,59 @@
{"users":[{"id":1,"name":"Rodrigo Rahman","email":"rodrigorahman@academiadoflutter.com.br","password":"123"},{"id":2,"name":"Guilherme","email":"guilherme@gmail.com","password":"1234"},{"id":3,"name":"Luana Rahman Alterado Patch","email":"luana@academiadoflutter.com.br","password":"123"}],"products":[{"id":0,"title":"Academia do flutter"},{"id":1,"title":"Jornada Dart"},{"id":2,"title":"Jornada GetX"},{"id":3,"title":"Academia do flutter alterado"},{"id":4,"title":"Academia do flutter 2"},{"id":5,"title":"Academia do flutter","user_id":"#userAuthRef"},{"id":6,"title":"Academia do flutter","user_id":"1"},{"id":7,"title":"Academia do flutter","user_id":"1"}],"students":[{"id":1,"name":"Academia do flutter 2"}]}
{
"users": [
{
"id": 0,
"name": "Rodrigo Rahman",
"email": "rodrigorahman@academiadoflutter.com.br",
"password": "123"
},
{
"id": 1,
"name": "Guilherme",
"email": "Guilherme@gmail.com",
"password": "1234"
}
],
"products": [
{
"id": 0,
"title": "Academia do flutter"
},
{
"id": 1,
"title": "Jornada Dart"
},
{
"id": 2,
"title": "Jornada GetX"
},
{
"id": 3,
"title": "Academia do flutter alterado"
},
{
"id": 4,
"title": "Academia do flutter 2"
},
{
"id": 5,
"title": "Academia do flutter",
"user_id": "#userAuthRef"
},
{
"id": 6,
"title": "Academia do flutter",
"user_id": "1"
},
{
"id": 7,
"title": "Academia do flutter",
"user_id": "1"
}
],
"students": [
{
"id": 1,
"name": "Academia do flutter 2"
}
]
}
5 changes: 5 additions & 0 deletions lib/src/core/broadcast/broadcast_base.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import '../../models/broadcast_model.dart';

abstract class BroadcastBase {
Future<bool> execute({required BroadcastModel broadcast});
}
50 changes: 50 additions & 0 deletions lib/src/core/broadcast/broadcast_controller.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import 'dart:developer';

import 'package:event_bus/event_bus.dart';
import 'package:json_rest_server/src/core/broadcast/broadcast_base.dart';
import 'package:json_rest_server/src/core/broadcast/broadcast_factory.dart';
import 'package:json_rest_server/src/core/enum/broadcast_type.dart';
import 'package:json_rest_server/src/models/broadcast_model.dart';

class BroadCastController {
final EventBus _eventBus = EventBus();
List<String> _customProviders = [];

BroadCastController() {
_eventBus.on<BroadcastModel>().listen((BroadcastModel broadCast) {
BroadcastBase? broadcastBase =
BroadcastFactory.create(broadcast: broadCast);

broadcastBase?.execute(broadcast: broadCast);
});
}

BroadCastController single(String provider) {
_customProviders.clear();
_customProviders.add(provider);
return this;
}

BroadCastController multi(List<String> provider) {
_customProviders.clear();
_customProviders = provider.toSet().toList();
return this;
}

void execute({List<String>? providers, required BroadcastModel broadcast}) {
if (_customProviders.isNotEmpty) {
providers = _customProviders;
}
if (providers != null) {
for (var provider in providers) {
if (BroadCastType.fromString(provider) == null) {
log('BroadCast provider: $provider not found');
} else {
_eventBus.fire(broadcast.copyWith(
broadCastType: BroadCastType.fromString(provider)));
}
}
}
_customProviders.clear();
}
}
26 changes: 26 additions & 0 deletions lib/src/core/broadcast/broadcast_factory.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'package:get_it/get_it.dart';
import 'package:json_rest_server/src/core/broadcast/broadcast_base.dart';
import 'package:json_rest_server/src/core/broadcast/slack/slack_broadcast_impl.dart';
import 'package:json_rest_server/src/core/broadcast/socket/socket_broadcast_impl.dart';
import 'package:json_rest_server/src/core/enum/broadcast_type.dart';
import 'package:json_rest_server/src/models/broadcast_model.dart';
import 'package:json_rest_server/src/models/config_model.dart';
import 'package:json_rest_server/src/server/socket/socket_handler.dart';

class BroadcastFactory {
static BroadcastBase? create({required BroadcastModel broadcast}) {
switch (broadcast.broadCastType) {
case BroadCastType.socket:
return SocketBroadCastImpl(
socket: GetIt.I.isRegistered<SocketHandler>()
? GetIt.I.get<SocketHandler>()
: null,
);
case BroadCastType.slack:
return SlackBroadCastImpl(config: GetIt.I.get<ConfigModel>());

default:
return null;
}
}
}
36 changes: 36 additions & 0 deletions lib/src/core/broadcast/slack/slack_broadcast_impl.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:convert';
import 'dart:developer';

import 'package:http/http.dart' as http;
import 'package:json_rest_server/src/models/broadcast_model.dart';
import 'package:json_rest_server/src/models/config_model.dart';

import '../broadcast_base.dart';

class SlackBroadCastImpl implements BroadcastBase {
final ConfigModel _config;
SlackBroadCastImpl({
required ConfigModel config,
}) : _config = config;
@override
Future<bool> execute({required BroadcastModel broadcast}) async {
if (_config.slack != null) {
if (_config.slack!.url.isEmpty) {
return false;
}
Map payload = {};
if (_config.slack?.channel != null) {
payload['channel'] = _config.slack?.channel ?? '';
}
payload['text'] = broadcast.toJson();
final response = await http.post(Uri.parse(_config.slack!.url),
body: json.encode(payload));
if (response.statusCode == 200) {
log('Send to Slack', time: DateTime.now());
}
return true;
}
return false;
}
}
26 changes: 26 additions & 0 deletions lib/src/core/broadcast/socket/socket_broadcast_impl.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:developer';

import 'package:json_rest_server/src/models/broadcast_model.dart';
import 'package:json_rest_server/src/server/socket/socket_handler.dart';

import '../broadcast_base.dart';

class SocketBroadCastImpl implements BroadcastBase {
final SocketHandler? _socket;
SocketBroadCastImpl({
SocketHandler? socket,
}) : _socket = socket;
@override
Future<bool> execute({required BroadcastModel broadcast}) async {
if (_socket == null) {
return false;
}
final sent = _socket!.sendMessage(broadcast.toJson());
if (sent) {
log('Send to socket', time: DateTime.now());
}

return true;
}
}
17 changes: 17 additions & 0 deletions lib/src/core/enum/broadcast_type.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
enum BroadCastType {
socket,
slack;

static BroadCastType? fromString(String type) {
switch (type.toUpperCase()) {
case 'SOCKET':
return BroadCastType.socket;

case 'SLACK':
return BroadCastType.slack;

default:
return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import 'dart:core';

class JsonHelper {
static JsonHelper? _instance;
class CorsHelper {
static CorsHelper? _instance;

final List<String> _origins = [];
final List<String> _methods = [];
final List<String> _headers = [];
// Avoid self instance

JsonHelper load(
CorsHelper load(
{List<String>? allowOrigins,
List<String>? allowMethods,
List<String>? allowHeaders}) {
_instance ??= JsonHelper();
_instance ??= CorsHelper();
_instance?._origins.addAll(allowOrigins ?? []);
_instance?._methods.addAll(allowMethods ?? []);
_instance?._headers.addAll(allowHeaders ?? []);
Expand Down
Loading

0 comments on commit dda0501

Please sign in to comment.