宝石:通用市场模拟器

导航至

本文由 Rushil Shah 编写,他是 InfluxData 2022年夏季的软件工程实习生。

当前系统

InfluxData 在 AWS Marketplace 上列出其 SaaS 产品。这意味着 AWS 处理所有产品报告以及向客户设置支付。组织的任务(在本例中为 InfluxData)是注册并发布他们的产品在 AWS Marketplace 上。

然后客户可以访问 AWS,看到 InfluxData 产品选项列在他们的 AWS 账户页面上,订阅产品,这将他们重定向到 InfluxData 的官方产品注册页面。

这是一个简单的流程,AWS 对此也有良好的文档。然而,在原始应用程序(Quartz)中测试此入职流程是繁琐的,因为它依赖于 AWS 市场及其 API。这意味着用户注册的测试消耗了大量第三方资源。

为了消除这种依赖并确保在测试 Quartz 的用户入职时保持类似的流程,团队决定开发一个模拟器,该模拟器的行为与 AWS 完全相同,但在本地运行,并确保 Quartz 获得与 AWS Marketplace 相同的交互。

AWS Marketplace 注册背后的技术细节

尽管市场服务非常复杂,无法在此详细说明,但在开发模拟器时需要一些核心功能。

REST API

AWS 有自己的标识符来唯一标识每个用户。在与 Quartz 交互期间,它使用 REST POST 请求交换这些标识符和令牌,以确保安全和数据完整性,并在从 AWS 页面重定向到目标应用程序注册页面时使用。AWS 还发送这些标识符供将来用于计费记录和账单。有关特定 API 的更多信息,请参阅此处

AWS 简单通知服务

当用户订阅产品时,AWS 向应用程序发送一些通知,以确认用户端的订阅。应用程序在接收到这些通知后,开始计费流程。当用户取消订阅产品时,也会发送通知,让应用程序知道需要停止计费周期。AWS 使用其 SNS 服务记录这些通知的详细信息,请参阅此处

AWS 简单队列服务

SNS的工作方式是向接收者发送一次性的非持久通知。SNS不会保留已发送通知的记录。为了确保我们不会错过通知,我们使用AWS队列来存储这些通知,并定期轮询队列以获取和处理所有通知。有关将AWS Marketplace集成到SaaS产品中的更多信息,请参阅此处

宝石

宝石就像AWS Marketplace一样,模拟上述服务。它使用几个第三方依赖项来模仿AWS功能。宝石有自己的本地PostgreSQL数据库,用于存储用户详细信息,如标识符和AWS订阅状态。在其之上,所有发送到本地队列的通知都持久化存储在数据库中,以供将来分析和测试。

InfluxData在AW Marketplace中有多个产品,用户可以订阅其中任何一个。目前,宝石支持一个全局产品,具有静态的产品代码,并且所有宝石用户都订阅了它。

ElasticMQ简介

宝石模拟AWS的API、SNS和SQS服务。

为了模拟AWS SNS和AWS SQS的行为,并将有关用户订阅的通知发送到Quartz,我们使用ElasticMQ,这是一个内存中的消息队列系统。ElasticMQ可以作为一个独立的应用程序运行,或者通过Docker运行。在宝石中,其唯一目的是模拟SQS。

宝石发送类似于AWS发送的通知,包括所需的关键值对,除了宝石的消息发送到本地队列。为了接收这些消息,有必要配置Quartz以监听与宝石通信的特定本地队列。

玩宝石

宝石的用户界面非常简单直观。点击“新建用户”按钮。这将执行以下操作

  1. 生成一个带有所有所需标识符的假用户
  2. 将其订阅到产品。更新数据库,添加所需数据
  3. 向本地队列发送订阅成功通知
  4. 重定向到Quartz注册页面

AWS-user-index

Redirection-to-Quartz

create-subscription

一旦创建并订阅,每个用户都可以被删除取消订阅

点击“取消订阅”按钮将启动宝石向本地队列发送所需的通知,并相应地更改数据库状态。

Quartz轮询本地队列,读取消息,并相应地更新用户和订阅数据。

User-Index--purge

这就是在任何时候,ElasticMQ本地队列的状态将看起来像,其中消息仍然在队列中。

iex(5)> ExAws.SQS.receive_message(url) |> ExAws.request
{:ok,
 %{
   body: %{
     messages: [
       %{
         attributes: [],
         body: "{\"Message\":\"{\\\"action\\\":\\\"subscribe-success\\\",\\\"customer-identifier\\\":\\\"2e80e7d6-f289-49c4-a123-d054c6d6f263\\\",\\\"product-code\\\":\\\"24rvlw4j78h53941sycw25cwe\\\"}\"}",
         md5_of_body: "b620f4bbfe060195a38418c3279f6fe2",
         message_attributes: [],
         message_id: "0a17fe27-98b7-45fb-a7d9-4512e1416b6b",
         receipt_handle: "0a17fe27-98b7-45fb-a7d9-4512e1416b6b#fcba1214-260e-477a-869d-269d4c33bc63"
       }
     ],
     request_id: "00000000-0000-0000-0000-000000000000"
   },
   headers: [
     {"Server", "akka-http/10.2.9"},
     {"Date", "Fri, 19 Aug 2022 21:01:44 GMT"},
     {"Content-Type", "text/xml; charset=UTF-8"},
     {"Content-Length", "910"}
   ],
   status_code: 200
 }}

未来范围

GEMS应用程序可以扩展以包括其他服务,如计费和计费,以在没有AWS依赖项的情况下对其进行测试。宝石与其他云服务(如GCP和Azure)类似工作。尽管它们具有完全不同的基础设施和工作流程,但通过访问适当的文档和资源,这样做是可能的。

结论

该项目涵盖了API设计的各个方面、几个标准函数编程模式和测试驱动开发。总的来说,这次经历学习曲线陡峭,非常难忘。