LoginSignup
2

More than 1 year has passed since last update.

Node.jsからIBM Cloud Object Storageへ接続する際のメモ

Posted at

はじめに

Node-REDからIBM Cloud Object Storageへ接続する際にエンドポイントの設定でハマったので、原因調査のためnode-red-contrib-cosモジュールで利用しているibm-cos-sdk (npmパッケージ)を使用した際のメモを残しておきます。

準備

1. ibm-cos-sdk (npmパッケージ)のインストール

適当のディレクトリを作成して、npmパッケージをインストールします。(例えば、testというディレクトリを作成します)

$ mkdir test
$ cd test
$ npm init -y
$ npm i ibm-cos-sdk

2. サンプルコードを作成

IBM Cloudのリファレンスページを参照して、サンプルコードを作成します。

client.js
var ibm = require('ibm-cos-sdk');

var config = {
 endpoint: '<エンドポイント>',
 ibmAuthEndpoint: 'https://iam.cloud.ibm.com/identity/token',
 apiKeyId: '<APIキーID>',
 serviceInstanceId: '<サービスインスタンスID>',
};

var cos = new ibm.S3(config);

function getBuckets() {
    console.log('Retrieving list of buckets');
    return cos.listBuckets()
    .promise()
    .then((data) => {
        if (data.Buckets != null) {
            console.log(data);
        }
    })
    .catch((e) => {
        console.error(`ERROR: ${e.code} - ${e.message}\n`);
    });
}

function getBucketContents(bucketName) {
    console.log(`Retrieving bucket contents from: ${bucketName}`);
    return cos.listObjects(
        {Bucket: bucketName},
    ).promise()
    .then((data) => {
        if (data != null && data.Contents != null) {
            for (var i = 0; i < data.Contents.length; i++) {
                var itemKey = data.Contents[i].Key;
                var itemSize = data.Contents[i].Size;
                console.log(`Item: ${itemKey} (${itemSize} bytes).`)
            }
        }    
    })
    .catch((e) => {
        console.error(`ERROR: ${e.code} - ${e.message}\n`);
    });
}

function getItem(bucketName, itemName) {
    console.log(`Retrieving item from bucket: ${bucketName}, key: ${itemName}`);
    return cos.getObject({
        Bucket: bucketName, 
        Key: itemName
    }).promise()
    .then((data) => {
        if (data != null) {
            console.log('File Contents: ' + Buffer.from(data.Body).toString());
        }    
    })
    .catch((e) => {
        console.error(`ERROR: ${e.code} - ${e.message}\n`);
    });
}

getBuckets();
getBucketContents('cloud-object-storage-82-cos-standard-1o6');
getItem('cloud-object-storage-82-cos-standard-1o6', 'test.txt');

config

ここで重要になるのはconfigに設定するendpoint、apiKeyId、serviceInstanceIdの値です。

apiKeyID と serviceInstanceId は、Cloud Object Storageの「サービス資格情報」の"apikey"と"resource_instance_id"を値を設定するのが正解です。
endpoint は バケットの設定(回復力・ロケーション)によって値が異なります。

68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f37323437392f61393633323632332d303634662d623436302d306436392d3561333139366562383761312e6a706567.jpg

間違いやすい点①

apiKeyIDと"apikey"で名称が微妙に違うことと、serviceInstanceIdは"resource_instance_id"で名称が異なっているのが間違いやすい点です。
「サービス資格情報」には iam_apikey_description や iam_apikey_name など、apikeyを含む似たような名称があったり、
serviceInstanceIdは、「サービス資格情報」のiam_serviceid_crnと混同しました。(serviceとidを含む名称のため)

間違いやすい点②

endpointは「サービス資格情報」の"endpoints"ではありません。

エンドポイントの情報は以下にあります。

例えば、アクセス先のバケットの回復力がRegional、ロケーションがjp-tokの場合、エンドポイント(パブリック接続)は
s3.jp-tok.cloud-object-storage.appdomain.cloud
になります。

サンプルコードの実行例

configに誤りがある場合

エンドポイントが間違っていてもバケットの一覧は表示されます。
バケットの中身や指定したファイル(オブジェクト)は表示されません。
(ERROR: NoSuchBucketやERROR: NoSuchKeyになります)

$ node client.js

Retrieving list of buckets
{
  Buckets: [
    {
      Name: 'cloud-object-storage-82-cos-standard-001',
      CreationDate: 2021-05-07T08:08:36.589Z
    },
    {
      Name: 'cloud-object-storage-82-cos-standard-1o6',
      CreationDate: 2021-05-07T03:31:45.802Z
    },
    {
      Name: 'cloud-object-storage-82-cos-standard-257',
      CreationDate: 2021-05-07T11:37:55.016Z
    },
    {
      Name: 'cloud-object-storage-82-cos-standard-ztk',
      CreationDate: 2021-05-06T07:51:49.717Z
    }
  ],
  Owner: {
    DisplayName: '77c04f4b-8e89-4636-be0c-be8eb1331f15',
    ID: '77c04f4b-8e89-4636-be0c-be8eb1331f15'
  }
}

Retrieving bucket contents from: cloud-object-storage-82-cos-standard-1o6
ERROR: NoSuchBucket - The specified bucket does not exist.

Retrieving item from bucket: cloud-object-storage-82-cos-standard-1o6, key: test.txt
ERROR: NoSuchKey - The specified key does not exist.

configが正しい場合

$ node client.js

Retrieving list of buckets
{
  Buckets: [
    {
      Name: 'cloud-object-storage-82-cos-standard-001',
      CreationDate: 2021-05-07T08:08:36.589Z
    },
    {
      Name: 'cloud-object-storage-82-cos-standard-1o6',
      CreationDate: 2021-05-07T03:31:45.802Z
    },
    {
      Name: 'cloud-object-storage-82-cos-standard-257',
      CreationDate: 2021-05-07T11:37:55.016Z
    },
    {
      Name: 'cloud-object-storage-82-cos-standard-ztk',
      CreationDate: 2021-05-06T07:51:49.717Z
    }
  ],
  Owner: {
    DisplayName: '77c04f4b-8e89-4636-be0c-be8eb1331f15',
    ID: '77c04f4b-8e89-4636-be0c-be8eb1331f15'
  }
}

Retrieving bucket contents from: cloud-object-storage-82-cos-standard-1o6
Item: test.txt (22 bytes).

Retrieving item from bucket: cloud-object-storage-82-cos-standard-1o6, key: test.txt
File Contents: This is a test file.

まとめ

みなさま、IBM CloudのLiteアカウントで良きNode-REDライフを!

参考

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2