mirror of https://github.com/apache/jclouds.git
Issue 112: added cloneVApp and getPublicIp
git-svn-id: http://jclouds.googlecode.com/svn/trunk@2490 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
8068e4e0e5
commit
bdb38fdf23
|
@ -48,6 +48,7 @@ import org.jclouds.rest.annotations.MapPayloadParam;
|
||||||
import org.jclouds.rest.annotations.ParamParser;
|
import org.jclouds.rest.annotations.ParamParser;
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.annotations.XMLResponseParser;
|
import org.jclouds.rest.annotations.XMLResponseParser;
|
||||||
|
import org.jclouds.vcloud.binders.BindCloneVAppParamsToXmlPayload;
|
||||||
import org.jclouds.vcloud.binders.BindInstantiateVAppTemplateParamsToXmlPayload;
|
import org.jclouds.vcloud.binders.BindInstantiateVAppTemplateParamsToXmlPayload;
|
||||||
import org.jclouds.vcloud.domain.Catalog;
|
import org.jclouds.vcloud.domain.Catalog;
|
||||||
import org.jclouds.vcloud.domain.CatalogItem;
|
import org.jclouds.vcloud.domain.CatalogItem;
|
||||||
|
@ -60,7 +61,9 @@ import org.jclouds.vcloud.domain.VAppTemplate;
|
||||||
import org.jclouds.vcloud.domain.VDC;
|
import org.jclouds.vcloud.domain.VDC;
|
||||||
import org.jclouds.vcloud.endpoints.Org;
|
import org.jclouds.vcloud.endpoints.Org;
|
||||||
import org.jclouds.vcloud.filters.SetVCloudTokenCookie;
|
import org.jclouds.vcloud.filters.SetVCloudTokenCookie;
|
||||||
|
import org.jclouds.vcloud.functions.VAppIdToUri;
|
||||||
import org.jclouds.vcloud.functions.VAppTemplateIdToUri;
|
import org.jclouds.vcloud.functions.VAppTemplateIdToUri;
|
||||||
|
import org.jclouds.vcloud.options.CloneVAppOptions;
|
||||||
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
|
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
|
||||||
import org.jclouds.vcloud.xml.CatalogHandler;
|
import org.jclouds.vcloud.xml.CatalogHandler;
|
||||||
import org.jclouds.vcloud.xml.CatalogItemHandler;
|
import org.jclouds.vcloud.xml.CatalogItemHandler;
|
||||||
|
@ -238,4 +241,15 @@ public interface VCloudAsyncClient {
|
||||||
@MapPayloadParam("name") String appName,
|
@MapPayloadParam("name") String appName,
|
||||||
@MapPayloadParam("template") @ParamParser(VAppTemplateIdToUri.class) String templateId,
|
@MapPayloadParam("template") @ParamParser(VAppTemplateIdToUri.class) String templateId,
|
||||||
InstantiateVAppTemplateOptions... options);
|
InstantiateVAppTemplateOptions... options);
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
|
||||||
|
@Path("/vdc/{vDCId}/action/cloneVApp")
|
||||||
|
@Produces("application/vnd.vmware.vcloud.cloneVAppParams+xml")
|
||||||
|
@Consumes(TASK_XML)
|
||||||
|
@XMLResponseParser(TaskHandler.class)
|
||||||
|
@MapBinder(BindCloneVAppParamsToXmlPayload.class)
|
||||||
|
Future<? extends Task> cloneVAppInVDC(@PathParam("vDCId") String vDCId,
|
||||||
|
@MapPayloadParam("vApp") @ParamParser(VAppIdToUri.class) String vAppIdToClone,
|
||||||
|
@MapPayloadParam("newName") String newName, CloneVAppOptions... options);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.jclouds.vcloud.domain.TasksList;
|
||||||
import org.jclouds.vcloud.domain.VApp;
|
import org.jclouds.vcloud.domain.VApp;
|
||||||
import org.jclouds.vcloud.domain.VAppTemplate;
|
import org.jclouds.vcloud.domain.VAppTemplate;
|
||||||
import org.jclouds.vcloud.domain.VDC;
|
import org.jclouds.vcloud.domain.VDC;
|
||||||
|
import org.jclouds.vcloud.options.CloneVAppOptions;
|
||||||
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
|
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -107,4 +108,7 @@ public interface VCloudClient {
|
||||||
|
|
||||||
VApp instantiateVAppTemplateInVDC(String vDCId, String appName, String templateId,
|
VApp instantiateVAppTemplateInVDC(String vDCId, String appName, String templateId,
|
||||||
InstantiateVAppTemplateOptions... options);
|
InstantiateVAppTemplateOptions... options);
|
||||||
|
|
||||||
|
Task cloneVAppInVDC(String vDCId, String vAppIdToClone, String newName,
|
||||||
|
CloneVAppOptions... options);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF 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.vcloud.binders;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_NAMESPACE;
|
||||||
|
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_SCHEMA;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import javax.xml.parsers.FactoryConfigurationError;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
import javax.xml.transform.TransformerException;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.rest.MapBinder;
|
||||||
|
import org.jclouds.rest.binders.BindToStringPayload;
|
||||||
|
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||||
|
import org.jclouds.vcloud.VCloudMediaType;
|
||||||
|
import org.jclouds.vcloud.options.CloneVAppOptions;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.jamesmurty.utils.XMLBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class BindCloneVAppParamsToXmlPayload implements MapBinder {
|
||||||
|
|
||||||
|
protected final String ns;
|
||||||
|
protected final String schema;
|
||||||
|
private final BindToStringPayload stringBinder;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public BindCloneVAppParamsToXmlPayload(BindToStringPayload stringBinder,
|
||||||
|
@Named(PROPERTY_VCLOUD_XML_NAMESPACE) String ns,
|
||||||
|
@Named(PROPERTY_VCLOUD_XML_SCHEMA) String schema) {
|
||||||
|
this.ns = ns;
|
||||||
|
this.schema = schema;
|
||||||
|
this.stringBinder = stringBinder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void bindToRequest(HttpRequest request, Map<String, String> postParams) {
|
||||||
|
checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest,
|
||||||
|
"this binder is only valid for GeneratedHttpRequests!");
|
||||||
|
GeneratedHttpRequest gRequest = (GeneratedHttpRequest) request;
|
||||||
|
checkState(gRequest.getArgs() != null, "args should be initialized at this point");
|
||||||
|
String newName = checkNotNull(postParams.remove("newName"), "newName");
|
||||||
|
String vApp = checkNotNull(postParams.remove("vApp"), "vApp");
|
||||||
|
|
||||||
|
CloneVAppOptions options = findOptionsInArgsOrNull(gRequest);
|
||||||
|
if (options == null) {
|
||||||
|
options = new CloneVAppOptions();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
stringBinder.bindToRequest(request, generateXml(newName, vApp, options));
|
||||||
|
} catch (ParserConfigurationException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} catch (FactoryConfigurationError e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} catch (TransformerException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String generateXml(String newName, String vApp, CloneVAppOptions options)
|
||||||
|
throws ParserConfigurationException, FactoryConfigurationError, TransformerException {
|
||||||
|
XMLBuilder rootBuilder = buildRoot(newName, options.isDeploy(), options.isPowerOn());
|
||||||
|
if (options.getDescription() != null)
|
||||||
|
rootBuilder.e("Description").text(options.getDescription());
|
||||||
|
rootBuilder.e("VApp").a("href", vApp).a("type", VCloudMediaType.VAPP_XML);
|
||||||
|
Properties outputProperties = new Properties();
|
||||||
|
outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
|
||||||
|
return rootBuilder.asString(outputProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected XMLBuilder buildRoot(String name, boolean deploy, boolean powerOn)
|
||||||
|
throws ParserConfigurationException, FactoryConfigurationError {
|
||||||
|
XMLBuilder rootBuilder = XMLBuilder.create("CloneVAppParams").a("name", name).a("deploy",
|
||||||
|
deploy+"").a("powerOn", powerOn+"").a("xmlns", ns).a("xmlns:xsi",
|
||||||
|
"http://www.w3.org/2001/XMLSchema-instance").a("xsi:schemaLocation",
|
||||||
|
ns + " " + schema);
|
||||||
|
return rootBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CloneVAppOptions findOptionsInArgsOrNull(GeneratedHttpRequest<?> gRequest) {
|
||||||
|
for (Object arg : gRequest.getArgs()) {
|
||||||
|
if (arg instanceof CloneVAppOptions) {
|
||||||
|
return (CloneVAppOptions) arg;
|
||||||
|
} else if (arg instanceof CloneVAppOptions[]) {
|
||||||
|
CloneVAppOptions[] options = (CloneVAppOptions[]) arg;
|
||||||
|
return (options.length > 0) ? options[0] : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bindToRequest(HttpRequest request, Object input) {
|
||||||
|
throw new IllegalStateException("CloneVAppParams is needs parameters");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String ifNullDefaultTo(String value, String defaultValue) {
|
||||||
|
return value != null ? value : checkNotNull(defaultValue, "defaultValue");
|
||||||
|
}
|
||||||
|
}
|
|
@ -48,6 +48,7 @@ import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.rest.MapBinder;
|
import org.jclouds.rest.MapBinder;
|
||||||
import org.jclouds.rest.binders.BindToStringPayload;
|
import org.jclouds.rest.binders.BindToStringPayload;
|
||||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||||
|
import org.jclouds.vcloud.domain.FenceMode;
|
||||||
import org.jclouds.vcloud.domain.ResourceType;
|
import org.jclouds.vcloud.domain.ResourceType;
|
||||||
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
|
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
|
||||||
|
|
||||||
|
@ -189,7 +190,7 @@ public class BindInstantiateVAppTemplateParamsToXmlPayload implements MapBinder
|
||||||
XMLBuilder networkConfigBuilder = instantiationParamsBuilder.e("NetworkConfigSection").e(
|
XMLBuilder networkConfigBuilder = instantiationParamsBuilder.e("NetworkConfigSection").e(
|
||||||
"NetworkConfig").a("name", name);
|
"NetworkConfig").a("name", name);
|
||||||
XMLBuilder featuresBuilder = networkConfigBuilder.e("Features");
|
XMLBuilder featuresBuilder = networkConfigBuilder.e("Features");
|
||||||
featuresBuilder.e("FenceMode").t("allowInOut");
|
featuresBuilder.e("FenceMode").t(FenceMode.ALLOW_IN_OUT.value());
|
||||||
featuresBuilder.e("Dhcp").t("false");
|
featuresBuilder.e("Dhcp").t("false");
|
||||||
networkConfigBuilder.e("NetworkAssociation").a("href", network);
|
networkConfigBuilder.e("NetworkAssociation").a("href", network);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF 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.vcloud.options;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CloneVAppOptions {
|
||||||
|
|
||||||
|
private boolean deploy;
|
||||||
|
private boolean powerOn;
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the clone should be deployed after it is created
|
||||||
|
*/
|
||||||
|
public CloneVAppOptions deploy() {
|
||||||
|
this.deploy = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the clone should be powered on after it is deployed
|
||||||
|
*/
|
||||||
|
public CloneVAppOptions powerOn() {
|
||||||
|
checkState(deploy, "must set deploy before setting powerOn");
|
||||||
|
powerOn = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the clone should be powered on after it is deployed
|
||||||
|
*/
|
||||||
|
public CloneVAppOptions withDescription(String description) {
|
||||||
|
checkNotNull(description, "description");
|
||||||
|
this.description = description;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDeploy() {
|
||||||
|
return deploy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPowerOn() {
|
||||||
|
return powerOn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see CloneVAppOptions#deploy()
|
||||||
|
*/
|
||||||
|
public static CloneVAppOptions deploy() {
|
||||||
|
CloneVAppOptions options = new CloneVAppOptions();
|
||||||
|
return options.deploy();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see CloneVAppOptions#powerOn()
|
||||||
|
*/
|
||||||
|
public static CloneVAppOptions powerOn() {
|
||||||
|
CloneVAppOptions options = new CloneVAppOptions();
|
||||||
|
return options.powerOn();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see CloneVAppOptions#withDescription(String)
|
||||||
|
*/
|
||||||
|
public static CloneVAppOptions withDescription(String description) {
|
||||||
|
CloneVAppOptions options = new CloneVAppOptions();
|
||||||
|
return options.withDescription(description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -53,6 +53,7 @@ import org.jclouds.vcloud.endpoints.internal.CatalogItemRoot;
|
||||||
import org.jclouds.vcloud.endpoints.internal.VAppRoot;
|
import org.jclouds.vcloud.endpoints.internal.VAppRoot;
|
||||||
import org.jclouds.vcloud.endpoints.internal.VAppTemplateRoot;
|
import org.jclouds.vcloud.endpoints.internal.VAppTemplateRoot;
|
||||||
import org.jclouds.vcloud.filters.SetVCloudTokenCookie;
|
import org.jclouds.vcloud.filters.SetVCloudTokenCookie;
|
||||||
|
import org.jclouds.vcloud.options.CloneVAppOptions;
|
||||||
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
|
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
|
||||||
import org.jclouds.vcloud.xml.CatalogHandler;
|
import org.jclouds.vcloud.xml.CatalogHandler;
|
||||||
import org.jclouds.vcloud.xml.CatalogItemHandler;
|
import org.jclouds.vcloud.xml.CatalogItemHandler;
|
||||||
|
@ -124,6 +125,47 @@ public class VCloudAsyncClientTest extends RestClientTest<VCloudAsyncClient> {
|
||||||
checkFilters(httpMethod);
|
checkFilters(httpMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testCloneVApp() throws SecurityException, NoSuchMethodException, IOException {
|
||||||
|
Method method = VCloudAsyncClient.class.getMethod("cloneVAppInVDC", String.class,
|
||||||
|
String.class, String.class, Array.newInstance(CloneVAppOptions.class, 0).getClass());
|
||||||
|
GeneratedHttpRequest<VCloudAsyncClient> httpMethod = processor.createRequest(method, "1",
|
||||||
|
"4181", "New Name");
|
||||||
|
|
||||||
|
assertRequestLineEquals(httpMethod, "POST http://vcloud/vdc/1/action/cloneVApp HTTP/1.1");
|
||||||
|
assertHeadersEqual(
|
||||||
|
httpMethod,
|
||||||
|
"Accept: application/vnd.vmware.vcloud.task+xml\nContent-Length: 396\nContent-Type: application/vnd.vmware.vcloud.cloneVAppParams+xml\n");
|
||||||
|
assertPayloadEquals(httpMethod, Utils.toStringAndClose(getClass().getResourceAsStream(
|
||||||
|
"/cloneVApp-default.xml")));
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
|
||||||
|
assertSaxResponseParserClassEquals(method, TaskHandler.class);
|
||||||
|
assertExceptionParserClassEquals(method, null);
|
||||||
|
|
||||||
|
checkFilters(httpMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCloneVAppOptions() throws SecurityException, NoSuchMethodException, IOException {
|
||||||
|
Method method = VCloudAsyncClient.class.getMethod("cloneVAppInVDC", String.class,
|
||||||
|
String.class, String.class, Array.newInstance(CloneVAppOptions.class, 0).getClass());
|
||||||
|
GeneratedHttpRequest<VCloudAsyncClient> httpMethod = processor.createRequest(method, "1",
|
||||||
|
"201", "New Linux Server", new CloneVAppOptions().deploy().powerOn()
|
||||||
|
.withDescription("The description of the new vApp"));
|
||||||
|
|
||||||
|
assertRequestLineEquals(httpMethod, "POST http://vcloud/vdc/1/action/cloneVApp HTTP/1.1");
|
||||||
|
assertHeadersEqual(
|
||||||
|
httpMethod,
|
||||||
|
"Accept: application/vnd.vmware.vcloud.task+xml\nContent-Length: 459\nContent-Type: application/vnd.vmware.vcloud.cloneVAppParams+xml\n");
|
||||||
|
assertPayloadEquals(httpMethod, Utils.toStringAndClose(getClass().getResourceAsStream(
|
||||||
|
"/cloneVApp.xml")));
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
|
||||||
|
assertSaxResponseParserClassEquals(method, TaskHandler.class);
|
||||||
|
assertExceptionParserClassEquals(method, null);
|
||||||
|
|
||||||
|
checkFilters(httpMethod);
|
||||||
|
}
|
||||||
|
|
||||||
public void testOrganization() throws SecurityException, NoSuchMethodException, IOException {
|
public void testOrganization() throws SecurityException, NoSuchMethodException, IOException {
|
||||||
Method method = VCloudAsyncClient.class.getMethod("getOrganization");
|
Method method = VCloudAsyncClient.class.getMethod("getOrganization");
|
||||||
GeneratedHttpRequest<VCloudAsyncClient> httpMethod = processor.createRequest(method);
|
GeneratedHttpRequest<VCloudAsyncClient> httpMethod = processor.createRequest(method);
|
||||||
|
@ -454,7 +496,8 @@ public class VCloudAsyncClientTest extends RestClientTest<VCloudAsyncClient> {
|
||||||
.toInstance("http://catalogItem");
|
.toInstance("http://catalogItem");
|
||||||
bind(String.class).annotatedWith(VAppTemplateRoot.class).toInstance(
|
bind(String.class).annotatedWith(VAppTemplateRoot.class).toInstance(
|
||||||
"https://vcloud.safesecureweb.com/api/v0.8/vAppTemplate");
|
"https://vcloud.safesecureweb.com/api/v0.8/vAppTemplate");
|
||||||
bind(String.class).annotatedWith(VAppRoot.class).toInstance("http://vApps");
|
bind(String.class).annotatedWith(VAppRoot.class).toInstance(
|
||||||
|
"https://services.vcloudexpress.terremark.com/api/vapp");
|
||||||
bind(URI.class).annotatedWith(VDC.class).toInstance(URI.create("http://vdc"));
|
bind(URI.class).annotatedWith(VDC.class).toInstance(URI.create("http://vdc"));
|
||||||
bind(URI.class).annotatedWith(TasksList.class).toInstance(
|
bind(URI.class).annotatedWith(TasksList.class).toInstance(
|
||||||
URI.create("http://tasksList"));
|
URI.create("http://tasksList"));
|
||||||
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF 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.vcloud.binders;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static org.easymock.EasyMock.expect;
|
||||||
|
import static org.easymock.classextension.EasyMock.createMock;
|
||||||
|
import static org.easymock.classextension.EasyMock.replay;
|
||||||
|
import static org.easymock.classextension.EasyMock.verify;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||||
|
import org.jclouds.util.Jsr330;
|
||||||
|
import org.jclouds.util.Utils;
|
||||||
|
import org.jclouds.vcloud.VCloudPropertiesBuilder;
|
||||||
|
import org.jclouds.vcloud.options.CloneVAppOptions;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.HashMultimap;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import com.google.common.collect.Multimaps;
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code BindCloneVAppParamsToXmlPayload}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "vcloud.BindCloneVAppParamsToXmlPayloadTest")
|
||||||
|
public class BindCloneVAppParamsToXmlPayloadTest {
|
||||||
|
Injector injector = Guice.createInjector(new AbstractModule() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
Properties props = new Properties();
|
||||||
|
Jsr330.bindProperties(binder(), checkNotNull(new VCloudPropertiesBuilder(props).build(),
|
||||||
|
"properties"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
public void testWithDescriptionDeployOn() throws IOException {
|
||||||
|
String expected = Utils.toStringAndClose(getClass().getResourceAsStream("/cloneVApp.xml"));
|
||||||
|
Multimap<String, String> headers = Multimaps.synchronizedMultimap(HashMultimap
|
||||||
|
.<String, String> create());
|
||||||
|
CloneVAppOptions options = new CloneVAppOptions().deploy().powerOn().withDescription(
|
||||||
|
"The description of the new vApp");
|
||||||
|
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
|
||||||
|
expect(request.getEndpoint()).andReturn(URI.create("http://localhost/key")).anyTimes();
|
||||||
|
expect(request.getArgs()).andReturn(new Object[] { options }).atLeastOnce();
|
||||||
|
expect(request.getFirstHeaderOrNull("Content-Type")).andReturn(null).atLeastOnce();
|
||||||
|
expect(request.getHeaders()).andReturn(headers).atLeastOnce();
|
||||||
|
request.setPayload(expected);
|
||||||
|
replay(request);
|
||||||
|
|
||||||
|
BindCloneVAppParamsToXmlPayload binder = injector
|
||||||
|
.getInstance(BindCloneVAppParamsToXmlPayload.class);
|
||||||
|
|
||||||
|
Map<String, String> map = Maps.newHashMap();
|
||||||
|
map.put("newName", "New Linux Server");
|
||||||
|
map.put("vApp", "https://services.vcloudexpress.terremark.com/api/vapp/201");
|
||||||
|
binder.bindToRequest(request, map);
|
||||||
|
verify(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDefault() throws IOException {
|
||||||
|
String expected = Utils.toStringAndClose(getClass().getResourceAsStream(
|
||||||
|
"/cloneVApp-default.xml"));
|
||||||
|
Multimap<String, String> headers = Multimaps.synchronizedMultimap(HashMultimap
|
||||||
|
.<String, String> create());
|
||||||
|
|
||||||
|
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
|
||||||
|
expect(request.getEndpoint()).andReturn(URI.create("http://localhost/key")).anyTimes();
|
||||||
|
expect(request.getArgs()).andReturn(new Object[] {}).atLeastOnce();
|
||||||
|
expect(request.getFirstHeaderOrNull("Content-Type")).andReturn(null).atLeastOnce();
|
||||||
|
expect(request.getHeaders()).andReturn(headers).atLeastOnce();
|
||||||
|
request.setPayload(expected);
|
||||||
|
replay(request);
|
||||||
|
|
||||||
|
BindCloneVAppParamsToXmlPayload binder = injector
|
||||||
|
.getInstance(BindCloneVAppParamsToXmlPayload.class);
|
||||||
|
|
||||||
|
Map<String, String> map = Maps.newHashMap();
|
||||||
|
map.put("newName", "New Name");
|
||||||
|
map.put("vApp", "https://services.vcloudexpress.terremark.com/api/vapp/4181");
|
||||||
|
binder.bindToRequest(request, map);
|
||||||
|
verify(request);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
<CloneVAppParams xmlns="http://www.vmware.com/vcloud/0.8" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" deploy="false" name="New Name" powerOn="false" xsi:schemaLocation="http://www.vmware.com/vcloud/0.8 http://vcloud.safesecureweb.com/ns/vcloud.xsd"><VApp href="https://services.vcloudexpress.terremark.com/api/vapp/4181" type="application/vnd.vmware.vcloud.vApp+xml"/></CloneVAppParams>
|
|
@ -0,0 +1 @@
|
||||||
|
<CloneVAppParams xmlns="http://www.vmware.com/vcloud/0.8" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" deploy="true" name="New Linux Server" powerOn="true" xsi:schemaLocation="http://www.vmware.com/vcloud/0.8 http://vcloud.safesecureweb.com/ns/vcloud.xsd"><Description>The description of the new vApp</Description><VApp href="https://services.vcloudexpress.terremark.com/api/vapp/201" type="application/vnd.vmware.vcloud.vApp+xml"/></CloneVAppParams>
|
|
@ -175,6 +175,15 @@ public interface TerremarkVCloudAsyncClient extends VCloudAsyncClient {
|
||||||
Future<? extends SortedSet<InternetService>> getInternetServicesOnPublicIp(
|
Future<? extends SortedSet<InternetService>> getInternetServicesOnPublicIp(
|
||||||
@PathParam("ipId") int ipId);
|
@PathParam("ipId") int ipId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see TerremarkVCloudClient#getPublicIp
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
|
||||||
|
@Path("/publicIps/{ipId}")
|
||||||
|
@XMLResponseParser(InternetServicesHandler.class)
|
||||||
|
Future<? extends SortedSet<InternetService>> getPublicIp(@PathParam("ipId") int ipId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see TerremarkVCloudClient#getPublicIpsAssociatedWithVDC
|
* @see TerremarkVCloudClient#getPublicIpsAssociatedWithVDC
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -109,6 +109,8 @@ public interface TerremarkVCloudClient extends VCloudClient {
|
||||||
*/
|
*/
|
||||||
SortedSet<InternetService> getInternetServicesOnPublicIp(int ipId);
|
SortedSet<InternetService> getInternetServicesOnPublicIp(int ipId);
|
||||||
|
|
||||||
|
SortedSet<InternetService> getPublicIp(int ipId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This call adds a node to an existing internet service.
|
* This call adds a node to an existing internet service.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
package org.jclouds.vcloud.terremark;
|
package org.jclouds.vcloud.terremark;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static org.jclouds.vcloud.options.CloneVAppOptions.Builder.deploy;
|
||||||
import static org.jclouds.vcloud.terremark.options.TerremarkInstantiateVAppTemplateOptions.Builder.processorCount;
|
import static org.jclouds.vcloud.terremark.options.TerremarkInstantiateVAppTemplateOptions.Builder.processorCount;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertNotNull;
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
@ -53,12 +54,14 @@ import org.jclouds.vcloud.domain.NamedResource;
|
||||||
import org.jclouds.vcloud.domain.ResourceType;
|
import org.jclouds.vcloud.domain.ResourceType;
|
||||||
import org.jclouds.vcloud.domain.Task;
|
import org.jclouds.vcloud.domain.Task;
|
||||||
import org.jclouds.vcloud.domain.VAppStatus;
|
import org.jclouds.vcloud.domain.VAppStatus;
|
||||||
|
import org.jclouds.vcloud.options.CloneVAppOptions;
|
||||||
import org.jclouds.vcloud.predicates.TaskSuccess;
|
import org.jclouds.vcloud.predicates.TaskSuccess;
|
||||||
import org.jclouds.vcloud.terremark.domain.ComputeOptions;
|
import org.jclouds.vcloud.terremark.domain.ComputeOptions;
|
||||||
import org.jclouds.vcloud.terremark.domain.CustomizationParameters;
|
import org.jclouds.vcloud.terremark.domain.CustomizationParameters;
|
||||||
import org.jclouds.vcloud.terremark.domain.InternetService;
|
import org.jclouds.vcloud.terremark.domain.InternetService;
|
||||||
import org.jclouds.vcloud.terremark.domain.Node;
|
import org.jclouds.vcloud.terremark.domain.Node;
|
||||||
import org.jclouds.vcloud.terremark.domain.Protocol;
|
import org.jclouds.vcloud.terremark.domain.Protocol;
|
||||||
|
import org.jclouds.vcloud.terremark.domain.PublicIpAddress;
|
||||||
import org.jclouds.vcloud.terremark.domain.TerremarkVApp;
|
import org.jclouds.vcloud.terremark.domain.TerremarkVApp;
|
||||||
import org.jclouds.vcloud.terremark.domain.TerremarkVDC;
|
import org.jclouds.vcloud.terremark.domain.TerremarkVDC;
|
||||||
import org.jclouds.vcloud.terremark.options.TerremarkInstantiateVAppTemplateOptions;
|
import org.jclouds.vcloud.terremark.options.TerremarkInstantiateVAppTemplateOptions;
|
||||||
|
@ -89,6 +92,8 @@ public class TerremarkVCloudClientLiveTest extends VCloudClientLiveTest {
|
||||||
|
|
||||||
private RetryablePredicate<String> successTester;
|
private RetryablePredicate<String> successTester;
|
||||||
|
|
||||||
|
private TerremarkVApp clone;
|
||||||
|
|
||||||
public static final String PREFIX = System.getProperty("user.name") + "-terremark";
|
public static final String PREFIX = System.getProperty("user.name") + "-terremark";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -99,6 +104,15 @@ public class TerremarkVCloudClientLiveTest extends VCloudClientLiveTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetPublicIpsAssociatedWithVDC() throws Exception {
|
||||||
|
for (PublicIpAddress ip : tmClient.getPublicIpsAssociatedWithVDC(tmClient.getDefaultVDC()
|
||||||
|
.getId())) {
|
||||||
|
assertNotNull(tmClient.getInternetServicesOnPublicIp(ip.getId()));
|
||||||
|
assertNotNull(tmClient.getPublicIp(ip.getId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetConfigCustomizationOptions() throws Exception {
|
public void testGetConfigCustomizationOptions() throws Exception {
|
||||||
Catalog response = connection.getCatalog();
|
Catalog response = connection.getCatalog();
|
||||||
|
@ -211,6 +225,35 @@ public class TerremarkVCloudClientLiveTest extends VCloudClientLiveTest {
|
||||||
22);
|
22);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// throws 500 errors
|
||||||
|
@Test(enabled = false, dependsOnMethods = { "testInstantiateAndPowerOn" })
|
||||||
|
public void testCloneVApp() {
|
||||||
|
// lookup the id of the datacenter you are deploying into
|
||||||
|
String vDCId = tmClient.getDefaultVDC().getId();
|
||||||
|
|
||||||
|
String vAppIdToClone = vApp.getId();
|
||||||
|
|
||||||
|
String newName = vApp.getName() + "clone";
|
||||||
|
|
||||||
|
CloneVAppOptions options = deploy().powerOn()
|
||||||
|
.withDescription("The description of " + newName);
|
||||||
|
|
||||||
|
System.out.printf("%d: cloning vApp%n", System.currentTimeMillis());
|
||||||
|
Task task = tmClient.cloneVAppInVDC(vDCId, vAppIdToClone, newName, options);
|
||||||
|
|
||||||
|
// wait for the task to complete
|
||||||
|
assert successTester.apply(task.getId());
|
||||||
|
System.out.printf("%d: done cloning vApp%n", System.currentTimeMillis());
|
||||||
|
|
||||||
|
// refresh task to get the new vApp location
|
||||||
|
task = tmClient.getTask(task.getId());
|
||||||
|
|
||||||
|
clone = tmClient.getVApp(task.getResult().getId());
|
||||||
|
assertEquals(clone.getStatus(), VAppStatus.ON);
|
||||||
|
|
||||||
|
assertEquals(clone.getName(), newName);
|
||||||
|
}
|
||||||
|
|
||||||
@Test(dependsOnMethods = { "testInstantiateAndPowerOn", "testAddInternetService" })
|
@Test(dependsOnMethods = { "testInstantiateAndPowerOn", "testAddInternetService" })
|
||||||
public void testPublicIp() throws InterruptedException, ExecutionException, TimeoutException,
|
public void testPublicIp() throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
IOException {
|
IOException {
|
||||||
|
@ -304,6 +347,16 @@ public class TerremarkVCloudClientLiveTest extends VCloudClientLiveTest {
|
||||||
}
|
}
|
||||||
tmClient.deleteVApp(vApp.getId());
|
tmClient.deleteVApp(vApp.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clone != null) {
|
||||||
|
try {
|
||||||
|
successTester.apply(tmClient.powerOffVApp(clone.getId()).getId());
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
tmClient.deleteVApp(clone.getId());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeGroups(groups = { "live" })
|
@BeforeGroups(groups = { "live" })
|
||||||
|
|
Loading…
Reference in New Issue