Merge pull request #164 from richardcloudsoft/cloudstack-template-live-test

Cloudstack template live test - extract template functionality
This commit is contained in:
Adrian Cole 2011-11-17 05:00:07 -08:00
commit 5cdff59bfe
6 changed files with 338 additions and 6 deletions

View File

@ -0,0 +1,292 @@
/**
* 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.cloudstack.domain;
import com.google.gson.annotations.SerializedName;
import java.util.Date;
/**
* @author Richard Downer
*/
public class TemplateExtraction implements Comparable<TemplateExtraction> {
public static Builder builder() {
return new Builder();
}
public static class Builder {
private long id;
private long accountId;
private Date created;
private long extractId;
private ExtractMode extractMode;
private String name;
private String state;
private String status;
private String storageType;
private int uploadPercentage;
private String url;
private long zoneId;
private String zoneName;
/**
* @param id the id of extracted object
*/
public Builder id(long id) {
this.id = id;
return this;
}
/**
* @param accountId the account id to which the extracted object belongs
*/
public Builder accountId(long accountId) {
this.accountId = accountId;
return this;
}
/**
* @param created the time and date the object was created
*/
public Builder created(Date created) {
this.created = created;
return this;
}
/**
* @param extractId the upload id of extracted object
*/
public Builder extractId(long extractId) {
this.extractId = extractId;
return this;
}
/**
* @param extractMode the mode of extraction - upload or download
*/
public Builder extractMode(ExtractMode extractMode) {
this.extractMode = extractMode;
return this;
}
/**
* @param name the name of the extracted object
*/
public Builder name(String name) {
this.name = name;
return this;
}
/**
* @param state the state of the extracted object
*/
public Builder state(String state) {
this.state = state;
return this;
}
/**
* @param status the status of the extraction
*/
public Builder status(String status) {
this.status = status;
return this;
}
/**
* @param storageType type of the storage
*/
public Builder storageType(String storageType) {
this.storageType = storageType;
return this;
}
/**
* @param uploadPercentage the percentage of the entity uploaded to the specified location
*/
public Builder uploadPercentage(int uploadPercentage) {
this.uploadPercentage = uploadPercentage;
return this;
}
/**
* @param url if mode = upload then url of the uploaded entity. if mode = download the url from which the entity can be downloaded
*/
public Builder url(String url) {
this.url = url;
return this;
}
/**
* @param zoneId zone ID the object was extracted from
*/
public Builder zoneId(long zoneId) {
this.zoneId = zoneId;
return this;
}
/**
* @param zoneName zone name the object was extracted from
*/
public Builder zoneName(String zoneName) {
this.zoneName = zoneName;
return this;
}
}
private long id;
@SerializedName("accountid")
private long accountId;
private Date created;
private long extractId;
private ExtractMode extractMode;
private String name;
private String state;
private String status;
@SerializedName("storagetype")
private String storageType;
@SerializedName("uploadpercentage")
private int uploadPercentage;
private String url;
@SerializedName("zoneid")
private long zoneId;
@SerializedName("zonename")
private String zoneName;
/**
* present only for serializer
*/
TemplateExtraction() {
}
/**
* @return the id of extracted object
*/
public long getId() {
return id;
}
/**
* @return the account id to which the extracted object belongs
*/
public long getAccountId() {
return accountId;
}
/**
* @return the time and date the object was created
*/
public Date getCreated() {
return created;
}
/**
* @return the upload id of extracted object
*/
public long getExtractId() {
return extractId;
}
/**
* @return the mode of extraction - upload or download
*/
public ExtractMode getExtractMode() {
return extractMode;
}
/**
* @return the name of the extracted object
*/
public String getName() {
return name;
}
/**
* @return the state of the extracted object
*/
public String getState() {
return state;
}
/**
* @return the status of the extraction
*/
public String getStatus() {
return status;
}
/**
* @return type of the storage
*/
public String getStorageType() {
return storageType;
}
/**
* @return the percentage of the entity uploaded to the specified location
*/
public int getUploadPercentage() {
return uploadPercentage;
}
/**
* @return if mode = upload then url of the uploaded entity. if mode = download the url from which the entity can be downloaded
*/
public String getUrl() {
return url;
}
/**
* @return zone ID the object was extracted from
*/
public long getZoneId() {
return zoneId;
}
/**
* @return zone name the object was extracted from
*/
public String getZoneName() {
return zoneName;
}
@Override
public boolean equals(Object o) {
throw new RuntimeException("FIXME: Implement me");
}
@Override
public int hashCode() {
throw new RuntimeException("FIXME: Implement me");
}
@Override
public String toString() {
throw new RuntimeException("FIXME: Implement me");
}
@Override
public int compareTo(TemplateExtraction other) {
throw new RuntimeException("FIXME: Implement me");
}
}

View File

@ -27,6 +27,7 @@ import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton;
import com.google.common.base.Strings;
import org.jclouds.cloudstack.domain.AsyncJob;
import org.jclouds.cloudstack.domain.AsyncJob.Builder;
import org.jclouds.cloudstack.domain.AsyncJobError;
@ -36,6 +37,7 @@ import org.jclouds.cloudstack.domain.PortForwardingRule;
import org.jclouds.cloudstack.domain.PublicIPAddress;
import org.jclouds.cloudstack.domain.SecurityGroup;
import org.jclouds.cloudstack.domain.Template;
import org.jclouds.cloudstack.domain.TemplateExtraction;
import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.domain.JsonBall;
import org.jclouds.json.Json;
@ -61,7 +63,7 @@ public class ParseTypedAsyncJob implements Function<AsyncJob<Map<String, JsonBal
@Named("jclouds.cloudstack.jobresult-type-map")
Map<String, Class<?>> typeMap = ImmutableMap.<String, Class<?>> builder().put("securitygroup", SecurityGroup.class)
.put("portforwardingrule", PortForwardingRule.class).put("ipforwardingrule", IPForwardingRule.class)
.put("template", Template.class).put("network", Network.class).put("ipaddress", PublicIPAddress.class)
.put("network", Network.class).put("ipaddress", PublicIPAddress.class)
.put("virtualmachine", VirtualMachine.class).build();
private final Json json;
@ -80,7 +82,15 @@ public class ParseTypedAsyncJob implements Function<AsyncJob<Map<String, JsonBal
builder.result(null);
} else {
Entry<String, JsonBall> entry = Iterables.get(toParse.getResult().entrySet(), 0);
if (typeMap.containsKey(entry.getKey())) {
if ("template".equals(entry.getKey())) {
// Sometimes Cloudstack will say 'template' and the payload is a Template object.
// Sometimes Cloudstack will say 'template' and the payload is a TemplateExtraction object.
// The 'state' field only exists on TemplateExtraction, so we can test this to work out what we have actually been given.
Template template = json.fromJson(entry.getValue().toString(), Template.class);
TemplateExtraction templateExtraction = json.fromJson(entry.getValue().toString(), TemplateExtraction.class);
boolean isTemplate = Strings.isNullOrEmpty(templateExtraction.getState());
builder.result(isTemplate ? template : templateExtraction);
} else if (typeMap.containsKey(entry.getKey())) {
builder.result(json.fromJson(entry.getValue().toString(), typeMap.get(entry.getKey())));
} else {
logger.warn(

View File

@ -28,6 +28,8 @@ import org.testng.annotations.AfterGroups;
import org.testng.annotations.Test;
import javax.annotation.Nullable;
import java.net.URI;
import java.net.URLDecoder;
import java.util.Random;
import java.util.Set;
@ -73,6 +75,7 @@ public class TemplateClientLiveTest extends BaseCloudStackClientLiveTest {
}
}
@Test(enabled = true)
public void testCreateTemplate() throws Exception {
Zone zone = Iterables.getFirst(client.getZoneClient().listZones(), null);
assertNotNull(zone);
@ -121,4 +124,21 @@ public class TemplateClientLiveTest extends BaseCloudStackClientLiveTest {
super.tearDown();
}
@Test(enabled = true, dependsOnMethods = "testCreateTemplate")
public void testExtractTemplate() throws Exception {
// Initiate the extraction and wait for it to complete
AsyncCreateResponse response = client.getTemplateClient().extractTemplate(template.getId(), ExtractMode.HTTP_DOWNLOAD, template.getZoneId());
assert jobComplete.apply(response.getJobId()) : template;
// Get the result
AsyncJob<TemplateExtraction> asyncJob = client.getAsyncJobClient().getAsyncJob(response.getJobId());
TemplateExtraction extract = asyncJob.getResult();
assertNotNull(extract);
// Check that the URL can be retrieved
String extractUrl = extract.getUrl();
assertNotNull(extractUrl);
URI uri = new URI(URLDecoder.decode(extractUrl, "utf-8"));
assertTrue(context.utils().http().exists(uri), "does not exist: " + uri);
}
}

View File

@ -19,13 +19,11 @@
package org.jclouds.cloudstack.functions;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.io.InputStream;
import org.jclouds.cloudstack.domain.AsyncJob;
import org.jclouds.cloudstack.domain.AsyncJobError;
import org.jclouds.cloudstack.domain.IPForwardingRule;
import org.jclouds.cloudstack.domain.PublicIPAddress;
import org.jclouds.cloudstack.domain.*;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.domain.JsonBall;
import org.jclouds.http.HttpResponse;
@ -187,4 +185,14 @@ public class ParseAsyncJobFromHttpResponseTest {
assertEquals(response, expects);
}
public void testOverloadedKeyName() {
InputStream is = getClass().getResourceAsStream("/queryasyncjobresultresponse-createtemplate.json");
ParseAsyncJobFromHttpResponse parser = i.getInstance(ParseAsyncJobFromHttpResponse.class);
AsyncJob response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is)));
assertTrue(response.getResult() instanceof Template, "response expected to be Template, actually is "+response.getResult().getClass());
is = getClass().getResourceAsStream("/queryasyncjobresultresponse-extracttemplate.json");
response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is)));
assertTrue(response.getResult() instanceof TemplateExtraction, "response expected to be TemplateExtraction, actually is "+response.getResult().getClass());
}
}

View File

@ -0,0 +1 @@
{ "queryasyncjobresultresponse" : {"jobid":2716,"jobstatus":1,"jobprocstatus":0,"jobresultcode":0,"jobresulttype":"object","jobresult":{"template":{"id":249,"name":"jclouds-c5c7dce0","displaytext":"jclouds live testCreateTemplate","ispublic":false,"created":"2011-11-16T06:43:00-0800","isready":true,"passwordenabled":false,"format":"VHD","isfeatured":false,"crossZones":false,"ostypeid":12,"ostypename":"CentOS 5.3 (64-bit)","account":"jcloud2","zoneid":1,"zonename":"Demo5","status":"Download Complete","size":8589934592,"templatetype":"USER","hypervisor":"XenServer","domain":"jCloud","domainid":11,"isextractable":true,"checksum":"bdc1c2c49b747694f97be5042323a1fa","sourcetemplateid":202}}} }

View File

@ -0,0 +1 @@
{ "queryasyncjobresultresponse" : {"jobid":2720,"jobstatus":1,"jobprocstatus":0,"jobresultcode":0,"jobresulttype":"object","jobresult":{"template":{"id":249,"name":"jclouds-c5c7dce0","extractId":6,"accountid":19,"state":"DOWNLOAD_URL_CREATED","zoneid":1,"zonename":"Demo5","extractMode":"HTTP_DOWNLOAD","url":"https:%2F%2F72-52-126-96.realhostip.com%2Fuserdata%2Ff52f8e7d-7c89-4cf7-8e5a-b5ea17366d73.vhd"}}} }