GCP - Pub/Sub サービス構築チュートリアル

[GCP - Pub/Sub サービス概要](https://qiita.com/minarai/private/fb1bec88ce767ce69bfe)からの続き
Pub/Sub サービスのセットアップ手順をまとめました。

# サービスアカウント作成
まず初めに行いたいのがサービスアカウントの作成です。
サービスアカウントとはユーザーの代わりにシステムがGCP各サービスを利用するためのアカウントのこと。

#### アカウントの作成
今回は[コンソール　サービスアカウント](https://console.cloud.google.com/iam-admin/serviceaccounts)から作成をします。

| ユーザー名       |       ロール1 |  
|:-----------------|:------------------|
| minarai-pub-sub| roles/pubsub.editor |

POCなんでPub/SubのCRUD関連の権限までもたせてあります。
本番環境ではサービスアカウントに適切な権限だけを持たせたり、ポリシーを適用するなどして運用するのが正解だと思います。


#### サービスアカウントの鍵を作成
サービスアカウント一覧に`minarai-pub-sub@****`が表示されたら`操作`から**鍵を作成（json)**を選択すると鍵が生成されローカルPCにダウンロードされるので適切な場所に配置する

#### サービス実行アカウントを変更
作成したサービスアカウントをアクティブにする

- 現在の設定一覧とアクティブなアカウントを確認する

```
% gcloud config configurations list
NAME     IS_ACTIVE  ACCOUNT                 PROJECT      COMPUTE_DEFAULT_ZONE  COMPUTE_DEFAULT_REGION
default  True       アカウント@gmail.com  プロジェクトID

# （省略化）　ついでにCOMPUTE_DEFAULT_ZONEも追加した
gcloud config set compute/region asia-northeast1
gcloud config set compute/zone asia-northeast1-a

# （省略化）　改めて確認
% gcloud config configurations list               
NAME     IS_ACTIVE  ACCOUNT                 PROJECT      COMPUTE_DEFAULT_ZONE  COMPUTE_DEFAULT_REGION
default  True       アカウント@gmail.com  プロジェクトID  asia-northeast1-a     asia-northeast1
```
- [新しいコンフィグを作成する](https://cloud.google.com/sdk/gcloud/reference/config/configurations/create?hl=ja)

`構文： gcloud config configurations create NAME FLAG`

```
% gcloud config configurations create minarai-pub-sub --activate
# アカウントを切り替えるとき
gcloud config configurations activate minarai-pub-sub

% gcloud config configurations list                                
NAME                IS_ACTIVE  ACCOUNT                 PROJECT      COMPUTE_DEFAULT_ZONE  COMPUTE_DEFAULT_REGION
default             False      アカウント@gmail.com  プロジェクトID  asia-northeast1-a     asia-northeast1
minarai-pub-sub     True

```

- [サービスアカウントをコンフィグに紐づける](https://cloud.google.com/sdk/gcloud/reference/config/set?hl=ja)

`構文: gcloud config set core/project プロジェクトID`
`構文： gcloud config set core/account サービスアカウント`
`構文： gcloud　config set compute/region リージョン`
`構文： gcloud config set compute/zone ゾーン`

```
% gcloud config set core/project プロジェクトID
% gcloud config set core/account サービスアカウント
% gcloud config set compute/region asia-northeast1
% gcloud config set compute/zone asia-northeast1-a

% gcloud config configurations list 
NAME                IS_ACTIVE  ACCOUNT                                                 PROJECT      COMPUTE_DEFAULT_ZONE  COMPUTE_DEFAULT_REGION
default             False      アカウント@gmail.com                                  プロジェクトID  asia-northeast1-a     asia-northeast1
minarai-app-engine  True       minarai-pub-sub@アカウント.iam.gserviceaccount.com  プロジェクトID  asia-northeast1-a     asia-northeast1
```

- サービスアカウントの認証

```
% gcloud auth activate-service-account --key-file ~/Documents/gcp/key/pub-sub-key.json
```

# [エミュレータを使用したローカルでのアプリのテスト](https://cloud.google.com/pubsub/docs/emulator?hl=ja)

アプリケーションをローカルで開発してテストするには、本番環境の Pub/Sub 環境のローカル エミュレーションを使用する Pub/Sub エミュレータを使用します。
Pub/Sub エミュレータは、gcloud コマンドライン ツールを使用して実行します。

### [エミュレータのインストール](https://cloud.google.com/pubsub/docs/emulator?hl=ja#installing_the_emulator)
コマンド プロンプトからエミュレータをインストールします。

```
% gcloud components install pubsub-emulator
% gcloud components update
```

### [エミュレータの開始](https://cloud.google.com/pubsub/docs/emulator?hl=ja#start)
エミュレータを起動するには、コマンド プロンプトから `pubsub start` を実行します。
コマンドを実行する前に、`PUBSUB_PROJECT_ID` を `Google Cloud プロジェクト ID `に置き換えてください。 この場合、プロジェクト ID には任意の有効な文字列を指定できます。
**Pub/Sub エミュレータがローカルで実行されるため、実際の Google Cloud プロジェクトを表す必要はありません。**
オプションの一覧は、[gcloud beta emulators pubsub start](https://cloud.google.com/sdk/gcloud/reference/beta/emulators/pubsub/start?hl=ja) をご覧ください。

```
% gcloud beta emulators pubsub start --project=PUBSUB_PROJECT_ID [options]
```

### [環境変数の設定](https://cloud.google.com/pubsub/docs/emulator?hl=ja#env)
エミュレータを起動した後、アプリケーションが Pub/Sub ではなくエミュレータに接続するように環境変数を設定する必要があります。これらの環境変数は、アプリケーションの実行に使用するマシンに設定します。

**エミュレータを起動するたびに、環境変数を設定する必要があります。**環境変数は、動的に割り当てられるポート番号に依存しています。この番号は、エミュレータを再起動するたびに変わる可能性があります。

#### [環境変数の自動設定](https://cloud.google.com/pubsub/docs/emulator?hl=ja#automatically_setting_the_variables)
アプリケーションとエミュレータが同じマシン上で動作している場合は、次のようにして環境変数を自動的に設定できます。

```
$(gcloud beta emulators pubsub env-init)
```

#### [環境変数の手動設定](https://cloud.google.com/pubsub/docs/emulator?hl=ja#manually_setting_the_variables)

```
# env-init コマンドを実行
gcloud beta emulators pubsub env-init

export PUBSUB_EMULATOR_HOST=localhost:8432
export PUBSUB_PROJECT_ID=my-project-id
```

Python App Engine スタンダード ローカル開発サーバーを使用している場合には、次のように環境変数をコマンドラインに渡す必要があります。

```
dev_appserver.py app.yaml --env_var PUBSUB_EMULATOR_HOST=${PUBSUB_EMULATOR_HOST}
```

### [エミュレータの使用](https://cloud.google.com/pubsub/docs/emulator?hl=ja#using_the_emulator)
エミュレータでは Cloud Console および gcloud pubsub コマンドはサポートされていません。

#### 実行手順

1） Pub/Sub サンプルアプリケーションをGitからpull

```
% git clone https://github.com/GoogleCloudPlatform/python-docs-samples
% cd python-docs-samples/pubsub/cloud-client
```
2） 必要なパッケージをインストール

```
% python3 -m venv pub-sub-env
% source pub-sub-env//bin/activate

% pip3 install -r requirements.txt
```

3） トピックを作成

```
% python publisher.py PUBSUB_PROJECT_ID create TOPIC_ID
```

4） （省略可）エミュレータで push サブスクリプションをテストするためのローカル push エンドポイントがない場合は、次の手順で http://localhost:3000/messages に作成

```
# JSON サーバーをインストール
npm install -g json-server
# JSON サーバーを起動
json-server --port 3000 --watch db.json
```
```db.json
{
  "messages": []
}
```

5) トピックへのサブスクリプションを作成

```
# pull サブスクリプションを作成
python subscriber.py PUBSUB_PROJECT_ID create TOPIC_ID SUBSCRIPTION_ID

# push サブスクリプションを作成
python subscriber.py PUBSUB_PROJECT_ID create-push TOPIC_ID SUBSCRIPTION_ID \
    PUSH_ENDPOINT
```

6) トピックにメッセージをパブリッシュ

```
python publisher.py PUBSUB_PROJECT_ID publish TOPIC_ID
```

7) ピックにパブリッシュされているメッセージを取得

```
python subscriber.py PUBSUB_PROJECT_ID receive SUBSCRIPTION_ID

# 取得結果の一例
{
      "messages": [
          {
              "subscription": "projects/PUBSUB_PROJECT_ID/subscriptions/SUBSCRIPTION_ID",
              "message": {
                  "data": "TWVzc2FnZSBudW1iZXIgMQ==",
                  "messageId": "10",
                  "attributes": {}
              },
              "id": 1
          },
          ...
      ]
    }
```

### [エミュレータの停止](https://cloud.google.com/pubsub/docs/emulator?hl=ja#stop)
エミュレータを停止するには、`Ctrl+C` キーを押します。
環境変数をアンセット

```
unset PUBSUB_EMULATOR_HOST
```

[GCP - Pub/Sub サービスの利用](https://qiita.com/minarai/private/0051d626244d5916b985)へ続きます