Google Cloud Storage:Notification 實作 (二) – 使用於 Google App Engine

GCS Notification 功能實作 (二):應用於 Google App Engine

Object Change Notification 是如何運作的?

application 端可以透過監控請求,去監控 GCS的 object 是否有變動。監控請求初始會建立一個 Notification Tunnel,當 GCS有變動時(新增、更新、刪除檔案),GCS 會透過 Notification Tunnel 傳送通知給 application端。目前 Notification Tunnel 只有一種類型,Web Hook。任何可以接收 HTTP POST 請求的伺服器都可以使用此方法。

參數簡介

•  ApplicationUrl:應用程式的 URL,必須為 HTTPS URL,不支援 HTTP
•  ChannelId:每個通知頻道的 ID,會協同通知訊息傳送給應用程式
•  BucketName:被監聽的資源 ID,停止通知時需要此 ID
•  ClientToken:(optional) 讓用戶端認證的 token
•  監聽 bucket

$ gsutil notification watchbucket [-i ChannelId] [-t ClientToken] ApplicationUrl gs://BucketName

•  移除通知設定

$ gsutil notification stopchannel ChannelId ResourceId

如何開放權限給 change notification

1. 新增一個 Service Account
•  
API & Services的子項目 Credentials
•  點選 Create credentials 並選擇 Service account key
•  
下拉式選單 Service account 請選擇 New service account
•  
輸入必填的 Service account name, ID 可自行修改
•  
Key type 選擇 JSON
•  
創立後會下載 JSON 格式的 Key

2. 賦予 gsutil 權限使用 Service Account
3. 更新 Cloud SDK

$ gcloud components update

4. 驗證 Service Account Email (開啟GCP Console中 IAM & admin 的 Service accounts ,並複製剛剛新增的 Service Account) 以及 key

$ gcloud auth activate-service-account [Service-Account信箱] --key-file [路徑/key的名稱]
// 驗證成功會出現以下訊息
$ Activated service account credentials for: [Service-Account信箱]

5. 再次確認是否驗證成功,會看到信箱前面有 active 的星號

$ gcloud auth list
Credentialed Accounts
ACTIVE  ACCOUNT
*      [Service-Account信箱]

6. 指定接收通知的 Domain
•  
確認您是這個 Domain 的管理者
•  
點選 Add domain
•  輸入指定的 Domain 並新增

7. 移除通知設定

$ gsutil notification stopchannel ChannelId ResourceId

應用程式範例

接下來會帶您建立一個 App Engine 的應用程式執行 Object Notification

1. 創立一個 Bucket,[Bucket Name] 為自填參數

$ gsutil mb gs://[Bucket Name]/
Creating gs://[Bucket Name]... //表示成功新增Bucket

2. 新增一個 For App Engine 的資料夾,裡面包括 app.yaml change_notification_client.py 兩個檔案

(app.yaml 程式碼)

runtime: python27
api_version: 1
threadsafe: true

handlers:
- url: /.*
script: change_notification_client.app

(change_notification_client.py 程式碼)

import json
import logging

import webapp2

class MainPage(webapp2.RequestHandler):
 """Process notification events."""
 def get(self):
   logging.info("Get request to notification page.")
   self.response.write("Welcome to the notification app.")

 def post(self):  # pylint: disable-msg=C6409
"""Process the notification event.

notification message in the log.
"""

logging.debug(
   '%s\n\n%s',
   '\n'.join(['%s: %s' % x for x in self.request.headers.iteritems()]),
   self.request.body)

# The following code is for demonstration. Replace
# it with your own notification processing code.

if 'X-Goog-Resource-State' in self.request.headers:
 resource_state = self.request.headers['X-Goog-Resource-State']
 if resource_state == 'sync':
   logging.info('Sync message received.')
 else:
   an_object = json.loads(self.request.body)
   bucket = an_object['bucket']
   object_name = an_object['name']
   logging.info('%s/%s %s', bucket, object_name, resource_state)
else:
 logging.info("Other post.")

logging.getLogger().setLevel(logging.DEBUG)
app = webapp2.WSGIApplication([('/', MainPage)], debug=True)

3. 部署這個 app 並且確認是否部署成功

$ gcloud app deploy //部署
$ gcloud app browse //部署的應用程式會在 http://[YOUR_PROJECT_ID].appspot.com 
// [YOUR_PROJECT_ID]為使用者的project id

4. 給予應用程式 Bucket 的權限

$ gsutil acl ch -u [YOUR_PROJECT_ID]@appspot.gserviceaccount.com:OWNER gs://[Bucket Name]

5. 到 APIs & Services 的 Credentials 點選 Create Credentials 然後選擇 Service Account Key
6. 之後選擇過剛剛賦予權限的 Service Account (這邊是選擇 App Engine Default Service Account)
7. 格式選擇 JSON,創立後會下載 JSON 格式的 Key
8. 賦予 gsutil 權限使用 Service Account

$ gcloud auth activate-service-account [Service-Account信箱] --key-file [路徑/key的名稱]
// 驗證成功會出現以下訊息
$ Activated service account credentials for: [Service-Account信箱]

9. 監控 Bucket

$ gsutil notification watchbucket [ApplicationURL] gs://[Bucket Name]  
//[ApplicationURL] = https://[YOUR_PROJECT_ID].appspot.com/

10 .測試

$ curl -X Post https://[YOUR_PROJECT_ID].appspot.com
$ gsutil cp [OBJECT] gs://[Bucket Name]/ 
// [OBJECT] 為任意一個檔案

11. 開啟 console 的 Stackdriver Logging 的 Logs 查看 Log

 

 


連絡「GCP 專門家」