Von AWS Step Functions zu Workflows migrieren

Auf dieser Seite werden die wichtigsten Gemeinsamkeiten und Unterschiede zwischen den beiden Produkten erläutert, damit Sie sich auf die Migration von AWS-Schrittfunktionen (Amazon Web Services) zu Workflows in Google Cloud vorbereiten können. Diese Informationen sollen Nutzern helfen, die bereits mit Step Functions vertraut sind, eine ähnliche Architektur mit Workflows zu implementieren.

Ähnlich wie Step Functions ist Workflows eine vollständig verwaltete, zustandsbasierte Orchestrierungsplattform, die Dienste in einer von Ihnen definierten Reihenfolge ausführt: einem Workflow. Diese Workflows können Dienste kombinieren, einschließlich benutzerdefinierter Dienste, die in Cloud Run oder Cloud Run-Funktionen gehostet werden, Google Cloud-Diensten wie Cloud Vision AI und BigQuery und einer beliebigen HTTP-basierten API.

Express-Workflows sind ein Workflowtyp von AWS Step Functions, der hier nicht berücksichtigt wird, da die Dauer eines Express-Workflows begrenzt ist und eine Workflowausführung genau einmal nicht unterstützt wird.

Hello World

In "Step Functions" ist eine Zustandsmaschine ein Workflow und eine Aufgabe ein Status in einem Workflow, der eine einzelne Arbeitseinheit darstellt, die ein anderer AWS-Dienst ausführt. Bei Schrittfunktionen muss jeder Status den nächsten Status definieren.

In Workflows werden die auszuführenden Aufgaben durch eine Reihe von Schritten mit der Workflow-Syntax beschrieben. Workflows behandeln Schritte als wenn sie sich in einer geordneten Liste befinden, und führt sie nacheinander aus, bis alle Schritte ausgeführt wurden.

Im folgenden „Hallo Welt“-Beispiel wird die Verwendung von Zuständen in Schrittfunktionen und Schritten in Workflows veranschaulicht:

Schrittfunktionen

  {
    "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
      }
    }
  }

YAML-Datei für Workflows

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

Workflows-JSON

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

Vergleich – Übersicht

In diesem Abschnitt werden die beiden Produkte genauer verglichen.

SchrittfunktionenWorkflows
SyntaxJSON (YAML in Tools) YAML oder JSON
AblaufsteuerungStatuswechsel Imperative Ablaufsteuerung mit Schritten
MitarbeiterRessourcen (ARN) HTTP-Anfragen und -Connectors
ZuverlässigkeitFangen/wiederholen Fangen/wiederholen
ParallelitätUnterstützt Unterstützt
StatusdatenStatus wird weitergegeben Workflow-Variablen
AuthentifizierungIAM IAM
Auswirkungen für NutzerWorkflow Studio, CLI, SDK, IaC Google Cloud Console, Befehlszeile, SDK, IaC
Preise Preise für Step Functions Preise für Workflows
Syntax

In Step Functions werden Funktionen hauptsächlich mit JSON definiert und YAML wird nicht direkt unterstützt. Im AWS Toolkit für Visual Studio Code und in AWS CloudFormation können Sie jedoch YAML für eine Step Functions-Definition verwenden.

Sie können Schritte in Workflows mithilfe der und können entweder in YAML oder JSON geschrieben werden. Die Mehrheit der Workflows sind in YAML. Die Beispiele auf dieser Seite zeigen die Vorteile auf, von YAML, einschließlich leichter Lese- und Schreibzugriff, und nativer Unterstützung von Kommentaren. Eine ausführliche Erläuterung der Workflows-Syntax finden Sie in der Syntaxreferenz.

Ablauf steuern

Sowohl Workflows als auch Step Functions modellieren Workflows als eine Reihe von Aufgaben: Schritte in Workflows und Zustände in Step Functions. Beide ermöglichen eine Aufgabe, um anzugeben, welche Aufgabe als Nächstes ausgeführt werden soll, und unterstützen schalterähnliche Aufgaben Bedingungen, um die nächste Arbeitseinheit basierend auf dem aktuellen Status auszuwählen. Ein wichtiger Unterschied besteht darin, dass bei Step Functions jeder Status den nächsten definiert, während bei Workflows die Schritte in der Reihenfolge ausgeführt werden, in der sie angegeben sind (einschließlich alternativer nächster Schritte). Weitere Informationen finden Sie unter Voraussetzungen und Schritte.

Worker

Beide Produkte orchestrieren Rechenressourcen wie Funktionen, Container und andere Webdienste nutzen, um Aufgaben zu erledigen. In Step Functions wird der Worker durch ein Resource-Feld identifiziert, das syntaktisch ein URI ist. Die URIs, mit denen Worker-Ressourcen im Amazon Resource Name-Format (ARN) vorliegen und Nutzer kann einen beliebigen HTTP-Endpunkt nicht direkt aufrufen.

Workflows können HTTP-Anfragen an einen beliebigen HTTP-Endpunkt senden und eine Antwort erhalten. Mithilfe von Connectors können Sie eine Verbindung zu anderen Google Cloud APIs in einem Workflow herstellen und Ihre Workflows in andere Google Cloud-Produkte wie Pub/Sub, BigQuery oder Cloud Build integrieren. Anschlüsse das Anrufen von Diensten zu vereinfachen, da sie die Formatierung von Anfragen für Sie übernehmen. Methoden und Argumente, sodass Sie die Details einer Google Cloud API Sie können auch die Zeitüberschreitung und die Abfragerichtlinien konfigurieren.

Zuverlässigkeit

Wenn eine Aufgabe fehlschlägt, muss Ihr Workflow in der Lage sein, den Vorgang entsprechend zu wiederholen. und den Workflow bei Bedarf umleiten. Sowohl Schrittfunktionen als auch Workflows erreichen mit ähnlichen Mechanismen Zuverlässigkeit: Ausnahmebehandlung mit Wiederholungen und eventuelle Weiterleitung an eine andere Stelle im Workflow. Weitere Informationen finden Sie unter Workflowfehler.

Parallelität

Möglicherweise möchten Sie, dass Ihr Workflow mehrere Aufgaben parallel ausführt. Schritt Functions bietet zwei Möglichkeiten, dies zu erreichen: Sie können ein Datenelement verwenden und mehreren verschiedenen Aufgaben gleichzeitig auszuführen. Oder Sie verwenden ein Array und übergeben einer Aufgabe zuordnen.

In Workflows können Sie einen Teil Ihres Workflows definieren, können zwei oder mehr Schritte gleichzeitig ausgeführt werden. Sie können entweder Äste definieren, die gleichzeitig ausgeführt werden, oder eine Schleife, in der Iterationen gleichzeitig ausgeführt werden. Weitere Informationen finden Sie unter Workflowschritte parallel ausführen.

Statusdaten

Ein Vorteil einer Workflow-Engine besteht darin, dass Statusdaten ohne externen Datenspeicher verwaltet werden. In „Step Functions“ werden die Statusdaten in einer JSON-Struktur von einem Zustand zum anderen wechseln.

In Workflows können Sie die Statusdaten in globalen Variablen. Da die Ausführungsdauer bis zu einem Jahr betragen darf, können Sie die Statusdaten so lange aufbewahren, wie die Instanz noch ausgeführt wird.

Authentifizierung

Beide Produkte nutzen für die Authentifizierung und Zugriffssteuerung ein untergeordnetes IAM-System (Identity and Access Management). Mit einer IAM-Rolle können Sie beispielsweise Schrittfunktionen aufrufen

In Workflows können Sie mit einem Dienstkonto eine workflow; können Sie OAuth 2.0 oder OIDC verwenden, um eine Verbindung zu Google Cloud herzustellen. APIs und Sie können einen Autorisierungs-Anfrage-Header für die Authentifizierung bei eine Drittanbieter-API. Weitere Informationen finden Sie unter Zugriff auf Google Cloud-Ressourcen für einen Workflow gewähren und Authentifizierte Anfragen von einem Workflow aus ausführen.

Nutzer

Sie können ein Befehlszeilentool oder ein IaC-Tool (Infrastructure as Code) wie Terraform verwenden, um sowohl Step Functions als auch Workflows zu definieren und zu verwalten.

Darüber hinaus unterstützt Workflows die Ausführung von Workflows mit den Clientbibliotheken, in der Google Cloud Console, mit der Google Cloud CLI, oder durch Senden einer Anfrage an die Workflows REST API. Weitere Informationen finden Sie unter Workflow ausführen.

Preise

Beide Produkte haben eine kostenlose Stufe. Weitere Informationen findest du in den jeweiligen Preisen. Seiten: Preise für Schrittfunktionen und Preise für Workflows.

Statustypen zu Schritten zuordnen

In Schrittfunktionen gibt es acht Statustypen. Stadien sind Elemente eines Zustands Maschine, die Entscheidungen auf der Grundlage ihrer Eingaben treffen, Aktionen ausführen und in andere Bundesstaaten. Vor der Migration von "Step Functions" zu wie Sie die einzelnen Workflows zu einem Workflow-Schritt hinzufügen.

Choice

Ein Choice-Zustand fügt einer Zustandsmaschine eine Verzweigungslogik hinzu.

In Workflows können Sie einen switch-Block als Auswahlmechanismus verwenden, mit dem der Wert eines Ausdrucks den Ablauf der Ausführung eines Workflows steuern kann. Wenn ein Wert übereinstimmt, wird die Anweisung dieser Bedingung ausgeführt. Weitere Informationen finden Sie unter Bedingungen.

Schrittfunktionen

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

YAML-Datei für Workflows

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

Workflows JSON

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

Fail

Der Status Fail stoppt die Ausführung des Zustandsautomaten und markiert ihn als Fehler.

In Workflows können Sie mit dem raise benutzerdefinierte Fehler auslösen Syntax und Sie können Fehler mithilfe eines try/except-Blocks abfangen und beheben. Für Weitere Informationen finden Sie unter Fehler ausgeben.

Schrittfunktionen

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

YAML-Datei für Workflows

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

Workflows JSON

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

Map

Mit einem Map-Zustand können Sie eine Reihe von Schritten für jedes Element eines Eingabearrays ausführen.

In Workflows können Sie for-Schleifen für Iterationen verwenden.

Schrittfunktionen

  { "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
      }
    }
  }

YAML-Datei für 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}

Workflows-JSON

  [
    {
      "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

Mit dem Status Parallel können Sie parallele Ausführungszweige in Ihrem Zustandsautomat. Im folgenden Step Functions-Beispiel werden eine Adressen- und eine Telefonnummernsuche parallel ausgeführt.

In Workflows können Sie mit einem parallel-Schritt einen Teil Ihres Workflows definieren, in dem zwei oder mehr Schritte gleichzeitig ausgeführt werden können. Weitere Informationen Weitere Informationen finden Sie unter Parallele Schritte.

Schrittfunktionen

  { "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
             }
           }
         }
        ]
      }
    }
  }

YAML-Datei für 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}

Workflows JSON

  {
    "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

Im Status Pass wird die Eingabe an die Ausgabe übergeben, ohne dass eine Arbeit ausgeführt wird. Dies ist die häufig zur Bearbeitung der Statusdaten im JSON-Format verwendet werden.

Da Workflows Daten nicht auf diese Weise weitergeben, können Sie Belassen Sie den Zustand als No-Op oder ändern Sie mit einem Zuweisungsschritt Variablen. Weitere Informationen finden Sie unter Variablen zuweisen:

Schrittfunktionen

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

YAML-Datei für Workflows

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

Workflows JSON

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

Erfolgreich

Mit dem Status Succeed wird eine Ausführung erfolgreich beendet.

In Workflows können Sie return im Hauptworkflow verwenden, um die Ausführung eines Workflows zu beenden. Sie können einen Workflow auch beenden, (vorausgesetzt, der Schritt springt nicht zu einem anderen Schritt) oder Sie verwenden next: end, um die Ausführung eines Workflows zu beenden, wenn kein Wert zurückgegeben werden muss. Weitere Informationen finden Sie unter Ausführung eines Workflows abschließen.

Schrittfunktionen

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

YAML-Datei für Workflows

  return: "Success!"
  next: end

Workflows JSON

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

Task

Ein Task-Zustand steht für eine einzelne Arbeitseinheit, die von einem Zustandsautomaten ausgeführt wird. In im folgenden Beispiel für „Step Functions“ wird eine Lambda-Funktion aufgerufen. (Aktivitäten sind eine AWS-Schrittfunktionen-Funktion, mit der Sie eine Aufgabe in Ihrem Zustandsautomaten, wo die Arbeit an anderer Stelle ausgeführt wird.)

Im Workflow-Beispiel an einen HTTP-Endpunkt gesendet wird, um Cloud Run-Funktion. Sie können auch einen Connector verwenden, der den einfachen Zugriff auf andere Google Cloud-Produkte ermöglicht. Außerdem Sie können einen Workflow pausieren und Daten abfragen. Oder Sie kann einen Callback-Endpunkt verwenden um Ihrem Workflow zu signalisieren, dass ein bestimmtes Ereignis eingetreten ist, und warten Sie, ohne Abfragen erstellen.

Schrittfunktionen

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

YAML-Datei für Workflows

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

Workflows-JSON

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

Wait

Der Status Wait verzögert die Fortsetzung des Zustandsautomat für eine bestimmte Zeit.

Mit der Standardbibliotheksfunktion sys.sleep von Workflows können Sie die Ausführung für die angegebene Anzahl von Sekunden bis zu maximal 31.536.000 (ein Jahr) pausieren.

Schrittfunktionen

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

YAML-Datei für Workflows

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

Workflows-JSON

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

Beispiel: Mikrodienste orchestrieren

Im folgenden Beispiel für Schrittfunktionen wird ein Aktienkurs geprüft, kaufen oder verkaufen und meldet das Ergebnis. Der Statusautomat im Beispiel wird durch Übergeben von Parametern in AWS Lambda eingebunden. Er verwendet eine Amazon SQS-Warteschlange, um eine manuelle Genehmigung anzufordern, und ein Amazon SNS-Topic, um die Ergebnisse der Abfrage zurückzugeben.

{
      "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
          }
      }
  }

Zu Workflows migrieren

So migrieren Sie das vorherige Schrittfunktionen-Beispiel zu Workflows: können Sie entsprechende Workflow-Schritte erstellen, indem Sie Cloud Run-Funktionen, die eine Callback-Endpunkt, der auf HTTP-Anfragen, die an diesem Endpunkt ankommen, und die Verwendung eines Workflows Connector für die Veröffentlichung in einem Pub/Sub-Thema anstelle von Amazon SNS-Thema:

  1. Führen Sie die Schritte zum Erstellen eines Workflows aus. aber noch nicht bereitstellen.

  2. Fügen Sie in der Definition des Workflows einen Schritt zum Erstellen eines Callback-Endpunkts hinzu der auf menschliche Eingaben wartet, sowie einen Schritt, bei dem ein Workflow für die Veröffentlichung in einem Pub/Sub-Thema. Beispiel:

    YAML-Datei für 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
      ...

    Workflows JSON

      {
        "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"
              }
            }
          ]
        }
      }

    Ersetzen Sie Folgendes:

    • LOCATION: eine unterstützte Google Cloud-Region. Beispiel: us-central1
    • PUBSUB_TOPIC_NAME: der Name Ihres Pub/Sub . Beispiel: my_stock_example.
  3. Stellen Sie den Workflow bereit und führen Sie ihn dann aus.

  4. Während der Ausführung des Workflows wird eine Pause eingelegt und auf die Aufrufung des Rückruf-Endpunkts gewartet. Dazu können Sie einen curl-Befehl verwenden. Beispiel:

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

    Ersetzen Sie CALLBACK_URL durch den Rest der Pfad zu deinem Callback-Endpunkt.

  5. Sobald der Workflow abgeschlossen ist, können Sie die Nachricht über das Pub/Sub-Abo empfangen. Beispiel:

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

    Die Ausgabe sollte in etwa so aussehen (entweder buy oder sell):

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

Nächste Schritte