Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,17 @@
</repository>
</repositories>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bom</artifactId>
<version>2.21.17</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jgroups</groupId>
Expand All @@ -62,9 +73,12 @@
</exclusions>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-ec2</artifactId>
<version>1.11.125</version>
<groupId>software.amazon.awssdk</groupId>
<artifactId>ec2</artifactId>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>regions</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
Expand All @@ -91,8 +105,8 @@
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<artifactId>mockito-core</artifactId>
<version>5.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down
61 changes: 0 additions & 61 deletions src/main/java/com/meltmedia/jgroups/aws/AWSFaultLogger.java

This file was deleted.

41 changes: 19 additions & 22 deletions src/main/java/com/meltmedia/jgroups/aws/AWS_PING.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,6 @@
*/
package com.meltmedia.jgroups.aws;

import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
import com.amazonaws.services.ec2.model.Filter;
import com.amazonaws.services.ec2.model.Instance;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.jgroups.Address;
import org.jgroups.Event;
import org.jgroups.Message;
Expand All @@ -32,6 +26,12 @@
import org.jgroups.stack.IpAddress;
import org.jgroups.util.NameCache;
import org.jgroups.util.Responses;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.regions.internal.util.EC2MetadataUtils;
import software.amazon.awssdk.services.ec2.Ec2Client;
import software.amazon.awssdk.services.ec2.model.DescribeInstancesRequest;
import software.amazon.awssdk.services.ec2.model.Filter;
import software.amazon.awssdk.services.ec2.model.Instance;

import java.util.List;
import java.util.Objects;
Expand Down Expand Up @@ -124,7 +124,7 @@ public class AWS_PING extends Discovery {
}

@Property(description = "The AWS Credentials Chain Class to use when searching for the account.")
protected String credentials_provider_class = com.amazonaws.auth.DefaultAWSCredentialsProviderChain.class.getName();
protected String credentials_provider_class = DefaultCredentialsProvider.class.getName();
@Property(description = "The AWS Access Key for the account to search.")
protected String access_key;
@Property(description = "The AWS Secret Key for the account to search.")
Expand All @@ -145,12 +145,12 @@ public class AWS_PING extends Discovery {
/**
* This is looked up using the endpoint http://instance-data/latest/dynamic/instance-identity/document
*/
private InstanceIdentity instanceIdentity;
private EC2MetadataUtils.InstanceInfo instanceInfo;

/**
* The Service for all AWS related stuff
*/
private AmazonEC2 ec2;
private Ec2Client ec2;

/**
* Utility for expanding one ip address + port and range to multiple address:port
Expand All @@ -175,24 +175,21 @@ public void init() throws Exception {
super.init();

//get the instance identity
try (CloseableHttpClient client = HttpClients.createDefault()) {
this.instanceIdentity = InstanceIdentity.getIdentity(client);
}
this.instanceInfo = EC2MetadataUtils.getInstanceInfo();

//setup ec2 client
this.ec2 = EC2Factory.create(
instanceIdentity,
instanceInfo,
access_key,
secret_key,
credentials_provider_class,
new CredentialsProviderFactory(),
log_aws_error_messages);
new CredentialsProviderFactory());

this.ipAddressUtils = new IPAddressUtils(port_number, port_range);
this.tagUtils = new TagsUtils(ec2, instanceIdentity, tags).validateTags();
this.tagUtils = new TagsUtils(ec2, instanceInfo, tags).validateTags();
this.filterUtils = new FilterUtils(filters, tagUtils);

log.info("Configured for instance: " + instanceIdentity.instanceId);
log.info("Configured for instance: " + instanceInfo.getInstanceId());
filterUtils.getAwsFilters().ifPresent(f -> log.info("Configured with filters [%s]", f));
tagUtils.getAwsTagNames().ifPresent(t -> log.info("Configured with tags [%s]", t));
}
Expand All @@ -204,7 +201,7 @@ public void init() throws Exception {
public void stop() {
try {
if (ec2 != null) {
ec2.shutdown();
ec2.close();
}
} finally {
super.stop();
Expand Down Expand Up @@ -264,7 +261,7 @@ private List<String> getPrivateIpAddresses() {
// if there are aws filters defined, add them to the list.
filterUtils.getAwsFilters().ifPresent(filters::addAll);

final DescribeInstancesRequest request = new DescribeInstancesRequest().withFilters(filters);
final DescribeInstancesRequest request = DescribeInstancesRequest.builder().filters(filters).build();

if (log.isDebugEnabled()) {
log.debug("Describing AWS instances with the following filters [%s]", filters);
Expand All @@ -273,9 +270,9 @@ private List<String> getPrivateIpAddresses() {

// NOTE: the reservations group nodes together by when they were started. We
// need to dig through all of the reservations.
final List<String> result = ec2.describeInstances(request).getReservations().stream()
.flatMap(reservation -> reservation.getInstances().stream())
.map(Instance::getPrivateIpAddress)
final List<String> result = ec2.describeInstancesPaginator(request).reservations().stream()
.flatMap(reservation -> reservation.instances().stream())
.map(Instance::privateIpAddress)
.filter(Objects::nonNull)
.collect(Collectors.toList());

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.meltmedia.jgroups.aws;

import com.amazonaws.auth.AWSCredentialsProvider;
import org.jgroups.logging.Log;
import org.jgroups.logging.LogFactory;
import org.jgroups.util.Util;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;

public class CredentialsProviderFactory {
private final Log log;
Expand All @@ -24,16 +24,14 @@ public CredentialsProviderFactory(final Log log) {
* @throws ClassNotFoundException if the implementation could not be found.
* @throws InstantiationException if the implementation does not have a no argument constructor.
*/
public AWSCredentialsProvider createCredentialsProvider(final String credentialProviderClass) throws Exception {
public AwsCredentialsProvider createCredentialsProvider(final String credentialProviderClass) throws Exception {
try {
final Class<?> credsProviderClazz = Util.loadClass(credentialProviderClass, getClass());
return (AWSCredentialsProvider) credsProviderClazz.newInstance();
return (AwsCredentialsProvider) credsProviderClazz.getMethod("create").invoke(null);
} catch (NoSuchMethodException e) {
throw new Exception("unable to find create method on credentials provider class " + credentialProviderClass);
} catch (ClassNotFoundException e) {
throw new Exception("unable to load credentials provider class " + credentialProviderClass);
} catch (InstantiationException e) {
log.error("an instance of " + credentialProviderClass + " could not be created. Please check that it implements" +
" interface AWSCredentialsProvider and that is has a public empty constructor !");
throw e;
}
}
}
78 changes: 19 additions & 59 deletions src/main/java/com/meltmedia/jgroups/aws/EC2Factory.java
Original file line number Diff line number Diff line change
@@ -1,89 +1,49 @@
package com.meltmedia.jgroups.aws;

import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.handlers.RequestHandler;
import com.amazonaws.internal.StaticCredentialsProvider;
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2Client;
import com.amazonaws.transform.Unmarshaller;
import org.w3c.dom.Node;

import java.lang.reflect.Field;
import java.util.List;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.regions.internal.util.EC2MetadataUtils;
import software.amazon.awssdk.services.ec2.Ec2Client;


/**
* A factory for AmazonEC2 instances.
*/
@SuppressWarnings("deprecation")
public class EC2Factory {
private static String EC2_ENDPOINT_TEMPLATE = "ec2.{REGION}.amazonaws.com";

public static AmazonEC2 create(
final InstanceIdentity instanceIdentity,
public static Ec2Client create(
final EC2MetadataUtils.InstanceInfo instanceInfo,
final String accessKey,
final String secretKey,
final String credentialsProviderClass,
final CredentialsProviderFactory credentialsProviderFactory,
final Boolean logAwsErrorMessages) throws Exception {
final CredentialsProviderFactory credentialsProviderFactory
) throws Exception {

final AmazonEC2 ec2 = setupEC2Client(
instanceIdentity.region,
return setupEC2Client(
instanceInfo.getRegion(),
accessKey,
secretKey,
credentialsProviderClass,
credentialsProviderFactory);

//Lets do some good old reflection work to add a unmarshaller to the AmazonEC2Client just to log the exceptions from soap.
if (logAwsErrorMessages) {
setupAWSExceptionLogging(ec2);
}
return ec2;
}

private static AmazonEC2 setupEC2Client(
private static Ec2Client setupEC2Client(
final String region,
final String accessKey,
final String secretKey,
final String credentialsProviderClass,
final CredentialsProviderFactory credentialsProviderFactory) throws Exception {

final String endpoint = EC2_ENDPOINT_TEMPLATE.replace("{REGION}", region);
final AWSCredentialsProvider credentialsProvider = accessKey == null && secretKey == null ?
final AwsCredentialsProvider credentialsProvider = accessKey == null && secretKey == null ?
credentialsProviderFactory.createCredentialsProvider(credentialsProviderClass) :
new StaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey));

final AmazonEC2 ec2 = new AmazonEC2Client(credentialsProvider);
ec2.setEndpoint(endpoint);
return ec2;
}
StaticCredentialsProvider.create(AwsBasicCredentials.create(accessKey, secretKey));

/**
* Sets up the AmazonEC2Client to log soap faults from the AWS EC2 api server.
*/
private static void setupAWSExceptionLogging(AmazonEC2 ec2) {
boolean accessible = false;
Field exceptionUnmarshallersField = null;
try {
exceptionUnmarshallersField = AmazonEC2Client.class.getDeclaredField("exceptionUnmarshallers");
accessible = exceptionUnmarshallersField.isAccessible();
exceptionUnmarshallersField.setAccessible(true);
@SuppressWarnings("unchecked") final List<Unmarshaller<AmazonServiceException, Node>> exceptionUnmarshallers = (List<Unmarshaller<AmazonServiceException, Node>>) exceptionUnmarshallersField.get(ec2);
exceptionUnmarshallers.add(0, new AWSFaultLogger());
((AmazonEC2Client) ec2).addRequestHandler((RequestHandler) exceptionUnmarshallers.get(0));
} catch (Throwable t) {
//I don't care about this.
} finally {
if (exceptionUnmarshallersField != null) {
try {
exceptionUnmarshallersField.setAccessible(accessible);
} catch (SecurityException se) {
//I don't care about this.
}
}
}
return Ec2Client.builder()
.credentialsProvider(credentialsProvider)
.region(Region.of(region))
.build();
}

}
Loading