Von AWS Step Functions zu Workflows migrieren

Auf dieser Seite werden wichtige Ähnlichkeiten und Unterschiede zwischen den beiden Produkten erläutert, um Sie bei der Vorbereitung der Migration von den Step Functions-Funktionen von Amazon Web Services (AWS) zu Workflows in Google Cloud zu unterstützen. Die folgenden Informationen sollen Nutzern helfen, die bereits mit Step Functions vertraut sind, eine ähnliche Architektur mithilfe von Workflows zu implementieren.

Wie bei Step Functions ist auch Workflows eine vollständig verwaltete, zustandsbasierte Orchestrierungsplattform, die Dienste in einer von Ihnen definierten Reihenfolge ausführt: ein Workflow. In diesen Workflows können Dienste kombiniert werden, darunter benutzerdefinierte Dienste, die in Cloud Run oder Cloud Functions gehostet werden, Google Cloud-Dienste wie Cloud Vision AI und BigQuery sowie jede HTTP-basierte API.

Beachten Sie, dass Step Functions Express-Workflows ein AWS Step Functions-Workflowtyp ist, der hier nicht berücksichtigt wird, da die Dauer eines Express-Workflows begrenzt ist und eine genau einmalige Ausführung von Workflows nicht unterstützt wird.

Hello World

In „Step Functions“ ist ein Zustandsautomat 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 in einer Reihe von Schritten mit der Workflows-Syntax beschrieben. Workflows behandeln Schritte wie in einer geordneten Liste und führen sie nacheinander aus, bis alle Schritte ausgeführt wurden.

Das folgende „Hello World“-Beispiel zeigt die Verwendung von Status in Step Functions und Schritten in Workflows:

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 ausführlicher verglichen.

SchrittfunktionenWorkflows
SyntaxJSON (YAML in Tools) YAML oder JSON
Ablauf steuernÜbergang zwischen Bundesstaaten Imperative Ablaufsteuerung mit Schritten
ArbeiterRessourcen (ARN) HTTP-Anfragen und Connectors
ZuverlässigkeitFangen/Wiederholen Fangen/Wiederholen
ParallelitätUnterstützt Unterstützt
StatusdatenStatus wird übergeben Workflowvariablen
AuthentifizierungIAM IAM
Auswirkungen für NutzerWorkflow Studio, Befehlszeile, SDK, IaC Google Cloud Console, Befehlszeile, SDK, IaC
Preise Step Functions-Preise Preise für Workflows
Syntax

Step Functions verwendet hauptsächlich JSON zum Definieren von Funktionen und unterstützt YAML nicht direkt. 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 Workflows-Schritte mit der Workflows-Syntax beschreiben. Diese können entweder in YAML oder JSON geschrieben werden. Die meisten Workflows werden in YAML ausgeführt. Die Beispiele auf dieser Seite zeigen die Vorteile von YAML, darunter Lese- und Schreibfreundlichkeit sowie die native Unterstützung von Kommentaren. Eine ausführliche Erläuterung der Workflow-Syntax finden Sie in der Syntaxreferenz.

Ablaufsteuerung

Sowohl Workflows als auch Step Functions modellieren Workflows als eine Reihe von Aufgaben: Schritte in Workflows und Status in Schrittfunktionen. Beide ermöglichen eine Aufgabe, anzugeben, welche Aufgabe als Nächstes ausgeführt werden soll, und unterstützen wechselähnliche Bedingungen, um die nächste Arbeitseinheit basierend auf dem aktuellen Status auszuwählen. Ein wesentlicher Unterschied besteht darin, dass bei Schrittfunktionen jeder Status erforderlich ist, um den nächsten zu definieren, während Workflows dagegen Schritte in der angegebenen Reihenfolge ausführt (einschließlich alternativer nächsten Schritte). Weitere Informationen finden Sie unter Bedingungen und Schritte.

Worker

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

Workflows können HTTP-Anfragen an einen beliebigen HTTP-Endpunkt senden und eine Antwort erhalten. Connectors erleichtern das Herstellen einer Verbindung zu anderen Google Cloud APIs innerhalb eines Workflows und die Integration Ihrer Workflows in andere Google Cloud-Produkte wie Pub/Sub, BigQuery oder Cloud Build. Connectors vereinfachen das Aufrufen von Diensten, da sie die Formatierung von Anfragen für Sie verarbeiten und Methoden und Argumente bereitstellen, sodass Sie die Details einer Google Cloud API nicht kennen müssen. Sie können auch die Zeitüberschreitungs- und Abfragerichtlinien konfigurieren.

Zuverlässigkeit

Wenn eine Aufgabe fehlschlägt, muss der Workflow in der Lage sein, entsprechende Wiederholungen auszuführen, bei Bedarf Ausnahmen abzufangen und den Workflow nach Bedarf umzuleiten. Sowohl die Schrittfunktionen als auch die Workflows erreichen Zuverlässigkeit durch ähnliche Mechanismen: das Abfangen von Ausnahmen bei Wiederholungsversuchen und die 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 orchestriert. Step Functions bietet zwei Möglichkeiten, dies zu erreichen: Sie können ein Datenelement parallel an mehrere verschiedene Aufgaben übergeben oder Sie können ein Array verwenden und seine Elemente an dieselbe Aufgabe übergeben.

In Workflows können Sie einen Teil Ihres Workflows definieren, in dem zwei oder mehr Schritte gleichzeitig ausgeführt werden können. Sie können entweder Zweige 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 für Sie verwaltet werden. In Step Functions werden die Statusdaten in einer JSON-Struktur von einem Status in einen anderen übergeben.

In Workflows können Sie die Statusdaten in globalen Variablen speichern. Da die Ausführungsdauer maximal ein Jahr beträgt, können Sie die Statusdaten so lange beibehalten, wie die Instanz noch ausgeführt wird.

Authentifizierung

Beide Produkte basieren auf einem zugrunde liegenden Identity and Access Management-System (IAM) zur Authentifizierung und Zugriffssteuerung. Sie können beispielsweise eine IAM-Rolle verwenden, um Step Functions-Funktionen aufzurufen.

In Workflows können Sie ein Dienstkonto verwenden, um einen Workflow aufzurufen. Sie können mithilfe von OAuth 2.0 oder OIDC eine Verbindung zu Google Cloud APIs herstellen und einen Autorisierungsanfrageheader zur Authentifizierung bei einer Drittanbieter-API verwenden. Weitere Informationen finden Sie unter Workflowberechtigung für den Zugriff auf Google Cloud-Ressourcen gewähren und Authentifizierte Anfragen von einem Workflow aus senden.

Nutzer

Sie können ein Befehlszeilentool oder Infrastruktur als Code (IaC) wie Terraform verwenden, um sowohl Schrittfunktionen als auch Workflows zu definieren und zu verwalten.

Darüber hinaus unterstützt Workflows die Ausführung von Workflows mithilfe der 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 finden Sie auf den entsprechenden Preisseiten: Step Functions-Preise und Preise für Workflows.

Statustypen den Schritten zuordnen

Es gibt acht Statustypen in Schrittfunktionen. Status sind Elemente in einem Zustandsautomaten, die Entscheidungen auf der Grundlage ihrer Eingabe treffen, Aktionen ausführen und Ausgaben an andere Zustände übergeben können. Bevor Sie von Schrittfunktionen zu Workflows migrieren, sollten Sie wissen, wie jeder Statustyp in einen Workflowschritt übersetzt wird.

Choice

Mit dem Status Choice wird einem Zustandsautomaten eine Verzweigungslogik hinzugefügt.

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 benutzerdefinierte Fehler mit der Syntax raise auslösen und Fehler mit einem try/except-Block erfassen und beheben. Weitere Informationen finden Sie unter Fehler auslösen.

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 dem Status Map kann eine Reihe von Schritten für jedes Element eines Eingabearrays ausgeführt werden.

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 parallele Ausführungszweige auf der Zustandsmaschine erstellt werden. Im folgenden Step Functions-Beispiel wird eine Adresse 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 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

Ein Pass-Zustand übergibt seine Eingabe an seine Ausgabe, ohne Änderungen auszuführen. Dies wird häufig verwendet, um die Statusdaten im JSON-Format zu bearbeiten.

Da Workflows Daten nicht auf diese Weise übergeben, können Sie den Status als Nullvorgang belassen oder einen Zuweisungsschritt verwenden, um die Variablen zu ändern. 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

Der Status Succeed beendet eine Ausführung erfolgreich.

In Workflows können Sie im Hauptworkflow return verwenden, um die Ausführung eines Workflows zu beenden. Sie können einen Workflow auch beenden, indem Sie den letzten Schritt abschließen (vorausgesetzt, der Schritt springt nicht zu einem anderen). Alternativ können Sie die Ausführung eines Workflows mit next: end 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. Im folgenden Step Functions-Beispiel wird eine Lambda-Funktion aufgerufen. Aktivitäten sind ein AWS Step Functions-Feature, mit dem Sie eine Aufgabe auf Ihrem Zustandscomputer haben können, wenn die Arbeit an anderer Stelle ausgeführt wird.

Im Workflow-Beispiel erfolgt ein Aufruf an einen HTTP-Endpunkt, um eine Cloud Function aufzurufen. Sie können auch einen Connector verwenden, der einfachen Zugriff auf andere Google Cloud-Produkte ermöglicht. Außerdem können Sie einen Workflow pausieren und Daten abfragen. Alternativ können Sie einen Callback-Endpunkt verwenden, um Ihrem Workflow zu signalisieren, dass ein bestimmtes Ereignis aufgetreten ist, und ohne Abfrage auf dieses Ereignis zu warten.

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, dass die Zustandsmaschine für eine bestimmte Zeit fortgesetzt wird.

Sie können die Standardbibliotheksfunktion von Workflows sys.sleep verwenden, um die Ausführung für die angegebene Anzahl von Sekunden bis zu maximal 3.153.6000 (ein Jahr) zu sperren.

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

Das folgende Step Functions-Beispiel prüft einen Aktienkurs, bestimmt, ob etwas gekauft oder verkauft wird, und meldet das Ergebnis. Die Zustandsmaschine im Beispiel wird in AWS Lambda integriert, indem Parameter übergibt, eine Amazon SQS-Warteschlange verwendet, um menschliche Genehmigung anzufordern, und ein Amazon SNS-Thema verwendet, 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

Wenn Sie das vorherige Schritt-für-Schritt-Beispiel zu Workflows migrieren möchten, können Sie die entsprechenden Workflows-Schritte erstellen. Dazu binden Sie Cloud Functions ein, unterstützen einen Callback-Endpunkt, der auf HTTP-Anfragen an diesem Endpunkt wartet, und einen Workflow-Connector zur Veröffentlichung in einem Pub/Sub-Thema anstelle des Amazon SNS-Themas:

  1. Führen Sie die Schritte zum Erstellen eines Workflows aus, stellen Sie ihn jedoch noch nicht bereit.

  2. Fügen Sie der Workflowdefinition einen Schritt hinzu, um einen Callback-Endpunkt zu erstellen, der auf menschliche Eingaben wartet, und einen Schritt, der einen Workflows-Connector zum Veröffentlichen in einem Pub/Sub-Thema verwendet. 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-Themas. 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 der Workflow pausiert und Sie wartet, bis Sie den Callback-Endpunkt aufrufen. Sie können dazu 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 des Pfads zu Ihrem Callback-Endpunkt.

  5. Wenn der Workflow erfolgreich abgeschlossen wurde, können Sie die Nachricht vom Pub/Sub-Abo empfangen. Beispiel:

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

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

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

Nächste Schritte