Généralités

 

Spécification Gadz.org

Versionnement

Versionnement sémantique :

Spécifications actuelles

Version 2.1

Structure d'un message

Un message RabbitMQ est composé de 2 parties : les propriétés et le payload.

Propriétés

Les propriétés permettent de caractériser un message et son traitement. Certaines sont obligatoires pour le fonctionnement de rabbitMQ alors que d'autres sont laissé à la libre appreciation des applications clientes. Voici les propriétés par défaut de RabbitMQ :

 

 

content-typeMIME content type.
content-encodingMIME content encoding.
delivery-modeNon-persistent (1) or persistent (2).
priorityMessage priority, 0 to 9.
correlation-idApplication correlation identifier.
reply-toAddress to reply to.
expirationMessage expiration specification.
message-idApplication message identifier.
timestampMessage timestamp.
typeMessage type name.
user-idCreating user id.
app-idCreating application id.
reservedReserved, must be empty.
headersMessage header field table.

 

Ci dessous sont définit les valeurs de ces paramètres et la signification donnée dans le SOA Gadz.org

content-type

Le Content-Type du payload. Gadz.org ne supporte pour l'instant que le type "application/json". Si la valeur est absente, le message est considéré comme du "application/json"

content-encoding

L'encodage du message. Gadz.org ne supporte pour l'instant que la valeur "deflate" mais la valeur "gzip" pourra être supporté pour réduire la charge sur le serveur RabbitMQ. En cas d'absence du paramètre, la valeur est par défaut à "deflate"

delivery-mode

Paramètre obligatoire de RabbitMQ, par défaut à 1 (Non-persistent). Ceci permet de savoir si le message doit être persisté sur le disque dur ou  non. Un message non persisté sera perdu en cas de coupure du serveur RabbitMQ

priority

Non utilisé par Gadz.org. Utilie uniquement pour les queues priorisées (doc)

message-id

Null par defaut. Gadz.org utilise un UUID (v1 ou v4, ceci n'a pas d'importance). C'est à l'applicaiton emmetrice de créer cet ID

correlation-id

Utilisé pour répondre à un message. Il référence l'ID du message de la requete dont son message est la réponse.

reply-to

Gadz.org utilise cette propriété pour définir l'exchange auquel la réponse doit être envoyé.

expiration

La durée de vie en milliseconde du message. Ceci permet d'éviter que certain message ne soit executer de manière trop différés ci ceux-ci peuvent provoquer des effet de bords. C'est à l’application envoyant le message de le définir.
Exemple : Limiter la durée de vie d'un message demande l'envoi d'un email de récupération de mot de passe à 3h . Si le message n'est pas traité dans les 3h, il s'auto détruit pour éviter d'envoyer un message hors contexte à l'utilisateur.
Avant d'utiliser se paramètre, veuillez lire la documentation rabbitMQ.

timestamp

Timestamp de création du message. C'est à l'application émettrice de l'ajouter (RabbitMQ ne l'ajoute pas par défaut).

type

Le type de message. Une des valeur suivante :  event , request , reply , log

user-id

User id utilisé pour se connecter à RabbitMQ. Null par défaut. Si l'expéditeur souhaite réveller son idéentité, user-id doit être égal au nom d'utilisateur RabbitMQ ou le message sera refusé

app-id

L'id de l'applicaiton emmetrice. Valeur a définir  par l'emmeteur

headers

Valeurs définies par l'application émettrices pouvant être utilisé par le consommateur

Voici les headers définis par Gadz.org :

HeadersObligatoireValeur si nullCommentaire
soa-versionOui1.0La version du SOA sur laquelle s'appuie l’émetteur. Ce numéro n’apparaît qu'à partir de la version 2
softfail-countNon0Le nombre de fois que ce message a été traité en softfail
client-libraryNonnullLe client utilisé par l'émetteur (ex: GorgService 5.3). Ceci facilite le debug et peut permettre d'adapter la réponse.
admin-idNonnullL'id de l'admin ayant déclenché cette action pour faciliter le debug e le suivit des action

Des headers supplémentaires peuvent être définis en fonction du type de message 

 Payload

Le payload contient les données devant être traitées par le consommateur du message. Il doit être du type défini par la propriété content-type

Types de messages

Événement (ou notification)

Un événement DOIT être envoyé à l'exchange d'événement (voir Topologie)

Un événement DOIT avoir pour type event 

Une requête DOIT avoir une clé de routage du type event.[identifiant_du_service_emmeteur].[resource].[evenement]. Par exemple event.gappsd.account.created

Les spécifications du payload (voir Structure des messages) du message sont définies par le service émettant l'événement.

Requête

Une requête appel directement une fonction d'un service.

Un événement DOIT avoir pour type request 

Une requête PEUT attendre une réponse. Dans ce cas la requête DOIT contenir contenir la propriété reply_to ayant pour valeur le nom d'un exchange de réponse (voir Topologie).

Les spécifications du payload (voir Structure des messages) du message sont définies par le service cible.

Une requête DOIT être envoyée à un exchange de requête (voir Topologie).

Une requête DOIT avoir une clé de routage du type request.[identifiant_du_service_cible].[resource_manipulée].[action]. Par exemple request.gappsd.account.create

Reponse

Un message de type "réponse" est émis en réponse à un message de type requête

Un événement DOIT avoir pour type reply 

Une réponse DOIT contenir la propriété correlation-id ayant pour valeur le uuid du message de la requête associée.

Une réponse DOIT être envoyée à un exchange de réponse (voir Topologie).

Les spécifications de du payload (voir Structure des messages) du message sont définies par le service émettant la réponse.

Une requête DOIT avoir une clé de routage du type reply.[identifiant_du_service_emmeteur].[resource_manipulée].[action]. Par exemple reply.gappsd.account.create.

Une réponse utilise également les headers suivant :

HeadersObligatoireValeur si nullCommentaire
status-codeOuiN/ALe statut de la réponse. Les code http sont utilisés (200 = succes, 4XX = erreur client, 5XX = erreur serveur
error-typeNonnullValeur admissible softfail , hardfail. Définit si l'erreur est permanenent ou temporaire. En cas d'erreur temporaire, l'émetteur de la requête
next-try-inNonnullEn cas de softfail - le délai en millisecondes du prochain essai prévu (a partir du timestamp de création du message). Si cet header n'est pas présent ou à "0" alors que le header "error-status" est présent, cela signifie que le service ne gère pas les softfails automatiquement.
error-nameNonnullEn cas d'erreur (statut >=400) - Un nom d'erreur permettant au client de traiter automatiquement l'erreur

Log

Un événement DOIT avoir pour type log 

Un message de type "log" permet de centraliser les logs liés aux messages et faciliter le debug.

Une réponse DOIT contenir la propriété correlation-id ayant pour valeur le uuid du message ayant généré le log

Un log DOIT être envoyée à l'exchange de log (voir Topologie).

Un log DOIT avoir une clé de routage identique au message ayant généré le log.

Le payload d'un message de log contient les données de debug

HeadersObligatoireValeur si nullCommentaire
levelOui1La valeur numérique du niveau (voir plus bas). L'utilisation du format numérique permet d'utiliser des exchanges de type "header" et ainsi trier les messages en fonciton de leur niveau.
next-try-innonnullEn cas de softfail
error-namenonnonUn nom d'erreur si il s'agit d'une erreur déjà identifiée
error-typeNonnullValeur admissible softfail , hardfail. Définit si l'erreur est permanenent ou temporaire. En cas d'erreur temporaire, l'émetteur de la requête

Niveaux de logs :

NiveauIdentifiantCommentaires
DEBUG0Des données de debug, ces logs ne sont pas voués à être utilisé en produciton de manière permanente
INFO1Logs permettant de suivre la progression du processus du service
WARNING2Logs avertissant d'une situation potentiellement dangereuse (utilisation d'une fonciton dépréciée ...)
SOFTFAIL3Logs avertissant d'un softfail.
HARDFAIL4Logs avertissant d'un hardfail

 

Types d'erreurs

Les messages sont séparés en 2 classes d'erreur

Les termes "Softfail" et "Hardfail" sont tirés de la précédente version du manager Google Apps écrit en python par les X. https://github.com/vzanotti/gappsd

Softfail

Une erreur temporaire empêche le traitement du message. Il s'agit d'une erreur due à l'environnement extérieur, indépendante du service consommateur. Le message est envoyé dans une queue de stockage pour être retraité plus tard automatiquement.

Exemples :

Hardfail

Une erreur empêche le traitement du message. Il s'agit d'une erreur du au message lui même. Le message ne peux et ne pourra jamais être traiter.

Exemple :

ChangeLog

v2.0

Utilisation des headers et des propriétés des messages plutot que du payload.

Passage de la V1 à la V2 : 

v1.0

Première version