התראות על שינוי אובייקטים

אפשר להשתמש בהתראות על שינוי אובייקטים כדי להודיע לאפליקציה כשאובייקט מתווסף לקטגוריה, מתעדכן או נמחק ממנה.

האם צריך להשתמש בהתראות על שינוי אובייקטים?

בדרך כלל לא מומלץ להשתמש בהתראות על שינוי אובייקטים. הכלי המומלץ ליצירת התראות שעוקבות אחר שינויים באובייקטים בקטגוריות של Cloud Storage הוא התראות Pub/Sub של Cloud Storage, כי הוא מהיר יותר, גמיש יותר, קל יותר להגדרה וחסכוני יותר. למדריך מפורט על הגדרת התראות Pub/Sub בשביל Cloud Storage, ראו הגדרת התראות Pub/Sub בשביל Cloud Storage.

אם אתם משתמשים בהתראות על שינוי אובייקטים, מומלץ לעבור להתראות של Pub/Sub. מידע על מעבר להתראות Pub/Sub זמין במאמר מעבר מהתראות על שינוי אובייקט להתראות Pub/Sub.

איך פועלות התראות על שינוי אובייקטים

אפליקציית לקוח יכולה לשלוח בקשה למעקב אחרי שינויים באובייקטים בקטגוריה מסוימת.

כשממלאים את בקשת המעקב, נוצר ערוץ התראות חדש. ערוץ התראות הוא האמצעי שבאמצעותו נשלחת הודעת התראה לאפליקציה שעוקבת אחרי קטגוריה מסוימת. יש תמיכה רק בסוג אחד של ערוץ התראות, הוק (hook) אינטרנט.

אחרי שיוצרים ערוץ התראות, האפליקציה Cloud Storage מודיעה לאפליקציה בכל פעם שאובייקט נוסף, מעודכן או נמחק מהקטגוריה. לדוגמה, כשמוסיפים תמונה חדשה לקטגוריה, אפשר שהאפליקציה תקבל התראה ליצור תמונה ממוזערת.

פרטים על התראות על שינוי אובייקטים

הסברים על המונחים

הטבלה הבאה מכילה תיאור של מספר מונחים המופיעים במשאבי העזרה בנושא התראה על שינוי אובייקט:

מונח תיאור
כתובת ה-URL של האפליקציה כתובת ה-URL של האפליקציה. זוהי הכתובת שאליה יישלחו ההתראות. שימו לב שזו חייבת להיות כתובת URL מסוג HTTPS, אי אפשר להשתמש בכתובות URL מסוג HTTP.
מזהה הערוץ המזהה של ערוץ התראות. חייב להיות ייחודי בקטגוריה מסוימת. כלומר, אם יש מספר ערוצי התראות לקטגוריה אחת, לכל ערוץ התראות צריך להיות מזהה ערוץ נפרד. המזהה הזה יישלח לאפליקציה יחד עם כל הודעת התראה.
מזהה המשאב מזהה אטום של המשאב הנמצא במעקב. צריך לציין את מזהה המשאב כדי לעצור ערוץ התראות. אפשר לאחזר את המזהה הזה מהתשובה לבקשת מעקב או מהכותרת X-Goog-Resource-Id של הודעות לגבי אירוע התראה.
טוקן הלקוח (אופציונלי) אפשר להשתמש באסימוני לקוח כדי לאמת אירועי התראות. כדי לעשות את זה, צריך להגדיר אסימון לקוח בהתאמה אישית יחד עם הבקשה למעקב. הודעות ההתראות יכילו את האסימון הזה כדי לאפשר אימות שהן אותנטיות.

יצירת ערוץ התראות

כדי להתחיל מעקב אחרי התראות על שינויים בקטגוריה, שולחים בקשת watchAll. פעולה זו תיצור ערוץ התראות ששולח אירועי התראות לaddress הנתון עבור הקטגוריה הנתונה. ערוץ ההתראות כולל אסימון לקוח בהתאמה אישית ומזהה ערוץ אם צוינו.

דוגמה לבקשת POST לצורך מעקב אחרי קטגוריה:

POST /storage/v1/b/BucketName/o/watch?alt=json HTTP/1.1
Host: storage.googleapis.com
Content-Length: 200
User-Agent: google-api-python-client/1.0
Content-Type: application/json
Authorization: Bearer oauth2_token

{
  "token": "ClientToken",
  "type": "web_hook",
  "id": "ChannelId",
  "address": "ApplicationUrl"
}

הרשאה לשליחת התראות

במהלך המעקב אחרי קטגוריה, ערוץ ההתראות שנוצר ישויך לפרויקט במסוף Google Cloud של האפליקציה שממנה נשלחה בקשת ה-API. המשמעות היא, לדוגמה, שאם משתמשים מעניקים גישה לאפליקציה מותקנת או לאפליקציית אינטרנט דרך תהליך OAuth2, ערוץ ההתראות שנוצר על-ידי האפליקציה משויך לפרויקט של האפליקציה, ולא לפרויקט המכיל את הקטגוריה שאחריה עוקבים.

מכיוון שחשבון שירות משויך לפרויקט, אם משתמשים בחשבון שירות למעקב אחרי קטגוריה, נוצר ערוץ התראות בפרויקט של חשבון השירות.

הפסקת ערוץ התראות

הפסקת ערוץ התראות על שינוי אובייקט מונעת פרסום של התראות על שינוי אובייקט בכתובת ה-URL של האפליקציה המשויכת. כדי לעצור בהצלחה ערוץ התראות על שינוי אובייקטים, צריך לדעת את הפרמטרים הבאים:

  • מזהה המשאב של הערוץ של התראות על שינוי אובייקט (RESOURCE_ID)
  • מזהה הערוץ של ערוץ ההתראות על שינוי אובייקט (CHANNEL_ID)
  • המשתמש או חשבון השירות שיצרו את ערוץ ההתראות על שינוי אובייקטים. רק יוצר הערוץ יכול להפסיק את הערוץ.

שורת הפקודה

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. התקנה של gsutil.
  3. כדי למצוא את כל הערוצים הפעילים של הודעות על שינויים באובייקטים ולרשום את הפרטים שלהם כדי לזהות את CHANNEL_ID, את RESOURCE_ID ואת חשבון השירות שיצר את הערוץ, משתמשים בפקודה gsutil notification list:
      gsutil notification list -o gs://BUCKET_NAME
      

    כאשר:

    BUCKET_NAME הוא שם הקטגוריה. לדוגמה, my-bucket.

    אם הבקשה מבוצעת בהצלחה, הפקודה תחזיר פלט שדומה להודעה הבאה:

    Notification channel 1:
                 Channel identifier: test_channel
                 Resource identifier: htopjgdthsgdt
                 Application URL: url=https://examplepetstore.com/notifications
                 Created by: examplepetstore@xyz.com
                 Creation time: 2020-01-01 00:00:00.764000
  4. אם הערוץ נוצר על ידי חשבון שירות, תצטרכו להתחזות ליוצר של חשבון השירות כדי לוודא שיש לכם את ההרשאות הנדרשות.
    gcloud config set auth/impersonate_service_account CHANNEL_CREATOR

    כאשר:

    CHANNEL_CREATOR הוא חשבון השירות שיצר את הערוץ.
  5. מפסיקים את ערוץ ההתראות על שינוי אובייקטים מהקטגוריה באמצעות הערכים CHANNEL_ID ו-RESOURCE_ID שזוהו.
    gsutil notification stopchannel CHANNEL_ID RESOURCE_ID

    כאשר:

    • CHANNEL_ID הוא מזהה הערוץ של ערוץ ההתראות על שינוי אובייקט.
    • RESOURCE_ID הוא מזהה המשאב של ערוץ ההתראות על שינוי אובייקט.
  6. ממשקי API ל-REST

    API ל-JSON

    כדי לעצור ערוץ התראות, שולחים בקשת stop. פעולה זו תעצור את כל אירועי ההתראות שפורסמו למזהה המשאב (resourceId) ולמזהה הערוץ (id) שצוינו. לא תהיה לכך השפעה על ערוצים נוספים באותו משאב. אפשר למצוא את מזהי המשאב והערוץ בתשובה לבקשת מעקב או בגוף ההודעות על אירועי ההתראות.

    דוגמה לבקשת POST לעצירת ערוץ:

    POST /storage/v1/channels/stop HTTP/1.1
    Host: storage.googleapis.com
    Content-Length: 200
    User-Agent: google-api-python-client/1.0
    Content-Type: application/json
    Authorization: Bearer oauth2_token
    
    {
      "resourceId": "ResourceId",
      "id": "ChannelId"
    }

סוגי הודעות על אירועי התראות

סנכרון

אירוע התראה נשלח כשערוץ התראות חדש נוצר אחרי ששולחים בקשת מעקב. אחרי קבלת אירוע הסנכרון, כל השינויים הבאים בקטגוריה יישלחו לכתובת ה-URL של האפליקציה שהוגדרה בשביל הערוץ.

ההתראה נשלחת כבקשת POST לכתובת ה-URL של האפליקציה שהוגדרה. אין גוף בבקשה. המטא-נתונים של התראת הסנכרון נמצאים בכותרות של הבקשה. דוגמה לבקשה של התראת סנכרון:

POST /ApplicationUrlPath
Accept: */*
Content-Type: application/json; charset="utf-8"
Content_Length: 0
Host: ApplicationUrlHost
X-Goog-Channel-Id: ChannelId
X-Goog-Channel-Token: ClientToken
X-Goog-Resource-Id: ResourceId
X-Goog-Resource-State: sync
X-Goog-Resource-Uri: https://storage.googleapis.com/storage/v1/b/BucketName/o?alt=json

הוספה, עדכון או מחיקה של אובייקט

אירוע התראה נשלח כשאובייקט חדש מתווסף לקטגוריה, כשמשנים תוכן או מטא-נתונים של אובייקט קיים או כשאובייקט נמחק מקטגוריה.

ההתראה נשלחת כבקשת POST לכתובת ה-URL של האפליקציה שהוגדרה. גוף הבקשה מכיל הודעה מקודדת באמצעות JSON כפי שמוצג בבקשת ההתראה הבאה:

POST /ApplicationUrlPath
Accept: */*
Content-Length: 1097
Content-Type: application/json; charset="utf-8"
Host: ApplicationUrlHost
X-Goog-Channel-Id: ChannelId
X-Goog-Channel-Token: ClientToken
X-Goog-Resource-Id: ResourceId
X-Goog-Resource-State: ResourceState
X-Goog-Resource-Uri: https://storage.googleapis.com/storage/v1/b/BucketName/o?alt=json

{
 "kind": "storage#object",
 "id": "BucketName/ObjectName",
 "selfLink": "https://www.googleapis.com/storage/v1/b/BucketName/o/ObjectName",
 "name": "ObjectName",
 "bucket": "BucketName",
 "generation": "1367014943964000",
 "metageneration": "1",
 "contentType": "application/octet-stream",
 "updated": "2013-04-26T22:22:23.832Z",
 "size": "10",
 "md5Hash": "xHZY0QLVuYng2gnOQD90Yw==",
 "mediaLink": "https://content-storage.googleapis.com/storage/v1/b/BucketName/o/ObjectName?generation=1367014943964000&alt=media",
 "owner": {
  "entity": "user-jeffersonloveshiking@gmail.com"
 },
 "crc32c": "C7+82w==",
 "etag": "COD2jMGv6bYCEAE="
}
כאשר ResourceState הוא:
  • exists - להוספות ולעדכונים של אובייקטים.
  • not_exists - למחיקות של אובייקטים.

כאשר התוכן של הודעת ה-JSON מכיל את הייצוג הנוכחי של האובייקט כפי שמתואר בתיאור משאב האובייקט.

מסירה אמינה

הודעה על שינוי אובייקט תנסה לשלוח התראות לאפליקציה באופן אמין. אולם שימו לב שהתראות עשויות להתעכב ללא הגבלת זמן, ושלא מובטחת עמידה בלוח זמנים. מכיוון שיכול להיות שהאפליקציה לא תמיד תהיה זמינה, כששולחים התראות, חשוב לפעול על פי הכללים הבאים:

  • אם הניסיון למסירת התראה נכשל, יבוצעו ניסיונות נוספים. מרווח הזמן בין ניסיונות מסירה נוספים נקבע על-ידי אלגוריתם השהיה מעריכית לפני ניסיון חוזר (exponential backoff) שמתחיל בניסיון חוזר 30 שניות אחרי הכשל הראשוני. המסירות הבאות מתבצעות במרווחי זמן הולכים וגדלים, עד למרווח זמן מקסימלי של 90 דקות. חשוב לשים לב שמרווחי הזמן העוקבים של הניסיונות החוזרים כוללים מעט אקראיות, כך שהם לא מתרחשים בערכים מעריכיים מדויקים. אחרי מרווח הזמן המרבי של 90 דקות לניסיון חוזר, מתבצעים ניסיונות חוזרים נוספים בכל 90 דקות למשך 7 ימים. אם אי אפשר למסור את ההתראה בפרק הזמן הזה, היא תימחק באופן סופי.
  • אם אי אפשר ליצור קשר עם האפליקציה לאחר 20 שניות או אם האפליקציה משיבה את אחד מקודי התשובה הבאים של HTTP, ניסיון מסירת ההתראה נחשב כנכשל ומנסים שוב:
    • ‫‎500 Internal Server Error
    • ‫‎502 Bad Gateway
    • ‫‎503 Service Unavailable
    • ‫‎504 Gateway Timeout
  • אם האפליקציה משיבה את אחד מקודי התשובה הבאים של HTTP, ההתראה נחשבת כהתראה שנמסרה בהצלחה:
    • ‫‎102 Processing
    • ‫‎200 OK
    • ‫‎201 Created
    • ‫‎202 Accepted
    • ‫‎204 No Content
  • כל קוד תשובה אחר של HTTP שהוחזר על-ידי האפליקציה נחשב כנכשל באופן סופי ולא יתבצע ניסיון חוזר.

דוגמה לאפליקציית לקוח

בקטע הזה מוסבר איך ליצור אפליקציית לקוח של App Engine שמעבדת אירועי התראות.

האפליקציה לדוגמה מכילה מחלקה בשם MainPage. כשמשתמשים מעדכנים או מוסיפים אובייקט לקטגוריה, המחלקה MainPage מעבדת את אירוע ההתראה. כדי לפשט את הדברים, ה-method post שמבצעת את העיבוד בפועל רק מתעדת הודעה עם שעת קבלת ההתראה. אפשר להחליף את הקוד הזה בלוגיקת העיבוד בפועל. אם עדיין לא התקדמתם בפיתוח אפליקציות של App Engine, מומלץ לפרוס אפליקציה לדוגמה או לפעול לפי המדריך לפני שממשיכים.

  1. הגדרת האפליקציה
    יוצרים את קובץ התצורה app.yaml כדי לציין את אפליקציית הלקוח שמטפלת באירועי התראות על שינוי בקטגוריה.
    application: APPLICATION
    version: 1
    runtime: python38
    api_version: 1
    threadsafe: true
    
    handlers:
    - url: /.*
      script: change_notification_client.app
  2. יצירת האפליקציה
    הדוגמה הבאה מממשת אפליקציית לקוח לטיפול באירועי התראות על שינוי בקטגוריה. מעניקים את השם change_notification_client.py, ולאחר מכן פורסים את האפליקציה:
    """Notification handling for Google Cloud Storage."""
    
    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.
    
        This method is invoked when the notification channel is first created with
        a sync event, and then subsequently every time an object is added to the
        bucket, updated (both content and metadata) or removed. It records the
        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 Engine, צריך להריץ את הפקודה הבאה כדי להעניק לאפליקציה גישת בעלים לקטגוריה:
  4. מתחילים לעקוב אחר שינויים באובייקטים בקטגוריה.
    יוצרים ערוץ התראות בשביל האפליקציה על-ידי צפייה בקטגוריה באמצעות בקשת watchAll עם address של כתובת ה-URL של אפליקציית App Engine, למשל: https://ApplicationId.appspot.com/.
  5. בדיקת האפליקציה.
    כדי לבדוק אם האפליקציה עובדת כצפוי, מבצעים את הפעולות הבאות:
    1. כדי לוודא שהאפליקציה פרוסה ועובדת כראוי, מבצעים את הפקודה הבאה של curl:
      curl -X Post https://APPLICATIONID.appspot.com
      אם השתמשתם בשם דומיין משלכם כדי לפרוס את האפליקציה, צריך להשתמש בו במקום ב-appspot.com בפקודה הקודמת.
    2. עוברים לדף Logging של הפרויקט. אם צריך, מרעננים את רשימת ההודעות ביומן. מוודאים שהודעת היומן שנשלחה על-ידי האפליקציה רשומה ביומן.
    3. מוסיפים אובייקט לקטגוריה. Cloud Storage שולחת התראה לאפליקציה, שלאחר מכן רושמת הודעה.
    4. עוברים אל <a href="https://console.cloud.google.com/project//logs">הדף Logging של הפרויקט. מרעננים את רשימת ההודעות שנרשמו ביומן ומוצאים את ההודעה של העתקת האובייקט.
    5. </ol>
      

    6. עצירת ערוץ ההתראות
      כדי לעצור את ערוץ ההתראות, מציינים את מזהה הערוץ ומזהה המשאב שהוחזרו כששלחתם את פקודת ההתראה ליצירת ערוץ התראות.