Created
September 1, 2023 16:31
-
-
Save atsapura/6976f0941e5bffb5c68bc212180d2468 to your computer and use it in GitHub Desktop.
App Env example with test env
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type IAppEnv = | |
abstract member Now: Instant | |
abstract member OrderDiffStorage: IOrderDiffStorage | |
abstract member DomainOrderStorage: IOrderStorage | |
abstract member OrderEventSender: IOrderEventSender | |
abstract member CatalogClient: ICatalogClient | |
abstract member ErpOrderListener: IErpOrderListener | |
abstract member Config: Config | |
type AppEnv(diffStorage: IOrderDiffStorage, | |
domainOrderStorage: IOrderStorage, | |
orderEventSender: IOrderEventSender, | |
catalogClient: ICatalogClient, | |
erpOrderListener: IErpOrderListener, | |
config) = | |
member _.Now = currentInstant() | |
member _.OrderDiffStorage = diffStorage | |
member _.DomainOrderStorage = domainOrderStorage | |
member _.OrderEventSender = orderEventSender | |
member _.Config = config | |
member _.CatalogClient = catalogClient | |
member _.ErpOrderListener = erpOrderListener | |
interface IAppEnv with | |
member this.Now = this.Now | |
member this.OrderDiffStorage = this.OrderDiffStorage | |
member this.DomainOrderStorage = this.DomainOrderStorage | |
member this.OrderEventSender = this.OrderEventSender | |
member this.Config = this.Config | |
member this.CatalogClient = this.CatalogClient | |
member this.ErpOrderListener = this.ErpOrderListener | |
type ConfiguredEnv = | |
inherit AppEnv | |
new (configuration, logger, httpClientFactory) = | |
let serviceBusClient = ServiceBusClient(configuration.Infrastructure.ServiceBusConnection) | |
let blobClient = BlobServiceClient(configuration.Infrastructure.BlobConnection) | |
let queueClient = QueueClient(configuration.Infrastructure.BlobConnection, AzureQueues.ErpOrders) | |
let customerDbClient = CustomerDb.clientForConnectionString configuration.Infrastructure.CustomerDbConnection | |
let orderDiffContainerClient = blobClient.GetBlobContainerClient("erp-order-diffs-test") | |
let ordersContainer = blobClient.GetBlobContainerClient("erp-orders") | |
let diffStorage = OrderDiffStorage.Client(orderDiffContainerClient) | |
let domainOrderStorage = OrderStorage.Client(customerDbClient) | |
let eventSender = OrderEventSender.Client(serviceBusClient) | |
let erpOrderListener = ErpOrderListener(queueClient, ordersContainer, logger) | |
let catalogClient = | |
CatalogClient(httpClientFactory, catalogSettingOfConfig configuration.Infrastructure) | |
{ inherit AppEnv(diffStorage, domainOrderStorage, eventSender, catalogClient, erpOrderListener, configuration) } | |
module MigrationEnvironment = | |
type FakeEventSender() = | |
member _.Send events = | |
async { | |
return () | |
} | |
interface IOrderEventSender with | |
member this.Send e = this.Send e | |
type BlobOrderSaver(blobClient: BlobServiceClient) = | |
let blobContainer = blobClient.GetBlobContainerClient "domain-orders-test" | |
let blobName orderId = $"%i{orderId}.json" | |
member _.SaveOrder order = | |
async { | |
let entity = customerOrderToEntity order | |
let content = JsonConvert.SerializeObject entity |> BinaryData | |
let! r = blobContainer.UploadBlobAsync(blobName order.ErpOrderId, content) |> Async.AwaitTask | |
return Ok() | |
} | |
member _.GetOrder orderId = | |
async { | |
let blobClient = blobContainer.GetBlobClient(blobName orderId) | |
let! resp = blobClient.DownloadContentAsync() |> Async.AwaitTask | |
if resp.HasValue then | |
let content = resp.Value.Content.ToString() | |
let entity = JsonConvert.DeserializeObject<RootSalesOrderEntity> content | |
return entity |> customerOrderToDomain |> Some | |
else return None | |
} | |
interface IOrderStorage with | |
member this.GetOrder id = this.GetOrder id | |
member this.SaveOrder order = this.SaveOrder order | |
type MigrationEnv = | |
inherit AppEnv | |
new (configuration, logger, httpClientFactory) = | |
let blobClient = BlobServiceClient(configuration.Infrastructure.BlobConnection) | |
let queueClient = QueueClient(configuration.Infrastructure.BlobConnection, AzureQueues.ErpOrders) | |
let orderDiffContainerClient = blobClient.GetBlobContainerClient("erp-order-diffs-test") | |
let ordersContainer = blobClient.GetBlobContainerClient("erp-orders") | |
let diffStorage = OrderDiffStorage.Client(orderDiffContainerClient) | |
let domainOrderStorage = BlobOrderSaver blobClient | |
let eventSender = FakeEventSender() | |
let erpOrderListener = ErpOrderListener(queueClient, ordersContainer, logger) | |
let catalogClient = | |
CatalogClient(httpClientFactory, catalogSettingOfConfig configuration.Infrastructure) | |
{ inherit AppEnv(diffStorage, domainOrderStorage, eventSender, catalogClient, erpOrderListener, configuration) } | |
module TestEnvironment = | |
let createConsoleLogger<'T>() = | |
LoggerFactory.Create(fun builder -> | |
builder.AddSimpleConsole(fun options -> | |
options.SingleLine <- true | |
options.IncludeScopes <- true | |
options.TimestampFormat <- "HH:mm:ss") |> ignore | |
).CreateLogger<'T>() | |
type BullshitHttpFactory() = | |
let nameRegistry = Dictionary<_,_>() | |
interface IHttpClientFactory with | |
member this.CreateClient name = | |
match Dict.tryFind name nameRegistry with | |
| None -> | |
let client = new HttpClient() | |
nameRegistry.Add(name, client) | |
client | |
| Some client -> client | |
type FakeErpOrderListener(erpOrderContainer: BlobContainerClient, logger: ILogger) = | |
let orderIds = | |
[| | |
3312620 | |
3312620 | |
3312619 | |
|] |> Array.map (fun i -> $"%i{i}.json") | |
let mutable i = 0 | |
member this.GetIncomingOrder() = | |
task { | |
do! Async.Sleep (TimeSpan.FromSeconds 10) | |
if i < orderIds.Length - 1 then | |
let blobPath = orderIds[i] | |
i <- i + 1 | |
let blobClient = erpOrderContainer.GetBlobClient blobPath | |
let! content = blobClient.DownloadContentAsync() | |
if content.HasValue then | |
let json = content.Value.Content.ToString() | |
let orderId = blobPath |> System.IO.Path.GetFileNameWithoutExtension | |
match tryParse<int> orderId with | |
| None -> | |
logger.LogCritical($"Invalid order id %s{orderId}") | |
return None | |
| Some orderId -> | |
let message = | |
{ | |
IncomingOrder.OrderId = orderId | |
Order = json | |
} | |
return Some message | |
else | |
logger.LogError($"No content for blob %s{blobPath}") | |
return None | |
else | |
logger.LogError("No content for azure queue message") | |
return None | |
} | |
interface IErpOrderListener with | |
member this.GetIncomingOrder() = this.GetIncomingOrder() | |
type FakeListenerEnv = | |
inherit AppEnv | |
new (configuration) = | |
let logger = createConsoleLogger<FakeListenerEnv>() | |
let httpClientFactory = BullshitHttpFactory() | |
let serviceBusClient = ServiceBusClient(configuration.Infrastructure.ServiceBusConnection) | |
let blobClient = BlobServiceClient(configuration.Infrastructure.BlobConnection) | |
let customerDbClient = CustomerDb.clientForConnectionString configuration.Infrastructure.CustomerDbConnection | |
let orderDiffContainerClient = blobClient.GetBlobContainerClient("erp-order-diffs-test") | |
let ordersContainer = blobClient.GetBlobContainerClient("erp-orders") | |
let diffStorage = OrderDiffStorage.Client(orderDiffContainerClient) | |
let domainOrderStorage = OrderStorage.Client(customerDbClient) | |
let eventSender = OrderEventSender.Client(serviceBusClient) | |
let erpOrderListener = FakeErpOrderListener(ordersContainer, logger) | |
let catalogClient = | |
CatalogClient(httpClientFactory, catalogSettingOfConfig configuration.Infrastructure) | |
{ inherit AppEnv(diffStorage, domainOrderStorage, eventSender, catalogClient, erpOrderListener, configuration) } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment