8.5. 用途
たとえば、camelazure
ストレージアカウントの container1
にあるブロック blob hello.txt
から blob コンテンツをダウンロードするには、次のスニペットを使用します。
from("azure-storage-blob://camelazure/container1?blobName=hello.txt&accessKey=yourAccessKey"). to("file://blobdirectory");
8.5.1. コンポーネントプロデューサーによって評価されるメッセージヘッダー
ヘッダー | 変数名 | タイプ | 操作 | 説明 |
---|---|---|---|---|
|
|
| すべて | それを超えると {@link RuntimeException} が発生する任意のタイムアウト値。 |
|
|
| コンテナーと BLOB に関する操作 | コンテナーまたは BLOB に関連付けるメタデータ。 |
|
|
|
|
このコンテナー内のデータを公開する方法を指定します。パブリックアクセスがない場合は |
|
|
| コンテナーと BLOB に関する操作 | これには、さまざまな要求の正常な動作を現在の条件に制限する値が含まれています。これらの条件は完全にオプションです。 |
|
|
|
| 特定のブロブを一覧表示するための詳細 |
|
|
|
| 結果をフィルター処理して、名前が指定された接頭辞で始まる BLOB のみを返します。すべての BLOB を返すには null の場合があります。 |
|
|
|
| すべての BlobPrefix 要素を含め、返される BLOB の最大数を指定します。要求で maxResultsPerPage が指定されていないか、5,000 を超える値が指定されている場合、サーバーは最大 5,000 項目を返します。 |
|
|
|
| {@link BlobContainerClient} オブジェクトで listBlobsFlatSegment への呼び出しの動作を設定するために使用できるオプションを定義します。 |
|
|
|
| 一連の操作の追加パラメーター。 |
|
|
|
| AccessTier の値を定義します。 |
|
|
| BLOB のアップロードに関連するほとんどの操作 | ブロックコンテンツの MD5 ハッシュ。このハッシュは、転送中にブロックの整合性を検証するために使用されます。このヘッダーが指定されている場合、ストレージサービスは、到着したコンテンツのハッシュとこのヘッダー値を比較します。この MD5 ハッシュは BLOB には保存されないことに注意してください。2 つのハッシュが一致しない場合、操作は失敗します。 |
|
|
| ページブロブに関連する操作 | {@link PageRange} オブジェクト。ページを 512 バイトの境界に揃える必要がある場合、開始オフセットは 512 の係数である必要があり、終了オフセットは 512 - 1 の係数である必要があります。有効なバイト範囲の例は、0 - 511、512 - 1023 などです。 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 返すブロックのタイプを指定します。 |
|
|
|
| ページ BLOB の最大サイズを 8 TB まで指定します。ページ BLOB のサイズは、512 バイトの境界に合わせる必要があります。 |
|
|
|
| リクエストの追跡に使用できるユーザー制御の値。シーケンス番号の値は、0 から 2^63 - 1 の間でなければなりません。デフォルト値は 0 です。 |
|
|
|
| この BLOB のスナップショットを削除するための動作を指定します。\{@code Include} は、ベース BLOB とすべてのスナップショットを削除します。\{@code Only} はスナップショットのみを削除します。スナップショットが削除されている場合は、null を渡す必要があります。 |
|
|
|
| サービスによって返されるデータを指定する {@link ListBlobContainersOptions}。 |
|
|
|
| ファイルへのダウンロードに使用する {@link ParallelTransferOptions}。並列転送数パラメーターは無視されます。 |
|
|
|
| ダウンロードした BLOB が保存されるファイルディレクトリー。 |
|
|
|
| URL ダウンロードリンクのデフォルトの有効期限 (ミリ秒) をオーバーライドします。 |
|
|
| ブロブに関連する操作 | 交換ヘッダーの BLOB 名をオーバーライド/設定します。 |
|
|
| コンテナーと BLOB に関する操作 | 交換ヘッダーのコンテナー名をオーバーライド/設定します。 |
|
|
| すべて | 実行するプロデューサー操作を指定します。プロデューサー操作に関連するこのページのドキュメントを参照してください。 |
|
|
|
| 結果をフィルタリングして、指定された正規表現と名前が一致する BLOB のみを返します。すべてを返すには null の場合があります。接頭辞と正規表現の両方が設定されている場合、正規表現が優先され、接頭辞は無視されます。 |
|
|
|
| 結果をフィルタリングして、開始時刻の前後のイベントを返します。注意: 前の時間に属するいくつかのイベントも返される可能性があります。この時間に属するいくつかのイベントが欠落している可能性があります。その時間のすべてのイベントが確実に返されるようにするには、開始時間を 1 時間単位で切り捨てます。 |
|
|
|
| 結果をフィルタリングして、終了時刻のほぼ前にイベントを返します。注意: 次の 1 時間に属するいくつかのイベントも返される可能性があります。この時間に属するいくつかのイベントが欠落している可能性があります。その時間のすべてのイベントが確実に返されるようにするには、終了時間を 1 時間単位で切り上げます。 |
|
|
|
| これにより、サービス呼び出し中に Http パイプラインを介して渡される追加のコンテキストが提供されます。 |
|
|
|
| コピー BLOB 操作でソースアカウント名として使用されるソース BLOB アカウント名 |
|
|
|
| コピー BLOB 操作でソースコンテナー名として使用されるソース BLOB コンテナー名 |
8.5.2. コンポーネントのプロデューサーまたはコンシューマーによって設定されるメッセージヘッダー
ヘッダー | 変数名 | タイプ | 説明 |
---|---|---|---|
|
|
| BLOB のアクセス層。 |
|
|
| BLOB のアクセス層が最後に変更された日時。 |
|
|
| BLOB のアーカイブステータス。 |
|
|
| ブロブの作成時間。 |
|
|
| ページ BLOB の現在のシーケンス番号。 |
|
|
| ブロブのサイズ。 |
|
|
| ブロブのタイプ。 |
|
|
| BLOB に指定されたキャッシュコントロール。 |
|
|
| 追加 BLOB にコミットされたブロックの数 |
|
|
| BLOB に指定されたコンテンツの配置。 |
|
|
| BLOB に指定されたコンテンツエンコーディング。 |
|
|
| BLOB に指定されたコンテンツ言語。 |
|
|
| BLOB に指定されたコンテンツ MD5。 |
|
|
| BLOB に指定されたコンテンツタイプ。 |
|
|
| BLOB に対する最後のコピー操作が完了した日時。 |
|
|
| BLOB の最後の増分コピースナップショットのスナップショット識別子。 |
|
|
| BLOB に対して実行された最後のコピー操作の識別子。 |
|
|
| BLOB に対して実行された最後のコピー操作の状態。 |
|
|
| BLOB に対して実行された最後のコピー操作のソース。 |
|
|
| BLOB に対して実行された最後のコピー操作の状態。 |
|
|
| BLOB に対する最後のコピー操作の説明。 |
|
|
| ブロブの E タグ |
|
|
| BLOB のアクセス層が BLOB のプロパティーから推測されたかどうかを示すフラグ。 |
|
|
| BLOB が増分コピーされたかどうかを示すフラグ。 |
|
|
| BLOB のコンテンツがサーバー上で暗号化されているかどうかを示すフラグ。 |
|
|
| BLOB が最後に変更された日時。 |
|
|
| BLOB のリースの種類。 |
|
|
| BLOB のリースの状態。 |
|
|
| BLOB のリースのステータス。 |
|
|
| BLOB に関連付けられた追加のメタデータ。 |
|
|
| ブロックがブロック BLOB にコミットされたオフセット。 |
|
|
|
操作 |
|
|
|
|
|
|
| ユーザーが使用できる解析されていない httpHeaders を返します。 |
8.5.3. 高度な Azure Storage Blob 設定
Camel アプリケーションがファイアウォールの背後で実行されている場合、または BlobServiceClient
インスタンス設定をより詳細に制御する必要がある場合は、独自のインスタンスを作成できます。
StorageSharedKeyCredential credential = new StorageSharedKeyCredential("yourAccountName", "yourAccessKey"); String uri = String.format("https://%s.blob.core.windows.net", "yourAccountName"); BlobServiceClient client = new BlobServiceClientBuilder() .endpoint(uri) .credential(credential) .buildClient(); // This is camel context context.getRegistry().bind("client", client);
次に、Camel azure-storage-blob
コンポーネント設定でこのインスタンスを参照します。
from("azure-storage-blob://cameldev/container1?blobName=myblob&serviceClient=#client") .to("mock:result");
8.5.4. レジストリー内の BlobServiceClient クライアントの自動検出
このコンポーネントは、レジストリー内の BlobServiceClient bean の存在を検出できます。そのタイプの唯一のインスタンスである場合、それはクライアントとして使用され、上記の例のように uri パラメーターとして定義する必要はありません。これは、エンドポイントのよりスマートな設定に非常に役立つ場合があります。
8.5.5. Azure Storage Blob プロデューサーの操作
Camel Azure Storage Blob コンポーネントは、プロデューサー側で幅広い操作を提供します。
サービスレベルの操作
これらの操作には、accountName
が 必要 です。
操作 | 説明 |
---|---|
| ブロブの内容を取得します。この操作の出力をブロブ範囲に制限できます。 |
| ストレージアカウント内の BLOB と BLOB メタデータに発生したすべての変更のトランザクションログを返します。変更フィードは、これらの変更の順序付けられた、保証された、永続的で不変の読み取り専用ログを提供します。 |
コンテナーレベルでの操作
これらの操作には、accountName
と containerName
が 必要です。
操作 | 説明 |
---|---|
| ストレージアカウント内に新しいコンテナーを作成します。同じ名前のコンテナーがすでに存在する場合、プロデューサーはそれを無視します。 |
| ストレージアカウント内の指定されたコンテナーを削除します。コンテナーが存在しない場合、操作は失敗します。 |
| フォルダー構造がフラット化された、このコンテナー内の BLOB のリストを返します。 |
BLOB レベルでの操作
これらの操作では、accountName
、containerName
、および blobName
が 必須です。
操作 | ブロブの種類 | 説明 |
---|---|---|
| 共通 | ブロブの内容を取得します。この操作の出力をブロブ範囲に制限できます。 |
| 共通 | ブロブを削除します。 |
| 共通 | パスで指定されたファイルに BLOB 全体をダウンロードします。ファイルが作成されますが、存在してはなりません。ファイルがすでに存在する場合、{@link FileAlreadyExistsException} が出力されます。 |
| 共通 | Shared Access Signature (SAS) を使用して、指定された BLOB のダウンロードリンクを生成します。デフォルトでは、これは許可されたアクセスを 1 時間に制限します。ただし、ヘッダーを使用してデフォルトの有効期限をオーバーライドできます。 |
| BlockBlob | 新しいブロック BLOB を作成するか、既存のブロック BLOB の内容を更新します。既存のブロック BLOB を更新すると、BLOB の既存のメタデータが上書きされます。PutBlob では部分的な更新はサポートされていません。既存の BLOB のコンテンツは新しいコンテンツで上書きされます。 |
|
|
指定されたブロックをブロック BLOB のステージング領域にアップロードし、後で commitBlobBlockList の呼び出しによってコミットします。ただし、ヘッダー |
|
|
BLOB を設定するブロック ID のリストを指定して、BLOB を書き込みます。ブロックが BLOB の一部として書き込まれるためには、ブロックが前の |
|
| 指定されたブロックリストフィルターを使用して、ブロック BLOB の一部としてアップロードされたブロックのリストを返します。 |
|
| 長さ 0 の追加 BLOB を作成します。commitAppendBlo`b 操作を呼び出して、追加 BLOB にデータを追加します。 |
|
|
新しいデータブロックを既存の追加 BLOB の末尾にコミットします。ヘッダー |
|
|
指定された長さのページ BLOB を作成します。 |
|
|
1 つ以上のページをページ BLOB に書き込みます。書き込みサイズは 512 の倍数である必要があります。ヘッダー |
|
| ページ BLOB のサイズを指定されたサイズ (512 の倍数である必要があります) に変更します。 |
|
| 指定されたページをページ BLOB から解放します。範囲のサイズは 512 の倍数でなければなりません。 |
|
| ページ BLOB またはページ BLOB のスナップショットの有効なページ範囲のリストを返します。 |
|
| 異なるアカウントからでも、あるコンテナーから別のコンテナーに BLOB をコピーします。 |
これらの操作を camel アプリケーションで使用する方法については、このページの例のセクションを参照してください。
8.5.6. コンシューマーの例
ファイルコンポーネントを使用して BLOB をファイルに取り込むには、次のようにします。
from("azure-storage-blob://camelazure/container1?blobName=hello.txt&accountName=yourAccountName&accessKey=yourAccessKey"). to("file://blobdirectory");
ただし、ファイルコンポーネントを使用せずにファイルに直接書き込むこともできます。BLOB をマシンに保存するには、fileDir
フォルダーパスを指定する必要があります。
from("azure-storage-blob://camelazure/container1?blobName=hello.txt&accountName=yourAccountName&accessKey=yourAccessKey&fileDir=/var/to/awesome/dir"). to("mock:results");
また、コンポーネントはバッチコンシューマーをサポートしているため、コンテナー名を指定するだけで複数の BLOB を使用できます。コンシューマーは、コンテナー内の BLOB の数に応じて複数の交換を返します。
例
from("azure-storage-blob://camelazure/container1?accountName=yourAccountName&accessKey=yourAccessKey&fileDir=/var/to/awesome/dir"). to("mock:results");
8.5.7. プロデューサー操作の例
-
listBlobContainers
from("direct:start") .process(exchange -> { // set the header you want the producer to evaluate, refer to the previous // section to learn about the headers that can be set // e.g: exchange.getIn().setHeader(BlobConstants.LIST_BLOB_CONTAINERS_OPTIONS, new ListBlobContainersOptions().setMaxResultsPerPage(10)); }) .to("azure-storage-blob://camelazure?operation=listBlobContainers&client&serviceClient=#client") .to("mock:result");
-
createBlobContainer
from("direct:start") .process(exchange -> { // set the header you want the producer to evaluate, refer to the previous // section to learn about the headers that can be set // e.g: exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, "newContainerName"); }) .to("azure-storage-blob://camelazure/container1?operation=createBlobContainer&serviceClient=#client") .to("mock:result");
-
deleteBlobContainer
:
from("direct:start") .process(exchange -> { // set the header you want the producer to evaluate, refer to the previous // section to learn about the headers that can be set // e.g: exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, "overridenName"); }) .to("azure-storage-blob://camelazure/container1?operation=deleteBlobContainer&serviceClient=#client") .to("mock:result");
-
listBlobs
:
from("direct:start") .process(exchange -> { // set the header you want the producer to evaluate, refer to the previous // section to learn about the headers that can be set // e.g: exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, "overridenName"); }) .to("azure-storage-blob://camelazure/container1?operation=listBlobs&serviceClient=#client") .to("mock:result");
-
getBlob
:
交換本体に outputStream
を設定し、それにデータを書き込むことができます。例:
from("direct:start") .process(exchange -> { // set the header you want the producer to evaluate, refer to the previous // section to learn about the headers that can be set // e.g: exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, "overridenName"); // set our body exchange.getIn().setBody(outputStream); }) .to("azure-storage-blob://camelazure/container1?blobName=blob&operation=getBlob&serviceClient=#client") .to("mock:result");
本体を設定しない場合、この操作は、さらに下流に進むことができる InputStream
インスタンスを提供します。
from("direct:start") .to("azure-storage-blob://camelazure/container1?blobName=blob&operation=getBlob&serviceClient=#client") .process(exchange -> { InputStream inputStream = exchange.getMessage().getBody(InputStream.class); // We use Apache common IO for simplicity, but you are free to do whatever dealing // with inputStream System.out.println(IOUtils.toString(inputStream, StandardCharsets.UTF_8.name())); }) .to("mock:result");
-
deleteBlob
:
from("direct:start") .process(exchange -> { // set the header you want the producer to evaluate, refer to the previous // section to learn about the headers that can be set // e.g: exchange.getIn().setHeader(BlobConstants.BLOB_NAME, "overridenName"); }) .to("azure-storage-blob://camelazure/container1?blobName=blob&operation=deleteBlob&serviceClient=#client") .to("mock:result");
-
downloadBlobToFile
:
from("direct:start") .process(exchange -> { // set the header you want the producer to evaluate, refer to the previous // section to learn about the headers that can be set // e.g: exchange.getIn().setHeader(BlobConstants.BLOB_NAME, "overridenName"); }) .to("azure-storage-blob://camelazure/container1?blobName=blob&operation=downloadBlobToFile&fileDir=/var/mydir&serviceClient=#client") .to("mock:result");
-
downloadLink
from("direct:start") .to("azure-storage-blob://camelazure/container1?blobName=blob&operation=downloadLink&serviceClient=#client") .process(exchange -> { String link = exchange.getMessage().getHeader(BlobConstants.DOWNLOAD_LINK, String.class); System.out.println("My link " + link); }) .to("mock:result");
-
uploadBlockBlob
from("direct:start") .process(exchange -> { // set the header you want the producer to evaluate, refer to the previous // section to learn about the headers that can be set // e.g: exchange.getIn().setHeader(BlobConstants.BLOB_NAME, "overridenName"); exchange.getIn().setBody("Block Blob"); }) .to("azure-storage-blob://camelazure/container1?blobName=blob&operation=uploadBlockBlob&serviceClient=#client") .to("mock:result");
-
stageBlockBlobList
from("direct:start") .process(exchange -> { final List<BlobBlock> blocks = new LinkedList<>(); blocks.add(BlobBlock.createBlobBlock(new ByteArrayInputStream("Hello".getBytes()))); blocks.add(BlobBlock.createBlobBlock(new ByteArrayInputStream("From".getBytes()))); blocks.add(BlobBlock.createBlobBlock(new ByteArrayInputStream("Camel".getBytes()))); exchange.getIn().setBody(blocks); }) .to("azure-storage-blob://camelazure/container1?blobName=blob&operation=stageBlockBlobList&serviceClient=#client") .to("mock:result");
-
commitBlockBlobList
from("direct:start") .process(exchange -> { // We assume here you have the knowledge of these blocks you want to commit final List<Block> blocksIds = new LinkedList<>(); blocksIds.add(new Block().setName("id-1")); blocksIds.add(new Block().setName("id-2")); blocksIds.add(new Block().setName("id-3")); exchange.getIn().setBody(blocksIds); }) .to("azure-storage-blob://camelazure/container1?blobName=blob&operation=commitBlockBlobList&serviceClient=#client") .to("mock:result");
-
getBlobBlockList
from("direct:start") .to("azure-storage-blob://camelazure/container1?blobName=blob&operation=getBlobBlockList&serviceClient=#client") .log("${body}") .to("mock:result");
-
createAppendBlob
from("direct:start") .to("azure-storage-blob://camelazure/container1?blobName=blob&operation=createAppendBlob&serviceClient=#client") .to("mock:result");
-
commitAppendBlob
from("direct:start") .process(exchange -> { final String data = "Hello world from my awesome tests!"; final InputStream dataStream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)); exchange.getIn().setBody(dataStream); // of course you can set whatever headers you like, refer to the headers section to learn more }) .to("azure-storage-blob://camelazure/container1?blobName=blob&operation=commitAppendBlob&serviceClient=#client") .to("mock:result");
-
createPageBlob
from("direct:start") .to("azure-storage-blob://camelazure/container1?blobName=blob&operation=createPageBlob&serviceClient=#client") .to("mock:result");
-
uploadPageBlob
from("direct:start") .process(exchange -> { byte[] dataBytes = new byte[512]; // we set range for the page from 0-511 new Random().nextBytes(dataBytes); final InputStream dataStream = new ByteArrayInputStream(dataBytes); final PageRange pageRange = new PageRange().setStart(0).setEnd(511); exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange); exchange.getIn().setBody(dataStream); }) .to("azure-storage-blob://camelazure/container1?blobName=blob&operation=uploadPageBlob&serviceClient=#client") .to("mock:result");
-
resizePageBlob
from("direct:start") .process(exchange -> { final PageRange pageRange = new PageRange().setStart(0).setEnd(511); exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange); }) .to("azure-storage-blob://camelazure/container1?blobName=blob&operation=resizePageBlob&serviceClient=#client") .to("mock:result");
-
clearPageBlob
from("direct:start") .process(exchange -> { final PageRange pageRange = new PageRange().setStart(0).setEnd(511); exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange); }) .to("azure-storage-blob://camelazure/container1?blobName=blob&operation=clearPageBlob&serviceClient=#client") .to("mock:result");
-
getPageBlobRanges
from("direct:start") .process(exchange -> { final PageRange pageRange = new PageRange().setStart(0).setEnd(511); exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange); }) .to("azure-storage-blob://camelazure/container1?blobName=blob&operation=getPageBlobRanges&serviceClient=#client") .log("${body}") .to("mock:result");
-
copyBlob
from("direct:copyBlob") .process(exchange -> { exchange.getIn().setHeader(BlobConstants.BLOB_NAME, "file.txt"); exchange.getMessage().setHeader(BlobConstants.SOURCE_BLOB_CONTAINER_NAME, "containerblob1"); exchange.getMessage().setHeader(BlobConstants.SOURCE_BLOB_ACCOUNT_NAME, "account"); }) .to("azure-storage-blob://account/containerblob2?operation=copyBlob&sourceBlobAccessKey=RAW(accessKey)") .to("mock:result");
このようにして、アカウント 'account' のコンテナー containerblob1 内の file.txt が、同じアカウントのコンテナー containerblob2 にコピーされます。
8.5.8. 開発ノート (重要)
すべての統合テストは Testcontainers を使用し、デフォルトで実行されます。Azure サービスを使用してすべての統合テストを実行できるようにするには、Azure の accessKey と accountName を取得する必要があります。モック単体テストに加えて、マイナーバージョンのアップグレードでも Azure クライアントが問題を起こす可能性があるため、変更を加えたり、クライアントのアップグレードごとに統合テストを実行したりする必要があります。統合テストを実行するには、このコンポーネントディレクトリーで次の maven コマンドを実行します。
mvn verify -PfullTests -DaccountName=myacc -DaccessKey=mykey
ここで、accountName
は Azure アカウント名で、accessKey
は Azure portal から生成されるアクセスキーです。