
Amazon S3: ファイルダウンロード
この工程は、Amazon S3 の指定ファイルをダウンロードします。一度に複数のダウンロードが可能です。複数ダウンロードする場合、データ項目では 1 行につき 1 つずつオブジェクトキーを書くようにしてください。
Basic Configs
- 工程名
- メモ
Configs for this Auto Step
- conf_AccessKey
- C1: アクセスキー *
- conf_SecretKey
- C2: シークレットアクセスキー *
- conf_Region
- C3: リージョンコード *
- conf_Bucket
- C4: バケット名 *
- conf_Keys
- C5: ダウンロードするファイルのオブジェクトキー *
- conf_Files
- C6: ダウンロードファイルを追加保存するデータ項目 *
Notes
- アクセスキー、シークレットアクセスキーの作成方法については、Amazon Web Services のドキュメントを参照してください
Capture

See Also
Script (click to open)
- 次のスクリプトが記述されている XML ファイルをダウンロードできます
- aws-s3-file-download.xml (C) Questetra, Inc. (MIT License)
- Professional のワークフロー基盤では、ファイル内容を改変しオリジナルのアドオン自動工程として活用できます
const MAX_OBJECT_KEY_BYTES = 1024;
function main() {
////// == 工程コンフィグ・ワークフローデータの参照 / Config & Data Retrieving ==
const awsKey = configs.getObject("conf_AccessKey").getToken();
const awsSecret = configs.getObject("conf_SecretKey").getToken();
const region = retrieveRegion();
const bucket = retrieveBucket();
const objectKeys = retrieveObjectKeys();
////// == 演算 / Calculating ==
if (objectKeys.length === 0) {
return;
}
const fileDef = configs.getObject("conf_Files");
const files = engine.findData(fileDef) ?? new java.util.ArrayList();
objectKeys.forEach(objectKey => {
const newFile = downloadFile(awsKey, awsSecret, region, bucket, objectKey);
files.add(newFile);
});
engine.setData(fileDef, files);
}
/**
* config からリージョンコードを読み出す
* リージョンコードの形式として不正な場合はエラー
* @return {String}
*/
function retrieveRegion() {
const region = configs.get("conf_Region");
// 今後リージョンが増えることも考えて、中央の最大文字数には余裕をみている
const reg = new RegExp("^[a-z]{2}-[a-z]{4,16}-[1-9]$");
if (!reg.test(region)) {
throw new Error("Region Code is invalid.");
}
return region;
}
/**
* form-type="SELECT" editable="true"
* の設定値を読み出す
* @return {String}
*/
function getConfSelectValue(configName) {
const def = configs.getObject(configName);
if (def === null) {
return configs.get(configName);
}
return engine.findData(def) ?? "";
}
/**
* config からバケット名を読み出す
* バケット名の形式として不正な場合はエラー
* @return {String}
*/
function retrieveBucket() {
const bucket = getConfSelectValue("conf_Bucket");
if (bucket === "") {
throw new Error("Bucket Name is blank.");
}
const reg = new RegExp("^[0-9a-z][0-9a-z-.]{1,61}[0-9a-z]$");
if (!reg.test(bucket) || bucket.includes("..")) {
throw new Error("Bucket Name is invalid.");
}
return bucket;
}
/**
* config からオブジェクトキーを読み出す
* @return {Array<String>}
*/
function retrieveObjectKeys() {
const keyStr = getConfSelectValue("conf_Keys");
const keys = keyStr.split("\n").filter(key => key.length !== 0); // 空行は読み飛ばす。
keys.forEach(key => {
if (encodeURIComponent(key).replace(/%../g, "x").length > MAX_OBJECT_KEY_BYTES) {
throw new Error(`The object key "${key}" is too long. Object key must be less than ${MAX_OBJECT_KEY_BYTES} bytes.`);
}
if(key.endsWith('/')) {
throw new Error(`The object key "${key}" is invalid. Object key must not end with a slash.`);
}
});
if (keys.length > httpClient.getRequestingLimit()) {
throw new Error("The number of object keys exceeds the limit.");
}
return keys;
}
/**
* 保存時のファイル名の最大長
*/
const FILE_NAME_MAX_LENGTH = 200;
/**
* ファイルダウンロード
* @param key アクセスキー
* @param secret シークレットアクセスキー
* @param region リージョン
* @param bucket バケット
* @param objectKey オブジェクトキー
*/
function downloadFile(key, secret, region, bucket, objectKey) {
const encodedObjectKey = encodeURIComponent(objectKey);
const url = `https://${bucket}.s3.${region}.amazonaws.com/${encodedObjectKey}`;
const response = httpClient.begin()
.awsSignV4(key, secret, region, "s3")
.header("x-amz-checksum-mode", "ENABLED")
.get(url);
const status = response.getStatusCode();
if (status !== 200) {
engine.log(response.getResponseAsString());
throw new Error(`Failed to download "${objectKey}" from S3. status: ${status}`);
}
const data = response.getResponse();
// SHA-256 か SHA-1 のチェックサムがある場合、検証
validateChecksum(objectKey, response, "x-amz-checksum-sha256", () => digest.sha256(data));
validateChecksum(objectKey, response, "x-amz-checksum-sha1", () => digest.sha1(data));
let fileName = objectKey.split("/").pop();
if(fileName.length > FILE_NAME_MAX_LENGTH) {
fileName = fileName.substring(0, FILE_NAME_MAX_LENGTH-3) + "...";
}
return new com.questetra.bpms.core.event.scripttask.NewQfile(
fileName,
response.getContentType(),
data
);
}
/**
* チェックサムの検証
* @param objectKey ダウンロードしたファイルのオブジェクトキー
* @param response レスポンス
* @param headerName チェックサムヘッダー名
* @param calculate チェックサムを計算する関数
*/
function validateChecksum(objectKey, response, headerName, calculate) {
let checksumHeaders = response.getHeaderValues(headerName);
if (checksumHeaders.isEmpty()) {
return;
}
const checksum = checksumHeaders.get(0);
const calculated = base64.encodeToString(calculate());
if (checksum !== calculated) {
throw new Error(`The checksum of the downloaded file "${objectKey}" does not match. s3: ${checksum}, file: ${calculated}`);
}
engine.log(`Checksum of "${objectKey}" is OK. ${checksum}`);
}