Esegui la migrazione da AWS Step Functions a Workflows

Per aiutarti a eseguire la migrazione dalle funzioni Step di Amazon Web Services (AWS) a Workflows su Google Cloud, questa pagina spiega le principali analogie e le differenze tra i due prodotti. Queste informazioni hanno lo scopo di aiutare per coloro che hanno già familiarità con le funzioni Step Functions utilizzando Workflows.

Come Step Functions, Workflows è un servizio completamente gestito, di orchestrazione che esegue i servizi in un ordine da te definito: una flusso di lavoro. Questi flussi di lavoro possono combinare servizi, inclusi quelli personalizzati in hosting su funzioni di Cloud Run o Cloud Run, servizi Google Cloud come Cloud Vision AI e BigQuery e qualsiasi API basata su HTTP.

Tieni presente che Step Functions Express Workflows è un flusso di lavoro di AWS Step Functions non considerato qui poiché la durata di un flusso di lavoro Express limitato e l'esecuzione "exactly-once" del flusso di lavoro non è supportata.

Hello World

In Step Functions, una macchina a stato è un flusso di lavoro e un'attività è uno stato in un che rappresenta una singola unità di lavoro eseguita da un altro servizio AWS. Step Functions richiede che ogni stato definisca quello successivo.

In Workflows, una serie di passaggi che utilizza lo strumento descrive le attività da eseguire. Workflows tratta i passaggi come se fossero in un elenco ordinato e li esegue uno alla volta finché sono stati eseguiti i passaggi.

Il seguente "Hello World" un esempio illustra l'utilizzo degli stati nel passaggio Funzioni e passaggi in Workflows:

Funzioni dei passaggi

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

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

JSON di Workflows

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

Panoramica di confronto

Questa sezione mette a confronto i due prodotti in modo più dettagliato.

Funzioni dei passaggiFlussi di lavoro
SintassiJSON (YAML negli strumenti) YAML o JSON
Flusso di controlloTransizione tra stati Controllo imperativo del flusso con passaggi
LavoratoreRisorse (ARN) Richieste e connettori HTTP
AffidabilitàCattura/riprova Cattura/riprova
ParallelismoSupportato Supportato
Dati relativi allo statoLo stato viene trasmesso Variabili di Workflows
AutenticazioneIAM IAM
Esperienza utenteWorkflow Studio, interfaccia a riga di comando, SDK, IaC Console Google Cloud, interfaccia a riga di comando, SDK, IaC
Prezzi Prezzi di Step Functions Prezzi di Workflows
Sintassi

Step Functions utilizza principalmente JSON per definire le funzioni e non supporta direttamente YAML; nel toolkit AWS per Visual Studio Code e in AWS CloudFormation, puoi usare YAML per una definizione delle funzioni passo.

Puoi descrivere i passaggi di Workflows utilizzando e possono essere scritte in formato YAML o JSON. La maggior parte dei i flussi di lavoro sono in formato YAML. Gli esempi in questa pagina dimostrano i vantaggi di YAML, tra cui la facilità di lettura e la scrittura e il supporto nativo dei commenti. Per una spiegazione dettagliata della sintassi di Workflows, consulta Riferimento per la sintassi.

Flusso di controllo

Entrambi i flussi di lavoro e le funzioni di passaggio modellano i flussi di lavoro in serie di attività: steps in Workflows e state in Step Functions. Entrambi consentono a un'attività di indicare l'attività successiva da eseguire e supportano il passaggio da un dispositivo all'altro condizionali per scegliere l'unità di lavoro successiva in base allo stato attuale. Una chiave la differenza è che le funzioni Step richiedono ogni stato per definire quello successivo, mentre Workflows esegue i passaggi nell'ordine in cui sono specificato (inclusi i passaggi successivi alternativi). Per ulteriori informazioni, vedi Condizioni e Passaggi.

Worker

Entrambi i prodotti orchestrano le risorse di calcolo come funzioni, container altri servizi web per svolgere attività. In Step Functions, il worker identificato da un campo Resource che è sintatticamente un URI. Gli URI utilizzati identificare le risorse worker in formato Amazon Resource Name (ARN) e gli utenti non può richiamare direttamente un endpoint HTTP arbitrario.

Workflows possono inviare richieste HTTP a un endpoint HTTP arbitrario e ricevere una risposta. Connettori facilitano la connessione ad altre API Google Cloud all'interno di un flusso di lavoro, e integrare i flussi di lavoro con altri prodotti Google Cloud come in Pub/Sub, BigQuery o Cloud Build. Connettori semplificare i servizi di chiamata perché gestiscono la formattazione delle richieste per te, fornendo metodi e argomenti in modo che non sia necessario conoscere i dettagli l'API Google Cloud. Puoi anche configurare timeout e polling criteri.

Affidabilità

Se un'attività non riesce, il flusso di lavoro deve essere in grado di riprovare in modo appropriato, individua le eccezioni laddove necessario e reindirizzare il flusso di lavoro in base alle esigenze. Entrambi i passaggi Functions e Workflows garantiscono affidabilità utilizzando modelli meccanismi: eccezione di rilevamento con nuovi tentativi e invio finale a altrove nel flusso di lavoro. Per ulteriori informazioni, consulta la sezione Errori del flusso di lavoro.

Parallelismo

Potresti volere che il tuo flusso di lavoro orchestra più attività in parallelo. Passo avanti Functions offre due modi per raggiungere questo obiettivo: puoi prendere un elemento di dati e passare in parallelo a più attività diverse; Oppure puoi utilizzare un array e passare i suoi elementi alla stessa attività.

In Workflows, puoi definire una parte del flusso di lavoro in cui possono essere eseguiti contemporaneamente due o più passaggi. Puoi definire i rami che o un loop in cui le iterazioni vengono eseguite contemporaneamente. Per maggiori dettagli, vedi Esegui i passaggi del flusso di lavoro in parallelo.

Dati sullo stato

Un vantaggio di un motore dei flussi di lavoro è che i dati sullo stato vengono conservati senza un datastore esterno. In Step Functions, i dati sullo stato vengono trasmessi in una struttura JSON da uno stato all'altro.

In Workflows, puoi salvare i dati sullo stato in come la codifica one-hot delle variabili categoriche. Poiché è consentita una durata di esecuzione fino a un anno, puoi conservare i dati sullo stato finché l'istanza è ancora in esecuzione.

Autenticazione

Entrambi i prodotti si basano su un sistema Identity and Access Management (IAM) sottostante per l'autenticazione e controllo dell'accesso. Ad esempio, puoi utilizzare un ruolo IAM per richiamano le funzioni Step.

In Workflows, puoi utilizzare un account di servizio per richiamare un workflow; puoi utilizzare OAuth 2.0 o OIDC per connetterti a Google Cloud le API e puoi utilizzare un'intestazione della richiesta di autorizzazione per eseguire l'autenticazione un'API di terze parti. Per ulteriori informazioni, vedi Concedi l'autorizzazione dei flussi di lavoro per l'accesso alle risorse Google Cloud e Effettuare richieste autenticate da un flusso di lavoro.

Esperienza utente

Puoi utilizzare uno strumento a riga di comando o uno strumento Infrastructure as Code (IaC), come Terraform, per definire e gestire sia Step Functions che Workflows.

Inoltre, Workflows supporta l'esecuzione di flussi di lavoro. utilizzando le librerie client nella console Google Cloud, utilizzando Google Cloud CLI, o inviando una richiesta all'API REST Workflows. Per maggiori dettagli, consulta Eseguire un flusso di lavoro.

Prezzi

Entrambi i prodotti prevedono un Livello gratuito. Per ulteriori dettagli, consulta i rispettivi prezzi pagine: Prezzi di Step Functions e prezzi di Workflows.

Mappatura dei tipi di stato ai passaggi

Esistono otto tipi di stato nelle funzioni Step. Gli stati sono elementi in uno stato machine learning che può prendere decisioni in base ai propri input, eseguire azioni e passare l'output in altri stati. Prima di eseguire la migrazione dalle funzioni step a Workflows, assicurati di comprendere come tradurre ogni a un passaggio di Workflows.

Choice

Uno stato Choice aggiunge logica di diramazione a una macchina a stati.

In Workflows, puoi utilizzare un blocco switch come selezione meccanismo che consente al valore di un'espressione di controllare il flusso di un dell'esecuzione del flusso di lavoro. Se un valore corrisponde, viene eseguita l'istruzione di quella condizione. Per ulteriori informazioni, consulta la sezione Condizioni.

Funzioni dei passaggi

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

YAML di Workflows

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

JSON di Workflows

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

Fail

Uno stato Fail interrompe l'esecuzione della macchina a stati e la contrassegna come errore.

In Workflows, puoi segnalare errori personalizzati utilizzando l'raise ed è possibile individuare e gestire gli errori utilizzando un blocco try/except. Per Per ulteriori informazioni, consulta la sezione Segnalare errori.

Funzioni dei passaggi

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

YAML di Workflows

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

JSON di Workflows

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

Map

È possibile utilizzare uno stato Map per eseguire una serie di passaggi per ogni elemento di un input un array di dati.

In Workflows, puoi utilizzare un for loop per iterazioni.

Funzioni dei passaggi

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

Uno stato Parallel può essere utilizzato per creare rami di esecuzione paralleli o macchina a stato. Nel seguente esempio di Step Functions, un indirizzo e un numero viene eseguita in parallelo.

In Workflows, puoi utilizzare un passaggio parallel per definire una parte il flusso di lavoro in cui possono essere eseguiti contemporaneamente due o più passaggi. Per maggiori informazioni informazioni, consulta Passaggi paralleli.

Funzioni dei passaggi

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

Uno stato Pass passa il proprio input al proprio output, senza eseguire operazioni. Questo è di uso comune per manipolare i dati di stato nel file JSON.

Poiché Workflows non trasmette i dati in questo modo, è possibile lascia lo stato autonomo oppure puoi utilizzare un passaggio "Assign" per modificare come la codifica one-hot delle variabili categoriche. Per ulteriori informazioni, vedi Assegna variabili.

Funzioni dei passaggi

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

YAML di Workflows

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

JSON di Workflows

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

Riuscito

Uno stato Succeed interrompe un'esecuzione correttamente.

In Workflows, puoi utilizzare return nel flusso di lavoro principale per arrestare l'esecuzione di un flusso di lavoro. Puoi anche completare un flusso di lavoro passaggio finale (supponendo che il passaggio non passi a un altro), oppure puoi usare next: end per interrompere l'esecuzione di un flusso di lavoro se non devi restituire un valore. Per ulteriori informazioni, vedi Completa l'esecuzione di un flusso di lavoro.

Funzioni dei passaggi

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

YAML di Workflows

  return: "Success!"
  next: end

JSON di Workflows

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

Task

Uno stato Task rappresenta una singola unità di lavoro eseguita da una macchina a stati. Nel nell'esempio di Step Functions riportato di seguito, richiama una funzione Lambda. (le attività sono una funzionalità di funzioni passo-passo AWS che ti consente di assegnare nella macchina a stati in cui il lavoro viene svolto altrove.)

Nell'esempio di Workflows, viene effettuata una chiamata a un endpoint HTTP per richiamare una nella funzione Cloud Run. Puoi anche utilizzare un connettore che consente un facile accesso ad altri prodotti Google Cloud. Inoltre, puoi mettere in pausa un flusso di lavoro e eseguire un sondaggio per i dati. Oppure può utilizzare un endpoint di callback per segnalare al flusso di lavoro che si è verificato un evento specifico e attendere senza sondaggio.

Funzioni dei passaggi

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

YAML di Workflows

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

JSON di Workflows

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

Wait

Uno stato Wait ritarda il funzionamento della macchina statale per un periodo di tempo specificato.

Puoi utilizzare lo strumento sys.sleep di Workflows funzione di libreria standard per sospendere l'esecuzione per il numero di secondi specificato fino a un massimo di 31536000 (uno anno).

Funzioni dei passaggi

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

YAML di Workflows

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

JSON di Workflows

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

Esempio: orchestrazione di microservizi

Il seguente esempio di Step Functions controlla un prezzo delle azioni, determina se acquistare o vendere e generare un report sui risultati. La macchina a stati nell'esempio si integra con AWS Lambda passando parametri, utilizza una coda Amazon SQS per richiedere e utilizza un argomento Amazon SNS per restituire i risultati della query.

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

Esegui la migrazione a Workflows

Per eseguire la migrazione dell'esempio di Step Functions precedente in Workflows, puoi creare i passaggi equivalenti di Workflows integrando Funzioni di Cloud Run, che supportano endpoint di callback che attende l'invio di richieste HTTP a quell'endpoint e l'utilizzo di Workflows per pubblicare in un argomento Pub/Sub invece dell'argomento Amazon SNS:

  1. Completa i passaggi per creare un flusso di lavoro ma non eseguirne ancora il deployment.

  2. Nella definizione del flusso di lavoro, aggiungi un passaggio per creare un endpoint di callback che attende l'input umano e un passaggio che utilizza un Workflows per pubblicare in un argomento Pub/Sub. Ad esempio:

    YAML di 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 di 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"
              }
            }
          ]
        }
      }

    Sostituisci quanto segue:

    • LOCATION: una regione di Google Cloud supportata. Ad esempio: us-central1.
    • PUBSUB_TOPIC_NAME: il nome del tuo Pub/Sub per ogni argomento. Ad esempio, my_stock_example.
  3. Esegui il deployment ed esegui il flusso di lavoro.

  4. Durante l'esecuzione del flusso di lavoro, questo viene messo in pausa e attende che tu richiami il metodo endpoint di callback. Per farlo, puoi utilizzare un comando curl. Ad esempio:

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

    Sostituisci CALLBACK_URL con il resto dei dell'endpoint di callback.

  5. Una volta completato il flusso di lavoro, puoi ricevono il messaggio dalla sottoscrizione Pub/Sub. Ad esempio:

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

    Il messaggio di output dovrebbe essere simile al seguente (buy o sell):

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

Passaggi successivi