AWS SDK for Javaの高水準ラッパーAWS Resource APIs for Javaを使ってみた
よく訓練されたアップル信者、都元です。本日何かが発売しておりますが平常心で行きます。平常心です。Javaを使ってAWSのAPIを叩く時に使うのはAWS SDK for Javaですね。
AWS SDK for Java
このAWS SDK for Javaですが、APIを呼び出す際に、一般的にこのようなコードを各必要があります。
AmazonFooBar amazonFooBar = new AmazonFooBarClient(); BazQuxResult bazQuxResult = amazonFooBar.bazQux(new BazQuxRequest() .withCourge("...") .withGrault(10)); Garply garply = bazQuxResult.getGarply();
クライアントを作るところまでは良いでしょう。その後、リクエストオブジェクトを作って、クライアントに渡して、レスポンスオブジェクトを得て、その中から必要な何かを色々取り出すわけです。
AmazonEC2 amazonEC2 = new AmazonEC2Client(); amazonEC2.setRegion(Region.getRegion(Regions.AP_NORTHEAST_1)); DescribeInstancesResult describeInstancesResult = amazonEC2.describeInstances(new DescribeInstancesRequest() .withInstanceIds("i-...") .withMaxResults(10)); List<Reservation> reservations = describeInstancesResult.getReservations(); for (Reservation reservation : reservations) { List<Instance> instances = reservation.getInstances(); for (Instance instance : instances) { // ... } }
ほぼ全てのAPI呼び出しについて、この形式で記述する必要があります。まぁある意味正しい抽象化なのかもしれませんが、ちょっと低水準な感は否めません。
AWS Resource APIs for Java
といったまどろっこしさを解消する高水準なラッパーとしてAWS Resource APIs for Javaというものが発表されています。Maven的にはこんな所に置いてあります。
<dependency> <groupId>com.amazonaws.resources</groupId> <artifactId>aws-resources</artifactId> <version>0.0.1</version> <type>pom</type> </dependency>
さてこのAPIですが、使い方はこんなかんじ。
EC2 ec2 = ServiceBuilder.forService(EC2.class) .withCredentials(new ProfileCredentialsProvider("default")) .withRegion(Region.getRegion(Regions.AP_NORTHEAST_1)) .build(); InstanceCollection instances = ec2.getInstances(); for (Instance instance : instances) { System.out.printf("EC2 instance %s : %s%n", instance.getId(), instance.getState().getName()); }
クライアントを作るところは大して変わらないとして。その後のAPIがだいぶ抽象化されています。危険なので書きませんでしたがinstance.terminate();と書いたりすると、全インスタンスを片っ端からterminateしてくれたりします。
AMIとEBS snapshotを全部消す!
たまにお片付けが必要、ということで書いてみました。下記のコードはよく理解しないまま実行すると色々取り返しがつかないので、実行前に必ず全てを理解してくださいね。
EC2 ec2 = ServiceBuilder.forService(EC2.class) .withCredentials(new ProfileCredentialsProvider("default")) .withRegion(Region.getRegion(Regions.AP_NORTHEAST_1)) .build(); ImageCollection images = ec2.getImages(new DescribeImagesRequest() .withOwners("self")); for (Image image : images) { System.out.printf("AMI %s : %s - deleting...", image.getId(), image.getDescription()); ResultCapture<Void> rc = new ResultCapture<>(); try { image.deregister(rc); System.out.println(rc); } catch (Exception e) { System.out.printf("failed - %s%n", e.getMessage()); } } SnapshotCollection snapshots = ec2.getSnapshots(new DescribeSnapshotsRequest().withOwnerIds("self")); for (Snapshot snapshot : snapshots) { System.out.printf("EBS snapshot %s : %s - deleting... ", snapshot.getId(), snapshot.getDescription()); ResultCapture<Void> rc = new ResultCapture<>(); try { snapshot.delete(rc); System.out.println(rc); } catch (Exception e) { System.out.printf("failed - %s%n", e.getMessage()); } }
従来よりもだいぶ分かりやすいコードが書けるようになりました。ちなみに実行結果は下記のような感じでした。
AMI ami-xxxxxxxx : null - deleting...{reponseMetadata={RequestId=xxxxxxxx-7f3b-474c-8828-ed60543234d1}, clientResult=null} AMI ami-xxxxxxxx : null - deleting...{reponseMetadata={RequestId=xxxxxxxx-5aaf-4c73-ac45-851170f0a5d8}, clientResult=null} AMI ami-xxxxxxxx : null - deleting...{reponseMetadata={RequestId=xxxxxxxx-22f5-44cc-b9d4-402babe472b2}, clientResult=null} AMI ami-xxxxxxxx : null - deleting...{reponseMetadata={RequestId=xxxxxxxx-cf7c-4869-890f-b7699d5a5762}, clientResult=null} AMI ami-xxxxxxxx : null - deleting...{reponseMetadata={RequestId=xxxxxxxx-cba6-4c57-a6bb-ed4ad0fbe0ea}, clientResult=null} EBS snapshot snap-xxxxxxxx : Created by CreateImage(i-xxxxxxxx) for ami-xxxxxxxx from vol-xxxxxxxx - deleting... {reponseMetadata={RequestId=xxxxxxxx-e198-4695-97ff-e46baeebde09}, clientResult=null} EBS snapshot snap-xxxxxxxx : Created by CreateImage(i-xxxxxxxx) for ami-xxxxxxxx from vol-xxxxxxxx - deleting... {reponseMetadata={RequestId=xxxxxxxx-a800-461d-bba4-e4df348676d5}, clientResult=null} EBS snapshot snap-xxxxxxxx : Created by CreateImage(i-xxxxxxxx) for ami-xxxxxxxx from vol-xxxxxxxx - deleting... {reponseMetadata={RequestId=xxxxxxxx-85a2-49bc-91cb-3af5aba8c9fd}, clientResult=null} EBS snapshot snap-xxxxxxxx : Created by CreateImage(i-xxxxxxxx) for ami-xxxxxxxx from vol-xxxxxxxx - deleting... {reponseMetadata={RequestId=xxxxxxxx-c4f2-4022-8614-68778e1f2bc5}, clientResult=null} EBS snapshot snap-xxxxxxxx : Created by CreateImage(i-xxxxxxxx) for ami-xxxxxxxx from vol-xxxxxxxx - deleting... {reponseMetadata={RequestId=xxxxxxxx-bc22-41c8-9089-2545305d180d}, clientResult=null}
まだバージョンは 0.0.1 ということで生まれたてのプロダクトですので、現時点で対応しているAWSプロダクトは、EC2・IAM・Glacierのみです。が、今後対応プロダクトは増えていくものと思います。素のSDKに嫌気がさしていた方は、こちらを使ってみると良いかもしれません。