mirror of https://github.com/apache/jclouds.git
Fixed ec2 issue where whole thing aborts if one regoin is unavailable. Should be easy to implement with other providers.
This commit is contained in:
parent
073eba9699
commit
428b2bd2ea
|
@ -67,7 +67,7 @@ import com.google.inject.name.Names;
|
||||||
/**
|
/**
|
||||||
* Configures the EC2 connection.
|
* Configures the EC2 connection.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole (EDIT: Nick Terry nterry@familysearch.org)
|
||||||
*/
|
*/
|
||||||
@RequiresHttp
|
@RequiresHttp
|
||||||
@ConfiguresRestClient
|
@ConfiguresRestClient
|
||||||
|
@ -133,27 +133,30 @@ public class EC2RestClientModule<S extends EC2Client, A extends EC2AsyncClient>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class RegionIdToZoneId implements javax.inject.Provider<Map<String, String>> {
|
|
||||||
private final AvailabilityZoneAndRegionClient client;
|
|
||||||
private final Map<String, URI> regions;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public RegionIdToZoneId(EC2Client client, @Region Map<String, URI> regions) {
|
|
||||||
this.client = client.getAvailabilityZoneAndRegionServices();
|
|
||||||
this.regions = regions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
@Zone
|
@Zone
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> get() {
|
public Map<String, String> get() {
|
||||||
Builder<String, String> map = ImmutableMap.<String, String> builder();
|
Builder<String, String> map = ImmutableMap.builder();
|
||||||
|
HttpResponseException exception = null;
|
||||||
for (Entry<String, URI> region : regions.entrySet()) {
|
for (Entry<String, URI> region : regions.entrySet()) {
|
||||||
for (AvailabilityZoneInfo zoneInfo : client.describeAvailabilityZonesInRegion(region.getKey())) {
|
try {
|
||||||
map.put(zoneInfo.getZone(), region.getKey());
|
for (AvailabilityZoneInfo zoneInfo : client.describeAvailabilityZonesInRegion(region.getKey())) {
|
||||||
|
map.put(zoneInfo.getZone(), region.getKey());
|
||||||
|
}
|
||||||
|
} catch (HttpResponseException e) {
|
||||||
|
if (e.getMessage().contains("Unable to tunnel through proxy")) {
|
||||||
|
exception = e;
|
||||||
|
logger.error(e, "Could not describe availability zones in Region: %s", region.getKey());
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return map.build();
|
ImmutableMap<String, String> result = map.build();
|
||||||
|
if (result.isEmpty() && exception != null) {
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
package org.jclouds.ec2.config;
|
||||||
|
|
||||||
|
import static org.easymock.classextension.EasyMock.*;
|
||||||
|
|
||||||
|
import org.easymock.classextension.IMocksControl;
|
||||||
|
import org.jclouds.ec2.EC2Client;
|
||||||
|
import org.jclouds.ec2.domain.AvailabilityZoneInfo;
|
||||||
|
import org.jclouds.ec2.services.AvailabilityZoneAndRegionClient;
|
||||||
|
import org.jclouds.http.HttpCommand;
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
import static org.testng.Assert.*;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A test for {@link EC2RestClientModule}.
|
||||||
|
*
|
||||||
|
* @author Eric Pabst (pabstec@familysearch.org)
|
||||||
|
*/
|
||||||
|
public class EC2RestClientModuleTest {
|
||||||
|
@Test
|
||||||
|
public void testDescribeAvailabilityZonesInRegion_BestEffort() {
|
||||||
|
IMocksControl control = createControl();
|
||||||
|
EC2Client client = control.createMock(EC2Client.class);
|
||||||
|
AvailabilityZoneAndRegionClient regionClient = control.createMock(AvailabilityZoneAndRegionClient.class);
|
||||||
|
AvailabilityZoneInfo info1 = control.createMock(AvailabilityZoneInfo.class);
|
||||||
|
AvailabilityZoneInfo info2 = control.createMock(AvailabilityZoneInfo.class);
|
||||||
|
HttpCommand command = control.createMock(HttpCommand.class);
|
||||||
|
HttpResponseException exception = new HttpResponseException("Error: Unable to tunnel through proxy: ...", command, null);
|
||||||
|
|
||||||
|
expect(client.getAvailabilityZoneAndRegionServices()).andStubReturn(regionClient);
|
||||||
|
expect(regionClient.describeAvailabilityZonesInRegion("accessibleRegion1")).andReturn(Collections.singleton(info1));
|
||||||
|
expect(regionClient.describeAvailabilityZonesInRegion("inaccessibleRegion")).andThrow(exception);
|
||||||
|
expect(regionClient.describeAvailabilityZonesInRegion("accessibleRegion2")).andReturn(Collections.singleton(info2));
|
||||||
|
expect(info1.getZone()).andStubReturn("zone1");
|
||||||
|
expect(info2.getZone()).andStubReturn("zone2");
|
||||||
|
|
||||||
|
Map<String, URI> regions = new LinkedHashMap<String, URI>();
|
||||||
|
regions.put("accessibleRegion1", null);
|
||||||
|
regions.put("inaccessibleRegion", null);
|
||||||
|
regions.put("accessibleRegion2", null);
|
||||||
|
control.replay();
|
||||||
|
|
||||||
|
Map<String,String> expectedResult = new HashMap<String,String>();
|
||||||
|
expectedResult.put("zone1", "accessibleRegion1");
|
||||||
|
expectedResult.put("zone2", "accessibleRegion2");
|
||||||
|
|
||||||
|
EC2RestClientModule.RegionIdToZoneId regionIdToZoneId = new EC2RestClientModule.RegionIdToZoneId(client, regions);
|
||||||
|
assertEquals(regionIdToZoneId.get(), expectedResult);
|
||||||
|
control.verify();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDescribeAvailabilityZonesInRegion_RethrowIfNoneFound() {
|
||||||
|
IMocksControl control = createControl();
|
||||||
|
EC2Client client = control.createMock(EC2Client.class);
|
||||||
|
AvailabilityZoneAndRegionClient regionClient = control.createMock(AvailabilityZoneAndRegionClient.class);
|
||||||
|
HttpCommand command = control.createMock(HttpCommand.class);
|
||||||
|
HttpResponseException exception = new HttpResponseException("Error: Unable to tunnel through proxy: ...", command, null);
|
||||||
|
|
||||||
|
expect(client.getAvailabilityZoneAndRegionServices()).andStubReturn(regionClient);
|
||||||
|
expect(regionClient.describeAvailabilityZonesInRegion("inaccessibleRegion")).andThrow(exception);
|
||||||
|
|
||||||
|
Map<String, URI> regions = new LinkedHashMap<String, URI>();
|
||||||
|
regions.put("inaccessibleRegion", null);
|
||||||
|
control.replay();
|
||||||
|
|
||||||
|
EC2RestClientModule.RegionIdToZoneId regionIdToZoneId = new EC2RestClientModule.RegionIdToZoneId(client, regions);
|
||||||
|
try {
|
||||||
|
regionIdToZoneId.get();
|
||||||
|
fail("expected exception");
|
||||||
|
} catch (HttpResponseException e) {
|
||||||
|
assertEquals(e, exception);
|
||||||
|
}
|
||||||
|
control.verify();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDescribeAvailabilityZonesInRegion_NoZones() {
|
||||||
|
IMocksControl control = createControl();
|
||||||
|
EC2Client client = control.createMock(EC2Client.class);
|
||||||
|
AvailabilityZoneAndRegionClient regionClient = control.createMock(AvailabilityZoneAndRegionClient.class);
|
||||||
|
|
||||||
|
expect(client.getAvailabilityZoneAndRegionServices()).andStubReturn(regionClient);
|
||||||
|
expect(regionClient.describeAvailabilityZonesInRegion("emptyRegion")).andReturn(Collections.<AvailabilityZoneInfo>emptySet());
|
||||||
|
|
||||||
|
Map<String, URI> regions = new LinkedHashMap<String, URI>();
|
||||||
|
regions.put("emptyRegion", null);
|
||||||
|
control.replay();
|
||||||
|
|
||||||
|
EC2RestClientModule.RegionIdToZoneId regionIdToZoneId = new EC2RestClientModule.RegionIdToZoneId(client, regions);
|
||||||
|
assertEquals(regionIdToZoneId.get(), Collections.<String, String>emptyMap());
|
||||||
|
control.verify();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue