Gems:通用市场模拟器

导航至

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

当前系统

InfluxData 在 AWS Marketplace 上列出其 SaaS 产品。这意味着 AWS 处理所有产品报告并为客户设置付款。组织(在本例中为 InfluxData)的工作是在 AWS Marketplace 上注册和发布其产品。

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

这是一个简单的过程,AWS 为此提供了良好的文档。但是,在原始应用程序 (Quartz) 中测试此入职流程很麻烦,因为它依赖于 AWS Marketplace 及其 API。这意味着测试用户注册会消耗大量第三方资源。

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

AWS Marketplace 注册的幕后

尽管 Marketplace 服务非常复杂,无法在此处详细介绍,但在开发模拟器时仍需要一些核心功能。

REST API

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

AWS Simple Notification Service

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

AWS Simple Queue Service

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

Gems

Gems 的作用就像 AWS Marketplace,并模拟上述服务。它使用多个第三方依赖项来模拟 AWS 功能。Gems 具有本地 PostgreSQL 数据库,用于存储用户详细信息,如标识符和 AWS 订阅状态。最重要的是,发送到本地队列的所有通知都持久存储在数据库中,以供将来分析和测试。

InfluxData 在 AW Marketplace 中列出了多个产品,用户可以订阅其中任何一个。Gems 目前支持具有静态产品代码的单个全局产品,所有 Gems 用户都订阅该产品。

ElasticMQ 简介

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

为了模拟 AWS SNS 和 AWS SQS 的行为并发送关于用户订阅给 Quartz 的通知,我们使用 ElasticMQ,这是一个内存消息队列系统。ElasticMQ 既可以作为独立应用程序运行,也可以通过 Docker 运行。它在 Gems 中的唯一目的是模拟 SQS。

Gems 发送类似于 AWS 发送的通知,以及所需的键值对,只是 Gems 消息进入本地队列。为了接收这些消息,有必要配置 Quartz 以侦听与 Gems 通信的特定本地队列。

使用 Gems

Gems UI 非常简单明了。单击“新建用户”按钮。这将执行以下操作

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

AWS-user-index

Redirection-to-Quartz

create-subscription

创建和订阅后,每个用户都可以删除取消订阅

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

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 依赖项的情况下对其进行测试。Gems 与其他云服务(如 GCP 和 Azure)的工作方式类似。尽管它们具有完全不同的基础设施和工作流程,但访问适当的文档和资源使得这样做成为可能。

结论

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