Bermigrasi dari AWS Step Functions ke Workflows

Untuk membantu Anda bersiap memigrasikan dari Step Functions Amazon Web Services (AWS) ke Workflow di Google Cloud, halaman ini menjelaskan kesamaan dan perbedaan utama antara kedua produk tersebut. Informasi ini ditujukan untuk membantu orang yang sudah memahami Step Functions menerapkan arsitektur serupa menggunakan Alur Kerja.

Seperti Step Functions, Workflows adalah platform orkestrasi berbasis status terkelola sepenuhnya yang menjalankan layanan dalam urutan yang Anda tentukan: alur kerja. Alur kerja ini dapat menggabungkan berbagai layanan, termasuk layanan kustom yang dihosting di Cloud Run atau fungsi Cloud Run, layanan Google Cloud seperti Cloud Vision AI dan BigQuery, serta API berbasis HTTP apa pun.

Perhatikan bahwa Alur Kerja Ekspres Step Functions adalah jenis alur kerja AWS Step Functions yang tidak dipertimbangkan di sini karena durasi Alur Kerja Ekspres terbatas, dan eksekusi alur kerja tepat sekali tidak didukung.

Halo dunia

Di Step Functions, mesin status adalah alur kerja, dan tugas adalah status dalam alur kerja yang mewakili satu unit pekerjaan yang dilakukan layanan AWS lainnya. Step Functions mengharuskan setiap status menentukan status berikutnya.

Dalam Alur Kerja, serangkaian langkah yang menggunakan sintaksis Alur Kerja menjelaskan tugas yang akan dijalankan. Alur kerja memperlakukan langkah-langkah seolah-olah berada dalam daftar yang diurutkan dan menjalankannya satu per satu hingga semua langkah telah berjalan.

Contoh "Halo dunia" berikut menunjukkan penggunaan status dalam Fungsi Langkah dan langkah dalam Alur Kerja:

Step Functions

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

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

JSON Alur Kerja

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

Ringkasan perbandingan

Bagian ini membandingkan kedua produk secara lebih mendetail.

Step FunctionsWorkflows
SintaksJSON (YAML dalam alat) YAML atau JSON
Alur kontrolTransisi di antara status Kontrol alur imperatif dengan langkah-langkah
PekerjaResource (ARN) dan tugas HTTP Permintaan dan konektor HTTP
KeandalanTangkap/coba lagi Tangkap/coba lagi
KeparalelanDidukung Didukung
Data statusStatus diteruskan Variabel alur kerja
AuthenticationIAM IAM
Pengalaman penggunaWorkflow Studio, CLI, SDK, IaC Konsol Google Cloud, CLI, SDK, IaC
Harga Harga Step Functions Harga alur kerja
Sintaks

Step Functions terutama menggunakan JSON untuk menentukan fungsi dan tidak mendukung YAML secara langsung; namun, di AWS Toolkit untuk Visual Studio Code dan di AWS CloudFormation, Anda dapat menggunakan YAML untuk definisi Step Functions.

Anda dapat menjelaskan langkah-langkah Alur Kerja menggunakan sintaksis Alur Kerja, dan langkah-langkah tersebut dapat ditulis dalam YAML atau JSON. Sebagian besar alur kerja menggunakan YAML. Contoh di halaman ini menunjukkan kelebihan YAML, termasuk kemudahan membaca dan menulis, serta dukungan native untuk komentar. Untuk penjelasan mendetail tentang sintaksis Alur Kerja, lihat Referensi sintaksis.

Alur kontrol

Alur kerja Workflow dan Step Functions memodelkan alur kerja sebagai serangkaian tugas: langkah di Workflow dan status di Step Functions. Keduanya memungkinkan tugas untuk menunjukkan tugas mana yang akan dieksekusi berikutnya dan mendukung kondisional seperti tombol untuk memilih unit tugas berikutnya berdasarkan status saat ini. Satu perbedaan utama adalah Step Functions mewajibkan setiap status untuk menentukan status berikutnya, sedangkan Alur Kerja menjalankan langkah-langkah sesuai urutan yang ditentukan (termasuk langkah berikutnya alternatif). Untuk informasi selengkapnya, lihat Kondisi dan Langkah.

Pekerja

Kedua produk tersebut mengatur resource komputasi seperti fungsi, penampung, dan layanan web lainnya untuk menyelesaikan berbagai hal. Di Step Functions, pekerja diidentifikasi oleh kolom Resource yang secara sintaksis merupakan URI. URI yang digunakan untuk mengidentifikasi resource pekerja dalam format Amazon Resource Name (ARN). Untuk langsung memanggil endpoint HTTP arbitrer, Anda dapat menentukan tugas HTTP.

Alur kerja dapat mengirim permintaan HTTP ke endpoint HTTP arbitrer dan mendapatkan respons. Konektor memudahkan koneksi ke Google Cloud API lainnya dalam alur kerja, dan mengintegrasikan alur kerja Anda dengan produk Google Cloud lainnya seperti Pub/Sub, BigQuery, atau Cloud Build. Konektor menyederhanakan layanan panggilan karena menangani pemformatan permintaan untuk Anda, menyediakan metode dan argumen sehingga Anda tidak perlu mengetahui detail Google Cloud API. Anda juga dapat mengonfigurasi kebijakan waktu tunggu dan polling.

Keandalan

Jika tugas gagal, alur kerja Anda harus dapat mencoba ulang dengan tepat, menangkap pengecualian jika perlu, dan mengalihkan alur kerja sesuai kebutuhan. Fungsi Langkah dan Alur Kerja mencapai keandalan menggunakan mekanisme yang serupa: penangkapan pengecualian dengan percobaan ulang, dan pengiriman akhir ke tempat lain dalam alur kerja. Untuk mengetahui informasi selengkapnya, lihat Error alur kerja.

Keparalelan

Anda mungkin ingin alur kerja mengatur beberapa tugas secara paralel. Fungsi Langkah menyediakan dua cara untuk mencapai hal ini: Anda dapat mengambil satu item data dan meneruskannya secara paralel ke beberapa tugas yang berbeda; atau, Anda dapat menggunakan array dan meneruskan elemennya ke tugas yang sama.

Di Alur Kerja, Anda dapat menentukan bagian alur kerja tempat dua langkah atau lebih dapat dijalankan secara serentak. Anda dapat menentukan cabang yang berjalan secara serentak, atau loop tempat iterasi berjalan secara serentak. Untuk mengetahui detailnya, lihat Menjalankan langkah alur kerja secara paralel.

Data status

Salah satu manfaat mesin alur kerja adalah data status dipertahankan untuk Anda tanpa datastore eksternal. Di Step Functions, data status diteruskan dalam struktur JSON dari satu status ke status lainnya.

Di Alur Kerja, Anda dapat menyimpan data status dalam variabel global. Karena Anda diizinkan hingga durasi eksekusi satu tahun, Anda dapat menyimpan data status selama instance masih dalam eksekusi.

Autentikasi

Kedua produk tersebut mengandalkan sistem Identity and Access Management (IAM) yang mendasarinya untuk autentikasi dan kontrol akses. Misalnya, Anda dapat menggunakan peran IAM untuk memanggil Step Functions.

Di Alur Kerja, Anda dapat menggunakan akun layanan untuk memanggil alur kerja; Anda dapat menggunakan OAuth 2.0 atau OIDC untuk terhubung dengan Google Cloud API; dan Anda dapat menggunakan header permintaan otorisasi untuk mengautentikasi dengan API pihak ketiga. Untuk mengetahui informasi selengkapnya, lihat Memberikan izin alur kerja untuk mengakses resource Google Cloud dan Membuat permintaan yang diautentikasi dari alur kerja.

Pengalaman pengguna

Anda dapat menggunakan alat command line, atau infrastruktur sebagai kode (IaC) seperti Terraform, untuk menentukan dan mengelola Step Functions dan Alur Kerja.

Selain itu, Alur Kerja mendukung eksekusi alur kerja menggunakan library klien, di konsol Google Cloud, menggunakan Google Cloud CLI, atau dengan mengirim permintaan ke Workflows REST API. Untuk mengetahui detailnya, lihat Menjalankan alur kerja.

Harga

Kedua produk tersebut memiliki paket gratis. Untuk mengetahui detail selengkapnya, lihat halaman harga masing-masing: Harga Step Functions dan Harga Workflows.

Memetakan jenis status ke langkah

Ada delapan jenis status di Step Functions. Status adalah elemen dalam mesin status yang dapat membuat keputusan berdasarkan inputnya, melakukan tindakan, dan meneruskan output ke status lain. Sebelum bermigrasi dari Step Functions ke alur kerja, pastikan Anda memahami cara menerjemahkan setiap jenis status ke langkah alur kerja.

Choice

Status Choice menambahkan logika cabang ke mesin status.

Dalam Alur Kerja, Anda dapat menggunakan blok switch sebagai mekanisme pemilihan yang memungkinkan nilai ekspresi mengontrol alur eksekusi alur kerja. Jika nilai cocok, pernyataan kondisi tersebut akan dieksekusi. Untuk mengetahui informasi selengkapnya, lihat Kondisi.

Step Functions

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

YAML Alur Kerja

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

JSON Alur Kerja

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

Fail

Status Fail menghentikan eksekusi mesin status dan menandainya sebagai kegagalan.

Di Workflow, Anda dapat menampilkan error kustom menggunakan sintaksis raise, dan Anda dapat menangkap serta menangani error menggunakan blok try/except. Untuk mengetahui informasi selengkapnya, lihat Menyebabkan error.

Step Functions

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

YAML Alur Kerja

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

JSON Alur Kerja

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

Map

Status Map dapat digunakan untuk menjalankan serangkaian langkah untuk setiap elemen array input.

Di Workflow, Anda dapat menggunakan loop for untuk iterations.

Step Functions

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

  - 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 Alur Kerja

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

Status Parallel dapat digunakan untuk membuat cabang eksekusi paralel di mesin status Anda. Pada contoh Step Functions berikut, pencarian alamat dan telepon dilakukan secara paralel.

Di Alur Kerja, Anda dapat menggunakan langkah parallel untuk menentukan bagian alur kerja tempat dua langkah atau lebih dapat dijalankan secara serentak. Untuk informasi selengkapnya, lihat Langkah paralel.

Step Functions

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

  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 Alur Kerja

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

Status Pass meneruskan input ke output-nya, tanpa melakukan pekerjaan. Hal ini biasanya digunakan untuk memanipulasi data status dalam JSON.

Karena Alur Kerja tidak meneruskan data dengan cara ini, Anda dapat meninggalkan status sebagai no-op, atau Anda dapat menggunakan langkah penetapan untuk mengubah variabel. Untuk mengetahui informasi selengkapnya, lihat Menetapkan variabel.

Step Functions

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

YAML Alur Kerja

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

JSON Alur Kerja

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

Berhasil

Status Succeed berhasil menghentikan eksekusi.

Di Alur Kerja, Anda dapat menggunakan return di alur kerja utama untuk menghentikan eksekusi alur kerja. Anda juga dapat menyelesaikan alur kerja dengan menyelesaikan langkah terakhir (dengan asumsi bahwa langkah tidak beralih ke langkah lain), atau Anda dapat menggunakan next: end untuk menghentikan eksekusi alur kerja jika tidak perlu menampilkan nilai. Untuk mengetahui informasi selengkapnya, lihat Menyelesaikan eksekusi alur kerja.

Step Functions

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

YAML Alur Kerja

  return: "Success!"
  next: end

JSON Alur Kerja

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

Task

Status Task mewakili satu unit pekerjaan yang dilakukan oleh mesin status. Dalam contoh Step Functions berikut, fungsi ini memanggil fungsi Lambda. (Aktivitas adalah fitur AWS Step Functions yang memungkinkan Anda memiliki tugas di mesin status tempat pekerjaan dilakukan di tempat lain.)

Dalam contoh Alur Kerja, panggilan dilakukan ke endpoint HTTP untuk memanggil fungsi Cloud Run. Anda juga dapat menggunakan konektor yang memungkinkan akses mudah ke produk Google Cloud lainnya. Selain itu, Anda dapat menjeda alur kerja dan melakukan polling untuk data. Atau, Anda dapat menggunakan endpoint callback untuk memberi tahu alur kerja bahwa peristiwa yang ditentukan telah terjadi, dan menunggu peristiwa tersebut tanpa polling.

Step Functions

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

YAML Alur Kerja

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

JSON Alur Kerja

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

Wait

Status Wait menunda mesin status agar tidak berlanjut selama waktu yang ditentukan.

Anda dapat menggunakan fungsi library standar sys.sleep Workflows untuk menangguhkan eksekusi selama jumlah detik tertentu hingga maksimum 31536000 (satu tahun).

Step Functions

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

YAML Alur Kerja

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

JSON Alur Kerja

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

Contoh: Mengatur microservice

Contoh Step Functions berikut memeriksa harga saham, menentukan apakah akan membeli atau menjual, dan melaporkan hasilnya. Mesin status dalam contoh ini terintegrasi dengan AWS Lambda dengan meneruskan parameter, menggunakan antrean Amazon SQS untuk meminta persetujuan manusia, dan menggunakan topik Amazon SNS untuk menampilkan hasil kueri.

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

Bermigrasi ke Alur Kerja

Untuk memigrasikan contoh Step Functions sebelumnya ke Workflows, Anda dapat membuat langkah Workflows yang setara dengan mengintegrasikan fungsi Cloud Run, mendukung endpoint callback yang menunggu permintaan HTTP tiba di endpoint tersebut, dan menggunakan konektor Workflows untuk memublikasikan ke topik Pub/Sub sebagai pengganti topik Amazon SNS:

  1. Selesaikan langkah-langkah untuk membuat alur kerja, tetapi jangan deploy alur kerja tersebut.

  2. Dalam definisi alur kerja, tambahkan langkah untuk membuat endpoint callback yang menunggu input manusia, dan langkah yang menggunakan konektor Alur Kerja untuk memublikasikan ke topik Pub/Sub. Contoh:

    YAML Alur Kerja

      ---
      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 Alur Kerja

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

    Ganti kode berikut:

    • LOCATION: Region Google Cloud yang didukung. Misalnya, us-central1.
    • PUBSUB_TOPIC_NAME: nama topik Pub/Sub Anda. Contoh, my_stock_example.
  3. Deploy, lalu jalankan alur kerja.

  4. Selama eksekusi alur kerja, alur kerja akan dijeda dan menunggu Anda memanggil endpoint callback. Anda dapat menggunakan perintah curl untuk melakukannya. Contoh:

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

    Ganti CALLBACK_URL dengan bagian lain dari jalur ke endpoint callback Anda.

  5. Setelah alur kerja berhasil diselesaikan, Anda dapat menerima pesan dari langganan Pub/Sub. Contoh:

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

    Pesan output akan mirip dengan berikut ini (buy atau sell):

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

Langkah selanjutnya