わかってみたらなんでもなかったのですが、解決へたどり着くまでにかなり遠回りしたので、他の人の参考になればと思って記事を各ことにしました。
概要
Amazon S3に保存してあるファイルを取得して、その情報をクライアントへ返すということをやっています。クライアントアプリへAWS-SDKを組み込んでうまく動いていたのですが、同様の方法でWebサービスへ組み込んだら動かないという現象が発生しました。
前提
- AWSアカウントの環境を構築済み
- Amazon S3のバケットを作成済み
- ダウンロード対象となるファイルはS3へ保存済み
- Webサービスの環境が作成済みで稼働している(ここへ手を入れる)
環境
- OS:Windows Server 2012R2
- IIS:8.5
- 言語:vb.net(.NET Framework 4.5)
やったこと
-
AWS CLIでコマンドを実行
- ファイルが取得できることを確認
- Amazon S3への接続経路、アクセス権限、接続情報に問題なし
- ファイルが取得できることを確認
-
Webサービスへ手を入れてSDKで取得
- 「A WebException with status TrustFailure was thrown.」というメッセージが表示される
- Webで検索すると「証明書に関するエラー」が有力
- 証明書を無効にするロジックを組んでやってみた
- 「Error making request with Error Code Forbidden and Http Status Code Forbidden. No further error information was returned by the service.」というメッセージが表示される
- そもそもリクエストを受け付けてくれていないようで、全然ダメ
- 「A WebException with status TrustFailure was thrown.」というメッセージが表示される
-
他の環境で実績があるクライアントアプリを動かしてみた
- ファイルが取得できることを確認
- AWS-SDKの組み込みは問題ないため、Webサービスであることが原因ということが確定
- ファイルが取得できることを確認
-
インフラ担当者へ相談してみた
- クライアントアプリを実行するときにIEのプロキシ設定をはずしたら「A WebException with status TrustFailure was thrown.」というメッセージが表示される
- プロキシが効いていないことが原因でほぼ間違いない
- クライアントアプリを実行するときにIEのプロキシ設定をはずしたら「A WebException with status TrustFailure was thrown.」というメッセージが表示される
-
Webサービスへプロキシの指定を入れて実行
- ファイルを取得することができました!
参考までに、該当ロジックを載せます
備忘録として載せるために必要なロジックだけを抜き出しました。エラートラップとか変数の宣言とか組み込みがよくない部分はありますが、ご愛嬌ということでお願いします。
Imports System.IO
Imports Amazon
Imports Amazon.S3
Imports Amazon.S3.Transfer
Imports Amazon.S3.Model
public class main
Private localTmpDir As String = String.Empty
Private bucketRegion As RegionEndpoint
Private s3Client As IAmazonS3
Private bucketName As String = "{s3-bucketname}"
private sub main()
'S3クライアントインスタンス生成(s3configを使用)
Dim s3Config As New AmazonS3Config
s3Config.RegionEndpoint = RegionEndpoint.APNortheast1
s3Config.ProxyHost = "{255.255.255.255}"
s3Config.ProxyPort = 80
s3Client = New AmazonS3Client("{access_key}", "{secret_key}", s3Config)
localTmpDir = String.Format("D:\tmp\{0}", DateTime.Now.ToString("yyyyMMdd"))
If Not Directory.Exists(localTmpDir) Then MkDir(localTmpDir)
Dim FileList As New List(Of String)
Dim FileName As String = String.Empty
FileList.Add("ファイル1.txt")
FileList.Add("ファイル2.txt")
Dim SB As New StringBuilder
getImageFileFromS3BySDK(localTmpDir, bucketName, FileList)
end sub
Private Sub getImageFileFromS3BySDK(ByVal pDlDir As String, ByVal pBucketName As String, ByVal pFileList As List(Of String))
Try
Dim fileTransferUtility As New TransferUtility(s3Client)
For Each Str As String In pFileList
Dim dlFullPatrh As String = Path.Combine(pDlDir, Str.Replace("/", "\"))
fileTransferUtility.Download(dlFullPatrh, pBucketName, Str)
Next
Catch ex As Exception
'todo: エラー時の処理
End Try
End Sub
end class
参考ページ
おわりに
結果としてプロキシの設定が効いていないことが原因でしたが、エラーメッセージから推測するのは難しかった(私では不可)です。AWSへの接続に関する経験値が低かったことと、一度インフラ担当の方へ相談したときに首をかしげられてしまったことがあり、必要以上に調査に時間をとられてしまいました。
原因不明なときは状況を書き出してみたり、他の人へ相談して状況整理と知識を集めることをするのが必要だと感じました。