יצירת חבילה

האפשרויות להעלאה

ממשק ה-API של Android Over The Air מאפשר להעלות נתוני חבילה כדי ליצור משאב Package חדש. הנושאים האלה חבילות OTA שאפשר לשייך להגדרה אחת או יותר כדי שהעדכון יישלח למכשירים.

אנחנו מספקים קובץ בינארי ל-Linux ול-Windows כדי לאפשר העלאות של חבילות שניתן להמשיך זמינים לשימוש בחינם במקום להטמיע את הפרוטוקולים שמתוארים בהמשך. אם רוצים יש להשתמש באחד מהפרוטוקולים שמתוארים בהמשך.

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

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

אפשר לשלוח בקשות העלאה בכל אחת מהדרכים הבאות. עם כותרת הבקשה X-Goog-Upload-Protocol, מציינים את השיטה שבה משתמשים.

  • העלאה מרובת חלקים: X-Goog-Upload-Protocol: multipart. להעברה מהירה של קבצים ומטא-נתונים קטנים יותר; מעבירה את הקובץ יחד עם מטא-נתונים שמתארים אותו, בבקשה אחת.
  • העלאה שניתן להמשיך: X-Goog-Upload-Protocol: resumable. להעברה אמינה, חשובה במיוחד עם . באמצעות השיטה הזו משתמשים בבקשה להתחלת הסשן, שיכולה לכלול מטא-נתונים. זוהי אסטרטגיה טובה לשימוש כי הוא מתאים גם לקבצים קטנים יותר, בעלות של בקשת HTTP אחת נוספת לכל העלאה.

העלאה מרובת חלקים

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

כדי להשתמש בהעלאה מרובת חלקים, צריך לשלוח בקשת POST אל /upload/package URI ומגדירים את X-Goog-Upload-Protocol ל-multipart.

כותרות ה-HTTP ברמה העליונה שבהן צריך להשתמש כששולחים בקשה להעלאה מרובת חלקים כוללות:

  • Content-Type צריך להגדיר את הטווח בתור 'מרוב חלקים'/'קשור' ולכלול את מחרוזת הגבולות שרוצים. שמשמש לזיהוי החלקים של הבקשה.
  • Content-Length מוגדר למספר הכולל של הבייטים בגוף הבקשה.

גוף הבקשה מעוצב בתור תוכן multipart/related מסוג [RFC2387] ומכיל בדיוק שני חלקים. החלקים מזוהים באמצעות מחרוזת גבול, ואחרי המחרוזת הסופית יש שני מקפים.

צריך להוסיף כותרת Content-Type לכל חלק בבקשה מרובת החלקים:

  1. חלק של מטא-נתונים: חייב להיות קודם, Content-Type חייב להיות application/json.
  2. חלק מדיה: חייב להיות שני, וContent-Type חייב להיות application/zip.

דוגמה: העלאה מרובת חלקים

בדוגמה הבאה מוצגת בקשה של העלאה מרובת חלקים עבור ממשק ה-API של Android Over The Air.

POST /upload/package HTTP/1.1
Host: androidovertheair.googleapis.com
Authorization: Bearer your_auth_token
Content-Type: multipart/related; boundary=BOUNDARY
Content-Length: number_of_bytes_in_entire_request_body

--BOUNDARY
Content-Type: application/json; charset=UTF-8

{"deployment": "id", "package_title": "title" }
--BOUNDARY
Content-Type: application/zip; charset=UTF-8

Package ZIP
--BOUNDARY--

אם הבקשה תתבצע בהצלחה, השרת יחזיר את קוד הסטטוס 200 OK של HTTP

HTTP/1.1 200

אפשר לעשות זאת בקלות באמצעות שימוש ב-curl. ו-oauth2l. בהמשך מוצגת בקשה לדוגמה שמתבסס על ההנחה שאתם משתמשים במפתח שירות (עיינו איך לקבל הרשאה כדי לקבל מידע נוסף).

דוגמה לבקשת curl
    JSON={"deployment": "id", "package_title": "title" }
    SERVICE_KEY_FILE=path to your service key json file
    curl \
    -H "$(./oauth2l header --json $SERVICE_KEY_FILE android_partner_over_the_air)" \
    -H "Host: androidovertheair.googleapis.com" \
    -H "X-Goog-Upload-Protocol: multipart" \
    -H "Content-Type: multipart/form-data" \
    -F "json=$JSON;type=application/json" \
    -F "data=@update.zip;type=application/zip" \
    androidovertheair.googleapis.com/upload/package
  

העלאה שניתן להמשיך

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

פרוטוקול ההעלאה שניתן להמשיך משתמש בכמה פקודות:

  1. התחלת סשן שניתן להמשיך שולחים בקשה ראשונית ל-URI של ההעלאה שכוללת את התחילית מטא-נתונים ומגדירים מיקום ייחודי של העלאה שניתן להמשיך.
  2. שומרים את ה-URI של הסשן שניתן להמשיך. שומרים את ה-URI של הסשן שהוחזר תגובה לבקשה הראשונית, משתמשים בה בשאר הבקשות בסשן הזה.
  3. מעלים את הקובץ. שולחים את כל קובץ ה-ZIP או חלק ממנו ל-URI של הסשן שניתן להמשיך.

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

הערה: התוקף של ה-URI של ההעלאה פג לאחר 3 ימים.

שלב 1: התחלת סשן שניתן להמשיך

כדי להתחיל העלאה שניתן להמשיך, צריך לשלוח בקשת POST אל /upload/package URI ומגדירים את X-Goog-Upload-Protocol ל-resumable.

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

בבקשה הראשונית משתמשים בכותרות ה-HTTP הבאות:

  • X-Goog-Upload-Header-Content-Type זהו סוג התוכן של הקובץ שמעלים, וצריך להגדיר אותו כ-application/zip.
  • X-Goog-Upload-Command הגדרה לערך start
  • X-Goog-Upload-Header-Content-Length מוגדר למספר הבייטים של נתוני ההעלאה שיועברו בבקשות הבאות. אם האורך לא ידוע בזמן הבקשה, אפשר להשמיט את הכותרת.
  • Content-Type זהו סוג התוכן של המטא-נתונים וצריך להגדיר אותו כ-application/json.
  • Content-Length צריך להגדיר את מספר הבייטים שצוין בגוף הבקשה הראשונית.
דוגמה: בקשת התחלת סשן שניתן להמשיך

בדוגמה הבאה מוצגת דוגמה להתחלת סשן שניתן להמשיך ב-Android Over The Air API.

POST /upload/package HTTP/1.1
Host: android/over-the-air.googleapis.com
Authorization: Bearer your_auth_token
Content-Length: 38
Content-Type: application/json; charset=UTF-8
X-Goog-Upload-Command: start
X-Goog-Upload-Header-Content-Type: application/zip
X-Goog-Upload-Header-Content-Length: 2000000

{"deployment": "id", "package_title": "title" }

בקטע הבא מוסבר איך לטפל בתשובה.

שלב 2: שומרים את ה-URI של הסשן שניתן להמשיך

אם בקשת התחלת הסשן מצליחה, שרת ה-API מגיב עם קוד הסטטוס 200 OK של HTTP. בנוסף, היא מספקת כותרת X-Goog-Upload-URL שמציינת את ה-URI של הסשן שניתן להמשיך. הכותרת X-Goog-Upload-URL, שמוצגת בדוגמה למטה, כוללת פרמטר שאילתה upload_id שנותן את מזהה ההעלאה הייחודי שבו צריך להשתמש בסשן הזה. התשובה מכילה גם X-Goog-Upload-Status שיהיה active אם בקשת ההעלאה הייתה חוקית ואושרה. יכול להיות שהסטטוס הזה הוא final אם ההעלאה נדחתה.

דוגמה: תגובה להתחלת סשן שניתן להמשיך

זו התגובה לבקשה בשלב 1:

HTTP/1.1 200 OK
X-Goog-Upload-Status: active
X-Goog-Upload-URL: androidovertheair.googleapis.com/?upload_id=xa298sd_sdlkj2
Content-Length: 0

ערך הכותרת X-Goog-Upload-URL, כפי שמוצג בתשובה לדוגמה שלמעלה, הוא ה-URI של הסשן שבו תשתמשו כנקודת הקצה של HTTP להעלאת הקובץ בפועל או לשליחת שאילתות לגבי סטטוס ההעלאה.

מעתיקים ושומרים את ה-URI של הסשן כדי להשתמש בו לבקשות הבאות.

שלב 3: העלאת הקובץ

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

POST session_uri

כותרות ה-HTTP שבהן צריך להשתמש כששולחים בקשות להעלאת קבצים שניתן להמשיך כוללות:

  1. Content-Length צריך להגדיר את הערך הזה למספר הבייטים שאתם מעלים בבקשה הזו, שהוא בדרך כלל גודל הקובץ להעלאה.
  2. X-Goog-Upload-Command מגדירים את האפשרויות upload ו-finalize.
  3. X-Goog-Upload-Offset ההגדרה הזו מציינת את ההיסט שבו צריך לכתוב את הבייטים. שימו לב שהלקוחות להעלות בייטים סדרתיים.
דוגמה: בקשה להעלאת קובץ שניתן להמשיך

בהמשך מוצגת בקשה שניתן להמשיך כדי להעלות את קובץ ה-ZIP כולו בגודל 2,000,000 בייטים, בשביל הדוגמה הנוכחית.

POST /?upload_id=xa298sd_sdlkj2 HTTP/1.1
Host: androidovertheair.googleapis.com
X-Goog-Upload-Protocol: resumable
X-Goog-Upload-Command: upload, finalize
X-Goog-Upload-Offset: 0
Content-Length: 2000000
Content-Type: application/zip

bytes 0-1999999

אם הבקשה מצליחה, השרת ישיב באמצעות HTTP 200 Ok.

אם בקשת ההעלאה הופסקה או אם מקבלים HTTP 503 Service Unavailable או תגובת 5xx אחרת מהשרת, יש לבצע את ההליך שמתואר בקטע המשך העלאה שהופסקה.


העלאת הקובץ במקטעי נתונים

העלאות שניתן להמשיך מאפשרות לחלק קובץ למקטעים ולשלוח סדרה של בקשות להעלאת כל מקטע ברצף. זו לא הגישה המועדפת, כי יש עלויות ביצועים שקשורות לבקשות הנוספות, בדרך כלל, מומלץ שהלקוחות יעלו את כל הבייטים שנותרו של המטען הייעודי (payload) כוללים את הפקודה finalize בכל פקודת upload.

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


המשך העלאה שהופסקה

אם בקשת העלאה הופסקה לפני קבלת תשובה או אם קיבלת תגובת HTTP 503 Service Unavailable מהשרת, ואז צריך להמשיך את ההעלאה שהופסקה. לשם כך:

  1. סטטוס הבקשה. שליחת בקשה לסטטוס הנוכחי של ההעלאה על ידי שליחת בקשה ל-URI של ההעלאה כאשר X-Goog-Upload-Command מוגדר ל-query.

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

  2. קבלת מספר הבייטים שמעלים. מעבדים את התשובה משאילתת הסטטוס. השרת משתמש את הכותרת X-Goog-Upload-Size-Received בתגובה, כדי לציין כמה בייטים היא קיבלה עד עכשיו.
  3. מעלים את הנתונים שנותרו. לסיום, עכשיו, אחרי שאתם יודעים לאן להמשיך את הטיפול בבקשה, שלחו את את שאר הנתונים או את המקטע הנוכחי. שימו לב שתצטרכו להתייחס לנתונים הנותרים בתור מקטע נפרד בכל מקרה, לכן צריך להגדיר את הכותרת X-Goog-Upload-Offset להיסט המתאים כשממשיכים את ההעלאה.
דוגמה: המשך העלאה שהופסקה

1) מבקשים את סטטוס ההעלאה.

POST /?upload_id=xa298sd_sdlkj2 HTTP/1.1
Host: androidovertheair.googleapis.com
X-Goog-Upload-Command: query

בדומה לכל הפקודות, הלקוח חייב לבדוק את הכותרת X-Goog-Upload-Status בתגובת ה-HTTP של פקודת שאילתה. אם הכותרת קיימת והערך אינו active, ההעלאה כבר הסתיימה.

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

תגובת השרת משתמשת בכותרת X-Goog-Upload-Size-Received כדי לציין שהיא קיבל את 43 הבייטים הראשונים של הקובץ עד כה.

HTTP/1.1 200 OK
X-Goog-Upload-Status: active
X-Goog-Upload-Size-Received: 42

3) ממשיכים את ההעלאה מהנקודה שבה היא נעצרה.

הבקשה הבאה תמשיך את ההעלאה על ידי שליחת הבייטים הנותרים של הקובץ, החל מבייטים 43.

POST /?upload_id=xa298sd_sdlkj2 HTTP/1.1
Host: androidovertheair.googleapis.com
X-Goog-Upload-Command: upload, finalize
Content-Length: 1999957
X-Goog-Upload-Offset: 43

bytes 43-1999999

שיטות מומלצות

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

  • אפשר להמשיך או לנסות שוב העלאות שנכשלו עקב הפרעות בחיבור או בגלל שגיאות 5xx, כולל:
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout
  • צריך להשתמש באסטרטגיית השהיה מעריכית לפני ניסיון חוזר (exponential backoff) אם מוחזרת שגיאת שרת 5xx כשמממשים בקשות העלאה או מנסים שוב אותן. השגיאות האלה יכולות להתרחש אם יש עומס יתר בשרת. השהיה מעריכית לפני ניסיון חוזר (exponential backoff) יכולה לעזור לפתור בעיות כאלה במהלך תקופות של נפח גבוה של בקשות או תנועה כבדה ברשת.
  • לא צריך לטפל בסוגים אחרים של בקשות על ידי השהיה מעריכית לפני ניסיון חוזר (exponential backoff), אבל עדיין אפשר לנסות מספר מהן. כשמבצעים ניסיון חוזר של הבקשות האלה, צריך להגביל את מספר הניסיונות החוזרים שלהן. לדוגמה, הקוד עשוי להגביל ל-10 ניסיונות חוזרים או פחות לפני דיווח על שגיאה.
  • כדי לטפל ב-404 Not Found שגיאות, כשמבצעים העלאות שניתן להמשיך, צריך להתחיל את ההעלאה כולה מההתחלה.

השהיה מעריכית לפני ניסיון חוזר (exponential backoff)

השהיה מעריכית לפני ניסיון חוזר (exponential backoff) היא אסטרטגיה סטנדרטית לטיפול בשגיאות באפליקציות רשת, שבה הלקוח מנסה שוב ושוב לשלוח בקשה שנכשלה ומשך הזמן הולך וגדל. אם כמות גדולה של בקשות או תנועה כבדה ברשת גורמת לשרת להחזיר שגיאות, השהיה מעריכית לפני ניסיון חוזר (exponential backoff) היא אסטרטגיה טובה לטיפול בשגיאות האלה. לעומת זאת, זו לא אסטרטגיה רלוונטית לטיפול בשגיאות שלא קשורות לנפח הרשת או לזמני התגובה, כמו פרטי כניסה לא חוקיים של הרשאה או שגיאות של 'קובץ לא נמצא'.

בשימוש נכון, השהיה מעריכית לפני ניסיון חוזר (exponential backoff) מגדילה את יעילות השימוש ברוחב הפס, מקטינה את מספר הבקשות שדרושות לקבלת תגובה מוצלחת וממקסמת את התפוקה של הבקשות בסביבות בו-זמנית.

התהליך ליישום השהיה מעריכית פשוטה לפני ניסיון חוזר (exponential backoff) הוא:

  1. שולחים בקשה ל-API.
  2. מקבלים את התשובה HTTP 503, שמצביעה על כך שצריך לנסות שוב את הבקשה.
  3. יש להמתין שנייה אחת + הכמות האקראית_number_milliseconds ולנסות שוב את הבקשה.
  4. מקבלים את התשובה HTTP 503, שמצביעה על כך שצריך לנסות שוב את הבקשה.
  5. צריך להמתין 2 שניות +Android_number_milliseconds, ולנסות שוב את הבקשה.
  6. מקבלים את התשובה HTTP 503, שמצביעה על כך שצריך לנסות שוב את הבקשה.
  7. צריך להמתין 4 שניות +Android_number_milliseconds, ולנסות שוב את הבקשה.
  8. מקבלים את התשובה HTTP 503, שמצביעה על כך שצריך לנסות שוב את הבקשה.
  9. צריך להמתין 8 שניות +GCLID_number_milliseconds, ולנסות שוב את הבקשה.
  10. מקבלים את התשובה HTTP 503, שמצביעה על כך שצריך לנסות שוב את הבקשה.
  11. צריך להמתין 16 שניות +Android_number_milliseconds, ולנסות שוב את הבקשה.
  12. הפסקת ההפעלה. תיעוד או דיווח על שגיאה.

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

הערה: ההמתנה היא תמיד (2 ^ n) +TRUE_number_milliseconds, כאשר n הוא מספר שלם מונוטוני שגדל בהתחלה כ-0. המספר השלם n גדל ב-1 לכל איטרציה (כל בקשה).

האלגוריתם מוגדר לסיום כש-n הוא 5. תקרה זו מונעת מלקוחות לבצע ניסיונות חוזרים ללא הגבלה, וכתוצאה מכך מתרחשת עיכוב כולל של כ-32 שניות לפני שהבקשה נחשבת ל"שגיאה שלא ניתן לשחזר". מספר מקסימלי גדול יותר של ניסיונות חוזרים הוא תקין, במיוחד אם מתבצעת העלאה ארוכה. חשוב לזכור להגביל את ההשהיה לפני ניסיון חוזר למשהו סביר (למשל, פחות מדקה).