Note
|
Pour commencer, vous pouvez :
|
Note
|
Si vous rencontrez un problème, vous pouvez contacter l’équipe :
|
Après avoir déclaré des valeurs, elles sont accèssibles depuis n’importe qu’elle étape grâce à la clef donnée.
Warning
|
Si une prochaine étape ajoute une autre valeur en utilisant la même clef, alors la valeur précédente sera perdue et remplacée par la nouvelle. |
Pour pouvoir utiliser la valeur il faut l’écrire avec un #
, exemple : #clef_définie
L’utilisation doit se faire à l’intérieur d’un bloc d’évaluation : ${ }
Exemple, ${#clef_définie}
{
"type":"context-put",
"inputs": {
"entries": {
"prenom" : "toto" (1)
}
}
},
{
"type": "context-put"
"inputs": {
"entries":
{
"réutilisation": "${#prenom}" (2)
"concaténation": "${#prenom.concat(" à la plage")}" (3)
}
}
}
}
-
La clef
prenom
contiendra la valeurtoto
-
On utilise la valeur de
#prenom
, donc la clefréutilisation
contiendra aussitoto
-
La clef
concaténation
contiendratoto à la plage
Par exemple, pour créer une variable avec :
-
Une valeur fixe :
"ADS" : "0217DA00014822"
-
Une valeur calculée au moment de l’exécution :
-
Date à l’instant t :
"startDate" : "$\{T(java.time.LocalDateTime).now().toString()}Z"
-
Date dans le futur (instant t + 1800 secondes) :
"endDate" : "$\{T(java.time.LocalDateTime).now().plusSeconds(1800).toString()}Z"
-
Cette action prend 1 paramètre en entrée :
-
entries
-
C’est une
Map
, c’est à dire une liste de "clef": "valeur"
-
{
"type":"context-put", (1)
"inputs": { (2)
"entries": { (3)
"un_nom_de_clef" : "une valeur", (4)
"un_autre_nom_de_clef" : "une autre valeur"
}
}
}
-
on défini l’action à effectuer :
context-put
-
on ouvre le bloc
inputs
, c’est là que sont déclarés les entrées nécessaires à une action -
on défini le paramètre
entries
, qui est nécessaire à l’actioncontext-put
-
on défini
{
"type":"sql", (1)
"inputs": {
"statements": [ (2)
"select * from random_table",
"show tables"
]
}
}
-
on défini l’action
sql
-
on défini la liste des requetes à executer
Une liste de Records : 3 attributs disponibles : - public final int affectedRows; - public final List<String> headers; - public final List<List<Object>> rows; 2 méthodes disponibles sur chaque Record : - List<Map<String, Object>> toListOfMaps() => un élément de la liste correspond à un resultat, la map permet de retrouver chaque résultat par sa clef - Object[][] toMatrix() => ligne correspond à une résultat, colonne correspond à l'index la colonne de la requete
{
"type":"http-get",
"target": "some_target", (1)
"inputs":{
"uri": "/actuator/health", (2)
"headers": { (3)
"X--API-VERSION": "1.0",
"X--HEADER-1": "42"
},
"timeout": "3000 ms" (4)
}
}
-
Target de type http ou https
-
Uri de la requete
-
Optionel Headers de la requete
-
Optionel par défault 2 secondes. Unité disponible : "ms", "s", "sec", "m", "min", "h", "hour", "hours", "hour(s)", "d", "day", "days", "day(s)"
- status => int - body => String - headers => org.springframework.http.HttpHeaders
{
"type":"http-post",
"target": "some_target", (1)
"inputs":{
"uri": "/actuator/health", (2)
"headers": { (3)
"X--API-VERSION": "1.0",
"X--HEADER-1": "42"
},
"timeout": "3000 ms", (4)
"body" : "some body" (5)
}
}
-
Target de type http ou https
-
Uri de la requete
-
Optionel Headers de la requete
-
Optionel par défault 2 secondes. Unité disponible : "ms", "s", "sec", "m", "min", "h", "hour", "hours", "hour(s)", "d", "day", "days", "day(s)"
-
Body de la requete
- status => int - body => String - headers => org.springframework.http.HttpHeaders
{
"type":"http-put",
"target": "some_target", (1)
"inputs": {
"uri": "/actuator/health", (2)
"headers": { (3)
"X--API-VERSION": "1.0",
"X--HEADER-1": "42"
},
"timeout": "3000 ms", (4)
"body" : "some body" (5)
}
}
-
Target de type http ou https
-
Uri de la requete
-
Optionel Headers de la requete
-
Optionel par défault 2 secondes. Unité disponible : "ms", "s", "sec", "m", "min", "h", "hour", "hours", "hour(s)", "d", "day", "days", "day(s)"
-
Body de la requete
- status => int - body => String - headers => org.springframework.http.HttpHeaders
{
"type":"http-delete",
"target": "some_target", (1)
"inputs":{
"uri": "/actuator/health", (2)
"headers": { (3)
"X--API-VERSION": "1.0",
"X--HEADER-1": "42"
},
"timeout": "3000 ms" (4)
}
}
-
Target de type http ou https
-
Uri de la requete
-
Optionel Headers de la requete
-
Optionel par défault 2 secondes. Unité disponible : "ms", "s", "sec", "m", "min", "h", "hour", "hours", "hour(s)", "d", "day", "days", "day(s)"
- status => int - body => String - headers => org.springframework.http.HttpHeaders
{
"type":"https-server-start",
"inputs":{
"port": "8443", (1)
"truststore-path": "/tmp/trustore.jks", (2)
"truststore-passowrd": "password" (3)
}
}
-
port d’écoute
-
path local vers le trustore
-
password pour lire le trustore
- httpsServer => l'instance WireMockServer qui sera réutilisé pour récupérer les messages reçu par le serveur - Une finally operation qui arrete le server à la fin du scénario
{
"type":"https-listener",
"inputs": {
"https-server": "${#httpsServer}" (1)
"uri": "/test", (2)
"verb": "POST", (3)
"expected-message-count": "2" (4)
}
}
-
instance du serveur http d’écoute
-
uri (regexp) sur laquelle récupérer les messages
-
sur quel VERB récupérer les message
-
Optionel Nombre de message attendu. KO si nombre de message différent. 1 par default
- requests => une liste de com.github.tomakehurst.wiremock.verification.LoggedRequest
{
"type":"json-assert",
"inputs":{
"document": "document_json", (1)
"expected": { (2)
"$.status.code": 200.0,
"$.status.reason": "OK"
}
}
}
-
Document json à évaluer
-
Pour chaque path (key), on vérifie que la valeur correspond (value)
Un objet logger est disponible avec info(), error() qui va logger directement les infos au niveau du step
{
"type":"compare",
"inputs":{
"actual": "chaîne_de_caractères_1", (1)
"expected": "chaîne_de_caractères_2", (2)
"mode": "mode", (3)
}
}
-
Chaîne de caractères à évaluer
-
Chaîne de caractères à comparer
-
Mode à comparer: equals, not equals, not-equals, contains, not contains, not-contains
Un objet logger est disponible avec info(), error() qui va logger directement les infos au niveau du step
{
"type":"compare",
"inputs":{
"actual": "chiffre_1", (1)
"expected": "chiffre_2", (2)
"mode": "mode", (3)
}
}
-
Chiffre à évaluer
-
Chiffre à comparer
-
Mode à comparer: greater than, less than, greater-than, less-than
{
"type":"json-compare",
"inputs": {
"document1": "document_json1", (1)
"document2": "document_json2", (2)
"comparingPaths": { (3)
"$.status": "$.test.status",
"$.status.code": "$.test.status.code"
}
}
}
-
Premier document
-
Second document
-
Path à comparer entre le premier document et le second document
{
"type":"xml-assert",
"inputs": {
"document": "document_xml", (1)
"expected": { (2)
"$.status.code": 200.0,
"$.status.reason": "OK"
}
}
}
-
Document xml à évaluer
-
Pour chaque path (key), on vérifie que la valeur correspond (value)
{
"type":"assert",
"inputs":{
"asserts": (1)
[
{"assert-true": "${1 == 1}"},
{"assert-true": "${#httpStatus == 200}"}
]
}
}
-
Liste d’assert à évaluer
{
"type":"jms-clean-queue",
"target": "target_jms", (1)
"inputs":{
"destination": "dynamicQueues/test" (2)
}
}
-
target de type jms connection
-
queue distante à vider
Warning
|
Ne récupère que des javax.jms.TextMessage |
{
"type":"jms-listener",
"target": "target_jms", (1)
"inputs": {
"destination": "dynamicQueues/test" (2)
}
}
-
target de type jms connection
-
queue distante sur laquelle récupérer un messages JMS
- textMessage => le contenu du message sous format String - jmsProperties => une Map<String, Object> des headers JMS
N’envoi que des javax.jms.TextMessage
{
"type":"jms-sender",
"target": "target_jms", (1)
"inputs":{
"destination": "dynamicQueues/test", (2)
"body": "some body" (3)
"headers": { (4)
"X--JMS-VERSION": "1.0",
"X--HEADER-1": "42"
},
}
}
-
target de type jms connection
-
queue distante sur laquelle envoyer un messages JMS
-
contenu du message jms
-
Optionel header du message jms
{
"type": "amqp-create-bound-temporary-queue",
"target": "target_amqp", (1)
"inputs": {
"exchange-name": "amq.direct", (2)
"routing-key": "routemeplease", (3)
"queue-name": "my queue" (4)
}
}
-
Target de type amqp connection
-
Exchange existant sur lequel bindé la queue
-
Nom de la routing key
-
Queue temporaire à créer sur lequel le binding va être fait
- queueName => le nom de la queue - Une finally operation qui va supprimer la queue créée
{
"type": "amqp-delete-queue",
"target": "target_amqp", (1)
"inputs": {
"queue-name": "my queue" (2)
}
}
-
Target de type amqp connection
-
Queue temporaire à supprimer
- queueName => le nom de la queue - Une finally operation qui va supprimer la queue créée
{
"type": "amqp-unbind-queue",
"target": "target_amqp", (1)
"inputs": {
"exchange-name": "amq.direct", (2)
"routing-key": "routemeplease", (3)
"queue-name": "my queue" (4)
}
}
-
Target de type amqp connection
-
Exchange existant sur lequel est bindé la queue
-
Nom de la routing key
-
Queue existante
{
"type": "amqp-basic-publish",
"target": "target_amqp", (1)
"inputs": {
"exchange-name": "amq.direct", (2)
"routing-key": "routemeplease", (3)
"payload": "my payload" (4)
"headers": { (5)
"X--AMQP-VERSION": "1.0",
"X--HEADER-1": "42"
},
"properties": { (6)
"X--AMQP-PROPERTIES": "1.0",
"X--PROPERTIES-1": "42"
},
}
}
-
Target de type amqp connection
-
Exchange existant sur lequel bindé la queue
-
Nom de la routing key
-
Queue temporaire à créer sur lequel le binding va être fait
-
Headers à ajouter au message
-
Properties du message
- payload => payload envoyé - headers => headers envoyé sous format String
{
"type": "amqp-basic-get",
"target": "test_amqp", (1)
"inputs": {
"queue-name": "my queue" (2)
}
}
-
Target de type amqp connection
-
Queue sur lequel récupére le message
- message => message complet com.rabbitmq.client.GetResponse - body => contenu message récupéré - headers => headers du message récupéré
{
"type": "selenium-driver-init",
"inputs": {
"driverPath": "path", (1)
"browserPath": "path" (2)
}
}
-
Path vers driver en local
-
Path vers browser en local
- webDriver => instance de webdriver créé - Une finally operation qui arrete le driver à la fin du scénario
{
"type": "selenium-click"
"inputs": {
"web-driver": "${#webDriver}", (1)
"selector": "//chutney-home-page/div[1]/button", (2)
"by": "xpath", (3)
"wait": "2", (4)
}
}
-
Instance de webdriver créée précédemment
-
Selector vers le button a cliqué
-
Type de selector : "xpath", "id", "name", "className", "cssSelector"
-
Optionel Timemout en seconde pour trouver l’élément, 1 seconde par default
{
"type": "selenium-close"
"inputs": {
"web-driver": "${#webDriver}" (1)
}
}
-
Instance de webdriver créée précédemment
{
"type": "selenium-get"
"inputs": {
"web-driver": "${#webDriver}", (1)
"valu"e: "http://url:port/unepage" (2)
}
}
-
Instance de webdriver créée précédemment
-
Url à ouvrir
- outputGet => contient le nom de la page ouverte
{
"type": "selenium-click"
"inputs": {
"web-driver": "${#webDriver}", (1)
"selector": "//chutney-home-page/div[1]/button", (2)
"by": "xpath", (3)
"wait": "2" (4)
}
}
-
Instance de webdriver créée précédemment
-
Selector vers le button a cliqué
-
Type de selector : "xpath", "id", "name", "className", "cssSelector"
-
Optionel Timemout en seconde pour trouver l’élément, 1 seconde par default
- outputGetText => contient le text récupérer au format String
{
"type": "selenium-quit"
"inputs": {
"web-driver": "${#webDriver}" (1)
}
}
-
Instance de webdriver créée précédemment
Le screeshot est logger au niveau de la tache au format image/png;base64
{
"type": "selenium-screenshot
"inputs": {
"web-driver": "${#webDriver}" (1)
}
}
-
Instance de webdriver créée précédemment
{
"type": "selenium-send-keys"
"inputs": {
"web-driver": "${#webDriver}", (1)
"selector": "//input[@name='username']", (2)
"by": "xpath", (3)
"wait": "5", (4)
"value": "my username" (5)
}
}
-
Instance de webdriver créée précédemment
-
Selector vers le button a cliqué
-
Type de selector : "xpath", "id", "name", "className", "cssSelector"
-
Optionel Timemout en seconde pour trouver l’élément, 1 seconde par default
-
Texte à écrire
{
"type": "selenium-send-keys"
"inputs": {
"web-driver": "${#webDriver}", (1)
"selector": "windowId", (2)
"by": "id", (3)
"wait": "5" (4)
}
}
-
Instance de webdriver créée précédemment
-
Selector vers le button a cliqué
-
Type de selector : "xpath", "id", "name", "className", "cssSelector"
-
Optionel Timemout en seconde pour trouver l’élément, 1 seconde par default
{
"type": "selenium-wait"
"inputs": {
"web-driver": "${#webDriver}", (1)
"selector": "//input[@name='username']", (2)
"by": "xpath", (3)
"wait": "5" (4)
}
}
-
Instance de webdriver créée précédemment
-
Selector vers le button a cliqué
-
Type de selector : "xpath", "id", "name", "className", "cssSelector"
-
Optionel Timemout en seconde pour trouver l’élément, 1 seconde par default
{
"type": "mongo-count"
"inputs": {
"collection": "my collection", (1)
"query": "/my query" (2)
}
}
-
La collection à requêter
-
La requête
- count => le nombre de document
{
"type": "mongo-delete"
"inputs": {
"collection": "my collection", (1)
"query": "my query" (2)
}
}
-
La collection à requêter
-
La requête
- deletedCount => le nombre de document supprimé
{
"type": "mongo-find"
"inputs": {
"collection": "my collection", (1)
"query": "my query", (2)
"limit": "42" (3)
}
}
-
La collection à requêter
-
La requête
-
Optionel 20 par default
- documents => liste de document au format String
{
"type": "mongo-insert"
"inputs": {
"collection": "my collection", (1)
"document": "my document to insert" (2)
}
}
-
La collection où insérer le document
-
Le document à insérer
Warning
|
pour le paramètre arrayFilters, seulement de puis la version mongodb 3.5.12 |
{
"type": "mongo-update"
"inputs": {
"collection": "my collection", (1)
"filter": "my filter", (2)
"update": "my update to apply", (3)
"arrayFilters": "my filter" (4)
}
}
-
La collection à requêter
-
Le filtre pour sélectionner les document à mettre à jour
-
La mise a jour à appliquer
-
Optionel liste d’arrayFilters. Voir https://jira.mongodb.org/browse/SERVER-831 pour l’usage
- modifiedCount => le nombre de document modifié
Va logger tout le contexte du scénario au niveau du report du step
{
"type": "debug"
}
{
"type": "kafka-basic-publish",
"target": "target_kafka", (1)
"inputs": {
"topic": "topic_name", (2)
"payload": "my payload", (3)
"headers": { (4)
"X--KAFKA-VERSION": "1.0",
"X--HEADER-1": "42"
},
}
}
-
Target de type kafka
-
Topic existant sur lequel envoyer le message
-
Contenu du message à envoyer
-
Headers à ajouter au message
- payload => payload envoyé - headers => headers envoyé sous format String
{
"type": "kafka-basic-consume",
"target": "target_kafka", (1)
"inputs": {
"topic": "topic_name", (2)
"group": "group_id", (3)
"properties": { (4)
"client.id": "client_id"
},
"nb-messages": "1", (5)
"selector": "$..[?($.headers.header1=='value1' && $.payload.id=="1122")]", (6)
"timeout": "60 sec", (7)
}
}
-
Target de type kafka
-
Topic existant sur lequel écouter les messages
-
Le goup id du consumer
-
Optionel Propriétés supplémentaires pour le consumer comme 'auto.offset.reset', see: https://kafka.apache.org/documentation/#consumerconfigs
-
Optionel par défault 1. Nombre de messages à récupérer
-
Optionel par défault null. Selecteur json path
-
Optionel par défault 60 secondes. Unité disponible : "ms", "s", "sec", "m", "min", "h", "hour", "hours", "hour(s)", "d", "day", "days", "day(s)"
- body => messages consommés sous format d'une liste Map avec clés headers et payload - payloads => payloads extraits de messages sous format d'une liste - headers => headers extraits de messages sous format d'une liste
Un objet logger est disponible avec info(), error() qui va logger directement les infos au niveau du step
{
"type": "groovy",
"inputs": {
"script": "topic_name", (1)
"parameters": { (2)
"key": "value",
"key2": "value2"
}
}
}
-
Script groovy au format String
-
Map des parametres à ajouter on contexte groovy
- results => Liste de résultat de chaque commande ssh
Cette fonction est pour enregistrer une value dans un Json document, en utilisant son json path.
{
"type": "http-get", (1)
"outputs": { (2)
"title_book_01":
"${ (3)
#json( (4)
#body, (5)
'$.store.book[0].title' (6)
)
.toString() (7)
}" (3)
}
}
-
cette exemple utilise http-get, mais jsonPathFunction peut être utilsé dans context HTTP
-
output de l’appel http
-
début et fin de SpEL
-
appel jsonPathFunction
-
1er paramètre de cette function: un json document, ici c’est le body de reponse http-get
-
2er paramètre de cette function: le json path de la valeur souhaitée
-
l’output de cette function est un object, on peut le caster un string si besons
Cette fonction est pour enregistrer une value dans un xml document, en utilisant son path.
{ "inputs":
{
"entries":
{
"STANDARD_XML":
'''
<node1>
<node2 attr1="attr1"/>
<node3 attr1="attr2">text1</node3>
<node4/>
<node5>
<![CDATA[some stuff]]>
</node5>
</node1>
''',
"attribute_value": "${ (1)
#xpath( (2)
#STANDARD_XML, (3)
"/node1/node2/@attr1" (4)
)
}",(1) (5)
"text_value": "${#xpath(#STANDARD_XML,'/node1/node3/text()')}", (6)
"single_node_containing_text": "${#xpath(#STANDARD_XML,'/node1/node3')}", (7)
"single_node_containing_CDATA": "${#xpath(#STANDARD_XML,'/node1/node5')}" (8)
}
}
}
-
début et fin de SpEL
-
appel xPathFunction
-
1er paramètre de cette function: un xml document
-
2er paramètre de cette function: le xml path de la valeur souhaitée
-
le résultat de ce exemple: "attr1"
-
le résultat de ce exemple: "text1"
-
le résultat de ce exemple: "text1"
-
le résultat de ce exemple: "some stuff"
Cette function est pour parser la date de type String à different type, selon le formateur fourni.
{
"inputs": {
"entries": {
"dateToParse": "2018-01-15T14:38:21Z",
"dateParsed": "${ (1)
#date(#dateToParse) (2)
}",(1)
"epochSecond": "${#dateParsed.getEpochSecond()}" (3)
}
}
}
-
début et fin de SpEL
-
appel dateFunction
-
l’epochSecond de ce exemple : 1516027101
Quand il n'y a pas de formatteur fourni, l'output est type Instant.
{
"inputs": {
"entries": {
"dateToParse": "2018-01-15",
"dateParsed": "${ (1)
#date(#dateToParse, "yyyy-MM-dd") (2)
}",(1)
"dayOfWeek": "${#dateParsed.getDayOfWeek()}" (3)
}
}
}
-
début et fin de SpEL
-
appel dateFunction
-
le jour de ce exemple : "MONDAY"
Avec date et son formatteur "yyyy-MM-dd", l'output est type LocalDate.
{
"inputs": {
"entries": {
"dateToParse": "2018-01-15T14:38:21+0200",
"dateParsed": "${ (1)
#date(#dateToParse, "yyyy-MM-dd'T'HH:mm:ssx") (2)
}", (1)
"zone": "${#dateParsed.getZone()}" (3)
}
}
}
-
début et fin de SpEL
-
appel dateFunction
-
le zone de ce exemple : "+02:00"
Avec date et son formatteur "yyyy-MM-dd'T'HH:mm:ssx", l'output est type ZonedDateTime.
Exemple 04
{
"inputs": {
"entries": {
"dateToParse": "2018-01-15T14:38:21",
"dateParsed": "${ (1)
#date(#dateToParse, "yyyy-MM-dd'T'HH:mm:ss") (2)
}", (1)
"minute": "${#dateParsed.getMinute()"} (3)
}
}
}
-
début et fin de SpEL
-
appel dateFunction
-
le value minute de ce exemple : "38"
Avec date et son formatteur "yyyy-MM-dd'T'HH:mm:ss", l'output est type LocalDateTime.
String str_replace(String input, String regularExpression, String replacement)
{
"description": "Remplace poivron par pimiento",
"implementation":
{
"type": "compare", (1)
"inputs":
{
"actual": "${ #str_replace(\"carotte, poivron, courgette\", \"poivron\", \"pimiento\") }", (2)
"expected": "carotte, pimiento, courgette",
"mode": "equals" (1)
} (3)
}
}
-
Exemple d’utilisation avec une comparaison d’égalité (tâche
compare
avec le modeequals
) -
Appel à la fonction
str_replace
avec des paramètres -
Le résultat de cet exemple est : "vrai", car la variable le mot poivron est remplacé par pimiento
{
"inputs": {
"entries": {
"input": "{ \"chutney\" : 12345, \"Carotte\" : \"poivron\" }",
"regExp": "(?i)(.*\"caRotTe\" : )(\".*?\")(.*)",
"replacement": "$1\"pimiento\"$3",
"replaced": "${ (1)
#str_replace(#input,#regExp,#replacement) (2)
}" (1)
} (3)
}
}
-
début et fin de SpEL
-
appel stringRepalceFunction
-
le résultat de cet exemple : "{ \"chutney\" : 12345, \"Carotte\" : \"pimiento\" }"
Object nullable(Object maybeNullValue)
Le résultat d’une expression SpEL est parfois null, ce qui est traité comme une erreur par le système.
Toutefois, ce résultat est parfois attendu et souhaité.
Dans ce cas, il faut indiquer au système que la valeur null ne doit pas être traitée comme une erreur.
Pour ce faire, il faut utiliser la fonction nullable
pour englober l’expression dont la valeur peut être nulle.
{
"description": "Assert nullable value",
"implementation":
{
"type": "compare", (1)
"inputs":
{
"actual": "${ (2)
#nullable(#nil) (3)
}", (2)
"expected": "null",
"mode": "equals" (1)
} (4)
}
}
-
Exemple d’utilisation avec une comparaison d’égalité (tâche
compare
avec le modeequals
) -
début et fin de SpEL
-
la variable
#nil
n’existe pas et vaut donc null. Elle est passée en paramètre de la fonctionnullable
-
le résultat de cet exemple est : "vrai", car la variable nil est remplacée par la chaine de charactère "null"
Une strategie d’exécution permet de définir la façon dont Chutney va exécuter une ou plusieurs étapes. Aujourd’hui, il existe 2 strategies :
-
Les étapes s’exécutent les unes à la suite des autres.
-
Dès qu’une étape est en échec alors tout le test s’arrête.
{
"name": "Etape exécuter une seule fois",
"type": "fail", (1)
"strategy": { (2)
"type": "sequential" (3)
}
},
{
"name": "Etape jamais exécuter", (4)
"type": "success",
"strategy": {
"type": "sequential"
}
}
-
On déclare une action de type
fail
, qui sera donc en échec -
On déclare qu’on va utiliser une stratégie
-
On déclare que la strategie à appliquée est
sequential
-
Cette étape ne sera jamais exécutée car le test échoue à l’étape précédente
Tip
|
La stratégie sequential est appliquée par défaut. Il n’est pas nécessaire de l’écrire sur chaque étape.
|
{
"name": "Etape exécuter une seule fois",
"type": "fail" (1)
},
{
"name": "Etape jamais exécuter",
"type": "success"
}
-
Ici, il n’y a pas de stratégie définie, la stratégie par défaut s’applique donc automatiquement.
Certaine étapes sont parfois en échec, mais vous souhaitez pouvoir ré-essayer jusqu’à obtenir un succès avec :
-
Une durée limitée,
-
Et un nombre de tentatives limitées
Pour cela,
il faut utiliser la strategy retry-with-timeout
.
{
"name": "Etape relancer plusieurs fois",
"type": "fail", (1)
"strategy": { (2)
"type": "retry-with-timeout", (3)
"parameters": { (4)
"timeOut": "30 min", (5)
"retryDelay": "1 min" (6)
}
}
}
-
On déclare une action de type
fail
, qui sera donc toujours en échec -
On déclare qu’on va utiliser une stratégie
-
On déclare que la strategie à appliquée est
retry-with-timeout
-
On déclare les paramètres à utiliser pour cette stratégie
-
Le paramètre
timeOut
défini la durée maximum pendant laquelle cette étape sera relancer -
Le paramètre
retryDelay
défini la durée à attendre entre chaque tentative