订阅确认支持

https://blueprints.launchpad.net/zaqar/+spec/subscription-confirmation-support

支持订阅者在 Zaqar 发送通知之前确认他们是否需要这些通知。

问题描述

目前 Zaqar 可以在订阅创建后向订阅者发布通知。它不需要订阅者确认订阅。这将导致一个问题,即用户可能会发送订阅者不需要的垃圾信息。

提议的变更

参考 Amazon SNS,我们将支持发送包含订阅确认信息(例如,消息类型、预签名确认 URL、签名信息)的 HTTP POST 请求到订阅端点。端点需要使用通知中的 URL 来确认订阅。当订阅被删除时,Zaqar 服务器将发送一个通知,表明该 ID 的订阅已被删除。这种机制告诉端点不再需要等待通知了。

  • 消息类型将为 SubscriptionConfirmation、Notification 和 UnsubscribeConfirmation。

  • 为了向后兼容,我们还应该在 Zaqar 配置文件中添加一个新的选项,如下所示

    [notification]
    require_confirmation=true/false
    

如果用户在配置文件中省略此选项,则默认值为“false”。 进一步,我们可以更改默认值为“true”,以使订阅更加安全。

因此,webhook 中的流程将如下所示

  1. 用户在 Zaqar 中创建订阅。

  2. Zaqar 发送一个包含订阅确认信息的 HTTP POST 请求。此请求如下所示

    POST URL

    http://endpointUrl
    

    请求体

     {
         'MessageType': 'SubscriptionConfirmation',
         'Message': 'You have chosen to subscribe to the queue: xxx.',
         'URL-Signature': 'xxxx',
         'URL-METHODS': 'PUT',
         'URL-PATHS': '/v2/queues/{queue_name}/subscriptions/{subscriptions_id}/confirm',
         'X-PROJECT-ID': 'xxxx',
         'URL-EXPIRES': '3600-01-01T00:00:00',
         'SubscribeURL': 'https://zaqar_server/v2/queues/{queue_name}/subscriptions/{subscriptions_id}/confirm',
         'SubscribeBody': {'confirmed': True},
         'UnsubscribeBody': {'confirmed': False},
    }
    
  3. 订阅者使用请求体中的信息确认此订阅,并将预签名的确认请求发送到 Zaqar。这是 Zaqar 中的一个新端点。此请求如下所示

    PUT URL

    https://zaqar_server/v2/queues/{queue_name}/subscriptions/{subscriptions_id}/confirm
    

    请求体

    {
        'confirmed': True
    }
    

    同时,使用 Zaqar 中的预签名功能也需要 HTTP 标头。如果订阅者想要取消订阅,只需将“confirmed”设置为 False。如果 Zaqar 成功处理此请求,Zaqar 将响应

    响应代码

    204
    

    如果 Zaqar 由于某种错误而未能处理此请求,它将在响应体中返回错误消息。

  4. 确认工作流完成后,Zaqar 开始向此端点发送通知。

注意

如果 Zaqar 服务器未收到响应,或者订阅者由于某些错误而未发送响应,则订阅将保持“confirmed”为 false,并且 Zaqar 将支持通过再次调用订阅创建 API 来重新发送确认请求。

因此,电子邮件中的流程将如下所示

  1. 用户在 Zaqar 中创建订阅。

  2. Zaqar 发送一封包含订阅确认页面链接的电子邮件。电子邮件内容如下:: “您已选择订阅队列:{queue name}。” “此队列属于项目:{project id}。” “要确认此订阅,请单击或访问以下链接:” “{confirmation link}”

  3. 当订阅者访问此链接时,他会获得一个页面,该页面通过 ajax 请求调用 Zaqar 以确认订阅,就像 webhook 方式一样。

  4. 该页面显示有关订阅是否成功确认的信息。

  5. Zaqar 开始向此端点发送通知。

注意

关于确认页面,Zaqar 将在 Zaqar 树中托管一个示例页面,但它不是 Zaqar 服务的一部分。云管理员应手动提供此页面的托管。成功托管此页面后,云管理员应在 Zaqar 配置“external_confirmation_url”中指定此页面位置。

缺点

备选方案

另一种选择是,当订阅者创建订阅时,他还需要调用 Zaqar 的确认 API 在确认过期之前确认它。在这种选项中,Zaqar 不会自行发送任何确认通知。

数据模型影响

在订阅模型中添加新的状态“confirmed”。

AWS SNS API 和 Zaqar API 比较

为了让开发人员更好地理解此功能,此规范比较了 SNS API 和 Zaqar API 之间的区别。

订阅确认请求 SNS 使用 GET 请求,如下所示

GET https://sns.us-west-2.amazonaws.com/?Action=ConfirmSubscription&TopicArn={Topic}&Token={Token}

Zaqar 使用 PUT 请求,如下所示

PUT https://zaqar_server/v2/queues/{queue_name}/subscriptions/{subscriptions_id}/confirm

请求体

{
    'confirmed': True
}

实现

负责人

主要负责人

wangxiyuan<wangxiyuan@huawei.com>

二级分配人

wanghao<wanghao749@huawei.com>

里程碑

完成目标里程碑

Newton-3

工作项

  1. 在 wsgi 中实现订阅者确认 API。

  2. 更新订阅资源以在 MongoDB 驱动程序上添加新的属性“confirmed”。

  3. 添加新的配置选项。

  4. 更新通知以通过电子邮件发送确认消息。

  5. 在 websocket 中实现订阅者确认 API。

  6. 更新其他驱动程序上的订阅资源。

  7. 更新通知以通过 webhook 发送确认消息。

  8. 添加消息类型。

依赖项

Amazon SNS: http://docs.aws.amazon.com/sns/latest/dg/SendMessageToHttp.html