消費者與提供者之間的合約測試 - Pact.io

Introduction Pact是一個程式碼優先工具,使用contract tests測試 HTTP 以及訊息整合。Contract test斷言應用程式對應用程式之間的訊息,有符合文件所記錄的共識。如果沒有contract testing,那麼確保應用程式之前協作正確的唯一方式就只有使用容易壞掉又維護性高的整合測試了。 測試煙霧警報器的時候,會使用測試按鈕,不會直接燒了房子,同理可證,Pact提供程式碼這樣一個測試按鈕,讓你在部署好所有微服務之前,能夠先安全地確認程式碼正確執行。 Pact合約測試流程動圖 Consumer 針對provider mock執行單元測試,驗證自己程式的行為 跨系統之間的互動行為會捕捉至contract Contract由不同團隊之間共享,使用Pactflow工具能夠確保協同合作性 Contract中的requests 重演了 provider API 並驗證 consumer 的預期值 Provider 的測試中所有其他系統都用替身,所以能隔離測試 Javascript code guide, 5 mins 1 2 3 4 5 group = 'au.com.dius.pactworkshop' dependencies { testImplementation 'au.com.dius.pact.consumer:junit5:4.6.5' } contract testing是什麼 Contract testing 是用來測試某個integration point的技術,藉由隔離測試個別的APP,以確保它接收或傳送出的訊息,符合紀載在合約上的共識。 如果是透過HTTP通訊的應用程式,這些訊息就會是HTTP請求/回覆,如果是使用Queue的應用程式,這些訊息就會是要傳送到隊列的內容。 Pact實作合約測試的方式,就是確認所有呼叫你的test doubles的測試都會得到如同實際app一樣的回傳值。 什麼時候使用contract testing 當你有兩個需要互通有無的service時,contract testing就可以立刻派上用場,例如API client要與web front-end溝通的應用場景。雖然單一客戶端對單一個服務是很常建的use case,contract testing在微服務架構(有多個services的環境)更彰顯其價值。如果有格式良好的合約測試,開發就要避免版本地域就更家容易。合約測試可說是微服務開發與部署的殺手級應用。 合約測試術語 consumer: 例如需要接收資料的client provider: 例如server上的API,提供client所需的資料 通常在微服務架構下,client/server的術語不適合所有情境,例如透過訊息隊列的溝通就不適合。所以這裡會以consumer與provider為主。 消費者驅動的contracts Pact是程式碼優先、消費者驅動的合約測試工具,通常由寫程式的開發或測試人員使用。在自動化的consumer tests過程中產生這個contract。這種模式的一個主要優勢是,全部的communication中,只測試到 consumer會實際使用到的部分communication。也就是說,任何不會被當前的consumer所使用到的 provider行為,都可以在不弄壞測試結果的前提下做異動修改。 另外Pact contract也不像schema或者規格 (例如 OAS) 這類靜態的artefact定義資源的所有可能的狀態,pact contract實施方式是藉由執行測試案例的集合,每個元素描述了具體的請求/回應對。Pact實際上就是範例式合約。參考Schema測試與Contract測試的差異

框架比較:Springboot 與 Quarkus

以下的筆記主要參照Baeldung這篇文章,後續會在針對如何用Quarkus建立第一個專案補充說明。 SpringBoot v.s. Quarkus 概觀 這篇文章的關注點在於比較兩個廣為人知的Java框架—SpringBoot與Quarkus。看完文章,能更加瞭解兩者之間的相似、差異處以及各自的特殊性。另外也有一些測試來檢測效能並觀察表現。 SpringBoot 這個Java framework主要用於企業級應用程式。集成了所有Spring project,提供許多production-ready的整合,可協助開發者提高生產力。 減少了要配置的數量以及文件樣板。另外因為約定大於配置的方法,會根據runtime時classpath中的依賴 (dependencies),自動註冊預設的配置。SpringBoot大幅減少了許多Java應用程式上市的時間。 Quarkus Quarkus 是另外一個framework,其方法類似SpringBoot,但另外能在快速的啟動時間內,交付較小型的artifacts,有更好的資源利用度以及效率。 Quarkus 是以 cloud、serverless以及容器化環境所最佳化的框架。除此之外,Quarkus framework與Java其他框架的的整合性也很好。 比較這兩者 如上所述,這兩個framework與其他的project跟framework的整合性都不錯,但其內部 implementation & architecture 並不相同。例如,SpringBoot提供兩種 web capabilities: blocking(Servlets) 以及 non-blocking(WebFlux) Quarkus 當然也有提供這兩種行為,但它可以讓開發同時使用blocking跟non-blocking這兩種策略。另外 Quarkus 有將響應式的方法內嵌在本身的架構中。 因此這裡主要比較的是 Spring WebFlux 以及 Quarkus reactive capabilities 比較相似的情境 (non-blocking)。 另外,這兩個projects中比較顯著的功能是新建 native images (binary executables 以及 platform-specific executables),所以也會比較這兩個projects的native images。 註: SpringBoot 2.7 版本的 native image support 仍在實驗階段,直到 VERSION 3 才正式支持 native image support,需要使用 GraalVM。 註: Native image 這裡指的是將Java程式碼建構成 standalone executable 可執行檔的技術。Executable 包含了 java classes, classes from its dependencies, runtime library class, 以及 jdk 的 native code。

資料庫版控,走起,高飛!Flyway

因為G.K.老師常常強調 Flyway 的優勢,資料庫版控、避免共用的資料庫不知道被誰扔了dirty data導致其他人開發的功能壞掉,等等的好處,所以來看看官方文件。 初探Flyway Flyway@build.gradle: dependencies { implementation 'org.flywaydb:flyway-core' } Flyway@application.yml: spring.flyway.url=jdbc:h2:mem:flyway spring.flyway.schemas={default_schema} spring.flyway.user= spring.flyway.password= Three ways to interact with Flyway 除了提供版本控制與持續交付的功能,flyway 可以根據程式交付進度,來自動化部署資料庫。 Flyway Desktop 提供GUI讓資料庫開發跟數據家能夠追蹤資料庫物件的異動,並且在版本控制中管理資料遷移的腳本。 Flyway command-line 是可以獨立運行的套件 (只需要操作系統,不用其他支援框架),有Windows、macOS以及Linux版本。適合想要用命令列介面遷移資料庫的user,而不用將Flyway整合進應用程式,也不用安裝build tool。 另外可以用 API 將 Flway 整合進應用程式,在程式啟動時一同執行資料庫遷移。 Flyway commands Flyway Desktop 安裝時,會一併安裝command line以及API,主要有以下命令: Migrate 將schema遷移成最新的版本 是Flyway workflow的中心,它會在檔案系統或你的類別路經中掃描找出可用的migrations,並比較已經執行到資料庫的遷移,如果有任何差異就會做對應的migration,以彌平差異。 通常是在application startup時期執行migrate Clean 在已經配置好schemas的資料庫中,刪掉所有資料表物件 千萬不能用在 production DB 如果是複雜的資料庫結構,可能因為明確的dependency graph架構不起來,所以沒辦法清乾淨所有物件。另外有些物件考量安全性,也不會清除,例如 SQL server 的 users 資料。可以加上 afterClean callback 來額外定義要 drop 的敘述 Info 可以了解當下有哪些migration已經執行了,哪一些還沒開始,何時執行的migration以及執行結果是成功或失敗。 Validate 驗證可用的 migration 是否相當於已經被執行的 migration 可以偵測意料之外的異動,可以預防重新產生schema 在 migration 執行時,存進一個checksum (使用CRC32校驗)。要驗證時,就查看本地的migration與已經執行到database的 migration 是否有相同一致的checksum。 此外,可能會有一些 hotfix, migration deletion 或者異動,可能違反Flyway驗證習慣,這時候也可以客製化驗證規則 Undo 復原最近一次被執行的migration版本 需要指定 target,這樣Flyway會綁你倒回至target之前的版本 如果沒有要 undo 的 versioned migration,呼叫這個undo就沒啥用 Baseline 給之前已經存在的數據庫 (已經包含數據,但之前沒有被Flyway管理)建立一個基準起始版本 Repair 用來修復 flyway_schema_history 資料庫的,有以下用途 移除failed migration entries (失敗的遷移紀錄) 只適用於不支援DDL transactions的資料庫 PostgreSQL, Oracle: 支持ddl事務 MySQL, MariaDB, SQLite: 不支持ddl事務

非阻塞式🌌 Non Blocking Jdbc

Part 1 阻塞式程式碼是現代軟體工程的禍根,它需要比較多的CPU cycles以及memory使用資源,提高了執行程式的成本 I. Blocking/Asynchronous/Asynchronous-Non-Blocking 這個章節(I)會學到: 了解 non-blocking calls 在做什麼 了解 event based system 的重要性以及他們如何協助調用 non-blocking calls 圖表的呈現面向: 程式語言: Java 會使用到 Java 執行緒 非同步的方法為綠底,同步的方法是紅底 藍底是不會產生阻塞的Java方法 Blocking Call save方法呼叫write方法 write方法是一個blocking call: 寫入磁碟 直到 write to disk 完成之後,這個 thread 才會停止 blocking 狀態 這個thread在blocking call return之後重新開始 接著這個thread呼叫notify方法 Asynchronous Call 非同步呼叫 save方法呼叫write方法,這個write方法包裝了一個asynchronous call 此 write包裝方法使用Executor(線程池或其他併發機制)產出一個執行緒來寫入磁碟 這個新產生的執行緒進入阻塞狀態,直到write to disk工作完成 執行save方法的主要執行緒不受到組塞,可以執行其他程序 新產生的執行緒在完成 blocking call 之後回傳,並呼叫notify方法 Asynchronous Non Blocking Call save方法呼叫write方法 (write方法使用 Java NIO) Non Blocking Call 不會阻塞主要執行緒 non-blocking write 方法進入阻塞狀態,直到write to disk的工作完成 執行save方法的主要執行緒並不會受到阻塞,可以執行其他程序 在non-blocking call完成之後,這個non-blocking方法呼叫notify方法 結論 Blocking Call

初探GitLab CI/CD - 如何撰寫.gitlab-ci.yml

使用 CI/CD 建構應用程式 開始 CI/CD 是軟體開發其中一個continuous method,你可以在這方法中持續的建構、測試、部署、監測迭代的程式碼異動。 這種方式有助於降低在有誤的前一個版本中開發新程式,GitLab CI/CD在開發早期階段就能抓錯,確保部署到正式環境的程式碼符合所建立的程式碼標準,而這個程序是更大的workflow之中的一個環節: Plan Create Verify Secure Release Monitor Manage your organization Learn Git Use CI/CD to build your app Secure your app Deploy and release your app Monitor app performance Organize work with projects Manage your code Manage infrastructure Monitor GitLab Runner usage Plan and track work Analyze GitLab usage 1. 首先建立.gitlab-ci.yml 在project根目錄建立 .gitlab-ci.yml,定義在CI/CD pipeline中所要執行的 stages, jobs, script。 另外也會定義variables,不同jobs之間的依賴關係,並且指定每個job什麼時候會被執行,應該如何被執行。 沒有硬性規定要怎麼命名,但.gitlab-ci.yml是這個 CI/CD configuration file 最常見的名字。

如何查看哪一個SQL語法是最佳解:explain執行計畫

昨天與一位做自有產品的執行長官面談被問到如何確認SQL的效能,當下沒能立即回答上。 但今天在練習 LeetCode SQL 50 的時候,看到有神人對一道 570. Managers with at Least 5 Direct Reports 題目給出了五種 solutions,於是回想起之前聽過但不常用的 explain 語法,這樣慘痛的教訓肯定是要花時間瞭解一下的吧。 問題 題目只有一張 Table : Employee: 每一列包含了員工id、員工名、員工所屬部門以及他們的所屬主管id,如果managerId 為 null,就表示這員工沒有直屬主管。 沒有員工會自己當自己的主管,即 id 與 managerId 不能為相同的值。 1 2 3 4 5 6 create table employee ( id int not null primary key auto_increment, name varchar(20), department varchar(2), managerId int ) auto_increment=101; Table 欄位內容: Employee table: +-----+-------+------------+-----------+ | id | name | department | managerId | +-----+-------+------------+-----------+ | 101 | John | A | null | | 102 | Dan | A | 101 | | 103 | James | A | 101 | | 104 | Amy | A | 101 | | 105 | Anne | A | 101 | | 106 | Ron | B | 101 | +-----+-------+------------+-----------+ 預期結果: +------+ | name | +------+ | John | +------+ 解法: A.