Merge branch 'master' of github.com:jclouds/jclouds into 1.5.x

* 'master' of github.com:jclouds/jclouds: (30 commits)
  Merge Keystone optional admin API provider with optional extension provider
  Added binding for optional extensions
  Make the OpenStack extension lists accessible for all APIs. Copied the Nova extension related code to the shared keystone package and added providers for extensions and aliases to all modules
  added statement to rebase dist packages
  added VAppNetworksLiveTest
  Further OpenStack extensibility changes. Fixing constructors in RestContext classes
  Fixed a possible NPE when ServiceFunctionLoader finds no OSGi service for a function.
  fixed broken test
  threading issue in test
  openstack-quantum extensibility
  openstack-swift extensibility
  openstack-glance extensibility
  openstack-nova extensibility
  openstack-keystone extensibility
  add FirstNetwork, in line with FirstRegion, etc., for use in FGCP provider
  missing class
  refactoring of smartos-ssh
  Extend the VmSpecification to allow for all the extra memory settings.
  Issue 1067:update to guava 13
  removed invalid @Nullable usage and also usage of javax package usage
  ...
This commit is contained in:
Adrian Cole 2012-08-13 20:29:15 -07:00
commit 81d5f31359
178 changed files with 2328 additions and 1226 deletions

View File

@ -24,7 +24,6 @@ import static com.google.common.base.Preconditions.checkState;
import java.util.Map; import java.util.Map;
import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
@ -68,7 +67,7 @@ public class BindCloneDriveOptionsToPlainTextString implements MapBinder {
request.setPayload(listOfMapsToListOfKeyValuesDelimitedByBlankLines.apply(ImmutableSet.of(Maps.transformValues(postParams, new Function<Object, String>() { request.setPayload(listOfMapsToListOfKeyValuesDelimitedByBlankLines.apply(ImmutableSet.of(Maps.transformValues(postParams, new Function<Object, String>() {
@Override @Override
public String apply(@Nullable Object input) { public String apply(Object input) {
return input == null ? null : input.toString(); return input == null ? null : input.toString();
} }
})))); }))));

View File

@ -27,7 +27,6 @@ import static org.jclouds.util.InetAddresses2.isPrivateIPAddress;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
@ -153,12 +152,12 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No
filter(getIPForwardingRulesByVirtualMachine.getUnchecked(from.getId()), filter(getIPForwardingRulesByVirtualMachine.getUnchecked(from.getId()),
new Predicate<IPForwardingRule>() { new Predicate<IPForwardingRule>() {
@Override @Override
public boolean apply(@Nullable IPForwardingRule rule) { public boolean apply(IPForwardingRule rule) {
return !"Deleting".equals(rule.getState()); return !"Deleting".equals(rule.getState());
} }
}), new Function<IPForwardingRule, String>() { }), new Function<IPForwardingRule, String>() {
@Override @Override
public String apply(@Nullable IPForwardingRule rule) { public String apply(IPForwardingRule rule) {
return rule.getIPAddress(); return rule.getIPAddress();
} }
})); }));

View File

@ -20,8 +20,6 @@ package org.jclouds.cloudstack.predicates;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import javax.annotation.Nullable;
import org.jclouds.cloudstack.domain.GuestIPType; import org.jclouds.cloudstack.domain.GuestIPType;
import org.jclouds.cloudstack.domain.Network; import org.jclouds.cloudstack.domain.Network;
import org.jclouds.cloudstack.domain.NetworkService; import org.jclouds.cloudstack.domain.NetworkService;
@ -163,7 +161,7 @@ public class NetworkPredicates {
} }
@Override @Override
public boolean apply(@Nullable GuestIPType guestIPType) { public boolean apply(GuestIPType guestIPType) {
return guestIPType == this.guestIPType; return guestIPType == this.guestIPType;
} }

View File

@ -26,8 +26,6 @@ import static org.testng.Assert.assertTrue;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Set; import java.util.Set;
import javax.annotation.Nullable;
import org.jclouds.cloudstack.domain.AsyncCreateResponse; import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.FirewallRule; import org.jclouds.cloudstack.domain.FirewallRule;
import org.jclouds.cloudstack.domain.Network; import org.jclouds.cloudstack.domain.Network;
@ -69,7 +67,7 @@ public class FirewallClientLiveTest extends BaseCloudStackClientLiveTest {
network = find(client.getNetworkClient().listNetworks(), Predicates.and(supportsPortForwarding(), network = find(client.getNetworkClient().listNetworks(), Predicates.and(supportsPortForwarding(),
new Predicate<Network>() { new Predicate<Network>() {
@Override @Override
public boolean apply(@Nullable Network network) { public boolean apply(Network network) {
return network.isDefault() return network.isDefault()
&& !network.isSecurityGroupEnabled() && !network.isSecurityGroupEnabled()
&& network.getAccount().equals(user.getAccount()); && network.getAccount().equals(user.getAccount());

View File

@ -24,8 +24,6 @@ import static org.testng.Assert.assertEquals;
import java.util.Set; import java.util.Set;
import javax.annotation.Nullable;
import org.jclouds.cloudstack.domain.ConfigurationEntry; import org.jclouds.cloudstack.domain.ConfigurationEntry;
import org.jclouds.cloudstack.internal.BaseCloudStackClientLiveTest; import org.jclouds.cloudstack.internal.BaseCloudStackClientLiveTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -97,7 +95,7 @@ public class GlobalConfigurationClientLiveTest extends BaseCloudStackClientLiveT
private ConfigurationEntry getEntryByName(Set<ConfigurationEntry> entries, final String name) { private ConfigurationEntry getEntryByName(Set<ConfigurationEntry> entries, final String name) {
return Iterables.find(entries, new Predicate<ConfigurationEntry>() { return Iterables.find(entries, new Predicate<ConfigurationEntry>() {
@Override @Override
public boolean apply(@Nullable ConfigurationEntry entry) { public boolean apply(ConfigurationEntry entry) {
return entry != null && Objects.equal(name, entry.getName()); return entry != null && Objects.equal(name, entry.getName());
} }
}); });

View File

@ -23,8 +23,6 @@ import static org.jclouds.cloudstack.options.UpdateDomainOptions.Builder.name;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull; import static org.testng.Assert.assertNull;
import javax.annotation.Nullable;
import org.jclouds.cloudstack.domain.Domain; import org.jclouds.cloudstack.domain.Domain;
import org.jclouds.cloudstack.internal.BaseCloudStackClientLiveTest; import org.jclouds.cloudstack.internal.BaseCloudStackClientLiveTest;
import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeMethod;
@ -48,7 +46,7 @@ public class GlobalDomainClientLiveTest extends BaseCloudStackClientLiveTest {
domainClient = globalAdminClient.getDomainClient(); domainClient = globalAdminClient.getDomainClient();
rootDomain = find(domainClient.listDomains(), new Predicate<Domain>() { rootDomain = find(domainClient.listDomains(), new Predicate<Domain>() {
@Override @Override
public boolean apply(@Nullable Domain domain) { public boolean apply(Domain domain) {
return domain != null && domain.getName().equals("ROOT"); return domain != null && domain.getName().equals("ROOT");
} }
}); });

View File

@ -30,8 +30,6 @@ import java.util.NoSuchElementException;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import org.jclouds.cloudstack.domain.AsyncJob; import org.jclouds.cloudstack.domain.AsyncJob;
import org.jclouds.cloudstack.domain.JobResult; import org.jclouds.cloudstack.domain.JobResult;
import org.jclouds.cloudstack.domain.LoadBalancerRule; import org.jclouds.cloudstack.domain.LoadBalancerRule;
@ -78,7 +76,7 @@ public class LoadBalancerClientLiveTest extends BaseCloudStackClientLiveTest {
Predicates.and(hasLoadBalancerService(), isVirtualNetwork(), Predicates.and(hasLoadBalancerService(), isVirtualNetwork(),
new Predicate<Network>() { new Predicate<Network>() {
@Override @Override
public boolean apply(@Nullable Network network) { public boolean apply(Network network) {
return network.isDefault() return network.isDefault()
&& !network.isSecurityGroupEnabled() && !network.isSecurityGroupEnabled()
&& !network.isSystem() && !network.isSystem()

View File

@ -27,8 +27,6 @@ import java.net.URI;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.util.Set; import java.util.Set;
import javax.annotation.Nullable;
import org.jclouds.cloudstack.domain.AsyncCreateResponse; import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.AsyncJob; import org.jclouds.cloudstack.domain.AsyncJob;
import org.jclouds.cloudstack.domain.ExtractMode; import org.jclouds.cloudstack.domain.ExtractMode;
@ -107,7 +105,7 @@ public class TemplateClientLiveTest extends BaseCloudStackClientLiveTest {
Iterable<Network> networks = client.getNetworkClient().listNetworks(ListNetworksOptions.Builder.zoneId(zone.getId()).isDefault(true)); Iterable<Network> networks = client.getNetworkClient().listNetworks(ListNetworksOptions.Builder.zoneId(zone.getId()).isDefault(true));
networks = Iterables.filter(networks, new Predicate<Network>() { networks = Iterables.filter(networks, new Predicate<Network>() {
@Override @Override
public boolean apply(@Nullable Network network) { public boolean apply(Network network) {
return network != null && network.getState().equals("Implemented"); return network != null && network.getState().equals("Implemented");
} }
}); });
@ -160,7 +158,7 @@ public class TemplateClientLiveTest extends BaseCloudStackClientLiveTest {
Iterable<Network> networks = client.getNetworkClient().listNetworks(ListNetworksOptions.Builder.zoneId(zone.getId()).isDefault(true)); Iterable<Network> networks = client.getNetworkClient().listNetworks(ListNetworksOptions.Builder.zoneId(zone.getId()).isDefault(true));
networks = Iterables.filter(networks, new Predicate<Network>() { networks = Iterables.filter(networks, new Predicate<Network>() {
@Override @Override
public boolean apply(@Nullable Network network) { public boolean apply(Network network) {
return network != null && network.getName().equals("Virtual Network"); return network != null && network.getName().equals("Virtual Network");
} }
}); });
@ -181,7 +179,7 @@ public class TemplateClientLiveTest extends BaseCloudStackClientLiveTest {
final String zoneId = zone.getId(); final String zoneId = zone.getId();
Predicate<Template> templateReadyPredicate = new Predicate<Template>() { Predicate<Template> templateReadyPredicate = new Predicate<Template>() {
@Override @Override
public boolean apply(@Nullable Template template) { public boolean apply(Template template) {
if (template == null) return false; if (template == null) return false;
Template t2 = client.getTemplateClient().getTemplateInZone(template.getId(), zoneId); Template t2 = client.getTemplateClient().getTemplateInZone(template.getId(), zoneId);
Logger.CONSOLE.info("%s", t2.getStatus()); Logger.CONSOLE.info("%s", t2.getStatus());

View File

@ -34,8 +34,6 @@ import java.util.Set;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.annotation.Nullable;
import org.jclouds.cloudstack.CloudStackClient; import org.jclouds.cloudstack.CloudStackClient;
import org.jclouds.cloudstack.domain.AsyncCreateResponse; import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.AsyncJob; import org.jclouds.cloudstack.domain.AsyncJob;
@ -94,7 +92,7 @@ public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest {
if (networks.size() > 0) { if (networks.size() > 0) {
Network network = get(filter(networks, new Predicate<Network>() { Network network = get(filter(networks, new Predicate<Network>() {
@Override @Override
public boolean apply(@Nullable Network network) { public boolean apply(Network network) {
return network != null && network.getState().equals("Implemented"); return network != null && network.getState().equals("Implemented");
} }
}), 0); }), 0);
@ -143,7 +141,7 @@ public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest {
String zoneId = getFirst(networks, null).getZoneId(); String zoneId = getFirst(networks, null).getZoneId();
options.networkIds(Iterables.transform(networks, new Function<Network, String>() { options.networkIds(Iterables.transform(networks, new Function<Network, String>() {
@Override @Override
public String apply(@Nullable Network network) { public String apply(Network network) {
return network.getId(); return network.getId();
} }
})); }));
@ -240,7 +238,7 @@ public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest {
Network requiredNetwork = getOnlyElement(filter(adminClient.getNetworkClient().listNetworks( Network requiredNetwork = getOnlyElement(filter(adminClient.getNetworkClient().listNetworks(
ListNetworksOptions.Builder.zoneId(template.getZoneId())), new Predicate<Network>() { ListNetworksOptions.Builder.zoneId(template.getZoneId())), new Predicate<Network>() {
@Override @Override
public boolean apply(@Nullable Network network) { public boolean apply(Network network) {
return network.isDefault() && return network.isDefault() &&
network.getGuestIPType() == GuestIPType.VIRTUAL; network.getGuestIPType() == GuestIPType.VIRTUAL;
} }

View File

@ -26,8 +26,6 @@ import static org.testng.Assert.assertEquals;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Set; import java.util.Set;
import javax.annotation.Nullable;
import org.jclouds.cloudstack.domain.IPForwardingRule; import org.jclouds.cloudstack.domain.IPForwardingRule;
import org.jclouds.cloudstack.domain.Network; import org.jclouds.cloudstack.domain.Network;
import org.jclouds.cloudstack.domain.PublicIPAddress; import org.jclouds.cloudstack.domain.PublicIPAddress;
@ -96,7 +94,7 @@ public class StaticNATVirtualMachineInNetworkLiveTest extends NATClientLiveTest
rule = getOnlyElement(filter(client.getNATClient().getIPForwardingRulesForIPAddress(ip.getId()), rule = getOnlyElement(filter(client.getNATClient().getIPForwardingRulesForIPAddress(ip.getId()),
new Predicate<IPForwardingRule>() { new Predicate<IPForwardingRule>() {
@Override @Override
public boolean apply(@Nullable IPForwardingRule rule) { public boolean apply(IPForwardingRule rule) {
return rule != null && rule.getStartPort() == 22; return rule != null && rule.getStartPort() == 22;
} }
})); }));

View File

@ -20,8 +20,6 @@ package org.jclouds.ec2;
import java.util.Set; import java.util.Set;
import javax.annotation.Nullable;
import org.jclouds.ec2.features.WindowsAsyncApi; import org.jclouds.ec2.features.WindowsAsyncApi;
import org.jclouds.ec2.services.AMIAsyncClient; import org.jclouds.ec2.services.AMIAsyncClient;
import org.jclouds.ec2.services.AvailabilityZoneAndRegionAsyncClient; import org.jclouds.ec2.services.AvailabilityZoneAndRegionAsyncClient;
@ -31,6 +29,7 @@ import org.jclouds.ec2.services.InstanceAsyncClient;
import org.jclouds.ec2.services.KeyPairAsyncClient; import org.jclouds.ec2.services.KeyPairAsyncClient;
import org.jclouds.ec2.services.SecurityGroupAsyncClient; import org.jclouds.ec2.services.SecurityGroupAsyncClient;
import org.jclouds.ec2.services.WindowsAsyncClient; import org.jclouds.ec2.services.WindowsAsyncClient;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Region; import org.jclouds.location.Region;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;

View File

@ -21,8 +21,6 @@ package org.jclouds.ec2;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
import org.jclouds.ec2.features.WindowsApi; import org.jclouds.ec2.features.WindowsApi;
import org.jclouds.ec2.services.AMIClient; import org.jclouds.ec2.services.AMIClient;
@ -33,6 +31,7 @@ import org.jclouds.ec2.services.InstanceClient;
import org.jclouds.ec2.services.KeyPairClient; import org.jclouds.ec2.services.KeyPairClient;
import org.jclouds.ec2.services.SecurityGroupClient; import org.jclouds.ec2.services.SecurityGroupClient;
import org.jclouds.ec2.services.WindowsClient; import org.jclouds.ec2.services.WindowsClient;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Region; import org.jclouds.location.Region;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;

View File

@ -23,7 +23,6 @@ import java.security.KeyFactory;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.spec.KeySpec; import java.security.spec.KeySpec;
import javax.annotation.Nullable;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.inject.Inject; import javax.inject.Inject;
@ -32,6 +31,7 @@ import org.jclouds.crypto.Pems;
import org.jclouds.domain.LoginCredentials; import org.jclouds.domain.LoginCredentials;
import org.jclouds.ec2.compute.domain.PasswordDataAndPrivateKey; import org.jclouds.ec2.compute.domain.PasswordDataAndPrivateKey;
import org.jclouds.encryption.internal.Base64; import org.jclouds.encryption.internal.Base64;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;

View File

@ -21,12 +21,16 @@ package org.jclouds.openstack.keystone.v2_0;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.functions.ZoneToEndpoint;
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata; import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
import org.jclouds.openstack.keystone.v2_0.features.ServiceApi; import org.jclouds.openstack.keystone.v2_0.features.ServiceApi;
import org.jclouds.openstack.keystone.v2_0.features.TenantApi; import org.jclouds.openstack.keystone.v2_0.features.TenantApi;
import org.jclouds.openstack.keystone.v2_0.features.TokenApi; import org.jclouds.openstack.keystone.v2_0.features.TokenApi;
import org.jclouds.openstack.keystone.v2_0.features.UserApi; import org.jclouds.openstack.keystone.v2_0.features.UserApi;
import org.jclouds.openstack.v2_0.features.ExtensionApi;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.EndpointParam;
import com.google.common.base.Optional; import com.google.common.base.Optional;
@ -54,6 +58,12 @@ public interface KeystoneApi {
@Delegate @Delegate
ServiceApi getServiceApi(); ServiceApi getServiceApi();
/**
* Provides synchronous access to Extension features.
*/
@Delegate
ExtensionApi getExtensionApi();
/** /**
* Provides synchronous access to Token features * Provides synchronous access to Token features
*/ */
@ -66,7 +76,6 @@ public interface KeystoneApi {
@Delegate @Delegate
Optional<UserApi> getUserApi(); Optional<UserApi> getUserApi();
/** /**
* Provides synchronous access to Tenant features * Provides synchronous access to Tenant features
*/ */

View File

@ -27,6 +27,7 @@ import org.jclouds.openstack.keystone.v2_0.features.ServiceAsyncApi;
import org.jclouds.openstack.keystone.v2_0.features.TenantAsyncApi; import org.jclouds.openstack.keystone.v2_0.features.TenantAsyncApi;
import org.jclouds.openstack.keystone.v2_0.features.TokenAsyncApi; import org.jclouds.openstack.keystone.v2_0.features.TokenAsyncApi;
import org.jclouds.openstack.keystone.v2_0.features.UserAsyncApi; import org.jclouds.openstack.keystone.v2_0.features.UserAsyncApi;
import org.jclouds.openstack.v2_0.features.ExtensionAsyncApi;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.SelectJson; import org.jclouds.rest.annotations.SelectJson;
@ -60,6 +61,12 @@ public interface KeystoneAsyncApi {
@Delegate @Delegate
ServiceAsyncApi getServiceApi(); ServiceAsyncApi getServiceApi();
/**
* Provides asynchronous access to Extension features.
*/
@Delegate
ExtensionAsyncApi getExtensionApi();
/** /**
* @see KeystoneApi#getTokenApi() * @see KeystoneApi#getTokenApi()
*/ */
@ -71,7 +78,6 @@ public interface KeystoneAsyncApi {
*/ */
@Delegate @Delegate
Optional<UserAsyncApi> getUserApi(); Optional<UserAsyncApi> getUserApi();
/** /**
* @see KeystoneApi#getTenantApi() * @see KeystoneApi#getTenantApi()

View File

@ -23,6 +23,8 @@ import static org.jclouds.util.Suppliers2.getLastValueInMap;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.inject.Singleton; import javax.inject.Singleton;
@ -41,11 +43,14 @@ import org.jclouds.openstack.keystone.v2_0.features.TokenApi;
import org.jclouds.openstack.keystone.v2_0.features.TokenAsyncApi; import org.jclouds.openstack.keystone.v2_0.features.TokenAsyncApi;
import org.jclouds.openstack.keystone.v2_0.features.UserApi; import org.jclouds.openstack.keystone.v2_0.features.UserApi;
import org.jclouds.openstack.keystone.v2_0.features.UserAsyncApi; import org.jclouds.openstack.keystone.v2_0.features.UserAsyncApi;
import org.jclouds.openstack.keystone.v2_0.functions.PresentWhenAdminURLExistsForIdentityService;
import org.jclouds.openstack.keystone.v2_0.handlers.KeystoneErrorHandler; import org.jclouds.openstack.keystone.v2_0.handlers.KeystoneErrorHandler;
import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToAdminURIFromAccessForTypeAndVersion; import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToAdminURIFromAccessForTypeAndVersion;
import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToAdminURISupplier; import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToAdminURISupplier;
import org.jclouds.openstack.v2_0.ServiceType; import org.jclouds.openstack.v2_0.ServiceType;
import org.jclouds.openstack.v2_0.domain.Extension;
import org.jclouds.openstack.v2_0.features.ExtensionApi;
import org.jclouds.openstack.v2_0.features.ExtensionAsyncApi;
import org.jclouds.openstack.v2_0.functions.PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet;
import org.jclouds.openstack.v2_0.services.Identity; import org.jclouds.openstack.v2_0.services.Identity;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.annotations.ApiVersion; import org.jclouds.rest.annotations.ApiVersion;
@ -54,7 +59,13 @@ import org.jclouds.rest.functions.ImplicitOptionalConverter;
import org.jclouds.util.Suppliers2; import org.jclouds.util.Suppliers2;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import com.google.common.reflect.TypeToken; import com.google.common.reflect.TypeToken;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Provides; import com.google.inject.Provides;
@ -70,17 +81,18 @@ public class KeystoneRestClientModule<S extends KeystoneApi, A extends KeystoneA
RestClientModule<S, A> { RestClientModule<S, A> {
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder() public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()
.put(ServiceApi.class, ServiceAsyncApi.class).put(TokenApi.class, TokenAsyncApi.class) .put(ServiceApi.class, ServiceAsyncApi.class)
.put(UserApi.class, UserAsyncApi.class).put(TenantApi.class, TenantAsyncApi.class).build(); .put(ExtensionApi.class, ExtensionAsyncApi.class)
.put(TokenApi.class, TokenAsyncApi.class)
.put(UserApi.class, UserAsyncApi.class)
.put(TenantApi.class, TenantAsyncApi.class)
.build();
@SuppressWarnings("unchecked")
public KeystoneRestClientModule() { public KeystoneRestClientModule() {
super(TypeToken.class.cast(TypeToken.of(KeystoneApi.class)), TypeToken.class.cast(TypeToken super(TypeToken.class.cast(TypeToken.of(KeystoneApi.class)), TypeToken.class.cast(TypeToken.of(KeystoneAsyncApi.class)), DELEGATE_MAP);
.of(KeystoneAsyncApi.class)), DELEGATE_MAP);
} }
protected KeystoneRestClientModule(TypeToken<S> syncApiType, TypeToken<A> asyncApiType, protected KeystoneRestClientModule(TypeToken<S> syncApiType, TypeToken<A> asyncApiType, Map<Class<?>, Class<?>> sync2Async) {
Map<Class<?>, Class<?>> sync2Async) {
super(syncApiType, asyncApiType, sync2Async); super(syncApiType, asyncApiType, sync2Async);
} }
@ -88,7 +100,6 @@ public class KeystoneRestClientModule<S extends KeystoneApi, A extends KeystoneA
@Override @Override
protected void configure() { protected void configure() {
bind(ImplicitOptionalConverter.class).to(PresentWhenAdminURLExistsForIdentityService.class);
install(new FactoryModuleBuilder().implement(RegionIdToAdminURISupplier.class, install(new FactoryModuleBuilder().implement(RegionIdToAdminURISupplier.class,
RegionIdToAdminURIFromAccessForTypeAndVersion.class).build(RegionIdToAdminURISupplier.Factory.class)); RegionIdToAdminURIFromAccessForTypeAndVersion.class).build(RegionIdToAdminURISupplier.Factory.class));
} }
@ -112,6 +123,31 @@ public class KeystoneRestClientModule<S extends KeystoneApi, A extends KeystoneA
} }
} }
@Override
protected void configure() {
bind(ImplicitOptionalConverter.class).to(PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.class);
super.configure();
}
@Provides
@Singleton
public Multimap<URI, URI> aliases() {
return ImmutableMultimap.<URI, URI>builder()
.build();
}
@Provides
@Singleton
public LoadingCache<String, Set<? extends Extension>> provideExtensionsByZone(final javax.inject.Provider<KeystoneApi> keystoneApi) {
return CacheBuilder.newBuilder().expireAfterWrite(23, TimeUnit.HOURS)
.build(CacheLoader.from(Suppliers.memoize(new Supplier<Set<? extends Extension>>() {
@Override
public Set<? extends Extension> get() {
return keystoneApi.get().getExtensionApi().listExtensions();
}
})));
}
@Override @Override
protected void bindErrorHandlers() { protected void bindErrorHandlers() {
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(KeystoneErrorHandler.class); bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(KeystoneErrorHandler.class);

View File

@ -40,5 +40,5 @@ public interface ServiceApi {
/** /**
* The operation returns a list of tenants which the current token provides access to. * The operation returns a list of tenants which the current token provides access to.
*/ */
Set<Tenant> listTenants(); Set<? extends Tenant> listTenants();
} }

View File

@ -57,5 +57,5 @@ public interface ServiceAsyncApi {
@Path("/tenants") @Path("/tenants")
@RequestFilters(AuthenticateRequest.class) @RequestFilters(AuthenticateRequest.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<Tenant>> listTenants(); ListenableFuture<? extends Set<? extends Tenant>> listTenants();
} }

View File

@ -40,7 +40,7 @@ public interface TenantApi {
/** /**
* The operation returns a list of tenants which the current token provides access to. * The operation returns a list of tenants which the current token provides access to.
*/ */
Set<Tenant> list(); Set<? extends Tenant> list();
/** /**
* Retrieve information about a tenant, by tenant ID * Retrieve information about a tenant, by tenant ID

View File

@ -62,7 +62,7 @@ public interface TenantAsyncApi {
@Path("/tenants") @Path("/tenants")
@RequestFilters(AuthenticateRequest.class) @RequestFilters(AuthenticateRequest.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<Tenant>> list(); ListenableFuture<? extends Set<? extends Tenant>> list();
/** @see TenantApi#get(String) */ /** @see TenantApi#get(String) */
@GET @GET
@ -71,7 +71,7 @@ public interface TenantAsyncApi {
@Path("/tenants/{tenantId}") @Path("/tenants/{tenantId}")
@RequestFilters(AuthenticateRequest.class) @RequestFilters(AuthenticateRequest.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Tenant> get(@PathParam("tenantId") String tenantId); ListenableFuture<? extends Tenant> get(@PathParam("tenantId") String tenantId);
/** @see TenantApi#getByName(String) */ /** @see TenantApi#getByName(String) */
@GET @GET
@ -80,6 +80,6 @@ public interface TenantAsyncApi {
@Path("/tenants") @Path("/tenants")
@RequestFilters(AuthenticateRequest.class) @RequestFilters(AuthenticateRequest.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Tenant> getByName(@QueryParam("name") String tenantName); ListenableFuture<? extends Tenant> getByName(@QueryParam("name") String tenantName);
} }

View File

@ -72,6 +72,6 @@ public interface TokenApi {
* *
* @return the set of endpoints * @return the set of endpoints
*/ */
Set<Endpoint> listEndpointsForToken(String token); Set<? extends Endpoint> listEndpointsForToken(String token);
} }

View File

@ -64,7 +64,7 @@ public interface TokenAsyncApi {
@Path("/tokens/{token}") @Path("/tokens/{token}")
@RequestFilters(AuthenticateRequest.class) @RequestFilters(AuthenticateRequest.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Token> get(@PathParam("token") String token); ListenableFuture<? extends Token> get(@PathParam("token") String token);
/** @see TokenApi#getUserOfToken(String) */ /** @see TokenApi#getUserOfToken(String) */
@GET @GET
@ -73,7 +73,7 @@ public interface TokenAsyncApi {
@Path("/tokens/{token}") @Path("/tokens/{token}")
@RequestFilters(AuthenticateRequest.class) @RequestFilters(AuthenticateRequest.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<User> getUserOfToken(@PathParam("token") String token); ListenableFuture<? extends User> getUserOfToken(@PathParam("token") String token);
/** @see TokenApi#isValid(String) */ /** @see TokenApi#isValid(String) */
@HEAD @HEAD
@ -89,6 +89,6 @@ public interface TokenAsyncApi {
@Path("/tokens/{token}/endpoints") @Path("/tokens/{token}/endpoints")
@RequestFilters(AuthenticateRequest.class) @RequestFilters(AuthenticateRequest.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<Endpoint>> listEndpointsForToken(@PathParam("token") String token); ListenableFuture<? extends Set<? extends Endpoint>> listEndpointsForToken(@PathParam("token") String token);
} }

View File

@ -48,7 +48,7 @@ public interface UserApi {
* *
* @return the list of users * @return the list of users
*/ */
Set<User> list(); Set<? extends User> list();
/** /**
* Retrieve information about a user, by user ID * Retrieve information about a user, by user ID
@ -73,13 +73,13 @@ public interface UserApi {
* *
* @return the set of Roles granted to the user * @return the set of Roles granted to the user
*/ */
Set<Role> listRolesOfUser(String userId); Set<? extends Role> listRolesOfUser(String userId);
/** /**
* List the roles a user has been granted on a specific tenant * List the roles a user has been granted on a specific tenant
* *
* @return the set of roles * @return the set of roles
*/ */
Set<Role> listRolesOfUserOnTenant(String userId, String tenantId); Set<? extends Role> listRolesOfUserOnTenant(String userId, String tenantId);
} }

View File

@ -61,7 +61,7 @@ public interface UserAsyncApi {
@Path("/users") @Path("/users")
@RequestFilters(AuthenticateRequest.class) @RequestFilters(AuthenticateRequest.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<User>> list(); ListenableFuture<? extends Set<? extends User>> list();
/** @see UserApi#get(String) */ /** @see UserApi#get(String) */
@GET @GET
@ -70,7 +70,7 @@ public interface UserAsyncApi {
@Path("/users/{userId}") @Path("/users/{userId}")
@RequestFilters(AuthenticateRequest.class) @RequestFilters(AuthenticateRequest.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<User> get(@PathParam("userId") String userId); ListenableFuture<? extends User> get(@PathParam("userId") String userId);
/** @see UserApi#getByName(String) */ /** @see UserApi#getByName(String) */
@GET @GET
@ -79,7 +79,7 @@ public interface UserAsyncApi {
@Path("/users") @Path("/users")
@RequestFilters(AuthenticateRequest.class) @RequestFilters(AuthenticateRequest.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<User> getByName(@QueryParam("name") String userName); ListenableFuture<? extends User> getByName(@QueryParam("name") String userName);
/** @see UserApi#listRolesOfUser(String) */ /** @see UserApi#listRolesOfUser(String) */
@GET @GET
@ -88,7 +88,7 @@ public interface UserAsyncApi {
@Path("/users/{userId}/roles") @Path("/users/{userId}/roles")
@RequestFilters(AuthenticateRequest.class) @RequestFilters(AuthenticateRequest.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<Role>> listRolesOfUser(@PathParam("userId") String userId); ListenableFuture<? extends Set<? extends Role>> listRolesOfUser(@PathParam("userId") String userId);
/** @see UserApi#listRolesOfUserOnTenant(String, String) */ /** @see UserApi#listRolesOfUserOnTenant(String, String) */
@GET @GET
@ -97,5 +97,5 @@ public interface UserAsyncApi {
@Path("/tenants/{tenantId}/users/{userId}/roles") @Path("/tenants/{tenantId}/users/{userId}/roles")
@RequestFilters(AuthenticateRequest.class) @RequestFilters(AuthenticateRequest.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<Role>> listRolesOfUserOnTenant(@PathParam("userId") String userId, @PathParam("tenantId") String tenantId); ListenableFuture<? extends Set<? extends Role>> listRolesOfUserOnTenant(@PathParam("userId") String userId, @PathParam("tenantId") String tenantId);
} }

View File

@ -1,46 +0,0 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.keystone.v2_0.functions;
import javax.inject.Singleton;
import org.jclouds.internal.ClassMethodArgsAndReturnVal;
import org.jclouds.rest.functions.ImplicitOptionalConverter;
import com.google.common.base.Optional;
/**
*
* @author Adrian Cole
*
*/
@Singleton
public class PresentWhenAdminURLExistsForIdentityService implements ImplicitOptionalConverter {
@Override
public Optional<Object> apply(ClassMethodArgsAndReturnVal input) {
//TODO: log and return absent when the admin url for identity service isn't available
return Optional.of(input.getReturnVal());
}
public String toString() {
return "presentWhenAdminURLExistsForIdentityService()";
}
}

View File

@ -16,7 +16,7 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jclouds.openstack.nova.v2_0.domain; package org.jclouds.openstack.v2_0.domain;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
@ -26,8 +26,6 @@ import java.util.Date;
import java.util.Set; import java.util.Set;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.openstack.v2_0.domain.Link;
import org.jclouds.openstack.v2_0.domain.Resource;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper; import com.google.common.base.Objects.ToStringHelper;

View File

@ -16,13 +16,13 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jclouds.openstack.nova.v2_0.features; package org.jclouds.openstack.v2_0.features;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
import org.jclouds.openstack.nova.v2_0.domain.Extension; import org.jclouds.openstack.v2_0.domain.Extension;
/** /**
* Provides asynchronous access to Extensions via their REST API. * Provides asynchronous access to Extensions via their REST API.
@ -42,7 +42,7 @@ public interface ExtensionApi {
* *
* @return all extensions * @return all extensions
*/ */
Set<Extension> listExtensions(); Set<? extends Extension> listExtensions();
/** /**
* Extensions may also be queried individually by their unique alias. * Extensions may also be queried individually by their unique alias.

View File

@ -16,7 +16,7 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jclouds.openstack.nova.v2_0.features; package org.jclouds.openstack.v2_0.features;
import java.util.Set; import java.util.Set;
@ -27,7 +27,7 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest; import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.openstack.nova.v2_0.domain.Extension; import org.jclouds.openstack.v2_0.domain.Extension;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson; import org.jclouds.rest.annotations.SelectJson;
@ -59,7 +59,7 @@ public interface ExtensionAsyncApi {
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Path("/extensions") @Path("/extensions")
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<Extension>> listExtensions(); ListenableFuture<? extends Set<? extends Extension>> listExtensions();
/** /**
* @see ExtensionApi#getExtensionByAlias * @see ExtensionApi#getExtensionByAlias
@ -69,6 +69,6 @@ public interface ExtensionAsyncApi {
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Path("/extensions/{alias}") @Path("/extensions/{alias}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Extension> getExtensionByAlias(@PathParam("alias") String id); ListenableFuture<? extends Extension> getExtensionByAlias(@PathParam("alias") String id);
} }

View File

@ -16,7 +16,7 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jclouds.openstack.nova.v2_0.functions; package org.jclouds.openstack.v2_0.functions;
import java.net.URI; import java.net.URI;
@ -25,7 +25,7 @@ import javax.inject.Provider;
import javax.inject.Singleton; import javax.inject.Singleton;
import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriBuilder;
import org.jclouds.openstack.nova.v2_0.domain.Extension; import org.jclouds.openstack.v2_0.domain.Extension;
import com.google.common.base.Function; import com.google.common.base.Function;

View File

@ -0,0 +1,88 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.v2_0.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.Set;
import javax.inject.Inject;
import org.jclouds.internal.ClassMethodArgsAndReturnVal;
import org.jclouds.openstack.v2_0.domain.Extension;
import org.jclouds.openstack.v2_0.predicates.ExtensionPredicates;
import org.jclouds.rest.functions.ImplicitOptionalConverter;
import com.google.common.base.Optional;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap;
/**
* We use the annotation {@link org.jclouds.openstack.services.Extension} to
* bind a class that iimplements an extension API to an {@link Extension}.
*
* @author Adrian Cole
*
*/
public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet implements
ImplicitOptionalConverter {
private final LoadingCache<String, Set<? extends Extension>> extensions;
private final Multimap<URI, URI> aliases;
@Inject
public PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet(
LoadingCache<String, Set<? extends Extension>> extensions,
Multimap<URI, URI> aliases) {
this.extensions = checkNotNull(extensions, "extensions");
this.aliases = aliases == null ? ImmutableMultimap.<URI, URI>of() : ImmutableMultimap.copyOf(aliases);
}
@Override
public Optional<Object> apply(ClassMethodArgsAndReturnVal input) {
Optional<org.jclouds.openstack.v2_0.services.Extension> ext = Optional.fromNullable(input.getClazz().getAnnotation(
org.jclouds.openstack.v2_0.services.Extension.class));
if (ext.isPresent()) {
URI namespace = URI.create(ext.get().namespace());
if (input.getArgs() == null || input.getArgs().length == 0) {
if (Iterables.any(extensions.getUnchecked(""),
ExtensionPredicates.namespaceOrAliasEquals(namespace, aliases.get(namespace))))
return Optional.of(input.getReturnVal());
} else if (input.getArgs() != null && input.getArgs().length == 1) {
if (Iterables.any(extensions.getUnchecked(checkNotNull(input.getArgs()[0], "arg[0] in %s", input).toString()),
ExtensionPredicates.namespaceOrAliasEquals(namespace, aliases.get(namespace))))
return Optional.of(input.getReturnVal());
} else {
throw new RuntimeException(String.format("expecting zero or one args %s", input));
}
return Optional.absent();
} else {
// No extension annotation, should check whether to return absent
return Optional.of(input.getReturnVal());
}
}
@Override
public String toString() {
return "presentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet()";
}
}

View File

@ -16,14 +16,14 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jclouds.openstack.nova.v2_0.predicates; package org.jclouds.openstack.v2_0.predicates;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI; import java.net.URI;
import java.util.Collection; import java.util.Collection;
import org.jclouds.openstack.nova.v2_0.domain.Extension; import org.jclouds.openstack.v2_0.domain.Extension;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;

View File

@ -50,7 +50,7 @@ public class ServiceApiExpectTest extends BaseKeystoneRestApiExpectTest<Keystone
HttpResponse.builder().statusCode(200) HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/tenant_list.json", APPLICATION_JSON)).build()) .payload(payloadFromResourceWithContentType("/tenant_list.json", APPLICATION_JSON)).build())
.getServiceApi(); .getServiceApi();
Set<Tenant> tenants = api.listTenants(); Set<? extends Tenant> tenants = api.listTenants();
assertNotNull(tenants); assertNotNull(tenants);
assertFalse(tenants.isEmpty()); assertFalse(tenants.isEmpty());

View File

@ -37,7 +37,7 @@ public class ServiceApiLiveTest extends BaseKeystoneApiLiveTest {
public void testTenants() { public void testTenants() {
ServiceApi api = keystoneContext.getApi().getServiceApi(); ServiceApi api = keystoneContext.getApi().getServiceApi();
Set<Tenant> result = api.listTenants(); Set<? extends Tenant> result = api.listTenants();
assertNotNull(result); assertNotNull(result);
assertFalse(result.isEmpty()); assertFalse(result.isEmpty());

View File

@ -56,7 +56,7 @@ public class TenantApiExpectTest extends BaseKeystoneRestApiExpectTest<KeystoneA
HttpResponse.builder().statusCode(200).payload( HttpResponse.builder().statusCode(200).payload(
payloadFromResourceWithContentType("/tenant_list.json", APPLICATION_JSON)).build()) payloadFromResourceWithContentType("/tenant_list.json", APPLICATION_JSON)).build())
.getTenantApi().get(); .getTenantApi().get();
Set<Tenant> tenants = api.list(); Set<? extends Tenant> tenants = api.list();
assertNotNull(tenants); assertNotNull(tenants);
assertFalse(tenants.isEmpty()); assertFalse(tenants.isEmpty());
@ -74,7 +74,7 @@ public class TenantApiExpectTest extends BaseKeystoneRestApiExpectTest<KeystoneA
HttpResponse.builder().statusCode(200).payload( HttpResponse.builder().statusCode(200).payload(
payloadFromResourceWithContentType("/tenant_list_att.json", APPLICATION_JSON)).build()) payloadFromResourceWithContentType("/tenant_list_att.json", APPLICATION_JSON)).build())
.getTenantApi().get(); .getTenantApi().get();
Set<Tenant> tenants = api.list(); Set<? extends Tenant> tenants = api.list();
assertNotNull(tenants); assertNotNull(tenants);
assertFalse(tenants.isEmpty()); assertFalse(tenants.isEmpty());

View File

@ -38,7 +38,7 @@ public class TenantApiLiveTest extends BaseKeystoneApiLiveTest {
public void testTenants() { public void testTenants() {
TenantApi api = keystoneContext.getApi().getTenantApi().get(); TenantApi api = keystoneContext.getApi().getTenantApi().get();
Set<Tenant> result = api.list(); Set<? extends Tenant> result = api.list();
assertNotNull(result); assertNotNull(result);
assertFalse(result.isEmpty()); assertFalse(result.isEmpty());

View File

@ -138,7 +138,7 @@ public class TokenApiExpectTest extends BaseKeystoneRestApiExpectTest<KeystoneAp
authenticatedGET().endpoint(endpoint + "/v2.0/tokens/XXXXXX/endpoints").build(), authenticatedGET().endpoint(endpoint + "/v2.0/tokens/XXXXXX/endpoints").build(),
HttpResponse.builder().statusCode(200).payload(payloadFromResourceWithContentType("/user_endpoints.json", APPLICATION_JSON)).build()) HttpResponse.builder().statusCode(200).payload(payloadFromResourceWithContentType("/user_endpoints.json", APPLICATION_JSON)).build())
.getTokenApi().get(); .getTokenApi().get();
Set<Endpoint> endpoints = api.listEndpointsForToken("XXXXXX"); Set<? extends Endpoint> endpoints = api.listEndpointsForToken("XXXXXX");
assertEquals(endpoints, ImmutableSet.of( assertEquals(endpoints, ImmutableSet.of(
Endpoint.builder().publicURL(URI.create("https://csnode.jclouds.org/v2.0/")) Endpoint.builder().publicURL(URI.create("https://csnode.jclouds.org/v2.0/"))

View File

@ -82,7 +82,7 @@ public class TokenApiLiveTest extends BaseKeystoneApiLiveTest {
public void testTokenEndpoints() { public void testTokenEndpoints() {
TokenApi api = keystoneContext.getApi().getTokenApi().get(); TokenApi api = keystoneContext.getApi().getTokenApi().get();
Set<Endpoint> endpoints = api.listEndpointsForToken(token); Set<? extends Endpoint> endpoints = api.listEndpointsForToken(token);
assertNotNull(endpoints); assertNotNull(endpoints);
assertFalse(endpoints.isEmpty()); assertFalse(endpoints.isEmpty());

View File

@ -56,7 +56,7 @@ public class UserApiExpectTest extends BaseKeystoneRestApiExpectTest<KeystoneApi
authenticatedGET().endpoint(endpoint + "/v2.0/users").build(), authenticatedGET().endpoint(endpoint + "/v2.0/users").build(),
HttpResponse.builder().statusCode(200).payload(payloadFromResourceWithContentType("/user_list.json", APPLICATION_JSON)).build()) HttpResponse.builder().statusCode(200).payload(payloadFromResourceWithContentType("/user_list.json", APPLICATION_JSON)).build())
.getUserApi().get(); .getUserApi().get();
Set<User> users = api.list(); Set<? extends User> users = api.list();
assertNotNull(users); assertNotNull(users);
assertFalse(users.isEmpty()); assertFalse(users.isEmpty());
@ -123,7 +123,7 @@ public class UserApiExpectTest extends BaseKeystoneRestApiExpectTest<KeystoneApi
authenticatedGET().endpoint(endpoint + "/v2.0/users/3f6c1c9ba993495ead7d2eb2192e284f/roles").build(), authenticatedGET().endpoint(endpoint + "/v2.0/users/3f6c1c9ba993495ead7d2eb2192e284f/roles").build(),
HttpResponse.builder().statusCode(200).payload(payloadFromResourceWithContentType("/user_role_list.json", APPLICATION_JSON)).build()) HttpResponse.builder().statusCode(200).payload(payloadFromResourceWithContentType("/user_role_list.json", APPLICATION_JSON)).build())
.getUserApi().get(); .getUserApi().get();
Set<Role> roles = api.listRolesOfUser("3f6c1c9ba993495ead7d2eb2192e284f"); Set<? extends Role> roles = api.listRolesOfUser("3f6c1c9ba993495ead7d2eb2192e284f");
assertNotNull(roles); assertNotNull(roles);
assertFalse(roles.isEmpty()); assertFalse(roles.isEmpty());
assertEquals(roles, ImmutableSet.of( assertEquals(roles, ImmutableSet.of(
@ -154,7 +154,7 @@ public class UserApiExpectTest extends BaseKeystoneRestApiExpectTest<KeystoneApi
authenticatedGET().endpoint(endpoint + "/v2.0/users/3f6c1c9ba993495ead7d2eb2192e284f/roles").build(), authenticatedGET().endpoint(endpoint + "/v2.0/users/3f6c1c9ba993495ead7d2eb2192e284f/roles").build(),
HttpResponse.builder().statusCode(200).payload(payloadFromResourceWithContentType("/user_tenant_role_list.json", APPLICATION_JSON)).build()) HttpResponse.builder().statusCode(200).payload(payloadFromResourceWithContentType("/user_tenant_role_list.json", APPLICATION_JSON)).build())
.getUserApi().get(); .getUserApi().get();
Set<Role> roles = api.listRolesOfUser("3f6c1c9ba993495ead7d2eb2192e284f"); Set<? extends Role> roles = api.listRolesOfUser("3f6c1c9ba993495ead7d2eb2192e284f");
assertNotNull(roles); assertNotNull(roles);
assertFalse(roles.isEmpty()); assertFalse(roles.isEmpty());
assertEquals(roles, ImmutableSet.of( assertEquals(roles, ImmutableSet.of(

View File

@ -41,7 +41,7 @@ public class UserApiLiveTest extends BaseKeystoneApiLiveTest {
public void testUsers() { public void testUsers() {
UserApi api = keystoneContext.getApi().getUserApi().get(); UserApi api = keystoneContext.getApi().getUserApi().get();
Set<User> users = api.list(); Set<? extends User> users = api.list();
assertNotNull(users); assertNotNull(users);
assertFalse(users.isEmpty()); assertFalse(users.isEmpty());
for (User user : users) { for (User user : users) {
@ -54,12 +54,12 @@ public class UserApiLiveTest extends BaseKeystoneApiLiveTest {
public void testUserRolesOnTenant() { public void testUserRolesOnTenant() {
UserApi api = keystoneContext.getApi().getUserApi().get(); UserApi api = keystoneContext.getApi().getUserApi().get();
Set<User> users = api.list(); Set<? extends User> users = api.list();
Set<Tenant> tenants = keystoneContext.getApi().getTenantApi().get().list(); Set<? extends Tenant> tenants = keystoneContext.getApi().getTenantApi().get().list();
for (User user : users) { for (User user : users) {
for (Tenant tenant : tenants) { for (Tenant tenant : tenants) {
Set<Role> roles = api.listRolesOfUserOnTenant(user.getId(), tenant.getId()); Set<? extends Role> roles = api.listRolesOfUserOnTenant(user.getId(), tenant.getId());
for (Role role : roles) { for (Role role : roles) {
assertNotNull(role.getId()); assertNotNull(role.getId());
} }
@ -72,7 +72,7 @@ public class UserApiLiveTest extends BaseKeystoneApiLiveTest {
UserApi api = keystoneContext.getApi().getUserApi().get(); UserApi api = keystoneContext.getApi().getUserApi().get();
for (User user : api.list()) { for (User user : api.list()) {
Set<Role> roles = api.listRolesOfUser(user.getId()); Set<? extends Role> roles = api.listRolesOfUser(user.getId());
for (Role role : roles) { for (Role role : roles) {
assertNotNull(role.getId()); assertNotNull(role.getId());
} }

View File

@ -1,4 +1,4 @@
package org.jclouds.openstack.nova.v2_0.functions; package org.jclouds.openstack.v2_0.functions;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
@ -8,8 +8,7 @@ import javax.inject.Provider;
import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriBuilder;
import org.jclouds.date.internal.SimpleDateFormatDateService; import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.openstack.nova.v2_0.domain.Extension; import org.jclouds.openstack.v2_0.domain.Extension;
import org.jclouds.openstack.nova.v2_0.extensions.ExtensionNamespaces;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.sun.jersey.api.uri.UriBuilderImpl; import com.sun.jersey.api.uri.UriBuilderImpl;
@ -39,6 +38,6 @@ public class ExtensionToNameSpaceTest {
assertEquals(fn.apply(Extension.builder().alias("security_groups").name("SecurityGroups").namespace( assertEquals(fn.apply(Extension.builder().alias("security_groups").name("SecurityGroups").namespace(
URI.create("https://docs.openstack.org/ext/securitygroups/api/v1.1")).updated( URI.create("https://docs.openstack.org/ext/securitygroups/api/v1.1")).updated(
new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-07-21T00:00:00+00:00")).description( new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-07-21T00:00:00+00:00")).description(
"Security group support").build()), URI.create(ExtensionNamespaces.SECURITY_GROUPS)); "Security group support").build()), URI.create("http://docs.openstack.org/ext/securitygroups/api/v1.1"));
} }
} }

View File

@ -1,4 +1,4 @@
package org.jclouds.openstack.nova.v2_0.functions; package org.jclouds.openstack.v2_0.functions;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
@ -9,10 +9,9 @@ import javax.inject.Named;
import org.jclouds.date.internal.SimpleDateFormatDateService; import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.internal.ClassMethodArgsAndReturnVal; import org.jclouds.internal.ClassMethodArgsAndReturnVal;
import org.jclouds.openstack.nova.v2_0.domain.Extension;
import org.jclouds.openstack.nova.v2_0.extensions.ExtensionNamespaces;
import org.jclouds.openstack.nova.v2_0.extensions.KeyPairAsyncApi;
import org.jclouds.openstack.v2_0.ServiceType; import org.jclouds.openstack.v2_0.ServiceType;
import org.jclouds.openstack.v2_0.domain.Extension;
import org.jclouds.openstack.v2_0.functions.PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -40,8 +39,8 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio
new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-08-08T00:00:00+00:00")).description( new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-08-08T00:00:00+00:00")).description(
"Keypair Support").build(); "Keypair Support").build();
@org.jclouds.openstack.v2_0.services.Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.KEYPAIRS) @org.jclouds.openstack.v2_0.services.Extension(of = ServiceType.COMPUTE, namespace = "http://docs.openstack.org/ext/keypairs/api/v1.1")
static interface KeyPairIPAsyncApi { static interface KeyPairAsyncApi {
} }
@ -50,7 +49,7 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio
new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-06-16T00:00:00+00:00")).description( new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-06-16T00:00:00+00:00")).description(
"Floating IPs support").build(); "Floating IPs support").build();
@org.jclouds.openstack.v2_0.services.Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.FLOATING_IPS) @org.jclouds.openstack.v2_0.services.Extension(of = ServiceType.COMPUTE, namespace = "http://docs.openstack.org/ext/floating_ips/api/v1.1")
static interface FloatingIPAsyncApi { static interface FloatingIPAsyncApi {
} }
@ -68,27 +67,27 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio
ClassMethodArgsAndReturnVal getFloatingIPExtension() throws SecurityException, NoSuchMethodException { ClassMethodArgsAndReturnVal getFloatingIPExtension() throws SecurityException, NoSuchMethodException {
return ClassMethodArgsAndReturnVal.builder().clazz(FloatingIPAsyncApi.class).method( return ClassMethodArgsAndReturnVal.builder().clazz(FloatingIPAsyncApi.class).method(
NovaAsyncApi.class.getDeclaredMethod("getFloatingIPExtensionForZone", String.class)).args( NovaAsyncApi.class.getDeclaredMethod("getFloatingIPExtensionForZone", String.class)).args(
new Object[] { "expectedzone" }).returnVal("foo").build(); new Object[] { "zone" }).returnVal("foo").build();
} }
ClassMethodArgsAndReturnVal getKeyPairExtension() throws SecurityException, NoSuchMethodException { ClassMethodArgsAndReturnVal getKeyPairExtension() throws SecurityException, NoSuchMethodException {
return ClassMethodArgsAndReturnVal.builder().clazz(KeyPairAsyncApi.class).method( return ClassMethodArgsAndReturnVal.builder().clazz(KeyPairAsyncApi.class).method(
NovaAsyncApi.class.getDeclaredMethod("getKeyPairExtensionForZone", String.class)).args( NovaAsyncApi.class.getDeclaredMethod("getKeyPairExtensionForZone", String.class)).args(
new Object[] { "expectedzone" }).returnVal("foo").build(); new Object[] { "zone" }).returnVal("foo").build();
} }
public void testPresentWhenExtensionsIncludeNamespaceFromAnnotationAbsentWhenNot() throws SecurityException, NoSuchMethodException { public void testPresentWhenExtensionsIncludeNamespaceFromAnnotationAbsentWhenNot() throws SecurityException, NoSuchMethodException {
assertEquals(whenExtensionsInclude(keypairs, floatingIps).apply(getFloatingIPExtension()), Optional.of("foo")); assertEquals(whenExtensionsInZoneInclude("zone", keypairs, floatingIps).apply(getFloatingIPExtension()), Optional.of("foo"));
assertEquals(whenExtensionsInclude(keypairs, floatingIps).apply(getKeyPairExtension()), Optional.of("foo")); assertEquals(whenExtensionsInZoneInclude("zone", keypairs, floatingIps).apply(getKeyPairExtension()), Optional.of("foo"));
assertEquals(whenExtensionsInclude(keypairs).apply(getFloatingIPExtension()), Optional.absent()); assertEquals(whenExtensionsInZoneInclude("zone", keypairs).apply(getFloatingIPExtension()), Optional.absent());
assertEquals(whenExtensionsInclude(floatingIps).apply(getKeyPairExtension()), Optional.absent()); assertEquals(whenExtensionsInZoneInclude("zone", floatingIps).apply(getKeyPairExtension()), Optional.absent());
} }
public void testZoneWithoutExtensionsReturnsAbsent() throws SecurityException, NoSuchMethodException { public void testZoneWithoutExtensionsReturnsAbsent() throws SecurityException, NoSuchMethodException {
assertEquals(whenExtensionsInclude(floatingIps).apply( assertEquals(whenExtensionsInZoneInclude("zone", floatingIps).apply(
getFloatingIPExtension().toBuilder().args(new Object[] { "differentzone" }).build()), Optional.absent()); getFloatingIPExtension().toBuilder().args(new Object[] { "differentzone" }).build()), Optional.absent());
assertEquals(whenExtensionsInclude(keypairs).apply( assertEquals(whenExtensionsInZoneInclude("zone", keypairs).apply(
getKeyPairExtension().toBuilder().args(new Object[] { "differentzone" }).build()), Optional.absent()); getKeyPairExtension().toBuilder().args(new Object[] { "differentzone" }).build()), Optional.absent());
} }
@ -105,22 +104,22 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio
Multimap<URI, URI> aliases = ImmutableMultimap.of(keypairs.getNamespace(), keypairsWithDifferentNamespace Multimap<URI, URI> aliases = ImmutableMultimap.of(keypairs.getNamespace(), keypairsWithDifferentNamespace
.getNamespace()); .getNamespace());
assertEquals(whenExtensionsAndAliasesInclude(ImmutableSet.of(keypairsWithDifferentNamespace), aliases).apply( assertEquals(whenExtensionsAndAliasesInZoneInclude("zone", ImmutableSet.of(keypairsWithDifferentNamespace), aliases).apply(
getKeyPairExtension()), Optional.of("foo")); getKeyPairExtension()), Optional.of("foo"));
assertEquals(whenExtensionsAndAliasesInclude(ImmutableSet.of(keypairsWithDifferentNamespace), aliases).apply( assertEquals(whenExtensionsAndAliasesInZoneInclude("zone", ImmutableSet.of(keypairsWithDifferentNamespace), aliases).apply(
getFloatingIPExtension()), Optional.absent()); getFloatingIPExtension()), Optional.absent());
} }
private PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet whenExtensionsInclude( private PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet whenExtensionsInZoneInclude(
Extension... extensions) { String zone, Extension... extensions) {
return whenExtensionsAndAliasesInclude(ImmutableSet.copyOf(extensions), ImmutableMultimap.<URI, URI> of()); return whenExtensionsAndAliasesInZoneInclude(zone, ImmutableSet.copyOf(extensions), ImmutableMultimap.<URI, URI> of());
} }
private PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet whenExtensionsAndAliasesInclude( private PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet whenExtensionsAndAliasesInZoneInclude(
final Set<Extension> extensions, final Multimap<URI, URI> aliases) { String zone, final Set<Extension> extensions, final Multimap<URI, URI> aliases) {
final LoadingCache<String, Set<Extension>> extensionsForZone = CacheBuilder.newBuilder().build( final LoadingCache<String, Set<? extends Extension>> extensionsForZone = CacheBuilder.newBuilder().build(
CacheLoader.from(Functions.forMap(ImmutableMap.of("expectedzone", extensions, "differentzone", CacheLoader.from(Functions.forMap(ImmutableMap.<String, Set<? extends Extension>>of(zone, extensions, "differentzone",
ImmutableSet.<Extension> of())))); ImmutableSet.<Extension> of()))));
PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet fn = Guice.createInjector( PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet fn = Guice.createInjector(
@ -130,12 +129,11 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio
} }
@Provides @Provides
LoadingCache<String, Set<Extension>> getExtensions() { LoadingCache<String, Set<? extends Extension>> getExtensions() {
return extensionsForZone; return extensionsForZone;
} }
@Provides @Provides
@Named("openstack.nova.extensions")
Multimap<URI, URI> getAliases() { Multimap<URI, URI> getAliases() {
return aliases; return aliases;
} }

View File

@ -16,15 +16,15 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jclouds.openstack.nova.v2_0.predicates; package org.jclouds.openstack.v2_0.predicates;
import static org.jclouds.openstack.nova.v2_0.predicates.ExtensionPredicates.aliasEquals; import static org.jclouds.openstack.v2_0.predicates.ExtensionPredicates.aliasEquals;
import static org.jclouds.openstack.nova.v2_0.predicates.ExtensionPredicates.namespaceEquals; import static org.jclouds.openstack.v2_0.predicates.ExtensionPredicates.namespaceEquals;
import java.net.URI; import java.net.URI;
import org.jclouds.date.internal.SimpleDateFormatDateService; import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.openstack.nova.v2_0.domain.Extension; import org.jclouds.openstack.v2_0.domain.Extension;
import org.testng.annotations.Test; import org.testng.annotations.Test;
/** /**

View File

@ -39,10 +39,10 @@ import org.jclouds.openstack.nova.v2_0.extensions.SimpleTenantUsageApi;
import org.jclouds.openstack.nova.v2_0.extensions.VirtualInterfaceApi; import org.jclouds.openstack.nova.v2_0.extensions.VirtualInterfaceApi;
import org.jclouds.openstack.nova.v2_0.extensions.VolumeApi; import org.jclouds.openstack.nova.v2_0.extensions.VolumeApi;
import org.jclouds.openstack.nova.v2_0.extensions.VolumeTypeApi; import org.jclouds.openstack.nova.v2_0.extensions.VolumeTypeApi;
import org.jclouds.openstack.nova.v2_0.features.ExtensionApi;
import org.jclouds.openstack.nova.v2_0.features.FlavorApi; import org.jclouds.openstack.nova.v2_0.features.FlavorApi;
import org.jclouds.openstack.nova.v2_0.features.ImageApi; import org.jclouds.openstack.nova.v2_0.features.ImageApi;
import org.jclouds.openstack.nova.v2_0.features.ServerApi; import org.jclouds.openstack.nova.v2_0.features.ServerApi;
import org.jclouds.openstack.v2_0.features.ExtensionApi;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.EndpointParam;
@ -100,98 +100,98 @@ public interface NovaApi {
* Provides synchronous access to Floating IP features. * Provides synchronous access to Floating IP features.
*/ */
@Delegate @Delegate
Optional<FloatingIPApi> getFloatingIPExtensionForZone( Optional<? extends FloatingIPApi> getFloatingIPExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides synchronous access to Security Group features. * Provides synchronous access to Security Group features.
*/ */
@Delegate @Delegate
Optional<SecurityGroupApi> getSecurityGroupExtensionForZone( Optional<? extends SecurityGroupApi> getSecurityGroupExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides synchronous access to Key Pair features. * Provides synchronous access to Key Pair features.
*/ */
@Delegate @Delegate
Optional<KeyPairApi> getKeyPairExtensionForZone( Optional<? extends KeyPairApi> getKeyPairExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides synchronous access to Host Administration features. * Provides synchronous access to Host Administration features.
*/ */
@Delegate @Delegate
Optional<HostAdministrationApi> getHostAdministrationExtensionForZone( Optional<? extends HostAdministrationApi> getHostAdministrationExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides synchronous access to Simple Tenant Usage features. * Provides synchronous access to Simple Tenant Usage features.
*/ */
@Delegate @Delegate
Optional<SimpleTenantUsageApi> getSimpleTenantUsageExtensionForZone( Optional<? extends SimpleTenantUsageApi> getSimpleTenantUsageExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides synchronous access to Volume features. * Provides synchronous access to Volume features.
*/ */
@Delegate @Delegate
Optional<VolumeApi> getVolumeExtensionForZone( Optional<? extends VolumeApi> getVolumeExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides synchronous access to Virtual Interface features. * Provides synchronous access to Virtual Interface features.
*/ */
@Delegate @Delegate
Optional<VirtualInterfaceApi> getVirtualInterfaceExtensionForZone( Optional<? extends VirtualInterfaceApi> getVirtualInterfaceExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides synchronous access to Server Extra Data features. * Provides synchronous access to Server Extra Data features.
*/ */
@Delegate @Delegate
Optional<ServerWithSecurityGroupsApi> getServerWithSecurityGroupsExtensionForZone( Optional<? extends ServerWithSecurityGroupsApi> getServerWithSecurityGroupsExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides synchronous access to Server Admin Actions features. * Provides synchronous access to Server Admin Actions features.
*/ */
@Delegate @Delegate
Optional<AdminActionsApi> getAdminActionsExtensionForZone( Optional<? extends AdminActionsApi> getAdminActionsExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides synchronous access to Aggregate features. * Provides synchronous access to Aggregate features.
*/ */
@Delegate @Delegate
Optional<HostAggregateApi> getHostAggregateExtensionForZone( Optional<? extends HostAggregateApi> getHostAggregateExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides synchronous access to Flavor extra specs features. * Provides synchronous access to Flavor extra specs features.
*/ */
@Delegate @Delegate
Optional<FlavorExtraSpecsApi> getFlavorExtraSpecsExtensionForZone( Optional<? extends FlavorExtraSpecsApi> getFlavorExtraSpecsExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides synchronous access to Quota features. * Provides synchronous access to Quota features.
*/ */
@Delegate @Delegate
Optional<QuotaApi> getQuotaExtensionForZone( Optional<? extends QuotaApi> getQuotaExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides synchronous access to Quota Classes features. * Provides synchronous access to Quota Classes features.
*/ */
@Delegate @Delegate
Optional<QuotaClassApi> getQuotaClassExtensionForZone( Optional<? extends QuotaClassApi> getQuotaClassExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides synchronous access to Volume Type features. * Provides synchronous access to Volume Type features.
*/ */
@Delegate @Delegate
Optional<VolumeTypeApi> getVolumeTypeExtensionForZone( Optional<? extends VolumeTypeApi> getVolumeTypeExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
} }

View File

@ -37,10 +37,10 @@ import org.jclouds.openstack.nova.v2_0.extensions.SimpleTenantUsageAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.VirtualInterfaceAsyncApi; import org.jclouds.openstack.nova.v2_0.extensions.VirtualInterfaceAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.VolumeAsyncApi; import org.jclouds.openstack.nova.v2_0.extensions.VolumeAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.VolumeTypeAsyncApi; import org.jclouds.openstack.nova.v2_0.extensions.VolumeTypeAsyncApi;
import org.jclouds.openstack.nova.v2_0.features.ExtensionAsyncApi;
import org.jclouds.openstack.nova.v2_0.features.FlavorAsyncApi; import org.jclouds.openstack.nova.v2_0.features.FlavorAsyncApi;
import org.jclouds.openstack.nova.v2_0.features.ImageAsyncApi; import org.jclouds.openstack.nova.v2_0.features.ImageAsyncApi;
import org.jclouds.openstack.nova.v2_0.features.ServerAsyncApi; import org.jclouds.openstack.nova.v2_0.features.ServerAsyncApi;
import org.jclouds.openstack.v2_0.features.ExtensionAsyncApi;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.EndpointParam;
@ -98,49 +98,49 @@ public interface NovaAsyncApi {
* Provides asynchronous access to Floating IP features. * Provides asynchronous access to Floating IP features.
*/ */
@Delegate @Delegate
Optional<FloatingIPAsyncApi> getFloatingIPExtensionForZone( Optional<? extends FloatingIPAsyncApi> getFloatingIPExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides asynchronous access to Security Group features. * Provides asynchronous access to Security Group features.
*/ */
@Delegate @Delegate
Optional<SecurityGroupAsyncApi> getSecurityGroupExtensionForZone( Optional<? extends SecurityGroupAsyncApi> getSecurityGroupExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides asynchronous access to Key Pair features. * Provides asynchronous access to Key Pair features.
*/ */
@Delegate @Delegate
Optional<KeyPairAsyncApi> getKeyPairExtensionForZone( Optional<? extends KeyPairAsyncApi> getKeyPairExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides asynchronous access to Host Administration features. * Provides asynchronous access to Host Administration features.
*/ */
@Delegate @Delegate
Optional<HostAdministrationAsyncApi> getHostAdministrationExtensionForZone( Optional<? extends HostAdministrationAsyncApi> getHostAdministrationExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides asynchronous access to Simple Tenant Usage features. * Provides asynchronous access to Simple Tenant Usage features.
*/ */
@Delegate @Delegate
Optional<SimpleTenantUsageAsyncApi> getSimpleTenantUsageExtensionForZone( Optional<? extends SimpleTenantUsageAsyncApi> getSimpleTenantUsageExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides asynchronous access to Volume features. * Provides asynchronous access to Volume features.
*/ */
@Delegate @Delegate
Optional<VolumeAsyncApi> getVolumeExtensionForZone( Optional<? extends VolumeAsyncApi> getVolumeExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides asynchronous access to Virtual Interface features. * Provides asynchronous access to Virtual Interface features.
*/ */
@Delegate @Delegate
Optional<VirtualInterfaceAsyncApi> getVirtualInterfaceExtensionForZone( Optional<? extends VirtualInterfaceAsyncApi> getVirtualInterfaceExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
@ -148,49 +148,49 @@ public interface NovaAsyncApi {
* Provides asynchronous access to Server Extra Data features. * Provides asynchronous access to Server Extra Data features.
*/ */
@Delegate @Delegate
Optional<ServerWithSecurityGroupsAsyncApi> getServerWithSecurityGroupsExtensionForZone( Optional<? extends ServerWithSecurityGroupsAsyncApi> getServerWithSecurityGroupsExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides asynchronous access to Server Admin Actions features. * Provides asynchronous access to Server Admin Actions features.
*/ */
@Delegate @Delegate
Optional<AdminActionsAsyncApi> getAdminActionsExtensionForZone( Optional<? extends AdminActionsAsyncApi> getAdminActionsExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides asynchronous access to HostAggregate features. * Provides asynchronous access to HostAggregate features.
*/ */
@Delegate @Delegate
Optional<HostAggregateAsyncApi> getHostAggregateExtensionForZone( Optional<? extends HostAggregateAsyncApi> getHostAggregateExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides asynchronous access to Flavor extra specs features. * Provides asynchronous access to Flavor extra specs features.
*/ */
@Delegate @Delegate
Optional<FlavorExtraSpecsAsyncApi> getFlavorExtraSpecsExtensionForZone( Optional<? extends FlavorExtraSpecsAsyncApi> getFlavorExtraSpecsExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides asynchronous access to Quota features. * Provides asynchronous access to Quota features.
*/ */
@Delegate @Delegate
Optional<QuotaAsyncApi> getQuotaExtensionForZone( Optional<? extends QuotaAsyncApi> getQuotaExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides asynchronous access to Quota Classes features. * Provides asynchronous access to Quota Classes features.
*/ */
@Delegate @Delegate
Optional<QuotaClassAsyncApi> getQuotaClassExtensionForZone( Optional<? extends QuotaClassAsyncApi> getQuotaClassExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/** /**
* Provides asynchronous access to Volume Type features. * Provides asynchronous access to Volume Type features.
*/ */
@Delegate @Delegate
Optional<VolumeTypeAsyncApi> getVolumeTypeExtensionForZone( Optional<? extends VolumeTypeAsyncApi> getVolumeTypeExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone); @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
} }

View File

@ -135,7 +135,7 @@ public class NovaComputeService extends BaseComputeService {
} }
private void cleanupOrphanedSecurityGroupsInZone(Set<String> groups, String zoneId) { private void cleanupOrphanedSecurityGroupsInZone(Set<String> groups, String zoneId) {
Optional<SecurityGroupApi> securityGroupApi = novaApi.getSecurityGroupExtensionForZone(zoneId); Optional<? extends SecurityGroupApi> securityGroupApi = novaApi.getSecurityGroupExtensionForZone(zoneId);
if (securityGroupApi.isPresent()) { if (securityGroupApi.isPresent()) {
for (String group : groups) { for (String group : groups) {
for (SecurityGroup securityGroup : Iterables.filter(securityGroupApi.get().listSecurityGroups(), for (SecurityGroup securityGroup : Iterables.filter(securityGroupApi.get().listSecurityGroups(),
@ -152,7 +152,7 @@ public class NovaComputeService extends BaseComputeService {
} }
private void cleanupOrphanedKeyPairsInZone(Set<String> groups, String zoneId) { private void cleanupOrphanedKeyPairsInZone(Set<String> groups, String zoneId) {
Optional<KeyPairApi> keyPairApi = novaApi.getKeyPairExtensionForZone(zoneId); Optional<? extends KeyPairApi> keyPairApi = novaApi.getKeyPairExtensionForZone(zoneId);
if (keyPairApi.isPresent()) { if (keyPairApi.isPresent()) {
for (String group : groups) { for (String group : groups) {
for (Map<String, KeyPair> view : keyPairApi.get().listKeyPairs()) { for (Map<String, KeyPair> view : keyPairApi.get().listKeyPairs()) {

View File

@ -159,12 +159,12 @@ public class NovaComputeServiceAdapter implements
Set<String> zones = zoneIds.get(); Set<String> zones = zoneIds.get();
checkState(zones.size() > 0, "no zones found in supplier %s", zoneIds); checkState(zones.size() > 0, "no zones found in supplier %s", zoneIds);
for (final String zoneId : zones) { for (final String zoneId : zones) {
Set<Image> images = novaApi.getImageApiForZone(zoneId).listImagesInDetail(); Set<? extends Image> images = novaApi.getImageApiForZone(zoneId).listImagesInDetail();
if (images.size() == 0) { if (images.size() == 0) {
logger.debug("no images found in zone %s", zoneId); logger.debug("no images found in zone %s", zoneId);
continue; continue;
} }
Iterable<Image> active = filter(images, ImagePredicates.statusEquals(Image.Status.ACTIVE)); Iterable<? extends Image> active = filter(images, ImagePredicates.statusEquals(Image.Status.ACTIVE));
if (images.size() == 0) { if (images.size() == 0) {
logger.debug("no images with status active in zone %s; non-active: %s", zoneId, logger.debug("no images with status active in zone %s; non-active: %s", zoneId,
transform(active, new Function<Image, String>() { transform(active, new Function<Image, String>() {

View File

@ -62,7 +62,7 @@ public class CreateSecurityGroupIfNeeded implements Function<ZoneSecurityGroupNa
checkNotNull(zoneSecurityGroupNameAndPorts, "zoneSecurityGroupNameAndPorts"); checkNotNull(zoneSecurityGroupNameAndPorts, "zoneSecurityGroupNameAndPorts");
String zoneId = zoneSecurityGroupNameAndPorts.getZone(); String zoneId = zoneSecurityGroupNameAndPorts.getZone();
Optional<SecurityGroupApi> api = novaApi.getSecurityGroupExtensionForZone(zoneId); Optional<? extends SecurityGroupApi> api = novaApi.getSecurityGroupExtensionForZone(zoneId);
checkArgument(api.isPresent(), "Security groups are required, but the extension is not availablein zone %s!", zoneId); checkArgument(api.isPresent(), "Security groups are required, but the extension is not availablein zone %s!", zoneId);
logger.debug(">> creating securityGroup %s", zoneSecurityGroupNameAndPorts); logger.debug(">> creating securityGroup %s", zoneSecurityGroupNameAndPorts);
try { try {

View File

@ -31,7 +31,6 @@ import java.util.NoSuchElementException;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
@ -96,7 +95,7 @@ public class ImageToOperatingSystem implements Function<Image, OperatingSystem>
try { try {
osFamily = find(Arrays.asList(OsFamily.values()), new Predicate<OsFamily>() { osFamily = find(Arrays.asList(OsFamily.values()), new Predicate<OsFamily>() {
@Override @Override
public boolean apply(@Nullable OsFamily osFamily) { public boolean apply(OsFamily osFamily) {
return any(imageNameParts, equalTo(osFamily.name().toLowerCase())); return any(imageNameParts, equalTo(osFamily.name().toLowerCase()));
} }
}); });

View File

@ -59,7 +59,7 @@ public class CreateUniqueKeyPair extends CacheLoader<ZoneAndName, KeyPair> {
String zoneId = checkNotNull(zoneAndName, "zoneAndName").getZone(); String zoneId = checkNotNull(zoneAndName, "zoneAndName").getZone();
String prefix = zoneAndName.getName(); String prefix = zoneAndName.getName();
Optional<KeyPairApi> api = novaApi.getKeyPairExtensionForZone(zoneId); Optional<? extends KeyPairApi> api = novaApi.getKeyPairExtensionForZone(zoneId);
checkArgument(api.isPresent(), "Key pairs are required, but the extension is not available in zone %s!", checkArgument(api.isPresent(), "Key pairs are required, but the extension is not available in zone %s!",
zoneId); zoneId);

View File

@ -51,7 +51,7 @@ public class LoadFloatingIpsForInstance extends CacheLoader<ZoneAndId, Iterable<
@Override @Override
public Iterable<FloatingIP> load(final ZoneAndId key) throws Exception { public Iterable<FloatingIP> load(final ZoneAndId key) throws Exception {
String zone = key.getZone(); String zone = key.getZone();
Optional<FloatingIPApi> ipApiOptional = api.getFloatingIPExtensionForZone(zone); Optional<? extends FloatingIPApi> ipApiOptional = api.getFloatingIPExtensionForZone(zone);
if (ipApiOptional.isPresent()) { if (ipApiOptional.isPresent()) {
return Iterables.filter(ipApiOptional.get().listFloatingIPs(), return Iterables.filter(ipApiOptional.get().listFloatingIPs(),
new Predicate<FloatingIP>() { new Predicate<FloatingIP>() {

View File

@ -18,6 +18,7 @@
*/ */
package org.jclouds.openstack.nova.v2_0.config; package org.jclouds.openstack.nova.v2_0.config;
import java.net.URI;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -29,47 +30,48 @@ import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.annotation.ClientError; import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection; import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError; import org.jclouds.http.annotation.ServerError;
import org.jclouds.openstack.nova.v2_0.NovaAsyncApi;
import org.jclouds.openstack.nova.v2_0.NovaApi; import org.jclouds.openstack.nova.v2_0.NovaApi;
import org.jclouds.openstack.nova.v2_0.domain.Extension; import org.jclouds.openstack.nova.v2_0.NovaAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.AdminActionsAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.AdminActionsApi; import org.jclouds.openstack.nova.v2_0.extensions.AdminActionsApi;
import org.jclouds.openstack.nova.v2_0.extensions.FlavorExtraSpecsAsyncApi; import org.jclouds.openstack.nova.v2_0.extensions.AdminActionsAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.ExtensionNamespaces;
import org.jclouds.openstack.nova.v2_0.extensions.FlavorExtraSpecsApi; import org.jclouds.openstack.nova.v2_0.extensions.FlavorExtraSpecsApi;
import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPAsyncApi; import org.jclouds.openstack.nova.v2_0.extensions.FlavorExtraSpecsAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPApi; import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPApi;
import org.jclouds.openstack.nova.v2_0.extensions.HostAdministrationAsyncApi; import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.HostAdministrationApi; import org.jclouds.openstack.nova.v2_0.extensions.HostAdministrationApi;
import org.jclouds.openstack.nova.v2_0.extensions.HostAggregateAsyncApi; import org.jclouds.openstack.nova.v2_0.extensions.HostAdministrationAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.HostAggregateApi; import org.jclouds.openstack.nova.v2_0.extensions.HostAggregateApi;
import org.jclouds.openstack.nova.v2_0.extensions.KeyPairAsyncApi; import org.jclouds.openstack.nova.v2_0.extensions.HostAggregateAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.KeyPairApi; import org.jclouds.openstack.nova.v2_0.extensions.KeyPairApi;
import org.jclouds.openstack.nova.v2_0.extensions.QuotaAsyncApi; import org.jclouds.openstack.nova.v2_0.extensions.KeyPairAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.QuotaClassAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.QuotaClassApi;
import org.jclouds.openstack.nova.v2_0.extensions.QuotaApi; import org.jclouds.openstack.nova.v2_0.extensions.QuotaApi;
import org.jclouds.openstack.nova.v2_0.extensions.SecurityGroupAsyncApi; import org.jclouds.openstack.nova.v2_0.extensions.QuotaAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.QuotaClassApi;
import org.jclouds.openstack.nova.v2_0.extensions.QuotaClassAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.SecurityGroupApi; import org.jclouds.openstack.nova.v2_0.extensions.SecurityGroupApi;
import org.jclouds.openstack.nova.v2_0.extensions.ServerWithSecurityGroupsAsyncApi; import org.jclouds.openstack.nova.v2_0.extensions.SecurityGroupAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.ServerWithSecurityGroupsApi; import org.jclouds.openstack.nova.v2_0.extensions.ServerWithSecurityGroupsApi;
import org.jclouds.openstack.nova.v2_0.extensions.SimpleTenantUsageAsyncApi; import org.jclouds.openstack.nova.v2_0.extensions.ServerWithSecurityGroupsAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.SimpleTenantUsageApi; import org.jclouds.openstack.nova.v2_0.extensions.SimpleTenantUsageApi;
import org.jclouds.openstack.nova.v2_0.extensions.VirtualInterfaceAsyncApi; import org.jclouds.openstack.nova.v2_0.extensions.SimpleTenantUsageAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.VirtualInterfaceApi; import org.jclouds.openstack.nova.v2_0.extensions.VirtualInterfaceApi;
import org.jclouds.openstack.nova.v2_0.extensions.VolumeAsyncApi; import org.jclouds.openstack.nova.v2_0.extensions.VirtualInterfaceAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.VolumeApi; import org.jclouds.openstack.nova.v2_0.extensions.VolumeApi;
import org.jclouds.openstack.nova.v2_0.extensions.VolumeTypeAsyncApi; import org.jclouds.openstack.nova.v2_0.extensions.VolumeAsyncApi;
import org.jclouds.openstack.nova.v2_0.extensions.VolumeTypeApi; import org.jclouds.openstack.nova.v2_0.extensions.VolumeTypeApi;
import org.jclouds.openstack.nova.v2_0.features.ExtensionAsyncApi; import org.jclouds.openstack.nova.v2_0.extensions.VolumeTypeAsyncApi;
import org.jclouds.openstack.nova.v2_0.features.ExtensionApi;
import org.jclouds.openstack.nova.v2_0.features.FlavorAsyncApi;
import org.jclouds.openstack.nova.v2_0.features.FlavorApi; import org.jclouds.openstack.nova.v2_0.features.FlavorApi;
import org.jclouds.openstack.nova.v2_0.features.ImageAsyncApi; import org.jclouds.openstack.nova.v2_0.features.FlavorAsyncApi;
import org.jclouds.openstack.nova.v2_0.features.ImageApi; import org.jclouds.openstack.nova.v2_0.features.ImageApi;
import org.jclouds.openstack.nova.v2_0.features.ServerAsyncApi; import org.jclouds.openstack.nova.v2_0.features.ImageAsyncApi;
import org.jclouds.openstack.nova.v2_0.features.ServerApi; import org.jclouds.openstack.nova.v2_0.features.ServerApi;
import org.jclouds.openstack.nova.v2_0.functions.PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet; import org.jclouds.openstack.nova.v2_0.features.ServerAsyncApi;
import org.jclouds.openstack.nova.v2_0.handlers.NovaErrorHandler; import org.jclouds.openstack.nova.v2_0.handlers.NovaErrorHandler;
import org.jclouds.openstack.v2_0.domain.Extension;
import org.jclouds.openstack.v2_0.features.ExtensionApi;
import org.jclouds.openstack.v2_0.features.ExtensionAsyncApi;
import org.jclouds.openstack.v2_0.functions.PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.config.RestClientModule;
import org.jclouds.rest.functions.ImplicitOptionalConverter; import org.jclouds.rest.functions.ImplicitOptionalConverter;
@ -78,6 +80,9 @@ import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import com.google.common.reflect.TypeToken;
import com.google.inject.Provides; import com.google.inject.Provides;
/** /**
@ -86,11 +91,13 @@ import com.google.inject.Provides;
* @author Adrian Cole * @author Adrian Cole
*/ */
@ConfiguresRestClient @ConfiguresRestClient
public class NovaRestClientModule extends RestClientModule<NovaApi, NovaAsyncApi> { public class NovaRestClientModule<S extends NovaApi, A extends NovaAsyncApi> extends RestClientModule<S, A> {
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder() public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()
.put(ServerApi.class, ServerAsyncApi.class).put(FlavorApi.class, FlavorAsyncApi.class) .put(ServerApi.class, ServerAsyncApi.class)
.put(ImageApi.class, ImageAsyncApi.class).put(ExtensionApi.class, ExtensionAsyncApi.class) .put(FlavorApi.class, FlavorAsyncApi.class)
.put(ImageApi.class, ImageAsyncApi.class)
.put(ExtensionApi.class, ExtensionAsyncApi.class)
.put(FloatingIPApi.class, FloatingIPAsyncApi.class) .put(FloatingIPApi.class, FloatingIPAsyncApi.class)
.put(SecurityGroupApi.class, SecurityGroupAsyncApi.class) .put(SecurityGroupApi.class, SecurityGroupAsyncApi.class)
.put(KeyPairApi.class, KeyPairAsyncApi.class) .put(KeyPairApi.class, KeyPairAsyncApi.class)
@ -106,30 +113,67 @@ public class NovaRestClientModule extends RestClientModule<NovaApi, NovaAsyncApi
.put(QuotaClassApi.class, QuotaClassAsyncApi.class) .put(QuotaClassApi.class, QuotaClassAsyncApi.class)
.put(VolumeTypeApi.class, VolumeTypeAsyncApi.class) .put(VolumeTypeApi.class, VolumeTypeAsyncApi.class)
.build(); .build();
public NovaRestClientModule() { public NovaRestClientModule() {
super(DELEGATE_MAP); super(TypeToken.class.cast(TypeToken.of(NovaApi.class)), TypeToken.class.cast(TypeToken.of(NovaAsyncApi.class)), DELEGATE_MAP);
}
protected NovaRestClientModule(TypeToken<S> syncClientType, TypeToken<A> asyncClientType,
Map<Class<?>, Class<?>> sync2Async) {
super(syncClientType, asyncClientType, sync2Async);
} }
@Override @Override
protected void configure() { protected void configure() {
install(new NovaParserModule()); install(new NovaParserModule());
bind(ImplicitOptionalConverter.class).to( bind(ImplicitOptionalConverter.class).to(PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.class);
PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.class);
super.configure(); super.configure();
} }
@Provides
@Singleton
public Multimap<URI, URI> aliases() {
return ImmutableMultimap.<URI, URI>builder()
.put(URI.create(ExtensionNamespaces.SECURITY_GROUPS),
URI.create("http://docs.openstack.org/compute/ext/securitygroups/api/v1.1"))
.put(URI.create(ExtensionNamespaces.FLOATING_IPS),
URI.create("http://docs.openstack.org/compute/ext/floating_ips/api/v1.1"))
.put(URI.create(ExtensionNamespaces.KEYPAIRS),
URI.create("http://docs.openstack.org/compute/ext/keypairs/api/v1.1"))
.put(URI.create(ExtensionNamespaces.SIMPLE_TENANT_USAGE),
URI.create("http://docs.openstack.org/compute/ext/os-simple-tenant-usage/api/v1.1"))
.put(URI.create(ExtensionNamespaces.HOSTS),
URI.create("http://docs.openstack.org/compute/ext/hosts/api/v1.1"))
.put(URI.create(ExtensionNamespaces.VOLUMES),
URI.create("http://docs.openstack.org/compute/ext/volumes/api/v1.1"))
.put(URI.create(ExtensionNamespaces.VIRTUAL_INTERFACES),
URI.create("http://docs.openstack.org/compute/ext/virtual_interfaces/api/v1.1"))
.put(URI.create(ExtensionNamespaces.CREATESERVEREXT),
URI.create("http://docs.openstack.org/compute/ext/createserverext/api/v1.1"))
.put(URI.create(ExtensionNamespaces.ADMIN_ACTIONS),
URI.create("http://docs.openstack.org/compute/ext/admin-actions/api/v1.1"))
.put(URI.create(ExtensionNamespaces.AGGREGATES),
URI.create("http://docs.openstack.org/compute/ext/aggregates/api/v1.1"))
.put(URI.create(ExtensionNamespaces.FLAVOR_EXTRA_SPECS),
URI.create("http://docs.openstack.org/compute/ext/flavor_extra_specs/api/v1.1"))
.put(URI.create(ExtensionNamespaces.QUOTAS),
URI.create("http://docs.openstack.org/compute/ext/quotas-sets/api/v1.1"))
.put(URI.create(ExtensionNamespaces.QUOTA_CLASSES),
URI.create("http://docs.openstack.org/compute/ext/quota-classes-sets/api/v1.1"))
.put(URI.create(ExtensionNamespaces.VOLUME_TYPES),
URI.create("http://docs.openstack.org/compute/ext/volume_types/api/v1.1"))
.build();
}
@Provides @Provides
@Singleton @Singleton
public LoadingCache<String, Set<Extension>> provideExtensionsByZone(final Provider<NovaApi> novaApi) { public LoadingCache<String, Set<? extends Extension>> provideExtensionsByZone(final Provider<NovaApi> novaApi) {
return CacheBuilder.newBuilder().expireAfterWrite(23, TimeUnit.HOURS) return CacheBuilder.newBuilder().expireAfterWrite(23, TimeUnit.HOURS)
.build(new CacheLoader<String, Set<Extension>>() { .build(new CacheLoader<String, Set<? extends Extension>>() {
@Override @Override
public Set<Extension> load(String key) throws Exception { public Set<? extends Extension> load(String key) throws Exception {
return novaApi.get().getExtensionApiForZone(key).listExtensions(); return novaApi.get().getExtensionApiForZone(key).listExtensions();
} }
}); });
} }

View File

@ -31,8 +31,8 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest; import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.openstack.nova.v2_0.domain.FloatingIP; import org.jclouds.openstack.nova.v2_0.domain.FloatingIP;
import org.jclouds.openstack.nova.v2_0.features.ExtensionAsyncApi;
import org.jclouds.openstack.v2_0.ServiceType; import org.jclouds.openstack.v2_0.ServiceType;
import org.jclouds.openstack.v2_0.features.ExtensionAsyncApi;
import org.jclouds.openstack.v2_0.services.Extension; import org.jclouds.openstack.v2_0.services.Extension;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.Payload; import org.jclouds.rest.annotations.Payload;

View File

@ -32,8 +32,8 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest; import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.openstack.nova.v2_0.domain.KeyPair; import org.jclouds.openstack.nova.v2_0.domain.KeyPair;
import org.jclouds.openstack.nova.v2_0.features.ExtensionAsyncApi;
import org.jclouds.openstack.v2_0.ServiceType; import org.jclouds.openstack.v2_0.ServiceType;
import org.jclouds.openstack.v2_0.features.ExtensionAsyncApi;
import org.jclouds.openstack.v2_0.services.Extension; import org.jclouds.openstack.v2_0.services.Extension;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.Payload; import org.jclouds.rest.annotations.Payload;

View File

@ -43,14 +43,14 @@ public interface FlavorApi {
* *
* @return all flavors (IDs, names, links) * @return all flavors (IDs, names, links)
*/ */
Set<Resource> listFlavors(); Set<? extends Resource> listFlavors();
/** /**
* List all flavors (all details) * List all flavors (all details)
* *
* @return all flavors (all details) * @return all flavors (all details)
*/ */
Set<Flavor> listFlavorsInDetail(); Set<? extends Flavor> listFlavorsInDetail();
/** /**
* List details of the specified flavor * List details of the specified flavor

View File

@ -61,7 +61,7 @@ public interface FlavorAsyncApi {
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Path("/flavors") @Path("/flavors")
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<Resource>> listFlavors(); ListenableFuture<? extends Set<? extends Resource>> listFlavors();
/** /**
* @see FlavorApi#listFlavorsInDetail * @see FlavorApi#listFlavorsInDetail
@ -71,7 +71,7 @@ public interface FlavorAsyncApi {
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Path("/flavors/detail") @Path("/flavors/detail")
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<Flavor>> listFlavorsInDetail(); ListenableFuture<? extends Set<? extends Flavor>> listFlavorsInDetail();
/** /**
* @see FlavorApi#getFlavor * @see FlavorApi#getFlavor
@ -81,6 +81,6 @@ public interface FlavorAsyncApi {
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Path("/flavors/{id}") @Path("/flavors/{id}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Flavor> getFlavor(@PathParam("id") String id); ListenableFuture<? extends Flavor> getFlavor(@PathParam("id") String id);
} }

View File

@ -43,14 +43,14 @@ public interface ImageApi {
* *
* @return all images (IDs, names, links) * @return all images (IDs, names, links)
*/ */
Set<Resource> listImages(); Set<? extends Resource> listImages();
/** /**
* List all images (all details) * List all images (all details)
* *
* @return all images (all details) * @return all images (all details)
*/ */
Set<Image> listImagesInDetail(); Set<? extends Image> listImagesInDetail();
/** /**
* List details of the specified image * List details of the specified image

View File

@ -59,7 +59,7 @@ public interface ImageAsyncApi {
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Path("/images") @Path("/images")
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<Resource>> listImages(); ListenableFuture<? extends Set<? extends Resource>> listImages();
/** /**
* @see ImageApi#listImagesInDetail * @see ImageApi#listImagesInDetail
@ -69,7 +69,7 @@ public interface ImageAsyncApi {
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Path("/images/detail") @Path("/images/detail")
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<Image>> listImagesInDetail(); ListenableFuture<? extends Set<? extends Image>> listImagesInDetail();
/** /**
* @see ImageApi#getImage * @see ImageApi#getImage
@ -79,7 +79,7 @@ public interface ImageAsyncApi {
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Path("/images/{id}") @Path("/images/{id}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Image> getImage(@PathParam("id") String id); ListenableFuture<? extends Image> getImage(@PathParam("id") String id);
/** /**
* @see ImageApi#deleteImage * @see ImageApi#deleteImage

View File

@ -47,14 +47,14 @@ public interface ServerApi {
* *
* @return all servers (IDs, names, links) * @return all servers (IDs, names, links)
*/ */
Set<Resource> listServers(); Set<? extends Resource> listServers();
/** /**
* List all servers (all details) * List all servers (all details)
* *
* @return all servers (all details) * @return all servers (all details)
*/ */
Set<Server> listServersInDetail(); Set<? extends Server> listServersInDetail();
/** /**
* List details of the specified server * List details of the specified server

View File

@ -76,7 +76,7 @@ public interface ServerAsyncApi {
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Path("/servers") @Path("/servers")
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<Resource>> listServers(); ListenableFuture<? extends Set<? extends Resource>> listServers();
/** /**
* @see ServerApi#listServersInDetail * @see ServerApi#listServersInDetail
@ -86,7 +86,7 @@ public interface ServerAsyncApi {
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Path("/servers/detail") @Path("/servers/detail")
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<Server>> listServersInDetail(); ListenableFuture<? extends Set<? extends Server>> listServersInDetail();
/** /**
* @see ServerApi#getServer * @see ServerApi#getServer
@ -96,7 +96,7 @@ public interface ServerAsyncApi {
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Path("/servers/{id}") @Path("/servers/{id}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Server> getServer(@PathParam("id") String id); ListenableFuture<? extends Server> getServer(@PathParam("id") String id);
/** /**
* @see ServerApi#deleteServer * @see ServerApi#deleteServer
@ -144,7 +144,7 @@ public interface ServerAsyncApi {
@Path("/servers/{id}/action") @Path("/servers/{id}/action")
@Consumes @Consumes
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Payload("%7B\"resize\":%7B\"flavorId\":{flavorId}%7D%7D") @Payload("%7B\"resize\":%7B\"flavorRef\":{flavorId}%7D%7D")
ListenableFuture<Void> resizeServer(@PathParam("id") String id, @PayloadParam("flavorId") String flavorId); ListenableFuture<Void> resizeServer(@PathParam("id") String id, @PayloadParam("flavorId") String flavorId);
/** /**

View File

@ -1,113 +0,0 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v2_0.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.net.URI;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.internal.ClassMethodArgsAndReturnVal;
import org.jclouds.openstack.nova.v2_0.domain.Extension;
import org.jclouds.openstack.nova.v2_0.extensions.ExtensionNamespaces;
import org.jclouds.openstack.nova.v2_0.predicates.ExtensionPredicates;
import org.jclouds.rest.functions.ImplicitOptionalConverter;
import com.google.common.base.Optional;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap;
/**
* We use the annotation {@link org.jclouds.openstack.services.Extension} to
* bind a class that is an extension to an extension found in the
* {@link org.jclouds.openstack.nova.v2_0.features.ExtensionApi#listExtensions} call.
*
* @author Adrian Cole
*
*/
@Singleton
public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet implements
ImplicitOptionalConverter {
private final LoadingCache<String, Set<Extension>> extensions;
@com.google.inject.Inject(optional=true)
@Named("openstack.nova.extensions")
Multimap<URI, URI> aliases = ImmutableMultimap.<URI, URI>builder()
.put(URI.create(ExtensionNamespaces.SECURITY_GROUPS),
URI.create("http://docs.openstack.org/compute/ext/securitygroups/api/v1.1"))
.put(URI.create(ExtensionNamespaces.FLOATING_IPS),
URI.create("http://docs.openstack.org/compute/ext/floating_ips/api/v1.1"))
.put(URI.create(ExtensionNamespaces.KEYPAIRS),
URI.create("http://docs.openstack.org/compute/ext/keypairs/api/v1.1"))
.put(URI.create(ExtensionNamespaces.SIMPLE_TENANT_USAGE),
URI.create("http://docs.openstack.org/compute/ext/os-simple-tenant-usage/api/v1.1"))
.put(URI.create(ExtensionNamespaces.HOSTS),
URI.create("http://docs.openstack.org/compute/ext/hosts/api/v1.1"))
.put(URI.create(ExtensionNamespaces.VOLUMES),
URI.create("http://docs.openstack.org/compute/ext/volumes/api/v1.1"))
.put(URI.create(ExtensionNamespaces.VIRTUAL_INTERFACES),
URI.create("http://docs.openstack.org/compute/ext/virtual_interfaces/api/v1.1"))
.put(URI.create(ExtensionNamespaces.CREATESERVEREXT),
URI.create("http://docs.openstack.org/compute/ext/createserverext/api/v1.1"))
.put(URI.create(ExtensionNamespaces.ADMIN_ACTIONS),
URI.create("http://docs.openstack.org/compute/ext/admin-actions/api/v1.1"))
.put(URI.create(ExtensionNamespaces.AGGREGATES),
URI.create("http://docs.openstack.org/compute/ext/aggregates/api/v1.1"))
.put(URI.create(ExtensionNamespaces.FLAVOR_EXTRA_SPECS),
URI.create("http://docs.openstack.org/compute/ext/flavor_extra_specs/api/v1.1"))
.put(URI.create(ExtensionNamespaces.QUOTAS),
URI.create("http://docs.openstack.org/compute/ext/quotas-sets/api/v1.1"))
.put(URI.create(ExtensionNamespaces.QUOTA_CLASSES),
URI.create("http://docs.openstack.org/compute/ext/quota-classes-sets/api/v1.1"))
.put(URI.create(ExtensionNamespaces.VOLUME_TYPES),
URI.create("http://docs.openstack.org/compute/ext/volume_types/api/v1.1"))
.build();
@Inject
public PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet(
LoadingCache<String, Set<Extension>> extensions) {
this.extensions = checkNotNull(extensions, "extensions");
}
@Override
public Optional<Object> apply(ClassMethodArgsAndReturnVal input) {
Optional<org.jclouds.openstack.v2_0.services.Extension> ext = Optional.fromNullable(input.getClazz().getAnnotation(
org.jclouds.openstack.v2_0.services.Extension.class));
if (ext.isPresent()) {
checkState(input.getArgs() != null && input.getArgs().length == 1, "expecting an arg %s", input);
URI namespace = URI.create(ext.get().namespace());
if (Iterables.any(extensions.getUnchecked(checkNotNull(input.getArgs()[0], "arg[0] in %s", input).toString()),
ExtensionPredicates.namespaceOrAliasEquals(namespace, aliases.get(namespace))))
return Optional.of(input.getReturnVal());
}
return Optional.absent();
}
public String toString() {
return "presentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet()";
}
}

View File

@ -46,12 +46,12 @@ public class CreateVolumeOptions implements MapBinder {
@Inject @Inject
private BindToJsonPayload jsonBinder; private BindToJsonPayload jsonBinder;
private String name; protected String name;
private String description; protected String description;
private String volumeType; protected String volumeType;
private String availabilityZone; protected String availabilityZone;
private String snapshotId; protected String snapshotId;
private Map<String, String> metadata = ImmutableMap.of(); protected Map<String, String> metadata = ImmutableMap.of();
@Override @Override
public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) { public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) {
@ -61,6 +61,12 @@ public class CreateVolumeOptions implements MapBinder {
image.put("display_name", name); image.put("display_name", name);
if (description != null) if (description != null)
image.put("display_description", description); image.put("display_description", description);
if (volumeType != null)
image.put("volume_type", volumeType);
if (availabilityZone != null)
image.put("availability_zone", availabilityZone);
if (snapshotId != null)
image.put("snapshot_id", snapshotId);
if (!metadata.isEmpty()) if (!metadata.isEmpty())
image.put("metadata", metadata); image.put("metadata", metadata);
return jsonBinder.bindToRequest(request, ImmutableMap.of("volume", image)); return jsonBinder.bindToRequest(request, ImmutableMap.of("volume", image));

View File

@ -62,7 +62,7 @@ public class FindSecurityGroupWithNameAndReturnTrue implements Predicate<AtomicR
checkNotNull(securityGroupInZoneRef, "securityGroupRef"); checkNotNull(securityGroupInZoneRef, "securityGroupRef");
final ZoneAndName securityGroupInZone = checkNotNull(securityGroupInZoneRef.get(), "securityGroupInZone"); final ZoneAndName securityGroupInZone = checkNotNull(securityGroupInZoneRef.get(), "securityGroupInZone");
Optional<SecurityGroupApi> api = novaApi.getSecurityGroupExtensionForZone(securityGroupInZone.getZone()); Optional<? extends SecurityGroupApi> api = novaApi.getSecurityGroupExtensionForZone(securityGroupInZone.getZone());
checkArgument(api.isPresent(), "Security groups are required, but the extension is not available!"); checkArgument(api.isPresent(), "Security groups are required, but the extension is not available!");
logger.trace("looking for security group %s", securityGroupInZone.slashEncode()); logger.trace("looking for security group %s", securityGroupInZone.slashEncode());

View File

@ -26,8 +26,6 @@ import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.annotation.Nullable;
import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.OsFamily;
import org.jclouds.openstack.nova.v2_0.domain.Image; import org.jclouds.openstack.nova.v2_0.domain.Image;
@ -69,7 +67,7 @@ public class ImageToOperatingSystemTest {
return Iterables.toArray( return Iterables.toArray(
Iterables.transform(Arrays.asList(OsFamily.values()), new Function<OsFamily, Object[]>() { Iterables.transform(Arrays.asList(OsFamily.values()), new Function<OsFamily, Object[]>() {
@Override @Override
public Object[] apply(@Nullable OsFamily osFamily) { public Object[] apply(OsFamily osFamily) {
return new Object[] { osFamily }; return new Object[] { osFamily };
} }
}), Object[].class); }), Object[].class);

View File

@ -52,7 +52,9 @@ public class CreateUniqueKeyPairTest {
KeyPair pair = createMock(KeyPair.class); KeyPair pair = createMock(KeyPair.class);
expect(api.getKeyPairExtensionForZone("zone")).andReturn(Optional.of(keyApi)).atLeastOnce(); Optional optKeyApi = Optional.of(keyApi);
expect(api.getKeyPairExtensionForZone("zone")).andReturn(optKeyApi).atLeastOnce();
expect(keyApi.createKeyPair("group-1")).andReturn(pair); expect(keyApi.createKeyPair("group-1")).andReturn(pair);
@ -83,7 +85,7 @@ public class CreateUniqueKeyPairTest {
KeyPair pair = createMock(KeyPair.class); KeyPair pair = createMock(KeyPair.class);
expect(api.getKeyPairExtensionForZone("zone")).andReturn(Optional.of(keyApi)).atLeastOnce(); expect(api.getKeyPairExtensionForZone("zone")).andReturn((Optional) Optional.of(keyApi)).atLeastOnce();
expect(uniqueIdSupplier.get()).andReturn("1"); expect(uniqueIdSupplier.get()).andReturn("1");
expect(keyApi.createKeyPair("group-1")).andThrow(new IllegalStateException()); expect(keyApi.createKeyPair("group-1")).andThrow(new IllegalStateException());

View File

@ -46,7 +46,7 @@ public class LoadFloatingIpsForInstanceTest {
FloatingIPApi ipApi = createMock(FloatingIPApi.class); FloatingIPApi ipApi = createMock(FloatingIPApi.class);
FloatingIP testIp = FloatingIP.builder().id("1").ip("1.1.1.1").fixedIp("10.1.1.1").instanceId("i-blah").build(); FloatingIP testIp = FloatingIP.builder().id("1").ip("1.1.1.1").fixedIp("10.1.1.1").instanceId("i-blah").build();
expect(api.getFloatingIPExtensionForZone("Zone")).andReturn(Optional.of(ipApi)).atLeastOnce(); expect(api.getFloatingIPExtensionForZone("Zone")).andReturn((Optional) Optional.of(ipApi)).atLeastOnce();
expect(ipApi.listFloatingIPs()).andReturn(ImmutableSet.<FloatingIP>of(testIp)).atLeastOnce(); expect(ipApi.listFloatingIPs()).andReturn(ImmutableSet.<FloatingIP>of(testIp)).atLeastOnce();
replay(api); replay(api);
@ -65,7 +65,7 @@ public class LoadFloatingIpsForInstanceTest {
NovaApi api = createMock(NovaApi.class); NovaApi api = createMock(NovaApi.class);
FloatingIPApi ipApi = createMock(FloatingIPApi.class); FloatingIPApi ipApi = createMock(FloatingIPApi.class);
expect(api.getFloatingIPExtensionForZone("Zone")).andReturn(Optional.of(ipApi)).atLeastOnce(); expect(api.getFloatingIPExtensionForZone("Zone")).andReturn((Optional) Optional.of(ipApi)).atLeastOnce();
expect(ipApi.listFloatingIPs()).andReturn(ImmutableSet.<FloatingIP>of()).atLeastOnce(); expect(ipApi.listFloatingIPs()).andReturn(ImmutableSet.<FloatingIP>of()).atLeastOnce();
@ -86,7 +86,7 @@ public class LoadFloatingIpsForInstanceTest {
NovaApi api = createMock(NovaApi.class); NovaApi api = createMock(NovaApi.class);
FloatingIPApi ipApi = createMock(FloatingIPApi.class); FloatingIPApi ipApi = createMock(FloatingIPApi.class);
expect(api.getFloatingIPExtensionForZone("Zone")).andReturn(Optional.of(ipApi)).atLeastOnce(); expect(api.getFloatingIPExtensionForZone("Zone")).andReturn((Optional) Optional.of(ipApi)).atLeastOnce();
expect(ipApi.listFloatingIPs()).andReturn( expect(ipApi.listFloatingIPs()).andReturn(
ImmutableSet.<FloatingIP>of(FloatingIP.builder().id("1").ip("1.1.1.1").build())) ImmutableSet.<FloatingIP>of(FloatingIP.builder().id("1").ip("1.1.1.1").build()))

View File

@ -27,11 +27,11 @@ import org.jclouds.http.HttpResponseException;
import org.jclouds.openstack.nova.v2_0.domain.BackupType; import org.jclouds.openstack.nova.v2_0.domain.BackupType;
import org.jclouds.openstack.nova.v2_0.domain.Image; import org.jclouds.openstack.nova.v2_0.domain.Image;
import org.jclouds.openstack.nova.v2_0.domain.Server.Status; import org.jclouds.openstack.nova.v2_0.domain.Server.Status;
import org.jclouds.openstack.nova.v2_0.features.ExtensionApi;
import org.jclouds.openstack.nova.v2_0.features.ImageApi; import org.jclouds.openstack.nova.v2_0.features.ImageApi;
import org.jclouds.openstack.nova.v2_0.features.ServerApi; import org.jclouds.openstack.nova.v2_0.features.ServerApi;
import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiLiveTest; import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiLiveTest;
import org.jclouds.openstack.nova.v2_0.options.CreateBackupOfServerOptions; import org.jclouds.openstack.nova.v2_0.options.CreateBackupOfServerOptions;
import org.jclouds.openstack.v2_0.features.ExtensionApi;
import org.testng.annotations.AfterGroups; import org.testng.annotations.AfterGroups;
import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeGroups;
@ -53,7 +53,7 @@ public class AdminActionsApiLiveTest extends BaseNovaApiLiveTest {
private ImageApi imageApi; private ImageApi imageApi;
private ServerApi serverApi; private ServerApi serverApi;
private ExtensionApi extensionApi; private ExtensionApi extensionApi;
private Optional<AdminActionsApi> apiOption; private Optional<? extends AdminActionsApi> apiOption;
private String zone; private String zone;
private String testServerId; private String testServerId;

View File

@ -44,7 +44,7 @@ import com.google.common.collect.Maps;
@Test(groups = "live", testName = "FlavorExtraSpecsApiLiveTest", singleThreaded = true) @Test(groups = "live", testName = "FlavorExtraSpecsApiLiveTest", singleThreaded = true)
public class FlavorExtraSpecsApiLiveTest extends BaseNovaApiLiveTest { public class FlavorExtraSpecsApiLiveTest extends BaseNovaApiLiveTest {
private FlavorApi flavorApi; private FlavorApi flavorApi;
private Optional<FlavorExtraSpecsApi> apiOption; private Optional<? extends FlavorExtraSpecsApi> apiOption;
private String zone; private String zone;
private Resource testFlavor; private Resource testFlavor;

View File

@ -48,7 +48,7 @@ public class FloatingIPApiLiveTest extends BaseNovaApiLiveTest {
@Test @Test
public void testListFloatingIPs() throws Exception { public void testListFloatingIPs() throws Exception {
for (String zoneId : novaContext.getApi().getConfiguredZones()) { for (String zoneId : novaContext.getApi().getConfiguredZones()) {
Optional<FloatingIPApi> apiOption = novaContext.getApi().getFloatingIPExtensionForZone(zoneId); Optional<? extends FloatingIPApi> apiOption = novaContext.getApi().getFloatingIPExtensionForZone(zoneId);
if (!apiOption.isPresent()) if (!apiOption.isPresent())
continue; continue;
FloatingIPApi api = apiOption.get(); FloatingIPApi api = apiOption.get();
@ -70,7 +70,7 @@ public class FloatingIPApiLiveTest extends BaseNovaApiLiveTest {
@Test @Test
public void testAllocateAndDeallocateFloatingIPs() throws Exception { public void testAllocateAndDeallocateFloatingIPs() throws Exception {
for (String zoneId : novaContext.getApi().getConfiguredZones()) { for (String zoneId : novaContext.getApi().getConfiguredZones()) {
Optional<FloatingIPApi> apiOption = novaContext.getApi().getFloatingIPExtensionForZone(zoneId); Optional<? extends FloatingIPApi> apiOption = novaContext.getApi().getFloatingIPExtensionForZone(zoneId);
if (!apiOption.isPresent()) if (!apiOption.isPresent())
continue; continue;
FloatingIPApi api = apiOption.get(); FloatingIPApi api = apiOption.get();
@ -101,7 +101,7 @@ public class FloatingIPApiLiveTest extends BaseNovaApiLiveTest {
@Test @Test
public void testAddAndRemoveFloatingIp() throws Exception { public void testAddAndRemoveFloatingIp() throws Exception {
for (String zoneId : novaContext.getApi().getConfiguredZones()) { for (String zoneId : novaContext.getApi().getConfiguredZones()) {
Optional<FloatingIPApi> apiOption = novaContext.getApi().getFloatingIPExtensionForZone(zoneId); Optional<? extends FloatingIPApi> apiOption = novaContext.getApi().getFloatingIPExtensionForZone(zoneId);
if (!apiOption.isPresent()) if (!apiOption.isPresent())
continue; continue;
FloatingIPApi api = apiOption.get(); FloatingIPApi api = apiOption.get();

View File

@ -42,7 +42,7 @@ import com.google.common.collect.Iterables;
*/ */
@Test(groups = "live", testName = "HostAdministrationApiLiveTest", singleThreaded = true) @Test(groups = "live", testName = "HostAdministrationApiLiveTest", singleThreaded = true)
public class HostAdministrationApiLiveTest extends BaseNovaApiLiveTest { public class HostAdministrationApiLiveTest extends BaseNovaApiLiveTest {
private Optional<HostAdministrationApi> optApi = Optional.absent(); private Optional<? extends HostAdministrationApi> optApi = Optional.absent();
Predicate<Host> isComputeHost = new Predicate<Host>() { Predicate<Host> isComputeHost = new Predicate<Host>() {
@Override @Override

View File

@ -44,8 +44,8 @@ import com.google.common.collect.Iterables;
*/ */
@Test(groups = "live", testName = "AggregateApiLiveTest", singleThreaded = true) @Test(groups = "live", testName = "AggregateApiLiveTest", singleThreaded = true)
public class HostAggregateApiLiveTest extends BaseNovaApiLiveTest { public class HostAggregateApiLiveTest extends BaseNovaApiLiveTest {
private Optional<HostAggregateApi> apiOption; private Optional<? extends HostAggregateApi> apiOption;
private Optional<HostAdministrationApi> hostAdminOption; private Optional<? extends HostAdministrationApi> hostAdminOption;
private HostAggregate testAggregate; private HostAggregate testAggregate;

View File

@ -36,7 +36,7 @@ import com.google.common.collect.Iterables;
*/ */
@Test(groups = "live", testName = "QuotaApiLiveTest", singleThreaded = true) @Test(groups = "live", testName = "QuotaApiLiveTest", singleThreaded = true)
public class QuotaApiLiveTest extends BaseNovaApiLiveTest { public class QuotaApiLiveTest extends BaseNovaApiLiveTest {
private Optional<QuotaApi> apiOption; private Optional<? extends QuotaApi> apiOption;
private String tenant; private String tenant;
@BeforeClass(groups = {"integration", "live"}) @BeforeClass(groups = {"integration", "live"})

View File

@ -36,7 +36,7 @@ import com.google.common.collect.Iterables;
*/ */
@Test(groups = "live", testName = "QuotaClassApiLiveTest", singleThreaded = true) @Test(groups = "live", testName = "QuotaClassApiLiveTest", singleThreaded = true)
public class QuotaClassApiLiveTest extends BaseNovaApiLiveTest { public class QuotaClassApiLiveTest extends BaseNovaApiLiveTest {
private Optional<QuotaClassApi> apiOption; private Optional<? extends QuotaClassApi> apiOption;
private String zone; private String zone;
@BeforeClass(groups = {"integration", "live"}) @BeforeClass(groups = {"integration", "live"})

View File

@ -41,7 +41,7 @@ import com.google.common.collect.Iterables;
@Test(groups = "live", testName = "ServerWithSecurityGroupsApiLiveTest", singleThreaded = true) @Test(groups = "live", testName = "ServerWithSecurityGroupsApiLiveTest", singleThreaded = true)
public class ServerWithSecurityGroupsApiLiveTest extends BaseNovaApiLiveTest { public class ServerWithSecurityGroupsApiLiveTest extends BaseNovaApiLiveTest {
private ServerApi serverApi; private ServerApi serverApi;
private Optional<ServerWithSecurityGroupsApi> apiOption; private Optional<? extends ServerWithSecurityGroupsApi> apiOption;
private String zone; private String zone;
@BeforeGroups(groups = {"integration", "live"}) @BeforeGroups(groups = {"integration", "live"})

View File

@ -38,7 +38,7 @@ public class SimpleTenantUsageApiLiveTest extends BaseNovaApiLiveTest {
public void testList() throws Exception { public void testList() throws Exception {
for (String zoneId : novaContext.getApi().getConfiguredZones()) { for (String zoneId : novaContext.getApi().getConfiguredZones()) {
Optional<SimpleTenantUsageApi> optApi = novaContext.getApi().getSimpleTenantUsageExtensionForZone(zoneId); Optional<? extends SimpleTenantUsageApi> optApi = novaContext.getApi().getSimpleTenantUsageExtensionForZone(zoneId);
if (optApi.isPresent() && identity.endsWith(":admin")) { if (optApi.isPresent() && identity.endsWith(":admin")) {
SimpleTenantUsageApi api = optApi.get(); SimpleTenantUsageApi api = optApi.get();
Set<SimpleTenantUsage> usages = api.listTenantUsages(); Set<SimpleTenantUsage> usages = api.listTenantUsages();

View File

@ -38,7 +38,7 @@ import com.google.common.collect.Iterables;
*/ */
@Test(groups = "live", testName = "VirtualInterfaceApiLiveTest", singleThreaded = true) @Test(groups = "live", testName = "VirtualInterfaceApiLiveTest", singleThreaded = true)
public class VirtualInterfaceApiLiveTest extends BaseNovaApiLiveTest { public class VirtualInterfaceApiLiveTest extends BaseNovaApiLiveTest {
private Optional<VirtualInterfaceApi> apiOption; private Optional<? extends VirtualInterfaceApi> apiOption;
private String zone; private String zone;

View File

@ -48,7 +48,7 @@ import com.google.common.collect.Iterables;
@Test(groups = "live", testName = "VolumeApiLiveTest", singleThreaded = true) @Test(groups = "live", testName = "VolumeApiLiveTest", singleThreaded = true)
public class VolumeApiLiveTest extends BaseNovaApiLiveTest { public class VolumeApiLiveTest extends BaseNovaApiLiveTest {
private Optional<VolumeApi> volumeOption; private Optional<? extends VolumeApi> volumeOption;
private String zone; private String zone;
private Volume testVolume; private Volume testVolume;

View File

@ -46,7 +46,7 @@ import com.google.common.collect.Iterables;
@Test(groups = "live", testName = "VolumeTypeApiLiveTest", singleThreaded = true) @Test(groups = "live", testName = "VolumeTypeApiLiveTest", singleThreaded = true)
public class VolumeTypeApiLiveTest extends BaseNovaApiLiveTest { public class VolumeTypeApiLiveTest extends BaseNovaApiLiveTest {
private Optional<VolumeTypeApi> volumeTypeOption; private Optional<? extends VolumeTypeApi> volumeTypeOption;
private String zone; private String zone;
private VolumeType testVolumeType; private VolumeType testVolumeType;

View File

@ -23,8 +23,9 @@ import static org.testng.Assert.assertTrue;
import java.util.Set; import java.util.Set;
import org.jclouds.openstack.nova.v2_0.domain.Extension;
import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiLiveTest; import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiLiveTest;
import org.jclouds.openstack.v2_0.domain.Extension;
import org.jclouds.openstack.v2_0.features.ExtensionApi;
import org.testng.annotations.Test; import org.testng.annotations.Test;
/** /**
@ -44,7 +45,7 @@ public class ExtensionApiLiveTest extends BaseNovaApiLiveTest {
public void testListExtensions() throws Exception { public void testListExtensions() throws Exception {
for (String zoneId : novaContext.getApi().getConfiguredZones()) { for (String zoneId : novaContext.getApi().getConfiguredZones()) {
ExtensionApi api = novaContext.getApi().getExtensionApiForZone(zoneId); ExtensionApi api = novaContext.getApi().getExtensionApiForZone(zoneId);
Set<Extension> response = api.listExtensions(); Set<? extends Extension> response = api.listExtensions();
assert null != response; assert null != response;
assertTrue(response.size() >= 0); assertTrue(response.size() >= 0);
for (Extension extension : response) { for (Extension extension : response) {

View File

@ -45,7 +45,7 @@ public class FlavorApiLiveTest extends BaseNovaApiLiveTest {
public void testListFlavors() throws Exception { public void testListFlavors() throws Exception {
for (String zoneId : novaContext.getApi().getConfiguredZones()) { for (String zoneId : novaContext.getApi().getConfiguredZones()) {
FlavorApi api = novaContext.getApi().getFlavorApiForZone(zoneId); FlavorApi api = novaContext.getApi().getFlavorApiForZone(zoneId);
Set<Resource> response = api.listFlavors(); Set<? extends Resource> response = api.listFlavors();
assert null != response; assert null != response;
assertTrue(response.size() >= 0); assertTrue(response.size() >= 0);
for (Resource flavor : response) { for (Resource flavor : response) {
@ -66,7 +66,7 @@ public class FlavorApiLiveTest extends BaseNovaApiLiveTest {
public void testListFlavorsInDetail() throws Exception { public void testListFlavorsInDetail() throws Exception {
for (String zoneId : novaContext.getApi().getConfiguredZones()) { for (String zoneId : novaContext.getApi().getConfiguredZones()) {
FlavorApi api = novaContext.getApi().getFlavorApiForZone(zoneId); FlavorApi api = novaContext.getApi().getFlavorApiForZone(zoneId);
Set<Flavor> response = api.listFlavorsInDetail(); Set<? extends Flavor> response = api.listFlavorsInDetail();
assert null != response; assert null != response;
assertTrue(response.size() >= 0); assertTrue(response.size() >= 0);
for (Flavor flavor : response) { for (Flavor flavor : response) {

View File

@ -41,7 +41,7 @@ public class ImageApiLiveTest extends BaseNovaApiLiveTest {
public void testListImages() throws Exception { public void testListImages() throws Exception {
for (String zoneId : novaContext.getApi().getConfiguredZones()) { for (String zoneId : novaContext.getApi().getConfiguredZones()) {
ImageApi api = novaContext.getApi().getImageApiForZone(zoneId); ImageApi api = novaContext.getApi().getImageApiForZone(zoneId);
Set<Resource> response = api.listImages(); Set<? extends Resource> response = api.listImages();
assertNotNull(response); assertNotNull(response);
assertTrue(response.size() >= 0); assertTrue(response.size() >= 0);
for (Resource image : response) { for (Resource image : response) {
@ -58,7 +58,7 @@ public class ImageApiLiveTest extends BaseNovaApiLiveTest {
public void testListImagesInDetail() throws Exception { public void testListImagesInDetail() throws Exception {
for (String zoneId : novaContext.getApi().getConfiguredZones()) { for (String zoneId : novaContext.getApi().getConfiguredZones()) {
ImageApi api = novaContext.getApi().getImageApiForZone(zoneId); ImageApi api = novaContext.getApi().getImageApiForZone(zoneId);
Set<Image> response = api.listImagesInDetail(); Set<? extends Image> response = api.listImagesInDetail();
assertNotNull(response); assertNotNull(response);
assertTrue(response.size() >= 0); assertTrue(response.size() >= 0);
for (Image image : response) { for (Image image : response) {

View File

@ -40,7 +40,7 @@ public class ServerApiLiveTest extends BaseNovaApiLiveTest {
public void testListServersInDetail() throws Exception { public void testListServersInDetail() throws Exception {
for (String zoneId : novaContext.getApi().getConfiguredZones()) { for (String zoneId : novaContext.getApi().getConfiguredZones()) {
ServerApi api = novaContext.getApi().getServerApiForZone(zoneId); ServerApi api = novaContext.getApi().getServerApiForZone(zoneId);
Set<Resource> response = api.listServers(); Set<? extends Resource> response = api.listServers();
assert null != response; assert null != response;
assertTrue(response.size() >= 0); assertTrue(response.size() >= 0);
for (Resource server : response) { for (Resource server : response) {

View File

@ -28,7 +28,7 @@ import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.json.BaseSetParserTest; import org.jclouds.json.BaseSetParserTest;
import org.jclouds.json.config.GsonModule; import org.jclouds.json.config.GsonModule;
import org.jclouds.openstack.nova.v2_0.config.NovaParserModule; import org.jclouds.openstack.nova.v2_0.config.NovaParserModule;
import org.jclouds.openstack.nova.v2_0.domain.Extension; import org.jclouds.openstack.v2_0.domain.Extension;
import org.jclouds.rest.annotations.SelectJson; import org.jclouds.rest.annotations.SelectJson;
import org.testng.annotations.Test; import org.testng.annotations.Test;

View File

@ -28,7 +28,7 @@ import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.json.BaseSetParserTest; import org.jclouds.json.BaseSetParserTest;
import org.jclouds.json.config.GsonModule; import org.jclouds.json.config.GsonModule;
import org.jclouds.openstack.nova.v2_0.config.NovaParserModule; import org.jclouds.openstack.nova.v2_0.config.NovaParserModule;
import org.jclouds.openstack.nova.v2_0.domain.Extension; import org.jclouds.openstack.v2_0.domain.Extension;
import org.jclouds.openstack.v2_0.domain.Link; import org.jclouds.openstack.v2_0.domain.Link;
import org.jclouds.openstack.v2_0.domain.Link.Relation; import org.jclouds.openstack.v2_0.domain.Link.Relation;
import org.jclouds.rest.annotations.SelectJson; import org.jclouds.rest.annotations.SelectJson;

View File

@ -27,7 +27,7 @@ import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.json.BaseItemParserTest; import org.jclouds.json.BaseItemParserTest;
import org.jclouds.json.config.GsonModule; import org.jclouds.json.config.GsonModule;
import org.jclouds.openstack.nova.v2_0.config.NovaParserModule; import org.jclouds.openstack.nova.v2_0.config.NovaParserModule;
import org.jclouds.openstack.nova.v2_0.domain.Extension; import org.jclouds.openstack.v2_0.domain.Extension;
import org.jclouds.openstack.v2_0.domain.Link; import org.jclouds.openstack.v2_0.domain.Link;
import org.jclouds.openstack.v2_0.domain.Link.Relation; import org.jclouds.openstack.v2_0.domain.Link.Relation;
import org.jclouds.rest.annotations.SelectJson; import org.jclouds.rest.annotations.SelectJson;

View File

@ -36,7 +36,6 @@ import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nullable;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.jclouds.apis.BaseViewLiveTest; import org.jclouds.apis.BaseViewLiveTest;
@ -48,6 +47,7 @@ import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.domain.StorageType; import org.jclouds.blobstore.domain.StorageType;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.javax.annotation.Nullable;
import org.testng.ITestContext; import org.testng.ITestContext;
import org.testng.annotations.AfterClass; import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;

View File

@ -27,12 +27,11 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.annotation.Nullable;
import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.StorageMetadata; import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.util.Strings2; import org.jclouds.util.Strings2;
import org.testng.SkipException; import org.testng.SkipException;
import org.testng.annotations.Test; import org.testng.annotations.Test;

View File

@ -205,6 +205,22 @@ public abstract class BaseTemplateBuilderLiveTest extends BaseComputeServiceCont
|| location.getParent().getIso3166Codes().containsAll(location.getIso3166Codes()) : location + " ||" || location.getParent().getIso3166Codes().containsAll(location.getIso3166Codes()) : location + " ||"
+ location.getParent(); + location.getParent();
break; break;
case SYSTEM:
Location systemParent = location.getParent();
// loop up to root, which must be the provider
while (systemParent.getParent() != null) {
systemParent = systemParent.getParent();
}
assertProvider(systemParent);
break;
case NETWORK:
Location networkParent = location.getParent();
// loop up to root, which must be the provider
while (networkParent.getParent() != null) {
networkParent = networkParent.getParent();
}
assertProvider(networkParent);
break;
case HOST: case HOST:
Location provider2 = location.getParent().getParent().getParent(); Location provider2 = location.getParent().getParent().getParent();
// zone can be a direct descendant of provider // zone can be a direct descendant of provider

View File

@ -106,7 +106,7 @@
<dependency> <dependency>
<groupId>com.google.guava</groupId> <groupId>com.google.guava</groupId>
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
<version>12.0</version> <version>13.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.osgi</groupId> <groupId>org.osgi</groupId>

View File

@ -86,6 +86,40 @@ public class LocationPredicates {
} }
} }
public static Predicate<Location> isSystem() {
return IsSystem.INSTANCE;
}
static enum IsSystem implements Predicate<Location> {
INSTANCE;
@Override
public boolean apply(Location input) {
return input.getScope() == LocationScope.SYSTEM;
}
@Override
public String toString() {
return "isSystem()";
}
}
public static Predicate<Location> isNetwork() {
return IsNetwork.INSTANCE;
}
static enum IsNetwork implements Predicate<Location> {
INSTANCE;
@Override
public boolean apply(Location input) {
return input.getScope() == LocationScope.NETWORK;
}
@Override
public String toString() {
return "isNetwork()";
}
}
public static Predicate<Location> idEquals(String id) { public static Predicate<Location> idEquals(String id) {
return new IdEquals(id); return new IdEquals(id);
} }

View File

@ -0,0 +1,67 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.location.suppliers.implicit;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.find;
import static com.google.common.collect.Iterables.transform;
import static org.jclouds.location.predicates.LocationPredicates.isNetwork;
import java.util.NoSuchElementException;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.collect.Memoized;
import org.jclouds.domain.Location;
import org.jclouds.location.functions.ToIdAndScope;
import org.jclouds.location.suppliers.ImplicitLocationSupplier;
import com.google.common.base.Supplier;
/**
*
* @author Dies Koper
*
*/
@Singleton
public class FirstNetwork implements ImplicitLocationSupplier {
private final Supplier<Set<? extends Location>> locationsSupplier;
@Inject
FirstNetwork(@Memoized Supplier<Set<? extends Location>> locationsSupplier) {
this.locationsSupplier = checkNotNull(locationsSupplier,
"locationsSupplierSupplier");
}
@Override
public Location get() {
Set<? extends Location> locations = locationsSupplier.get();
try {
return find(locations, isNetwork());
} catch (NoSuchElementException e) {
throw new NoSuchElementException(
"none of the locations are scope NETWORK: "
+ transform(locations, ToIdAndScope.INSTANCE));
}
}
}

View File

@ -20,6 +20,8 @@ package org.jclouds.util;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import com.google.common.base.Optional; import com.google.common.base.Optional;
@ -35,7 +37,11 @@ public class Optionals2 {
if (optional) { if (optional) {
ParameterizedType futureType = ParameterizedType.class.cast(method.getGenericReturnType()); ParameterizedType futureType = ParameterizedType.class.cast(method.getGenericReturnType());
// TODO: error checking in case this is a type, not a class. // TODO: error checking in case this is a type, not a class.
syncClass = Class.class.cast(futureType.getActualTypeArguments()[0]); Type t = futureType.getActualTypeArguments()[0];
if (t instanceof WildcardType) {
t = ((WildcardType) t).getUpperBounds()[0];
}
syncClass = Class.class.cast(t);
} else { } else {
syncClass = method.getReturnType(); syncClass = method.getReturnType();
} }

View File

@ -0,0 +1,71 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.location.suppliers.implicit;
import static org.testng.Assert.assertEquals;
import java.util.NoSuchElementException;
import java.util.Set;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationBuilder;
import org.jclouds.domain.LocationScope;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableSet;
/**
* Tests behavior of {@code FirstNetwork}
*
* @author Adrian Cole
* @author Dies Koper
*/
@Test(groups = "unit", testName = "FirstNetworkTest")
public class FirstNetworkTest {
Location provider = new LocationBuilder().scope(LocationScope.PROVIDER).id("servo").description("http://servo")
.build();
Location region = new LocationBuilder().scope(LocationScope.REGION).id("servo-r").description("http://r.servo")
.parent(provider).build();
Location network = new LocationBuilder().scope(LocationScope.NETWORK).id("servo-n").description("http://z.r.servo")
.parent(region).build();
@Test
public void testDidntFindNetworkThrowsNSEEWithReasonableMessage() {
Supplier<Set<? extends Location>> supplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(provider, region));
FirstNetwork fn = new FirstNetwork(supplier);
try {
fn.get();
assert false;
} catch (NoSuchElementException e) {
assertEquals(e.getMessage(), "none of the locations are scope NETWORK: [servo:PROVIDER, servo-r:REGION]");
}
}
@Test
public void testFirstNetwork() {
Supplier<Set<? extends Location>> supplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(provider, region, network));
FirstNetwork fn = new FirstNetwork(supplier);
assertEquals(fn.get(), network);
}
}

View File

@ -21,13 +21,12 @@ package org.jclouds.elb;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
import org.jclouds.elb.features.AvailabilityZoneApi;
import org.jclouds.elb.features.InstanceApi; import org.jclouds.elb.features.InstanceApi;
import org.jclouds.elb.features.LoadBalancerApi; import org.jclouds.elb.features.LoadBalancerApi;
import org.jclouds.elb.features.PolicyApi; import org.jclouds.elb.features.PolicyApi;
import org.jclouds.elb.features.AvailabilityZoneApi; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Region; import org.jclouds.location.Region;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;

View File

@ -20,13 +20,12 @@ package org.jclouds.elb;
import java.util.Set; import java.util.Set;
import javax.annotation.Nullable;
import org.jclouds.aws.filters.FormSigner; import org.jclouds.aws.filters.FormSigner;
import org.jclouds.elb.features.AvailabilityZoneAsyncApi;
import org.jclouds.elb.features.InstanceAsyncApi; import org.jclouds.elb.features.InstanceAsyncApi;
import org.jclouds.elb.features.LoadBalancerAsyncApi; import org.jclouds.elb.features.LoadBalancerAsyncApi;
import org.jclouds.elb.features.PolicyAsyncApi; import org.jclouds.elb.features.PolicyAsyncApi;
import org.jclouds.elb.features.AvailabilityZoneAsyncApi; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Region; import org.jclouds.location.Region;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;

View File

@ -23,8 +23,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.annotation.Nullable;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
@ -135,7 +133,7 @@ public class PolicyType {
return Maps.uniqueIndex(attributeMetadata, new Function<AttributeMetadata<?>, String>(){ return Maps.uniqueIndex(attributeMetadata, new Function<AttributeMetadata<?>, String>(){
@Override @Override
public String apply(@Nullable AttributeMetadata<?> input) { public String apply(AttributeMetadata<?> input) {
return input.getName(); return input.getName();
} }

View File

@ -22,8 +22,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Set; import java.util.Set;
import javax.annotation.Nullable;
import org.jclouds.elb.domain.AttributeMetadata; import org.jclouds.elb.domain.AttributeMetadata;
import org.jclouds.elb.domain.Policy; import org.jclouds.elb.domain.Policy;
import org.jclouds.elb.domain.PolicyType; import org.jclouds.elb.domain.PolicyType;
@ -95,7 +93,7 @@ public class PolicyApiLiveTest extends BaseELBApiLiveTest {
Iterable<String> names = Iterables.transform(response, new Function<PolicyType, String>() { Iterable<String> names = Iterables.transform(response, new Function<PolicyType, String>() {
@Override @Override
public String apply(@Nullable PolicyType input) { public String apply(PolicyType input) {
return input.getName(); return input.getName();
} }

View File

@ -19,8 +19,6 @@
package org.jclouds.nodepool.config; package org.jclouds.nodepool.config;
import javax.annotation.Nullable;
import org.jclouds.apis.ApiMetadata; import org.jclouds.apis.ApiMetadata;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.config.JCloudsNativeComputeServiceAdapterContextModule; import org.jclouds.compute.config.JCloudsNativeComputeServiceAdapterContextModule;
@ -30,6 +28,7 @@ import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.domain.LoginCredentials; import org.jclouds.domain.LoginCredentials;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.nodepool.NodePoolApiMetadata; import org.jclouds.nodepool.NodePoolApiMetadata;
import org.jclouds.nodepool.NodePoolComputeServiceAdapter; import org.jclouds.nodepool.NodePoolComputeServiceAdapter;
import org.jclouds.nodepool.NodePoolComputeServiceContext; import org.jclouds.nodepool.NodePoolComputeServiceContext;

View File

@ -26,6 +26,7 @@ import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Region; import org.jclouds.location.Region;
import org.jclouds.location.functions.RegionToEndpoint; import org.jclouds.location.functions.RegionToEndpoint;
import org.jclouds.openstack.glance.v1_0.features.ImageApi; import org.jclouds.openstack.glance.v1_0.features.ImageApi;
import org.jclouds.openstack.v2_0.features.ExtensionApi;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.EndpointParam;
@ -49,6 +50,13 @@ public interface GlanceApi {
@Region @Region
Set<String> getConfiguredRegions(); Set<String> getConfiguredRegions();
/**
* Provides synchronous access to Extension features.
*/
@Delegate
ExtensionApi getExtensionApiForRegion(
@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
/** /**
* Provides synchronous access to Image features. * Provides synchronous access to Image features.
*/ */

View File

@ -24,6 +24,7 @@ import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Region; import org.jclouds.location.Region;
import org.jclouds.location.functions.RegionToEndpoint; import org.jclouds.location.functions.RegionToEndpoint;
import org.jclouds.openstack.glance.v1_0.features.ImageAsyncApi; import org.jclouds.openstack.glance.v1_0.features.ImageAsyncApi;
import org.jclouds.openstack.v2_0.features.ExtensionAsyncApi;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.EndpointParam;
@ -46,6 +47,13 @@ public interface GlanceAsyncApi {
@Region @Region
Set<String> getConfiguredRegions(); Set<String> getConfiguredRegions();
/**
* Provides asynchronous access to Extension features.
*/
@Delegate
ExtensionAsyncApi getExtensionApiForRegion(
@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
/** /**
* Provides asynchronous access to Image features. * Provides asynchronous access to Image features.
*/ */

View File

@ -18,7 +18,13 @@
*/ */
package org.jclouds.openstack.glance.v1_0.config; package org.jclouds.openstack.glance.v1_0.config;
import java.net.URI;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.inject.Provider;
import javax.inject.Singleton;
import org.jclouds.http.HttpErrorHandler; import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.annotation.ClientError; import org.jclouds.http.annotation.ClientError;
@ -26,15 +32,27 @@ import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError; import org.jclouds.http.annotation.ServerError;
import org.jclouds.json.config.GsonModule.DateAdapter; import org.jclouds.json.config.GsonModule.DateAdapter;
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter; import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import org.jclouds.openstack.glance.v1_0.GlanceAsyncApi;
import org.jclouds.openstack.glance.v1_0.GlanceApi; import org.jclouds.openstack.glance.v1_0.GlanceApi;
import org.jclouds.openstack.glance.v1_0.features.ImageAsyncApi; import org.jclouds.openstack.glance.v1_0.GlanceAsyncApi;
import org.jclouds.openstack.glance.v1_0.features.ImageApi; import org.jclouds.openstack.glance.v1_0.features.ImageApi;
import org.jclouds.openstack.glance.v1_0.features.ImageAsyncApi;
import org.jclouds.openstack.glance.v1_0.handlers.GlanceErrorHandler; import org.jclouds.openstack.glance.v1_0.handlers.GlanceErrorHandler;
import org.jclouds.openstack.v2_0.domain.Extension;
import org.jclouds.openstack.v2_0.features.ExtensionApi;
import org.jclouds.openstack.v2_0.features.ExtensionAsyncApi;
import org.jclouds.openstack.v2_0.functions.PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.config.RestClientModule;
import org.jclouds.rest.functions.ImplicitOptionalConverter;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import com.google.common.reflect.TypeToken;
import com.google.inject.Provides;
/** /**
* Configures the Glance connection. * Configures the Glance connection.
@ -42,22 +60,47 @@ import com.google.common.collect.ImmutableMap;
* @author Adrian Cole * @author Adrian Cole
*/ */
@ConfiguresRestClient @ConfiguresRestClient
public class GlanceRestClientModule extends RestClientModule<GlanceApi, GlanceAsyncApi> { public class GlanceRestClientModule<S extends GlanceApi, A extends GlanceAsyncApi> extends RestClientModule<S, A> {
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder() public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()
.put(ExtensionApi.class, ExtensionAsyncApi.class)
.put(ImageApi.class, ImageAsyncApi.class) .put(ImageApi.class, ImageAsyncApi.class)
.build(); .build();
public GlanceRestClientModule() { public GlanceRestClientModule() {
super(DELEGATE_MAP); super(TypeToken.class.cast(TypeToken.of(GlanceApi.class)), TypeToken.class.cast(TypeToken.of(GlanceAsyncApi.class)), DELEGATE_MAP);
}
protected GlanceRestClientModule(TypeToken<S> syncClientType, TypeToken<A> asyncClientType, Map<Class<?>, Class<?>> sync2Async) {
super(syncClientType, asyncClientType, sync2Async);
} }
@Override @Override
protected void configure() { protected void configure() {
bind(DateAdapter.class).to(Iso8601DateAdapter.class); bind(DateAdapter.class).to(Iso8601DateAdapter.class);
bind(ImplicitOptionalConverter.class).to(PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.class);
super.configure(); super.configure();
} }
@Provides
@Singleton
public Multimap<URI, URI> aliases() {
return ImmutableMultimap.<URI, URI>builder()
.build();
}
@Provides
@Singleton
public LoadingCache<String, Set<? extends Extension>> provideExtensionsByZone(final Provider<GlanceApi> glanceApi) {
return CacheBuilder.newBuilder().expireAfterWrite(23, TimeUnit.HOURS)
.build(new CacheLoader<String, Set<? extends Extension>>() {
@Override
public Set<? extends Extension> load(String key) throws Exception {
return glanceApi.get().getExtensionApiForRegion(key).listExtensions();
}
});
}
@Override @Override
protected void bindErrorHandlers() { protected void bindErrorHandlers() {
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(GlanceErrorHandler.class); bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(GlanceErrorHandler.class);

Some files were not shown because too many files have changed in this diff Show More