パッケージを作成する

アップロード オプション

Android Over The Air API を使用すると、パッケージ データをアップロードして新しい Package リソースを作成できます。これらは 1 つ以上の設定と関連付けてアップデートを配信することができる OTA パッケージ 提供します。

Google では、再開可能なパッケージ アップロードを容易にする Linux 用と Windows 用のバイナリを提供しており、 以下で説明するプロトコルを実装する代わりに、 を自由に使用できます。より深いレベルで 下記のいずれかのプロトコルを使用してください。

これを使用するには、まずサービス アカウントを作成し、そのアカウント用の JSON キーファイルを取得する必要があります。 アカウント作成のガイドについては、こちらをご覧ください。
バイナリと鍵ファイルを入手したら、コマンドライン オプションを使用して実行し、 鍵ファイル、デプロイメント、アップロードするパッケージを指定します。--help を使用してください すべてのオプションを表示します。

アップロードのプロトコル

アップロード リクエストは次のいずれかの方法で行うことができます。 使用する方法は、X-Goog-Upload-Protocol リクエスト ヘッダーで指定します。

  • マルチパート アップロードX-Goog-Upload-Protocol: multipart)。データを 小さなファイルとメタデータファイルとそのファイルを記述するメタデータのすべてを 1 つのリクエストで転送します。
  • 再開可能アップロードX-Goog-Upload-Protocol: resumable)。大規模なデータセットで特に重要な、信頼性の高い転送を実現 できます。このメソッドでは、セッション開始リクエストを使用します。オプションでメタデータを含めることができます。これはほとんどの組織にとって アップロードごとに HTTP リクエストを 1 つ追加する手間を要しますが、比較的小さいファイルでも機能します。

マルチパート アップロード

送信するデータが小さい場合に適しています アップロードできるように、十分な余裕を持たせてください。

マルチパート アップロードを使用するには、/upload/packagePOST リクエストを送信します。 URI を指定し、X-Goog-Upload-Protocolmultipart に設定します。

マルチパート アップロード リクエストを作成するときに使用する最上位 HTTP ヘッダーには、以下を含めます。

  • Content-Type。multipart/related に設定し、対象境界文字列を含めます。 リクエストの各部分を識別できます。
  • Content-Length。リクエスト本文の総バイト数に設定します。

リクエストの本文は、multipart/related コンテンツの形式になります。 タイプ [RFC2387] であり、厳密に 2 つの部分を含みます。 各部分は境界文字列で区別され、最後の境界文字列には後に 2 つのハイフンが続きます。

マルチパート リクエストの各部分には、次の Content-Type ヘッダーを追加する必要があります。

  1. メタデータ パート: 最初に配置する必要があります。Content-Typeapplication/json にする必要があります。
  2. メディアパート: 2 番目に配置する必要があります。Content-Typeapplication/zip にする必要があります。

例: マルチパート アップロード

Android Over The Air API のマルチパート アップロード リクエストの例を次に示します。

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--

リクエストが成功すると、サーバーは HTTP 200 OK ステータス コードを返します。

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. 再開可能なセッションを開始します。次の URL を含むアップロード URI に最初のリクエストを送信します。 一意の再開可能なアップロード場所を確立します。
  2. 再開可能なセッション URI を保存します。URL で返されたセッション URI を 最初のリクエストのレスポンス。このセッションの残りのリクエストに使用します。
  3. ファイルをアップロードします。ZIP ファイルの全体または一部を再開可能なセッション URI に送信します。

また、再開可能なアップロードを使用するアプリには、中断したアップロードを再開するためのコードが必要です。アップロードが 正常に受信されたデータの量を確認し、その時点からアップロードを再開します。

注: アップロード URI は 3 日後に期限切れになります。

手順 1: 再開可能なセッションを開始する

再開可能なアップロードを開始するには、/upload/packagePOST リクエストを送信します。 URI を指定し、X-Goog-Upload-Protocolresumable に設定します。

この最初のリクエストの本文にはメタデータのみを含める必要があります。実際の 後続のリクエストでアップロードするファイルの内容を指定します。

最初のリクエストでは、次の HTTP ヘッダーを使用します。

  • X-Goog-Upload-Header-Content-Type。アップロードするファイルのコンテンツ タイプで、application/zip に設定する必要があります。
  • X-Goog-Upload-Commandstart に設定
  • 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 サーバーは HTTP 200 OK ステータス コードを返します。 また、再開可能セッション URI を指定する X-Goog-Upload-URL ヘッダーも返します。 次の例の X-Goog-Upload-URL ヘッダーには、upload_id クエリ パラメータが含まれています。 このセッションで使用する一意のアップロード 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 リクエストを 確認できます。アップロード リクエストの形式は次のとおりです。

POST session_uri

再開可能なファイル アップロードのリクエストを作成するときに使用する HTTP ヘッダーの内容は次のとおりです。

  1. Content-Length。この値は、このリクエストでアップロードするバイト数(通常はアップロード ファイルのサイズ)に設定します。
  2. X-Goog-Upload-Commanduploadfinalize に設定します。
  3. X-Goog-Upload-Offset。これは、バイトが書き込まれるオフセットを指定しています。なお、クライアントは バイトを順番にアップロードする必要があります。
例: 再開可能なファイル アップロード リクエスト

この例で 2,000,000 バイトの ZIP ファイル全体をアップロードする再開可能なリクエストは次のとおりです。

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 レスポンスがサーバーから返された場合は、中断されたアップロードを再開するに記載されている手順に沿って操作してください。


チャンク形式でファイルをアップロードする

再開可能なアップロードでは、ファイルをチャンクに分割し、一連のリクエストを送信して各チャンクを順番にアップロードできます。 この方法は推奨されません。リクエスト数の増加に伴ってパフォーマンス コストがかかります。また、 通常は不要です。クライアントには、ペイロードの残りのバイトをすべてアップロードし、 すべての upload コマンドに finalize コマンドを含めます。

ただし、分割を使用して転送するデータの量を減らす 単一リクエスト。また、従来のブラウザでアップロードの進行状況を表示することもできます。 アップロードの進行状況をサポートしていません


中断されたアップロードを再開する

レスポンスを受信する前にアップロード リクエストが終了した場合や、 サーバーから HTTP 503 Service Unavailable レスポンスが返された場合は、中断されたアップロードを再開する必要があります。手順は次のとおりです。

  1. ステータスをリクエストする。アップロード URI にリクエストを発行して、アップロードの現在のステータスをクエリする X-Goog-Upload-Commandquery に設定します。

    注: アップロードが中断された場合でなくても、チャンク間のステータスをリクエストできます。これは、 たとえば、従来のブラウザでアップロードの進行状況を表示したい場合に役立ちます。

  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

すべてのコマンドと同様に、クライアントはクエリコマンドの HTTP レスポンスの X-Goog-Upload-Status ヘッダーを確認する必要があります。 ヘッダーが存在し、値が 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
  • アップロードの再開または再試行のリクエスト時に 5xx サーバーエラーが返された場合は、指数バックオフ戦略を使用します。こうしたエラーは、サーバーに負荷がかかりすぎているときに発生することがあります。指数バックオフは、大量のリクエストまたは大量のネットワーク トラフィックが発生しているときに、この種の問題の軽減に役立ちます。
  • その他の種類のリクエストは指数バックオフでは処理できませんが、多数のリクエストは再試行できます。リクエストを再試行するときは、再試行の回数を制限します。たとえば、コードで再試行回数を 10 回に制限し、それを超えるとエラーが報告されるようにします。
  • 再開可能なアップロードで 404 Not Found エラーが発生した場合には、最初から全体のアップロードをやり直します。

指数バックオフ

指数バックオフは、ネットワーク アプリケーションの標準的なエラー処理方法で、クライアントはリクエスト間の遅延を増加させながら、失敗したリクエストを定期的に再試行します。大量のリクエストまたは大量のネットワーク トラフィックが原因でサーバーがエラーを返した場合、指数バックオフはこのようなエラーの処理に適した方法です。逆に、承認認証情報が無効である、ファイルが見つからないなど、ネットワークのボリュームまたはレスポンス タイムに関係のないエラーの処理には適していません。

指数バックオフを適切に使用すると、帯域幅の使用効率が高くなり、より少ないリクエスト数で正常なレスポンスを受け取ることができ、同時実行環境でのリクエストのスループットが最大化します。

シンプルな指数バックオフを実装するフローは次のとおりです。

  1. API へのリクエストを作成します。
  2. リクエストの再試行が必要であることを示す HTTP 503 レスポンスを受信します。
  3. 1 秒 + random_number_milliseconds の間待機してから、リクエストを再試行します。
  4. リクエストの再試行が必要であることを示す HTTP 503 レスポンスを受信します。
  5. 2 秒 + random_number_milliseconds の間待機してから、リクエストを再試行します。
  6. リクエストの再試行が必要であることを示す HTTP 503 レスポンスを受信します。
  7. 4 秒 + random_number_milliseconds の間待機してから、リクエストを再試行します。
  8. リクエストの再試行が必要であることを示す HTTP 503 レスポンスを受信します。
  9. 8 秒 + random_number_milliseconds の間待機してから、リクエストを再試行します。
  10. リクエストの再試行が必要であることを示す HTTP 503 レスポンスを受信します。
  11. 16 秒 + random_number_milliseconds の間待機してから、リクエストを再試行します。
  12. フローを停止します。エラーをレポートまたはログに記録します。

上記のフローで、random_number_milliseconds は、1,000 ミリ秒以下の乱数です。ランダムな遅延を少し加えると、負荷がより均等に分散され、サーバーに負荷がかかる可能性があるため、これが必要となります。random_number_milliseconds の値は、待機するたびに再定義する必要があります。

注: 待機時間は常に (2 ^ n) + random_number_milliseconds(n は 0 から始まる単調増加整数)です。整数 n は、繰り返し(リクエスト)のたびに 1 ずつ増えます。

このアルゴリズムは、n が 5 になると終了するように設定されています。この上限によって、クライアントが無限に再試行を繰り返すことを防ぎます。総遅延時間が約 32 秒になると、リクエストは「回復不能なエラー」と判断されます。再試行の最大回数を増やすこともできます(特に、長いアップロードを行う場合)。ただし、再試行の遅延時間には合理的な上限を設定してください(たとえば 1 分未満)。