6. SQSキューからのメッセージ受信 (handson-cli-cloudwatch-queue)

作業の目的 [why]

SQSキュー"handson-cli-cloudwatch-queue"のメッセージを受信します。

完了条件/事前条件 [設計者用情報]

完了条件 [after]

主処理は、以下を満たしたときに成功したものとします。

完了条件1

SQSメッセージファイル"${HOME}/environment/tmp-handson-cli-cloudwatch/2020-01-06-handson-cli-cloudwatch-queue.json"が存在する。

事前条件 [before]

主処理の実施は、以下の状態であることを前提とします。

事前条件1

SQSキュー"handson-cli-cloudwatch-queue"が存在する。

事前条件2

SQSキュー"handson-cli-cloudwatch-queue"のメッセージ数が"1"である。

事前条件3

SQSメッセージ用ディレクトリ"${HOME}/environment/tmp-handson-cli-cloudwatch"が存在する。

事前条件4

SQSメッセージファイル"${HOME}/environment/tmp-handson-cli-cloudwatch/2020-01-06-handson-cli-cloudwatch-queue.json"が存在しない。

作業対象 [what]

  • SQSキュー

標準時間(合計)

8分

パラメータ設定

パラメータ設定の標準時間

2分

作業に必要なモノ・情報 [resource]

作業開始には、以下が全て揃っていることが必要です。

リソース1: SQSキュー名

  • メッセージを受信するSQSキューの名称です。

  • 今回は"handson-cli-cloudwatch-queue"とします。

リソース2: SQSメッセージ用ディレクトリ

  • 今回は"${HOME}/environment/tmp-handson-cli-cloudwatch"をSQSメッセージ用ディレクトリとします。

ディレクトリが存在することを確認します。

コマンド:

ls -d ${HOME}/environment/tmp-handson-cli-cloudwatch

結果(例:存在する場合):

${HOME}/environment/tmp-handson-cli-cloudwatch

存在しない場合は作成します。

コマンド:

mkdir -p ${HOME}/environment/tmp-handson-cli-cloudwatch

リソース3: SQSメッセージファイル

  • 今回は"${HOME}/environment/tmp-handson-cli-cloudwatch/2020-01-06-handson-cli-cloudwatch-queue.json"をSQSメッセージファイルとします。

    ls ${HOME}/environment/tmp-handson-cli-cloudwatch/2020-01-06-handson-cli-cloudwatch-queue.json

パラメータの指定

作業に必要なパラメータを変数に格納をします。

0.0. リージョンの指定

変数の設定

export AWS_DEFAULT_REGION='ap-northeast-1'

0.1. SQSキュー名の指定

SQSキュー名を指定します。

変数の設定:

SQS_QUEUE_NAME="handson-cli-cloudwatch-queue"

0.2. SQSメッセージ用ディレクトリの指定

変数の設定:

DIR_SQS_MESSAGE="${HOME}/environment/tmp-handson-cli-cloudwatch"

0.3. SQSメッセージファイルの指定

変数の設定:

FILE_SQS_MESSAGE="${DIR_SQS_MESSAGE}/$(date +%Y-%m-%d)-${SQS_QUEUE_NAME}.json" \
  && echo ${FILE_SQS_MESSAGE}

結果(例):

${HOME}/environment/tmp-handson-cli-cloudwatch/2020-01-06-handson-cli-cloudwatch-queue.json

パラメータの保存

設定されている変数の保存先となるファイル名を指定します。

変数の設定:

DIR_PARAMETER="${HOME}/tmp/parameter-handson-cli-cloudwatch"
FILE_PARAMETER="${DIR_PARAMETER}/$(date +%Y-%m-%d)-sqs-message-read.env" \
  && echo ${FILE_PARAMETER}

結果(例):

${HOME}/tmp/parameter-handson-cli-cloudwatch/2020-01-06-sqs-message-read.env

各変数に正しいパラメータ値が格納されていることを確認しながら保存します。

変数の確認:

cat << EOF > ${FILE_PARAMETER}

  # 0.0. AWS_DEFAULT_REGION:"ap-northeast-1"
         AWS_DEFAULT_REGION="${AWS_DEFAULT_REGION}"

  # 0.1. SQS_QUEUE_NAME:"handson-cli-cloudwatch-queue"
         SQS_QUEUE_NAME="${SQS_QUEUE_NAME}"
  # 0.2. DIR_SQS_MESSAGE:"${HOME}/environment/tmp-handson-cli-cloudwatch"
         DIR_SQS_MESSAGE="${DIR_SQS_MESSAGE}"
  # 0.3. FILE_SQS_MESSAGE:"${HOME}/environment/tmp-handson-cli-cloudwatch/2020-01-06-handson-cli-cloudwatch-queue.json"
         FILE_SQS_MESSAGE="${FILE_SQS_MESSAGE}"

EOF

cat ${FILE_PARAMETER}

下段の変数が入っていない、もしくは上段と同等の値が入っていない場合は、それぞれの手順番号に戻って変数の設定を行います。

タスクの実施

タスク標準時間

6分

1. 前処理

処理対象の状態確認

主処理の実施は、以下の状態であることを前提とします。

前提と異なることが判明した場合、直ちに処理を中止します。

事前条件1: SQSキュー"handson-cli-cloudwatch-queue"が存在する。

「SQSキュー"handson-cli-cloudwatch-queue"が存在する。」ことを確認します。

コマンド:

aws sqs list-queues \
  --queue-name-prefix ${SQS_QUEUE_NAME} \
  --query "QueueUrls[?contains(@, \`${SQS_QUEUE_NAME}\`)]" \
  --output text

結果(例):

https://ap-northeast-1.queue.amazonaws.com/XXXXXXXXXXXX/handson-cli-cloudwatch-queue

SQSキューのURLを取得します。

コマンド:

SQS_QUEUE_URL=$( \
  aws sqs get-queue-url \
    --queue-name ${SQS_QUEUE_NAME} \
    --output text \
) \
 && echo ${SQS_QUEUE_URL}

結果(例):

https://ap-northeast-1.queue.amazonaws.com/XXXXXXXXXXXX/handson-cli-cloudwatch-queue

事前条件2: SQSキュー"handson-cli-cloudwatch-queue"のメッセージ数が"1"である。

「SQSキュー"handson-cli-cloudwatch-queue"のメッセージ数が"1"である。」ことを確認します。

コマンド:

aws sqs get-queue-attributes \
  --queue-url ${SQS_QUEUE_URL} \
  --attribute-names ApproximateNumberOfMessages \
  --query 'Attributes.ApproximateNumberOfMessages' \
  --output text

結果(例):

1

事前条件3: SQSメッセージ用ディレクトリ"${HOME}/environment/tmp-handson-cli-cloudwatch"が存在する。

「SQSメッセージ用ディレクトリ"${HOME}/environment/tmp-handson-cli-cloudwatch"が存在する。」ことを確認します。

コマンド:

ls -d ${DIR_SQS_MESSAGE}

結果(例):

${HOME}/environment/tmp-handson-cli-cloudwatch

事前条件4: SQSメッセージファイル"${HOME}/environment/tmp-handson-cli-cloudwatch/2020-01-06-handson-cli-cloudwatch-queue.json"が存在しない。

「SQSメッセージファイル"${HOME}/environment/tmp-handson-cli-cloudwatch/2020-01-06-handson-cli-cloudwatch-queue.json"が存在しない。」ことを確認します。

コマンド:

! ls ${FILE_SQS_MESSAGE}

結果(例):

ls: ${HOME}/environment/tmp-handson-cli-cloudwatch/2020-01-06-handson-cli-cloudwatch-queue.json No such file or directory

2. 主処理

SQSキューからのメッセージ受信

SQSのキューは、受信操作をするとVisibilityTimeoutの時間だけ見えなくなります。

シェルで処理する場合は、出力結果を一旦ファイルに保存するのがよいでしょう。

変数の確認:

cat << ETX

  # SQS_QUEUE_URL:"https://ap-northeast-1.queue.amazonaws.com/XXXXXXXXXXXX/handson-cli-cloudwatch-queue"
    SQS_QUEUE_URL="${SQS_QUEUE_URL}"
  # FILE_SQS_MESSAGE:"${HOME}/environment/tmp-handson-cli-cloudwatch/2020-01-06-handson-cli-cloudwatch-queue.json"
    FILE_SQS_MESSAGE="${FILE_SQS_MESSAGE}"

ETX

コマンド:

aws sqs receive-message \
  --queue-url "${SQS_QUEUE_URL}" \
  > ${FILE_SQS_MESSAGE} \
    && cat ${FILE_SQS_MESSAGE}

結果(例):

{
    "Messages": [
        {
            "Body": "Hello World!",
            "ReceiptHandle": "AQEBUo4y+XVuRSe4jMv0QM6Ob1viUnPbZ64WI01+Kmj6erhv192m80m+wgyob+zBgL4OMT+bps4KR/q5WK+W3tnno6cCFuwKGRM4OQGM9omMkK1F+ZwBC49hbl7UlzqAqcSrHfxyDo5x+xEyrEyL+sFK2MxNV6d0mF+7WxXTboyAu7JxIiKLG6cUlkhWfk3W4/Kghagy5erwRhwTaKtmF+7hw3Y99b55JLFTrZjW+/Jrq9awLCedce0kBQ3d2+7pnlpEcoY42+7T1dRI2s7um+nj5TIUpx2oSd9BWBHCjd8UQjmyye645asrWMAl1VCvHZrHRIG/v3vgq776e1mmi9pGxN96IW1aDZCQ1CSeqTFASe4=",
            "MD5OfBody": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "MessageId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
        }
    ]
}

3. 後処理

3.1. 完了条件の確認

主処理は、以下を満たしたときに成功したものとします。

完了条件1: SQSメッセージファイル"${HOME}/environment/tmp-handson-cli-cloudwatch/2020-01-06-handson-cli-cloudwatch-queue.json"が存在する。

「SQSメッセージファイル"${HOME}/environment/tmp-handson-cli-cloudwatch/2020-01-06-handson-cli-cloudwatch-queue.json"が存在する。」ことを確認します。

コマンド:

ls ${FILE_SQS_MESSAGE}

結果(例):

${HOME}/environment/tmp-handson-cli-cloudwatch/2020-01-06-handson-cli-cloudwatch-queue.json

3.2. 後処理に必要な作業

メッセージの取り出し

メッセージボディを取り出してみます。

コマンド:

SQS_MESSAGE_BODY=$( \
  cat ${FILE_SQS_MESSAGE} \
  | jp.py 'Messages[].Body' \
  | sed 's/[]\"\[]//g' \
) \
  && echo ${SQS_MESSAGE_BODY}

結果(例):

Hello World!

メッセージの削除

誰かが取得したメッセージは、「処理済み」としてキューから削除しておく必要があります。

ReceiptHandleの値でメッセージを特定して、delete-messageコマンドで削除します。

コマンド:

SQS_MESSAGE_RECEIPT_HANDLE=$( \
  cat ${FILE_SQS_MESSAGE} \
  | jp.py 'Messages[].ReceiptHandle' \
  | sed 's/[]\"\[]//g' \
) \
  && echo ${SQS_MESSAGE_RECEIPT_HANDLE}

結果(例):

AQEBxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=

変数の確認:

cat << ETX

  # SQS_QUEUE_URL:"https://ap-northeast-1.queue.amazonaws.com/XXXXXXXXXXXX/handson-cli-cloudwatch-queue"
    SQS_QUEUE_URL="${SQS_QUEUE_URL}"
  # SQS_MESSAGE_RECEIPT_HANDLE:"AQEBxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx="
    SQS_MESSAGE_RECEIPT_HANDLE="${SQS_MESSAGE_RECEIPT_HANDLE}"

ETX

コマンド:

aws sqs delete-message \
  --queue-url "${SQS_QUEUE_URL}" \
  --receipt-handle ${SQS_MESSAGE_RECEIPT_HANDLE}

結果(例):

(出力なし)

メッセージ数の確認

コマンド:

aws sqs get-queue-attributes \
  --queue-url ${SQS_QUEUE_URL} \
  --attribute-names ApproximateNumberOfMessages \
  --query 'Attributes.ApproximateNumberOfMessages' \
  --output text

結果(例):

0

値がゼロになっていれば、処理待ちのメッセージが無いことになります。

完了