sns.adoc 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. = SNS Integration
  2. https://aws.amazon.com/sns/[SNS] is a pub/sub messaging service that allows clients to publish notifications to a particuluar topic.
  3. A Spring Boot starter is provided to auto-configure SNS integration beans.
  4. Maven coordinates, using <<index.adoc#bill-of-materials, Spring Cloud AWS BOM>>:
  5. [source,xml]
  6. ----
  7. <dependency>
  8. <groupId>io.awspring.cloud</groupId>
  9. <artifactId>spring-cloud-aws-starter-sns</artifactId>
  10. </dependency>
  11. ----
  12. == Sending Notifications
  13. === SNS Template
  14. The starter automatically configures and registers a `SnsTemplate` bean providing higher level abstractions for sending SNS notifications.
  15. `SnsTemplate` implements Spring Messaging abstractions making it easy to combine with other messaging technologies compatible with Spring Messaging.
  16. It supports sending notifications with payload of type:
  17. * `String` - using `org.springframework.messaging.converter.StringMessageConverter`
  18. * `Object` - which gets serialized to JSON using `org.springframework.messaging.converter.MappingJackson2MessageConverter` and Jackson's `com.fasterxml.jackson.databind.ObjectMapper` autoconfigured by Spring Boot.
  19. Additionally, it exposes handful of methods supporting `org.springframework.messaging.Message`.
  20. [source,java]
  21. ----
  22. import io.awspring.cloud.sns.core.SnsTemplate;
  23. import org.springframework.messaging.Message;
  24. import org.springframework.messaging.support.MessageBuilder;
  25. class NotificationService {
  26. private final SnsTemplate snsTemplate;
  27. NotificationService(SnsTemplate snsTemplate) {
  28. this.snsTemplate = snsTemplate;
  29. }
  30. void sendNotification() {
  31. // sends String payload
  32. snsTemplate.sendNotification("topic-arn", "payload", "subject");
  33. // sends object serialized to JSON
  34. snsTemplate.sendNotification("topic-arn", new Person("John", "Doe"), "subject");
  35. // sends a Spring Messaging Message
  36. Message<String> message = MessageBuilder.withPayload("payload")
  37. .setHeader("header-name", "header-value")
  38. .build();
  39. snsTemplate.send("topic-arn", message);
  40. }
  41. }
  42. ----
  43. If autoconfigured converters do not meet your needs, you can provide a custom `SnsTemplate` bean with a message converter of your choice.
  44. When sending SNS notification, it is required to provide a topic ARN. Spring Cloud AWS simplifies it and allows providing a topic name instead, under a condition that topic with that name has already been created.
  45. Otherwise, Spring Cloud AWS will make an attempt to create topic with this name with a first call.
  46. The behavior of resolving topic ARN by a topic name can be altered by providing a custom bean of type `io.awspring.cloud.sns.core.TopicArnResolver`.
  47. If resolving topic name by create topic call is not possible you can autoconfigure Bean of `io.awspring.cloud.sns.core.TopicsListingTopicArnResolver`.
  48. Autoconfiguration will automatically configure `SnsTemplate` with `TopicArnResolverConfiguration`.
  49. ----
  50. import org.springframework.context.annotation.Bean;
  51. import org.springframework.context.annotation.Configuration;
  52. import software.amazon.awssdk.services.sns.SnsClient;
  53. import io.awspring.cloud.sns.core.TopicArnResolver;
  54. import io.awspring.cloud.sns.core.TopicsListingTopicArnResolver;
  55. @Configuration
  56. public class TopicArnResolverConfiguration {
  57. @Bean
  58. public TopicArnResolver topicArnResolver(SnsClient snsClient) {
  59. return new TopicsListingTopicArnResolver(snsClient);
  60. }
  61. }
  62. ----
  63. === SNS Operations
  64. Because of Spring Messaging compatibility, `SnsTemplate` exposes many methods that you may not need if you don't need Spring Messaging abstractions.
  65. In such case, we recommend using `SnsOperations` - an interface implemented by `SnsTemplate`, that exposes a convenient method for sending SNS notification, including support for FIFO topics.
  66. [source,java]
  67. ----
  68. import io.awspring.cloud.sns.core.SnsNotification;
  69. import io.awspring.cloud.sns.core.SnsOperations;
  70. import io.awspring.cloud.sns.core.SnsTemplate;
  71. class NotificationService {
  72. private final SnsOperations snsOperations;
  73. NotificationService(SnsOperations snsOperations) {
  74. this.snsOperations = snsOperations;
  75. }
  76. void sendNotification() {
  77. SnsNotification<Person> notification = SnsNotification.builder(new Person("John", "Doe"))
  78. .deduplicationId("..")
  79. .groupId("..")
  80. .build();
  81. snsOperations.sendNotification("topic-arn", notification);
  82. }
  83. }
  84. ----
  85. == Sending SMS Messages
  86. The starter automatically configures and registers a `SnsSmsTemplate` bean providing higher level abstractions for sending SMS messages to SNS topic or directly to a phone number.
  87. - https://docs.amazonaws.cn/en_us/sns/latest/dg/sns-mobile-phone-number-as-subscriber.html[Mobile text messaging (SMS)]
  88. - https://docs.amazonaws.cn/en_us/sns/latest/dg/sms_publish-to-phone.html[Publishing to a mobile phone]
  89. - https://docs.amazonaws.cn/en_us/sns/latest/dg/sms_publish-to-topic.html[Publishing to a topic]
  90. Both `SnsSmsTemplate#send` and `SnsSmsTemplate#sendToTopic` take an optional parameter `SnsMessageAttributes` that provide a fluent type safe interface for setting https://docs.aws.amazon.com/sns/latest/dg/sms_publish-to-phone.html[MessageAttributes]
  91. [source,java]
  92. ----
  93. import io.awspring.cloud.sns.sms.SmsMessageAttributes;
  94. import io.awspring.cloud.sns.sms.SmsType;
  95. import io.awspring.cloud.sns.sms.SnsSmsTemplate;
  96. class NotificationService {
  97. private SnsSmsTemplate smsTemplate;
  98. NotificationService(SnsSmsTemplate smsTemplate) {
  99. this.smsTemplate = smsTemplate;
  100. }
  101. void sendSms() {
  102. smsTemplate.send("+1XXX5550100", "the message", SmsMessageAttributes.builder()
  103. .smsType(SmsType.PROMOTIONAL).senderID("mySenderID").maxPrice("0.50").build());
  104. }
  105. }
  106. ----
  107. == Using SNS Client
  108. To have access to all lower level SNS operations, we recommend using `SnsClient` from AWS SDK. `SnsClient` bean is autoconfigured by `SnsAutoConfiguration`.
  109. If autoconfigured `SnsClient` bean configuration does not meet your needs, it can be replaced by creating a custom bean of type `SnsClient`.
  110. [source,java]
  111. ----
  112. import software.amazon.awssdk.services.sns.SnsClient;
  113. class NotificationService {
  114. private final SnsClient snsClient;
  115. public NotificationService(SnsClient snsClient) {
  116. this.snsClient = snsClient;
  117. }
  118. void sendNotification() {
  119. snsClient.publish(request -> request.topicArn("sns-topic-arn").message("payload"));
  120. }
  121. }
  122. ----
  123. == Annotation-driven HTTP notification endpoint
  124. SNS supports multiple endpoint types (SQS, Email, HTTP, HTTPS), Spring Cloud AWS provides support for HTTP(S) endpoints.
  125. SNS sends three type of requests to an HTTP topic listener endpoint, for each of them annotations are provided:
  126. * Subscription request -> `@NotificationSubscriptionMapping`
  127. * Notification request -> `@NotificationMessageMapping`
  128. * Unsubscription request -> `@NotificationUnsubscribeMapping`
  129. HTTP endpoints are based on Spring MVC controllers. Spring Cloud AWS added some custom argument resolvers to extract the message and subject out of the notification requests.
  130. Example of integration:
  131. [source,java]
  132. ----
  133. import io.awspring.cloud.sns.annotation.endpoint.NotificationMessageMapping;
  134. import io.awspring.cloud.sns.annotation.endpoint.NotificationSubscriptionMapping;
  135. import io.awspring.cloud.sns.annotation.endpoint.NotificationUnsubscribeConfirmationMapping;
  136. import io.awspring.cloud.sns.annotation.handlers.NotificationMessage;
  137. import io.awspring.cloud.sns.annotation.handlers.NotificationSubject;
  138. import io.awspring.cloud.sns.handlers.NotificationStatus;
  139. import org.springframework.stereotype.Controller;
  140. import org.springframework.web.bind.annotation.RequestMapping;
  141. @Controller
  142. @RequestMapping("/topicName")
  143. public class NotificationTestController {
  144. @NotificationSubscriptionMapping
  145. public void handleSubscriptionMessage(NotificationStatus status) {
  146. //We subscribe to start receive the message
  147. status.confirmSubscription();
  148. }
  149. @NotificationMessageMapping
  150. public void handleNotificationMessage(@NotificationSubject String subject, @NotificationMessage String message) {
  151. // ...
  152. }
  153. @NotificationUnsubscribeConfirmationMapping
  154. public void handleUnsubscribeMessage(NotificationStatus status) {
  155. //e.g. the client has been unsubscribed and we want to "re-subscribe"
  156. status.confirmSubscription();
  157. }
  158. }
  159. ----
  160. == Configuration
  161. The Spring Boot Starter for SNS provides the following configuration options:
  162. [cols="2,3,1,1"]
  163. |===
  164. | Name | Description | Required | Default value
  165. | `spring.cloud.aws.sns.enabled` | Enables the SNS integration. | No | `true`
  166. | `spring.cloud.aws.sns.endpoint` | Configures endpoint used by `SnsClient`. | No | `http://localhost:4566`
  167. | `spring.cloud.aws.sns.region` | Configures region used by `SnsClient`. | No | `eu-west-1`
  168. |===
  169. == IAM Permissions
  170. Following IAM permissions are required by Spring Cloud AWS:
  171. [cols="2,1"]
  172. |===
  173. | To publish notification to topic | `sns:Publish`
  174. | To publish notification you will also need | `sns:ListTopics`
  175. | To use Annotation-driven HTTP notification endpoint | `sns:ConfirmSubscription`
  176. | For resolving topic name to ARN | `sns:CreateTopic`
  177. |===
  178. Sample IAM policy granting access to SNS:
  179. [source,json,indent=0]
  180. ----
  181. {
  182. "Version": "2012-10-17",
  183. "Statement": [
  184. {
  185. "Effect": "Allow",
  186. "Action": [
  187. "sns:Publish",
  188. "sns:ConfirmSubscription"
  189. ],
  190. "Resource": "yourArn"
  191. },
  192. {
  193. "Effect": "Allow",
  194. "Action": "sns:ListTopics",
  195. "Resource": "*"
  196. },
  197. {
  198. "Effect": "Allow",
  199. "Action": "sns:CreateTopic",
  200. "Resource": "*"
  201. }
  202. ]
  203. }
  204. ----