使用 Java spring cloud aws 确认 SNS 通知时出现 InvalidParameterException

Posted

技术标签:

【中文标题】使用 Java spring cloud aws 确认 SNS 通知时出现 InvalidParameterException【英文标题】:InvalidParameterException while confirming SNS notification using Java spring cloud aws 【发布时间】:2016-07-03 12:00:33 【问题描述】:

我有使用 Spring-aws-cloud 编写的 SNS http 端点。我遵循以下tutorial。当我从我的 SNS 主题请求确认时,我从我的应用程序控制台收到以下错误。似乎 status.confirmSubscription() 失败了。 我得到的错误是:

zonaws.services.sns.model.InvalidParameterException: Invalid parameter: TopicArn (Service: AmazonSNS; Status Code: 400; Error Code: InvalidParameter; Request ID: d47581bd-789f-58f0-b976-ced91fec6929)
        at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:1383) ~[aws-java-sdk-core-1.10.61.jar:na]
        at com.amazonaws.http.AmazonHttpClient.executeOneRequest(AmazonHttpClient.java:902) ~[aws-java-sdk-core-1.10.61.jar:na]
        at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:607) ~[aws-java-sdk-core-1.10.61.jar:na]
        at com.amazonaws.http.AmazonHttpClient.doExecute(AmazonHttpClient.java:376) ~[aws-java-sdk-core-1.10.61.jar:na]
        at com.amazonaws.http.AmazonHttpClient.executeWithTimer(AmazonHttpClient.java:338) ~[aws-java-sdk-core-1.10.61.jar:na]
        at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:287) ~[aws-java-sdk-core-1.10.61.jar:na]
        at com.amazonaws.services.sns.AmazonSNSClient.invoke(AmazonSNSClient.java:2459) ~[aws-java-sdk-sns-1.10.7.jar:na]
        at com.amazonaws.services.sns.AmazonSNSClient.confirmSubscription(AmazonSNSClient.java:284) ~[aws-java-sdk-sns-1.10.7.jar:na]
        at com.amazonaws.services.sns.AmazonSNSClient.confirmSubscription(AmazonSNSClient.java:1761) ~[aws-java-sdk-sns-1.10.7.jar:na]
        at org.springframework.cloud.aws.messaging.endpoint.NotificationStatusHandlerMethodArgumentResolver$AmazonSnsNotificationStatus.confirmSubscription(NotificationStatusHandlerMethodArgumentResolver.java:62) ~[spring-cloud-aws-messaging-1.0.4.RELEASE.jar:1.0.4.RELEASE]
        at com.fastretailing.catalogPlatformSCMProducer.controller.SNSController.handleSubscriptionMessage(SNSController.java:73) ~[classes/:na]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_45]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_45]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_45]
        at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_45]
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:222) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:969) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:871) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) ~[tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:845) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) ~[tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.0.30.jar:8.0.30]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) ~[tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) [tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521) [tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096) [tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674) [tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) [tomcat-embed-core-8.0.30.jar:8.0.30]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) [tomcat-embed-core-8.0.30.jar:8.0.30]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_45]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_45]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.30.jar:8.0.30]
        at java.lang.Thread.run(Thread.java:745) [na:1.8.0_45]

我的 pom.xml 如下。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>

      <groupId>com.fastretailing.fr-cpf-scm-producer</groupId>
      <artifactId>fr-cpf-scm-producer</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>jar</packaging>
      <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.2.RELEASE</version>
      </parent>

      <dependencies>
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>

        </dependency>


        <!-- Spring cloud for SNS http endpoint-->
        <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-aws-messaging</artifactId>
          <version>1.0.4.RELEASE</version>
        </dependency>
        <!-- For Spring AWS autoconfiguration-->
        <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-aws-autoconfigure</artifactId>
          <version>1.0.4.RELEASE</version>
        </dependency>
        <!-- Apache commons-->
        <dependency>
          <groupId>org.apache.commons</groupId>
          <artifactId>commons-io</artifactId>
          <version>1.3.2</version>
        </dependency>
        <!-- Amazon s3 client-->
        <dependency>
          <groupId>com.amazonaws</groupId>
          <artifactId>aws-java-sdk-s3</artifactId>
          <version> 1.10.61</version>
        </dependency>

        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-batch</artifactId>
        </dependency>
        <!-- Mongo client -->
        <dependency>
          <groupId>org.springframework.data</groupId>
          <artifactId>spring-data-mongodb</artifactId>
          <version>1.8.4.RELEASE</version>
        </dependency>

        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>



        <dependency>
          <groupId>org.springframework.batch</groupId>
          <artifactId>spring-batch-test</artifactId>
          <version>3.0.6.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>5.1.38</version>
        </dependency>
        <dependency>
          <groupId>org.apache.kafka</groupId>
          <artifactId>kafka_2.10</artifactId>
          <version>0.9.0.1</version>
          <exclusions>
            <exclusion>
              <groupId>org.slf4j</groupId>
              <artifactId>slf4j-log4j12</artifactId>
            </exclusion>
          </exclusions>
        </dependency>

      </dependencies>

      <properties>
        <java.version>1.8</java.version>
        <spring-cloud-version>1.0.0.RELEASE</spring-cloud-version>
      </properties>


      <build>
        <resources>
          <resource>
            <directory>config</directory>
          </resource>
        </resources>

        <plugins>
          <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
          </plugin>
        </plugins>
      </build>

    </project>

【问题讨论】:

我想补充一些说明,因为我遇到了同样的问题。问题是 TopicARN 在订阅确认消息中被 URLEncoded。在偶然发现这篇文章后,我注意到我的订阅确认被发送到了一个 us-east URL。明确设置区域后,我可以订阅没有问题。 【参考方案1】:

就像比尔说的,需要配置区域。下面是一些示例代码:

return AmazonSNSClientBuilder.standard()
        .withRegion(Regions.US_WEST_2)
        .build();

有关详细信息,请参阅

http://docs.aws.amazon.com/java-sdk/latest/developer-guide/creating-clients.html

【讨论】:

【参考方案2】:

这是固定的。问题在于区域配置。对于 Spring aws cloud,我们必须禁用区域的自动检测,并且需要配置所需的区域。

【讨论】:

【参考方案3】:

我也遇到过同样的问题,我已经参考了这个link。 事实上,我的问题是:主题/目标 arn 是针对 us-west-2 的。但是我的 SNS 客户端默认指向 ap-southeast-1

其实这个link也是这么说的:

主题/目标 arn 适用于 us-west-2。但是,您的 SNS 客户端默认指向 us-east-1。您需要像这样在 snsClient 上调用 setRegion: snsClient.setRegion(Region.getRegion(Regions.US_WEST_2));

它可能对某些人有所帮助。

【讨论】:

以上是关于使用 Java spring cloud aws 确认 SNS 通知时出现 InvalidParameterException的主要内容,如果未能解决你的问题,请参考以下文章

如何在本地使用 spring-cloud-starter-aws 运行应用程序?

防止 spring-cloud-aws-messaging 尝试停止队列

使用 Spring Cloud AWS 自动配置担任角色

带有 Spring-cloud-aws 和 cloudwatch 指标的 Spring Boot

使用 Spring Cloud 的目的是啥? AWS 和 Springcloud 有啥区别?

AWS 实例配置文件不适用于 Spring Cloud AWS