這是本文件的舊版!


WireMock - Record events from webhook

我有一隻待測程式(SUT)會相依於外部服務(External Service)的webhook 機制,操作流程如下:

  1. SUT會對外部服務特定事件註冊webhook 位置。
  2. 當外部服務發生特定事件時,會發送event到SUT所註冊的位置。
  3. SUT對外部服務反註冊webhook 位置。


WireMock有提供webhook的extension,讓你可以自行編寫程式或mappingfile腳本去做到在“特定操作後,發送webhook操作”,但它並不支援Recording的功能。本篇文章,主要分享如何讓WireMock擁有錄製webhook的功能。

Pre-notice

由於Solution與整個Record流程息息相關,我必須先說明我所採用的流程。在我的故事中,有四隻程式:

  1. Record Program: 負責控制整個WireMock腳本記錄流程的程式。
  2. SUT: 待測程式,透過REST API提供與External Service相關功能的服務。
  3. WireMock: 負責記錄SUT與External Service互動的過程並產生腳本,提供REST API讓Record Program控制Record流程。
  4. External Service: SUT所互動的外部服務。


詳細流程如下:

  1. Record Program請WireMock開始記錄SUT與External Service互動過程。
  2. Record Program對SUT觸發command,並開始poll command完成結果。
  3. SUT對WireMock做操作。
  4. WireMock將操作轉送給External Service。
  5. Record Program發現command執行完成。
  6. Record Program請WireMock停止記錄。
  7. WireMock產生SUT與External Service互動過程的執行腳本(mappings)。
  8. Record Program針對腳本命名。

Thinking & Design-phase1

針對Pre-notice的流程,我有幾個問題需要解決:

  1. WireMock如何捕捉External Service發送給SUT的callback event?
  2. 補捉之後如何將這些events放置到腳本的Post中?
  3. 放置到腳本中後,如何在適當的時間由WireMock返回給SUT?

首先討論第三個問題,如果有辦法產生如下方的腳本內容,應該可以解決問題。讓我先針對內容做說明:

  1. webhook callback的內容會被放在postServerActions中,會在WireMock回應SUT後觸發這些動作。
  2. 啟用webhook delay的機制,讓它根據時間延後發送;而這個時間其實是SUT註冊callback URL到WireMock收到callback event的duration。


接著回到第一個問題,我採用的方式是將註冊的callback url改到WireMock身上,流程如下圖。另外會把原本的callback url與註冊時間記錄下來,以用來處理收到callback event後的轉送與計算問題三個delay時間:

延續上圖流程,當收到callback event後,就可以透過上圖記錄的原始callback url,送回給SUT並記錄收到event的時間:

在還不考慮技術與實作細節的情況下,這solution似乎是可行的。讓我們繼續看下去。

Note. 第一個問題,我曾想過2個解決方法。第一個方法是同時註冊SUT與WireMock的callback URL給External Service,讓External Service同時發event給兩者;但由於無法確定event收到的先後順序而影響到步驟6的執行,所以捨棄這個方法。

Design & Implement