Migrer des fonctions d'étape AWS vers Workflows

Pour vous aider à passer d'Amazon Web Services (AWS) Step Functions aux workflows sur Google Cloud, cette page explique les principales similitudes et différences entre les deux produits. Ces informations vous aideront ceux qui connaissent déjà les fonctions graduelles implémentent une méthode similaire à l'aide de Workflows.

Comme Step Functions, Workflows est une plate-forme d'orchestration entièrement gérée, basée sur l'état, qui exécute des services dans l'ordre que vous définissez : un workflow. Ces workflows peuvent combiner des services, y compris des services personnalisés hébergés sur des fonctions Cloud Run ou Cloud Run, les services Google Cloud comme Cloud Vision AI et BigQuery, et n'importe quelle API HTTP.

Notez que les workflows Express Step Functions sont un type de workflow AWS Step Functions qui n'est pas pris en compte ici, car la durée d'un workflow Express est limitée et l'exécution d'un workflow "une seule fois" n'est pas prise en charge.

Hello world

Dans Step Functions, une machine d'état est un workflow, et une tâche est un état qui représente une seule unité de travail exécutée par un autre service AWS. Step Functions exige que chaque état définisse l'état suivant.

Dans Workflows, une série d'étapes utilisant l'API Workflows la syntaxe décrit les tâches à exécuter. Workflows traite les étapes comme s'ils se trouvaient dans une liste ordonnée et les exécute un par un jusqu'à ce que toutes les étapes ont été exécutées.

Le message "Hello world" suivant exemple illustrant l'utilisation d'états dans l'étape Fonctions et étapes dans Workflows:

Fonctions en escalier

  {
    "Comment": "Hello world example of Pass states in Amazon States Language",
    "StartAt": "Hello",
    "States": {
      "Hello": {
        "Type": "Pass",
        "Result": "Hello",
        "Next": "World"
      },
      "World": {
        "Type": "Pass",
        "Result": "World",
        "End": true
      }
    }
  }

Fichier YAML des workflows

  ---
  # Hello world example of steps using Google Cloud Workflows syntax
  main:
      steps:
      - Hello:
          next: World
      - World:
          next: end
  ...

JSON Workflows

  {
    "main": {
      "steps": [
        {
          "Hello": {
            "next": "World"
          }
        },
        {
          "World": {
            "next": "end"
          }
        }
      ]
    }
  }

Présentation de la comparaison

Cette section compare les deux produits plus en détail.

Fonctions en escalierWorkflows
SyntaxeJSON (YAML dans les outils) YAML ou JSON
Flux de contrôleTransitions entre les états Contrôle de flux impératif avec étapes
WorkerRessources (ARN) Requêtes HTTP et connecteurs
FiabilitéReprendre/Réessayer Attraper/Réessayer
ParallélismeCompatible Compatible
Données d'étatL'état est transmis Variables Workflows
AuthentificationIAM IAM
Expérience utilisateurWorkflow Studio, CLI, SDK, IaC Console Google Cloud, CLI, SDK, IaC
Tarifs Tarifs des fonctions Step Tarifs de Workflows
Syntaxe

Step Functions utilise principalement le format JSON pour définir des fonctions et n'est pas compatible directement avec le format YAML. Toutefois, dans AWS Toolkit pour Visual Studio Code et dans AWS CloudFormation, vous pouvez utiliser le format YAML pour une définition Step Functions.

Vous pouvez décrire les étapes de Workflows à l'aide de la syntaxe Workflows. Elles peuvent être écrites en YAML ou en JSON. La majorité des sont au format YAML. Les exemples de cette page illustrent les avantages de YAML, dont la facilité de lecture et d'écriture, et la compatibilité native avec les commentaires. Pour obtenir une explication détaillée de la syntaxe Workflows, consultez la documentation de référence sur la syntaxe.

Flux de contrôle

Workflows et Step Functions modélisent les workflows en tant que série de tâches : étapes dans Workflows et états dans Step Functions. Les deux permettent à une tâche d'indiquer la tâche à exécuter ensuite et acceptent les conditions similaires à un commutateur pour sélectionner l'unité de travail suivante en fonction de l'état actuel. Une touche est que les fonctions d'étape nécessitent que chaque état définisse le suivant. tandis que Workflows exécute les étapes dans l'ordre dans lequel elles sont (y compris les étapes suivantes alternatives). Pour en savoir plus, consultez les sections Conditions et Étapes.

Nœud de calcul

Les deux produits orchestrent des ressources de calcul telles que des fonctions, des conteneurs et d'autres services Web pour accomplir des tâches. Dans Step Functions, le nœud de calcul est identifié par un champ Resource, qui est syntaxiquement un URI. Les URI utilisés pour identifier les ressources de travail sont au format ARN (Amazon Resource Name), et les utilisateurs ne peuvent pas appeler directement un point de terminaison HTTP arbitraire.

Les workflows peuvent envoyer des requêtes HTTP à un point de terminaison HTTP arbitraire et obtenir une réponse. Connecteurs facilitent la connexion à d'autres API Google Cloud dans un workflow, et pour intégrer vos workflows à d'autres produits Google Cloud, comme Pub/Sub, BigQuery ou Cloud Build. Connecteurs simplifier les services d'appel, car ils gèrent le formatage des requêtes à votre place, en fournissant des méthodes et des arguments pour ne pas avoir à connaître les détails API Google Cloud. Vous pouvez également configurer le délai avant expiration et l'interrogation règles.

Fiabilité

Si une tâche échoue, votre workflow doit pouvoir effectuer de nouvelles tentatives appropriées, intercepter des exceptions le cas échéant, et réacheminer le workflow si nécessaire. Les deux étapes pour Cloud Functions et Workflows s'appuient sur des d'exception: interception d'exceptions avec de nouvelles tentatives et distribution finale à ailleurs dans le workflow. Pour en savoir plus, consultez Erreurs de workflow.

Parallélisme

Vous pouvez souhaiter que votre workflow orchestre plusieurs tâches en parallèle. Étape Il existe deux façons d'y parvenir: vous pouvez prendre un élément de données en parallèle de plusieurs tâches différentes ; ou utiliser un tableau et transmettre ses éléments à la même tâche.

Dans les workflows, vous pouvez définir une partie de votre workflow dans laquelle deux étapes ou plus peuvent s'exécuter simultanément. Vous pouvez définir des branches qui s'exécutent simultanément ou une boucle dans laquelle les itérations s'exécutent simultanément. Pour en savoir plus, consultez Exécuter les étapes du workflow en parallèle.

Données d'état

L'un des avantages d'un moteur de workflow est que les données d'état sont gérées pour vous sans datastore externe. Dans les fonctions d'étape, les données d'état sont transmises d'un état à un autre dans une structure JSON.

Dans Workflows, vous pouvez enregistrer les données d'état dans des variables globales. Étant donné que la durée d'exécution est limitée à un an, vous pouvez conserver les données d'état tant que l'instance est en cours d'exécution.

Authentification

Ces deux produits s'appuient sur un système de Identity and Access Management (IAM) sous-jacent pour l'authentification et le contrôle des accès. Par exemple, vous pouvez utiliser un rôle IAM pour appeler des fonctions d'étape.

Dans Workflows, vous pouvez utiliser un compte de service pour appeler un workflow. Vous pouvez utiliser OAuth 2.0 ou OIDC pour vous connecter aux API Google Cloud. Vous pouvez également utiliser un en-tête de requête d'autorisation pour vous authentifier auprès d'une API tierce. Pour en savoir plus, consultez Autoriser un workflow à accéder aux ressources Google Cloud et Effectuer des requêtes authentifiées à partir d'un workflow.

Expérience utilisateur

Vous pouvez utiliser un outil de ligne de commande ou une infrastructure en tant que code (IAC) telle que Terraform pour définir et gérer à la fois des fonctions de séquencement et des workflows.

En outre, Workflows permet l'exécution de workflows à l'aide des bibliothèques clientes de la console Google Cloud, de la Google Cloud CLI, ou en envoyant une requête à l'API REST Workflows. Pour en savoir plus, consultez la section Exécuter un workflow.

Tarifs

Les deux produits disposent d'une version gratuite. Pour en savoir plus, consultez leurs tarifs respectifs. pages: Tarifs des fonctions d'étape et Tarification de Workflows.

Mappage des types d'états sur les étapes

Step Functions propose huit types d'états. Les états sont des éléments d'une machine à états qui peuvent prendre des décisions en fonction de leurs entrées, effectuer des actions et transmettre des sorties à d'autres états. Avant de migrer de Step Functions vers Workflows, assurez-vous de savoir comment traduire chaque type d'état en étape Workflows.

Choice

Un état Choice ajoute une logique d'embranchement à une machine à états.

Dans les workflows, vous pouvez utiliser un bloc switch en tant que mécanisme de sélection qui permet à la valeur d'une expression de contrôler le flux d'exécution d'un workflow. Si une valeur correspond, l'instruction de cette condition est exécutée. Pour en savoir plus, consultez la section Conditions.

Fonctions d'étape

  "ChoiceState": {
    "Type": "Choice",
    "Choices": [
      {
        "Variable": "$.foo",
        "NumericEquals": 1,
        "Next": "FirstMatchState"
      },
      {
        "Variable": "$.foo",
        "NumericEquals": 2,
        "Next": "SecondMatchState"
      }
    ],
    "Default": "DefaultState"
  }

Fichier YAML des workflows

  switch:
    - condition: ${result.body.SomeField < 10}
      next: small
    - condition: ${result.body.SomeField < 100}
      next: medium
    - condition: true
      next: default_step

JSON Workflows

  {
    "switch": [
      {
        "condition": "${result.body.SomeField < 10}",
        "next": "small"
      },
      {
        "condition": "${result.body.SomeField < 100}",
        "next": "medium"
      },
      {
        "condition": true,
        "next": "default_step"
      }
    ]
  }

Fail

Un état Fail arrête l'exécution de la machine à états et la marque comme l'échec.

Dans Workflows, vous pouvez générer des erreurs personnalisées à l'aide du raise syntaxe. De plus, vous pouvez intercepter et gérer les erreurs à l'aide d'un bloc try/except. Pour Pour en savoir plus, consultez la section Générer des erreurs.

Fonctions d'étape

  "FailState": {
      "Type": "Fail",
      "Error": "ErrorA",
      "Cause": "Kaiju attack"
  }

Fichier YAML des workflows

  raise:
      code: 55
      message: "Something went wrong."

JSON Workflows

  {
    "raise": {
      "code": 55,
      "message": "Something went wrong."
    }
  }

Map

Un état Map peut être utilisé pour exécuter un ensemble d'étapes pour chaque élément d'une entrée. tableau.

Dans Workflows, vous pouvez utiliser une boucle for pour itérations.

Fonctions en escalier

  { "StartAt": "ExampleMapState",
    "States": {
      "ExampleMapState": {
        "Type": "Map",
        "Iterator": {
           "StartAt": "CallLambda",
           "States": {
             "CallLambda": {
               "Type": "Task",
               "Resource": "arn:aws:lambda:us-east-1:123456789012:function:HelloFunction",
               "End": true
             }
           }
        }, "End": true
      }
    }
  }

Fichier YAML des workflows

  - assignStep:
      assign:
        - map:
            1: 10
            2: 20
            3: 30
        - sum: 0
  - loopStep:
      for:
          value: key
          in: ${keys(map)}
          steps:
            - sumStep:
                assign:
                  - sum: ${sum + map[key]}
  - returnStep:
      return: ${sum}

JSON Workflows

  [
    {
      "assignStep": {
        "assign": [
          {
            "map": {
              "1": 10,
              "2": 20,
              "3": 30
            }
          },
          {
            "sum": 0
          }
        ]
      }
    },
    {
      "loopStep": {
        "for": {
          "value": "key",
          "in": "${keys(map)}",
          "steps": [
            {
              "sumStep": {
                "assign": [
                  {
                    "sum": "${sum + map[key]}"
                  }
                ]
              }
            }
          ]
        }
      }
    },
    {
      "returnStep": {
        "return": "${sum}"
      }
    }
  ]

Parallel

Un état Parallel peut être utilisé pour créer des branches d'exécution parallèles dans votre machine à états. Dans l'exemple Step Functions suivant, une recherche d'adresse et de numéro de téléphone est effectuée en parallèle.

Dans Workflows, vous pouvez utiliser une étape parallel pour définir une partie de votre workflow dans lequel deux étapes ou plus peuvent s'exécuter simultanément. Pour en savoir plus, consultez la section Étapes parallèles.

Fonctions en escalier

  { "StartAt": "LookupCustomerInfo",
    "States": {
      "LookupCustomerInfo": {
        "Type": "Parallel",
        "End": true,
        "Branches": [
          {
           "StartAt": "LookupAddress",
           "States": {
             "LookupAddress": {
               "Type": "Task",
               "Resource": "arn:aws:lambda:us-east-1:123456789012:function:AddressFinder",
               "End": true
             }
           }
         },
         {
           "StartAt": "LookupPhone",
           "States": {
             "LookupPhone": {
               "Type": "Task",
               "Resource": "arn:aws:lambda:us-east-1:123456789012:function:PhoneFinder",
               "End": true
             }
           }
         }
        ]
      }
    }
  }

Fichier YAML des workflows

  main:
     params: [args]
     steps:
     - init:
         assign:
         - workflow_id: "lookupAddress"
         - customer_to_lookup:
             - address: ${args.customerId}
             - phone: ${args.customerId}
         - addressed: ["", ""] # to write to this variable, you must share it
     - parallel_address:
         parallel:
             shared: [addressed]
             for:
                 in: ${customer_to_lookup}
                 index: i # optional, use if index is required
                 value: arg
                 steps:
                 - address:
                     call: googleapis.workflowexecutions.v1.projects.locations.workflows.executions.run
                     args:
                         workflow_id: ${workflow_id}
                         argument: ${arg}
                     result: r
                 - set_result:
                     assign:
                     - addressed[i]: ${r}
     - return:
             return: ${addressed}

JSON des workflows

  {
    "main": {
      "params": [
        "args"
      ],
      "steps": [
        {
          "init": {
            "assign": [
              {
                "workflow_id": "lookupAddress"
              },
              {
                "customer_to_lookup": [
                  {
                    "address": "${args.customerId}"
                  },
                  {
                    "phone": "${args.customerId}"
                  }
                ]
              },
              {
                "addressed": [
                  "",
                  ""
                ]
              }
            ]
          }
        },
        {
          "parallel_address": {
            "parallel": {
              "shared": [
                "addressed"
              ],
              "for": {
                "in": "${customer_to_lookup}",
                "index": "i",
                "value": "arg",
                "steps": [
                  {
                    "address": {
                      "call": "googleapis.workflowexecutions.v1.projects.locations.workflows.executions.run",
                      "args": {
                        "workflow_id": "${workflow_id}",
                        "argument": "${arg}"
                      },
                      "result": "r"
                    }
                  },
                  {
                    "set_result": {
                      "assign": [
                        {
                          "addressed[i]": "${r}"
                        }
                      ]
                    }
                  }
                ]
              }
            }
          }
        },
        {
          "return": {
            "return": "${addressed}"
          }
        }
      ]
    }
  }

Pass

Un état Pass transmet son entrée à sa sortie, sans effectuer de travail. Cette méthode est couramment utilisée pour manipuler les données d'état dans le fichier JSON.

Comme Workflows ne transmet pas de données de cette manière, vous pouvez laisser l'état sans action ou utiliser une étape d'attribution pour modifier les variables. Pour en savoir plus, consultez Attribuez des variables.

Fonctions d'étape

  "No-op": {
    "Type": "Pass",
    "Result": {
      "x-datum": 0.38,
      "y-datum": 622.22
    },
    "ResultPath": "$.coords",
    "Next": "End"
  }

Fichier YAML des workflows

  assign:
      - number: 5
      - number_plus_one: ${number+1}
      - other_number: 10
      - string: "hello"

JSON Workflows

  {
    "assign": [
      {
        "number": 5
      },
      {
        "number_plus_one": "${number+1}"
      },
      {
        "other_number": 10
      },
      {
        "string": "hello"
      }
    ]
  }

Réussite

Un état Succeed arrête une exécution.

Dans Workflows, vous pouvez utiliser return dans le workflow principal pour arrêter l'exécution d'un workflow. Vous pouvez également terminer un workflow en suivant la dernière étape (en supposant que l'étape ne passe pas à une autre), ou vous pouvez utiliser next: end pour arrêter l'exécution d'un workflow si vous n'avez pas besoin de renvoyer de valeur. Pour en savoir plus, consultez la section Achever l'exécution d'un workflow.

Fonctions en escalier

  "SuccessState": {
    "Type": "Succeed"
  }

Fichier YAML des workflows

  return: "Success!"
  next: end

JSON Workflows

  {
    "return": "Success!",
    "next": "end"
  }

Task

Un état Task représente une seule unité de travail effectuée par une machine à états. Dans l'exemple Step Functions suivant, il appelle une fonction Lambda. (Les activités sont une fonctionnalité AWS Step Functions qui vous permet d'avoir une tâche dans votre machine à états où le travail est effectué ailleurs.)

Dans l'exemple Workflows, est effectué sur un point de terminaison HTTP pour appeler fonction Cloud Run. Vous pouvez également utiliser un connecteur qui permet d'accéder facilement à d'autres produits Google Cloud. Vous pouvez également mettre en pause un workflow et interroger les données. Ou vous : peuvent utiliser un point de terminaison de rappel ; pour signaler à votre workflow qu'un événement spécifié s'est produit et attendre qu'il sans interrogation.

Fonctions d'étape

  "HelloWorld": {
    "Type": "Task",
    "Resource": "arn:aws:lambda:us-east-1:123456789012:function:HelloFunction",
    "End": true
  }

Fichier YAML des workflows

  - HelloWorld:
      call: http.get
      args:
          url: https://REGION-PROJECT_ID.cloudfunctions.net/helloworld
      result: helloworld_result

JSON Workflows

  [
    {
      "HelloWorld": {
        "call": "http.get",
        "args": {
          "url": "https://REGION-PROJECT_ID.cloudfunctions.net/helloworld"
        },
        "result": "helloworld_result"
      }
    }
  ]

Wait

Un état Wait empêche la machine d'état de continuer pendant une durée spécifiée.

Vous pouvez utiliser la fonction de bibliothèque standard sys.sleep de Workflows pour suspendre l'exécution du nombre de secondes spécifié à un maximum de 3 153 6000 (un an).

Fonctions d'étape

  "wait_ten_seconds" : {
    "Type" : "Wait",
    "Seconds" : 10,
    "Next": "NextState"
  }

Fichier YAML des workflows

  - someSleep:
      call: sys.sleep
      args:
          seconds: 10

JSON Workflows

  [
    {
      "someSleep": {
        "call": "sys.sleep",
        "args": {
          "seconds": 10
        }
      }
    }
  ]

Exemple : Orchestration de microservices

L'exemple de fonction Step suivant vérifie le cours d'une action, détermine s'il faut d'acheter ou de vendre, et rend compte du résultat. La machine à états de l'exemple s'intègre à AWS Lambda en transmettant des paramètres, utilise une file d'attente Amazon SQS pour demander une approbation humaine et utilise un sujet Amazon SNS pour renvoyer les résultats de la requête.

{
      "StartAt": "Check Stock Price",
      "Comment": "An example of integrating Lambda functions in Step Functions state machine",
      "States": {
          "Check Stock Price": {
              "Type": "Task",
              "Resource": "CHECK_STOCK_PRICE_LAMBDA_ARN",
              "Next": "Generate Buy/Sell recommendation"
          },
          "Generate Buy/Sell recommendation": {
              "Type": "Task",
              "Resource": "GENERATE_BUY_SELL_RECOMMENDATION_LAMBDA_ARN",
              "ResultPath": "$.recommended_type",
              "Next": "Request Human Approval"
          },
          "Request Human Approval": {
              "Type": "Task",
              "Resource": "arn:PARTITION:states:::sqs:sendMessage.waitForTaskToken",
              "Parameters": {
                  "QueueUrl": "REQUEST_HUMAN_APPROVAL_SQS_URL",
                  "MessageBody": {
                      "Input.$": "$",
                      "TaskToken.$": "$$.Task.Token"
                  }
              },
              "ResultPath": null,
              "Next": "Buy or Sell?"
          },
          "Buy or Sell?": {
              "Type": "Choice",
              "Choices": [
                  {
                      "Variable": "$.recommended_type",
                      "StringEquals": "buy",
                      "Next": "Buy Stock"
                  },
                  {
                      "Variable": "$.recommended_type",
                      "StringEquals": "sell",
                      "Next": "Sell Stock"
                  }
              ]
          },
          "Buy Stock": {
              "Type": "Task",
              "Resource": "BUY_STOCK_LAMBDA_ARN",
              "Next": "Report Result"
          },
          "Sell Stock": {
              "Type": "Task",
              "Resource": "SELL_STOCK_LAMBDA_ARN",
              "Next": "Report Result"
          },
          "Report Result": {
              "Type": "Task",
              "Resource": "arn:PARTITION:states:::sns:publish",
              "Parameters": {
                  "TopicArn": "REPORT_RESULT_SNS_TOPIC_ARN",
                  "Message": {
                      "Input.$": "$"
                  }
              },
              "End": true
          }
      }
  }

Migrer vers Workflows

Pour migrer l'exemple Step Functions précédent vers Workflows, vous pouvez créer les étapes Workflows équivalentes en intégrant des fonctions Cloud Run, en prenant en charge un point de terminaison de rappel qui attend que les requêtes HTTP arrivent à ce point de terminaison, et en utilisant un connecteur Workflows pour publier sur un sujet Pub/Sub à la place du sujet Amazon SNS :

  1. Suivez les étapes de création d'un workflow. mais ne la déployez pas tout de suite.

  2. Dans la définition du workflow, ajoutez une étape permettant de créer un point de terminaison de rappel qui attend une entrée humaine et une étape qui utilise un connecteur Workflows pour publier sur un sujet Pub/Sub. Exemple :

    Fichier YAML des workflows

      ---
      main:
        steps:
          - init:
              assign:
                - projectId: '${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}'
                - region: LOCATION
                - topic: PUBSUB_TOPIC_NAME
          - Check Stock Price:
              call: http.get
              args:
                url: ${"https://" + region + "-" + projectId + ".cloudfunctions.net/CheckStockPrice"}
                auth:
                  type: OIDC
              result: stockPriceResponse
          - Generate Buy/Sell Recommendation:
              call: http.get
              args:
                url: ${"https://" + region + "-" + projectId + ".cloudfunctions.net/BuySellRecommend"}
                auth:
                  type: OIDC
                query:
                  price: ${stockPriceResponse.body.stock_price}
              result: recommendResponse
          - Create Approval Callback:
              call: events.create_callback_endpoint
              args:
                  http_callback_method: "GET"
              result: callback_details
          - Print Approval Callback Details:
              call: sys.log
              args:
                  severity: "INFO"
                  text: ${"Listening for callbacks on " + callback_details.url}
          - Await Approval Callback:
              call: events.await_callback
              args:
                  callback: ${callback_details}
                  timeout: 3600
              result: approvalResponse
          - Approval?:
              try:
                switch:
                  - condition: ${approvalResponse.http_request.query.response[0] == "yes"}
                    next: Buy or Sell?
              except:
                as: e
                steps:
                  - unknown_response:
                      raise: ${"Unknown response:" + e.message}
                      next: end
          - Buy or Sell?:
              switch:
                - condition: ${recommendResponse.body == "buy"}
                  next: Buy Stock
                - condition: ${recommendResponse.body == "sell"}
                  next: Sell Stock
                - condition: true
                  raise: ${"Unknown recommendation:" + recommendResponse.body}
          - Buy Stock:
              call: http.post
              args:
                url: ${"https://" + region + "-" + projectId + ".cloudfunctions.net/BuyStock"}
                auth:
                  type: OIDC
                body:
                  action: ${recommendResponse.body}
              result: message
          - Sell Stock:
              call: http.post
              args:
                url: ${"https://" + region + "-" + projectId + ".cloudfunctions.net/SellStock"}
                auth:
                  type: OIDC
                body:
                  action: ${recommendResponse.body}
              result: message
          - Report Result:
              call: googleapis.pubsub.v1.projects.topics.publish
              args:
                topic: ${"projects/" + projectId + "/topics/" + topic}
                body:
                  messages:
                  - data: '${base64.encode(json.encode(message))}'
              next: end
      ...

    JSON Workflows

      {
        "main": {
          "steps": [
            {
              "init": {
                "assign": [
                  {
                    "projectId": "${sys.get_env(\"GOOGLE_CLOUD_PROJECT_ID\")}"
                  },
                  {
                    "region": "LOCATION"
                  },
                  {
                    "topic": [
                      "PUBSUB_TOPIC_NAME"
                    ]
                  }
                ]
              }
            },
            {
              "Check Stock Price": {
                "call": "http.get",
                "args": {
                  "url": "${\"https://\" + region + \"-\" + projectId + \".cloudfunctions.net/CheckStockPrice\"}",
                  "auth": {
                    "type": "OIDC"
                  }
                },
                "result": "stockPriceResponse"
              }
            },
            {
              "Generate Buy/Sell Recommendation": {
                "call": "http.get",
                "args": {
                  "url": "${\"https://\" + region + \"-\" + projectId + \".cloudfunctions.net/BuySellRecommend\"}",
                  "auth": {
                    "type": "OIDC"
                  },
                  "query": {
                    "price": "${stockPriceResponse.body.stock_price}"
                  }
                },
                "result": "recommendResponse"
              }
            },
            {
              "Create Approval Callback": {
                "call": "events.create_callback_endpoint",
                "args": {
                  "http_callback_method": "GET"
                },
                "result": "callback_details"
              }
            },
            {
              "Print Approval Callback Details": {
                "call": "sys.log",
                "args": {
                  "severity": "INFO",
                  "text": "${\"Listening for callbacks on \" + callback_details.url}"
                }
              }
            },
            {
              "Await Approval Callback": {
                "call": "events.await_callback",
                "args": {
                  "callback": "${callback_details}",
                  "timeout": 3600
                },
                "result": "approvalResponse"
              }
            },
            {
              "Approval?": {
                "try": {
                  "switch": [
                    {
                      "condition": "${approvalResponse.http_request.query.response[0] == \"yes\"}",
                      "next": "Buy or Sell?"
                    }
                  ]
                },
                "except": {
                  "as": "e",
                  "steps": [
                    {
                      "unknown_response": {
                        "raise": "${\"Unknown response:\" + e.message}",
                        "next": "end"
                      }
                    }
                  ]
                }
              }
            },
            {
              "Buy or Sell?": {
                "switch": [
                  {
                    "condition": "${recommendResponse.body == \"buy\"}",
                    "next": "Buy Stock"
                  },
                  {
                    "condition": "${recommendResponse.body == \"sell\"}",
                    "next": "Sell Stock"
                  },
                  {
                    "condition": true,
                    "raise": "${\"Unknown recommendation:\" + recommendResponse.body}"
                  }
                ]
              }
            },
            {
              "Buy Stock": {
                "call": "http.post",
                "args": {
                  "url": "${\"https://\" + region + \"-\" + projectId + \".cloudfunctions.net/BuyStock\"}",
                  "auth": {
                    "type": "OIDC"
                  },
                  "body": {
                    "action": "${recommendResponse.body}"
                  }
                },
                "result": "message"
              }
            },
            {
              "Sell Stock": {
                "call": "http.post",
                "args": {
                  "url": "${\"https://\" + region + \"-\" + projectId + \".cloudfunctions.net/SellStock\"}",
                  "auth": {
                    "type": "OIDC"
                  },
                  "body": {
                    "action": "${recommendResponse.body}"
                  }
                },
                "result": "message"
              }
            },
            {
              "Report Result": {
                "call": "googleapis.pubsub.v1.projects.topics.publish",
                "args": {
                  "topic": "${\"projects/\" + projectId + \"/topics/\" + topic}",
                  "body": {
                    "messages": [
                      {
                        "data": "${base64.encode(json.encode(message))}"
                      }
                    ]
                  }
                },
                "next": "end"
              }
            }
          ]
        }
      }

    Remplacez les éléments suivants :

    • LOCATION: région Google Cloud compatible Par exemple, us-central1.
    • PUBSUB_TOPIC_NAME: nom de votre instance Pub/Sub sur un sujet. Exemple :my_stock_example
  3. Déployez, puis exécutez le workflow.

  4. Pendant l'exécution du workflow, il se met en pause et attend que vous appeliez le point de terminaison de rappel. Pour ce faire, vous pouvez utiliser une commande curl. Exemple :

    curl -H "Authorization: Bearer $(gcloud auth print-access-token)"
    https://workflowexecutions.googleapis.com/v1/projects/CALLBACK_URL?response=yes
    

    Remplacez CALLBACK_URL par le reste des vers le point de terminaison de votre rappel.

  5. Une fois le workflow terminé, vous pouvez recevoir le message de l'abonnement Pub/Sub. Exemple :

    gcloud pubsub subscriptions pull stock_example-sub  --format="value(message.data)" | jq
    

    Le message de sortie doit ressembler à ce qui suit (buy ou sell):

    {
      "body": "buy",
      "code": 200,
      "headers": {
      [...]
      }
    

Étape suivante