View Javadoc
1   package com.meltmedia.jgroups.aws;
2   
3   import com.amazonaws.AmazonServiceException;
4   import com.amazonaws.auth.AWSCredentialsProvider;
5   import com.amazonaws.auth.BasicAWSCredentials;
6   import com.amazonaws.handlers.RequestHandler;
7   import com.amazonaws.internal.StaticCredentialsProvider;
8   import com.amazonaws.services.ec2.AmazonEC2;
9   import com.amazonaws.services.ec2.AmazonEC2Client;
10  import com.amazonaws.transform.Unmarshaller;
11  import org.w3c.dom.Node;
12  
13  import java.lang.reflect.Field;
14  import java.util.List;
15  
16  
17  /**
18   * A factory for AmazonEC2 instances.
19   */
20  @SuppressWarnings("deprecation")
21  public class EC2Factory {
22    private static String EC2_ENDPOINT_TEMPLATE = "ec2.{REGION}.amazonaws.com";
23  
24    public static AmazonEC2 create(
25        final InstanceIdentity instanceIdentity,
26        final String accessKey,
27        final String secretKey,
28        final String credentialsProviderClass,
29        final CredentialsProviderFactory credentialsProviderFactory,
30        final Boolean logAwsErrorMessages) throws Exception {
31  
32      final AmazonEC2 ec2 = setupEC2Client(
33          instanceIdentity.region,
34          accessKey,
35          secretKey,
36          credentialsProviderClass,
37          credentialsProviderFactory);
38  
39      //Lets do some good old reflection work to add a unmarshaller to the AmazonEC2Client just to log the exceptions from soap.
40      if (logAwsErrorMessages) {
41        setupAWSExceptionLogging(ec2);
42      }
43      return ec2;
44    }
45  
46    private static AmazonEC2 setupEC2Client(
47        final String region,
48        final String accessKey,
49        final String secretKey,
50        final String credentialsProviderClass,
51        final CredentialsProviderFactory credentialsProviderFactory) throws Exception {
52  
53      final String endpoint = EC2_ENDPOINT_TEMPLATE.replace("{REGION}", region);
54      final AWSCredentialsProvider credentialsProvider = accessKey == null && secretKey == null ?
55          credentialsProviderFactory.createCredentialsProvider(credentialsProviderClass) :
56          new StaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey));
57  
58      final AmazonEC2 ec2 = new AmazonEC2Client(credentialsProvider);
59      ec2.setEndpoint(endpoint);
60      return ec2;
61    }
62  
63    /**
64     * Sets up the AmazonEC2Client to log soap faults from the AWS EC2 api server.
65     */
66    private static void setupAWSExceptionLogging(AmazonEC2 ec2) {
67      boolean accessible = false;
68      Field exceptionUnmarshallersField = null;
69      try {
70        exceptionUnmarshallersField = AmazonEC2Client.class.getDeclaredField("exceptionUnmarshallers");
71        accessible = exceptionUnmarshallersField.isAccessible();
72        exceptionUnmarshallersField.setAccessible(true);
73        @SuppressWarnings("unchecked") final List<Unmarshaller<AmazonServiceException, Node>> exceptionUnmarshallers = (List<Unmarshaller<AmazonServiceException, Node>>) exceptionUnmarshallersField.get(ec2);
74        exceptionUnmarshallers.add(0, new AWSFaultLogger());
75        ((AmazonEC2Client) ec2).addRequestHandler((RequestHandler) exceptionUnmarshallers.get(0));
76      } catch (Throwable t) {
77        //I don't care about this.
78      } finally {
79        if (exceptionUnmarshallersField != null) {
80          try {
81            exceptionUnmarshallersField.setAccessible(accessible);
82          } catch (SecurityException se) {
83            //I don't care about this.
84          }
85        }
86      }
87    }
88  
89  }