SoftLayer時代に作ったObjectStorage(SWIFT)をIBM Cloud(S3)に引っ越し

IBM Object Storage開発関連

Object Storage OpenStack Swift が徐々に終了していくとのことなので、S3に引っ越しする必要があります。該当機能を使っている場合は2019年3月31日までに移行が必要とのことです。詳細は以下を参照してください。

https://www.ibm.com/blogs/solutions/jp-ja/object-storage-openstack-swift-infrastructure/

S3の作成からツールを使ってのコピーはこのBLOGがわかりやすかったです。

IBM Cloud Object Storage のデータを Swift API コンテナ から S3 API バケットに移行する

https://qiita.com/khayama/items/0a55c2001aa5efe55286

IBM Cloud Object StorageのSwiftコンテナ からS3バケットへの移行検証

https://qiita.com/daihiraoka/items/5c49b7f2316c464704e7

で、問題は昔Javaで作ったプログラムも修正が必要だったり。。。
IBMのAPIドキュメントがところどころリンク切れしてたり、すでに非推奨メソッドになっていたり、、、ちょっと困ったのでまとめておきます。
参考にしたIBMのドキュメントはこちらです。
ダッシュボードが見れない方は少し見づらいですがここからもドキュメントがみれます。

スポンサーリンク

Javaライブラリを使ったサンプル

といっても、サンプルプログラムはScalaですw

build.sbtにIBMのライブラリを追加

独自で作ろうと思ったのですが、認証部分のドキュメントが見つからず。。。
なので素直にライブラリを使うことにしました。以下、build.sbtに追加する例です。

  "com.ibm.cos"          %  "ibm-cos-java-sdk"         % "2.1.+"

Mavenリポジトリはこちら

バケット一覧を取得するサンプルソース

withCredentialsのところは認証情報の読み込み方によってクラスを変える感じです。引数で認証情報を貰って使いたかったのでBasicAWSCredentials使いました。その他にも色々あるのですが、知りたい方はAWSのリファレンスみるのがいいと思います。
あとIBMのリージョン一覧はここみてください。東京リージョンは”ap-northeast-1”となります。

テスト実行

      val client = new S3Client(
        "アクセスキー",
        "シークレットアクセスキー",
        "エンドポイント"
      )
      val result = client.list()

その他の細かいリファレンスはJavadocをみてください。

AWS CLIから接続

【2019-06-07】追記
Javaのライブラリからだと細かい設定ができませんでした。ライフサイクルとか。
なので、なんだかんだでAWS CLIをインストールしておいたほうがいいです。
以下、インストール方法です。

初期設定

IBMのS3につなぐ際にはエンドポイントを指定する必要があります。以下はライフサイクルの設定をとるコマンドの例です。

aws --endpoint-url=https://エンドポイント s3api get-bucket-lifecycle-configuration --bucket バケット名

使えるコマンドの詳細は公式リファレンスみてください。

IBMのドキュメントはここです。

トラブルシュート

Javaライブラリの実行エラーごとの解決策のメモになります。

Unable to find a region via the region provider chain.

リージョン指定しわすれるとこのエラーがでます。(もしくは存在しないリージョン指定)withEndpointConfigurationで正しいリージョンを指定すれば解決します。

[info]   com.ibm.cloud.objectstorage.SdkClientException: Unable to find a region via the region provider chain. Must provide an explicit region in the builder or setup environment to supply a region.
[info]   at com.ibm.cloud.objectstorage.client.builder.AwsClientBuilder.setRegion(AwsClientBuilder.java:459)
[info]   at com.ibm.cloud.objectstorage.client.builder.AwsClientBuilder.configureMutableProperties(AwsClientBuilder.java:425)
[info]   at com.ibm.cloud.objectstorage.client.builder.AwsSyncClientBuilder.build(AwsSyncClientBuilder.java:46)
[info]   at utils.s3.S3Client.client$lzycompute(S3Client.scala:31)

The AWS Access Key Id you provided does not exist in our records.

エンドポイントを指定せずに実行していないか、認証情報が間違えていないか確認してください。

[info]   com.ibm.cloud.objectstorage.services.s3.model.AmazonS3Exception: The AWS Access Key Id you provided does not exist in our records. (Service: Amazon S3; Status Code: 403; Error Code: InvalidAccessKeyId; Request ID: 05B34906EB09EAED)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1588)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1258)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1030)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:742)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:716)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient.execute(AmazonHttpClient.java:513)
[info]   at com.ibm.cloud.objectstorage.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3633)

Client is immutable when created with the builder.

生成したClientでsetメソッドを呼ぶとエラーになります。設定周りはきちんとAmazonS3ClientBuilderを使いましょう。

Unable to execute HTTP request: Connect to s3.private.xxxxx:443 [s3.private.xxxxx] failed: connect timed out

接続できないドメインをエンドポイントに指定した場合に発生。あとはローカルPCからPrivate URLを指定すると名前解決できなくてエラーになったりします。IBMの内部ネットワーク外から接続する場合はPublic URLを指定しましょう。

[info]   com.ibm.cloud.objectstorage.SdkClientException: Unable to execute HTTP request: Connect to s3.private.xxxxx:443 [s3.private.xxxxx/10.1.xxx.xx] failed: connect timed out
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.handleRetryableException(AmazonHttpClient.java:1069)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1035)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:742)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:716)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient.execute(AmazonHttpClient.java:513)
[info]   at com.ibm.cloud.objectstorage.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3633)
[info]   at com.ibm.cloud.objectstorage.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3580)

Must have at least one AllowedMethod per rule (Service: Amazon S3; Status Code: 400; Error Code: InvalidRequest;

クロスオリジンの設定をclient.setBucketCrossOriginConfigurationでする際に、Methodの指定を忘れるとでるエラー。

[info]   com.ibm.cloud.objectstorage.services.s3.model.AmazonS3Exception: Must have at least one AllowedMethod per rule (Service: Amazon S3; Status Code: 400; Error Code: InvalidRequest; Request ID: XXXXXXX)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1588)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1258)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1030)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:742)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:716)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient.execute(AmazonHttpClient.java:513)
[info]   at com.ibm.cloud.objectstorage.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3633)

こんな感じで許可するメソッドを追加すればいいです。

      val ruleAM = List(
        CORSRule.AllowedMethods.PUT,
        CORSRule.AllowedMethods.POST,
        CORSRule.AllowedMethods.DELETE
      ).asJava
      // 検証環境
      client.setBucketCrossOriginConfiguration(
        "バケット名",
        new BucketCrossOriginConfiguration().withRules(
          new CORSRule().withAllowedOrigins(
            List("*").asJava
          ).withAllowedMethods(ruleAM).withId("CORSのルールID")
        )
      )

The CORS configuration does not exist

エラーではないですがCORSの設定が無い状態でgetBucketCrossOriginConfigurationをするとこのログがでます。また、その際にはnullが返ってきます。

[DEBUG]com.ibm.cloud.objectstorage.request 
Received error response: com.ibm.cloud.objectstorage.services.s3.model.AmazonS3Exception: The CORS configuration does not exist (Service: Amazon S3; Status Code: 404; Error Code: NoSuchCORSConfiguration; Request ID: XXXXX), S3 Extended Request ID: null

Bad Request (Service: Amazon S3; Status Code: 400; Error Code: 400 Bad Request; Request ID: null)

putObjectする際のキーに「/test/blank-icon.png」を設定したらこのエラーが。。。どうも内部で先頭に/つけてくれるみたいで「//test/blank-icon.png」になってしまうのが原因のようです。。。
「test/blank-icon.png」にしたらなおりました。

[DEBUG]com.ibm.cloud.objectstorage.services.s3.internal.S3ErrorResponseHandler Failed in parsing the error response : 
javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: 途中でファイルの末尾に達しました。
	at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:601) ~[na:1.8.0_45]
	at com.ibm.cloud.objectstorage.services.s3.internal.S3ErrorResponseHandler.createException(S3ErrorResponseHandler.java:125) [ibm-cos-java-sdk-s3-2.1.3.jar:na]
	at com.ibm.cloud.objectstorage.services.s3.internal.S3ErrorResponseHandler.handle(S3ErrorResponseHandler.java:67) [ibm-cos-java-sdk-s3-2.1.3.jar:na]
	at com.ibm.cloud.objectstorage.services.s3.internal.S3ErrorResponseHandler.handle(S3ErrorResponseHandler.java:50) [ibm-cos-java-sdk-s3-2.1.3.jar:na]
[DEBUG]com.ibm.cloud.objectstorage.request Received error response: com.ibm.cloud.objectstorage.services.s3.model.AmazonS3Exception: Bad Request (Service: Amazon S3; Status Code: 400; Error Code: 400 Bad Request; Request ID: null), S3 Extended Request ID: null
[info]   com.ibm.cloud.objectstorage.services.s3.model.AmazonS3Exception: Bad Request (Service: Amazon S3; Status Code: 400; Error Code: 400 Bad Request; Request ID: null)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1588)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1258)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1030)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:742)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:716)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649)
[info]   at com.ibm.cloud.objectstorage.http.AmazonHttpClient.execute(AmazonHttpClient.java:513)
[info]   at com.ibm.cloud.objectstorage.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3633)
©2018 LLC Shimer-System.
image/svg+xml