mirror of https://github.com/apache/jclouds.git
Issue 327: added URI option for getting VDC
This commit is contained in:
parent
7e5fb14f60
commit
7f38672a4c
|
@ -28,6 +28,8 @@ import static org.jclouds.vcloud.VCloudMediaType.VAPPTEMPLATE_XML;
|
|||
import static org.jclouds.vcloud.VCloudMediaType.VAPP_XML;
|
||||
import static org.jclouds.vcloud.VCloudMediaType.VDC_XML;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
|
@ -184,8 +186,9 @@ public interface VCloudAsyncClient {
|
|||
ListenableFuture<? extends VDC> getDefaultVDC();
|
||||
|
||||
/**
|
||||
* @see VCloudClient#getVDC
|
||||
* @see VCloudClient#getVDC(String)
|
||||
*/
|
||||
@Deprecated
|
||||
@GET
|
||||
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
|
||||
@Path("/vdc/{vDCId}")
|
||||
|
@ -194,6 +197,15 @@ public interface VCloudAsyncClient {
|
|||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends VDC> getVDC(@PathParam("vDCId") String vDCId);
|
||||
|
||||
/**
|
||||
* @see VCloudClient#getVDC(URI)
|
||||
*/
|
||||
@GET
|
||||
@XMLResponseParser(VDCHandler.class)
|
||||
@Consumes(VDC_XML)
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends VDC> getVDC(@EndpointParam URI vDCId);
|
||||
|
||||
/**
|
||||
* @see VCloudClient#getTasksList
|
||||
*/
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.vcloud;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
|
@ -37,8 +38,7 @@ import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
|
|||
* Provides access to VCloud resources via their REST API.
|
||||
* <p/>
|
||||
*
|
||||
* @see <a href="https://community.vcloudexpress.terremark.com/en-us/discussion_forums/f/60.aspx"
|
||||
* />
|
||||
* @see <a href="https://community.vcloudexpress.terremark.com/en-us/discussion_forums/f/60.aspx" />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Timeout(duration = 300, timeUnit = TimeUnit.SECONDS)
|
||||
|
@ -56,8 +56,8 @@ public interface VCloudClient {
|
|||
Organization getOrganization(String orgId);
|
||||
|
||||
/**
|
||||
* This call returns a list of all vCloud Data Centers (vdcs), catalogs, and
|
||||
* task lists within the organization.
|
||||
* This call returns a list of all vCloud Data Centers (vdcs), catalogs, and task lists within
|
||||
* the organization.
|
||||
*
|
||||
* @param name
|
||||
* organization name, or null for the default
|
||||
|
@ -74,8 +74,14 @@ public interface VCloudClient {
|
|||
|
||||
Network getNetwork(String networkId);
|
||||
|
||||
/**
|
||||
* please use {@link #getVDC(URI)}
|
||||
*/
|
||||
@Deprecated
|
||||
VDC getVDC(String vDCId);
|
||||
|
||||
VDC getVDC(URI vdc);
|
||||
|
||||
VDC getDefaultVDC();
|
||||
|
||||
TasksList getTasksList(String tasksListId);
|
||||
|
@ -89,14 +95,12 @@ public interface VCloudClient {
|
|||
Task undeployVApp(String vAppId);
|
||||
|
||||
/**
|
||||
* This call powers on the vApp, as specified in the vApp's ovf:Startup
|
||||
* element.
|
||||
* This call powers on the vApp, as specified in the vApp's ovf:Startup element.
|
||||
*/
|
||||
Task powerOnVApp(String vAppId);
|
||||
|
||||
/**
|
||||
* This call powers off the vApp, as specified in the vApp's ovf:Startup
|
||||
* element.
|
||||
* This call powers off the vApp, as specified in the vApp's ovf:Startup element.
|
||||
*/
|
||||
Task powerOffVApp(String vAppId);
|
||||
|
||||
|
@ -122,7 +126,7 @@ public interface VCloudClient {
|
|||
VApp getVApp(String appId);
|
||||
|
||||
VApp instantiateVAppTemplateInVDC(String vDCId, String appName, String templateId,
|
||||
InstantiateVAppTemplateOptions... options);
|
||||
InstantiateVAppTemplateOptions... options);
|
||||
|
||||
Task cloneVAppInVDC(String vDCId, String vAppIdToClone, String newName, CloneVAppOptions... options);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_TIMEO
|
|||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.SortedMap;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
@ -81,15 +82,14 @@ import com.google.inject.Provides;
|
|||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Configures the VCloud authentication service connection, including logging
|
||||
* and http transport.
|
||||
* Configures the VCloud authentication service connection, including logging and http transport.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@RequiresHttp
|
||||
@ConfiguresRestClient
|
||||
public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A extends VCloudAsyncClient> extends
|
||||
RestClientModule<S, A> {
|
||||
RestClientModule<S, A> {
|
||||
|
||||
public BaseVCloudRestClientModule(Class<S> syncClientType, Class<A> asyncClientType) {
|
||||
super(syncClientType, asyncClientType);
|
||||
|
@ -110,7 +110,7 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
|
|||
@Provides
|
||||
@Singleton
|
||||
protected Predicate<String> successTester(TaskSuccess success,
|
||||
@Named(PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED) long completed) {
|
||||
@Named(PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED) long completed) {
|
||||
return new RetryablePredicate<String>(success, completed);
|
||||
}
|
||||
|
||||
|
@ -135,16 +135,43 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
|
|||
}
|
||||
|
||||
@Provides
|
||||
@Named("VDC_TO_ORG")
|
||||
@Singleton
|
||||
protected Map<String, String> provideVDCtoORG(@Org Iterable<NamedResource> orgs, VCloudClient client) {
|
||||
Map<String, String> returnVal = Maps.newLinkedHashMap();
|
||||
for (NamedResource orgr : orgs) {
|
||||
for (NamedResource vdc : client.getOrganizationNamed(orgr.getName()).getVDCs().values()) {
|
||||
returnVal.put(vdc.getId(), orgr.getName());
|
||||
}
|
||||
}
|
||||
return returnVal;
|
||||
@VDC
|
||||
protected Supplier<Map<String, String>> provideVDCtoORG(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
|
||||
final @VDC Supplier<Map<String, Map<String, NamedResource>>> orgToVDCSupplier) {
|
||||
return Suppliers.memoizeWithExpiration(new RetryOnTimeOutExceptionSupplier<Map<String, String>>(
|
||||
new Supplier<Map<String, String>>() {
|
||||
public Map<String, String> get() {
|
||||
// http://code.google.com/p/google-guice/issues/detail?id=483
|
||||
// guice doesn't remember when singleton providers throw
|
||||
// exceptions.
|
||||
// in this case, if describeRegions fails, it is called
|
||||
// again for
|
||||
// each provider method that depends on it. To
|
||||
// short-circuit this,
|
||||
// we remember the last exception trusting that guice is
|
||||
// single-threaded
|
||||
if (authException != null)
|
||||
throw authException;
|
||||
try {
|
||||
Map<String, String> returnVal = Maps.newLinkedHashMap();
|
||||
for (Entry<String, Map<String, NamedResource>> orgr : orgToVDCSupplier.get().entrySet()) {
|
||||
for (String vdc : orgr.getValue().keySet()) {
|
||||
returnVal.put(vdc, orgr.getKey());
|
||||
}
|
||||
}
|
||||
return returnVal;
|
||||
} catch (AuthorizationException e) {
|
||||
authException = e;
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
assert false : e;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}), seconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
@ -168,41 +195,99 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
|
|||
@Provides
|
||||
@Singleton
|
||||
protected Supplier<VCloudSession> provideVCloudTokenCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
|
||||
final VCloudLoginAsyncClient login) {
|
||||
final VCloudLoginAsyncClient login) {
|
||||
return Suppliers.memoizeWithExpiration(new RetryOnTimeOutExceptionSupplier<VCloudSession>(
|
||||
new Supplier<VCloudSession>() {
|
||||
public VCloudSession get() {
|
||||
// http://code.google.com/p/google-guice/issues/detail?id=483
|
||||
// guice doesn't remember when singleton providers throw
|
||||
// exceptions.
|
||||
// in this case, if describeRegions fails, it is called
|
||||
// again for
|
||||
// each provider method that depends on it. To
|
||||
// short-circuit this,
|
||||
// we remember the last exception trusting that guice is
|
||||
// single-threaded
|
||||
if (authException != null)
|
||||
throw authException;
|
||||
try {
|
||||
return login.login().get(10, TimeUnit.SECONDS);
|
||||
} catch (AuthorizationException e) {
|
||||
BaseVCloudRestClientModule.this.authException = e;
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
assert false : e;
|
||||
return null;
|
||||
new Supplier<VCloudSession>() {
|
||||
public VCloudSession get() {
|
||||
// http://code.google.com/p/google-guice/issues/detail?id=483
|
||||
// guice doesn't remember when singleton providers throw
|
||||
// exceptions.
|
||||
// in this case, if describeRegions fails, it is called
|
||||
// again for
|
||||
// each provider method that depends on it. To
|
||||
// short-circuit this,
|
||||
// we remember the last exception trusting that guice is
|
||||
// single-threaded
|
||||
if (authException != null)
|
||||
throw authException;
|
||||
try {
|
||||
return login.login().get(10, TimeUnit.SECONDS);
|
||||
} catch (AuthorizationException e) {
|
||||
BaseVCloudRestClientModule.this.authException = e;
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
assert false : e;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}), seconds, TimeUnit.SECONDS);
|
||||
}), seconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@VDC
|
||||
protected Supplier<Map<String, Map<String, NamedResource>>> provideOrgToVDCCache(
|
||||
@Named(PROPERTY_SESSION_INTERVAL) long seconds, final OrgNameToVDCSupplier supplier) {
|
||||
return Suppliers.memoizeWithExpiration(
|
||||
new RetryOnTimeOutExceptionSupplier<Map<String, Map<String, NamedResource>>>(
|
||||
new Supplier<Map<String, Map<String, NamedResource>>>() {
|
||||
public Map<String, Map<String, NamedResource>> get() {
|
||||
// http://code.google.com/p/google-guice/issues/detail?id=483
|
||||
// guice doesn't remember when singleton providers throw
|
||||
// exceptions.
|
||||
// in this case, if describeRegions fails, it is called
|
||||
// again for
|
||||
// each provider method that depends on it. To
|
||||
// short-circuit this,
|
||||
// we remember the last exception trusting that guice is
|
||||
// single-threaded
|
||||
if (authException != null)
|
||||
throw authException;
|
||||
try {
|
||||
return supplier.get();
|
||||
} catch (AuthorizationException e) {
|
||||
authException = e;
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
assert false : e;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}), seconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class OrgNameToVDCSupplier implements Supplier<Map<String, Map<String, NamedResource>>> {
|
||||
protected final Supplier<VCloudSession> sessionSupplier;
|
||||
private final VCloudClient client;
|
||||
|
||||
@Inject
|
||||
protected OrgNameToVDCSupplier(Supplier<VCloudSession> sessionSupplier, VCloudClient client) {
|
||||
this.sessionSupplier = sessionSupplier;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Map<String, NamedResource>> get() {
|
||||
Map<String, Map<String, NamedResource>> returnVal = Maps.newLinkedHashMap();
|
||||
for (String orgName : sessionSupplier.get().getOrgs().keySet()) {
|
||||
returnVal.put(orgName, client.getOrganizationNamed(orgName).getVDCs());
|
||||
}
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@org.jclouds.vcloud.endpoints.VCloudLogin
|
||||
protected URI provideAuthenticationURI(VCloudVersionsAsyncClient versionService,
|
||||
@Named(PROPERTY_API_VERSION) String version) throws InterruptedException, ExecutionException, TimeoutException {
|
||||
@Named(PROPERTY_API_VERSION) String version) throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
SortedMap<String, URI> versions = versionService.getSupportedVersions().get(180, TimeUnit.SECONDS);
|
||||
checkState(versions.size() > 0, "No versions present");
|
||||
checkState(versions.containsKey(version), "version " + version + " not present in: " + versions);
|
||||
|
@ -262,7 +347,7 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
|
|||
@Provides
|
||||
@Singleton
|
||||
protected Organization provideOrganization(VCloudClient discovery) throws ExecutionException, TimeoutException,
|
||||
InterruptedException {
|
||||
InterruptedException {
|
||||
if (authException != null)
|
||||
throw authException;
|
||||
try {
|
||||
|
@ -293,7 +378,7 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
|
|||
@Network
|
||||
@Singleton
|
||||
protected URI provideDefaultNetwork(VCloudClient client) throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
TimeoutException {
|
||||
if (authException != null)
|
||||
throw authException;
|
||||
try {
|
||||
|
|
|
@ -306,7 +306,7 @@ public class VCloudAsyncClientTest extends RestClientTest<VCloudAsyncClient> {
|
|||
checkFilters(request);
|
||||
}
|
||||
|
||||
public void testGetVDC() throws SecurityException, NoSuchMethodException, IOException {
|
||||
public void testGetVDCString() throws SecurityException, NoSuchMethodException, IOException {
|
||||
Method method = VCloudAsyncClient.class.getMethod("getVDC", String.class);
|
||||
HttpRequest request = processor.createRequest(method, "1");
|
||||
|
||||
|
@ -321,6 +321,21 @@ public class VCloudAsyncClientTest extends RestClientTest<VCloudAsyncClient> {
|
|||
checkFilters(request);
|
||||
}
|
||||
|
||||
public void testGetVDCURI() throws SecurityException, NoSuchMethodException, IOException {
|
||||
Method method = VCloudAsyncClient.class.getMethod("getVDC", URI.class);
|
||||
HttpRequest request = processor.createRequest(method, URI.create("https://vcloud.safesecureweb.com/api/v0.8/vdc/1"));
|
||||
|
||||
assertRequestLineEquals(request, "GET https://vcloud.safesecureweb.com/api/v0.8/vdc/1 HTTP/1.1");
|
||||
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vdc+xml\n");
|
||||
assertPayloadEquals(request, null, null, false);
|
||||
|
||||
assertResponseParserClassEquals(method, request, ParseSax.class);
|
||||
assertSaxResponseParserClassEquals(method, VDCHandler.class);
|
||||
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
|
||||
|
||||
checkFilters(request);
|
||||
}
|
||||
|
||||
public void testGetDefaultTasksList() throws SecurityException, NoSuchMethodException, IOException {
|
||||
Method method = VCloudAsyncClient.class.getMethod("getDefaultTasksList");
|
||||
HttpRequest request = processor.createRequest(method);
|
||||
|
|
|
@ -28,9 +28,11 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.vcloud.endpoints.VDC;
|
||||
import org.jclouds.vcloud.terremark.compute.domain.OrgAndName;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -38,27 +40,25 @@ import com.google.common.base.Function;
|
|||
*
|
||||
*/
|
||||
@Singleton
|
||||
public class NodeMetadataToOrgAndName implements
|
||||
Function<NodeMetadata, OrgAndName> {
|
||||
public class NodeMetadataToOrgAndName implements Function<NodeMetadata, OrgAndName> {
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
final Map<String, String> vdcToOrg;
|
||||
final Supplier<Map<String, String>> vdcToOrg;
|
||||
|
||||
@Inject
|
||||
NodeMetadataToOrgAndName(@Named("VDC_TO_ORG") Map<String, String> vdcToOrg) {
|
||||
NodeMetadataToOrgAndName(@VDC Supplier<Map<String, String>> vdcToOrg) {
|
||||
this.vdcToOrg = vdcToOrg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrgAndName apply(NodeMetadata from) {
|
||||
if (from.getTag() != null) {
|
||||
String org = vdcToOrg.get(from.getLocation().getId());
|
||||
String org = vdcToOrg.get().get(from.getLocation().getId());
|
||||
if (org == null) {
|
||||
logger.warn("did not find an association for vdc %s in %s", from
|
||||
.getLocation().getId(), vdcToOrg);
|
||||
logger.warn("did not find an association for vdc %s in %s", from.getLocation().getId(), vdcToOrg);
|
||||
} else {
|
||||
return new OrgAndName(org, from.getTag());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue