Versionnement sémantique :
Version 1.0
Un événement DOIT être envoyée à l'exchange d'événement (voir Topologie)
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 de l'attribut data
(voir Structure des messages) du message sont définies par le service émettant l'événement.
Une requête appel directement une fonction d'un service.
Une requête PEUT attendre une réponse. Dans ce cas la requête DOIT contenir contenir le header reply_to_exchange
ayant pour valeur le nom d'un exchange de réponse (voir Topologie)
Les spécifications de l'attribut data
(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
Un message de type "réponse" est émit en réponse à un message de type requête
Une réponse DOIT contenir le header request_event_uuid
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 l'attribut data
(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
Un message de type "log" permet de centraliser les logs liés aux messages et faciliter le debug
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
Les messages doivent vérifier le schema JSON suivant :
{ "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": { "event_name": { "type": "string", "pattern": "^[_a-z]+((\\.)?[_a-z]+)*$", "description": "Event type. Must match the routing key" }, "event_uuid": { "type": "string", "description": "The unique identifier of this message as UUID", "pattern": "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" }, "event_creation_time": { "type": "string", "description": "Creation time in UTC ISO 8601 format", "pattern": "^([\\+-]?\\d{4}(?!\\d{2}\\b))((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))?|W([0-4]\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))([T\\s]((([01]\\d|2[0-3])((:?)[0-5]\\d)?|24\\:?00)([\\.,]\\d+(?!:))?)?(\\17[0-5]\\d([\\.,]\\d+)?)?([zZ]|([\\+-])([01]\\d|2[0-3]):?([0-5]\\d)?)?)?)?$" }, "event_sender_id": { "type": "string", "description": "Producer that sent the original message" }, "data": { "type": "object", "description": "Data used to process this message" }, "errors_count": { "type": "integer", "description": "Helper for counting errors" }, "errors": { "type": "array", "items": { "type": "object", "properties": { "error_type": { "enum": [ "debug", "info", "warning", "softerror", "harderror" ], "description": "Type of error." }, "error_sender": { "type": "string", "description": "Consummer that sent this error" }, "error_code":{ "type":"string", "description": "Optionnal error code from the consummer" }, "error_uuid":{ "type":"string", "description": "The unique identifier of this error as UUID", "pattern": "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" }, "error_message":{ "type":"string", "description": "Error explanation" }, "timestamp": { "type": "string", "description": "Time of occuring error in UTC ISO 8601", "pattern": "^([\\+-]?\\d{4}(?!\\d{2}\\b))((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))?|W([0-4]\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))([T\\s]((([01]\\d|2[0-3])((:?)[0-5]\\d)?|24\\:?00)([\\.,]\\d+(?!:))?)?(\\17[0-5]\\d([\\.,]\\d+)?)?([zZ]|([\\+-])([01]\\d|2[0-3]):?([0-5]\\d)?)?)?)?$" }, "error_debug": { "type": "object", "description": "Complementary informations for debugging" } }, "additionalProperties": false, "required": [ "error_type", "error_sender", "timestamp", "error_uuid", "error_message" ] } } }, "additionalProperties": false, "required": [ "event_name", "event_uuid", "event_creation_time", "event_sender_id", "data" ] } |
Exemple de message :
{ "event_uuid":"88d818a1-c77c-44e6-ad0c-8aa893468e94", "event_name":"request.gapps.account.create", "event_creation_time":"2016-05-29T15:03:50+00:00", "event_sender_id":"gram", "data":{ "id":"12453" }, "errors_count":1, "errors":[ { "error_type":"softerror", "error_uuid":"e157e1a0-2663-11e6-b67b-9e71128cae77", "error_sender":"gappsd", "error_message":"Google API Unavailable", "timestamp":"2016-05-29T15:03:50Z", "error_debug":{ "id":"12453" } } ] } |
Les messages sont séparés en 5 classes d'erreur
Les termes "Softerror" et "Harderror" sont tirés de la précédente version du manager Google Apps écrit en python par les X. https://github.com/vzanotti/gappsd |
Non implémenté
Non implémenté
Non implementé
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 retraiter plus tard automatiquement.
Exemples :
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 :
Première version