如何在本地测试 AWS SNS?

Posted

技术标签:

【中文标题】如何在本地测试 AWS SNS?【英文标题】:How to test AWS SNS locally? 【发布时间】:2017-07-23 12:35:04 【问题描述】:

我想使用Amazon SNS service。我希望能够订阅 http rest to SNS 主题以接收通知。

但是,我的应用程序在本地的 URL 为 localhost,因此我无法在本地测试应用程序的行为。

我发现一篇关于使用ngrok 服务器的文章,使用一些公共IP 而不是本地IP。

但是对我来说这似乎不是一个好的解决方案。

您有什么想法可以让我在本地拥有一个工作的SNS 订阅者吗?

【问题讨论】:

【参考方案1】:

您也可以使用ngrok 公开您的本地主机。

它的工作方式是动态创建一个子域,并将所有请求通过隧道传输到所需端口上的计算机。

想象一下这个场景,我在 localhost:8080 上运行了一个 nginx。 我打开终端并运行ngrok 8080,它将占用我的终端会话并记录我的公共网址,例如“as78fh.ngrok.com”。

如果我在另一台计算机上,打开浏览器并导航到 as78fh.ngrok.com/register 请求从我的 localhost:8080/register 通过隧道返回到 Internet 提供服务。

我将它用于许多棘手的开发,例如电子邮件 webhook、github 集成,当然还有 amazon sns。

【讨论】:

我使用了 ngrok,并使用它公开了我的网络服务,我在我的 AWS SNS 中创建了一个订阅,不幸的是,我没有收到确认消息!你知道是什么原因造成的吗? 嘿,访问 127.0.0.1:4040 并检查消息是否到达您的端点。如果是,问题可能是代码,如果消息没有到达您的隧道,请尝试使用 sns 面板重新发送确认 是的,我可以看到消息正在到达我的隧道,但我不知道为什么端点的代码没有执行。 好吧,好消息是它现在都在你的机器上了!检查 url 是否匹配,如果它返回 200。发生这种情况时我喜欢做的一件事是在第一行返回响应,只是为了检查完整的流程! 我正在尝试使用 admin:admin@blablabla.ngrok.io/api/core/v3/sns 的模式调用我在本地实现的 web 服务,它正在工作,但奇怪的是,当 aws sns 调用我的 web 服务时,响应代码是 401。 【参考方案2】:

看看GitHub中的一个假SNS实现,比如s12v/sns:

用于测试的伪造 Amazon Simple Notification Service (SNS)。支持:

创建/列出/删除主题 订阅端点 发布消息 订阅持久化 与(假)SQS、文件、HTTP、RabbitMQ、Slack 集成

【讨论】:

似乎它不适用于最新的sdk。 AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration("localhost:9911", "us-east-1"); AmazonSNS amazonSNSClient = AmazonSNSClientBuilder.standard() .withEndpointConfiguration(endpointConfiguration) .build(); System.out.println(amazonSNSClient.listTopics());如果我运行一个简单的代码 - 我收到一个错误:线程“主”SdkClientException 中的异常:无法执行 HTTP 请求:无法识别的 SSL 消息,明文连接?【参考方案3】:

我喜欢 ngrok,但您需要付费才能拥有一个固定的外部地址,如果您想免费使用,您可以使用备用电子邮件帐户收件箱发送 Email-JSON sns。然后是一个 IMAP 库来访问它、阅读电子邮件并通过管道传输数据。

【讨论】:

【参考方案4】:

我写了一个模仿 AWS SNS 的小型 library,我认为它符合您的需求。下面是一个Java中的用法示例:

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.sns.AmazonSNS;
import com.amazonaws.services.sns.AmazonSNSAsyncClientBuilder;
import io.github.gilbertojrequena.bonsai_sns.server.BonsaiSnsEnvironment;
import io.github.gilbertojrequena.bonsai_sns.server.BonsaiSnsServer;
import io.github.gilbertojrequena.bonsai_sns.server.Subscription;
import io.github.gilbertojrequena.bonsai_sns.server.Topic;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class SNSTest 

    private BonsaiSnsServer server;
    private AmazonSNS snsClient;

    @Before
    public void setup() 
        // start your app at 8080

        server = new BonsaiSnsServer.Builder()
            .withAccountId(123456789L)
            .withPort(7979)
            .withRegion("someRegion")
            .withBonsaiSnsEnvironmentDefinition(
                BonsaiSnsEnvironment.Companion.definition()
                    .withTopic(
                        Topic.Companion.definition()
                            .withName("name")
                            .withSubscription(
                                Subscription.Companion.definition()
                                    .withEndpoint("http:/localhost:8080/endpoint")
                                    .withProtocol("http")
                                    .withAttribute("a", "b")
                            )
                    )
            ).start();

        snsClient = AmazonSNSAsyncClientBuilder.standard()
            .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("accessKey", "secretKey")))
            .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("http://localhost:7979", "someRegion"))
            .build();
    

    @After
    public void shutdown() 
        server.stop();
    

    @Test
    public void testSomething() 
        snsClient.publish("arn:aws:sns:someRegion:123456789:name", "message");
        // assertions
    

【讨论】:

以上是关于如何在本地测试 AWS SNS?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 aws sns 中注册 iOS 设备令牌以接收推送通知?

如何在 Android (Xamarin) 上为 AWS SNS 启用推送通知

如何在 nodejs 中使用 FCM 发送 AWS SNS 推送通知?

我如何通过AWS SNS设置有关上传事件的AWS S3?

如何使用 AWS CloudFormation 为 SNS 订阅指定“原始消息传递”?

如何删除未确认的 AWS SNS 订阅