先前都是透過 Sales Service 來做雲端資源之間交互測試,但實際上並不是全部遭錯都在 Sales Service,原則上 Sales Service 只會跟 Redis 溝通,並且推送 Message 給 Pub/Sub,接下來我們就要來建立 Process Service 並把部分功能搬移到 Procsee Service 去了,建立 Cloud Run 的流程與建立 Sales Service 都相同我這裡就不再贅述可以參考先前的文章進行建立。
Process Sales 建立好之後我們把先前寫在 Sales Service 跟資料庫交互的部分搬移過來
首先安裝 EF Core 套件
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
建立DB Context Data/TicketSalesContext.cs
using Microsoft.EntityFrameworkCore;
namespace iThome2024.ProcessService.Data;
public class TicketSalesContext : DbContext
{
public TicketSalesContext(DbContextOptions<TicketSalesContext> options) : base(options)
{
}
}
搬移測試連線的 Code
app.MapGet("/Test/DbConnection", (TicketSalesContext context) =>
{
return context.Database.CanConnect();
})
.WithName("TestDbConnection")
.WithOpenApi();
調整完畢後再推送至 Giuhub 重新佈署進行測試,記得 Process Service 也一樣要設定由 Secret Manager 去得資料庫的連線字串,不然會因為沒有連線字串連線失敗。
測試 OK 沒問題
先前測試Pub/Sub 時事使用 Pull mode 來測試 Message 的傳送,但窮小子售票系統預計會使用 Push mode 將搶票資料退送給 Process Service 做處理,這樣可以確保沒有活動的時候就沒有流量不會被收取費用。
PubSub 會推送一個特定格式的 Json 到指定的 Endpoint
{
"message": {
"data": "SGVsbG8gQ2xvdWQgUHViL1N1YiEgSGVyZSBpcyBteSBtZXNzYWdlIQ==",
"messageId": "2070443601311540",
"message_id": "2070443601311540",
"publishTime": "2021-02-26T19:13:55.749Z",
"publish_time": "2021-02-26T19:13:55.749Z"
},
"subscription": "projects/myproject/subscriptions/mysubscription"
}
先建立一個 Class 來接收這個物件 VideModel/PubSubMessage.cs
using System.Text.Json.Serialization;
namespace iThome2024.ProcessService.ViewModel;
public class PubSubMessage
{
[JsonPropertyName("message")]
public Message? Message { get; set; }
[JsonPropertyName("subscription")]
public string? Subscription { get; set; }
}
public class Message
{
[JsonPropertyName("attributes")]
public Attributes? Attributes { get; set; }
[JsonPropertyName("data")]
public string? Data { get; set; }
[JsonPropertyName("messageId")]
public string? MessageId { get; set; }
[JsonPropertyName("publishTime")]
public DateTime PublishTime { get; set; }
}
public class Attributes
{
[JsonPropertyName("Content-Type")]
public string? ContentType { get; set; }
}
其中 Data 會是經過 Base64編碼的 UTF-8 字串,再建立一個用來解碼的 Class Common/Base64Converter.cs
using System.Text;
public class Base64Converter
{
public static string Base64ToUtf8(string base64String)
{
byte[] bytes = Convert.FromBase64String(base64String);
string utf8String = Encoding.UTF8.GetString(bytes);
return utf8String;
}
}
最後建立一個 Endpoint 給提供給 PubSub 的 Push Subscription
app.MapPost("/Test/SubEndpoint", (PubSubMessage context) =>
{
string utf8String = Base64Converter.Base64ToUtf8(context.Message?.Data ?? "");
app.Logger.LogInformation(utf8String);
return Results.Ok();
})
.WithName("TestSubEndpoint")
.WithOpenApi();
接下來新增一個 Subscription mode 選擇 push,網址就輸入 Process Service 的URL 跟先前建立 for PubSub 測試的 endpoint。
最後測試一下,我們從 Sales Service 發送一則 Message 給 PubSub,PubSub 會幫我們 Push 給Process Service。
我們發送一個 TestMessage001
給 Sales Service
我們到 Process Service 的 Log 就可以看到 Message 已經順利送達 Processor 了
這樣 Process Service 就建置完成了,經過測試跟其他元件的連接也都是順利的。