post-image

Messaging: Einrichtung Publish/Subscribe mit AWS SQS und AWS SNS


Ziel des Beitrags

In diesem Beitrag wird gezeigt wie AWS SNS und SQS zur Realisierung von Publish/Subscribe Kommunikation zwischen Diensten eingerichtet werden und die Funktionsweite mit dem AWS CLI getestet werden kann.

Dieser Artikel gehört zu einer Reihe von Beiträgen, die sich mit Messaging mit Hilfe von SNS und SQS auf der Cloud-Plattform AWS beschäftigen. Die weiteren Beiträge sind:

  1. Eigenschaften von AWS SQS und AWS SNS
  2. Einrichtung von Point-to-Point Messaging mit AWS SQS
  3. Messaging: AWS SQS und SNS mit Java nutzen

Publish/Subscribe mit SNS und SQS

Anlegen der SQS Subscriber Queues

Wir legen für jeden Nachrichten-Empfänger eine eigene Standard-Queue an (hier 2), da SNS nur mit diesen zusammen arbeitet

:~$ docker run --rm -it -v ~/aws-cli:/root/.aws amazon/aws-cli sqs create-queue --queue-name subscriber1
{
    "QueueUrl": "https://sqs.eu-west-1.amazonaws.com/XXXXXXYYYYYY/subscriber1"
}
:~$ docker run --rm -it -v ~/aws-cli:/root/.aws amazon/aws-cli sqs create-queue --queue-name subscriber2
{
    "QueueUrl": "https://sqs.eu-west-1.amazonaws.com/XXXXXXYYYYYY/subscriber2"
}

SNS berechtigen an die Subscriber Queues zu senden

Um die Berechtigungen für das Topic zum Zugriff auf die Queues zu setzen, benötigen wir von allen 3 Ressourcen die arn.

Ermitteln der arn für das Topic:

:~$ docker run --rm -it -v ~/aws-cli:/root/.aws amazon/aws-cli sns list-topics
{
    "Topics": [
        {
            "TopicArn": "arn:aws:sns:eu-west-1:935581097791:TestTopic"
        }
    ]
}

Ermitteln der arn für unsere beiden Queues:

:~$ docker run --rm -it -v ~/aws-cli:/root/.aws amazon/aws-cli sqs get-queue-attributes --queue-url https://sqs.eu-west-1.amazonaws.com/935581097791/subscriber1 --attribute-names QueueArn
{
    "Attributes": {
        "QueueArn": "arn:aws:sqs:eu-west-1:935581097791:subscriber1"
    }
}
:~$ docker run --rm -it -v ~/aws-cli:/root/.aws amazon/aws-cli sqs get-queue-attributes --queue-url https://sqs.eu-west-1.amazonaws.com/935581097791/subscriber2 --attribute-names QueueArn
{
    "Attributes": {
        "QueueArn": "arn:aws:sqs:eu-west-1:935581097791:subscriber2"
    }
}

Folgenden Inhalt in die Datei subscriber2-policy.json speichern, um dem zuvor angelegten Topic die Berechtigung zum Zugriff auf die Queue subscriber1 zu geben.

{
    "Policy": "{\"Version\": \"2012-10-17\", \"Id\": \"TestTopic-to-subscriber1\", \"Statement\": [{ \"Effect\":\"Allow\", \"Principal\": { \"Service\": \"sns.amazonaws.com\" }, \"Action\":\"sqs:SendMessage\", \"Resource\":\"arn:aws:sqs:eu-west-1:935581097791:subscriber1\", \"Condition\":{ \"ArnEquals\":{ \"aws:SourceArn\":\"arn:aws:sns:eu-west-1:935581097791:TestTopic\" } } }] }"
}

Folgenden Inhalt analog zum vorherigen Beispiel in die Datei subscriber2-policy.json speichern:

{
    "Policy": "{\"Version\": \"2012-10-17\", \"Id\": \"TestTopic-to-subscriber2\", \"Statement\": [{ \"Effect\":\"Allow\", \"Principal\": { \"Service\": \"sns.amazonaws.com\" }, \"Action\":\"sqs:SendMessage\", \"Resource\":\"arn:aws:sqs:eu-west-1:935581097791:subscriber2\", \"Condition\":{ \"ArnEquals\":{ \"aws:SourceArn\":\"arn:aws:sns:eu-west-1:935581097791:TestTopic\" } } }] }"
}

Die Berechtigungen für die beiden Queues setzen, indem die Attribute aus den beiden zuvor angelegten Dateien zu den Queues hinzugefügt werden. Hier dabei darauf achten, dass das aktuelle Verzeichnis, in dem die Dateien liegen auf den Pfad ````/root/tmp``` innerhalb des ausgeführten docker containers gesetzt wird und der URI entsprechend zu setzen ist.

:~$ docker run --rm -it -v ~/aws-cli:/root/.aws -v ${PWD}:/root/tmp amazon/aws-cli sqs set-queue-attributes --queue-url https://sqs.eu-west-1.amazonaws.com/935581097791/subscriber1 --attributes file:///root/tmp/subscriber1-policy.json
:~$ docker run --rm -it -v ~/aws-cli:/root/.aws -v ${PWD}:/root/tmp amazon/aws-cli sqs set-queue-attributes --queue-url https://sqs.eu-west-1.amazonaws.com/935581097791/subscriber2 --attributes file:///root/tmp/subscriber2-policy.json

SQS Queues mit SNS Topic verbinden

Um Nachrichten vom Topic in die Queues zu bekommen müssen die beiden Queues noch am Topic registriert werden. Diese Subscription wird ebenfalls mit einer àrn addressiert. Über diese können dann die Registrierungen wieder gelöscht oder verwaltet werden. Wir benötigen wieder die zuvor ermittelten arn für das Topic und die Queues.

:~$ docker run --rm -it -v ~/aws-cli:/root/.aws amazon/aws-cli sns subscribe --topic-arn arn:aws:sns:eu-west-1:935581097791:TestTopic --protocol sqs --notification-endpoint arn:aws:sqs:eu-west-1:935581097791:subscriber1
{
    "SubscriptionArn": "arn:aws:sns:eu-west-1:935581097791:TestTopic:4f38a88a-3e52-44b5-a060-e9eb17bc6397"
}
:~$ docker run --rm -it -v ~/aws-cli:/root/.aws amazon/aws-cli sns subscribe --topic-arn arn:aws:sns:eu-west-1:935581097791:TestTopic --protocol sqs --notification-endpoint arn:aws:sqs:eu-west-1:935581097791:subscriber2
{
    "SubscriptionArn": "arn:aws:sns:eu-west-1:935581097791:TestTopic:1a47b195-c1c2-4f20-b4c8-ad5f67460ac4"
}

Nun können wir eine Testnachricht veröffentlichen:

:~$ docker run --rm -it -v ~/aws-cli:/root/.aws amazon/aws-cli sns publish --message "Publish/Subscribe message" --topic-arn arn:aws:sns:eu-west-1:935581097791:TestTopic
{
    "MessageId": "0b97d1e1-9bf7-5412-835f-8663cdd7eae2"
}

Und in den jeweiligen Queues subscriber1 und subscriber2 die Nachricht abholen und löschen:

:~$ docker run --rm -it -v ~/aws-cli:/root/.aws amazon/aws-cli sqs receive-message --queue-url https://sqs.eu-west-1.amazonaws.com/935581097791/subscriber1
{
    "Messages": [
        {
            "MessageId": "5a0e0067-2eb3-4cfd-8238-046569248380",
            "ReceiptHandle": "AQEBNuZSYobYMX4IooJDxodX7y/J7OIElKFkqVPkh1/7ATxPhoaxNg8eIVSdJ0xfMO180SEek9mwbEhKPK86WvJPH6Lx379WMgGmNYORPiabmWg6PflFig7jvldOoLFXcryJL4vJsqvmF6cPBzWOlBRTv4JxS1052WtWtv9ZbsZ60hPlEkWX95PgLZJ3wMQtMjhRlJ7/FQMUCmZvXhEE8ZRKqc0YXyBetNwErDXQf+YlHQNHdwihI6wz18V2TODcSknqpj3nn33vwjc9QvGsut5aJh0EPwXAGxiwxz670TeAi3VvooWkAwbRKDCDroJuR+27yiT5WsALSgBSy2oHQPTT1Xe4B+TYSe7rBMWd43G+WDQffEX6HbHeyQY4VU0grUMb",
            "MD5OfBody": "84ba854f4e20c06196a4dea7ec93cfed",
            "Body": "{\n  \"Type\" : \"Notification\",\n  \"MessageId\" : \"0b97d1e1-9bf7-5412-835f-8663cdd7eae2\",\n  \"TopicArn\" : \"arn:aws:sns:eu-west-1:935581097791:TestTopic\",\n  \"Message\" : \"Publish/Subscribe message\",\n  \"Timestamp\" : \"2020-07-10T11:41:20.382Z\",\n  \"SignatureVersion\" : \"1\",\n  \"Signature\" : \"RKyx47hdxSNFFSHVXU+nIsrw260+pVrSU/oVayN4T72zCDp2JpYaKOzVpLcnVA/iLz0YlFhAHX7nXyJV2MvhMGVqfhDDzEZtt1gUJ5ZdyMcMT1Y05Y9zocDYEpsY0KN4VxasRA0iRAWVvYQ7i73Buwaf8H0rjqewhcAiwzbjI9lyxZzUCSmkxGUHDCU+G/C4Fp/hMMIu/hhO139QnEwZu16qND+2YY0F/IhGZ7ty/Vn9K2evs9Gm4U9RQTuqSBl0n9Ya7fDIUUSCdmxuq1PkWe5DXe1Rg9u423ljxI8vISDPKxiAi99GyKPvbVPaxkaa80Ro6a+yv/2xTVc1Yqj+Vg==\",\n  \"SigningCertURL\" : \"https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-a86cb10b4e1f29c941702d737128f7b6.pem\",\n  \"UnsubscribeURL\" : \"https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:935581097791:TestTopic:4f38a88a-3e52-44b5-a060-e9eb17bc6397\"\n}"
        }
    ]
}
:~$ docker run --rm -it -v ~/aws-cli:/root/.aws amazon/aws-cli sqs delete-message --queue-url https://sqs.eu-west-1.amazonaws.com/935581097791/subscriber1 --receipt-handle AQEBNuZSYobYMX4IooJDxodX7y/J7OIElKFkqVPkh1/7ATxPhoaxNg8eIVSdJ0xfMO180SEek9mwbEhKPK86WvJPH6Lx379WMgGmNYORPiabmWg6PflFig7jvldOoLFXcryJL4vJsqvmF6cPBzWOlBRTv4JxS1052WtWtv9ZbsZ60hPlEkWX95PgLZJ3wMQtMjhRlJ7/FQMUCmZvXhEE8ZRKqc0YXyBetNwErDXQf+YlHQNHdwihI6wz18V2TODcSknqpj3nn33vwjc9QvGsut5aJh0EPwXAGxiwxz670TeAi3VvooWkAwbRKDCDroJuR+27yiT5WsALSgBSy2oHQPTT1Xe4B+TYSe7rBMWd43G+WDQffEX6HbHeyQY4VU0grUMb
:~$ docker run --rm -it -v ~/aws-cli:/root/.aws amazon/aws-cli sqs receive-message --queue-url https://sqs.eu-west-1.amazonaws.com/935581097791/subscriber2
{
    "Messages": [
        {
            "MessageId": "0c937b55-82d9-40e7-a027-37071f2d1a63",
            "ReceiptHandle": "AQEBBBApDl3faFWlqjcg2wAPzn2WZ5NtDncfpoQwOiLm36Q2kqUlQtPaftCl13awc0UWBuMaCb76sf6k2+J1d7xUPa6Bqk1xxdOf99v8sO6cVPDAGitl6FPUQ4oCqRqNEuIexL6y/U5iH72o04Mu8OTnM/0r0l17uqqfkWiR+8q8w2Xl0VNXZUGDzudj6p/XBGoLgmqYQfkA02zhHL4+MDE+NSNxrv6wZCSMHAbI/pbBp//gG08Z5AnTD9t/YbNvtFK/+yEUdtPeNrGCoIGOgHumZYuTu7BW4ojDflGrEn8qV2ewaJcKEvzbusTvPlc1MrgNUcGq+y8njIT9ceFQOSBha05f98lwRBPiKBkh5NNFtC/iKUjtCY64JjzGMC+G8kwr",
            "MD5OfBody": "e23fb67b859ceea8549babf0383f17f9",
            "Body": "{\n  \"Type\" : \"Notification\",\n  \"MessageId\" : \"0b97d1e1-9bf7-5412-835f-8663cdd7eae2\",\n  \"TopicArn\" : \"arn:aws:sns:eu-west-1:935581097791:TestTopic\",\n  \"Message\" : \"Publish/Subscribe message\",\n  \"Timestamp\" : \"2020-07-10T11:41:20.382Z\",\n  \"SignatureVersion\" : \"1\",\n  \"Signature\" : \"RKyx47hdxSNFFSHVXU+nIsrw260+pVrSU/oVayN4T72zCDp2JpYaKOzVpLcnVA/iLz0YlFhAHX7nXyJV2MvhMGVqfhDDzEZtt1gUJ5ZdyMcMT1Y05Y9zocDYEpsY0KN4VxasRA0iRAWVvYQ7i73Buwaf8H0rjqewhcAiwzbjI9lyxZzUCSmkxGUHDCU+G/C4Fp/hMMIu/hhO139QnEwZu16qND+2YY0F/IhGZ7ty/Vn9K2evs9Gm4U9RQTuqSBl0n9Ya7fDIUUSCdmxuq1PkWe5DXe1Rg9u423ljxI8vISDPKxiAi99GyKPvbVPaxkaa80Ro6a+yv/2xTVc1Yqj+Vg==\",\n  \"SigningCertURL\" : \"https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-a86cb10b4e1f29c941702d737128f7b6.pem\",\n  \"UnsubscribeURL\" : \"https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:935581097791:TestTopic:1a47b195-c1c2-4f20-b4c8-ad5f67460ac4\"\n}"
        }
    ]
}
:~$ docker run --rm -it -v ~/aws-cli:/root/.aws amazon/aws-cli sqs delete-message --queue-url https://sqs.eu-west-1.amazonaws.com/935581097791/subscriber2 --receipt-handle AQEBBBApDl3faFWlqjcg2wAPzn2WZ5NtDncfpoQwOiLm36Q2kqUlQtPaftCl13awc0UWBuMaCb76sf6k2+J1d7xUPa6Bqk1xxdOf99v8sO6cVPDAGitl6FPUQ4oCqRqNEuIexL6y/U5iH72o04Mu8OTnM/0r0l17uqqfkWiR+8q8w2Xl0VNXZUGDzudj6p/XBGoLgmqYQfkA02zhHL4+MDE+NSNxrv6wZCSMHAbI/pbBp//gG08Z5AnTD9t/YbNvtFK/+yEUdtPeNrGCoIGOgHumZYuTu7BW4ojDflGrEn8qV2ewaJcKEvzbusTvPlc1MrgNUcGq+y8njIT9ceFQOSBha05f98lwRBPiKBkh5NNFtC/iKUjtCY64JjzGMC+G8kwr

Wie zu sehen ist, wird die ursprüngliche Nachricht in einer JSON-Struktur mit den Metadaten zu der Nachricht an jede Queue zugestellt. Die Ursprüngliche Nachricht befindet sich im (escapten) JSON-Objekt innerhalb des Feldes Body einer SQS-Nachricht.

Zugriff auf Topic und Queues ermöglichen

Auf die Topics und Queues darf zunächst nur der Ersteller zugreifen. Um diese in einer Applikation verwenden zu können müssen dann noch weitere Berechtigungen vergeben werden. Details hierzu finden sich in der Dokumentation zu SNS

Zurück