Object Body のアップロード
Object Body としてファイルをアップロードすると、Object とファイルを紐付けて管理できます。Object Body の機能概要については、Object Body のアクセス をご覧ください。
Thing SDK Embedded は、以下の 2 種類の Object Body アップロード方法を提供しています。
いずれの方法でも、アップロード完了と同時に、Object に紐付く Object Body がアップロードしたデータに入れ替わります。このとき、既存の Object Body がある場合は、自動的に削除されます。また、同時更新となった場合は、後からアップロードが完了したデータになります(Object Body には楽観的ロックの仕組みはありません)。
分割アップロードでは、各 Object Body にサイズの上限はなく、合計サイズが料金プランのストレージ上限に達するまで格納できます。一括アップロードでは、100 MB までです(ただし、サーバーの安定動作のため、1 回のアップロードリクエストは 1 分程度までを目安としてください)。
1 回の転送サイズを大きくする場合、初期化の際に指定した バッファーサイズ にご注意ください。1 回の API 呼び出しでの転送サイズと、HTTP ヘッダー等のリクエストに必要なサイズの合計は、初期化で指定したバッファーサイズ以下である必要があります。
分割アップロード
Object Body をアップロードする例を以下に挙げます。
/* Set object body parameters. */
#define OBJECT_ID "STATUS_TEMPERATURE"
#define CONTENT_TYPE "application/octet-stream"
char OBJECT_BODY1[] = {
0x31, 0x32, 0x33, 0x00, 0x34, 0x35, 0x36, 0x00, 0x37, 0x38, 0x39, 0x00
};
char OBJECT_BODY2[] = {
0x36, 0x35, 0x34, 0x00, 0x33, 0x32, 0x31, 0x00
};
char uploadID[KII_UPLOADID_SIZE + 1];
kii_chunk_data_t chunkData1, chunkData2;
/* Set bucket parameters. */
kii_bucket_t bucket;
memset(&bucket, 0x00, sizeof(kii_bucket_t));
bucket.scope = KII_SCOPE_THING;
bucket.bucket_name = "myBucket";
bucket.scope_id = "VENDOR_THING_ID:rBnvSPOXBDF9r29GJeGS";
/* Upload the object body in chunks. */
ret = kii_object_init_upload_body(&kii, &bucket, OBJECT_ID, uploadID);
if (ret != 0) {
/* Handle the error. */
return;
}
/* Set the first chunk. */
chunkData1.body_content_type = CONTENT_TYPE;
chunkData1.position = 0;
chunkData1.length = sizeof(OBJECT_BODY1) / sizeof(OBJECT_BODY1[0]);
chunkData1.total_length = sizeof(OBJECT_BODY1) / sizeof(OBJECT_BODY1[0]) + sizeof(OBJECT_BODY2) / sizeof(OBJECT_BODY2[0]);
chunkData1.chunk = OBJECT_BODY1;
/* Upload the first chunk. */
ret = kii_object_upload_body(&kii, &bucket, OBJECT_ID, uploadID, &chunkData1);
if (ret != 0) {
/* Handle the error. */
return;
}
/* Set the second chunk. */
chunkData2.body_content_type = CONTENT_TYPE;
chunkData2.position = chunkData1.length;
chunkData2.length = sizeof(OBJECT_BODY2) / sizeof(OBJECT_BODY2[0]);
chunkData2.total_length = chunkData1.total_length;
chunkData2.chunk = OBJECT_BODY2;
/* Upload the second chunk. */
ret = kii_object_upload_body(&kii, &bucket, OBJECT_ID, uploadID, &chunkData2);
if (ret != 0) {
/* Handle the error. */
return;
}
/* Finalize the upload. */
ret = kii_object_commit_upload(&kii, &bucket, OBJECT_ID, uploadID, 1);
if (ret != 0) {
/* Handle the error. */
return;
}
分割アップロードでは、チャンクと呼ばれる単位で Object Body を分割して実行します。この例では、Object Body を 2 つのチャンクに分割してアップロードします。
サンプルコードは、以下の 3 種類の API の呼び出しで構成されます。4 回の API 呼び出し中、2 回はチャンクのアップロードのために同じ API を使っています。
kii_object_init_upload_body
Object Body のアップロードを開始します。Object Body のアップロードを行うため、Object はあらかじめサーバー上に作成しておく必要があります。
アップロード対象の Object は、
kii_bucket_t
構造体と Object の ID で指定します。Bucket の指定方法は、Object の作成 をご覧ください。最後の引数は、アップロード ID を返す領域へのポインタです。後続の API では、取得した アップロード ID を使ってリクエストします。最低、
KII_UPLOADID_SIZE + 1
バイトの領域を確保してください。このサンプルコードでは省略していますが、アップロード ID の取得後、エラーなどにより処理を中止する場合は、できるだけ
kii_object_commit_upload
を使ってロールバックするように実装してください。kii_object_upload_body
Object Body のデータのチャンクをアップロードして、アップロード済みのデータに追加します。この API を実行しても、まだ次のチャンクを受け付け可能な状態になっており、Object Body は書き換わっていません。
アップロード対象の Object は
kii_bucket_t
構造体、Object の ID、アップロード ID の 3 つで表現します。アップロード対象のデータのチャンクは、以下の
kii_chunk_data_t
構造体で指定します。メンバー 説明 body_content_type
データの Content-Type を "type/subtype" の形式の文字列で指定します。すべてのチャンクで同じ文字列を指定します。Kii Cloud に送信された Content-Type は、ダウンロード時や、公開された Object Body をブラウザで参照するときに使用されます。 position
Object Body のアップロード開始位置です。初めのチャンクでは 0、2 回目以降は前回までのアップロードサイズの合計を指定します。 length
このチャンクに含まれるデータの長さをバイト単位で指定します。 chunk
が指すデータの有効なサイズです。total_length
すべてのチャンクを結合した際の、Object Body の全体サイズを指定します。 chunk
このチャンクに含まれるデータへのポインタです。 kii_object_upload_body
は、データの全体をアップロードし終わるまで、繰り返して呼ぶことができます。kii_object_commit_upload
アップロードされた Object Body をコミットするか、キャンセルするかを指定します。
引数ではアップロード対象の Object を
kii_bucket_t
構造体、Object の ID、アップロード ID の 3 つで表現します。最後の引数が 1 以上の場合、アップロードがコミットされ、新しい Object Body に差し替わります。0 の場合、アップロードはキャンセルされ、Object Body は元のままです。
このサンプルでは、動作テストのため、合計 24 バイトの Object Body を 2 つのチャンクに分けてアップロードしています。OBJECT_BODY1
に格納された 12 バイトを 1 回目の kii_object_upload_body()
の呼び出しで、OBJECT_BODY2
に格納された 8 バイトを 2 回目の kii_object_upload_body()
の呼び出しでそれぞれ登録します。最後にコミット操作を行うと、これらは連続した 24 バイトの Object Body として登録されます。
各 API の呼び出しの間に Thing のプロセスのシャットダウンが入るようなケースでも、アップロード ID やチャンクの位置などが正しく管理できれば登録できます。これにより、大きな Object Body でも安全にアップロードすることができます。
一括アップロード
分割を行わず、1 回の API 呼び出しで Object Body 全体をアップロードすることも可能です(ただし、特にサイズの大きなファイルを Kii Cloud にアップロードするケースなどにおいては分割アップロードを利用することを推奨します)。
一括アップロードを行う例を以下に挙げます。
/* Set object body parameters. */
#define OBJECT_ID "STATUS_TEMPERATURE"
#define CONTENT_TYPE "application/octet-stream"
#define OBJECT_LENGTH 12
char OBJECT_BODY[] = {
0x31, 0x32, 0x33, 0x00, 0x34, 0x35, 0x36, 0x00, 0x37, 0x38, 0x39, 0x00
};
/* Set bucket parameters. */
kii_bucket_t bucket;
memset(&bucket, 0x00, sizeof(kii_bucket_t));
bucket.scope = KII_SCOPE_THING;
bucket.bucket_name = "myBucket";
bucket.scope_id = "VENDOR_THING_ID:rBnvSPOXBDF9r29GJeGS";
/* Upload the object body. */
ret = kii_object_upload_body_at_once(&kii, &bucket, OBJECT_ID, CONTENT_TYPE, OBJECT_BODY, OBJECT_LENGTH);
if (ret != 0) {
/* Handle the error. */
return;
}
kii_object_upload_body_at_once
関数を使用すると、指定されたバッファーの内容を Object Body としてアップロードします。1 回の API の呼び出しで、Object Body の全体をアップロードしてサーバー上の Object Body を更新します。Object はあらかじめサーバー上に作成しておく必要があります。
アップロード対象の Object は、kii_bucket_t
構造体と Object の ID で指定します。Bucket の指定方法は、Object の作成 をご覧ください。
データの Content-Type を "type/subtype" の形式の文字列で指定します。Kii Cloud に送信された Content-Type は、ダウンロード時や、公開された Object Body をブラウザで参照するときに使用されます。