2017-12-28 55 views
0

Apache CamelはAWS S3とよくインターフェースしますが、正しく構築されていないシナリオが見つかりました。私がオンラインで見たすべてのCamelの例を見てみると、非ローカル環境で推奨される業界標準のAWS一時的な資格情報を誰も使用したことはありませんでした。 〜6ヶ月間生存する静的資格情報を使用することは、セキュリティ上の問題であり、手作業による負担(リフレッシュ)であり、現実的にはローカル環境以外の場所では使用しないでください。Apache Camel AWS S3:資格情報の有効期限と一時的な資格情報

カスタムのs3クライアントを設定すると、Camelは一時的な資格情報を取得できますが、AWS S3を指すキャメルルートはある時点で有効期限が切れます。 Camelはこれを知るには十分スマートではなく、例外やタイムアウトエラーを無期限に投げずにS3バケットをポーリングしようとし続けます。

私はそうのように私のエンドポイントにタイムアウト設定を追加しようとしました:

aws-s3://" + incomingAWSBucket + "?" + "amazonS3Client=#amazonS3Client&timeout=4000 

は誰がAWSの一時的な資格情報を使用してラクダをインターフェースまたはAWS資格の有効期限が切れた場合(前述のセットアップ与えられた)例外をスローする方法を説明することができます?

ありがとうございました!

+0

あなたはどのキャメルバージョン使用するか、より多くを伝えることができて、そこからのルートでそのエンドポイントを使用していますか?有効期限が切れた資格情報の場合、何をしたいのですか? –

+0

Camelバージョン2.20.0では、AWS s3を指すルートが1つあり、「to」ルートはローカルディレクトリです。最後に、資格情報がもはや機能しなくなった場合(基本的にタイムアウト例外)、キャメルに例外をスローしたいと思います。 –

+0

私はこれをまだ証明していませんが、キャメルプロセス内のAWSのデフォルトの資格情報チェーンに依存するカスタムS3クライアントを使用すると、資格情報自体を管理するクライアントになるようです。実験を終えると、これを更新します:AmazonS3ClientBuilder.standard()。withRegion(Regions.US_WEST_2).build(); –

答えて

0

他の人が望むのであれば、この質問への答えはチュートリアルには十分に密集しています。今のところ、私は正しいフォーラムとスレッドにコピーして貼り付けて、単語を出します:

あまりにも不平を言わずに、私はCamelがいかに強力で、そのドキュメントとサンプルのベースがAWSの世界での生産シナリオには本当に欠けています... 一口...これはオープンソースのlibのための一口と多分ストレッチです。

公式camel-s3 documentationを参照して、資格情報の問題を解決する方法を理解しました。まず、高度なS3構成を作成する方法を見てみましょう(aws sdk自体に依存しています。 s3クライアントを手動でインストールする)。 私はこれを理解した後、aws sdk documentation on IAM credentialsに行って、クライアント自体をビルドすることができるので、EC2インスタンスでこれがどのように機能するかを理解しました。上記の文書では、いくつかの裸の骨の例もあります。リストされている例を使ってテストをテストすると、この資格情報の更新(この質問の唯一の目的)が機能していないことがわかりました。最初は資格情報を得ることができましたが、手動で有効期限が切れた後でテスト中にリフレッシュしていませんでした。 最後に、資格情報の更新を独自に処理できるプロバイダチェーンを指定できることを確認しました。これを説明するawsのドキュメントはhereです。

最後に、aws s3バケットをポーリングするローカルのラクラセットアップの静的な認証情報が必要ですが、ec2sに保存されているリモート環境では、自分自身を完璧に更新する一時的な認証情報でアクセスできます。ワウサ! :)

これを行うには、一時的なIAM資格情報に依存している私のローカル開発とリモートラクラセットアップにローカルラクラセットアップを使用する工場を作っただけです。これにより、セキュリティ上の懸念や、すべてのリモート環境の資格情報を手動で更新する必要がなくなりました!

ファクトリの作成方法やローカル設定の&リモート設定を完全に設定する方法については説明しませんが、リモートセットアップ用のS3クライアントを作成するAmazonS3ClientBuilderのコードサンプルが含まれます。

AmazonS3ClientBuilder.standard() 
    .withCredentials(new InstanceProfileCredentialsProvider(false)) 
    .withRegion(Regions.US_WEST_2) 
    .build(); 

私がこれをどのように動作させることが望まれる場合は、プロセス全体を示すサンプルプロジェクトを提供できます。ここで要求することで

は、S3クライアントの私のローカルとリモートの実装です: ローカル:

public class LocalAWSS3ClientManagerImpl implements AWSS3ClientManager { 
    private static Logger logger = LoggerFactory.getLogger(LocalAWSS3ClientManagerImpl.class); 
    private PriorityCodeSourcesRoutesProperties priorityCodeSourcesRoutesProperties; 
    private SimpleRegistry registry = new SimpleRegistry(); 
    private CamelContext camelContext; 

public LocalAWSS3ClientManagerImpl(PriorityCodeSourcesRoutesProperties priorityCodeSourcesRoutesProperties) { 
    this.priorityCodeSourcesRoutesProperties = priorityCodeSourcesRoutesProperties; 
    registry.put("amazonS3Client", getS3Client()); 
    camelContext = new DefaultCamelContext(registry); 
    logger.info("Creating an AWS S3 manager for a local instance (you should not see this on AWS EC2s)."); 
} 

private AmazonS3 getS3Client() { 
    try { 
     String awsBucketAccessKey = priorityCodeSourcesRoutesProperties.getAwsBucketAccessKey(); 
     String awsBucketSecretKey = priorityCodeSourcesRoutesProperties.getAwsBucketSecretKey(); 
     AWSCredentials awsCredentials = new BasicAWSCredentials(awsBucketAccessKey, awsBucketSecretKey); 
     return AmazonS3ClientBuilder.standard().withCredentials(
       new AWSStaticCredentialsProvider(awsCredentials)).build(); 
    } catch (RuntimeException ex) { 
     logger.error("Could not create AWS S3 client with the given credentials from the local config."); 
    } 
    return null; 
} 

public Endpoint getIncomingAWSEndpoint(final String incomingAWSBucket, final String region, 
     final String fileNameToSaveAndDownload) { 
    return camelContext.getEndpoint(
      "aws-s3://" + incomingAWSBucket + "?" + "amazonS3Client=#amazonS3Client" 
      + "&region=" + region + "&deleteAfterRead=false" + "&prefix=" + fileNameToSaveAndDownload); 
} 

public Endpoint getOutgoingLocalEndpoint(final String outgoingEndpointDirectory, 
     final String fileNameToSaveAndDownload) { 
    return camelContext.getEndpoint(
      "file://" + outgoingEndpointDirectory + "?" + "fileName=" 
      + fileNameToSaveAndDownload + "&readLock=markerFile"); 
} 
} 

リモート:

public class RemoteAWSS3ClientManagerImpl implements AWSS3ClientManager { 
private static Logger logger = LoggerFactory.getLogger(RemoteAWSS3ClientManagerImpl.class); 
private PriorityCodeSourcesRoutesProperties priorityCodeSourcesRoutesProperties; 
private SimpleRegistry registry = new SimpleRegistry(); 
private CamelContext camelContext; 

public RemoteAWSS3ClientManagerImpl(PriorityCodeSourcesRoutesProperties priorityCodeSourcesRoutesProperties) { 
    this.priorityCodeSourcesRoutesProperties = priorityCodeSourcesRoutesProperties; 
    registry.put("amazonS3Client", getS3Client()); 
    camelContext = new DefaultCamelContext(registry); 
    logger.info("Creating an AWS S3 client for a remote instance (normal for ec2s)."); 
} 

private AmazonS3 getS3Client() { 
    try { 
     logger.info("Attempting to create an AWS S3 client with IAM role's temporary credentials."); 
     return AmazonS3ClientBuilder.standard() 
            .withCredentials(new InstanceProfileCredentialsProvider(false)) 
            .withRegion(Regions.US_WEST_2) 
            .build(); 
    } catch (RuntimeException ex) { 
     logger.error("Could not create AWS S3 client with the given credentials from the instance. " 
        + "The default credential chain was used to create the AWS S3 client. " 
        + ex.toString()); 
    } 
    return null; 
} 

public Endpoint getIncomingAWSEndpoint(final String incomingAWSBucket, final String region, 
     final String fileNameToSaveAndDownload) { 
    return camelContext.getEndpoint(
      "aws-s3://" + incomingAWSBucket + "?" + "amazonS3Client=#amazonS3Client" 
      + "&region=" + region + "&deleteAfterRead=false" + "&prefix=" + fileNameToSaveAndDownload); 
} 

public Endpoint getOutgoingLocalEndpoint(final String outgoingEndpointDirectory, 
     final String fileNameToSaveAndDownload) { 
    return camelContext.getEndpoint(
      "file://" + outgoingEndpointDirectory + "?" + "fileName=" 
      + fileNameToSaveAndDownload + "&readLock=markerFile"); 
} 

} 
+0

これは本当に面白いです。 Camel 2.21.xでは、クライアント設定を少し変更しています。https://github.com/apache/camel/commit/60d0ed8b43c0860ab42abb436df05f5c7a5a9e25私はサンプルプロジェクトを教えてくれますか? – Oscerd

+0

私は1つを作ることができましたが、絶対に必要な場合を除き、私はむしろそうしたいと思います。 今週は時間を割いて、完全なクラスを追加して、リモートクライアントとローカルクライアントをどのように組み立てるかのアイデアをより多く提供します。 –

+0

送信したコミットに関しては、これがどのように機能を大幅に拡張しているかわかりません。それでも静的な資格情報に依存しています(これはおそらく良いデフォルト動作です)。ただし、必要に応じて両方のシナリオ(リモートとローカル)を適切に処理できるようにコードを変更できます。 –